]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/predicates.md
* arm.md: Include predicates.md.
[thirdparty/gcc.git] / gcc / config / arm / predicates.md
1 ;; Predicate definitions for ARM and Thumb
2 ;; Copyright (C) 2004 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 2, 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 COPYING. If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22 (define_predicate "s_register_operand"
23 (match_code "reg,subreg")
24 {
25 if (GET_CODE (op) == SUBREG)
26 op = SUBREG_REG (op);
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));
33 })
34
35 ;; Any hard register.
36 (define_predicate "arm_hard_register_operand"
37 (match_code "reg")
38 {
39 return REGNO (op) < FIRST_PSEUDO_REGISTER;
40 })
41
42 ;; Any core register, or any pseudo. */
43 (define_predicate "arm_general_register_operand"
44 (match_code "reg,subreg")
45 {
46 if (GET_CODE (op) == SUBREG)
47 op = SUBREG_REG (op);
48
49 return (GET_CODE (op) == REG
50 && (REGNO (op) <= LAST_ARM_REGNUM
51 || REGNO (op) >= FIRST_PSEUDO_REGISTER));
52 })
53
54 (define_predicate "f_register_operand"
55 (match_code "reg,subreg")
56 {
57 if (GET_CODE (op) == SUBREG)
58 op = SUBREG_REG (op);
59
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));
65 })
66
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")))
71
72 (define_predicate "arm_immediate_operand"
73 (and (match_code "const_int")
74 (match_test "const_ok_for_arm (INTVAL (op))")))
75
76 (define_predicate "arm_neg_immediate_operand"
77 (and (match_code "const_int")
78 (match_test "const_ok_for_arm (-INTVAL (op))")))
79
80 (define_predicate "arm_not_immediate_operand"
81 (and (match_code "const_int")
82 (match_test "const_ok_for_arm (~INTVAL (op))")))
83
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")))
88
89 (define_predicate "arm_rhsm_operand"
90 (ior (match_operand 0 "arm_rhs_operand")
91 (match_operand 0 "memory_operand")))
92
93 (define_predicate "arm_add_operand"
94 (ior (match_operand 0 "arm_rhs_operand")
95 (match_operand 0 "arm_neg_immediate_operand")))
96
97 (define_predicate "arm_addimm_operand"
98 (ior (match_operand 0 "arm_immediate_operand")
99 (match_operand 0 "arm_neg_immediate_operand")))
100
101 (define_predicate "arm_not_operand"
102 (ior (match_operand 0 "arm_rhs_operand")
103 (match_operand 0 "arm_not_immediate_operand")))
104
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")
109 (match_test
110 "offsettable_address_p (reload_completed | reload_in_progress,
111 mode, XEXP (op, 0))")))
112
113 ;; True if the operand is a memory reference which is, or can be made,
114 ;; word aligned by adjusting the offset.
115 (define_predicate "alignable_memory_operand"
116 (match_code "mem")
117 {
118 rtx reg;
119
120 op = XEXP (op, 0);
121
122 return ((GET_CODE (reg = op) == REG
123 || (GET_CODE (op) == SUBREG
124 && GET_CODE (reg = SUBREG_REG (op)) == REG)
125 || (GET_CODE (op) == PLUS
126 && GET_CODE (XEXP (op, 1)) == CONST_INT
127 && (GET_CODE (reg = XEXP (op, 0)) == REG
128 || (GET_CODE (XEXP (op, 0)) == SUBREG
129 && GET_CODE (reg = SUBREG_REG (XEXP (op, 0))) == REG))))
130 && REGNO_POINTER_ALIGN (REGNO (reg)) >= 32);
131 })
132
133 (define_predicate "arm_reload_memory_operand"
134 (and (match_code "reg,subreg")
135 (match_test "(!CONSTANT_P (op)
136 && (true_regnum(op) == -1
137 || (GET_CODE (op) == REG
138 && REGNO (op) >= FIRST_PSEUDO_REGISTER)))")))
139
140 ;; True for valid operands for the rhs of an floating point insns.
141 ;; Allows regs or certain consts on FPA, just regs for everything else.
142 (define_predicate "arm_float_rhs_operand"
143 (ior (match_operand 0 "s_register_operand")
144 (and (match_code "const_double")
145 (match_test "TARGET_FPA && arm_const_double_rtx (op)"))))
146
147 (define_predicate "arm_float_add_operand"
148 (ior (match_operand 0 "arm_float_rhs_operand")
149 (and (match_code "const_double")
150 (match_test "TARGET_FPA && neg_const_double_rtx_ok_for_fpa (op)"))))
151
152 (define_predicate "vfp_compare_operand"
153 (ior (match_operand 0 "s_register_operand")
154 (and (match_code "const_double")
155 (match_test "arm_const_double_rtx (op)"))))
156
157 (define_predicate "arm_float_compare_operand"
158 (if_then_else (match_test "TARGET_VFP")
159 (match_operand 0 "vfp_compare_operand")
160 (match_operand 0 "arm_float_rhs_operand")))
161
162 ;; True for valid index operands.
163 (define_predicate "index_operand"
164 (ior (match_operand 0 "s_register_operand")
165 (and (match_operand 0 "immediate_operand")
166 (match_test "(GET_CODE (op) != CONST_INT
167 || (INTVAL (op) < 4096 && INTVAL (op) > -4096))"))))
168
169 ;; True for operators that can be combined with a shift in ARM state.
170 (define_special_predicate "shiftable_operator"
171 (and (match_code "plus,minus,ior,xor,and")
172 (match_test "mode == GET_MODE (op)")))
173
174 ;; True for logical binary opertors.
175 (define_special_predicate "logical_binary_operator"
176 (and (match_code "ior,xor,and")
177 (match_test "mode == GET_MODE (op)")))
178
179 ;; True for shift operators.
180 (define_special_predicate "shift_operator"
181 (and (ior (ior (and (match_code "mult")
182 (match_test "power_of_two_operand (XEXP (op, 1), mode)"))
183 (and (match_code "rotate")
184 (match_test "GET_CODE (XEXP (op, 1)) == CONST_INT
185 && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32")))
186 (match_code "ashift,ashiftrt,lshiftrt,rotatert"))
187 (match_test "mode == GET_MODE (op)")))
188
189 ;; True for EQ & NE
190 (define_special_predicate "equality_operator"
191 (match_code "eq,ne"))
192
193 ;; True for comparisons other than LTGT or UNEQ.
194 (define_special_predicate "arm_comparison_operator"
195 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt"))
196
197 (define_special_predicate "minmax_operator"
198 (and (match_code "smin,smax,umin,umax")
199 (match_test "mode == GET_MODE (op)")))
200
201 (define_special_predicate "cc_register"
202 (and (match_code "reg")
203 (and (match_test "REGNO (op) == CC_REGNUM")
204 (ior (match_test "mode == GET_MODE (op)")
205 (match_test "mode == VOIDmode && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC")))))
206
207 (define_special_predicate "dominant_cc_register"
208 (match_code "reg")
209 {
210 if (mode == VOIDmode)
211 {
212 mode = GET_MODE (op);
213
214 if (GET_MODE_CLASS (mode) != MODE_CC)
215 return false;
216 }
217
218 return (cc_register (op, mode)
219 && (mode == CC_DNEmode
220 || mode == CC_DEQmode
221 || mode == CC_DLEmode
222 || mode == CC_DLTmode
223 || mode == CC_DGEmode
224 || mode == CC_DGTmode
225 || mode == CC_DLEUmode
226 || mode == CC_DLTUmode
227 || mode == CC_DGEUmode
228 || mode == CC_DGTUmode));
229 })
230
231 (define_special_predicate "arm_extendqisi_mem_op"
232 (and (match_operand 0 "memory_operand")
233 (match_test "arm_legitimate_address_p (mode, XEXP (op, 0), SIGN_EXTEND,
234 0)")))
235
236 (define_predicate "power_of_two_operand"
237 (match_code "const_int")
238 {
239 HOST_WIDE_INT value = INTVAL (op);
240
241 return value != 0 && (value & (value - 1)) == 0;
242 })
243
244 (define_predicate "nonimmediate_di_operand"
245 (match_code "reg,subreg,mem")
246 {
247 if (s_register_operand (op, mode))
248 return true;
249
250 if (GET_CODE (op) == SUBREG)
251 op = SUBREG_REG (op);
252
253 return GET_CODE (op) == MEM && memory_address_p (DImode, XEXP (op, 0));
254 })
255
256 (define_predicate "di_operand"
257 (ior (match_code "const_int,const_double")
258 (and (match_code "reg,subreg,mem")
259 (match_operand 0 "nonimmediate_di_operand"))))
260
261 (define_predicate "nonimmediate_soft_df_operand"
262 (match_code "reg,subreg,mem")
263 {
264 if (s_register_operand (op, mode))
265 return true;
266
267 if (GET_CODE (op) == SUBREG)
268 op = SUBREG_REG (op);
269
270 return GET_CODE (op) == MEM && memory_address_p (DFmode, XEXP (op, 0));
271 })
272
273 (define_predicate "soft_df_operand"
274 (ior (match_code "const_double")
275 (and (match_code "reg,subreg,mem")
276 (match_operand 0 "nonimmediate_soft_df_operand"))))
277
278 (define_predicate "const_shift_operand"
279 (and (match_code "const_int")
280 (ior (match_operand 0 "power_of_two_operand")
281 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 32"))))
282
283
284 (define_special_predicate "load_multiple_operation"
285 (match_code "parallel")
286 {
287 HOST_WIDE_INT count = XVECLEN (op, 0);
288 int dest_regno;
289 rtx src_addr;
290 HOST_WIDE_INT i = 1, base = 0;
291 rtx elt;
292
293 if (count <= 1
294 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
295 return false;
296
297 /* Check to see if this might be a write-back. */
298 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
299 {
300 i++;
301 base = 1;
302
303 /* Now check it more carefully. */
304 if (GET_CODE (SET_DEST (elt)) != REG
305 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
306 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
307 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
308 return false;
309 }
310
311 /* Perform a quick check so we don't blow up below. */
312 if (count <= i
313 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
314 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG
315 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM)
316 return false;
317
318 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));
319 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);
320
321 for (; i < count; i++)
322 {
323 elt = XVECEXP (op, 0, i);
324
325 if (GET_CODE (elt) != SET
326 || GET_CODE (SET_DEST (elt)) != REG
327 || GET_MODE (SET_DEST (elt)) != SImode
328 || REGNO (SET_DEST (elt)) != (unsigned int)(dest_regno + i - base)
329 || GET_CODE (SET_SRC (elt)) != MEM
330 || GET_MODE (SET_SRC (elt)) != SImode
331 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
332 || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
333 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
334 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4)
335 return false;
336 }
337
338 return true;
339 })
340
341 (define_special_predicate "store_multiple_operation"
342 (match_code "parallel")
343 {
344 HOST_WIDE_INT count = XVECLEN (op, 0);
345 int src_regno;
346 rtx dest_addr;
347 HOST_WIDE_INT i = 1, base = 0;
348 rtx elt;
349
350 if (count <= 1
351 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
352 return false;
353
354 /* Check to see if this might be a write-back. */
355 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
356 {
357 i++;
358 base = 1;
359
360 /* Now check it more carefully. */
361 if (GET_CODE (SET_DEST (elt)) != REG
362 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
363 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
364 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
365 return false;
366 }
367
368 /* Perform a quick check so we don't blow up below. */
369 if (count <= i
370 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
371 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM
372 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG)
373 return false;
374
375 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));
376 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);
377
378 for (; i < count; i++)
379 {
380 elt = XVECEXP (op, 0, i);
381
382 if (GET_CODE (elt) != SET
383 || GET_CODE (SET_SRC (elt)) != REG
384 || GET_MODE (SET_SRC (elt)) != SImode
385 || REGNO (SET_SRC (elt)) != (unsigned int)(src_regno + i - base)
386 || GET_CODE (SET_DEST (elt)) != MEM
387 || GET_MODE (SET_DEST (elt)) != SImode
388 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
389 || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
390 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
391 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4)
392 return false;
393 }
394
395 return true;
396 })
397
398 (define_special_predicate "multi_register_push"
399 (match_code "parallel")
400 {
401 if ((GET_CODE (XVECEXP (op, 0, 0)) != SET)
402 || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC)
403 || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT))
404 return false;
405
406 return true;
407 })
408
409 ;;-------------------------------------------------------------------------
410 ;;
411 ;; Thumb predicates
412 ;;
413
414 (define_predicate "thumb_cmp_operand"
415 (ior (and (match_code "reg,subreg")
416 (match_operand 0 "s_register_operand"))
417 (and (match_code "const_int")
418 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 256"))))
419
420 (define_predicate "thumb_cmpneg_operand"
421 (and (match_code "const_int")
422 (match_test "INTVAL (op) < 0 && INTVAL (op) > -256")))
423
424 ;; Return TRUE if a result can be stored in OP without clobbering the
425 ;; condition code register. Prior to reload we only accept a
426 ;; register. After reload we have to be able to handle memory as
427 ;; well, since a pseudo may not get a hard reg and reload cannot
428 ;; handle output-reloads on jump insns.
429
430 ;; We could possibly handle mem before reload as well, but that might
431 ;; complicate things with the need to handle increment
432 ;; side-effects.
433 (define_predicate "thumb_cbrch_target_operand"
434 (and (match_code "reg,subreg,mem")
435 (ior (match_operand 0 "s_register_operand")
436 (and (match_test "reload_in_progress || reload_completed")
437 (match_operand 0 "memory_operand")))))
438
439 ;;-------------------------------------------------------------------------
440 ;;
441 ;; MAVERICK predicates
442 ;;
443
444 (define_predicate "cirrus_register_operand"
445 (match_code "reg,subreg")
446 {
447 if (GET_CODE (op) == SUBREG)
448 op = SUBREG_REG (op);
449
450 return (GET_CODE (op) == REG
451 && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS
452 || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS));
453 })
454
455 (define_predicate "cirrus_fp_register"
456 (match_code "reg,subreg")
457 {
458 if (GET_CODE (op) == SUBREG)
459 op = SUBREG_REG (op);
460
461 return (GET_CODE (op) == REG
462 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
463 || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS));
464 })
465
466 (define_predicate "cirrus_shift_const"
467 (and (match_code "const_int")
468 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64")))
469
470