* tree.c (maybe_warn_parm_abi): Inform the location of the class.
[official-gcc.git] / gcc / config / rx / predicates.md
blob93f31b05bb86355ae7d7d07d25003d742d2005d4
1 ;; Predicate definitions for Renesas RX.
2 ;; Copyright (C) 2008-2018 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
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/>.
23 ;; Check that the operand is suitable for a call insn.
24 ;; Only registers and symbol refs are allowed.
26 (define_predicate "rx_call_operand"
27   (ior (match_code "reg")
28        (and (match_test "!TARGET_JSR")
29             (match_code "symbol_ref")))
32 ;; For sibcall operations we can only use a symbolic address.
34 (define_predicate "rx_symbolic_call_operand"
35   (match_code "symbol_ref")
38 ;; Check that the operand is suitable for a shift insn
39 ;; Only small integers or a value in a register are permitted.
41 (define_predicate "rx_shift_operand"
42   (ior (match_operand 0 "register_operand")
43        (and (match_code "const_int")
44             (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
47 (define_predicate "rx_constshift_operand"
48   (and (match_code "const_int")
49        (match_test "IN_RANGE (INTVAL (op), 0, 31)"))
52 (define_predicate "rx_restricted_mem_operand"
53   (and (match_code "mem")
54        (match_test "rx_is_restricted_memory_address (XEXP (op, 0), mode)"))
57 ;; Check that the operand is suitable as the source operand
58 ;; for a logic or arithmeitc instruction.  Registers, integers
59 ;; and a restricted subset of memory addresses are allowed.
61 (define_predicate "rx_source_operand"
62   (ior (match_operand 0 "register_operand")
63        (match_operand 0 "immediate_operand")
64        (match_operand 0 "rx_restricted_mem_operand"))
67 ;; Check that the operand is suitable as the source operand
68 ;; for a comparison instruction.  This is the same as
69 ;; rx_source_operand except that SUBREGs are allowed but
70 ;; CONST_INTs are not.
72 (define_predicate "rx_compare_operand"
73   (ior (match_operand 0 "register_operand")
74        (match_operand 0 "rx_restricted_mem_operand"))
77 ;; Check that the operand is suitable as the source operand
78 ;; for a min/max instruction.  This is the same as
79 ;; rx_source_operand except that CONST_INTs are allowed but
80 ;; REGs and SUBREGs are not.
82 (define_predicate "rx_minmaxex_operand"
83   (ior (match_operand 0 "immediate_operand")
84        (match_operand 0 "rx_restricted_mem_operand"))
87 ;; Return true if OP is a store multiple operation.  This looks like:
89 ;;   [(set (SP) (MINUS (SP) (INT)))
90 ;;    (set (MEM (SP)) (REG))
91 ;;    (set (MEM (MINUS (SP) (INT))) (REG)) {optionally repeated}
92 ;;   ]
94 (define_special_predicate "rx_store_multiple_vector"
95   (match_code "parallel")
97   int count = XVECLEN (op, 0);
98   unsigned int src_regno;
99   rtx element;
100   int i;
102   /* Perform a quick check so we don't blow up below.  */
103   if (count <= 2)
104     return false;
106   /* Check that the first element of the vector is the stack adjust.  */
107   element = XVECEXP (op, 0, 0);
108   if (   ! SET_P (element)
109       || ! REG_P (SET_DEST (element))
110       ||   REGNO (SET_DEST (element)) != SP_REG
111       ||   GET_CODE (SET_SRC (element)) != MINUS
112       || ! REG_P (XEXP (SET_SRC (element), 0))
113       ||   REGNO (XEXP (SET_SRC (element), 0)) != SP_REG
114       || ! CONST_INT_P (XEXP (SET_SRC (element), 1)))
115     return false;
116          
117   /* Check that the next element is the first push.  */
118   element = XVECEXP (op, 0, 1);
119   if (   ! SET_P (element)
120       || ! REG_P (SET_SRC (element))
121       || GET_MODE (SET_SRC (element)) != SImode
122       || ! MEM_P (SET_DEST (element))
123       || GET_MODE (SET_DEST (element)) != SImode
124       || GET_CODE (XEXP (SET_DEST (element), 0)) != MINUS
125       || ! REG_P (XEXP (XEXP (SET_DEST (element), 0), 0))
126       ||   REGNO (XEXP (XEXP (SET_DEST (element), 0), 0)) != SP_REG
127       || ! CONST_INT_P (XEXP (XEXP (SET_DEST (element), 0), 1))
128       || INTVAL (XEXP (XEXP (SET_DEST (element), 0), 1))
129         != GET_MODE_SIZE (SImode))
130     return false;
132   src_regno = REGNO (SET_SRC (element));
134   /* Check that the remaining elements use SP-<disp>
135      addressing and decreasing register numbers.  */
136   for (i = 2; i < count; i++)
137     {
138       element = XVECEXP (op, 0, i);
140       if (   ! SET_P (element)
141           || ! REG_P (SET_SRC (element))
142           || GET_MODE (SET_SRC (element)) != SImode
143           || REGNO (SET_SRC (element)) != src_regno - (i - 1)
144           || ! MEM_P (SET_DEST (element))
145           || GET_MODE (SET_DEST (element)) != SImode
146           || GET_CODE (XEXP (SET_DEST (element), 0)) != MINUS
147           || ! REG_P (XEXP (XEXP (SET_DEST (element), 0), 0))
148           ||   REGNO (XEXP (XEXP (SET_DEST (element), 0), 0)) != SP_REG
149           || ! CONST_INT_P (XEXP (XEXP (SET_DEST (element), 0), 1))
150           || INTVAL (XEXP (XEXP (SET_DEST (element), 0), 1))
151              != i * GET_MODE_SIZE (SImode))
152         return false;
153     }
154   return true;
157 ;; Return true if OP is a load multiple operation.
158 ;; This looks like:
159 ;;  [(set (SP) (PLUS (SP) (INT)))
160 ;;   (set (REG) (MEM (SP)))
161 ;;   (set (REG) (MEM (PLUS (SP) (INT)))) {optionally repeated}
162 ;;  ]
164 (define_special_predicate "rx_load_multiple_vector"
165   (match_code "parallel")
167   int count = XVECLEN (op, 0);
168   unsigned int dest_regno;
169   rtx element;
170   int i;
172   /* Perform a quick check so we don't blow up below.  */
173   if (count <= 2)
174     return false;
176   /* Check that the first element of the vector is the stack adjust.  */
177   element = XVECEXP (op, 0, 0);
178   if (   ! SET_P (element)
179       || ! REG_P (SET_DEST (element))
180       ||   REGNO (SET_DEST (element)) != SP_REG
181       ||   GET_CODE (SET_SRC (element)) != PLUS
182       || ! REG_P (XEXP (SET_SRC (element), 0))
183       ||   REGNO (XEXP (SET_SRC (element), 0)) != SP_REG
184       || ! CONST_INT_P (XEXP (SET_SRC (element), 1)))
185     return false;
186          
187   /* Check that the next element is the first push.  */
188   element = XVECEXP (op, 0, 1);
189   if (   ! SET_P (element)
190       || ! REG_P (SET_DEST (element))
191       || ! MEM_P (SET_SRC (element))
192       || ! REG_P (XEXP (SET_SRC (element), 0))
193       ||   REGNO (XEXP (SET_SRC (element), 0)) != SP_REG)
194     return false;
196   dest_regno = REGNO (SET_DEST (element));
198   /* Check that the remaining elements use SP+<disp>
199      addressing and incremental register numbers.  */
200   for (i = 2; i < count; i++)
201     {
202       element = XVECEXP (op, 0, i);
204       if (   ! SET_P (element)
205           || ! REG_P (SET_DEST (element))
206           || GET_MODE (SET_DEST (element)) != SImode
207           || REGNO (SET_DEST (element)) != dest_regno + (i - 1)
208           || ! MEM_P (SET_SRC (element))
209           || GET_MODE (SET_SRC (element)) != SImode
210           || GET_CODE (XEXP (SET_SRC (element), 0)) != PLUS
211           || ! REG_P (XEXP (XEXP (SET_SRC (element), 0), 0))
212           ||   REGNO (XEXP (XEXP (SET_SRC (element), 0), 0)) != SP_REG
213           || ! CONST_INT_P (XEXP (XEXP (SET_SRC (element), 0), 1))
214           || INTVAL (XEXP (XEXP (SET_SRC (element), 0), 1))
215              != (i - 1) * GET_MODE_SIZE (SImode))
216         return false;
217     }
218   return true;
221 ;; Return true if OP is a pop-and-return load multiple operation.
222 ;; This looks like:
223 ;;  [(set (SP) (PLUS (SP) (INT)))
224 ;;   (set (REG) (MEM (SP)))
225 ;;   (set (REG) (MEM (PLUS (SP) (INT)))) {optional and possibly repeated}
226 ;;   (return)
227 ;;  ]
229 (define_special_predicate "rx_rtsd_vector"
230   (match_code "parallel")
232   int count = XVECLEN (op, 0);
233   unsigned int dest_regno;
234   rtx element;
235   int i;
237   /* Perform a quick check so we don't blow up below.  */
238   if (count <= 2)
239     return false;
241   /* Check that the first element of the vector is the stack adjust.  */
242   element = XVECEXP (op, 0, 0);
243   if (   ! SET_P (element)
244       || ! REG_P (SET_DEST (element))
245       ||   REGNO (SET_DEST (element)) != SP_REG
246       ||   GET_CODE (SET_SRC (element)) != PLUS
247       || ! REG_P (XEXP (SET_SRC (element), 0))
248       ||   REGNO (XEXP (SET_SRC (element), 0)) != SP_REG
249       || ! CONST_INT_P (XEXP (SET_SRC (element), 1)))
250     return false;
251          
252   /* Check that the next element is the first push.  */
253   element = XVECEXP (op, 0, 1);
254   if (   ! SET_P (element)
255       || ! REG_P (SET_DEST (element))
256       || ! MEM_P (SET_SRC (element))
257       || ! REG_P (XEXP (SET_SRC (element), 0))
258       ||   REGNO (XEXP (SET_SRC (element), 0)) != SP_REG)
259     return false;
261   dest_regno = REGNO (SET_DEST (element));
263   /* Check that the remaining elements, if any, and except
264      for the last one, use SP+<disp> addressing and incremental
265      register numbers.  */
266   for (i = 2; i < count - 1; i++)
267     {
268       element = XVECEXP (op, 0, i);
270       if (   ! SET_P (element)
271           || ! REG_P (SET_DEST (element))
272           || GET_MODE (SET_DEST (element)) != SImode
273           || REGNO (SET_DEST (element)) != dest_regno + (i - 1)
274           || ! MEM_P (SET_SRC (element))
275           || GET_MODE (SET_SRC (element)) != SImode
276           || GET_CODE (XEXP (SET_SRC (element), 0)) != PLUS
277           || ! REG_P (XEXP (XEXP (SET_SRC (element), 0), 0))
278           ||   REGNO (XEXP (XEXP (SET_SRC (element), 0), 0)) != SP_REG
279           || ! CONST_INT_P (XEXP (XEXP (SET_SRC (element), 0), 1))
280           || INTVAL (XEXP (XEXP (SET_SRC (element), 0), 1))
281              != (i - 1) * GET_MODE_SIZE (SImode))
282         return false;
283     }
285   /* The last element must be a RETURN.  */    
286   element = XVECEXP (op, 0, count - 1);
287   return GET_CODE (element) == RETURN;
290 (define_predicate "label_ref_operand"
291   (match_code "label_ref")
294 (define_predicate "rx_z_comparison_operator"
295   (match_code "eq,ne")
298 (define_predicate "rx_zs_comparison_operator"
299   (match_code "eq,ne,lt,ge")
302 ;; GT and LE omitted due to operand swap required.
303 (define_predicate "rx_fp_comparison_operator"
304   (match_code "eq,ne,lt,ge,ordered,unordered")
307 (define_predicate "rshift_operator"
308   (match_code "ashiftrt,lshiftrt")