Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/arm/predicates.md @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
rev | line source |
---|---|
0 | 1 ;; Predicate definitions for ARM and Thumb |
2 ;; Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. | |
3 ;; Contributed by ARM Ltd. | |
4 | |
5 ;; This file is part of GCC. | |
6 | |
7 ;; GCC is free software; you can redistribute it and/or modify it | |
8 ;; under the terms of the GNU General Public License as published | |
9 ;; by the Free Software Foundation; either version 3, or (at your | |
10 ;; option) any later version. | |
11 | |
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT | |
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
15 ;; License for more details. | |
16 | |
17 ;; You should have received a copy of the GNU General Public License | |
18 ;; along with GCC; see the file COPYING3. If not see | |
19 ;; <http://www.gnu.org/licenses/>. | |
20 | |
21 (define_predicate "s_register_operand" | |
22 (match_code "reg,subreg") | |
23 { | |
24 if (GET_CODE (op) == SUBREG) | |
25 op = SUBREG_REG (op); | |
26 /* We don't consider registers whose class is NO_REGS | |
27 to be a register operand. */ | |
28 /* XXX might have to check for lo regs only for thumb ??? */ | |
29 return (GET_CODE (op) == REG | |
30 && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
31 || REGNO_REG_CLASS (REGNO (op)) != NO_REGS)); | |
32 }) | |
33 | |
34 ;; Any hard register. | |
35 (define_predicate "arm_hard_register_operand" | |
36 (match_code "reg") | |
37 { | |
38 return REGNO (op) < FIRST_PSEUDO_REGISTER; | |
39 }) | |
40 | |
41 ;; A low register. | |
42 (define_predicate "low_register_operand" | |
43 (and (match_code "reg") | |
44 (match_test "REGNO (op) <= LAST_LO_REGNUM"))) | |
45 | |
46 ;; A low register or const_int. | |
47 (define_predicate "low_reg_or_int_operand" | |
48 (ior (match_code "const_int") | |
49 (match_operand 0 "low_register_operand"))) | |
50 | |
51 ;; Any core register, or any pseudo. */ | |
52 (define_predicate "arm_general_register_operand" | |
53 (match_code "reg,subreg") | |
54 { | |
55 if (GET_CODE (op) == SUBREG) | |
56 op = SUBREG_REG (op); | |
57 | |
58 return (GET_CODE (op) == REG | |
59 && (REGNO (op) <= LAST_ARM_REGNUM | |
60 || REGNO (op) >= FIRST_PSEUDO_REGISTER)); | |
61 }) | |
62 | |
63 (define_predicate "f_register_operand" | |
64 (match_code "reg,subreg") | |
65 { | |
66 if (GET_CODE (op) == SUBREG) | |
67 op = SUBREG_REG (op); | |
68 | |
69 /* We don't consider registers whose class is NO_REGS | |
70 to be a register operand. */ | |
71 return (GET_CODE (op) == REG | |
72 && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
73 || REGNO_REG_CLASS (REGNO (op)) == FPA_REGS)); | |
74 }) | |
75 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
76 (define_special_predicate "subreg_lowpart_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
77 (and (match_code "subreg") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
78 (match_test "subreg_lowpart_p (op)"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
79 |
0 | 80 ;; Reg, subreg(reg) or const_int. |
81 (define_predicate "reg_or_int_operand" | |
82 (ior (match_code "const_int") | |
83 (match_operand 0 "s_register_operand"))) | |
84 | |
85 (define_predicate "arm_immediate_operand" | |
86 (and (match_code "const_int") | |
87 (match_test "const_ok_for_arm (INTVAL (op))"))) | |
88 | |
89 (define_predicate "arm_neg_immediate_operand" | |
90 (and (match_code "const_int") | |
91 (match_test "const_ok_for_arm (-INTVAL (op))"))) | |
92 | |
93 (define_predicate "arm_not_immediate_operand" | |
94 (and (match_code "const_int") | |
95 (match_test "const_ok_for_arm (~INTVAL (op))"))) | |
96 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
97 (define_predicate "const0_operand" |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
98 (and (match_code "const_int") |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
99 (match_test "INTVAL (op) == 0"))) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
100 |
0 | 101 ;; Something valid on the RHS of an ARM data-processing instruction |
102 (define_predicate "arm_rhs_operand" | |
103 (ior (match_operand 0 "s_register_operand") | |
104 (match_operand 0 "arm_immediate_operand"))) | |
105 | |
106 (define_predicate "arm_rhsm_operand" | |
107 (ior (match_operand 0 "arm_rhs_operand") | |
108 (match_operand 0 "memory_operand"))) | |
109 | |
110 (define_predicate "arm_add_operand" | |
111 (ior (match_operand 0 "arm_rhs_operand") | |
112 (match_operand 0 "arm_neg_immediate_operand"))) | |
113 | |
114 (define_predicate "arm_addimm_operand" | |
115 (ior (match_operand 0 "arm_immediate_operand") | |
116 (match_operand 0 "arm_neg_immediate_operand"))) | |
117 | |
118 (define_predicate "arm_not_operand" | |
119 (ior (match_operand 0 "arm_rhs_operand") | |
120 (match_operand 0 "arm_not_immediate_operand"))) | |
121 | |
122 ;; True if the operand is a memory reference which contains an | |
123 ;; offsettable address. | |
124 (define_predicate "offsettable_memory_operand" | |
125 (and (match_code "mem") | |
126 (match_test | |
127 "offsettable_address_p (reload_completed | reload_in_progress, | |
128 mode, XEXP (op, 0))"))) | |
129 | |
130 ;; True if the operand is a memory operand that does not have an | |
131 ;; automodified base register (and thus will not generate output reloads). | |
132 (define_predicate "call_memory_operand" | |
133 (and (match_code "mem") | |
134 (and (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) | |
135 != RTX_AUTOINC") | |
136 (match_operand 0 "memory_operand")))) | |
137 | |
138 (define_predicate "arm_reload_memory_operand" | |
139 (and (match_code "mem,reg,subreg") | |
140 (match_test "(!CONSTANT_P (op) | |
141 && (true_regnum(op) == -1 | |
142 || (GET_CODE (op) == REG | |
143 && REGNO (op) >= FIRST_PSEUDO_REGISTER)))"))) | |
144 | |
145 ;; True for valid operands for the rhs of an floating point insns. | |
146 ;; Allows regs or certain consts on FPA, just regs for everything else. | |
147 (define_predicate "arm_float_rhs_operand" | |
148 (ior (match_operand 0 "s_register_operand") | |
149 (and (match_code "const_double") | |
150 (match_test "TARGET_FPA && arm_const_double_rtx (op)")))) | |
151 | |
152 (define_predicate "arm_float_add_operand" | |
153 (ior (match_operand 0 "arm_float_rhs_operand") | |
154 (and (match_code "const_double") | |
155 (match_test "TARGET_FPA && neg_const_double_rtx_ok_for_fpa (op)")))) | |
156 | |
157 (define_predicate "vfp_compare_operand" | |
158 (ior (match_operand 0 "s_register_operand") | |
159 (and (match_code "const_double") | |
160 (match_test "arm_const_double_rtx (op)")))) | |
161 | |
162 (define_predicate "arm_float_compare_operand" | |
163 (if_then_else (match_test "TARGET_VFP") | |
164 (match_operand 0 "vfp_compare_operand") | |
165 (match_operand 0 "arm_float_rhs_operand"))) | |
166 | |
167 ;; True for valid index operands. | |
168 (define_predicate "index_operand" | |
169 (ior (match_operand 0 "s_register_operand") | |
170 (and (match_operand 0 "immediate_operand") | |
171 (match_test "(GET_CODE (op) != CONST_INT | |
172 || (INTVAL (op) < 4096 && INTVAL (op) > -4096))")))) | |
173 | |
174 ;; True for operators that can be combined with a shift in ARM state. | |
175 (define_special_predicate "shiftable_operator" | |
176 (and (match_code "plus,minus,ior,xor,and") | |
177 (match_test "mode == GET_MODE (op)"))) | |
178 | |
179 ;; True for logical binary operators. | |
180 (define_special_predicate "logical_binary_operator" | |
181 (and (match_code "ior,xor,and") | |
182 (match_test "mode == GET_MODE (op)"))) | |
183 | |
184 ;; True for shift operators. | |
185 (define_special_predicate "shift_operator" | |
186 (and (ior (ior (and (match_code "mult") | |
187 (match_test "power_of_two_operand (XEXP (op, 1), mode)")) | |
188 (and (match_code "rotate") | |
189 (match_test "GET_CODE (XEXP (op, 1)) == CONST_INT | |
190 && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32"))) | |
191 (match_code "ashift,ashiftrt,lshiftrt,rotatert")) | |
192 (match_test "mode == GET_MODE (op)"))) | |
193 | |
194 ;; True for operators that have 16-bit thumb variants. */ | |
195 (define_special_predicate "thumb_16bit_operator" | |
196 (match_code "plus,minus,and,ior,xor")) | |
197 | |
198 ;; True for EQ & NE | |
199 (define_special_predicate "equality_operator" | |
200 (match_code "eq,ne")) | |
201 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
202 ;; True for integer comparisons and, if FP is active, for comparisons |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
203 ;; other than LTGT or UNEQ. |
0 | 204 (define_special_predicate "arm_comparison_operator" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
205 (ior (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
206 (and (match_test "TARGET_32BIT && TARGET_HARD_FLOAT |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
207 && (TARGET_FPA || TARGET_VFP)") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
208 (match_code "unordered,ordered,unlt,unle,unge,ungt")))) |
0 | 209 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
210 (define_special_predicate "lt_ge_comparison_operator" |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
211 (match_code "lt,ge")) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
212 |
0 | 213 (define_special_predicate "minmax_operator" |
214 (and (match_code "smin,smax,umin,umax") | |
215 (match_test "mode == GET_MODE (op)"))) | |
216 | |
217 (define_special_predicate "cc_register" | |
218 (and (match_code "reg") | |
219 (and (match_test "REGNO (op) == CC_REGNUM") | |
220 (ior (match_test "mode == GET_MODE (op)") | |
221 (match_test "mode == VOIDmode && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC"))))) | |
222 | |
223 (define_special_predicate "dominant_cc_register" | |
224 (match_code "reg") | |
225 { | |
226 if (mode == VOIDmode) | |
227 { | |
228 mode = GET_MODE (op); | |
229 | |
230 if (GET_MODE_CLASS (mode) != MODE_CC) | |
231 return false; | |
232 } | |
233 | |
234 return (cc_register (op, mode) | |
235 && (mode == CC_DNEmode | |
236 || mode == CC_DEQmode | |
237 || mode == CC_DLEmode | |
238 || mode == CC_DLTmode | |
239 || mode == CC_DGEmode | |
240 || mode == CC_DGTmode | |
241 || mode == CC_DLEUmode | |
242 || mode == CC_DLTUmode | |
243 || mode == CC_DGEUmode | |
244 || mode == CC_DGTUmode)); | |
245 }) | |
246 | |
247 (define_special_predicate "arm_extendqisi_mem_op" | |
248 (and (match_operand 0 "memory_operand") | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
249 (match_test "arm_legitimate_address_outer_p (mode, XEXP (op, 0), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
250 SIGN_EXTEND, 0)"))) |
0 | 251 |
252 (define_special_predicate "arm_reg_or_extendqisi_mem_op" | |
253 (ior (match_operand 0 "arm_extendqisi_mem_op") | |
254 (match_operand 0 "s_register_operand"))) | |
255 | |
256 (define_predicate "power_of_two_operand" | |
257 (match_code "const_int") | |
258 { | |
259 HOST_WIDE_INT value = INTVAL (op); | |
260 | |
261 return value != 0 && (value & (value - 1)) == 0; | |
262 }) | |
263 | |
264 (define_predicate "nonimmediate_di_operand" | |
265 (match_code "reg,subreg,mem") | |
266 { | |
267 if (s_register_operand (op, mode)) | |
268 return true; | |
269 | |
270 if (GET_CODE (op) == SUBREG) | |
271 op = SUBREG_REG (op); | |
272 | |
273 return GET_CODE (op) == MEM && memory_address_p (DImode, XEXP (op, 0)); | |
274 }) | |
275 | |
276 (define_predicate "di_operand" | |
277 (ior (match_code "const_int,const_double") | |
278 (and (match_code "reg,subreg,mem") | |
279 (match_operand 0 "nonimmediate_di_operand")))) | |
280 | |
281 (define_predicate "nonimmediate_soft_df_operand" | |
282 (match_code "reg,subreg,mem") | |
283 { | |
284 if (s_register_operand (op, mode)) | |
285 return true; | |
286 | |
287 if (GET_CODE (op) == SUBREG) | |
288 op = SUBREG_REG (op); | |
289 | |
290 return GET_CODE (op) == MEM && memory_address_p (DFmode, XEXP (op, 0)); | |
291 }) | |
292 | |
293 (define_predicate "soft_df_operand" | |
294 (ior (match_code "const_double") | |
295 (and (match_code "reg,subreg,mem") | |
296 (match_operand 0 "nonimmediate_soft_df_operand")))) | |
297 | |
298 (define_predicate "const_shift_operand" | |
299 (and (match_code "const_int") | |
300 (ior (match_operand 0 "power_of_two_operand") | |
301 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 32")))) | |
302 | |
303 | |
304 (define_special_predicate "load_multiple_operation" | |
305 (match_code "parallel") | |
306 { | |
307 HOST_WIDE_INT count = XVECLEN (op, 0); | |
308 int dest_regno; | |
309 rtx src_addr; | |
310 HOST_WIDE_INT i = 1, base = 0; | |
311 rtx elt; | |
312 | |
313 if (count <= 1 | |
314 || GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
315 return false; | |
316 | |
317 /* Check to see if this might be a write-back. */ | |
318 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) | |
319 { | |
320 i++; | |
321 base = 1; | |
322 | |
323 /* Now check it more carefully. */ | |
324 if (GET_CODE (SET_DEST (elt)) != REG | |
325 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG | |
326 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT | |
327 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4) | |
328 return false; | |
329 } | |
330 | |
331 /* Perform a quick check so we don't blow up below. */ | |
332 if (count <= i | |
333 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET | |
334 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG | |
335 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM) | |
336 return false; | |
337 | |
338 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1))); | |
339 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0); | |
340 | |
341 for (; i < count; i++) | |
342 { | |
343 elt = XVECEXP (op, 0, i); | |
344 | |
345 if (GET_CODE (elt) != SET | |
346 || GET_CODE (SET_DEST (elt)) != REG | |
347 || GET_MODE (SET_DEST (elt)) != SImode | |
348 || REGNO (SET_DEST (elt)) != (unsigned int)(dest_regno + i - base) | |
349 || GET_CODE (SET_SRC (elt)) != MEM | |
350 || GET_MODE (SET_SRC (elt)) != SImode | |
351 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS | |
352 || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) | |
353 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT | |
354 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4) | |
355 return false; | |
356 } | |
357 | |
358 return true; | |
359 }) | |
360 | |
361 (define_special_predicate "store_multiple_operation" | |
362 (match_code "parallel") | |
363 { | |
364 HOST_WIDE_INT count = XVECLEN (op, 0); | |
365 int src_regno; | |
366 rtx dest_addr; | |
367 HOST_WIDE_INT i = 1, base = 0; | |
368 rtx elt; | |
369 | |
370 if (count <= 1 | |
371 || GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
372 return false; | |
373 | |
374 /* Check to see if this might be a write-back. */ | |
375 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) | |
376 { | |
377 i++; | |
378 base = 1; | |
379 | |
380 /* Now check it more carefully. */ | |
381 if (GET_CODE (SET_DEST (elt)) != REG | |
382 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG | |
383 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT | |
384 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4) | |
385 return false; | |
386 } | |
387 | |
388 /* Perform a quick check so we don't blow up below. */ | |
389 if (count <= i | |
390 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET | |
391 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM | |
392 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG) | |
393 return false; | |
394 | |
395 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1))); | |
396 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0); | |
397 | |
398 for (; i < count; i++) | |
399 { | |
400 elt = XVECEXP (op, 0, i); | |
401 | |
402 if (GET_CODE (elt) != SET | |
403 || GET_CODE (SET_SRC (elt)) != REG | |
404 || GET_MODE (SET_SRC (elt)) != SImode | |
405 || REGNO (SET_SRC (elt)) != (unsigned int)(src_regno + i - base) | |
406 || GET_CODE (SET_DEST (elt)) != MEM | |
407 || GET_MODE (SET_DEST (elt)) != SImode | |
408 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS | |
409 || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) | |
410 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT | |
411 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4) | |
412 return false; | |
413 } | |
414 | |
415 return true; | |
416 }) | |
417 | |
418 (define_special_predicate "multi_register_push" | |
419 (match_code "parallel") | |
420 { | |
421 if ((GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
422 || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC) | |
423 || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT)) | |
424 return false; | |
425 | |
426 return true; | |
427 }) | |
428 | |
429 ;;------------------------------------------------------------------------- | |
430 ;; | |
431 ;; Thumb predicates | |
432 ;; | |
433 | |
434 (define_predicate "thumb1_cmp_operand" | |
435 (ior (and (match_code "reg,subreg") | |
436 (match_operand 0 "s_register_operand")) | |
437 (and (match_code "const_int") | |
438 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 256")))) | |
439 | |
440 (define_predicate "thumb1_cmpneg_operand" | |
441 (and (match_code "const_int") | |
442 (match_test "INTVAL (op) < 0 && INTVAL (op) > -256"))) | |
443 | |
444 ;; Return TRUE if a result can be stored in OP without clobbering the | |
445 ;; condition code register. Prior to reload we only accept a | |
446 ;; register. After reload we have to be able to handle memory as | |
447 ;; well, since a pseudo may not get a hard reg and reload cannot | |
448 ;; handle output-reloads on jump insns. | |
449 | |
450 ;; We could possibly handle mem before reload as well, but that might | |
451 ;; complicate things with the need to handle increment | |
452 ;; side-effects. | |
453 (define_predicate "thumb_cbrch_target_operand" | |
454 (and (match_code "reg,subreg,mem") | |
455 (ior (match_operand 0 "s_register_operand") | |
456 (and (match_test "reload_in_progress || reload_completed") | |
457 (match_operand 0 "memory_operand"))))) | |
458 | |
459 ;;------------------------------------------------------------------------- | |
460 ;; | |
461 ;; MAVERICK predicates | |
462 ;; | |
463 | |
464 (define_predicate "cirrus_register_operand" | |
465 (match_code "reg,subreg") | |
466 { | |
467 if (GET_CODE (op) == SUBREG) | |
468 op = SUBREG_REG (op); | |
469 | |
470 return (GET_CODE (op) == REG | |
471 && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS | |
472 || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS)); | |
473 }) | |
474 | |
475 (define_predicate "cirrus_fp_register" | |
476 (match_code "reg,subreg") | |
477 { | |
478 if (GET_CODE (op) == SUBREG) | |
479 op = SUBREG_REG (op); | |
480 | |
481 return (GET_CODE (op) == REG | |
482 && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
483 || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS)); | |
484 }) | |
485 | |
486 (define_predicate "cirrus_shift_const" | |
487 (and (match_code "const_int") | |
488 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64"))) | |
489 | |
490 | |
491 ;; Neon predicates | |
492 | |
493 (define_predicate "const_multiple_of_8_operand" | |
494 (match_code "const_int") | |
495 { | |
496 unsigned HOST_WIDE_INT val = INTVAL (op); | |
497 return (val & 7) == 0; | |
498 }) | |
499 | |
500 (define_predicate "imm_for_neon_mov_operand" | |
501 (match_code "const_vector") | |
502 { | |
503 return neon_immediate_valid_for_move (op, mode, NULL, NULL); | |
504 }) | |
505 | |
506 (define_predicate "imm_for_neon_logic_operand" | |
507 (match_code "const_vector") | |
508 { | |
509 return neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL); | |
510 }) | |
511 | |
512 (define_predicate "imm_for_neon_inv_logic_operand" | |
513 (match_code "const_vector") | |
514 { | |
515 return neon_immediate_valid_for_logic (op, mode, 1, NULL, NULL); | |
516 }) | |
517 | |
518 (define_predicate "neon_logic_op2" | |
519 (ior (match_operand 0 "imm_for_neon_logic_operand") | |
520 (match_operand 0 "s_register_operand"))) | |
521 | |
522 (define_predicate "neon_inv_logic_op2" | |
523 (ior (match_operand 0 "imm_for_neon_inv_logic_operand") | |
524 (match_operand 0 "s_register_operand"))) | |
525 | |
526 ;; TODO: We could check lane numbers more precisely based on the mode. | |
527 (define_predicate "neon_lane_number" | |
528 (and (match_code "const_int") | |
529 (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 7"))) | |
530 |