1/* Predicates for TI C6X 2 Copyright (C) 2010-2013 Free Software Foundation, Inc. 3 Contributed by Andrew Jenner <andrew@codesourcery.com> 4 Contributed by Bernd Schmidt <bernds@codesourcery.com> 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify it 9 under the terms of the GNU General Public License as published 10 by the Free Software Foundation; either version 3, or (at your 11 option) any later version. 12 13 GCC is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 16 License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GCC; see the file COPYING3. If not see 20 <http://www.gnu.org/licenses/>. */ 21 22(define_predicate "reg_or_const_int_operand" 23 (ior (match_operand 0 "register_operand") 24 (match_operand 0 "const_int_operand"))) 25 26(define_predicate "const_vector_operand" 27 (match_code "const_vector")) 28 29(define_predicate "scst5_operand" 30 (and (match_operand 0 "const_int_operand") 31 (match_test "satisfies_constraint_Is5 (op)"))) 32 33(define_predicate "reg_or_ucst4_operand" 34 (ior (match_operand 0 "register_operand") 35 (and (match_operand 0 "const_int_operand") 36 (match_test "satisfies_constraint_Iu4 (op)")))) 37 38(define_predicate "reg_or_scst5_operand" 39 (ior (match_operand 0 "register_operand") 40 (match_operand 0 "scst5_operand"))) 41 42(define_predicate "reg_or_ucst5_operand" 43 (ior (match_operand 0 "register_operand") 44 (and (match_operand 0 "const_int_operand") 45 (match_test "satisfies_constraint_Iu5 (op)")))) 46 47(define_predicate "addsi_operand" 48 (ior (match_operand 0 "register_operand") 49 (and (match_operand 0 "const_int_operand") 50 (match_test "satisfies_constraint_IsB (op)")))) 51 52(define_predicate "andsi_operand" 53 (ior (match_operand 0 "reg_or_scst5_operand") 54 (and (match_operand 0 "const_int_operand") 55 (match_test "satisfies_constraint_Jc (op)")))) 56 57(define_predicate "iorsi_operand" 58 (ior (match_operand 0 "reg_or_scst5_operand") 59 (and (match_operand 0 "const_int_operand") 60 (match_test "satisfies_constraint_Js (op)")))) 61 62(define_predicate "insv_operand" 63 (and (match_operand 0 "const_int_operand") 64 (match_test "INTVAL (op) == 0 || INTVAL (op) == -1"))) 65 66(define_predicate "c6x_jump_operand" 67 (match_code "label_ref,symbol_ref,reg")) 68 69(define_predicate "c6x_call_operand" 70 (ior (match_code "symbol_ref,reg") 71 (and (match_code "subreg") 72 (match_test "GET_CODE (XEXP (op, 0)) == REG"))) 73{ 74 /* The linker transforms jumps to undefined weak symbols in a way that 75 is incompatible with our code generation. */ 76 return (GET_CODE (op) != SYMBOL_REF 77 || (!SYMBOL_REF_WEAK (op) 78 && !c6x_long_call_p (op))); 79}) 80 81;; Returns 1 if OP is a symbolic operand, i.e. a symbol_ref or a label_ref, 82;; possibly with an offset. 83(define_predicate "symbolic_operand" 84 (ior (match_code "symbol_ref,label_ref") 85 (and (match_code "const") 86 (match_test "GET_CODE (XEXP (op,0)) == PLUS 87 && (GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF 88 || GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF) 89 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT")))) 90 91(define_predicate "const_int_or_symbolic_operand" 92 (ior (match_operand 0 "symbolic_operand") 93 (match_operand 0 "const_int_operand"))) 94 95;; Return nonzero iff OP is one of the integer constants 2, 4 or 8. 96(define_predicate "adda_scale_operand" 97 (and (match_code "const_int") 98 (match_test "INTVAL (op) == 2 || INTVAL (op) == 4 99 || ((TARGET_INSNS_64 || TARGET_INSNS_67) 100 && INTVAL (op) == 8)"))) 101 102;; Return nonzero iff OP is one of the integer constants 2 or 4. 103(define_predicate "suba_scale_operand" 104 (and (match_code "const_int") 105 (match_test "INTVAL (op) == 2 || INTVAL (op) == 4"))) 106 107;; True if this operator is valid for predication. 108(define_predicate "predicate_operator" 109 (match_code "eq,ne")) 110 111(define_predicate "c6x_comparison_operator" 112 (match_code "eq,ltu,gtu,lt,gt")) 113 114(define_predicate "non_c6x_comparison_operator" 115 (match_code "ne,leu,geu,le,ge")) 116 117;; FP Comparisons handled by c6x_expand_compare. 118(define_predicate "c6x_fp_comparison_operator" 119 (ior (match_code "eq,lt,gt,le,ge") 120 (and (match_test "TARGET_FP") 121 (match_code "ltgt,uneq,unlt,ungt,unle,unge,ordered,unordered")))) 122 123(define_predicate "c6x_any_comparison_operand" 124 (match_code "eq,lt,gt,le,ge,ltu,gtu") 125{ 126 rtx op0 = XEXP (op, 0); 127 rtx op1 = XEXP (op, 1); 128 if (ltugtu_operator (op, SImode) 129 && register_operand (op0, SImode) 130 && ((TARGET_INSNS_64 && reg_or_ucst5_operand (op1, SImode)) 131 || (!TARGET_INSNS_64 && reg_or_ucst4_operand (op1, SImode)))) 132 return true; 133 if (eqltgt_operator (op, SImode) 134 && register_operand (op0, SImode) 135 && reg_or_scst5_operand (op1, SImode)) 136 return true; 137 if (!TARGET_FP) 138 return false; 139 if (!eqltgt_operator (op, SFmode) && !eqltgt_operator (op, DFmode)) 140 return false; 141 if (register_operand (op0, GET_MODE (op)) 142 && register_operand (op1, GET_MODE (op))) 143 return true; 144 return false; 145}) 146 147(define_predicate "ltugtu_operator" 148 (match_code "ltu,gtu")) 149 150(define_predicate "eqltgt_operator" 151 (match_code "eq,lt,gt")) 152 153(define_predicate "eqne_operator" 154 (match_code "eq,ne")) 155 156(define_predicate "predicate_register" 157 (and (match_code "reg") 158 (ior (match_test "REGNO_REG_CLASS (REGNO (op)) == PREDICATE_A_REGS") 159 (match_test "REGNO_REG_CLASS (REGNO (op)) == PREDICATE_B_REGS")))) 160 161;; Allow const_ints for things like the real_mult patterns. 162(define_predicate "a_register" 163 (ior (and (match_code "reg") 164 (match_test "A_REGNO_P (REGNO (op))")) 165 (and (match_code "const_int") 166 (match_test "A_REGNO_P (INTVAL (op))")))) 167 168(define_predicate "b_register" 169 (ior (and (match_code "reg") 170 (match_test "B_REGNO_P (REGNO (op))")) 171 (and (match_code "const_int") 172 (match_test "B_REGNO_P (INTVAL (op))")))) 173 174(define_predicate "pic_register_operand" 175 (and (match_code "reg") 176 (match_test "op == pic_offset_table_rtx"))) 177 178;; True if OP refers to a symbol in the sdata section. 179(define_predicate "sdata_symbolic_operand" 180 (match_code "symbol_ref,const") 181{ 182 HOST_WIDE_INT offset = 0, size = 0; 183 tree t; 184 185 switch (GET_CODE (op)) 186 { 187 case CONST: 188 op = XEXP (op, 0); 189 if (GET_CODE (op) != PLUS 190 || GET_CODE (XEXP (op, 0)) != SYMBOL_REF 191 || GET_CODE (XEXP (op, 1)) != CONST_INT) 192 return false; 193 offset = INTVAL (XEXP (op, 1)); 194 op = XEXP (op, 0); 195 /* FALLTHRU */ 196 197 case SYMBOL_REF: 198 /* For shared libraries, only allow symbols we know are local. 199 For executables, the linker knows to create copy relocs if 200 necessary so we can use DP-relative addressing for all small 201 objects. */ 202 if ((c6x_initial_flag_pic && !SYMBOL_REF_LOCAL_P (op)) 203 || !SYMBOL_REF_SMALL_P (op)) 204 return false; 205 206 /* Note that in addition to DECLs, we can get various forms 207 of constants here. */ 208 t = SYMBOL_REF_DECL (op); 209 if (DECL_P (t)) 210 t = DECL_SIZE_UNIT (t); 211 else 212 t = TYPE_SIZE_UNIT (TREE_TYPE (t)); 213 if (t && host_integerp (t, 0)) 214 { 215 size = tree_low_cst (t, 0); 216 if (size < 0) 217 size = 0; 218 } 219 220 /* Don't allow addressing outside the object. */ 221 return (offset >= 0 && offset <= size); 222 223 default: 224 gcc_unreachable (); 225 } 226}) 227