]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/aarch64/predicates.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / aarch64 / predicates.md
1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2023 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 (include "../arm/common.md")
22
23 (define_special_predicate "cc_register"
24 (and (match_code "reg")
25 (and (match_test "REGNO (op) == CC_REGNUM")
26 (ior (match_test "mode == GET_MODE (op)")
27 (match_test "mode == VOIDmode
28 && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC"))))
29 )
30
31 (define_predicate "aarch64_call_insn_operand"
32 (ior (match_code "symbol_ref")
33 (match_operand 0 "register_operand")))
34
35 (define_predicate "aarch64_general_reg"
36 (and (match_operand 0 "register_operand")
37 (match_test "REGNO_REG_CLASS (REGNO (op)) == STUB_REGS
38 || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS")))
39
40 ;; Return true if OP a (const_int 0) operand.
41 (define_predicate "const0_operand"
42 (and (match_code "const_int")
43 (match_test "op == CONST0_RTX (mode)")))
44
45 (define_predicate "const_1_to_3_operand"
46 (match_code "const_int,const_vector")
47 {
48 op = unwrap_const_vec_duplicate (op);
49 return CONST_INT_P (op) && IN_RANGE (INTVAL (op), 1, 3);
50 })
51
52 (define_predicate "subreg_lowpart_operator"
53 (ior (match_code "truncate")
54 (and (match_code "subreg")
55 (match_test "subreg_lowpart_p (op)"))))
56
57 (define_predicate "aarch64_ccmp_immediate"
58 (and (match_code "const_int")
59 (match_test "IN_RANGE (INTVAL (op), -31, 31)")))
60
61 (define_predicate "aarch64_ccmp_operand"
62 (ior (match_operand 0 "register_operand")
63 (match_operand 0 "aarch64_ccmp_immediate")))
64
65 (define_predicate "aarch64_simd_register"
66 (and (match_code "reg")
67 (match_test "FP_REGNUM_P (REGNO (op))")))
68
69 (define_predicate "aarch64_reg_or_zero"
70 (and (match_code "reg,subreg,const_int,const_double")
71 (ior (match_operand 0 "register_operand")
72 (match_test "op == CONST0_RTX (GET_MODE (op))"))))
73
74 (define_predicate "aarch64_reg_or_fp_zero"
75 (ior (match_operand 0 "register_operand")
76 (and (match_code "const_double")
77 (match_test "aarch64_float_const_zero_rtx_p (op)"))))
78
79 (define_predicate "aarch64_reg_zero_or_fp_zero"
80 (ior (match_operand 0 "aarch64_reg_or_fp_zero")
81 (match_operand 0 "aarch64_reg_or_zero")))
82
83 (define_predicate "aarch64_reg_zero_or_m1_or_1"
84 (and (match_code "reg,subreg,const_int")
85 (ior (match_operand 0 "register_operand")
86 (ior (match_test "op == const0_rtx")
87 (ior (match_test "op == constm1_rtx")
88 (match_test "op == const1_rtx"))))))
89
90 (define_predicate "aarch64_reg_or_orr_imm"
91 (ior (match_operand 0 "register_operand")
92 (and (match_code "const_vector")
93 (match_test "aarch64_simd_valid_immediate (op, NULL,
94 AARCH64_CHECK_ORR)"))))
95
96 (define_predicate "aarch64_reg_or_bic_imm"
97 (ior (match_operand 0 "register_operand")
98 (and (match_code "const_vector")
99 (match_test "aarch64_simd_valid_immediate (op, NULL,
100 AARCH64_CHECK_BIC)"))))
101
102 (define_predicate "aarch64_fp_compare_operand"
103 (ior (match_operand 0 "register_operand")
104 (and (match_code "const_double")
105 (match_test "aarch64_float_const_zero_rtx_p (op)"))))
106
107 (define_predicate "aarch64_fp_pow2"
108 (and (match_code "const_double")
109 (match_test "aarch64_fpconst_pow_of_2 (op) > 0")))
110
111 (define_predicate "aarch64_fp_pow2_recip"
112 (and (match_code "const_double")
113 (match_test "aarch64_fpconst_pow2_recip (op) > 0")))
114
115 (define_predicate "aarch64_fp_vec_pow2"
116 (match_test "aarch64_vec_fpconst_pow_of_2 (op) > 0"))
117
118 (define_predicate "aarch64_sve_cnt_immediate"
119 (and (match_code "const_poly_int")
120 (match_test "aarch64_sve_cnt_immediate_p (op)")))
121
122 (define_predicate "aarch64_sub_immediate"
123 (and (match_code "const_int")
124 (match_test "aarch64_uimm12_shift (-UINTVAL (op))")))
125
126 (define_predicate "aarch64_plus_immediate"
127 (and (match_code "const_int")
128 (ior (match_test "aarch64_uimm12_shift (INTVAL (op))")
129 (match_test "aarch64_uimm12_shift (-UINTVAL (op))"))))
130
131 (define_predicate "aarch64_plus_operand"
132 (ior (match_operand 0 "register_operand")
133 (match_operand 0 "aarch64_plus_immediate")))
134
135 (define_predicate "aarch64_plushi_immediate"
136 (match_code "const_int")
137 {
138 HOST_WIDE_INT val = INTVAL (op);
139 /* The HImode value must be zero-extendable to an SImode plus_operand. */
140 return ((val & 0xfff) == val || sext_hwi (val & 0xf000, 16) == val);
141 })
142
143 (define_predicate "aarch64_plushi_operand"
144 (ior (match_operand 0 "register_operand")
145 (match_operand 0 "aarch64_plushi_immediate")))
146
147 (define_predicate "aarch64_pluslong_immediate"
148 (and (match_code "const_int")
149 (match_test "IN_RANGE (INTVAL (op), -0xffffff, 0xffffff)")))
150
151 (define_predicate "aarch64_sminmax_immediate"
152 (and (match_code "const_int")
153 (match_test "IN_RANGE (INTVAL (op), -128, 127)")))
154
155 (define_predicate "aarch64_sminmax_operand"
156 (ior (match_operand 0 "register_operand")
157 (match_operand 0 "aarch64_sminmax_immediate")))
158
159 (define_predicate "aarch64_uminmax_immediate"
160 (and (match_code "const_int")
161 (match_test "IN_RANGE (INTVAL (op), 0, 255)")))
162
163 (define_predicate "aarch64_uminmax_operand"
164 (ior (match_operand 0 "register_operand")
165 (match_operand 0 "aarch64_uminmax_immediate")))
166
167 (define_predicate "aarch64_pluslong_strict_immedate"
168 (and (match_operand 0 "aarch64_pluslong_immediate")
169 (not (match_operand 0 "aarch64_plus_immediate"))))
170
171 (define_predicate "aarch64_sve_scalar_inc_dec_immediate"
172 (and (match_code "const_poly_int")
173 (match_test "aarch64_sve_scalar_inc_dec_immediate_p (op)")))
174
175 (define_predicate "aarch64_sve_addvl_addpl_immediate"
176 (and (match_code "const_poly_int")
177 (match_test "aarch64_sve_addvl_addpl_immediate_p (op)")))
178
179 (define_predicate "aarch64_sve_plus_immediate"
180 (ior (match_operand 0 "aarch64_sve_scalar_inc_dec_immediate")
181 (match_operand 0 "aarch64_sve_addvl_addpl_immediate")))
182
183 (define_predicate "aarch64_split_add_offset_immediate"
184 (and (match_code "const_poly_int")
185 (match_test "aarch64_add_offset_temporaries (op) == 1")))
186
187 (define_predicate "aarch64_pluslong_operand"
188 (ior (match_operand 0 "register_operand")
189 (match_operand 0 "aarch64_pluslong_immediate")
190 (and (match_test "TARGET_SVE")
191 (match_operand 0 "aarch64_sve_plus_immediate"))))
192
193 (define_predicate "aarch64_pluslong_or_poly_operand"
194 (ior (match_operand 0 "aarch64_pluslong_operand")
195 (match_operand 0 "aarch64_split_add_offset_immediate")))
196
197 (define_predicate "aarch64_logical_immediate"
198 (and (match_code "const_int")
199 (match_test "aarch64_bitmask_imm (INTVAL (op), mode)")))
200
201 (define_predicate "aarch64_logical_operand"
202 (ior (match_operand 0 "register_operand")
203 (match_operand 0 "aarch64_logical_immediate")))
204
205 (define_predicate "aarch64_mov_imm_operand"
206 (and (match_code "const_int")
207 (match_test "aarch64_move_imm (INTVAL (op), mode)")))
208
209 (define_predicate "aarch64_logical_and_immediate"
210 (and (match_code "const_int")
211 (match_test "aarch64_and_bitmask_imm (INTVAL (op), mode)")))
212
213 (define_predicate "aarch64_shift_imm_si"
214 (and (match_code "const_int")
215 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 32")))
216
217 (define_predicate "aarch64_shift_imm_di"
218 (and (match_code "const_int")
219 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 64")))
220
221 (define_predicate "aarch64_shift_imm64_di"
222 (and (match_code "const_int")
223 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 64")))
224
225 (define_predicate "aarch64_reg_or_shift_imm_si"
226 (ior (match_operand 0 "register_operand")
227 (match_operand 0 "aarch64_shift_imm_si")))
228
229 (define_predicate "aarch64_reg_or_shift_imm_di"
230 (ior (match_operand 0 "register_operand")
231 (match_operand 0 "aarch64_shift_imm_di")))
232
233 ;; The imm3 field is a 3-bit field that only accepts immediates in the
234 ;; range 0..4.
235 (define_predicate "aarch64_imm3"
236 (and (match_code "const_int")
237 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 4")))
238
239 ;; The imm2 field is a 2-bit field that only accepts immediates in the
240 ;; range 0..3.
241 (define_predicate "aarch64_imm2"
242 (and (match_code "const_int")
243 (match_test "UINTVAL (op) <= 3")))
244
245 ;; The imm3 field is a 3-bit field that only accepts immediates in the
246 ;; range 0..7.
247 (define_predicate "aarch64_lane_imm3"
248 (and (match_code "const_int")
249 (match_test "UINTVAL (op) <= 7")))
250
251 ;; An immediate that fits into 24 bits.
252 (define_predicate "aarch64_imm24"
253 (and (match_code "const_int")
254 (match_test "IN_RANGE (UINTVAL (op), 0, 0xffffff)")))
255
256 (define_predicate "aarch64_mem_pair_offset"
257 (and (match_code "const_int")
258 (match_test "aarch64_offset_7bit_signed_scaled_p (mode, INTVAL (op))")))
259
260 (define_predicate "aarch64_mem_pair_operand"
261 (and (match_code "mem")
262 (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), false,
263 ADDR_QUERY_LDP_STP)")))
264
265 ;; Used for storing two 64-bit values in an AdvSIMD register using an STP
266 ;; as a 128-bit vec_concat.
267 (define_predicate "aarch64_mem_pair_lanes_operand"
268 (and (match_code "mem")
269 (match_test "aarch64_legitimate_address_p (GET_MODE (op), XEXP (op, 0),
270 false,
271 ADDR_QUERY_LDP_STP_N)")))
272
273 (define_predicate "aarch64_reg_or_mem_pair_operand"
274 (ior (match_operand 0 "register_operand")
275 (match_operand 0 "aarch64_mem_pair_lanes_operand")))
276
277 (define_predicate "aarch64_prefetch_operand"
278 (match_test "aarch64_address_valid_for_prefetch_p (op, false)"))
279
280 (define_predicate "aarch64_valid_symref"
281 (match_code "const, symbol_ref, label_ref")
282 {
283 return (aarch64_classify_symbolic_expression (op)
284 != SYMBOL_FORCE_TO_MEM);
285 })
286
287 (define_predicate "aarch64_tls_ie_symref"
288 (match_code "const, symbol_ref, label_ref")
289 {
290 switch (GET_CODE (op))
291 {
292 case CONST:
293 op = XEXP (op, 0);
294 if (GET_CODE (op) != PLUS
295 || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
296 || GET_CODE (XEXP (op, 1)) != CONST_INT)
297 return false;
298 op = XEXP (op, 0);
299 /* FALLTHRU */
300
301 case SYMBOL_REF:
302 return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC;
303
304 default:
305 gcc_unreachable ();
306 }
307 })
308
309 (define_predicate "aarch64_tls_le_symref"
310 (match_code "const, symbol_ref, label_ref")
311 {
312 switch (GET_CODE (op))
313 {
314 case CONST:
315 op = XEXP (op, 0);
316 if (GET_CODE (op) != PLUS
317 || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
318 || GET_CODE (XEXP (op, 1)) != CONST_INT)
319 return false;
320 op = XEXP (op, 0);
321 /* FALLTHRU */
322
323 case SYMBOL_REF:
324 return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC;
325
326 default:
327 gcc_unreachable ();
328 }
329 })
330
331 (define_predicate "aarch64_mov_operand"
332 (and (match_code "reg,subreg,mem,const,const_int,symbol_ref,label_ref,high,
333 const_poly_int,const_vector")
334 (ior (match_operand 0 "register_operand")
335 (ior (match_operand 0 "memory_operand")
336 (match_test "aarch64_mov_operand_p (op, mode)")))))
337
338 (define_predicate "aarch64_nonmemory_operand"
339 (and (match_code "reg,subreg,const,const_int,symbol_ref,label_ref,high,
340 const_poly_int,const_vector")
341 (ior (match_operand 0 "register_operand")
342 (match_test "aarch64_mov_operand_p (op, mode)"))))
343
344 (define_predicate "aarch64_movti_operand"
345 (ior (match_operand 0 "register_operand")
346 (match_operand 0 "memory_operand")
347 (and (match_operand 0 "const_scalar_int_operand")
348 (match_test "aarch64_mov128_immediate (op)"))))
349
350 (define_predicate "aarch64_reg_or_imm"
351 (ior (match_operand 0 "register_operand")
352 (match_operand 0 "const_scalar_int_operand")))
353
354 ;; True for integer comparisons and for FP comparisons other than LTGT or UNEQ.
355 (define_special_predicate "aarch64_comparison_operator"
356 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,
357 ordered,unlt,unle,unge,ungt"))
358
359 ;; Same as aarch64_comparison_operator but don't ignore the mode.
360 ;; RTL SET operations require their operands source and destination have
361 ;; the same modes, so we can't ignore the modes there. See PR target/69161.
362 (define_predicate "aarch64_comparison_operator_mode"
363 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,
364 ordered,unlt,unle,unge,ungt"))
365
366 (define_special_predicate "aarch64_comparison_operation"
367 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,
368 ordered,unlt,unle,unge,ungt")
369 {
370 if (XEXP (op, 1) != const0_rtx)
371 return false;
372 rtx op0 = XEXP (op, 0);
373 if (!REG_P (op0) || REGNO (op0) != CC_REGNUM)
374 return false;
375 return aarch64_get_condition_code (op) >= 0;
376 })
377
378 (define_special_predicate "aarch64_equality_operator"
379 (match_code "eq,ne"))
380
381 (define_special_predicate "aarch64_carry_operation"
382 (match_code "ltu,geu")
383 {
384 if (XEXP (op, 1) != const0_rtx)
385 return false;
386 rtx op0 = XEXP (op, 0);
387 if (!REG_P (op0) || REGNO (op0) != CC_REGNUM)
388 return false;
389 machine_mode ccmode = GET_MODE (op0);
390 if (ccmode == CC_Cmode)
391 return GET_CODE (op) == LTU;
392 if (ccmode == CC_ADCmode || ccmode == CCmode)
393 return GET_CODE (op) == GEU;
394 return false;
395 })
396
397 ; borrow is essentially the inverse of carry since the sense of the C flag
398 ; is inverted during subtraction. See the note in aarch64-modes.def.
399 (define_special_predicate "aarch64_borrow_operation"
400 (match_code "geu,ltu")
401 {
402 if (XEXP (op, 1) != const0_rtx)
403 return false;
404 rtx op0 = XEXP (op, 0);
405 if (!REG_P (op0) || REGNO (op0) != CC_REGNUM)
406 return false;
407 machine_mode ccmode = GET_MODE (op0);
408 if (ccmode == CC_Cmode)
409 return GET_CODE (op) == GEU;
410 if (ccmode == CC_ADCmode || ccmode == CCmode)
411 return GET_CODE (op) == LTU;
412 return false;
413 })
414
415 ;; True if the operand is memory reference suitable for a load/store exclusive.
416 (define_predicate "aarch64_sync_memory_operand"
417 (and (match_operand 0 "memory_operand")
418 (match_code "reg" "0")))
419
420 (define_predicate "aarch64_9bit_offset_memory_operand"
421 (and (match_operand 0 "memory_operand")
422 (ior (match_code "reg" "0")
423 (and (match_code "plus" "0")
424 (match_code "reg" "00")
425 (match_code "const_int" "01"))))
426 {
427 rtx mem_op = XEXP (op, 0);
428
429 if (REG_P (mem_op))
430 return GET_MODE (mem_op) == DImode;
431
432 rtx plus_op0 = XEXP (mem_op, 0);
433 rtx plus_op1 = XEXP (mem_op, 1);
434
435 if (GET_MODE (plus_op0) != DImode)
436 return false;
437
438 poly_int64 offset;
439 if (!poly_int_rtx_p (plus_op1, &offset))
440 gcc_unreachable ();
441
442 return aarch64_offset_9bit_signed_unscaled_p (mode, offset);
443 })
444
445 (define_predicate "aarch64_rcpc_memory_operand"
446 (if_then_else (match_test "AARCH64_ISA_RCPC8_4")
447 (match_operand 0 "aarch64_9bit_offset_memory_operand")
448 (match_operand 0 "aarch64_sync_memory_operand")))
449
450 ;; Predicates for parallel expanders based on mode.
451 (define_special_predicate "vect_par_cnst_hi_half"
452 (match_code "parallel")
453 {
454 return aarch64_simd_check_vect_par_cnst_half (op, mode, true);
455 })
456
457 (define_special_predicate "vect_par_cnst_lo_half"
458 (match_code "parallel")
459 {
460 return aarch64_simd_check_vect_par_cnst_half (op, mode, false);
461 })
462
463 (define_predicate "descending_int_parallel"
464 (match_code "parallel")
465 {
466 return aarch64_stepped_int_parallel_p (op, -1);
467 })
468
469 (define_predicate "ascending_int_parallel"
470 (match_code "parallel")
471 {
472 return aarch64_stepped_int_parallel_p (op, 1);
473 })
474
475 (define_special_predicate "aarch64_simd_lshift_imm"
476 (match_code "const,const_vector")
477 {
478 return aarch64_simd_shift_imm_p (op, mode, true);
479 })
480
481 (define_special_predicate "aarch64_simd_rshift_imm"
482 (match_code "const,const_vector")
483 {
484 return aarch64_simd_shift_imm_p (op, mode, false);
485 })
486
487 (define_predicate "aarch64_simd_imm_zero"
488 (and (match_code "const,const_vector")
489 (match_test "op == CONST0_RTX (GET_MODE (op))")))
490
491 (define_predicate "aarch64_simd_imm_one"
492 (and (match_code "const_vector")
493 (match_test "op == CONST1_RTX (GET_MODE (op))")))
494
495 (define_predicate "aarch64_simd_or_scalar_imm_zero"
496 (and (match_code "const_int,const_double,const,const_vector")
497 (match_test "op == CONST0_RTX (GET_MODE (op))")))
498
499 (define_predicate "aarch64_simd_imm_minus_one"
500 (and (match_code "const,const_vector")
501 (match_test "op == CONSTM1_RTX (GET_MODE (op))")))
502
503 (define_predicate "aarch64_simd_reg_or_zero"
504 (and (match_code "reg,subreg,const_int,const_double,const,const_vector")
505 (ior (match_operand 0 "register_operand")
506 (match_test "op == const0_rtx")
507 (match_operand 0 "aarch64_simd_or_scalar_imm_zero"))))
508
509 (define_predicate "aarch64_simd_reg_or_minus_one"
510 (ior (match_operand 0 "register_operand")
511 (match_operand 0 "aarch64_simd_imm_minus_one")))
512
513 (define_predicate "aarch64_simd_struct_operand"
514 (and (match_code "mem")
515 (match_test "TARGET_SIMD && aarch64_simd_mem_operand_p (op)")))
516
517 ;; Like general_operand but allow only valid SIMD addressing modes.
518 (define_predicate "aarch64_simd_general_operand"
519 (and (match_operand 0 "general_operand")
520 (match_test "!MEM_P (op)
521 || GET_CODE (XEXP (op, 0)) == POST_INC
522 || GET_CODE (XEXP (op, 0)) == REG")))
523
524 ;; Like nonimmediate_operand but allow only valid SIMD addressing modes.
525 (define_predicate "aarch64_simd_nonimmediate_operand"
526 (and (match_operand 0 "nonimmediate_operand")
527 (match_test "!MEM_P (op)
528 || GET_CODE (XEXP (op, 0)) == POST_INC
529 || GET_CODE (XEXP (op, 0)) == REG")))
530
531 ;; Predicates used by the various SIMD shift operations. These
532 ;; fall in to 3 categories.
533 ;; Shifts with a range 0-(bit_size - 1) (aarch64_simd_shift_imm)
534 ;; Shifts with a range 1-bit_size (aarch64_simd_shift_imm_offset)
535 ;; Shifts with a range 0-bit_size (aarch64_simd_shift_imm_bitsize)
536 (define_predicate "aarch64_simd_shift_imm_qi"
537 (and (match_code "const_int")
538 (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
539
540 (define_predicate "aarch64_simd_shift_imm_hi"
541 (and (match_code "const_int")
542 (match_test "IN_RANGE (INTVAL (op), 0, 15)")))
543
544 (define_predicate "aarch64_simd_shift_imm_si"
545 (and (match_code "const_int")
546 (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
547
548 (define_predicate "aarch64_simd_shift_imm_di"
549 (and (match_code "const_int")
550 (match_test "IN_RANGE (INTVAL (op), 0, 63)")))
551
552 (define_predicate "aarch64_simd_shift_imm_offset_qi"
553 (and (match_code "const_int")
554 (match_test "IN_RANGE (INTVAL (op), 1, 8)")))
555
556 (define_predicate "aarch64_simd_shift_imm_offset_hi"
557 (and (match_code "const_int")
558 (match_test "IN_RANGE (INTVAL (op), 1, 16)")))
559
560 (define_predicate "aarch64_simd_shift_imm_offset_si"
561 (and (match_code "const_int")
562 (match_test "IN_RANGE (INTVAL (op), 1, 32)")))
563
564 (define_predicate "aarch64_simd_shift_imm_offset_di"
565 (and (match_code "const_int")
566 (match_test "IN_RANGE (INTVAL (op), 1, 64)")))
567
568 (define_predicate "aarch64_simd_shift_imm_vec_exact_top"
569 (and (match_code "const_vector")
570 (match_test "aarch64_const_vec_all_same_in_range_p (op,
571 GET_MODE_UNIT_BITSIZE (GET_MODE (op)) / 2,
572 GET_MODE_UNIT_BITSIZE (GET_MODE (op)) / 2)")))
573
574 (define_predicate "aarch64_simd_shift_imm_vec_qi"
575 (and (match_code "const_vector")
576 (match_test "aarch64_const_vec_all_same_in_range_p (op, 1, 8)")))
577
578 (define_predicate "aarch64_simd_shift_imm_vec_hi"
579 (and (match_code "const_vector")
580 (match_test "aarch64_const_vec_all_same_in_range_p (op, 1, 16)")))
581
582 (define_predicate "aarch64_simd_shift_imm_vec_si"
583 (and (match_code "const_vector")
584 (match_test "aarch64_const_vec_all_same_in_range_p (op, 1, 32)")))
585
586 (define_predicate "aarch64_simd_shift_imm_vec_di"
587 (and (match_code "const_vector")
588 (match_test "aarch64_const_vec_all_same_in_range_p (op, 1, 64)")))
589
590 (define_predicate "aarch64_simd_shift_imm_bitsize_qi"
591 (and (match_code "const_int")
592 (match_test "IN_RANGE (INTVAL (op), 0, 8)")))
593
594 (define_predicate "aarch64_simd_shift_imm_bitsize_hi"
595 (and (match_code "const_int")
596 (match_test "IN_RANGE (INTVAL (op), 0, 16)")))
597
598 (define_predicate "aarch64_simd_shift_imm_bitsize_si"
599 (and (match_code "const_int")
600 (match_test "IN_RANGE (INTVAL (op), 0, 32)")))
601
602 (define_predicate "aarch64_simd_shift_imm_bitsize_di"
603 (and (match_code "const_int")
604 (match_test "IN_RANGE (INTVAL (op), 0, 64)")))
605
606 (define_predicate "aarch64_constant_pool_symref"
607 (and (match_code "symbol_ref")
608 (match_test "CONSTANT_POOL_ADDRESS_P (op)")))
609
610 (define_predicate "aarch64_constant_vector_operand"
611 (match_code "const,const_vector"))
612
613 (define_predicate "aarch64_sve_ld1r_operand"
614 (and (match_operand 0 "memory_operand")
615 (match_test "aarch64_sve_ld1r_operand_p (op)")))
616
617 (define_predicate "aarch64_sve_ld1rq_operand"
618 (and (match_code "mem")
619 (match_test "aarch64_sve_ld1rq_operand_p (op)")))
620
621 (define_predicate "aarch64_sve_ld1ro_operand_b"
622 (and (match_code "mem")
623 (match_test "aarch64_sve_ld1ro_operand_p (op, QImode)")))
624
625 (define_predicate "aarch64_sve_ld1ro_operand_h"
626 (and (match_code "mem")
627 (match_test "aarch64_sve_ld1ro_operand_p (op, HImode)")))
628
629 (define_predicate "aarch64_sve_ld1ro_operand_w"
630 (and (match_code "mem")
631 (match_test "aarch64_sve_ld1ro_operand_p (op, SImode)")))
632
633 (define_predicate "aarch64_sve_ld1ro_operand_d"
634 (and (match_code "mem")
635 (match_test "aarch64_sve_ld1ro_operand_p (op, DImode)")))
636
637 (define_predicate "aarch64_sve_ldff1_operand"
638 (and (match_code "mem")
639 (match_test "aarch64_sve_ldff1_operand_p (op)")))
640
641 (define_predicate "aarch64_sve_ldnf1_operand"
642 (and (match_code "mem")
643 (match_test "aarch64_sve_ldnf1_operand_p (op)")))
644
645 ;; Like memory_operand, but restricted to addresses that are valid for
646 ;; SVE LDR and STR instructions.
647 (define_predicate "aarch64_sve_ldr_operand"
648 (and (match_code "mem")
649 (match_test "aarch64_sve_ldr_operand_p (op)")))
650
651 (define_special_predicate "aarch64_sve_prefetch_operand"
652 (and (match_code "reg, plus")
653 (match_test "aarch64_sve_prefetch_operand_p (op, mode)")))
654
655 (define_predicate "aarch64_sve_nonimmediate_operand"
656 (ior (match_operand 0 "register_operand")
657 (match_operand 0 "aarch64_sve_ldr_operand")))
658
659 (define_predicate "aarch64_sve_general_operand"
660 (and (match_code "reg,subreg,mem,const,const_vector")
661 (ior (match_operand 0 "register_operand")
662 (match_operand 0 "aarch64_sve_ldr_operand")
663 (match_test "aarch64_mov_operand_p (op, mode)"))))
664
665 (define_predicate "aarch64_sve_struct_memory_operand"
666 (and (match_code "mem")
667 (match_test "aarch64_sve_struct_memory_operand_p (op)")))
668
669 (define_predicate "aarch64_sve_struct_nonimmediate_operand"
670 (ior (match_operand 0 "register_operand")
671 (match_operand 0 "aarch64_sve_struct_memory_operand")))
672
673 ;; Doesn't include immediates, since those are handled by the move
674 ;; patterns instead.
675 (define_predicate "aarch64_sve_dup_operand"
676 (ior (match_operand 0 "register_operand")
677 (match_operand 0 "aarch64_sve_ld1r_operand")))
678
679 (define_predicate "aarch64_sve_dup_ld1rq_operand"
680 (ior (match_operand 0 "register_operand")
681 (match_operand 0 "aarch64_sve_ld1rq_operand")))
682
683 (define_predicate "aarch64_sve_ptrue_svpattern_immediate"
684 (and (match_code "const")
685 (match_test "aarch64_sve_ptrue_svpattern_p (op, NULL)")))
686
687 (define_predicate "aarch64_sve_arith_immediate"
688 (and (match_code "const,const_vector")
689 (match_test "aarch64_sve_arith_immediate_p (mode, op, false)")))
690
691 (define_predicate "aarch64_sve_sub_arith_immediate"
692 (and (match_code "const,const_vector")
693 (match_test "aarch64_sve_arith_immediate_p (mode, op, true)")))
694
695 (define_predicate "aarch64_sve_qadd_immediate"
696 (and (match_code "const,const_vector")
697 (match_test "aarch64_sve_sqadd_sqsub_immediate_p (mode, op, false)")))
698
699 (define_predicate "aarch64_sve_qsub_immediate"
700 (and (match_code "const,const_vector")
701 (match_test "aarch64_sve_sqadd_sqsub_immediate_p (mode, op, true)")))
702
703 (define_predicate "aarch64_sve_vector_inc_dec_immediate"
704 (and (match_code "const,const_vector")
705 (match_test "aarch64_sve_vector_inc_dec_immediate_p (op)")))
706
707 (define_predicate "aarch64_sve_gather_immediate_b"
708 (and (match_code "const_int")
709 (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
710
711 (define_predicate "aarch64_sve_gather_immediate_h"
712 (and (match_code "const_int")
713 (match_test "IN_RANGE (INTVAL (op), 0, 62)")
714 (match_test "(INTVAL (op) & 1) == 0")))
715
716 (define_predicate "aarch64_sve_gather_immediate_w"
717 (and (match_code "const_int")
718 (match_test "IN_RANGE (INTVAL (op), 0, 124)")
719 (match_test "(INTVAL (op) & 3) == 0")))
720
721 (define_predicate "aarch64_sve_gather_immediate_d"
722 (and (match_code "const_int")
723 (match_test "IN_RANGE (INTVAL (op), 0, 248)")
724 (match_test "(INTVAL (op) & 7) == 0")))
725
726 (define_predicate "aarch64_sve_uxtb_immediate"
727 (and (match_code "const_vector")
728 (match_test "GET_MODE_UNIT_BITSIZE (GET_MODE (op)) > 8")
729 (match_test "aarch64_const_vec_all_same_int_p (op, 0xff)")))
730
731 (define_predicate "aarch64_sve_uxth_immediate"
732 (and (match_code "const_vector")
733 (match_test "GET_MODE_UNIT_BITSIZE (GET_MODE (op)) > 16")
734 (match_test "aarch64_const_vec_all_same_int_p (op, 0xffff)")))
735
736 (define_predicate "aarch64_sve_uxtw_immediate"
737 (and (match_code "const_vector")
738 (match_test "GET_MODE_UNIT_BITSIZE (GET_MODE (op)) > 32")
739 (match_test "aarch64_const_vec_all_same_int_p (op, 0xffffffff)")))
740
741 (define_predicate "aarch64_sve_uxt_immediate"
742 (ior (match_operand 0 "aarch64_sve_uxtb_immediate")
743 (match_operand 0 "aarch64_sve_uxth_immediate")
744 (match_operand 0 "aarch64_sve_uxtw_immediate")))
745
746 (define_predicate "aarch64_sve_logical_immediate"
747 (and (match_code "const,const_vector")
748 (match_test "aarch64_sve_bitmask_immediate_p (op)")))
749
750 ;; Used for SVE UMAX and UMIN.
751 (define_predicate "aarch64_sve_vsb_immediate"
752 (and (match_code "const_vector")
753 (match_test "GET_MODE_INNER (GET_MODE (op)) == QImode
754 ? aarch64_const_vec_all_same_in_range_p (op, -128, 127)
755 : aarch64_const_vec_all_same_in_range_p (op, 0, 255)")))
756
757 ;; Used for SVE MUL, SMAX and SMIN.
758 (define_predicate "aarch64_sve_vsm_immediate"
759 (and (match_code "const,const_vector")
760 (match_test "aarch64_const_vec_all_same_in_range_p (op, -128, 127)")))
761
762 (define_predicate "aarch64_sve_dup_immediate"
763 (and (match_code "const,const_vector")
764 (ior (match_test "aarch64_sve_dup_immediate_p (op)")
765 (match_test "aarch64_float_const_representable_p (op)"))))
766
767 (define_predicate "aarch64_sve_cmp_vsc_immediate"
768 (and (match_code "const_int,const_vector")
769 (match_test "aarch64_sve_cmp_immediate_p (op, true)")))
770
771 (define_predicate "aarch64_sve_cmp_vsd_immediate"
772 (and (match_code "const_int,const_vector")
773 (match_test "aarch64_sve_cmp_immediate_p (op, false)")))
774
775 (define_predicate "aarch64_sve_index_immediate"
776 (and (match_code "const_int")
777 (match_test "aarch64_sve_index_immediate_p (op)")))
778
779 (define_predicate "aarch64_sve_float_arith_immediate"
780 (and (match_code "const,const_vector")
781 (match_test "aarch64_sve_float_arith_immediate_p (op, false)")))
782
783 (define_predicate "aarch64_sve_float_negated_arith_immediate"
784 (and (match_code "const,const_vector")
785 (match_test "aarch64_sve_float_arith_immediate_p (op, true)")))
786
787 (define_predicate "aarch64_sve_float_arith_with_sub_immediate"
788 (ior (match_operand 0 "aarch64_sve_float_arith_immediate")
789 (match_operand 0 "aarch64_sve_float_negated_arith_immediate")))
790
791 (define_predicate "aarch64_sve_float_mul_immediate"
792 (and (match_code "const,const_vector")
793 (match_test "aarch64_sve_float_mul_immediate_p (op)")))
794
795 (define_predicate "aarch64_sve_float_maxmin_immediate"
796 (and (match_code "const_vector")
797 (ior (match_test "op == CONST0_RTX (GET_MODE (op))")
798 (match_test "op == CONST1_RTX (GET_MODE (op))"))))
799
800 (define_predicate "aarch64_sve_arith_operand"
801 (ior (match_operand 0 "register_operand")
802 (match_operand 0 "aarch64_sve_arith_immediate")))
803
804 (define_predicate "aarch64_sve_add_operand"
805 (ior (match_operand 0 "aarch64_sve_arith_operand")
806 (match_operand 0 "aarch64_sve_sub_arith_immediate")
807 (match_operand 0 "aarch64_sve_vector_inc_dec_immediate")))
808
809 (define_predicate "aarch64_sve_sqadd_operand"
810 (ior (match_operand 0 "register_operand")
811 (match_operand 0 "aarch64_sve_qadd_immediate")
812 (match_operand 0 "aarch64_sve_qsub_immediate")))
813
814 (define_predicate "aarch64_sve_pred_and_operand"
815 (ior (match_operand 0 "register_operand")
816 (match_operand 0 "aarch64_sve_uxt_immediate")))
817
818 (define_predicate "aarch64_sve_logical_operand"
819 (ior (match_operand 0 "register_operand")
820 (match_operand 0 "aarch64_sve_logical_immediate")))
821
822 (define_predicate "aarch64_sve_gather_offset_b"
823 (ior (match_operand 0 "register_operand")
824 (match_operand 0 "aarch64_sve_gather_immediate_b")))
825
826 (define_predicate "aarch64_sve_gather_offset_h"
827 (ior (match_operand 0 "register_operand")
828 (match_operand 0 "aarch64_sve_gather_immediate_h")))
829
830 (define_predicate "aarch64_sve_gather_offset_w"
831 (ior (match_operand 0 "register_operand")
832 (match_operand 0 "aarch64_sve_gather_immediate_w")))
833
834 (define_predicate "aarch64_sve_gather_offset_d"
835 (ior (match_operand 0 "register_operand")
836 (match_operand 0 "aarch64_sve_gather_immediate_d")))
837
838 (define_predicate "aarch64_sve_lshift_operand"
839 (ior (match_operand 0 "register_operand")
840 (match_operand 0 "aarch64_simd_lshift_imm")))
841
842 (define_predicate "aarch64_sve_rshift_operand"
843 (ior (match_operand 0 "register_operand")
844 (match_operand 0 "aarch64_simd_rshift_imm")))
845
846 (define_predicate "aarch64_sve_vsb_operand"
847 (ior (match_operand 0 "register_operand")
848 (match_operand 0 "aarch64_sve_vsb_immediate")))
849
850 (define_predicate "aarch64_sve_vsm_operand"
851 (ior (match_operand 0 "register_operand")
852 (match_operand 0 "aarch64_sve_vsm_immediate")))
853
854 (define_predicate "aarch64_sve_reg_or_dup_imm"
855 (ior (match_operand 0 "register_operand")
856 (match_operand 0 "aarch64_sve_dup_immediate")))
857
858 (define_predicate "aarch64_sve_cmp_vsc_operand"
859 (ior (match_operand 0 "register_operand")
860 (match_operand 0 "aarch64_sve_cmp_vsc_immediate")))
861
862 (define_predicate "aarch64_sve_cmp_vsd_operand"
863 (ior (match_operand 0 "register_operand")
864 (match_operand 0 "aarch64_sve_cmp_vsd_immediate")))
865
866 (define_predicate "aarch64_sve_index_operand"
867 (ior (match_operand 0 "register_operand")
868 (match_operand 0 "aarch64_sve_index_immediate")))
869
870 (define_predicate "aarch64_sve_float_arith_operand"
871 (ior (match_operand 0 "register_operand")
872 (match_operand 0 "aarch64_sve_float_arith_immediate")))
873
874 (define_predicate "aarch64_sve_float_arith_with_sub_operand"
875 (ior (match_operand 0 "register_operand")
876 (match_operand 0 "aarch64_sve_float_arith_with_sub_immediate")))
877
878 (define_predicate "aarch64_sve_float_mul_operand"
879 (ior (match_operand 0 "register_operand")
880 (match_operand 0 "aarch64_sve_float_mul_immediate")))
881
882 (define_predicate "aarch64_sve_float_maxmin_operand"
883 (ior (match_operand 0 "register_operand")
884 (match_operand 0 "aarch64_sve_float_maxmin_immediate")))
885
886 (define_predicate "aarch64_sve_vec_perm_operand"
887 (ior (match_operand 0 "register_operand")
888 (match_operand 0 "aarch64_constant_vector_operand")))
889
890 (define_predicate "aarch64_sve_ptrue_flag"
891 (and (match_code "const_int")
892 (ior (match_test "INTVAL (op) == SVE_MAYBE_NOT_PTRUE")
893 (match_test "INTVAL (op) == SVE_KNOWN_PTRUE"))))
894
895 (define_predicate "aarch64_sve_gp_strictness"
896 (and (match_code "const_int")
897 (ior (match_test "INTVAL (op) == SVE_RELAXED_GP")
898 (match_test "INTVAL (op) == SVE_STRICT_GP"))))
899
900 (define_predicate "aarch64_gather_scale_operand_b"
901 (and (match_code "const_int")
902 (match_test "INTVAL (op) == 1")))
903
904 (define_predicate "aarch64_gather_scale_operand_h"
905 (and (match_code "const_int")
906 (match_test "INTVAL (op) == 1 || INTVAL (op) == 2")))
907
908 (define_predicate "aarch64_gather_scale_operand_w"
909 (and (match_code "const_int")
910 (match_test "INTVAL (op) == 1 || INTVAL (op) == 4")))
911
912 (define_predicate "aarch64_gather_scale_operand_d"
913 (and (match_code "const_int")
914 (match_test "INTVAL (op) == 1 || INTVAL (op) == 8")))
915
916 ;; A special predicate that doesn't match a particular mode.
917 (define_special_predicate "aarch64_any_register_operand"
918 (match_code "reg"))
919
920 (define_predicate "aarch64_sve_any_binary_operator"
921 (match_code "plus,minus,mult,div,udiv,smax,umax,smin,umin,and,ior,xor"))
922
923 (define_predicate "aarch64_bytes_per_sve_vector_operand"
924 (and (match_code "const_int,const_poly_int")
925 (match_test "known_eq (wi::to_poly_wide (op, mode),
926 BYTES_PER_SVE_VECTOR)")))
927
928 (define_predicate "aarch64_memtag_tag_offset"
929 (and (match_code "const_int")
930 (match_test "IN_RANGE (INTVAL (op), 0, 15)")))
931
932 (define_predicate "aarch64_granule16_uimm6"
933 (and (match_code "const_int")
934 (match_test "IN_RANGE (INTVAL (op), 0, 1008)
935 && !(INTVAL (op) & 0xf)")))
936
937 (define_predicate "aarch64_granule16_simm9"
938 (and (match_code "const_int")
939 (match_test "IN_RANGE (INTVAL (op), -4096, 4080)
940 && !(INTVAL (op) & 0xf)")))