]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/mips/predicates.md
Makefile.in (insn-emit.o): Depend on $(INTEGRATE_H).
[thirdparty/gcc.git] / gcc / config / mips / predicates.md
1 ;; Predicate definitions for MIPS.
2 ;; Copyright (C) 2004 Free Software Foundation, Inc.
3 ;;
4 ;; This file is part of GCC.
5 ;;
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 2, or (at your option)
9 ;; any later version.
10 ;;
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
15 ;;
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING. If not, write to
18 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 ;; Boston, MA 02110-1301, USA.
20
21 (define_predicate "const_uns_arith_operand"
22 (and (match_code "const_int")
23 (match_test "SMALL_OPERAND_UNSIGNED (INTVAL (op))")))
24
25 (define_predicate "uns_arith_operand"
26 (ior (match_operand 0 "const_uns_arith_operand")
27 (match_operand 0 "register_operand")))
28
29 (define_predicate "const_arith_operand"
30 (and (match_code "const_int")
31 (match_test "SMALL_OPERAND (INTVAL (op))")))
32
33 (define_predicate "arith_operand"
34 (ior (match_operand 0 "const_arith_operand")
35 (match_operand 0 "register_operand")))
36
37 (define_predicate "const_uimm6_operand"
38 (and (match_code "const_int")
39 (match_test "UIMM6_OPERAND (INTVAL (op))")))
40
41 (define_predicate "const_imm10_operand"
42 (and (match_code "const_int")
43 (match_test "IMM10_OPERAND (INTVAL (op))")))
44
45 (define_predicate "reg_imm10_operand"
46 (ior (match_operand 0 "const_imm10_operand")
47 (match_operand 0 "register_operand")))
48
49 (define_predicate "sle_operand"
50 (and (match_code "const_int")
51 (match_test "SMALL_OPERAND (INTVAL (op) + 1)")))
52
53 (define_predicate "sleu_operand"
54 (and (match_operand 0 "sle_operand")
55 (match_test "INTVAL (op) + 1 != 0")))
56
57 (define_predicate "const_0_operand"
58 (and (match_code "const_int,const_double,const_vector")
59 (match_test "op == CONST0_RTX (GET_MODE (op))")))
60
61 (define_predicate "reg_or_0_operand"
62 (ior (and (match_operand 0 "const_0_operand")
63 (match_test "!TARGET_MIPS16"))
64 (match_operand 0 "register_operand")))
65
66 (define_predicate "const_1_operand"
67 (and (match_code "const_int,const_double,const_vector")
68 (match_test "op == CONST1_RTX (GET_MODE (op))")))
69
70 (define_predicate "reg_or_1_operand"
71 (ior (match_operand 0 "const_1_operand")
72 (match_operand 0 "register_operand")))
73
74 ;; This is used for indexing into vectors, and hence only accepts const_int.
75 (define_predicate "const_0_or_1_operand"
76 (and (match_code "const_int")
77 (ior (match_test "op == CONST0_RTX (GET_MODE (op))")
78 (match_test "op == CONST1_RTX (GET_MODE (op))"))))
79
80 (define_predicate "fpr_operand"
81 (and (match_code "reg")
82 (match_test "FP_REG_P (REGNO (op))")))
83
84 (define_predicate "lo_operand"
85 (and (match_code "reg")
86 (match_test "REGNO (op) == LO_REGNUM")))
87
88 (define_predicate "fcc_reload_operand"
89 (and (match_code "reg,subreg")
90 (match_test "ST_REG_P (true_regnum (op))")))
91
92 (define_special_predicate "pc_or_label_operand"
93 (match_code "pc,label_ref"))
94
95 (define_predicate "const_call_insn_operand"
96 (match_code "const,symbol_ref,label_ref")
97 {
98 enum mips_symbol_type symbol_type;
99
100 if (!mips_symbolic_constant_p (op, &symbol_type))
101 return false;
102
103 switch (symbol_type)
104 {
105 case SYMBOL_GENERAL:
106 /* We can only use direct calls for TARGET_ABSOLUTE_ABICALLS if we
107 are sure that the target function does not need $25 to be live
108 on entry. This is true for any locally-defined function because
109 any such function will use %hi/%lo accesses to set up $gp. */
110 if (TARGET_ABSOLUTE_ABICALLS
111 && !(GET_CODE (op) == SYMBOL_REF
112 && SYMBOL_REF_DECL (op)
113 && !DECL_EXTERNAL (SYMBOL_REF_DECL (op))))
114 return false;
115
116 /* If -mlong-calls, force all calls to use register addressing. Also,
117 if this function has the long_call attribute, we must use register
118 addressing. */
119 return !TARGET_LONG_CALLS && !SYMBOL_REF_LONG_CALL_P (op);
120
121 case SYMBOL_GOT_DISP:
122 /* Without explicit relocs, there is no special syntax for
123 loading the address of a call destination into a register.
124 Using "la $25,foo; jal $25" would prevent the lazy binding
125 of "foo", so keep the address of global symbols with the
126 jal macro. */
127 return !TARGET_EXPLICIT_RELOCS;
128
129 default:
130 return false;
131 }
132 })
133
134 (define_predicate "call_insn_operand"
135 (ior (match_operand 0 "const_call_insn_operand")
136 (match_operand 0 "register_operand")))
137
138 ;; A legitimate CONST_INT operand that takes more than one instruction
139 ;; to load.
140 (define_predicate "splittable_const_int_operand"
141 (match_code "const_int")
142 {
143 /* When generating mips16 code, LEGITIMATE_CONSTANT_P rejects
144 CONST_INTs that can't be loaded using simple insns. */
145 if (TARGET_MIPS16)
146 return false;
147
148 /* Don't handle multi-word moves this way; we don't want to introduce
149 the individual word-mode moves until after reload. */
150 if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
151 return false;
152
153 /* Otherwise check whether the constant can be loaded in a single
154 instruction. */
155 return !LUI_INT (op) && !SMALL_INT (op) && !SMALL_INT_UNSIGNED (op);
156 })
157
158 ;; A legitimate symbolic operand that takes more than one instruction
159 ;; to load.
160 (define_predicate "splittable_symbolic_operand"
161 (match_code "const,symbol_ref,label_ref")
162 {
163 enum mips_symbol_type symbol_type;
164 return (mips_symbolic_constant_p (op, &symbol_type)
165 && mips_split_p[symbol_type]);
166 })
167
168 (define_predicate "move_operand"
169 (match_operand 0 "general_operand")
170 {
171 enum mips_symbol_type symbol_type;
172
173 /* The thinking here is as follows:
174
175 (1) The move expanders should split complex load sequences into
176 individual instructions. Those individual instructions can
177 then be optimized by all rtl passes.
178
179 (2) The target of pre-reload load sequences should not be used
180 to store temporary results. If the target register is only
181 assigned one value, reload can rematerialize that value
182 on demand, rather than spill it to the stack.
183
184 (3) If we allowed pre-reload passes like combine and cse to recreate
185 complex load sequences, we would want to be able to split the
186 sequences before reload as well, so that the pre-reload scheduler
187 can see the individual instructions. This falls foul of (2);
188 the splitter would be forced to reuse the target register for
189 intermediate results.
190
191 (4) We want to define complex load splitters for combine. These
192 splitters can request a temporary scratch register, which avoids
193 the problem in (2). They allow things like:
194
195 (set (reg T1) (high SYM))
196 (set (reg T2) (low (reg T1) SYM))
197 (set (reg X) (plus (reg T2) (const_int OFFSET)))
198
199 to be combined into:
200
201 (set (reg T3) (high SYM+OFFSET))
202 (set (reg X) (lo_sum (reg T3) SYM+OFFSET))
203
204 if T2 is only used this once. */
205 switch (GET_CODE (op))
206 {
207 case CONST_INT:
208 return !splittable_const_int_operand (op, mode);
209
210 case CONST:
211 case SYMBOL_REF:
212 case LABEL_REF:
213 if (CONST_GP_P (op))
214 return true;
215 return (mips_symbolic_constant_p (op, &symbol_type)
216 && !mips_split_p[symbol_type]);
217
218 default:
219 return true;
220 }
221 })
222
223 (define_predicate "consttable_operand"
224 (match_test "CONSTANT_P (op)"))
225
226 (define_predicate "symbolic_operand"
227 (match_code "const,symbol_ref,label_ref")
228 {
229 enum mips_symbol_type type;
230 return mips_symbolic_constant_p (op, &type);
231 })
232
233 (define_predicate "general_symbolic_operand"
234 (match_code "const,symbol_ref,label_ref")
235 {
236 enum mips_symbol_type type;
237 return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GENERAL;
238 })
239
240 (define_predicate "got_disp_operand"
241 (match_code "const,symbol_ref,label_ref")
242 {
243 enum mips_symbol_type type;
244 return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_DISP;
245 })
246
247 (define_predicate "got_page_ofst_operand"
248 (match_code "const,symbol_ref,label_ref")
249 {
250 enum mips_symbol_type type;
251 return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_PAGE_OFST;
252 })
253
254 (define_predicate "symbol_ref_operand"
255 (match_code "symbol_ref"))
256
257 (define_predicate "stack_operand"
258 (and (match_code "mem")
259 (match_test "mips_stack_address_p (XEXP (op, 0), GET_MODE (op))")))
260
261 (define_predicate "macc_msac_operand"
262 (ior (and (match_code "plus") (match_test "ISA_HAS_MACC"))
263 (and (match_code "minus") (match_test "ISA_HAS_MSAC")))
264 {
265 rtx mult = XEXP (op, GET_CODE (op) == PLUS ? 0 : 1);
266 rtx accum = XEXP (op, GET_CODE (op) == PLUS ? 1 : 0);
267 return (GET_CODE (mult) == MULT
268 && REG_P (XEXP (mult, 0))
269 && REG_P (XEXP (mult, 1))
270 && REG_P (accum));
271 })
272
273
274 (define_predicate "equality_operator"
275 (match_code "eq,ne"))
276
277 (define_predicate "extend_operator"
278 (match_code "zero_extend,sign_extend"))
279
280 (define_predicate "trap_comparison_operator"
281 (match_code "eq,ne,lt,ltu,ge,geu"))
282
283 (define_predicate "order_operator"
284 (match_code "lt,ltu,le,leu,ge,geu,gt,gtu"))
285
286
287 (define_predicate "small_data_pattern"
288 (and (match_code "set,parallel,unspec,unspec_volatile,prefetch")
289 (match_test "mips_small_data_pattern_p (op)")))