annotate gcc/config/aarch64/predicates.md @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ;; Machine description for AArch64 architecture.
kono
parents:
diff changeset
2 ;; Copyright (C) 2009-2017 Free Software Foundation, Inc.
kono
parents:
diff changeset
3 ;; Contributed by ARM Ltd.
kono
parents:
diff changeset
4 ;;
kono
parents:
diff changeset
5 ;; This file is part of GCC.
kono
parents:
diff changeset
6 ;;
kono
parents:
diff changeset
7 ;; GCC is free software; you can redistribute it and/or modify it
kono
parents:
diff changeset
8 ;; under the terms of the GNU General Public License as published by
kono
parents:
diff changeset
9 ;; the Free Software Foundation; either version 3, or (at your option)
kono
parents:
diff changeset
10 ;; any later version.
kono
parents:
diff changeset
11 ;;
kono
parents:
diff changeset
12 ;; GCC is distributed in the hope that it will be useful, but
kono
parents:
diff changeset
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
kono
parents:
diff changeset
15 ;; General Public License for more details.
kono
parents:
diff changeset
16 ;;
kono
parents:
diff changeset
17 ;; You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
18 ;; along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
19 ;; <http://www.gnu.org/licenses/>.
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 (define_special_predicate "cc_register"
kono
parents:
diff changeset
22 (and (match_code "reg")
kono
parents:
diff changeset
23 (and (match_test "REGNO (op) == CC_REGNUM")
kono
parents:
diff changeset
24 (ior (match_test "mode == GET_MODE (op)")
kono
parents:
diff changeset
25 (match_test "mode == VOIDmode
kono
parents:
diff changeset
26 && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC"))))
kono
parents:
diff changeset
27 )
kono
parents:
diff changeset
28
kono
parents:
diff changeset
29 (define_predicate "aarch64_call_insn_operand"
kono
parents:
diff changeset
30 (ior (match_code "symbol_ref")
kono
parents:
diff changeset
31 (match_operand 0 "register_operand")))
kono
parents:
diff changeset
32
kono
parents:
diff changeset
33 ;; Return true if OP a (const_int 0) operand.
kono
parents:
diff changeset
34 (define_predicate "const0_operand"
kono
parents:
diff changeset
35 (and (match_code "const_int")
kono
parents:
diff changeset
36 (match_test "op == CONST0_RTX (mode)")))
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 (define_special_predicate "subreg_lowpart_operator"
kono
parents:
diff changeset
39 (and (match_code "subreg")
kono
parents:
diff changeset
40 (match_test "subreg_lowpart_p (op)")))
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 (define_predicate "aarch64_ccmp_immediate"
kono
parents:
diff changeset
43 (and (match_code "const_int")
kono
parents:
diff changeset
44 (match_test "IN_RANGE (INTVAL (op), -31, 31)")))
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 (define_predicate "aarch64_ccmp_operand"
kono
parents:
diff changeset
47 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
48 (match_operand 0 "aarch64_ccmp_immediate")))
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 (define_predicate "aarch64_simd_register"
kono
parents:
diff changeset
51 (and (match_code "reg")
kono
parents:
diff changeset
52 (ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS")
kono
parents:
diff changeset
53 (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_REGS"))))
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 (define_predicate "aarch64_reg_or_zero"
kono
parents:
diff changeset
56 (and (match_code "reg,subreg,const_int")
kono
parents:
diff changeset
57 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
58 (match_test "op == const0_rtx"))))
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 (define_predicate "aarch64_reg_or_fp_zero"
kono
parents:
diff changeset
61 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
62 (and (match_code "const_double")
kono
parents:
diff changeset
63 (match_test "aarch64_float_const_zero_rtx_p (op)"))))
kono
parents:
diff changeset
64
kono
parents:
diff changeset
65 (define_predicate "aarch64_reg_zero_or_m1_or_1"
kono
parents:
diff changeset
66 (and (match_code "reg,subreg,const_int")
kono
parents:
diff changeset
67 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
68 (ior (match_test "op == const0_rtx")
kono
parents:
diff changeset
69 (ior (match_test "op == constm1_rtx")
kono
parents:
diff changeset
70 (match_test "op == const1_rtx"))))))
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 (define_predicate "aarch64_reg_or_orr_imm"
kono
parents:
diff changeset
73 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
74 (and (match_code "const_vector")
kono
parents:
diff changeset
75 (match_test "aarch64_simd_valid_immediate (op, mode, false,
kono
parents:
diff changeset
76 NULL, AARCH64_CHECK_ORR)"))))
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 (define_predicate "aarch64_reg_or_bic_imm"
kono
parents:
diff changeset
79 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
80 (and (match_code "const_vector")
kono
parents:
diff changeset
81 (match_test "aarch64_simd_valid_immediate (op, mode, false,
kono
parents:
diff changeset
82 NULL, AARCH64_CHECK_BIC)"))))
kono
parents:
diff changeset
83
kono
parents:
diff changeset
84 (define_predicate "aarch64_fp_compare_operand"
kono
parents:
diff changeset
85 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
86 (and (match_code "const_double")
kono
parents:
diff changeset
87 (match_test "aarch64_float_const_zero_rtx_p (op)"))))
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 (define_predicate "aarch64_fp_pow2"
kono
parents:
diff changeset
90 (and (match_code "const_double")
kono
parents:
diff changeset
91 (match_test "aarch64_fpconst_pow_of_2 (op) > 0")))
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 (define_predicate "aarch64_fp_vec_pow2"
kono
parents:
diff changeset
94 (match_test "aarch64_vec_fpconst_pow_of_2 (op) > 0"))
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 (define_predicate "aarch64_sub_immediate"
kono
parents:
diff changeset
97 (and (match_code "const_int")
kono
parents:
diff changeset
98 (match_test "aarch64_uimm12_shift (-INTVAL (op))")))
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 (define_predicate "aarch64_plus_immediate"
kono
parents:
diff changeset
101 (and (match_code "const_int")
kono
parents:
diff changeset
102 (ior (match_test "aarch64_uimm12_shift (INTVAL (op))")
kono
parents:
diff changeset
103 (match_test "aarch64_uimm12_shift (-INTVAL (op))"))))
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 (define_predicate "aarch64_plus_operand"
kono
parents:
diff changeset
106 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
107 (match_operand 0 "aarch64_plus_immediate")))
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 (define_predicate "aarch64_pluslong_immediate"
kono
parents:
diff changeset
110 (and (match_code "const_int")
kono
parents:
diff changeset
111 (match_test "(INTVAL (op) < 0xffffff && INTVAL (op) > -0xffffff)")))
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 (define_predicate "aarch64_pluslong_strict_immedate"
kono
parents:
diff changeset
114 (and (match_operand 0 "aarch64_pluslong_immediate")
kono
parents:
diff changeset
115 (not (match_operand 0 "aarch64_plus_immediate"))))
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 (define_predicate "aarch64_pluslong_operand"
kono
parents:
diff changeset
118 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
119 (match_operand 0 "aarch64_pluslong_immediate")))
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 (define_predicate "aarch64_logical_immediate"
kono
parents:
diff changeset
122 (and (match_code "const_int")
kono
parents:
diff changeset
123 (match_test "aarch64_bitmask_imm (INTVAL (op), mode)")))
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 (define_predicate "aarch64_logical_operand"
kono
parents:
diff changeset
126 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
127 (match_operand 0 "aarch64_logical_immediate")))
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 (define_predicate "aarch64_mov_imm_operand"
kono
parents:
diff changeset
130 (and (match_code "const_int")
kono
parents:
diff changeset
131 (match_test "aarch64_move_imm (INTVAL (op), mode)")))
kono
parents:
diff changeset
132
kono
parents:
diff changeset
133 (define_predicate "aarch64_logical_and_immediate"
kono
parents:
diff changeset
134 (and (match_code "const_int")
kono
parents:
diff changeset
135 (match_test "aarch64_and_bitmask_imm (INTVAL (op), mode)")))
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 (define_predicate "aarch64_shift_imm_si"
kono
parents:
diff changeset
138 (and (match_code "const_int")
kono
parents:
diff changeset
139 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 32")))
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 (define_predicate "aarch64_shift_imm_di"
kono
parents:
diff changeset
142 (and (match_code "const_int")
kono
parents:
diff changeset
143 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 64")))
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 (define_predicate "aarch64_shift_imm64_di"
kono
parents:
diff changeset
146 (and (match_code "const_int")
kono
parents:
diff changeset
147 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 64")))
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 (define_predicate "aarch64_reg_or_shift_imm_si"
kono
parents:
diff changeset
150 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
151 (match_operand 0 "aarch64_shift_imm_si")))
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 (define_predicate "aarch64_reg_or_shift_imm_di"
kono
parents:
diff changeset
154 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
155 (match_operand 0 "aarch64_shift_imm_di")))
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 ;; The imm3 field is a 3-bit field that only accepts immediates in the
kono
parents:
diff changeset
158 ;; range 0..4.
kono
parents:
diff changeset
159 (define_predicate "aarch64_imm3"
kono
parents:
diff changeset
160 (and (match_code "const_int")
kono
parents:
diff changeset
161 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 4")))
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 ;; An immediate that fits into 24 bits.
kono
parents:
diff changeset
164 (define_predicate "aarch64_imm24"
kono
parents:
diff changeset
165 (and (match_code "const_int")
kono
parents:
diff changeset
166 (match_test "IN_RANGE (UINTVAL (op), 0, 0xffffff)")))
kono
parents:
diff changeset
167
kono
parents:
diff changeset
168 (define_predicate "aarch64_pwr_imm3"
kono
parents:
diff changeset
169 (and (match_code "const_int")
kono
parents:
diff changeset
170 (match_test "INTVAL (op) != 0
kono
parents:
diff changeset
171 && (unsigned) exact_log2 (INTVAL (op)) <= 4")))
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 (define_predicate "aarch64_pwr_2_si"
kono
parents:
diff changeset
174 (and (match_code "const_int")
kono
parents:
diff changeset
175 (match_test "INTVAL (op) != 0
kono
parents:
diff changeset
176 && (unsigned) exact_log2 (INTVAL (op)) < 32")))
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 (define_predicate "aarch64_pwr_2_di"
kono
parents:
diff changeset
179 (and (match_code "const_int")
kono
parents:
diff changeset
180 (match_test "INTVAL (op) != 0
kono
parents:
diff changeset
181 && (unsigned) exact_log2 (INTVAL (op)) < 64")))
kono
parents:
diff changeset
182
kono
parents:
diff changeset
183 (define_predicate "aarch64_mem_pair_offset"
kono
parents:
diff changeset
184 (and (match_code "const_int")
kono
parents:
diff changeset
185 (match_test "aarch64_offset_7bit_signed_scaled_p (mode, INTVAL (op))")))
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 (define_predicate "aarch64_mem_pair_operand"
kono
parents:
diff changeset
188 (and (match_code "mem")
kono
parents:
diff changeset
189 (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL,
kono
parents:
diff changeset
190 0)")))
kono
parents:
diff changeset
191
kono
parents:
diff changeset
192 (define_predicate "aarch64_prefetch_operand"
kono
parents:
diff changeset
193 (match_test "aarch64_address_valid_for_prefetch_p (op, false)"))
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 (define_predicate "aarch64_valid_symref"
kono
parents:
diff changeset
196 (match_code "const, symbol_ref, label_ref")
kono
parents:
diff changeset
197 {
kono
parents:
diff changeset
198 return (aarch64_classify_symbolic_expression (op)
kono
parents:
diff changeset
199 != SYMBOL_FORCE_TO_MEM);
kono
parents:
diff changeset
200 })
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 (define_predicate "aarch64_tls_ie_symref"
kono
parents:
diff changeset
203 (match_code "const, symbol_ref, label_ref")
kono
parents:
diff changeset
204 {
kono
parents:
diff changeset
205 switch (GET_CODE (op))
kono
parents:
diff changeset
206 {
kono
parents:
diff changeset
207 case CONST:
kono
parents:
diff changeset
208 op = XEXP (op, 0);
kono
parents:
diff changeset
209 if (GET_CODE (op) != PLUS
kono
parents:
diff changeset
210 || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
kono
parents:
diff changeset
211 || GET_CODE (XEXP (op, 1)) != CONST_INT)
kono
parents:
diff changeset
212 return false;
kono
parents:
diff changeset
213 op = XEXP (op, 0);
kono
parents:
diff changeset
214 /* FALLTHRU */
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 case SYMBOL_REF:
kono
parents:
diff changeset
217 return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC;
kono
parents:
diff changeset
218
kono
parents:
diff changeset
219 default:
kono
parents:
diff changeset
220 gcc_unreachable ();
kono
parents:
diff changeset
221 }
kono
parents:
diff changeset
222 })
kono
parents:
diff changeset
223
kono
parents:
diff changeset
224 (define_predicate "aarch64_tls_le_symref"
kono
parents:
diff changeset
225 (match_code "const, symbol_ref, label_ref")
kono
parents:
diff changeset
226 {
kono
parents:
diff changeset
227 switch (GET_CODE (op))
kono
parents:
diff changeset
228 {
kono
parents:
diff changeset
229 case CONST:
kono
parents:
diff changeset
230 op = XEXP (op, 0);
kono
parents:
diff changeset
231 if (GET_CODE (op) != PLUS
kono
parents:
diff changeset
232 || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
kono
parents:
diff changeset
233 || GET_CODE (XEXP (op, 1)) != CONST_INT)
kono
parents:
diff changeset
234 return false;
kono
parents:
diff changeset
235 op = XEXP (op, 0);
kono
parents:
diff changeset
236 /* FALLTHRU */
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 case SYMBOL_REF:
kono
parents:
diff changeset
239 return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC;
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 default:
kono
parents:
diff changeset
242 gcc_unreachable ();
kono
parents:
diff changeset
243 }
kono
parents:
diff changeset
244 })
kono
parents:
diff changeset
245
kono
parents:
diff changeset
246 (define_predicate "aarch64_mov_operand"
kono
parents:
diff changeset
247 (and (match_code "reg,subreg,mem,const,const_int,symbol_ref,label_ref,high")
kono
parents:
diff changeset
248 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
249 (ior (match_operand 0 "memory_operand")
kono
parents:
diff changeset
250 (match_test "aarch64_mov_operand_p (op, mode)")))))
kono
parents:
diff changeset
251
kono
parents:
diff changeset
252 (define_predicate "aarch64_movti_operand"
kono
parents:
diff changeset
253 (and (match_code "reg,subreg,mem,const_int")
kono
parents:
diff changeset
254 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
255 (ior (match_operand 0 "memory_operand")
kono
parents:
diff changeset
256 (match_operand 0 "const_int_operand")))))
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 (define_predicate "aarch64_reg_or_imm"
kono
parents:
diff changeset
259 (and (match_code "reg,subreg,const_int")
kono
parents:
diff changeset
260 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
261 (match_operand 0 "const_int_operand"))))
kono
parents:
diff changeset
262
kono
parents:
diff changeset
263 ;; True for integer comparisons and for FP comparisons other than LTGT or UNEQ.
kono
parents:
diff changeset
264 (define_special_predicate "aarch64_comparison_operator"
kono
parents:
diff changeset
265 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,
kono
parents:
diff changeset
266 ordered,unlt,unle,unge,ungt"))
kono
parents:
diff changeset
267
kono
parents:
diff changeset
268 ;; Same as aarch64_comparison_operator but don't ignore the mode.
kono
parents:
diff changeset
269 ;; RTL SET operations require their operands source and destination have
kono
parents:
diff changeset
270 ;; the same modes, so we can't ignore the modes there. See PR target/69161.
kono
parents:
diff changeset
271 (define_predicate "aarch64_comparison_operator_mode"
kono
parents:
diff changeset
272 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,
kono
parents:
diff changeset
273 ordered,unlt,unle,unge,ungt"))
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 (define_special_predicate "aarch64_comparison_operation"
kono
parents:
diff changeset
276 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,
kono
parents:
diff changeset
277 ordered,unlt,unle,unge,ungt")
kono
parents:
diff changeset
278 {
kono
parents:
diff changeset
279 if (XEXP (op, 1) != const0_rtx)
kono
parents:
diff changeset
280 return false;
kono
parents:
diff changeset
281 rtx op0 = XEXP (op, 0);
kono
parents:
diff changeset
282 if (!REG_P (op0) || REGNO (op0) != CC_REGNUM)
kono
parents:
diff changeset
283 return false;
kono
parents:
diff changeset
284 return aarch64_get_condition_code (op) >= 0;
kono
parents:
diff changeset
285 })
kono
parents:
diff changeset
286
kono
parents:
diff changeset
287 (define_special_predicate "aarch64_carry_operation"
kono
parents:
diff changeset
288 (match_code "ne,geu")
kono
parents:
diff changeset
289 {
kono
parents:
diff changeset
290 if (XEXP (op, 1) != const0_rtx)
kono
parents:
diff changeset
291 return false;
kono
parents:
diff changeset
292 machine_mode ccmode = (GET_CODE (op) == NE ? CC_Cmode : CCmode);
kono
parents:
diff changeset
293 rtx op0 = XEXP (op, 0);
kono
parents:
diff changeset
294 return REG_P (op0) && REGNO (op0) == CC_REGNUM && GET_MODE (op0) == ccmode;
kono
parents:
diff changeset
295 })
kono
parents:
diff changeset
296
kono
parents:
diff changeset
297 (define_special_predicate "aarch64_borrow_operation"
kono
parents:
diff changeset
298 (match_code "eq,ltu")
kono
parents:
diff changeset
299 {
kono
parents:
diff changeset
300 if (XEXP (op, 1) != const0_rtx)
kono
parents:
diff changeset
301 return false;
kono
parents:
diff changeset
302 machine_mode ccmode = (GET_CODE (op) == EQ ? CC_Cmode : CCmode);
kono
parents:
diff changeset
303 rtx op0 = XEXP (op, 0);
kono
parents:
diff changeset
304 return REG_P (op0) && REGNO (op0) == CC_REGNUM && GET_MODE (op0) == ccmode;
kono
parents:
diff changeset
305 })
kono
parents:
diff changeset
306
kono
parents:
diff changeset
307 ;; True if the operand is memory reference suitable for a load/store exclusive.
kono
parents:
diff changeset
308 (define_predicate "aarch64_sync_memory_operand"
kono
parents:
diff changeset
309 (and (match_operand 0 "memory_operand")
kono
parents:
diff changeset
310 (match_code "reg" "0")))
kono
parents:
diff changeset
311
kono
parents:
diff changeset
312 ;; Predicates for parallel expanders based on mode.
kono
parents:
diff changeset
313 (define_special_predicate "vect_par_cnst_hi_half"
kono
parents:
diff changeset
314 (match_code "parallel")
kono
parents:
diff changeset
315 {
kono
parents:
diff changeset
316 return aarch64_simd_check_vect_par_cnst_half (op, mode, true);
kono
parents:
diff changeset
317 })
kono
parents:
diff changeset
318
kono
parents:
diff changeset
319 (define_special_predicate "vect_par_cnst_lo_half"
kono
parents:
diff changeset
320 (match_code "parallel")
kono
parents:
diff changeset
321 {
kono
parents:
diff changeset
322 return aarch64_simd_check_vect_par_cnst_half (op, mode, false);
kono
parents:
diff changeset
323 })
kono
parents:
diff changeset
324
kono
parents:
diff changeset
325 (define_special_predicate "aarch64_simd_lshift_imm"
kono
parents:
diff changeset
326 (match_code "const_vector")
kono
parents:
diff changeset
327 {
kono
parents:
diff changeset
328 return aarch64_simd_shift_imm_p (op, mode, true);
kono
parents:
diff changeset
329 })
kono
parents:
diff changeset
330
kono
parents:
diff changeset
331 (define_special_predicate "aarch64_simd_rshift_imm"
kono
parents:
diff changeset
332 (match_code "const_vector")
kono
parents:
diff changeset
333 {
kono
parents:
diff changeset
334 return aarch64_simd_shift_imm_p (op, mode, false);
kono
parents:
diff changeset
335 })
kono
parents:
diff changeset
336
kono
parents:
diff changeset
337 (define_predicate "aarch64_simd_reg_or_zero"
kono
parents:
diff changeset
338 (and (match_code "reg,subreg,const_int,const_double,const_vector")
kono
parents:
diff changeset
339 (ior (match_operand 0 "register_operand")
kono
parents:
diff changeset
340 (ior (match_test "op == const0_rtx")
kono
parents:
diff changeset
341 (match_test "aarch64_simd_imm_zero_p (op, mode)")))))
kono
parents:
diff changeset
342
kono
parents:
diff changeset
343 (define_predicate "aarch64_simd_struct_operand"
kono
parents:
diff changeset
344 (and (match_code "mem")
kono
parents:
diff changeset
345 (match_test "TARGET_SIMD && aarch64_simd_mem_operand_p (op)")))
kono
parents:
diff changeset
346
kono
parents:
diff changeset
347 ;; Like general_operand but allow only valid SIMD addressing modes.
kono
parents:
diff changeset
348 (define_predicate "aarch64_simd_general_operand"
kono
parents:
diff changeset
349 (and (match_operand 0 "general_operand")
kono
parents:
diff changeset
350 (match_test "!MEM_P (op)
kono
parents:
diff changeset
351 || GET_CODE (XEXP (op, 0)) == POST_INC
kono
parents:
diff changeset
352 || GET_CODE (XEXP (op, 0)) == REG")))
kono
parents:
diff changeset
353
kono
parents:
diff changeset
354 ;; Like nonimmediate_operand but allow only valid SIMD addressing modes.
kono
parents:
diff changeset
355 (define_predicate "aarch64_simd_nonimmediate_operand"
kono
parents:
diff changeset
356 (and (match_operand 0 "nonimmediate_operand")
kono
parents:
diff changeset
357 (match_test "!MEM_P (op)
kono
parents:
diff changeset
358 || GET_CODE (XEXP (op, 0)) == POST_INC
kono
parents:
diff changeset
359 || GET_CODE (XEXP (op, 0)) == REG")))
kono
parents:
diff changeset
360
kono
parents:
diff changeset
361 (define_special_predicate "aarch64_simd_imm_zero"
kono
parents:
diff changeset
362 (match_code "const_vector")
kono
parents:
diff changeset
363 {
kono
parents:
diff changeset
364 return aarch64_simd_imm_zero_p (op, mode);
kono
parents:
diff changeset
365 })
kono
parents:
diff changeset
366
kono
parents:
diff changeset
367 (define_special_predicate "aarch64_simd_imm_minus_one"
kono
parents:
diff changeset
368 (match_code "const_vector")
kono
parents:
diff changeset
369 {
kono
parents:
diff changeset
370 return aarch64_const_vec_all_same_int_p (op, -1);
kono
parents:
diff changeset
371 })
kono
parents:
diff changeset
372
kono
parents:
diff changeset
373 ;; Predicates used by the various SIMD shift operations. These
kono
parents:
diff changeset
374 ;; fall in to 3 categories.
kono
parents:
diff changeset
375 ;; Shifts with a range 0-(bit_size - 1) (aarch64_simd_shift_imm)
kono
parents:
diff changeset
376 ;; Shifts with a range 1-bit_size (aarch64_simd_shift_imm_offset)
kono
parents:
diff changeset
377 ;; Shifts with a range 0-bit_size (aarch64_simd_shift_imm_bitsize)
kono
parents:
diff changeset
378 (define_predicate "aarch64_simd_shift_imm_qi"
kono
parents:
diff changeset
379 (and (match_code "const_int")
kono
parents:
diff changeset
380 (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 (define_predicate "aarch64_simd_shift_imm_hi"
kono
parents:
diff changeset
383 (and (match_code "const_int")
kono
parents:
diff changeset
384 (match_test "IN_RANGE (INTVAL (op), 0, 15)")))
kono
parents:
diff changeset
385
kono
parents:
diff changeset
386 (define_predicate "aarch64_simd_shift_imm_si"
kono
parents:
diff changeset
387 (and (match_code "const_int")
kono
parents:
diff changeset
388 (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
kono
parents:
diff changeset
389
kono
parents:
diff changeset
390 (define_predicate "aarch64_simd_shift_imm_di"
kono
parents:
diff changeset
391 (and (match_code "const_int")
kono
parents:
diff changeset
392 (match_test "IN_RANGE (INTVAL (op), 0, 63)")))
kono
parents:
diff changeset
393
kono
parents:
diff changeset
394 (define_predicate "aarch64_simd_shift_imm_offset_qi"
kono
parents:
diff changeset
395 (and (match_code "const_int")
kono
parents:
diff changeset
396 (match_test "IN_RANGE (INTVAL (op), 1, 8)")))
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 (define_predicate "aarch64_simd_shift_imm_offset_hi"
kono
parents:
diff changeset
399 (and (match_code "const_int")
kono
parents:
diff changeset
400 (match_test "IN_RANGE (INTVAL (op), 1, 16)")))
kono
parents:
diff changeset
401
kono
parents:
diff changeset
402 (define_predicate "aarch64_simd_shift_imm_offset_si"
kono
parents:
diff changeset
403 (and (match_code "const_int")
kono
parents:
diff changeset
404 (match_test "IN_RANGE (INTVAL (op), 1, 32)")))
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 (define_predicate "aarch64_simd_shift_imm_offset_di"
kono
parents:
diff changeset
407 (and (match_code "const_int")
kono
parents:
diff changeset
408 (match_test "IN_RANGE (INTVAL (op), 1, 64)")))
kono
parents:
diff changeset
409
kono
parents:
diff changeset
410 (define_predicate "aarch64_simd_shift_imm_bitsize_qi"
kono
parents:
diff changeset
411 (and (match_code "const_int")
kono
parents:
diff changeset
412 (match_test "IN_RANGE (INTVAL (op), 0, 8)")))
kono
parents:
diff changeset
413
kono
parents:
diff changeset
414 (define_predicate "aarch64_simd_shift_imm_bitsize_hi"
kono
parents:
diff changeset
415 (and (match_code "const_int")
kono
parents:
diff changeset
416 (match_test "IN_RANGE (INTVAL (op), 0, 16)")))
kono
parents:
diff changeset
417
kono
parents:
diff changeset
418 (define_predicate "aarch64_simd_shift_imm_bitsize_si"
kono
parents:
diff changeset
419 (and (match_code "const_int")
kono
parents:
diff changeset
420 (match_test "IN_RANGE (INTVAL (op), 0, 32)")))
kono
parents:
diff changeset
421
kono
parents:
diff changeset
422 (define_predicate "aarch64_simd_shift_imm_bitsize_di"
kono
parents:
diff changeset
423 (and (match_code "const_int")
kono
parents:
diff changeset
424 (match_test "IN_RANGE (INTVAL (op), 0, 64)")))
kono
parents:
diff changeset
425
kono
parents:
diff changeset
426 (define_predicate "aarch64_constant_pool_symref"
kono
parents:
diff changeset
427 (and (match_code "symbol_ref")
kono
parents:
diff changeset
428 (match_test "CONSTANT_POOL_ADDRESS_P (op)")))