OSDN Git Service

6485dab643d91e01300c39782d534bb6dcf971e6
[pf3gnuchains/gcc-fork.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, 51 Franklin Street, Fifth Floor,
20 ;; Boston, MA 02110-1301, 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 "mem,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 operators.
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