1169689Skan;; Predicate definitions for ARM and Thumb
2169689Skan;; Copyright (C) 2004 Free Software Foundation, Inc.
3169689Skan;; Contributed by ARM Ltd.
4169689Skan
5169689Skan;; This file is part of GCC.
6169689Skan
7169689Skan;; GCC is free software; you can redistribute it and/or modify it
8169689Skan;; under the terms of the GNU General Public License as published
9169689Skan;; by the Free Software Foundation; either version 2, or (at your
10169689Skan;; option) any later version.
11169689Skan
12169689Skan;; GCC is distributed in the hope that it will be useful, but WITHOUT
13169689Skan;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14169689Skan;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15169689Skan;; License for more details.
16169689Skan
17169689Skan;; You should have received a copy of the GNU General Public License
18169689Skan;; along with GCC; see the file COPYING.  If not, write to
19169689Skan;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20169689Skan;; Boston, MA 02110-1301, USA.
21169689Skan
22169689Skan(define_predicate "s_register_operand"
23169689Skan  (match_code "reg,subreg")
24169689Skan{
25169689Skan  if (GET_CODE (op) == SUBREG)
26169689Skan    op = SUBREG_REG (op);
27169689Skan  /* We don't consider registers whose class is NO_REGS
28169689Skan     to be a register operand.  */
29169689Skan  /* XXX might have to check for lo regs only for thumb ??? */
30169689Skan  return (GET_CODE (op) == REG
31169689Skan	  && (REGNO (op) >= FIRST_PSEUDO_REGISTER
32169689Skan	      || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
33169689Skan})
34169689Skan
35169689Skan;; Any hard register.
36169689Skan(define_predicate "arm_hard_register_operand"
37169689Skan  (match_code "reg")
38169689Skan{
39169689Skan  return REGNO (op) < FIRST_PSEUDO_REGISTER;
40169689Skan})
41169689Skan
42169689Skan;; Any core register, or any pseudo.  */ 
43169689Skan(define_predicate "arm_general_register_operand"
44169689Skan  (match_code "reg,subreg")
45169689Skan{
46169689Skan  if (GET_CODE (op) == SUBREG)
47169689Skan    op = SUBREG_REG (op);
48169689Skan
49169689Skan  return (GET_CODE (op) == REG
50169689Skan	  && (REGNO (op) <= LAST_ARM_REGNUM
51169689Skan	      || REGNO (op) >= FIRST_PSEUDO_REGISTER));
52169689Skan})
53169689Skan
54169689Skan(define_predicate "f_register_operand"
55169689Skan  (match_code "reg,subreg")
56169689Skan{
57169689Skan  if (GET_CODE (op) == SUBREG)
58169689Skan    op = SUBREG_REG (op);
59169689Skan
60169689Skan  /* We don't consider registers whose class is NO_REGS
61169689Skan     to be a register operand.  */
62169689Skan  return (GET_CODE (op) == REG
63169689Skan	  && (REGNO (op) >= FIRST_PSEUDO_REGISTER
64169689Skan	      || REGNO_REG_CLASS (REGNO (op)) == FPA_REGS));
65169689Skan})
66169689Skan
67169689Skan;; Reg, subreg(reg) or const_int.
68169689Skan(define_predicate "reg_or_int_operand"
69169689Skan  (ior (match_code "const_int")
70169689Skan       (match_operand 0 "s_register_operand")))
71169689Skan
72169689Skan(define_predicate "arm_immediate_operand"
73169689Skan  (and (match_code "const_int")
74169689Skan       (match_test "const_ok_for_arm (INTVAL (op))")))
75169689Skan
76169689Skan(define_predicate "arm_neg_immediate_operand"
77169689Skan  (and (match_code "const_int")
78169689Skan       (match_test "const_ok_for_arm (-INTVAL (op))")))
79169689Skan
80169689Skan(define_predicate "arm_not_immediate_operand"
81169689Skan  (and (match_code "const_int")
82169689Skan       (match_test "const_ok_for_arm (~INTVAL (op))")))
83169689Skan
84169689Skan;; Something valid on the RHS of an ARM data-processing instruction
85169689Skan(define_predicate "arm_rhs_operand"
86169689Skan  (ior (match_operand 0 "s_register_operand")
87169689Skan       (match_operand 0 "arm_immediate_operand")))
88169689Skan
89169689Skan(define_predicate "arm_rhsm_operand"
90169689Skan  (ior (match_operand 0 "arm_rhs_operand")
91169689Skan       (match_operand 0 "memory_operand")))
92169689Skan
93169689Skan(define_predicate "arm_add_operand"
94169689Skan  (ior (match_operand 0 "arm_rhs_operand")
95169689Skan       (match_operand 0 "arm_neg_immediate_operand")))
96169689Skan
97169689Skan(define_predicate "arm_addimm_operand"
98169689Skan  (ior (match_operand 0 "arm_immediate_operand")
99169689Skan       (match_operand 0 "arm_neg_immediate_operand")))
100169689Skan
101169689Skan(define_predicate "arm_not_operand"
102169689Skan  (ior (match_operand 0 "arm_rhs_operand")
103169689Skan       (match_operand 0 "arm_not_immediate_operand")))
104169689Skan
105169689Skan;; True if the operand is a memory reference which contains an
106169689Skan;; offsettable address.
107169689Skan(define_predicate "offsettable_memory_operand"
108169689Skan  (and (match_code "mem")
109169689Skan       (match_test
110169689Skan        "offsettable_address_p (reload_completed | reload_in_progress,
111169689Skan				mode, XEXP (op, 0))")))
112169689Skan
113169689Skan;; True if the operand is a memory operand that does not have an
114169689Skan;; automodified base register (and thus will not generate output reloads).
115169689Skan(define_predicate "call_memory_operand"
116169689Skan  (and (match_code "mem")
117169689Skan       (and (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0)))
118169689Skan			 != RTX_AUTOINC")
119169689Skan	    (match_operand 0 "memory_operand"))))
120169689Skan
121169689Skan(define_predicate "arm_reload_memory_operand"
122169689Skan  (and (match_code "mem,reg,subreg")
123169689Skan       (match_test "(!CONSTANT_P (op)
124169689Skan		     && (true_regnum(op) == -1
125169689Skan			 || (GET_CODE (op) == REG
126169689Skan			     && REGNO (op) >= FIRST_PSEUDO_REGISTER)))")))
127169689Skan
128169689Skan;; True for valid operands for the rhs of an floating point insns.
129169689Skan;;   Allows regs or certain consts on FPA, just regs for everything else.
130169689Skan(define_predicate "arm_float_rhs_operand"
131169689Skan  (ior (match_operand 0 "s_register_operand")
132169689Skan       (and (match_code "const_double")
133169689Skan	    (match_test "TARGET_FPA && arm_const_double_rtx (op)"))))
134169689Skan
135169689Skan(define_predicate "arm_float_add_operand"
136169689Skan  (ior (match_operand 0 "arm_float_rhs_operand")
137169689Skan       (and (match_code "const_double")
138169689Skan	    (match_test "TARGET_FPA && neg_const_double_rtx_ok_for_fpa (op)"))))
139169689Skan
140169689Skan(define_predicate "vfp_compare_operand"
141169689Skan  (ior (match_operand 0 "s_register_operand")
142169689Skan       (and (match_code "const_double")
143169689Skan	    (match_test "arm_const_double_rtx (op)"))))
144169689Skan
145169689Skan(define_predicate "arm_float_compare_operand"
146169689Skan  (if_then_else (match_test "TARGET_VFP")
147169689Skan		(match_operand 0 "vfp_compare_operand")
148169689Skan		(match_operand 0 "arm_float_rhs_operand")))
149169689Skan
150169689Skan;; True for valid index operands.
151169689Skan(define_predicate "index_operand"
152169689Skan  (ior (match_operand 0 "s_register_operand")
153169689Skan       (and (match_operand 0 "immediate_operand")
154169689Skan	    (match_test "(GET_CODE (op) != CONST_INT
155169689Skan			  || (INTVAL (op) < 4096 && INTVAL (op) > -4096))"))))
156169689Skan
157169689Skan;; True for operators that can be combined with a shift in ARM state.
158169689Skan(define_special_predicate "shiftable_operator"
159169689Skan  (and (match_code "plus,minus,ior,xor,and")
160169689Skan       (match_test "mode == GET_MODE (op)")))
161169689Skan
162169689Skan;; True for logical binary operators.
163169689Skan(define_special_predicate "logical_binary_operator"
164169689Skan  (and (match_code "ior,xor,and")
165169689Skan       (match_test "mode == GET_MODE (op)")))
166169689Skan
167169689Skan;; True for shift operators.
168169689Skan(define_special_predicate "shift_operator"
169169689Skan  (and (ior (ior (and (match_code "mult")
170169689Skan		      (match_test "power_of_two_operand (XEXP (op, 1), mode)"))
171169689Skan		 (and (match_code "rotate")
172169689Skan		      (match_test "GET_CODE (XEXP (op, 1)) == CONST_INT
173169689Skan				   && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32")))
174169689Skan	    (match_code "ashift,ashiftrt,lshiftrt,rotatert"))
175169689Skan       (match_test "mode == GET_MODE (op)")))
176169689Skan
177169689Skan;; True for EQ & NE
178169689Skan(define_special_predicate "equality_operator"
179169689Skan  (match_code "eq,ne"))
180169689Skan
181169689Skan;; True for comparisons other than LTGT or UNEQ.
182169689Skan(define_special_predicate "arm_comparison_operator"
183169689Skan  (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt"))
184169689Skan
185169689Skan(define_special_predicate "minmax_operator"
186169689Skan  (and (match_code "smin,smax,umin,umax")
187169689Skan       (match_test "mode == GET_MODE (op)")))
188169689Skan
189169689Skan(define_special_predicate "cc_register"
190169689Skan  (and (match_code "reg")
191169689Skan       (and (match_test "REGNO (op) == CC_REGNUM")
192169689Skan	    (ior (match_test "mode == GET_MODE (op)")
193169689Skan		 (match_test "mode == VOIDmode && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC")))))
194169689Skan
195169689Skan(define_special_predicate "dominant_cc_register"
196169689Skan  (match_code "reg")
197169689Skan{
198169689Skan  if (mode == VOIDmode)
199169689Skan    {
200169689Skan      mode = GET_MODE (op);
201169689Skan      
202169689Skan      if (GET_MODE_CLASS (mode) != MODE_CC)
203169689Skan	return false;
204169689Skan    }
205169689Skan
206169689Skan  return (cc_register (op, mode)
207169689Skan	  && (mode == CC_DNEmode
208169689Skan	     || mode == CC_DEQmode
209169689Skan	     || mode == CC_DLEmode
210169689Skan	     || mode == CC_DLTmode
211169689Skan	     || mode == CC_DGEmode
212169689Skan	     || mode == CC_DGTmode
213169689Skan	     || mode == CC_DLEUmode
214169689Skan	     || mode == CC_DLTUmode
215169689Skan	     || mode == CC_DGEUmode
216169689Skan	     || mode == CC_DGTUmode));
217169689Skan})
218169689Skan
219169689Skan(define_special_predicate "arm_extendqisi_mem_op"
220169689Skan  (and (match_operand 0 "memory_operand")
221169689Skan       (match_test "arm_legitimate_address_p (mode, XEXP (op, 0), SIGN_EXTEND,
222169689Skan					      0)")))
223169689Skan
224169689Skan(define_predicate "power_of_two_operand"
225169689Skan  (match_code "const_int")
226169689Skan{
227169689Skan  HOST_WIDE_INT value = INTVAL (op);
228169689Skan
229169689Skan  return value != 0 && (value & (value - 1)) == 0;
230169689Skan})
231169689Skan
232169689Skan(define_predicate "nonimmediate_di_operand"
233169689Skan  (match_code "reg,subreg,mem")
234169689Skan{
235169689Skan   if (s_register_operand (op, mode))
236169689Skan     return true;
237169689Skan
238169689Skan   if (GET_CODE (op) == SUBREG)
239169689Skan     op = SUBREG_REG (op);
240169689Skan
241169689Skan   return GET_CODE (op) == MEM && memory_address_p (DImode, XEXP (op, 0));
242169689Skan})
243169689Skan
244169689Skan(define_predicate "di_operand"
245169689Skan  (ior (match_code "const_int,const_double")
246169689Skan       (and (match_code "reg,subreg,mem")
247169689Skan	    (match_operand 0 "nonimmediate_di_operand"))))
248169689Skan
249169689Skan(define_predicate "nonimmediate_soft_df_operand"
250169689Skan  (match_code "reg,subreg,mem")
251169689Skan{
252169689Skan  if (s_register_operand (op, mode))
253169689Skan    return true;
254169689Skan
255169689Skan  if (GET_CODE (op) == SUBREG)
256169689Skan    op = SUBREG_REG (op);
257169689Skan
258169689Skan  return GET_CODE (op) == MEM && memory_address_p (DFmode, XEXP (op, 0));
259169689Skan})
260169689Skan
261169689Skan(define_predicate "soft_df_operand"
262169689Skan  (ior (match_code "const_double")
263169689Skan       (and (match_code "reg,subreg,mem")
264169689Skan	    (match_operand 0 "nonimmediate_soft_df_operand"))))
265169689Skan
266169689Skan(define_predicate "const_shift_operand"
267169689Skan  (and (match_code "const_int")
268169689Skan       (ior (match_operand 0 "power_of_two_operand")
269169689Skan	    (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 32"))))
270169689Skan
271169689Skan
272169689Skan(define_special_predicate "load_multiple_operation"
273169689Skan  (match_code "parallel")
274169689Skan{
275169689Skan  HOST_WIDE_INT count = XVECLEN (op, 0);
276169689Skan  int dest_regno;
277169689Skan  rtx src_addr;
278169689Skan  HOST_WIDE_INT i = 1, base = 0;
279169689Skan  rtx elt;
280169689Skan
281169689Skan  if (count <= 1
282169689Skan      || GET_CODE (XVECEXP (op, 0, 0)) != SET)
283169689Skan    return false;
284169689Skan
285169689Skan  /* Check to see if this might be a write-back.  */
286169689Skan  if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
287169689Skan    {
288169689Skan      i++;
289169689Skan      base = 1;
290169689Skan
291169689Skan      /* Now check it more carefully.  */
292169689Skan      if (GET_CODE (SET_DEST (elt)) != REG
293169689Skan          || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
294169689Skan          || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
295169689Skan          || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
296169689Skan        return false;
297169689Skan    }
298169689Skan
299169689Skan  /* Perform a quick check so we don't blow up below.  */
300169689Skan  if (count <= i
301169689Skan      || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
302169689Skan      || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG
303169689Skan      || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM)
304169689Skan    return false;
305169689Skan
306169689Skan  dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));
307169689Skan  src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);
308169689Skan
309169689Skan  for (; i < count; i++)
310169689Skan    {
311169689Skan      elt = XVECEXP (op, 0, i);
312169689Skan
313169689Skan      if (GET_CODE (elt) != SET
314169689Skan          || GET_CODE (SET_DEST (elt)) != REG
315169689Skan          || GET_MODE (SET_DEST (elt)) != SImode
316169689Skan          || REGNO (SET_DEST (elt)) != (unsigned int)(dest_regno + i - base)
317169689Skan          || GET_CODE (SET_SRC (elt)) != MEM
318169689Skan          || GET_MODE (SET_SRC (elt)) != SImode
319169689Skan          || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
320169689Skan          || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
321169689Skan          || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
322169689Skan          || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4)
323169689Skan        return false;
324169689Skan    }
325169689Skan
326169689Skan  return true;
327169689Skan})
328169689Skan
329169689Skan(define_special_predicate "store_multiple_operation"
330169689Skan  (match_code "parallel")
331169689Skan{
332169689Skan  HOST_WIDE_INT count = XVECLEN (op, 0);
333169689Skan  int src_regno;
334169689Skan  rtx dest_addr;
335169689Skan  HOST_WIDE_INT i = 1, base = 0;
336169689Skan  rtx elt;
337169689Skan
338169689Skan  if (count <= 1
339169689Skan      || GET_CODE (XVECEXP (op, 0, 0)) != SET)
340169689Skan    return false;
341169689Skan
342169689Skan  /* Check to see if this might be a write-back.  */
343169689Skan  if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
344169689Skan    {
345169689Skan      i++;
346169689Skan      base = 1;
347169689Skan
348169689Skan      /* Now check it more carefully.  */
349169689Skan      if (GET_CODE (SET_DEST (elt)) != REG
350169689Skan          || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
351169689Skan          || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
352169689Skan          || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
353169689Skan        return false;
354169689Skan    }
355169689Skan
356169689Skan  /* Perform a quick check so we don't blow up below.  */
357169689Skan  if (count <= i
358169689Skan      || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
359169689Skan      || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM
360169689Skan      || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG)
361169689Skan    return false;
362169689Skan
363169689Skan  src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));
364169689Skan  dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);
365169689Skan
366169689Skan  for (; i < count; i++)
367169689Skan    {
368169689Skan      elt = XVECEXP (op, 0, i);
369169689Skan
370169689Skan      if (GET_CODE (elt) != SET
371169689Skan          || GET_CODE (SET_SRC (elt)) != REG
372169689Skan          || GET_MODE (SET_SRC (elt)) != SImode
373169689Skan          || REGNO (SET_SRC (elt)) != (unsigned int)(src_regno + i - base)
374169689Skan          || GET_CODE (SET_DEST (elt)) != MEM
375169689Skan          || GET_MODE (SET_DEST (elt)) != SImode
376169689Skan          || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
377169689Skan          || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
378169689Skan          || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
379169689Skan          || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4)
380169689Skan        return false;
381169689Skan    }
382169689Skan
383169689Skan  return true;
384169689Skan})
385169689Skan
386169689Skan(define_special_predicate "multi_register_push"
387169689Skan  (match_code "parallel")
388169689Skan{
389169689Skan  if ((GET_CODE (XVECEXP (op, 0, 0)) != SET)
390169689Skan      || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC)
391169689Skan      || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT))
392169689Skan    return false;
393169689Skan
394169689Skan  return true;
395169689Skan})
396169689Skan
397169689Skan;;-------------------------------------------------------------------------
398169689Skan;;
399169689Skan;; Thumb predicates
400169689Skan;;
401169689Skan
402169689Skan(define_predicate "thumb_cmp_operand"
403169689Skan  (ior (and (match_code "reg,subreg")
404169689Skan	    (match_operand 0 "s_register_operand"))
405169689Skan       (and (match_code "const_int")
406169689Skan	    (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 256"))))
407169689Skan
408169689Skan(define_predicate "thumb_cmpneg_operand"
409169689Skan  (and (match_code "const_int")
410169689Skan       (match_test "INTVAL (op) < 0 && INTVAL (op) > -256")))
411169689Skan
412169689Skan;; Return TRUE if a result can be stored in OP without clobbering the
413169689Skan;; condition code register.  Prior to reload we only accept a
414169689Skan;; register.  After reload we have to be able to handle memory as
415169689Skan;; well, since a pseudo may not get a hard reg and reload cannot
416169689Skan;; handle output-reloads on jump insns.
417169689Skan
418169689Skan;; We could possibly handle mem before reload as well, but that might
419169689Skan;; complicate things with the need to handle increment
420169689Skan;; side-effects.
421169689Skan(define_predicate "thumb_cbrch_target_operand"
422169689Skan  (and (match_code "reg,subreg,mem")
423169689Skan       (ior (match_operand 0 "s_register_operand")
424169689Skan	    (and (match_test "reload_in_progress || reload_completed")
425169689Skan		 (match_operand 0 "memory_operand")))))
426169689Skan
427169689Skan;;-------------------------------------------------------------------------
428169689Skan;;
429169689Skan;; MAVERICK predicates
430169689Skan;;
431169689Skan
432169689Skan(define_predicate "cirrus_register_operand"
433169689Skan  (match_code "reg,subreg")
434169689Skan{
435169689Skan  if (GET_CODE (op) == SUBREG)
436169689Skan    op = SUBREG_REG (op);
437169689Skan
438169689Skan  return (GET_CODE (op) == REG
439169689Skan	  && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS
440169689Skan	      || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS));
441169689Skan})
442169689Skan
443169689Skan(define_predicate "cirrus_fp_register"
444169689Skan  (match_code "reg,subreg")
445169689Skan{
446169689Skan  if (GET_CODE (op) == SUBREG)
447169689Skan    op = SUBREG_REG (op);
448169689Skan
449169689Skan  return (GET_CODE (op) == REG
450169689Skan	  && (REGNO (op) >= FIRST_PSEUDO_REGISTER
451169689Skan	      || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS));
452169689Skan})
453169689Skan
454169689Skan(define_predicate "cirrus_shift_const"
455169689Skan  (and (match_code "const_int")
456169689Skan       (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64")))
457169689Skan
458169689Skan
459