1;; Predicate definitions for TI PRU. 2;; Copyright (C) 2014-2022 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. 11;; 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. 16;; 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/>. 20 21(define_predicate "const_1_operand" 22 (and (match_code "const_int") 23 (match_test "INTVAL (op) == 1"))) 24 25; Note: Always pass a valid mode! 26(define_predicate "const_ubyte_operand" 27 (match_code "const_int") 28{ 29 gcc_assert (mode != VOIDmode); 30 return IN_RANGE (INTVAL (op) & GET_MODE_MASK (mode), 0, 0xff); 31}) 32 33(define_predicate "const_uhword_operand" 34 (match_code "const_int") 35{ 36 gcc_assert (mode != VOIDmode); 37 return IN_RANGE (INTVAL (op) & GET_MODE_MASK (mode), 0, 0xffff); 38}) 39 40; TRUE for comparisons we support. 41(define_predicate "pru_cmp_operator" 42 (match_code "eq,ne,leu,ltu,geu,gtu")) 43 44; TRUE for signed comparisons that need special handling for PRU. 45(define_predicate "pru_signed_cmp_operator" 46 (match_code "ge,gt,le,lt")) 47 48;; FP Comparisons handled by pru_expand_pru_compare. 49(define_predicate "pru_fp_comparison_operator" 50 (match_code "eq,ne,lt,gt,le,ge")) 51 52;; Return true if OP is a constant that contains only one 1 in its 53;; binary representation. 54(define_predicate "single_one_operand" 55 (and (match_code "const_int") 56 (match_test "exact_log2 (INTVAL (op) & GET_MODE_MASK (mode)) >= 0"))) 57 58;; Return true if OP is a constant that contains only one 0 in its 59;; binary representation. 60(define_predicate "single_zero_operand" 61 (and (match_code "const_int") 62 (match_test "exact_log2 (~INTVAL (op) & GET_MODE_MASK (mode)) >= 0"))) 63 64(define_predicate "pru_muldst_operand" 65 (match_code "subreg,reg") 66{ 67 if (register_operand (op, mode)) 68 { 69 int regno; 70 71 if (REG_P (op)) 72 regno = REGNO (op); 73 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op))) 74 regno = REGNO (SUBREG_REG (op)); 75 else 76 return 0; 77 78 return REGNO_REG_CLASS (regno) == MULDST_REGS 79 || regno >= FIRST_PSEUDO_REGISTER; 80 } 81 return 0; 82}) 83 84(define_predicate "pru_mulsrc0_operand" 85 (match_code "subreg,reg") 86{ 87 if (register_operand (op, mode)) 88 { 89 int regno; 90 91 if (REG_P (op)) 92 regno = REGNO (op); 93 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op))) 94 regno = REGNO (SUBREG_REG (op)); 95 else 96 return 0; 97 98 return REGNO_REG_CLASS (regno) == MULSRC0_REGNUM 99 || regno >= FIRST_PSEUDO_REGISTER; 100 } 101 return 0; 102}) 103 104(define_predicate "pru_mulsrc1_operand" 105 (match_code "subreg,reg") 106{ 107 if (register_operand (op, mode)) 108 { 109 int regno; 110 111 if (REG_P (op)) 112 regno = REGNO (op); 113 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op))) 114 regno = REGNO (SUBREG_REG (op)); 115 else 116 return 0; 117 118 return REGNO_REG_CLASS (regno) == MULSRC1_REGNUM 119 || regno >= FIRST_PSEUDO_REGISTER; 120 } 121 return 0; 122}) 123 124(define_predicate "regio_operand" 125 (match_code "subreg,reg") 126{ 127 if (register_operand (op, mode)) 128 { 129 int regno; 130 131 if (REG_P (op)) 132 regno = REGNO (op); 133 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op))) 134 regno = REGNO (SUBREG_REG (op)); 135 else 136 return 0; 137 138 return REGNO_REG_CLASS (regno) == REGIO_REGS; 139 } 140 return 0; 141}) 142 143(define_predicate "reg_or_const_int_operand" 144 (ior (match_operand 0 "const_int_operand") 145 (match_operand 0 "register_operand"))) 146 147(define_predicate "reg_or_ubyte_operand" 148 (ior (match_operand 0 "const_ubyte_operand") 149 (match_operand 0 "register_operand"))) 150 151(define_predicate "reg_or_const_1_operand" 152 (ior (match_operand 0 "const_1_operand") 153 (match_operand 0 "register_operand"))) 154 155(define_predicate "const_shift_operand" 156 (and (match_code "const_int") 157 (match_test "SHIFT_INT (INTVAL (op))"))) 158 159(define_predicate "shift_operand" 160 (ior (match_operand 0 "const_shift_operand") 161 (match_operand 0 "register_operand"))) 162 163(define_predicate "ctable_addr_operand" 164 (and (match_code "const_int") 165 (match_test "pru_get_ctable_base_index (INTVAL (op)) >= 0"))) 166 167(define_predicate "ctable_base_operand" 168 (and (match_code "const_int") 169 (match_test "pru_get_ctable_exact_base_index (INTVAL (op)) >= 0"))) 170 171;; Ideally we should enforce a restriction to all text labels to fit in 172;; 16bits, as required by the PRU ISA. But for the time being we'll rely on 173;; binutils to catch text segment overflows. 174(define_predicate "call_operand" 175 (ior (match_operand 0 "immediate_operand") 176 (match_operand 0 "register_operand"))) 177 178;; Return true if OP is a text segment reference. 179;; This is needed for program memory address expressions. Borrowed from AVR. 180(define_predicate "text_segment_operand" 181 (match_code "code_label,label_ref,symbol_ref,plus,minus") 182{ 183 poly_int64 offset; 184 rtx base = strip_offset (op, &offset); 185 186 switch (GET_CODE (base)) 187 { 188 case CODE_LABEL: 189 /* Why AVR lists this as a valid option? Let's catch it. */ 190 gcc_unreachable (); 191 return false; 192 case LABEL_REF: 193 return true; 194 case SYMBOL_REF: 195 return SYMBOL_REF_FUNCTION_P (base); 196 case PLUS: 197 case MINUS: 198 /* Handle constructs like (&&label1 - &&label2). See pr70460.c. */ 199 return text_segment_operand (XEXP (op, 0), VOIDmode); 200 default: 201 return false; 202 } 203}) 204 205;; Return true if OP is a load multiple operation. It is known to be a 206;; PARALLEL and the first section will be tested. 207 208(define_special_predicate "load_multiple_operation" 209 (match_code "parallel") 210{ 211 machine_mode elt_mode; 212 int count = XVECLEN (op, 0); 213 unsigned int dest_regno; 214 rtx src_addr, base_reg; 215 poly_int64 base_offs; 216 int i; 217 218 /* Perform a quick check so we don't blow up below. */ 219 if (GET_CODE (XVECEXP (op, 0, 0)) != SET 220 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG 221 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) 222 return false; 223 224 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); 225 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); 226 elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0))); 227 228 base_reg = strip_offset (src_addr, &base_offs); 229 if (GET_CODE (base_reg) != REG) 230 return false; 231 232 for (i = 1; i < count; i++) 233 { 234 rtx elt_reg; 235 poly_int64 elt_offs; 236 rtx elt = XVECEXP (op, 0, i); 237 238 if (GET_CODE (elt) != SET 239 || GET_CODE (SET_DEST (elt)) != REG 240 || GET_MODE (SET_DEST (elt)) != elt_mode 241 || REGNO (SET_DEST (elt)) != dest_regno + i * GET_MODE_SIZE (elt_mode) 242 || GET_CODE (SET_SRC (elt)) != MEM 243 || GET_MODE (SET_SRC (elt)) != elt_mode) 244 return false; 245 246 elt_reg = strip_offset (XEXP (SET_SRC (elt), 0), &elt_offs); 247 248 if (GET_CODE (elt_reg) != REG 249 || ! rtx_equal_p (elt_reg, base_reg) 250 || elt_offs != base_offs + i * GET_MODE_SIZE (elt_mode)) 251 return false; 252 } 253 254 return true; 255}) 256 257;; Return true if OP is a store multiple operation. It is known to be a 258;; PARALLEL and the first section will be tested. 259 260(define_special_predicate "store_multiple_operation" 261 (match_code "parallel") 262{ 263 machine_mode elt_mode; 264 int count = XVECLEN (op, 0); 265 unsigned int src_regno; 266 rtx dest_addr, base_reg; 267 poly_int64 base_offs; 268 int i; 269 270 /* Perform a quick check so we don't blow up below. */ 271 if (GET_CODE (XVECEXP (op, 0, 0)) != SET 272 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM 273 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) 274 return false; 275 276 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); 277 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); 278 elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0))); 279 280 base_reg = strip_offset (dest_addr, &base_offs); 281 if (GET_CODE (base_reg) != REG) 282 return false; 283 284 for (i = 1; i < count; i++) 285 { 286 rtx elt_reg; 287 poly_int64 elt_offs; 288 rtx elt = XVECEXP (op, 0, i); 289 290 if (GET_CODE (elt) != SET 291 || GET_CODE (SET_SRC (elt)) != REG 292 || GET_MODE (SET_SRC (elt)) != elt_mode 293 || REGNO (SET_SRC (elt)) != src_regno + i * GET_MODE_SIZE (elt_mode) 294 || GET_CODE (SET_DEST (elt)) != MEM 295 || GET_MODE (SET_DEST (elt)) != elt_mode) 296 return false; 297 298 elt_reg = strip_offset (XEXP (SET_DEST (elt), 0), &elt_offs); 299 300 if (GET_CODE (elt_reg) != REG 301 || ! rtx_equal_p (elt_reg, base_reg) 302 || elt_offs != base_offs + i * GET_MODE_SIZE (elt_mode)) 303 return false; 304 } 305 return true; 306}) 307