1;; Predicate definitions for TI PRU. 2;; Copyright (C) 2014-2020 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 "reg_or_const_int_operand" 125 (ior (match_operand 0 "const_int_operand") 126 (match_operand 0 "register_operand"))) 127 128(define_predicate "reg_or_ubyte_operand" 129 (ior (match_operand 0 "const_ubyte_operand") 130 (match_operand 0 "register_operand"))) 131 132(define_predicate "reg_or_const_1_operand" 133 (ior (match_operand 0 "const_1_operand") 134 (match_operand 0 "register_operand"))) 135 136(define_predicate "const_shift_operand" 137 (and (match_code "const_int") 138 (match_test "SHIFT_INT (INTVAL (op))"))) 139 140(define_predicate "shift_operand" 141 (ior (match_operand 0 "const_shift_operand") 142 (match_operand 0 "register_operand"))) 143 144(define_predicate "ctable_addr_operand" 145 (and (match_code "const_int") 146 (match_test "pru_get_ctable_base_index (INTVAL (op)) >= 0"))) 147 148(define_predicate "ctable_base_operand" 149 (and (match_code "const_int") 150 (match_test "pru_get_ctable_exact_base_index (INTVAL (op)) >= 0"))) 151 152;; Ideally we should enforce a restriction to all text labels to fit in 153;; 16bits, as required by the PRU ISA. But for the time being we'll rely on 154;; binutils to catch text segment overflows. 155(define_predicate "call_operand" 156 (ior (match_operand 0 "immediate_operand") 157 (match_operand 0 "register_operand"))) 158 159;; Return true if OP is a text segment reference. 160;; This is needed for program memory address expressions. Borrowed from AVR. 161(define_predicate "text_segment_operand" 162 (match_code "code_label,label_ref,symbol_ref,plus,minus") 163{ 164 poly_int64 offset; 165 rtx base = strip_offset (op, &offset); 166 167 switch (GET_CODE (base)) 168 { 169 case CODE_LABEL: 170 /* Why AVR lists this as a valid option? Let's catch it. */ 171 gcc_unreachable (); 172 return false; 173 case LABEL_REF: 174 return true; 175 case SYMBOL_REF: 176 return SYMBOL_REF_FUNCTION_P (base); 177 case PLUS: 178 case MINUS: 179 /* Handle constructs like (&&label1 - &&label2). See pr70460.c. */ 180 return text_segment_operand (XEXP (op, 0), VOIDmode); 181 default: 182 return false; 183 } 184}) 185 186;; Return true if OP is a load multiple operation. It is known to be a 187;; PARALLEL and the first section will be tested. 188 189(define_special_predicate "load_multiple_operation" 190 (match_code "parallel") 191{ 192 machine_mode elt_mode; 193 int count = XVECLEN (op, 0); 194 unsigned int dest_regno; 195 rtx src_addr, base_reg; 196 poly_int64 base_offs; 197 int i; 198 199 /* Perform a quick check so we don't blow up below. */ 200 if (GET_CODE (XVECEXP (op, 0, 0)) != SET 201 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG 202 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) 203 return false; 204 205 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); 206 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); 207 elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0))); 208 209 base_reg = strip_offset (src_addr, &base_offs); 210 if (GET_CODE (base_reg) != REG) 211 return false; 212 213 for (i = 1; i < count; i++) 214 { 215 rtx elt_reg; 216 poly_int64 elt_offs; 217 rtx elt = XVECEXP (op, 0, i); 218 219 if (GET_CODE (elt) != SET 220 || GET_CODE (SET_DEST (elt)) != REG 221 || GET_MODE (SET_DEST (elt)) != elt_mode 222 || REGNO (SET_DEST (elt)) != dest_regno + i * GET_MODE_SIZE (elt_mode) 223 || GET_CODE (SET_SRC (elt)) != MEM 224 || GET_MODE (SET_SRC (elt)) != elt_mode) 225 return false; 226 227 elt_reg = strip_offset (XEXP (SET_SRC (elt), 0), &elt_offs); 228 229 if (GET_CODE (elt_reg) != REG 230 || ! rtx_equal_p (elt_reg, base_reg) 231 || elt_offs != base_offs + i * GET_MODE_SIZE (elt_mode)) 232 return false; 233 } 234 235 return true; 236}) 237 238;; Return true if OP is a store multiple operation. It is known to be a 239;; PARALLEL and the first section will be tested. 240 241(define_special_predicate "store_multiple_operation" 242 (match_code "parallel") 243{ 244 machine_mode elt_mode; 245 int count = XVECLEN (op, 0); 246 unsigned int src_regno; 247 rtx dest_addr, base_reg; 248 poly_int64 base_offs; 249 int i; 250 251 /* Perform a quick check so we don't blow up below. */ 252 if (GET_CODE (XVECEXP (op, 0, 0)) != SET 253 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM 254 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) 255 return false; 256 257 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); 258 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); 259 elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0))); 260 261 base_reg = strip_offset (dest_addr, &base_offs); 262 if (GET_CODE (base_reg) != REG) 263 return false; 264 265 for (i = 1; i < count; i++) 266 { 267 rtx elt_reg; 268 poly_int64 elt_offs; 269 rtx elt = XVECEXP (op, 0, i); 270 271 if (GET_CODE (elt) != SET 272 || GET_CODE (SET_SRC (elt)) != REG 273 || GET_MODE (SET_SRC (elt)) != elt_mode 274 || REGNO (SET_SRC (elt)) != src_regno + i * GET_MODE_SIZE (elt_mode) 275 || GET_CODE (SET_DEST (elt)) != MEM 276 || GET_MODE (SET_DEST (elt)) != elt_mode) 277 return false; 278 279 elt_reg = strip_offset (XEXP (SET_DEST (elt), 0), &elt_offs); 280 281 if (GET_CODE (elt_reg) != REG 282 || ! rtx_equal_p (elt_reg, base_reg) 283 || elt_offs != base_offs + i * GET_MODE_SIZE (elt_mode)) 284 return false; 285 } 286 return true; 287}) 288