1 ;; Predicate definitions for ARM and Thumb
2 ;; Copyright (C) 2004 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
5 ;; This file is part of GCC.
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 2, or (at your
10 ;; option) any later version.
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.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 ;; Boston, MA 02110-1301, USA.
22 (define_predicate "s_register_operand"
23 (match_code "reg,subreg")
25 if (GET_CODE (op) == SUBREG)
27 /* We don't consider registers whose class is NO_REGS
28 to be a register operand. */
29 /* XXX might have to check for lo regs only for thumb ??? */
30 return (GET_CODE (op) == REG
31 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
32 || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
36 (define_predicate "arm_hard_register_operand"
39 return REGNO (op) < FIRST_PSEUDO_REGISTER;
42 ;; Any core register, or any pseudo. */
43 (define_predicate "arm_general_register_operand"
44 (match_code "reg,subreg")
46 if (GET_CODE (op) == SUBREG)
49 return (GET_CODE (op) == REG
50 && (REGNO (op) <= LAST_ARM_REGNUM
51 || REGNO (op) >= FIRST_PSEUDO_REGISTER));
54 (define_predicate "f_register_operand"
55 (match_code "reg,subreg")
57 if (GET_CODE (op) == SUBREG)
60 /* We don't consider registers whose class is NO_REGS
61 to be a register operand. */
62 return (GET_CODE (op) == REG
63 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
64 || REGNO_REG_CLASS (REGNO (op)) == FPA_REGS));
67 ;; Reg, subreg(reg) or const_int.
68 (define_predicate "reg_or_int_operand"
69 (ior (match_code "const_int")
70 (match_operand 0 "s_register_operand")))
72 (define_predicate "arm_immediate_operand"
73 (and (match_code "const_int")
74 (match_test "const_ok_for_arm (INTVAL (op))")))
76 (define_predicate "arm_neg_immediate_operand"
77 (and (match_code "const_int")
78 (match_test "const_ok_for_arm (-INTVAL (op))")))
80 (define_predicate "arm_not_immediate_operand"
81 (and (match_code "const_int")
82 (match_test "const_ok_for_arm (~INTVAL (op))")))
84 ;; Something valid on the RHS of an ARM data-processing instruction
85 (define_predicate "arm_rhs_operand"
86 (ior (match_operand 0 "s_register_operand")
87 (match_operand 0 "arm_immediate_operand")))
89 (define_predicate "arm_rhsm_operand"
90 (ior (match_operand 0 "arm_rhs_operand")
91 (match_operand 0 "memory_operand")))
93 (define_predicate "arm_add_operand"
94 (ior (match_operand 0 "arm_rhs_operand")
95 (match_operand 0 "arm_neg_immediate_operand")))
97 (define_predicate "arm_addimm_operand"
98 (ior (match_operand 0 "arm_immediate_operand")
99 (match_operand 0 "arm_neg_immediate_operand")))
101 (define_predicate "arm_not_operand"
102 (ior (match_operand 0 "arm_rhs_operand")
103 (match_operand 0 "arm_not_immediate_operand")))
105 ;; True if the operand is a memory reference which contains an
106 ;; offsettable address.
107 (define_predicate "offsettable_memory_operand"
108 (and (match_code "mem")
110 "offsettable_address_p (reload_completed | reload_in_progress,
111 mode, XEXP (op, 0))")))
113 (define_predicate "arm_reload_memory_operand"
114 (and (match_code "mem,reg,subreg")
115 (match_test "(!CONSTANT_P (op)
116 && (true_regnum(op) == -1
117 || (GET_CODE (op) == REG
118 && REGNO (op) >= FIRST_PSEUDO_REGISTER)))")))
120 ;; True for valid operands for the rhs of an floating point insns.
121 ;; Allows regs or certain consts on FPA, just regs for everything else.
122 (define_predicate "arm_float_rhs_operand"
123 (ior (match_operand 0 "s_register_operand")
124 (and (match_code "const_double")
125 (match_test "TARGET_FPA && arm_const_double_rtx (op)"))))
127 (define_predicate "arm_float_add_operand"
128 (ior (match_operand 0 "arm_float_rhs_operand")
129 (and (match_code "const_double")
130 (match_test "TARGET_FPA && neg_const_double_rtx_ok_for_fpa (op)"))))
132 (define_predicate "vfp_compare_operand"
133 (ior (match_operand 0 "s_register_operand")
134 (and (match_code "const_double")
135 (match_test "arm_const_double_rtx (op)"))))
137 (define_predicate "arm_float_compare_operand"
138 (if_then_else (match_test "TARGET_VFP")
139 (match_operand 0 "vfp_compare_operand")
140 (match_operand 0 "arm_float_rhs_operand")))
142 ;; True for valid index operands.
143 (define_predicate "index_operand"
144 (ior (match_operand 0 "s_register_operand")
145 (and (match_operand 0 "immediate_operand")
146 (match_test "(GET_CODE (op) != CONST_INT
147 || (INTVAL (op) < 4096 && INTVAL (op) > -4096))"))))
149 ;; True for operators that can be combined with a shift in ARM state.
150 (define_special_predicate "shiftable_operator"
151 (and (match_code "plus,minus,ior,xor,and")
152 (match_test "mode == GET_MODE (op)")))
154 ;; True for logical binary operators.
155 (define_special_predicate "logical_binary_operator"
156 (and (match_code "ior,xor,and")
157 (match_test "mode == GET_MODE (op)")))
159 ;; True for shift operators.
160 (define_special_predicate "shift_operator"
161 (and (ior (ior (and (match_code "mult")
162 (match_test "power_of_two_operand (XEXP (op, 1), mode)"))
163 (and (match_code "rotate")
164 (match_test "GET_CODE (XEXP (op, 1)) == CONST_INT
165 && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32")))
166 (match_code "ashift,ashiftrt,lshiftrt,rotatert"))
167 (match_test "mode == GET_MODE (op)")))
170 (define_special_predicate "equality_operator"
171 (match_code "eq,ne"))
173 ;; True for comparisons other than LTGT or UNEQ.
174 (define_special_predicate "arm_comparison_operator"
175 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt"))
177 (define_special_predicate "minmax_operator"
178 (and (match_code "smin,smax,umin,umax")
179 (match_test "mode == GET_MODE (op)")))
181 (define_special_predicate "cc_register"
182 (and (match_code "reg")
183 (and (match_test "REGNO (op) == CC_REGNUM")
184 (ior (match_test "mode == GET_MODE (op)")
185 (match_test "mode == VOIDmode && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC")))))
187 (define_special_predicate "dominant_cc_register"
190 if (mode == VOIDmode)
192 mode = GET_MODE (op);
194 if (GET_MODE_CLASS (mode) != MODE_CC)
198 return (cc_register (op, mode)
199 && (mode == CC_DNEmode
200 || mode == CC_DEQmode
201 || mode == CC_DLEmode
202 || mode == CC_DLTmode
203 || mode == CC_DGEmode
204 || mode == CC_DGTmode
205 || mode == CC_DLEUmode
206 || mode == CC_DLTUmode
207 || mode == CC_DGEUmode
208 || mode == CC_DGTUmode));
211 (define_special_predicate "arm_extendqisi_mem_op"
212 (and (match_operand 0 "memory_operand")
213 (match_test "arm_legitimate_address_p (mode, XEXP (op, 0), SIGN_EXTEND,
216 (define_predicate "power_of_two_operand"
217 (match_code "const_int")
219 HOST_WIDE_INT value = INTVAL (op);
221 return value != 0 && (value & (value - 1)) == 0;
224 (define_predicate "nonimmediate_di_operand"
225 (match_code "reg,subreg,mem")
227 if (s_register_operand (op, mode))
230 if (GET_CODE (op) == SUBREG)
231 op = SUBREG_REG (op);
233 return GET_CODE (op) == MEM && memory_address_p (DImode, XEXP (op, 0));
236 (define_predicate "di_operand"
237 (ior (match_code "const_int,const_double")
238 (and (match_code "reg,subreg,mem")
239 (match_operand 0 "nonimmediate_di_operand"))))
241 (define_predicate "nonimmediate_soft_df_operand"
242 (match_code "reg,subreg,mem")
244 if (s_register_operand (op, mode))
247 if (GET_CODE (op) == SUBREG)
248 op = SUBREG_REG (op);
250 return GET_CODE (op) == MEM && memory_address_p (DFmode, XEXP (op, 0));
253 (define_predicate "soft_df_operand"
254 (ior (match_code "const_double")
255 (and (match_code "reg,subreg,mem")
256 (match_operand 0 "nonimmediate_soft_df_operand"))))
258 (define_predicate "const_shift_operand"
259 (and (match_code "const_int")
260 (ior (match_operand 0 "power_of_two_operand")
261 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 32"))))
264 (define_special_predicate "load_multiple_operation"
265 (match_code "parallel")
267 HOST_WIDE_INT count = XVECLEN (op, 0);
270 HOST_WIDE_INT i = 1, base = 0;
274 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
277 /* Check to see if this might be a write-back. */
278 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
283 /* Now check it more carefully. */
284 if (GET_CODE (SET_DEST (elt)) != REG
285 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
286 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
287 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
291 /* Perform a quick check so we don't blow up below. */
293 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
294 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG
295 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM)
298 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));
299 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);
301 for (; i < count; i++)
303 elt = XVECEXP (op, 0, i);
305 if (GET_CODE (elt) != SET
306 || GET_CODE (SET_DEST (elt)) != REG
307 || GET_MODE (SET_DEST (elt)) != SImode
308 || REGNO (SET_DEST (elt)) != (unsigned int)(dest_regno + i - base)
309 || GET_CODE (SET_SRC (elt)) != MEM
310 || GET_MODE (SET_SRC (elt)) != SImode
311 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
312 || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
313 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
314 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4)
321 (define_special_predicate "store_multiple_operation"
322 (match_code "parallel")
324 HOST_WIDE_INT count = XVECLEN (op, 0);
327 HOST_WIDE_INT i = 1, base = 0;
331 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
334 /* Check to see if this might be a write-back. */
335 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
340 /* Now check it more carefully. */
341 if (GET_CODE (SET_DEST (elt)) != REG
342 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
343 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
344 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
348 /* Perform a quick check so we don't blow up below. */
350 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
351 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM
352 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG)
355 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));
356 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);
358 for (; i < count; i++)
360 elt = XVECEXP (op, 0, i);
362 if (GET_CODE (elt) != SET
363 || GET_CODE (SET_SRC (elt)) != REG
364 || GET_MODE (SET_SRC (elt)) != SImode
365 || REGNO (SET_SRC (elt)) != (unsigned int)(src_regno + i - base)
366 || GET_CODE (SET_DEST (elt)) != MEM
367 || GET_MODE (SET_DEST (elt)) != SImode
368 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
369 || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
370 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
371 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4)
378 (define_special_predicate "multi_register_push"
379 (match_code "parallel")
381 if ((GET_CODE (XVECEXP (op, 0, 0)) != SET)
382 || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC)
383 || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT))
389 ;;-------------------------------------------------------------------------
394 (define_predicate "thumb_cmp_operand"
395 (ior (and (match_code "reg,subreg")
396 (match_operand 0 "s_register_operand"))
397 (and (match_code "const_int")
398 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 256"))))
400 (define_predicate "thumb_cmpneg_operand"
401 (and (match_code "const_int")
402 (match_test "INTVAL (op) < 0 && INTVAL (op) > -256")))
404 ;; Return TRUE if a result can be stored in OP without clobbering the
405 ;; condition code register. Prior to reload we only accept a
406 ;; register. After reload we have to be able to handle memory as
407 ;; well, since a pseudo may not get a hard reg and reload cannot
408 ;; handle output-reloads on jump insns.
410 ;; We could possibly handle mem before reload as well, but that might
411 ;; complicate things with the need to handle increment
413 (define_predicate "thumb_cbrch_target_operand"
414 (and (match_code "reg,subreg,mem")
415 (ior (match_operand 0 "s_register_operand")
416 (and (match_test "reload_in_progress || reload_completed")
417 (match_operand 0 "memory_operand")))))
419 ;;-------------------------------------------------------------------------
421 ;; MAVERICK predicates
424 (define_predicate "cirrus_register_operand"
425 (match_code "reg,subreg")
427 if (GET_CODE (op) == SUBREG)
428 op = SUBREG_REG (op);
430 return (GET_CODE (op) == REG
431 && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS
432 || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS));
435 (define_predicate "cirrus_fp_register"
436 (match_code "reg,subreg")
438 if (GET_CODE (op) == SUBREG)
439 op = SUBREG_REG (op);
441 return (GET_CODE (op) == REG
442 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
443 || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS));
446 (define_predicate "cirrus_shift_const"
447 (and (match_code "const_int")
448 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64")))