Skip analyzer strndup test on hppa*-*-hpux*
[official-gcc.git] / gcc / config / pru / predicates.md
blobfaa0dbf9fb4119ac366210e9f9a6afd7c1d1ce2f
1 ;; Predicate definitions for TI PRU.
2 ;; Copyright (C) 2014-2023 Free Software Foundation, Inc.
3 ;; Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
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/>.
21 (define_predicate "const_1_operand"
22   (and (match_code "const_int")
23        (match_test "INTVAL (op) == 1")))
25 (define_predicate "const_0_operand"
26   (and (match_code "const_int")
27        (match_test "INTVAL (op) == 0")))
29 ; Note: Always pass a valid mode!
30 (define_predicate "const_ubyte_operand"
31   (match_code "const_int")
33   gcc_assert (mode != VOIDmode);
34   return IN_RANGE (INTVAL (op) & GET_MODE_MASK (mode), 0, 0xff);
37 (define_predicate "const_uhword_operand"
38   (match_code "const_int")
40   gcc_assert (mode != VOIDmode);
41   return IN_RANGE (INTVAL (op) & GET_MODE_MASK (mode), 0, 0xffff);
44 ; TRUE for comparisons we support.
45 (define_predicate "pru_cmp_operator"
46   (match_code "eq,ne,leu,ltu,geu,gtu"))
48 ; TRUE for signed comparisons that need special handling for PRU.
49 (define_predicate "pru_signed_cmp_operator"
50   (match_code "ge,gt,le,lt"))
52 ;; FP Comparisons handled by pru_expand_pru_compare.
53 (define_predicate "pru_fp_comparison_operator"
54   (match_code "eq,ne,lt,gt,le,ge"))
56 ;; TRUE for comparisons supported by PRU's cstore.
57 (define_predicate "pru_cstore_comparison_operator"
58   (match_code "eq,ne,gtu"))
60 ;; Return true if OP is a constant that contains only one 1 in its
61 ;; binary representation.
62 (define_predicate "single_one_operand"
63   (and (match_code "const_int")
64        (match_test "exact_log2 (INTVAL (op) & GET_MODE_MASK (mode)) >= 0")))
66 ;; Return true if OP is a constant that contains only one 0 in its
67 ;; binary representation.
68 (define_predicate "single_zero_operand"
69   (and (match_code "const_int")
70        (match_test "exact_log2 (~INTVAL (op) & GET_MODE_MASK (mode)) >= 0")))
72 (define_predicate "pru_muldst_operand"
73   (match_code "subreg,reg")
75   if (register_operand (op, mode))
76     {
77       int regno;
79       if (REG_P (op))
80         regno = REGNO (op);
81       else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
82         regno = REGNO (SUBREG_REG (op));
83       else
84         return 0;
86       return REGNO_REG_CLASS (regno) == MULDST_REGS
87              || regno >= FIRST_PSEUDO_REGISTER;
88     }
89   return 0;
92 (define_predicate "pru_mulsrc0_operand"
93   (match_code "subreg,reg")
95   if (register_operand (op, mode))
96     {
97       int regno;
99       if (REG_P (op))
100         regno = REGNO (op);
101       else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
102         regno = REGNO (SUBREG_REG (op));
103       else
104         return 0;
106       return REGNO_REG_CLASS (regno) == MULSRC0_REGNUM
107              || regno >= FIRST_PSEUDO_REGISTER;
108     }
109   return 0;
112 (define_predicate "pru_mulsrc1_operand"
113   (match_code "subreg,reg")
115   if (register_operand (op, mode))
116     {
117       int regno;
119       if (REG_P (op))
120         regno = REGNO (op);
121       else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
122         regno = REGNO (SUBREG_REG (op));
123       else
124         return 0;
126       return REGNO_REG_CLASS (regno) == MULSRC1_REGNUM
127              || regno >= FIRST_PSEUDO_REGISTER;
128     }
129   return 0;
132 (define_predicate "regio_operand"
133   (match_code "subreg,reg")
135   if (register_operand (op, mode))
136     {
137       int regno;
139       if (REG_P (op))
140         regno = REGNO (op);
141       else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
142         regno = REGNO (SUBREG_REG (op));
143       else
144         return 0;
146       return REGNO_REG_CLASS (regno) == REGIO_REGS;
147     }
148   return 0;
151 (define_predicate "reg_or_const_int_operand"
152   (ior (match_operand 0 "const_int_operand")
153        (match_operand 0 "register_operand")))
155 (define_predicate "reg_or_ubyte_operand"
156   (ior (match_operand 0 "const_ubyte_operand")
157        (match_operand 0 "register_operand")))
159 (define_predicate "reg_or_const_1_operand"
160   (ior (match_operand 0 "const_1_operand")
161        (match_operand 0 "register_operand")))
163 (define_predicate "const_shift_operand"
164   (and (match_code "const_int")
165        (match_test "SHIFT_INT (INTVAL (op))")))
167 (define_predicate "shift_operand"
168   (ior (match_operand 0 "const_shift_operand")
169        (match_operand 0 "register_operand")))
171 (define_predicate "ctable_addr_operand"
172   (and (match_code "const_int")
173        (match_test "pru_get_ctable_base_index (INTVAL (op)) >= 0")))
175 (define_predicate "ctable_base_operand"
176   (and (match_code "const_int")
177        (match_test "pru_get_ctable_exact_base_index (INTVAL (op)) >= 0")))
179 ;; Ideally we should enforce a restriction to all text labels to fit in
180 ;; 16bits, as required by the PRU ISA.  But for the time being we'll rely on
181 ;; binutils to catch text segment overflows.
182 (define_predicate "call_operand"
183   (ior (match_operand 0 "immediate_operand")
184        (match_operand 0 "register_operand")))
186 ;; Return true if OP is a text segment reference.
187 ;; This is needed for program memory address expressions.  Borrowed from AVR.
188 (define_predicate "text_segment_operand"
189   (match_code "code_label,label_ref,symbol_ref,plus,minus")
191   poly_int64 offset;
192   rtx base = strip_offset (op, &offset);
194   switch (GET_CODE (base))
195     {
196     case CODE_LABEL:
197       /* Why AVR lists this as a valid option?  Let's catch it.  */
198       gcc_unreachable ();
199       return false;
200     case LABEL_REF:
201       return true;
202     case SYMBOL_REF:
203       return SYMBOL_REF_FUNCTION_P (base);
204     case PLUS:
205     case MINUS:
206       /* Handle constructs like (&&label1 - &&label2).  See pr70460.c.  */
207       return text_segment_operand (XEXP (op, 0), VOIDmode);
208     default:
209       return false;
210     }
213 ;; Return true if OP is a load multiple operation.  It is known to be a
214 ;; PARALLEL and the first section will be tested.
216 (define_special_predicate "load_multiple_operation"
217   (match_code "parallel")
219   machine_mode elt_mode;
220   int count = XVECLEN (op, 0);
221   unsigned int dest_regno;
222   rtx src_addr, base_reg;
223   poly_int64 base_offs;
224   int i;
226   /* Perform a quick check so we don't blow up below.  */
227   if (GET_CODE (XVECEXP (op, 0, 0)) != SET
228       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
229       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
230     return false;
232   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
233   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
234   elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0)));
236   base_reg = strip_offset (src_addr, &base_offs);
237   if (GET_CODE (base_reg) != REG)
238     return false;
240   for (i = 1; i < count; i++)
241     {
242       rtx elt_reg;
243       poly_int64 elt_offs;
244       rtx elt = XVECEXP (op, 0, i);
246       if (GET_CODE (elt) != SET
247           || GET_CODE (SET_DEST (elt)) != REG
248           || GET_MODE (SET_DEST (elt)) != elt_mode
249           || REGNO (SET_DEST (elt)) != dest_regno + i * GET_MODE_SIZE (elt_mode)
250           || GET_CODE (SET_SRC (elt)) != MEM
251           || GET_MODE (SET_SRC (elt)) != elt_mode)
252         return false;
254       elt_reg = strip_offset (XEXP (SET_SRC (elt), 0), &elt_offs);
256       if (GET_CODE (elt_reg) != REG
257           || ! rtx_equal_p (elt_reg, base_reg)
258           || elt_offs != base_offs + i * GET_MODE_SIZE (elt_mode))
259         return false;
260     }
262   return true;
265 ;; Return true if OP is a store multiple operation.  It is known to be a
266 ;; PARALLEL and the first section will be tested.
268 (define_special_predicate "store_multiple_operation"
269   (match_code "parallel")
271   machine_mode elt_mode;
272   int count = XVECLEN (op, 0);
273   unsigned int src_regno;
274   rtx dest_addr, base_reg;
275   poly_int64 base_offs;
276   int i;
278   /* Perform a quick check so we don't blow up below.  */
279   if (GET_CODE (XVECEXP (op, 0, 0)) != SET
280       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
281       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
282     return false;
284   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
285   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
286   elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0)));
288   base_reg = strip_offset (dest_addr, &base_offs);
289   if (GET_CODE (base_reg) != REG)
290     return false;
292   for (i = 1; i < count; i++)
293     {
294       rtx elt_reg;
295       poly_int64 elt_offs;
296       rtx elt = XVECEXP (op, 0, i);
298       if (GET_CODE (elt) != SET
299           || GET_CODE (SET_SRC (elt)) != REG
300           || GET_MODE (SET_SRC (elt)) != elt_mode
301           || REGNO (SET_SRC (elt)) != src_regno + i * GET_MODE_SIZE (elt_mode)
302           || GET_CODE (SET_DEST (elt)) != MEM
303           || GET_MODE (SET_DEST (elt)) != elt_mode)
304         return false;
306       elt_reg = strip_offset (XEXP (SET_DEST (elt), 0), &elt_offs);
308       if (GET_CODE (elt_reg) != REG
309           || ! rtx_equal_p (elt_reg, base_reg)
310           || elt_offs != base_offs + i * GET_MODE_SIZE (elt_mode))
311         return false;
312     }
313   return true;
316 ;; Return true if OP is a constant integer with one single consecutive
317 ;; range of bytes with value 0xff, and the rest of the bytes are 0x00.
318 (define_predicate "const_fillbytes_operand"
319   (match_code "const_int")
321   gcc_assert (mode != VOIDmode);
323   pru_byterange r = pru_calc_byterange (INTVAL (op), mode);
324   return r.start >=0 && r.nbytes > 0;
327 ;; Return true if OP is a constant integer with one single consecutive
328 ;; range of bytes with value 0x00, and the rest of the bytes are 0xff.
329 (define_predicate "const_zerobytes_operand"
330   (match_code "const_int")
332   gcc_assert (mode != VOIDmode);
334   pru_byterange r = pru_calc_byterange (~INTVAL (op), mode);
335   return r.start >=0 && r.nbytes > 0;