Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/arm/predicates.md @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 77e2b8dfacca |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
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 | |
76 ;; Reg, subreg(reg) or const_int. | |
77 (define_predicate "reg_or_int_operand" | |
78 (ior (match_code "const_int") | |
79 (match_operand 0 "s_register_operand"))) | |
80 | |
81 (define_predicate "arm_immediate_operand" | |
82 (and (match_code "const_int") | |
83 (match_test "const_ok_for_arm (INTVAL (op))"))) | |
84 | |
85 (define_predicate "arm_neg_immediate_operand" | |
86 (and (match_code "const_int") | |
87 (match_test "const_ok_for_arm (-INTVAL (op))"))) | |
88 | |
89 (define_predicate "arm_not_immediate_operand" | |
90 (and (match_code "const_int") | |
91 (match_test "const_ok_for_arm (~INTVAL (op))"))) | |
92 | |
93 ;; Something valid on the RHS of an ARM data-processing instruction | |
94 (define_predicate "arm_rhs_operand" | |
95 (ior (match_operand 0 "s_register_operand") | |
96 (match_operand 0 "arm_immediate_operand"))) | |
97 | |
98 (define_predicate "arm_rhsm_operand" | |
99 (ior (match_operand 0 "arm_rhs_operand") | |
100 (match_operand 0 "memory_operand"))) | |
101 | |
102 (define_predicate "arm_add_operand" | |
103 (ior (match_operand 0 "arm_rhs_operand") | |
104 (match_operand 0 "arm_neg_immediate_operand"))) | |
105 | |
106 (define_predicate "arm_addimm_operand" | |
107 (ior (match_operand 0 "arm_immediate_operand") | |
108 (match_operand 0 "arm_neg_immediate_operand"))) | |
109 | |
110 (define_predicate "arm_not_operand" | |
111 (ior (match_operand 0 "arm_rhs_operand") | |
112 (match_operand 0 "arm_not_immediate_operand"))) | |
113 | |
114 ;; True if the operand is a memory reference which contains an | |
115 ;; offsettable address. | |
116 (define_predicate "offsettable_memory_operand" | |
117 (and (match_code "mem") | |
118 (match_test | |
119 "offsettable_address_p (reload_completed | reload_in_progress, | |
120 mode, XEXP (op, 0))"))) | |
121 | |
122 ;; True if the operand is a memory operand that does not have an | |
123 ;; automodified base register (and thus will not generate output reloads). | |
124 (define_predicate "call_memory_operand" | |
125 (and (match_code "mem") | |
126 (and (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) | |
127 != RTX_AUTOINC") | |
128 (match_operand 0 "memory_operand")))) | |
129 | |
130 (define_predicate "arm_reload_memory_operand" | |
131 (and (match_code "mem,reg,subreg") | |
132 (match_test "(!CONSTANT_P (op) | |
133 && (true_regnum(op) == -1 | |
134 || (GET_CODE (op) == REG | |
135 && REGNO (op) >= FIRST_PSEUDO_REGISTER)))"))) | |
136 | |
137 ;; True for valid operands for the rhs of an floating point insns. | |
138 ;; Allows regs or certain consts on FPA, just regs for everything else. | |
139 (define_predicate "arm_float_rhs_operand" | |
140 (ior (match_operand 0 "s_register_operand") | |
141 (and (match_code "const_double") | |
142 (match_test "TARGET_FPA && arm_const_double_rtx (op)")))) | |
143 | |
144 (define_predicate "arm_float_add_operand" | |
145 (ior (match_operand 0 "arm_float_rhs_operand") | |
146 (and (match_code "const_double") | |
147 (match_test "TARGET_FPA && neg_const_double_rtx_ok_for_fpa (op)")))) | |
148 | |
149 (define_predicate "vfp_compare_operand" | |
150 (ior (match_operand 0 "s_register_operand") | |
151 (and (match_code "const_double") | |
152 (match_test "arm_const_double_rtx (op)")))) | |
153 | |
154 (define_predicate "arm_float_compare_operand" | |
155 (if_then_else (match_test "TARGET_VFP") | |
156 (match_operand 0 "vfp_compare_operand") | |
157 (match_operand 0 "arm_float_rhs_operand"))) | |
158 | |
159 ;; True for valid index operands. | |
160 (define_predicate "index_operand" | |
161 (ior (match_operand 0 "s_register_operand") | |
162 (and (match_operand 0 "immediate_operand") | |
163 (match_test "(GET_CODE (op) != CONST_INT | |
164 || (INTVAL (op) < 4096 && INTVAL (op) > -4096))")))) | |
165 | |
166 ;; True for operators that can be combined with a shift in ARM state. | |
167 (define_special_predicate "shiftable_operator" | |
168 (and (match_code "plus,minus,ior,xor,and") | |
169 (match_test "mode == GET_MODE (op)"))) | |
170 | |
171 ;; True for logical binary operators. | |
172 (define_special_predicate "logical_binary_operator" | |
173 (and (match_code "ior,xor,and") | |
174 (match_test "mode == GET_MODE (op)"))) | |
175 | |
176 ;; True for shift operators. | |
177 (define_special_predicate "shift_operator" | |
178 (and (ior (ior (and (match_code "mult") | |
179 (match_test "power_of_two_operand (XEXP (op, 1), mode)")) | |
180 (and (match_code "rotate") | |
181 (match_test "GET_CODE (XEXP (op, 1)) == CONST_INT | |
182 && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32"))) | |
183 (match_code "ashift,ashiftrt,lshiftrt,rotatert")) | |
184 (match_test "mode == GET_MODE (op)"))) | |
185 | |
186 ;; True for operators that have 16-bit thumb variants. */ | |
187 (define_special_predicate "thumb_16bit_operator" | |
188 (match_code "plus,minus,and,ior,xor")) | |
189 | |
190 ;; True for EQ & NE | |
191 (define_special_predicate "equality_operator" | |
192 (match_code "eq,ne")) | |
193 | |
194 ;; True for comparisons other than LTGT or UNEQ. | |
195 (define_special_predicate "arm_comparison_operator" | |
196 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt")) | |
197 | |
198 (define_special_predicate "minmax_operator" | |
199 (and (match_code "smin,smax,umin,umax") | |
200 (match_test "mode == GET_MODE (op)"))) | |
201 | |
202 (define_special_predicate "cc_register" | |
203 (and (match_code "reg") | |
204 (and (match_test "REGNO (op) == CC_REGNUM") | |
205 (ior (match_test "mode == GET_MODE (op)") | |
206 (match_test "mode == VOIDmode && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC"))))) | |
207 | |
208 (define_special_predicate "dominant_cc_register" | |
209 (match_code "reg") | |
210 { | |
211 if (mode == VOIDmode) | |
212 { | |
213 mode = GET_MODE (op); | |
214 | |
215 if (GET_MODE_CLASS (mode) != MODE_CC) | |
216 return false; | |
217 } | |
218 | |
219 return (cc_register (op, mode) | |
220 && (mode == CC_DNEmode | |
221 || mode == CC_DEQmode | |
222 || mode == CC_DLEmode | |
223 || mode == CC_DLTmode | |
224 || mode == CC_DGEmode | |
225 || mode == CC_DGTmode | |
226 || mode == CC_DLEUmode | |
227 || mode == CC_DLTUmode | |
228 || mode == CC_DGEUmode | |
229 || mode == CC_DGTUmode)); | |
230 }) | |
231 | |
232 (define_special_predicate "arm_extendqisi_mem_op" | |
233 (and (match_operand 0 "memory_operand") | |
234 (match_test "arm_legitimate_address_p (mode, XEXP (op, 0), SIGN_EXTEND, | |
235 0)"))) | |
236 | |
237 (define_special_predicate "arm_reg_or_extendqisi_mem_op" | |
238 (ior (match_operand 0 "arm_extendqisi_mem_op") | |
239 (match_operand 0 "s_register_operand"))) | |
240 | |
241 (define_predicate "power_of_two_operand" | |
242 (match_code "const_int") | |
243 { | |
244 HOST_WIDE_INT value = INTVAL (op); | |
245 | |
246 return value != 0 && (value & (value - 1)) == 0; | |
247 }) | |
248 | |
249 (define_predicate "nonimmediate_di_operand" | |
250 (match_code "reg,subreg,mem") | |
251 { | |
252 if (s_register_operand (op, mode)) | |
253 return true; | |
254 | |
255 if (GET_CODE (op) == SUBREG) | |
256 op = SUBREG_REG (op); | |
257 | |
258 return GET_CODE (op) == MEM && memory_address_p (DImode, XEXP (op, 0)); | |
259 }) | |
260 | |
261 (define_predicate "di_operand" | |
262 (ior (match_code "const_int,const_double") | |
263 (and (match_code "reg,subreg,mem") | |
264 (match_operand 0 "nonimmediate_di_operand")))) | |
265 | |
266 (define_predicate "nonimmediate_soft_df_operand" | |
267 (match_code "reg,subreg,mem") | |
268 { | |
269 if (s_register_operand (op, mode)) | |
270 return true; | |
271 | |
272 if (GET_CODE (op) == SUBREG) | |
273 op = SUBREG_REG (op); | |
274 | |
275 return GET_CODE (op) == MEM && memory_address_p (DFmode, XEXP (op, 0)); | |
276 }) | |
277 | |
278 (define_predicate "soft_df_operand" | |
279 (ior (match_code "const_double") | |
280 (and (match_code "reg,subreg,mem") | |
281 (match_operand 0 "nonimmediate_soft_df_operand")))) | |
282 | |
283 (define_predicate "const_shift_operand" | |
284 (and (match_code "const_int") | |
285 (ior (match_operand 0 "power_of_two_operand") | |
286 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 32")))) | |
287 | |
288 | |
289 (define_special_predicate "load_multiple_operation" | |
290 (match_code "parallel") | |
291 { | |
292 HOST_WIDE_INT count = XVECLEN (op, 0); | |
293 int dest_regno; | |
294 rtx src_addr; | |
295 HOST_WIDE_INT i = 1, base = 0; | |
296 rtx elt; | |
297 | |
298 if (count <= 1 | |
299 || GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
300 return false; | |
301 | |
302 /* Check to see if this might be a write-back. */ | |
303 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) | |
304 { | |
305 i++; | |
306 base = 1; | |
307 | |
308 /* Now check it more carefully. */ | |
309 if (GET_CODE (SET_DEST (elt)) != REG | |
310 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG | |
311 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT | |
312 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4) | |
313 return false; | |
314 } | |
315 | |
316 /* Perform a quick check so we don't blow up below. */ | |
317 if (count <= i | |
318 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET | |
319 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG | |
320 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM) | |
321 return false; | |
322 | |
323 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1))); | |
324 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0); | |
325 | |
326 for (; i < count; i++) | |
327 { | |
328 elt = XVECEXP (op, 0, i); | |
329 | |
330 if (GET_CODE (elt) != SET | |
331 || GET_CODE (SET_DEST (elt)) != REG | |
332 || GET_MODE (SET_DEST (elt)) != SImode | |
333 || REGNO (SET_DEST (elt)) != (unsigned int)(dest_regno + i - base) | |
334 || GET_CODE (SET_SRC (elt)) != MEM | |
335 || GET_MODE (SET_SRC (elt)) != SImode | |
336 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS | |
337 || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) | |
338 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT | |
339 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4) | |
340 return false; | |
341 } | |
342 | |
343 return true; | |
344 }) | |
345 | |
346 (define_special_predicate "store_multiple_operation" | |
347 (match_code "parallel") | |
348 { | |
349 HOST_WIDE_INT count = XVECLEN (op, 0); | |
350 int src_regno; | |
351 rtx dest_addr; | |
352 HOST_WIDE_INT i = 1, base = 0; | |
353 rtx elt; | |
354 | |
355 if (count <= 1 | |
356 || GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
357 return false; | |
358 | |
359 /* Check to see if this might be a write-back. */ | |
360 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) | |
361 { | |
362 i++; | |
363 base = 1; | |
364 | |
365 /* Now check it more carefully. */ | |
366 if (GET_CODE (SET_DEST (elt)) != REG | |
367 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG | |
368 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT | |
369 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4) | |
370 return false; | |
371 } | |
372 | |
373 /* Perform a quick check so we don't blow up below. */ | |
374 if (count <= i | |
375 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET | |
376 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM | |
377 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG) | |
378 return false; | |
379 | |
380 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1))); | |
381 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0); | |
382 | |
383 for (; i < count; i++) | |
384 { | |
385 elt = XVECEXP (op, 0, i); | |
386 | |
387 if (GET_CODE (elt) != SET | |
388 || GET_CODE (SET_SRC (elt)) != REG | |
389 || GET_MODE (SET_SRC (elt)) != SImode | |
390 || REGNO (SET_SRC (elt)) != (unsigned int)(src_regno + i - base) | |
391 || GET_CODE (SET_DEST (elt)) != MEM | |
392 || GET_MODE (SET_DEST (elt)) != SImode | |
393 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS | |
394 || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) | |
395 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT | |
396 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4) | |
397 return false; | |
398 } | |
399 | |
400 return true; | |
401 }) | |
402 | |
403 (define_special_predicate "multi_register_push" | |
404 (match_code "parallel") | |
405 { | |
406 if ((GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
407 || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC) | |
408 || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT)) | |
409 return false; | |
410 | |
411 return true; | |
412 }) | |
413 | |
414 ;;------------------------------------------------------------------------- | |
415 ;; | |
416 ;; Thumb predicates | |
417 ;; | |
418 | |
419 (define_predicate "thumb1_cmp_operand" | |
420 (ior (and (match_code "reg,subreg") | |
421 (match_operand 0 "s_register_operand")) | |
422 (and (match_code "const_int") | |
423 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 256")))) | |
424 | |
425 (define_predicate "thumb1_cmpneg_operand" | |
426 (and (match_code "const_int") | |
427 (match_test "INTVAL (op) < 0 && INTVAL (op) > -256"))) | |
428 | |
429 ;; Return TRUE if a result can be stored in OP without clobbering the | |
430 ;; condition code register. Prior to reload we only accept a | |
431 ;; register. After reload we have to be able to handle memory as | |
432 ;; well, since a pseudo may not get a hard reg and reload cannot | |
433 ;; handle output-reloads on jump insns. | |
434 | |
435 ;; We could possibly handle mem before reload as well, but that might | |
436 ;; complicate things with the need to handle increment | |
437 ;; side-effects. | |
438 (define_predicate "thumb_cbrch_target_operand" | |
439 (and (match_code "reg,subreg,mem") | |
440 (ior (match_operand 0 "s_register_operand") | |
441 (and (match_test "reload_in_progress || reload_completed") | |
442 (match_operand 0 "memory_operand"))))) | |
443 | |
444 ;;------------------------------------------------------------------------- | |
445 ;; | |
446 ;; MAVERICK predicates | |
447 ;; | |
448 | |
449 (define_predicate "cirrus_register_operand" | |
450 (match_code "reg,subreg") | |
451 { | |
452 if (GET_CODE (op) == SUBREG) | |
453 op = SUBREG_REG (op); | |
454 | |
455 return (GET_CODE (op) == REG | |
456 && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS | |
457 || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS)); | |
458 }) | |
459 | |
460 (define_predicate "cirrus_fp_register" | |
461 (match_code "reg,subreg") | |
462 { | |
463 if (GET_CODE (op) == SUBREG) | |
464 op = SUBREG_REG (op); | |
465 | |
466 return (GET_CODE (op) == REG | |
467 && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
468 || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS)); | |
469 }) | |
470 | |
471 (define_predicate "cirrus_shift_const" | |
472 (and (match_code "const_int") | |
473 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64"))) | |
474 | |
475 | |
476 ;; Neon predicates | |
477 | |
478 (define_predicate "const_multiple_of_8_operand" | |
479 (match_code "const_int") | |
480 { | |
481 unsigned HOST_WIDE_INT val = INTVAL (op); | |
482 return (val & 7) == 0; | |
483 }) | |
484 | |
485 (define_predicate "imm_for_neon_mov_operand" | |
486 (match_code "const_vector") | |
487 { | |
488 return neon_immediate_valid_for_move (op, mode, NULL, NULL); | |
489 }) | |
490 | |
491 (define_predicate "imm_for_neon_logic_operand" | |
492 (match_code "const_vector") | |
493 { | |
494 return neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL); | |
495 }) | |
496 | |
497 (define_predicate "imm_for_neon_inv_logic_operand" | |
498 (match_code "const_vector") | |
499 { | |
500 return neon_immediate_valid_for_logic (op, mode, 1, NULL, NULL); | |
501 }) | |
502 | |
503 (define_predicate "neon_logic_op2" | |
504 (ior (match_operand 0 "imm_for_neon_logic_operand") | |
505 (match_operand 0 "s_register_operand"))) | |
506 | |
507 (define_predicate "neon_inv_logic_op2" | |
508 (ior (match_operand 0 "imm_for_neon_inv_logic_operand") | |
509 (match_operand 0 "s_register_operand"))) | |
510 | |
511 ;; TODO: We could check lane numbers more precisely based on the mode. | |
512 (define_predicate "neon_lane_number" | |
513 (and (match_code "const_int") | |
514 (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 7"))) | |
515 |