Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/mips/predicates.md @ 56:3c8a44c06a95
Added tag gcc-4.4.5 for changeset 77e2b8dfacca
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:41:23 +0900 |
parents | 77e2b8dfacca |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 ;; Predicate definitions for MIPS. |
2 ;; Copyright (C) 2004, 2007, 2008 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 3, 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 COPYING3. If not see | |
18 ;; <http://www.gnu.org/licenses/>. | |
19 | |
20 (define_predicate "const_uns_arith_operand" | |
21 (and (match_code "const_int") | |
22 (match_test "SMALL_OPERAND_UNSIGNED (INTVAL (op))"))) | |
23 | |
24 (define_predicate "uns_arith_operand" | |
25 (ior (match_operand 0 "const_uns_arith_operand") | |
26 (match_operand 0 "register_operand"))) | |
27 | |
28 (define_predicate "const_arith_operand" | |
29 (and (match_code "const_int") | |
30 (match_test "SMALL_OPERAND (INTVAL (op))"))) | |
31 | |
32 (define_predicate "arith_operand" | |
33 (ior (match_operand 0 "const_arith_operand") | |
34 (match_operand 0 "register_operand"))) | |
35 | |
36 (define_predicate "const_uimm6_operand" | |
37 (and (match_code "const_int") | |
38 (match_test "UIMM6_OPERAND (INTVAL (op))"))) | |
39 | |
40 (define_predicate "const_imm10_operand" | |
41 (and (match_code "const_int") | |
42 (match_test "IMM10_OPERAND (INTVAL (op))"))) | |
43 | |
44 (define_predicate "reg_imm10_operand" | |
45 (ior (match_operand 0 "const_imm10_operand") | |
46 (match_operand 0 "register_operand"))) | |
47 | |
48 (define_predicate "sle_operand" | |
49 (and (match_code "const_int") | |
50 (match_test "SMALL_OPERAND (INTVAL (op) + 1)"))) | |
51 | |
52 (define_predicate "sleu_operand" | |
53 (and (match_operand 0 "sle_operand") | |
54 (match_test "INTVAL (op) + 1 != 0"))) | |
55 | |
56 (define_predicate "const_0_operand" | |
57 (and (match_code "const_int,const_double,const_vector") | |
58 (match_test "op == CONST0_RTX (GET_MODE (op))"))) | |
59 | |
60 (define_predicate "reg_or_0_operand" | |
61 (ior (and (match_operand 0 "const_0_operand") | |
62 (match_test "!TARGET_MIPS16")) | |
63 (match_operand 0 "register_operand"))) | |
64 | |
65 (define_predicate "const_1_operand" | |
66 (and (match_code "const_int,const_double,const_vector") | |
67 (match_test "op == CONST1_RTX (GET_MODE (op))"))) | |
68 | |
69 (define_predicate "reg_or_1_operand" | |
70 (ior (match_operand 0 "const_1_operand") | |
71 (match_operand 0 "register_operand"))) | |
72 | |
73 ;; This is used for indexing into vectors, and hence only accepts const_int. | |
74 (define_predicate "const_0_or_1_operand" | |
75 (and (match_code "const_int") | |
76 (ior (match_test "op == CONST0_RTX (GET_MODE (op))") | |
77 (match_test "op == CONST1_RTX (GET_MODE (op))")))) | |
78 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
79 (define_predicate "qi_mask_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
80 (and (match_code "const_int") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
81 (match_test "UINTVAL (op) == 0xff"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
82 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
83 (define_predicate "hi_mask_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
84 (and (match_code "const_int") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
85 (match_test "UINTVAL (op) == 0xffff"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
86 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
87 (define_predicate "si_mask_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
88 (and (match_code "const_int") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
89 (match_test "UINTVAL (op) == 0xffffffff"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
90 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
91 (define_predicate "and_load_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
92 (ior (match_operand 0 "qi_mask_operand") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
93 (match_operand 0 "hi_mask_operand") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
94 (match_operand 0 "si_mask_operand"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
95 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
96 (define_predicate "low_bitmask_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
97 (and (match_test "ISA_HAS_EXT_INS") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
98 (match_code "const_int") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
99 (match_test "low_bitmask_len (mode, INTVAL (op)) > 16"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
100 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
101 (define_predicate "and_reg_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
102 (ior (match_operand 0 "register_operand") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
103 (and (match_test "!TARGET_MIPS16") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
104 (match_operand 0 "const_uns_arith_operand")) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
105 (match_operand 0 "low_bitmask_operand") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
106 (match_operand 0 "si_mask_operand"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
107 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
108 (define_predicate "and_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
109 (ior (match_operand 0 "and_load_operand") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
110 (match_operand 0 "and_reg_operand"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
111 |
0 | 112 (define_predicate "d_operand" |
113 (and (match_code "reg") | |
114 (match_test "TARGET_MIPS16 | |
115 ? M16_REG_P (REGNO (op)) | |
116 : GP_REG_P (REGNO (op))"))) | |
117 | |
118 (define_predicate "lo_operand" | |
119 (and (match_code "reg") | |
120 (match_test "REGNO (op) == LO_REGNUM"))) | |
121 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
122 (define_predicate "hilo_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
123 (and (match_code "reg") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
124 (match_test "MD_REG_P (REGNO (op))"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
125 |
0 | 126 (define_predicate "fcc_reload_operand" |
127 (and (match_code "reg,subreg") | |
128 (match_test "ST_REG_P (true_regnum (op))"))) | |
129 | |
130 (define_special_predicate "pc_or_label_operand" | |
131 (match_code "pc,label_ref")) | |
132 | |
133 (define_predicate "const_call_insn_operand" | |
134 (match_code "const,symbol_ref,label_ref") | |
135 { | |
136 enum mips_symbol_type symbol_type; | |
137 | |
138 if (!mips_symbolic_constant_p (op, SYMBOL_CONTEXT_CALL, &symbol_type)) | |
139 return false; | |
140 | |
141 switch (symbol_type) | |
142 { | |
143 case SYMBOL_ABSOLUTE: | |
144 /* We can only use direct calls if we're sure that the target | |
145 function does not need $25 to be valid on entry. */ | |
146 if (mips_use_pic_fn_addr_reg_p (op)) | |
147 return false; | |
148 | |
149 /* If -mlong-calls or if this function has an explicit long_call | |
150 attribute, we must use register addressing. The | |
151 SYMBOL_FLAG_LONG_CALL bit is set by mips_encode_section_info. */ | |
152 return !(GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_LONG_CALL_P (op)); | |
153 | |
154 case SYMBOL_GOT_DISP: | |
155 /* Without explicit relocs, there is no special syntax for | |
156 loading the address of a call destination into a register. | |
157 Using "la $25,foo; jal $25" would prevent the lazy binding | |
158 of "foo", so keep the address of global symbols with the | |
159 jal macro. */ | |
160 return !TARGET_EXPLICIT_RELOCS; | |
161 | |
162 default: | |
163 return false; | |
164 } | |
165 }) | |
166 | |
167 (define_predicate "call_insn_operand" | |
168 (ior (match_operand 0 "const_call_insn_operand") | |
169 (match_operand 0 "register_operand"))) | |
170 | |
171 ;; A legitimate CONST_INT operand that takes more than one instruction | |
172 ;; to load. | |
173 (define_predicate "splittable_const_int_operand" | |
174 (match_code "const_int") | |
175 { | |
176 /* When generating mips16 code, LEGITIMATE_CONSTANT_P rejects | |
177 CONST_INTs that can't be loaded using simple insns. */ | |
178 if (TARGET_MIPS16) | |
179 return false; | |
180 | |
181 /* Don't handle multi-word moves this way; we don't want to introduce | |
182 the individual word-mode moves until after reload. */ | |
183 if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) | |
184 return false; | |
185 | |
186 /* Otherwise check whether the constant can be loaded in a single | |
187 instruction. */ | |
188 return !LUI_INT (op) && !SMALL_INT (op) && !SMALL_INT_UNSIGNED (op); | |
189 }) | |
190 | |
191 (define_predicate "move_operand" | |
192 (match_operand 0 "general_operand") | |
193 { | |
194 enum mips_symbol_type symbol_type; | |
195 | |
196 /* The thinking here is as follows: | |
197 | |
198 (1) The move expanders should split complex load sequences into | |
199 individual instructions. Those individual instructions can | |
200 then be optimized by all rtl passes. | |
201 | |
202 (2) The target of pre-reload load sequences should not be used | |
203 to store temporary results. If the target register is only | |
204 assigned one value, reload can rematerialize that value | |
205 on demand, rather than spill it to the stack. | |
206 | |
207 (3) If we allowed pre-reload passes like combine and cse to recreate | |
208 complex load sequences, we would want to be able to split the | |
209 sequences before reload as well, so that the pre-reload scheduler | |
210 can see the individual instructions. This falls foul of (2); | |
211 the splitter would be forced to reuse the target register for | |
212 intermediate results. | |
213 | |
214 (4) We want to define complex load splitters for combine. These | |
215 splitters can request a temporary scratch register, which avoids | |
216 the problem in (2). They allow things like: | |
217 | |
218 (set (reg T1) (high SYM)) | |
219 (set (reg T2) (low (reg T1) SYM)) | |
220 (set (reg X) (plus (reg T2) (const_int OFFSET))) | |
221 | |
222 to be combined into: | |
223 | |
224 (set (reg T3) (high SYM+OFFSET)) | |
225 (set (reg X) (lo_sum (reg T3) SYM+OFFSET)) | |
226 | |
227 if T2 is only used this once. */ | |
228 switch (GET_CODE (op)) | |
229 { | |
230 case CONST_INT: | |
231 return !splittable_const_int_operand (op, mode); | |
232 | |
233 case CONST: | |
234 case SYMBOL_REF: | |
235 case LABEL_REF: | |
236 if (CONST_GP_P (op)) | |
237 return true; | |
238 return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type) | |
239 && !mips_split_p[symbol_type]); | |
240 | |
241 case HIGH: | |
242 op = XEXP (op, 0); | |
243 return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type) | |
244 && !mips_split_hi_p[symbol_type]); | |
245 | |
246 default: | |
247 return true; | |
248 } | |
249 }) | |
250 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
251 (define_predicate "cprestore_save_slot_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
252 (and (match_code "mem") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
253 (match_test "mips_cprestore_address_p (XEXP (op, 0), false)"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
254 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
255 (define_predicate "cprestore_load_slot_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
256 (and (match_code "mem") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
257 (match_test "mips_cprestore_address_p (XEXP (op, 0), true)"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
258 |
0 | 259 (define_predicate "consttable_operand" |
260 (match_test "CONSTANT_P (op)")) | |
261 | |
262 (define_predicate "symbolic_operand" | |
263 (match_code "const,symbol_ref,label_ref") | |
264 { | |
265 enum mips_symbol_type type; | |
266 return mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type); | |
267 }) | |
268 | |
269 (define_predicate "absolute_symbolic_operand" | |
270 (match_code "const,symbol_ref,label_ref") | |
271 { | |
272 enum mips_symbol_type type; | |
273 return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type) | |
274 && type == SYMBOL_ABSOLUTE); | |
275 }) | |
276 | |
277 (define_predicate "force_to_mem_operand" | |
278 (match_code "const,symbol_ref,label_ref") | |
279 { | |
280 enum mips_symbol_type symbol_type; | |
281 return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type) | |
282 && symbol_type == SYMBOL_FORCE_TO_MEM); | |
283 }) | |
284 | |
285 (define_predicate "got_disp_operand" | |
286 (match_code "const,symbol_ref,label_ref") | |
287 { | |
288 enum mips_symbol_type type; | |
289 return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type) | |
290 && type == SYMBOL_GOT_DISP); | |
291 }) | |
292 | |
293 (define_predicate "got_page_ofst_operand" | |
294 (match_code "const,symbol_ref,label_ref") | |
295 { | |
296 enum mips_symbol_type type; | |
297 return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type) | |
298 && type == SYMBOL_GOT_PAGE_OFST); | |
299 }) | |
300 | |
301 (define_predicate "symbol_ref_operand" | |
302 (match_code "symbol_ref")) | |
303 | |
304 (define_predicate "stack_operand" | |
305 (and (match_code "mem") | |
306 (match_test "mips_stack_address_p (XEXP (op, 0), GET_MODE (op))"))) | |
307 | |
308 (define_predicate "macc_msac_operand" | |
309 (ior (and (match_code "plus") (match_test "ISA_HAS_MACC")) | |
310 (and (match_code "minus") (match_test "ISA_HAS_MSAC"))) | |
311 { | |
312 rtx mult = XEXP (op, GET_CODE (op) == PLUS ? 0 : 1); | |
313 rtx accum = XEXP (op, GET_CODE (op) == PLUS ? 1 : 0); | |
314 return (GET_CODE (mult) == MULT | |
315 && REG_P (XEXP (mult, 0)) | |
316 && REG_P (XEXP (mult, 1)) | |
317 && REG_P (accum)); | |
318 }) | |
319 | |
320 | |
321 (define_predicate "equality_operator" | |
322 (match_code "eq,ne")) | |
323 | |
324 (define_predicate "extend_operator" | |
325 (match_code "zero_extend,sign_extend")) | |
326 | |
327 (define_predicate "trap_comparison_operator" | |
328 (match_code "eq,ne,lt,ltu,ge,geu")) | |
329 | |
330 (define_predicate "order_operator" | |
331 (match_code "lt,ltu,le,leu,ge,geu,gt,gtu")) | |
332 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
333 ;; For NE, cstore uses sltu instructions in which the first operand is $0. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
334 ;; This isn't possible in mips16 code. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
335 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
336 (define_predicate "mips_cstore_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
337 (ior (match_code "eq,gt,gtu,ge,geu,lt,ltu,le,leu") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
338 (and (match_code "ne") (match_test "!TARGET_MIPS16")))) |
0 | 339 |
340 (define_predicate "small_data_pattern" | |
341 (and (match_code "set,parallel,unspec,unspec_volatile,prefetch") | |
342 (match_test "mips_small_data_pattern_p (op)"))) |