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