1 ;; Predicate definitions for TI PRU.
2 ;; Copyright (C) 2014-2023 Free Software Foundation, Inc.
3 ;; Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
5 ;; This file is part of GCC.
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)
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))
81 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
82 regno = REGNO (SUBREG_REG (op));
86 return REGNO_REG_CLASS (regno) == MULDST_REGS
87 || regno >= FIRST_PSEUDO_REGISTER;
92 (define_predicate "pru_mulsrc0_operand"
93 (match_code "subreg,reg")
95 if (register_operand (op, mode))
101 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
102 regno = REGNO (SUBREG_REG (op));
106 return REGNO_REG_CLASS (regno) == MULSRC0_REGNUM
107 || regno >= FIRST_PSEUDO_REGISTER;
112 (define_predicate "pru_mulsrc1_operand"
113 (match_code "subreg,reg")
115 if (register_operand (op, mode))
121 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
122 regno = REGNO (SUBREG_REG (op));
126 return REGNO_REG_CLASS (regno) == MULSRC1_REGNUM
127 || regno >= FIRST_PSEUDO_REGISTER;
132 (define_predicate "regio_operand"
133 (match_code "subreg,reg")
135 if (register_operand (op, mode))
141 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
142 regno = REGNO (SUBREG_REG (op));
146 return REGNO_REG_CLASS (regno) == REGIO_REGS;
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")
192 rtx base = strip_offset (op, &offset);
194 switch (GET_CODE (base))
197 /* Why AVR lists this as a valid option? Let's catch it. */
203 return SYMBOL_REF_FUNCTION_P (base);
206 /* Handle constructs like (&&label1 - &&label2). See pr70460.c. */
207 return text_segment_operand (XEXP (op, 0), VOIDmode);
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;
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)
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)
240 for (i = 1; i < count; i++)
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)
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))
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;
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)
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)
292 for (i = 1; i < count; i++)
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)
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))
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;