xref: /openbsd/gnu/gcc/gcc/config/mcore/predicates.md (revision 404b540a)
1*404b540aSrobert;; Predicate definitions for Motorola MCore.
2*404b540aSrobert;; Copyright (C) 2005 Free Software Foundation, Inc.
3*404b540aSrobert;;
4*404b540aSrobert;; This file is part of GCC.
5*404b540aSrobert;;
6*404b540aSrobert;; GCC is free software; you can redistribute it and/or modify
7*404b540aSrobert;; it under the terms of the GNU General Public License as published by
8*404b540aSrobert;; the Free Software Foundation; either version 2, or (at your option)
9*404b540aSrobert;; any later version.
10*404b540aSrobert;;
11*404b540aSrobert;; GCC is distributed in the hope that it will be useful,
12*404b540aSrobert;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13*404b540aSrobert;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*404b540aSrobert;; GNU General Public License for more details.
15*404b540aSrobert;;
16*404b540aSrobert;; You should have received a copy of the GNU General Public License
17*404b540aSrobert;; along with GCC; see the file COPYING.  If not, write to
18*404b540aSrobert;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19*404b540aSrobert;; Boston, MA 02110-1301, USA.
20*404b540aSrobert
21*404b540aSrobert;; Nonzero if OP is a normal arithmetic register.
22*404b540aSrobert
23*404b540aSrobert(define_predicate "mcore_arith_reg_operand"
24*404b540aSrobert  (match_code "reg,subreg")
25*404b540aSrobert{
26*404b540aSrobert  if (! register_operand (op, mode))
27*404b540aSrobert    return 0;
28*404b540aSrobert
29*404b540aSrobert  if (GET_CODE (op) == SUBREG)
30*404b540aSrobert    op = SUBREG_REG (op);
31*404b540aSrobert
32*404b540aSrobert  if (GET_CODE (op) == REG)
33*404b540aSrobert    return REGNO (op) != CC_REG;
34*404b540aSrobert
35*404b540aSrobert  return 1;
36*404b540aSrobert})
37*404b540aSrobert
38*404b540aSrobert;; Nonzero if OP can be source of a simple move operation.
39*404b540aSrobert
40*404b540aSrobert(define_predicate "mcore_general_movsrc_operand"
41*404b540aSrobert  (match_code "mem,const_int,reg,subreg,symbol_ref,label_ref")
42*404b540aSrobert{
43*404b540aSrobert  /* Any (MEM LABEL_REF) is OK.  That is a pc-relative load.  */
44*404b540aSrobert  if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == LABEL_REF)
45*404b540aSrobert    return 1;
46*404b540aSrobert
47*404b540aSrobert  return general_operand (op, mode);
48*404b540aSrobert})
49*404b540aSrobert
50*404b540aSrobert;; Nonzero if OP can be destination of a simple move operation.
51*404b540aSrobert
52*404b540aSrobert(define_predicate "mcore_general_movdst_operand"
53*404b540aSrobert  (match_code "mem,const_int,reg,subreg")
54*404b540aSrobert{
55*404b540aSrobert  if (GET_CODE (op) == REG && REGNO (op) == CC_REG)
56*404b540aSrobert    return 0;
57*404b540aSrobert
58*404b540aSrobert  return general_operand (op, mode);
59*404b540aSrobert})
60*404b540aSrobert
61*404b540aSrobert;; Nonzero if OP should be recognized during reload for an ixh/ixw
62*404b540aSrobert;; operand.  See the ixh/ixw patterns.
63*404b540aSrobert
64*404b540aSrobert(define_predicate "mcore_reload_operand"
65*404b540aSrobert  (match_code "mem,reg,subreg")
66*404b540aSrobert{
67*404b540aSrobert  if (mcore_arith_reg_operand (op, mode))
68*404b540aSrobert    return 1;
69*404b540aSrobert
70*404b540aSrobert  if (! reload_in_progress)
71*404b540aSrobert    return 0;
72*404b540aSrobert
73*404b540aSrobert  return GET_CODE (op) == MEM;
74*404b540aSrobert})
75*404b540aSrobert
76*404b540aSrobert;; Nonzero if OP is a valid source operand for an arithmetic insn.
77*404b540aSrobert
78*404b540aSrobert(define_predicate "mcore_arith_J_operand"
79*404b540aSrobert  (match_code "const_int,reg,subreg")
80*404b540aSrobert{
81*404b540aSrobert  if (register_operand (op, mode))
82*404b540aSrobert    return 1;
83*404b540aSrobert
84*404b540aSrobert  if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_J (INTVAL (op)))
85*404b540aSrobert    return 1;
86*404b540aSrobert
87*404b540aSrobert  return 0;
88*404b540aSrobert})
89*404b540aSrobert
90*404b540aSrobert;; Nonzero if OP is a valid source operand for an arithmetic insn.
91*404b540aSrobert
92*404b540aSrobert(define_predicate "mcore_arith_K_operand"
93*404b540aSrobert  (match_code "const_int,reg,subreg")
94*404b540aSrobert{
95*404b540aSrobert  if (register_operand (op, mode))
96*404b540aSrobert    return 1;
97*404b540aSrobert
98*404b540aSrobert  if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))
99*404b540aSrobert    return 1;
100*404b540aSrobert
101*404b540aSrobert  return 0;
102*404b540aSrobert})
103*404b540aSrobert
104*404b540aSrobert;; Nonzero if OP is a valid source operand for a shift or rotate insn.
105*404b540aSrobert
106*404b540aSrobert(define_predicate "mcore_arith_K_operand_not_0"
107*404b540aSrobert  (match_code "const_int,reg,subreg")
108*404b540aSrobert{
109*404b540aSrobert  if (register_operand (op, mode))
110*404b540aSrobert    return 1;
111*404b540aSrobert
112*404b540aSrobert  if (   GET_CODE (op) == CONST_INT
113*404b540aSrobert      && CONST_OK_FOR_K (INTVAL (op))
114*404b540aSrobert      && INTVAL (op) != 0)
115*404b540aSrobert    return 1;
116*404b540aSrobert
117*404b540aSrobert  return 0;
118*404b540aSrobert})
119*404b540aSrobert
120*404b540aSrobert;; TODO: Add a comment here.
121*404b540aSrobert
122*404b540aSrobert(define_predicate "mcore_arith_M_operand"
123*404b540aSrobert  (match_code "const_int,reg,subreg")
124*404b540aSrobert{
125*404b540aSrobert  if (register_operand (op, mode))
126*404b540aSrobert    return 1;
127*404b540aSrobert
128*404b540aSrobert  if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (INTVAL (op)))
129*404b540aSrobert    return 1;
130*404b540aSrobert
131*404b540aSrobert  return 0;
132*404b540aSrobert})
133*404b540aSrobert
134*404b540aSrobert;; TODO: Add a comment here.
135*404b540aSrobert
136*404b540aSrobert(define_predicate "mcore_arith_K_S_operand"
137*404b540aSrobert  (match_code "const_int,reg,subreg")
138*404b540aSrobert{
139*404b540aSrobert  if (register_operand (op, mode))
140*404b540aSrobert    return 1;
141*404b540aSrobert
142*404b540aSrobert  if (GET_CODE (op) == CONST_INT)
143*404b540aSrobert    {
144*404b540aSrobert      if (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_M (~INTVAL (op)))
145*404b540aSrobert	return 1;
146*404b540aSrobert    }
147*404b540aSrobert
148*404b540aSrobert  return 0;
149*404b540aSrobert})
150*404b540aSrobert
151*404b540aSrobert;; Nonzero if OP is a valid source operand for a cmov with two consts
152*404b540aSrobert;; +/- 1.
153*404b540aSrobert
154*404b540aSrobert(define_predicate "mcore_arith_O_operand"
155*404b540aSrobert  (match_code "const_int,reg,subreg")
156*404b540aSrobert{
157*404b540aSrobert  if (register_operand (op, mode))
158*404b540aSrobert    return 1;
159*404b540aSrobert
160*404b540aSrobert  if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_O (INTVAL (op)))
161*404b540aSrobert    return 1;
162*404b540aSrobert
163*404b540aSrobert  return 0;
164*404b540aSrobert})
165*404b540aSrobert
166*404b540aSrobert;; Nonzero if OP is a valid source operand for loading.
167*404b540aSrobert
168*404b540aSrobert(define_predicate "mcore_arith_imm_operand"
169*404b540aSrobert  (match_code "const_int,reg,subreg")
170*404b540aSrobert{
171*404b540aSrobert  if (register_operand (op, mode))
172*404b540aSrobert    return 1;
173*404b540aSrobert
174*404b540aSrobert  if (GET_CODE (op) == CONST_INT && const_ok_for_mcore (INTVAL (op)))
175*404b540aSrobert    return 1;
176*404b540aSrobert
177*404b540aSrobert  return 0;
178*404b540aSrobert})
179*404b540aSrobert
180*404b540aSrobert;; TODO: Add a comment here.
181*404b540aSrobert
182*404b540aSrobert(define_predicate "mcore_arith_any_imm_operand"
183*404b540aSrobert  (match_code "const_int,reg,subreg")
184*404b540aSrobert{
185*404b540aSrobert  if (register_operand (op, mode))
186*404b540aSrobert    return 1;
187*404b540aSrobert
188*404b540aSrobert  if (GET_CODE (op) == CONST_INT)
189*404b540aSrobert    return 1;
190*404b540aSrobert
191*404b540aSrobert  return 0;
192*404b540aSrobert})
193*404b540aSrobert
194*404b540aSrobert;; Nonzero if OP is a valid source operand for a btsti.
195*404b540aSrobert
196*404b540aSrobert(define_predicate "mcore_literal_K_operand"
197*404b540aSrobert  (match_code "const_int")
198*404b540aSrobert{
199*404b540aSrobert  if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))
200*404b540aSrobert    return 1;
201*404b540aSrobert
202*404b540aSrobert  return 0;
203*404b540aSrobert})
204*404b540aSrobert
205*404b540aSrobert;; Nonzero if OP is a valid source operand for an add/sub insn.
206*404b540aSrobert
207*404b540aSrobert(define_predicate "mcore_addsub_operand"
208*404b540aSrobert  (match_code "const_int,reg,subreg")
209*404b540aSrobert{
210*404b540aSrobert  if (register_operand (op, mode))
211*404b540aSrobert    return 1;
212*404b540aSrobert
213*404b540aSrobert  if (GET_CODE (op) == CONST_INT)
214*404b540aSrobert    {
215*404b540aSrobert      return 1;
216*404b540aSrobert
217*404b540aSrobert      /* The following is removed because it precludes large constants from being
218*404b540aSrobert	 returned as valid source operands for and add/sub insn.  While large
219*404b540aSrobert	 constants may not directly be used in an add/sub, they may if first loaded
220*404b540aSrobert	 into a register.  Thus, this predicate should indicate that they are valid,
221*404b540aSrobert	 and the constraint in mcore.md should control whether an additional load to
222*404b540aSrobert	 register is needed. (see mcore.md, addsi). -- DAC 4/2/1998  */
223*404b540aSrobert      /*
224*404b540aSrobert	if (CONST_OK_FOR_J(INTVAL(op)) || CONST_OK_FOR_L(INTVAL(op)))
225*404b540aSrobert          return 1;
226*404b540aSrobert      */
227*404b540aSrobert    }
228*404b540aSrobert
229*404b540aSrobert  return 0;
230*404b540aSrobert})
231*404b540aSrobert
232*404b540aSrobert;; Nonzero if OP is a valid source operand for a compare operation.
233*404b540aSrobert
234*404b540aSrobert(define_predicate "mcore_compare_operand"
235*404b540aSrobert  (match_code "const_int,reg,subreg")
236*404b540aSrobert{
237*404b540aSrobert  if (register_operand (op, mode))
238*404b540aSrobert    return 1;
239*404b540aSrobert
240*404b540aSrobert  if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
241*404b540aSrobert    return 1;
242*404b540aSrobert
243*404b540aSrobert  return 0;
244*404b540aSrobert})
245*404b540aSrobert
246*404b540aSrobert;; Return 1 if OP is a load multiple operation.  It is known to be a
247*404b540aSrobert;; PARALLEL and the first section will be tested.
248*404b540aSrobert
249*404b540aSrobert(define_predicate "mcore_load_multiple_operation"
250*404b540aSrobert  (match_code "parallel")
251*404b540aSrobert{
252*404b540aSrobert  int count = XVECLEN (op, 0);
253*404b540aSrobert  int dest_regno;
254*404b540aSrobert  rtx src_addr;
255*404b540aSrobert  int i;
256*404b540aSrobert
257*404b540aSrobert  /* Perform a quick check so we don't blow up below.  */
258*404b540aSrobert  if (count <= 1
259*404b540aSrobert      || GET_CODE (XVECEXP (op, 0, 0)) != SET
260*404b540aSrobert      || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
261*404b540aSrobert      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
262*404b540aSrobert    return 0;
263*404b540aSrobert
264*404b540aSrobert  dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
265*404b540aSrobert  src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
266*404b540aSrobert
267*404b540aSrobert  for (i = 1; i < count; i++)
268*404b540aSrobert    {
269*404b540aSrobert      rtx elt = XVECEXP (op, 0, i);
270*404b540aSrobert
271*404b540aSrobert      if (GET_CODE (elt) != SET
272*404b540aSrobert	  || GET_CODE (SET_DEST (elt)) != REG
273*404b540aSrobert	  || GET_MODE (SET_DEST (elt)) != SImode
274*404b540aSrobert	  || REGNO (SET_DEST (elt))    != (unsigned) (dest_regno + i)
275*404b540aSrobert	  || GET_CODE (SET_SRC (elt))  != MEM
276*404b540aSrobert	  || GET_MODE (SET_SRC (elt))  != SImode
277*404b540aSrobert	  || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
278*404b540aSrobert	  || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
279*404b540aSrobert	  || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
280*404b540aSrobert	  || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
281*404b540aSrobert	return 0;
282*404b540aSrobert    }
283*404b540aSrobert
284*404b540aSrobert  return 1;
285*404b540aSrobert})
286*404b540aSrobert
287*404b540aSrobert;; Similar, but tests for store multiple.
288*404b540aSrobert
289*404b540aSrobert(define_predicate "mcore_store_multiple_operation"
290*404b540aSrobert  (match_code "parallel")
291*404b540aSrobert{
292*404b540aSrobert  int count = XVECLEN (op, 0);
293*404b540aSrobert  int src_regno;
294*404b540aSrobert  rtx dest_addr;
295*404b540aSrobert  int i;
296*404b540aSrobert
297*404b540aSrobert  /* Perform a quick check so we don't blow up below.  */
298*404b540aSrobert  if (count <= 1
299*404b540aSrobert      || GET_CODE (XVECEXP (op, 0, 0)) != SET
300*404b540aSrobert      || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
301*404b540aSrobert      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
302*404b540aSrobert    return 0;
303*404b540aSrobert
304*404b540aSrobert  src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
305*404b540aSrobert  dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
306*404b540aSrobert
307*404b540aSrobert  for (i = 1; i < count; i++)
308*404b540aSrobert    {
309*404b540aSrobert      rtx elt = XVECEXP (op, 0, i);
310*404b540aSrobert
311*404b540aSrobert      if (GET_CODE (elt) != SET
312*404b540aSrobert	  || GET_CODE (SET_SRC (elt)) != REG
313*404b540aSrobert	  || GET_MODE (SET_SRC (elt)) != SImode
314*404b540aSrobert	  || REGNO (SET_SRC (elt)) != (unsigned) (src_regno + i)
315*404b540aSrobert	  || GET_CODE (SET_DEST (elt)) != MEM
316*404b540aSrobert	  || GET_MODE (SET_DEST (elt)) != SImode
317*404b540aSrobert	  || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
318*404b540aSrobert	  || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
319*404b540aSrobert	  || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
320*404b540aSrobert	  || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
321*404b540aSrobert	return 0;
322*404b540aSrobert    }
323*404b540aSrobert
324*404b540aSrobert  return 1;
325*404b540aSrobert})
326*404b540aSrobert
327*404b540aSrobert;; TODO: Add a comment here.
328*404b540aSrobert
329*404b540aSrobert(define_predicate "mcore_call_address_operand"
330*404b540aSrobert  (match_code "reg,subreg,const_int,symbol_ref")
331*404b540aSrobert{
332*404b540aSrobert  return register_operand (op, mode) || CONSTANT_P (op);
333*404b540aSrobert})
334