1;; Machine description for AArch64 architecture. 2;; Copyright (C) 2009-2013 Free Software Foundation, Inc. 3;; Contributed by ARM Ltd. 4;; 5;; This file is part of GCC. 6;; 7;; GCC is free software; you can redistribute it and/or modify it 8;; 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, but 13;; WITHOUT ANY WARRANTY; without even the implied warranty of 14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15;; 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_special_predicate "cc_register" 22 (and (match_code "reg") 23 (and (match_test "REGNO (op) == CC_REGNUM") 24 (ior (match_test "mode == GET_MODE (op)") 25 (match_test "mode == VOIDmode 26 && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC")))) 27) 28 29(define_predicate "aarch64_reg_or_zero" 30 (and (match_code "reg,subreg,const_int") 31 (ior (match_operand 0 "register_operand") 32 (match_test "op == const0_rtx")))) 33 34(define_predicate "aarch64_reg_or_fp_zero" 35 (and (match_code "reg,subreg,const_double") 36 (ior (match_operand 0 "register_operand") 37 (match_test "aarch64_float_const_zero_rtx_p (op)")))) 38 39(define_predicate "aarch64_reg_zero_or_m1_or_1" 40 (and (match_code "reg,subreg,const_int") 41 (ior (match_operand 0 "register_operand") 42 (ior (match_test "op == const0_rtx") 43 (ior (match_test "op == constm1_rtx") 44 (match_test "op == const1_rtx")))))) 45 46(define_predicate "aarch64_fp_compare_operand" 47 (ior (match_operand 0 "register_operand") 48 (and (match_code "const_double") 49 (match_test "aarch64_float_const_zero_rtx_p (op)")))) 50 51(define_predicate "aarch64_plus_immediate" 52 (and (match_code "const_int") 53 (ior (match_test "aarch64_uimm12_shift (INTVAL (op))") 54 (match_test "aarch64_uimm12_shift (-INTVAL (op))")))) 55 56(define_predicate "aarch64_plus_operand" 57 (ior (match_operand 0 "register_operand") 58 (match_operand 0 "aarch64_plus_immediate"))) 59 60(define_predicate "aarch64_pluslong_immediate" 61 (and (match_code "const_int") 62 (match_test "(INTVAL (op) < 0xffffff && INTVAL (op) > -0xffffff)"))) 63 64(define_predicate "aarch64_pluslong_operand" 65 (ior (match_operand 0 "register_operand") 66 (match_operand 0 "aarch64_pluslong_immediate"))) 67 68(define_predicate "aarch64_logical_immediate" 69 (and (match_code "const_int") 70 (match_test "aarch64_bitmask_imm (INTVAL (op), mode)"))) 71 72(define_predicate "aarch64_logical_operand" 73 (ior (match_operand 0 "register_operand") 74 (match_operand 0 "aarch64_logical_immediate"))) 75 76(define_predicate "aarch64_shift_imm_si" 77 (and (match_code "const_int") 78 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 32"))) 79 80(define_predicate "aarch64_shift_imm_di" 81 (and (match_code "const_int") 82 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 64"))) 83 84(define_predicate "aarch64_reg_or_shift_imm_si" 85 (ior (match_operand 0 "register_operand") 86 (match_operand 0 "aarch64_shift_imm_si"))) 87 88(define_predicate "aarch64_reg_or_shift_imm_di" 89 (ior (match_operand 0 "register_operand") 90 (match_operand 0 "aarch64_shift_imm_di"))) 91 92;; The imm3 field is a 3-bit field that only accepts immediates in the 93;; range 0..4. 94(define_predicate "aarch64_imm3" 95 (and (match_code "const_int") 96 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 4"))) 97 98(define_predicate "aarch64_pwr_imm3" 99 (and (match_code "const_int") 100 (match_test "INTVAL (op) != 0 101 && (unsigned) exact_log2 (INTVAL (op)) <= 4"))) 102 103(define_predicate "aarch64_pwr_2_si" 104 (and (match_code "const_int") 105 (match_test "INTVAL (op) != 0 106 && (unsigned) exact_log2 (INTVAL (op)) < 32"))) 107 108(define_predicate "aarch64_pwr_2_di" 109 (and (match_code "const_int") 110 (match_test "INTVAL (op) != 0 111 && (unsigned) exact_log2 (INTVAL (op)) < 64"))) 112 113(define_predicate "aarch64_mem_pair_operand" 114 (and (match_code "mem") 115 (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL, 116 0)"))) 117 118(define_predicate "aarch64_const_address" 119 (and (match_code "symbol_ref") 120 (match_test "mode == DImode && CONSTANT_ADDRESS_P (op)"))) 121 122(define_predicate "aarch64_valid_symref" 123 (match_code "const, symbol_ref, label_ref") 124{ 125 enum aarch64_symbol_type symbol_type; 126 return (aarch64_symbolic_constant_p (op, SYMBOL_CONTEXT_ADR, &symbol_type) 127 && symbol_type != SYMBOL_FORCE_TO_MEM); 128}) 129 130(define_predicate "aarch64_tls_ie_symref" 131 (match_code "const, symbol_ref, label_ref") 132{ 133 switch (GET_CODE (op)) 134 { 135 case CONST: 136 op = XEXP (op, 0); 137 if (GET_CODE (op) != PLUS 138 || GET_CODE (XEXP (op, 0)) != SYMBOL_REF 139 || GET_CODE (XEXP (op, 1)) != CONST_INT) 140 return false; 141 op = XEXP (op, 0); 142 143 case SYMBOL_REF: 144 return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC; 145 146 default: 147 gcc_unreachable (); 148 } 149}) 150 151(define_predicate "aarch64_tls_le_symref" 152 (match_code "const, symbol_ref, label_ref") 153{ 154 switch (GET_CODE (op)) 155 { 156 case CONST: 157 op = XEXP (op, 0); 158 if (GET_CODE (op) != PLUS 159 || GET_CODE (XEXP (op, 0)) != SYMBOL_REF 160 || GET_CODE (XEXP (op, 1)) != CONST_INT) 161 return false; 162 op = XEXP (op, 0); 163 164 case SYMBOL_REF: 165 return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC; 166 167 default: 168 gcc_unreachable (); 169 } 170}) 171 172(define_predicate "aarch64_mov_operand" 173 (and (match_code "reg,subreg,mem,const_int,symbol_ref,high") 174 (ior (match_operand 0 "register_operand") 175 (ior (match_operand 0 "memory_operand") 176 (ior (match_test "GET_CODE (op) == HIGH 177 && aarch64_valid_symref (XEXP (op, 0), 178 GET_MODE (XEXP (op, 0)))") 179 (ior (match_test "CONST_INT_P (op) 180 && aarch64_move_imm (INTVAL (op), mode)") 181 (match_test "aarch64_const_address (op, mode)"))))))) 182 183(define_predicate "aarch64_movti_operand" 184 (and (match_code "reg,subreg,mem,const_int") 185 (ior (match_operand 0 "register_operand") 186 (ior (match_operand 0 "memory_operand") 187 (match_operand 0 "const_int_operand"))))) 188 189(define_predicate "aarch64_reg_or_imm" 190 (and (match_code "reg,subreg,const_int") 191 (ior (match_operand 0 "register_operand") 192 (match_operand 0 "const_int_operand")))) 193 194;; True for integer comparisons and for FP comparisons other than LTGT or UNEQ. 195(define_special_predicate "aarch64_comparison_operator" 196 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt")) 197 198;; True if the operand is memory reference suitable for a load/store exclusive. 199(define_predicate "aarch64_sync_memory_operand" 200 (and (match_operand 0 "memory_operand") 201 (match_code "reg" "0"))) 202 203;; Predicates for parallel expanders based on mode. 204(define_special_predicate "vect_par_cnst_hi_half" 205 (match_code "parallel") 206{ 207 HOST_WIDE_INT count = XVECLEN (op, 0); 208 int nunits = GET_MODE_NUNITS (mode); 209 int i; 210 211 if (count < 1 212 || count != nunits / 2) 213 return false; 214 215 if (!VECTOR_MODE_P (mode)) 216 return false; 217 218 for (i = 0; i < count; i++) 219 { 220 rtx elt = XVECEXP (op, 0, i); 221 int val; 222 223 if (GET_CODE (elt) != CONST_INT) 224 return false; 225 226 val = INTVAL (elt); 227 if (val != (nunits / 2) + i) 228 return false; 229 } 230 return true; 231}) 232 233(define_special_predicate "vect_par_cnst_lo_half" 234 (match_code "parallel") 235{ 236 HOST_WIDE_INT count = XVECLEN (op, 0); 237 int nunits = GET_MODE_NUNITS (mode); 238 int i; 239 240 if (count < 1 241 || count != nunits / 2) 242 return false; 243 244 if (!VECTOR_MODE_P (mode)) 245 return false; 246 247 for (i = 0; i < count; i++) 248 { 249 rtx elt = XVECEXP (op, 0, i); 250 int val; 251 252 if (GET_CODE (elt) != CONST_INT) 253 return false; 254 255 val = INTVAL (elt); 256 if (val != i) 257 return false; 258 } 259 return true; 260}) 261 262 263(define_special_predicate "aarch64_simd_lshift_imm" 264 (match_code "const_vector") 265{ 266 return aarch64_simd_shift_imm_p (op, mode, true); 267}) 268 269(define_special_predicate "aarch64_simd_rshift_imm" 270 (match_code "const_vector") 271{ 272 return aarch64_simd_shift_imm_p (op, mode, false); 273}) 274 275(define_predicate "aarch64_simd_reg_or_zero" 276 (and (match_code "reg,subreg,const_int,const_vector") 277 (ior (match_operand 0 "register_operand") 278 (ior (match_test "op == const0_rtx") 279 (match_test "aarch64_simd_imm_zero_p (op, mode)"))))) 280 281(define_predicate "aarch64_simd_struct_operand" 282 (and (match_code "mem") 283 (match_test "TARGET_SIMD && aarch64_simd_mem_operand_p (op)"))) 284 285;; Like general_operand but allow only valid SIMD addressing modes. 286(define_predicate "aarch64_simd_general_operand" 287 (and (match_operand 0 "general_operand") 288 (match_test "!MEM_P (op) 289 || GET_CODE (XEXP (op, 0)) == POST_INC 290 || GET_CODE (XEXP (op, 0)) == REG"))) 291 292;; Like nonimmediate_operand but allow only valid SIMD addressing modes. 293(define_predicate "aarch64_simd_nonimmediate_operand" 294 (and (match_operand 0 "nonimmediate_operand") 295 (match_test "!MEM_P (op) 296 || GET_CODE (XEXP (op, 0)) == POST_INC 297 || GET_CODE (XEXP (op, 0)) == REG"))) 298 299(define_special_predicate "aarch64_simd_imm_zero" 300 (match_code "const_vector") 301{ 302 return aarch64_simd_imm_zero_p (op, mode); 303}) 304