[AArch64] Add STP pattern to store a vec_concat of two 64-bit registers
[official-gcc.git] / gcc / config / aarch64 / predicates.md
blob2eaf0a7630169c3f4c23632d2a90be9ca15680df
1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2017 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.
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.
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/>.
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"))))
29 (define_predicate "aarch64_call_insn_operand"
30   (ior (match_code "symbol_ref")
31        (match_operand 0 "register_operand")))
33 ;; Return true if OP a (const_int 0) operand.
34 (define_predicate "const0_operand"
35   (and (match_code "const_int")
36        (match_test "op == CONST0_RTX (mode)")))
38 (define_special_predicate "subreg_lowpart_operator"
39   (and (match_code "subreg")
40        (match_test "subreg_lowpart_p (op)")))
42 (define_predicate "aarch64_ccmp_immediate"
43   (and (match_code "const_int")
44        (match_test "IN_RANGE (INTVAL (op), -31, 31)")))
46 (define_predicate "aarch64_ccmp_operand"
47   (ior (match_operand 0 "register_operand")
48        (match_operand 0 "aarch64_ccmp_immediate")))
50 (define_predicate "aarch64_simd_register"
51   (and (match_code "reg")
52        (ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS")
53             (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_REGS"))))
55 (define_predicate "aarch64_reg_or_zero"
56   (and (match_code "reg,subreg,const_int")
57        (ior (match_operand 0 "register_operand")
58             (match_test "op == const0_rtx"))))
60 (define_predicate "aarch64_reg_or_fp_zero"
61   (ior (match_operand 0 "register_operand")
62         (and (match_code "const_double")
63              (match_test "aarch64_float_const_zero_rtx_p (op)"))))
65 (define_predicate "aarch64_reg_zero_or_m1_or_1"
66   (and (match_code "reg,subreg,const_int")
67        (ior (match_operand 0 "register_operand")
68             (ior (match_test "op == const0_rtx")
69                  (ior (match_test "op == constm1_rtx")
70                       (match_test "op == const1_rtx"))))))
72 (define_predicate "aarch64_reg_or_orr_imm"
73    (ior (match_operand 0 "register_operand")
74         (and (match_code "const_vector")
75              (match_test "aarch64_simd_valid_immediate (op, mode, false,
76                                                 NULL, AARCH64_CHECK_ORR)"))))
78 (define_predicate "aarch64_reg_or_bic_imm"
79    (ior (match_operand 0 "register_operand")
80         (and (match_code "const_vector")
81              (match_test "aarch64_simd_valid_immediate (op, mode, false,
82                                                 NULL, AARCH64_CHECK_BIC)"))))
84 (define_predicate "aarch64_fp_compare_operand"
85   (ior (match_operand 0 "register_operand")
86        (and (match_code "const_double")
87             (match_test "aarch64_float_const_zero_rtx_p (op)"))))
89 (define_predicate "aarch64_fp_pow2"
90   (and (match_code "const_double")
91         (match_test "aarch64_fpconst_pow_of_2 (op) > 0")))
93 (define_predicate "aarch64_fp_vec_pow2"
94   (match_test "aarch64_vec_fpconst_pow_of_2 (op) > 0"))
96 (define_predicate "aarch64_sub_immediate"
97   (and (match_code "const_int")
98        (match_test "aarch64_uimm12_shift (-INTVAL (op))")))
100 (define_predicate "aarch64_plus_immediate"
101   (and (match_code "const_int")
102        (ior (match_test "aarch64_uimm12_shift (INTVAL (op))")
103             (match_test "aarch64_uimm12_shift (-INTVAL (op))"))))
105 (define_predicate "aarch64_plus_operand"
106   (ior (match_operand 0 "register_operand")
107        (match_operand 0 "aarch64_plus_immediate")))
109 (define_predicate "aarch64_pluslong_immediate"
110   (and (match_code "const_int")
111        (match_test "(INTVAL (op) < 0xffffff && INTVAL (op) > -0xffffff)")))
113 (define_predicate "aarch64_pluslong_strict_immedate"
114   (and (match_operand 0 "aarch64_pluslong_immediate")
115        (not (match_operand 0 "aarch64_plus_immediate"))))
117 (define_predicate "aarch64_pluslong_operand"
118   (ior (match_operand 0 "register_operand")
119        (match_operand 0 "aarch64_pluslong_immediate")))
121 (define_predicate "aarch64_logical_immediate"
122   (and (match_code "const_int")
123        (match_test "aarch64_bitmask_imm (INTVAL (op), mode)")))
125 (define_predicate "aarch64_logical_operand"
126   (ior (match_operand 0 "register_operand")
127        (match_operand 0 "aarch64_logical_immediate")))
129 (define_predicate "aarch64_mov_imm_operand"
130   (and (match_code "const_int")
131        (match_test "aarch64_move_imm (INTVAL (op), mode)")))
133 (define_predicate "aarch64_logical_and_immediate"
134   (and (match_code "const_int")
135        (match_test "aarch64_and_bitmask_imm (INTVAL (op), mode)")))
137 (define_predicate "aarch64_shift_imm_si"
138   (and (match_code "const_int")
139        (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 32")))
141 (define_predicate "aarch64_shift_imm_di"
142   (and (match_code "const_int")
143        (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 64")))
145 (define_predicate "aarch64_shift_imm64_di"
146   (and (match_code "const_int")
147        (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 64")))
149 (define_predicate "aarch64_reg_or_shift_imm_si"
150   (ior (match_operand 0 "register_operand")
151        (match_operand 0 "aarch64_shift_imm_si")))
153 (define_predicate "aarch64_reg_or_shift_imm_di"
154   (ior (match_operand 0 "register_operand")
155        (match_operand 0 "aarch64_shift_imm_di")))
157 ;; The imm3 field is a 3-bit field that only accepts immediates in the
158 ;; range 0..4.
159 (define_predicate "aarch64_imm3"
160   (and (match_code "const_int")
161        (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 4")))
163 ;; An immediate that fits into 24 bits.
164 (define_predicate "aarch64_imm24"
165   (and (match_code "const_int")
166        (match_test "IN_RANGE (UINTVAL (op), 0, 0xffffff)")))
168 (define_predicate "aarch64_pwr_imm3"
169   (and (match_code "const_int")
170        (match_test "INTVAL (op) != 0
171                     && (unsigned) exact_log2 (INTVAL (op)) <= 4")))
173 (define_predicate "aarch64_pwr_2_si"
174   (and (match_code "const_int")
175        (match_test "INTVAL (op) != 0
176                     && (unsigned) exact_log2 (INTVAL (op)) < 32")))
178 (define_predicate "aarch64_pwr_2_di"
179   (and (match_code "const_int")
180        (match_test "INTVAL (op) != 0
181                     && (unsigned) exact_log2 (INTVAL (op)) < 64")))
183 (define_predicate "aarch64_mem_pair_offset"
184   (and (match_code "const_int")
185        (match_test "aarch64_offset_7bit_signed_scaled_p (mode, INTVAL (op))")))
187 (define_predicate "aarch64_mem_pair_operand"
188   (and (match_code "mem")
189        (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL,
190                                                0)")))
192 ;; Used for storing two 64-bit values in an AdvSIMD register using an STP
193 ;; as a 128-bit vec_concat.
194 (define_predicate "aarch64_mem_pair_lanes_operand"
195   (and (match_code "mem")
196        (match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0),
197                                                    PARALLEL, 1)")))
199 (define_predicate "aarch64_prefetch_operand"
200   (match_test "aarch64_address_valid_for_prefetch_p (op, false)"))
202 (define_predicate "aarch64_valid_symref"
203   (match_code "const, symbol_ref, label_ref")
205   return (aarch64_classify_symbolic_expression (op)
206           != SYMBOL_FORCE_TO_MEM);
209 (define_predicate "aarch64_tls_ie_symref"
210   (match_code "const, symbol_ref, label_ref")
212   switch (GET_CODE (op))
213     {
214     case CONST:
215       op = XEXP (op, 0);
216       if (GET_CODE (op) != PLUS
217           || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
218           || GET_CODE (XEXP (op, 1)) != CONST_INT)
219         return false;
220       op = XEXP (op, 0);
221       /* FALLTHRU */
223     case SYMBOL_REF:
224       return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC;
226     default:
227       gcc_unreachable ();
228     }
231 (define_predicate "aarch64_tls_le_symref"
232   (match_code "const, symbol_ref, label_ref")
234   switch (GET_CODE (op))
235     {
236     case CONST:
237       op = XEXP (op, 0);
238       if (GET_CODE (op) != PLUS
239           || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
240           || GET_CODE (XEXP (op, 1)) != CONST_INT)
241         return false;
242       op = XEXP (op, 0);
243       /* FALLTHRU */
245     case SYMBOL_REF:
246       return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC;
248     default:
249       gcc_unreachable ();
250     }
253 (define_predicate "aarch64_mov_operand"
254   (and (match_code "reg,subreg,mem,const,const_int,symbol_ref,label_ref,high")
255        (ior (match_operand 0 "register_operand")
256             (ior (match_operand 0 "memory_operand")
257                  (match_test "aarch64_mov_operand_p (op, mode)")))))
259 (define_predicate "aarch64_movti_operand"
260   (and (match_code "reg,subreg,mem,const_int")
261        (ior (match_operand 0 "register_operand")
262             (ior (match_operand 0 "memory_operand")
263                  (match_operand 0 "const_int_operand")))))
265 (define_predicate "aarch64_reg_or_imm"
266   (and (match_code "reg,subreg,const_int")
267        (ior (match_operand 0 "register_operand")
268             (match_operand 0 "const_int_operand"))))
270 ;; True for integer comparisons and for FP comparisons other than LTGT or UNEQ.
271 (define_special_predicate "aarch64_comparison_operator"
272   (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,
273                ordered,unlt,unle,unge,ungt"))
275 ;; Same as aarch64_comparison_operator but don't ignore the mode.
276 ;; RTL SET operations require their operands source and destination have
277 ;; the same modes, so we can't ignore the modes there.  See PR target/69161.
278 (define_predicate "aarch64_comparison_operator_mode"
279   (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,
280                ordered,unlt,unle,unge,ungt"))
282 (define_special_predicate "aarch64_comparison_operation"
283   (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,
284                ordered,unlt,unle,unge,ungt")
286   if (XEXP (op, 1) != const0_rtx)
287     return false;
288   rtx op0 = XEXP (op, 0);
289   if (!REG_P (op0) || REGNO (op0) != CC_REGNUM)
290     return false;
291   return aarch64_get_condition_code (op) >= 0;
294 (define_special_predicate "aarch64_carry_operation"
295   (match_code "ne,geu")
297   if (XEXP (op, 1) != const0_rtx)
298     return false;
299   machine_mode ccmode = (GET_CODE (op) == NE ? CC_Cmode : CCmode);
300   rtx op0 = XEXP (op, 0);
301   return REG_P (op0) && REGNO (op0) == CC_REGNUM && GET_MODE (op0) == ccmode;
304 (define_special_predicate "aarch64_borrow_operation"
305   (match_code "eq,ltu")
307   if (XEXP (op, 1) != const0_rtx)
308     return false;
309   machine_mode ccmode = (GET_CODE (op) == EQ ? CC_Cmode : CCmode);
310   rtx op0 = XEXP (op, 0);
311   return REG_P (op0) && REGNO (op0) == CC_REGNUM && GET_MODE (op0) == ccmode;
314 ;; True if the operand is memory reference suitable for a load/store exclusive.
315 (define_predicate "aarch64_sync_memory_operand"
316   (and (match_operand 0 "memory_operand")
317        (match_code "reg" "0")))
319 ;; Predicates for parallel expanders based on mode.
320 (define_special_predicate "vect_par_cnst_hi_half"
321   (match_code "parallel")
323   return aarch64_simd_check_vect_par_cnst_half (op, mode, true);
326 (define_special_predicate "vect_par_cnst_lo_half"
327   (match_code "parallel")
329   return aarch64_simd_check_vect_par_cnst_half (op, mode, false);
332 (define_special_predicate "aarch64_simd_lshift_imm"
333   (match_code "const_vector")
335   return aarch64_simd_shift_imm_p (op, mode, true);
338 (define_special_predicate "aarch64_simd_rshift_imm"
339   (match_code "const_vector")
341   return aarch64_simd_shift_imm_p (op, mode, false);
344 (define_predicate "aarch64_simd_reg_or_zero"
345   (and (match_code "reg,subreg,const_int,const_double,const_vector")
346        (ior (match_operand 0 "register_operand")
347            (ior (match_test "op == const0_rtx")
348                 (match_test "aarch64_simd_imm_zero_p (op, mode)")))))
350 (define_predicate "aarch64_simd_struct_operand"
351   (and (match_code "mem")
352        (match_test "TARGET_SIMD && aarch64_simd_mem_operand_p (op)")))
354 ;; Like general_operand but allow only valid SIMD addressing modes.
355 (define_predicate "aarch64_simd_general_operand"
356   (and (match_operand 0 "general_operand")
357        (match_test "!MEM_P (op)
358                     || GET_CODE (XEXP (op, 0)) == POST_INC
359                     || GET_CODE (XEXP (op, 0)) == REG")))
361 ;; Like nonimmediate_operand but allow only valid SIMD addressing modes.
362 (define_predicate "aarch64_simd_nonimmediate_operand"
363   (and (match_operand 0 "nonimmediate_operand")
364        (match_test "!MEM_P (op)
365                     || GET_CODE (XEXP (op, 0)) == POST_INC
366                     || GET_CODE (XEXP (op, 0)) == REG")))
368 (define_special_predicate "aarch64_simd_imm_zero"
369   (match_code "const_vector")
371   return aarch64_simd_imm_zero_p (op, mode);
374 (define_special_predicate "aarch64_simd_or_scalar_imm_zero"
375   (match_test "aarch64_simd_imm_zero_p (op, mode)"))
377 (define_special_predicate "aarch64_simd_imm_minus_one"
378   (match_code "const_vector")
380   return aarch64_const_vec_all_same_int_p (op, -1);
383 ;; Predicates used by the various SIMD shift operations.  These
384 ;; fall in to 3 categories.
385 ;;   Shifts with a range 0-(bit_size - 1) (aarch64_simd_shift_imm)
386 ;;   Shifts with a range 1-bit_size (aarch64_simd_shift_imm_offset)
387 ;;   Shifts with a range 0-bit_size (aarch64_simd_shift_imm_bitsize)
388 (define_predicate "aarch64_simd_shift_imm_qi"
389   (and (match_code "const_int")
390        (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
392 (define_predicate "aarch64_simd_shift_imm_hi"
393   (and (match_code "const_int")
394        (match_test "IN_RANGE (INTVAL (op), 0, 15)")))
396 (define_predicate "aarch64_simd_shift_imm_si"
397   (and (match_code "const_int")
398        (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
400 (define_predicate "aarch64_simd_shift_imm_di"
401   (and (match_code "const_int")
402        (match_test "IN_RANGE (INTVAL (op), 0, 63)")))
404 (define_predicate "aarch64_simd_shift_imm_offset_qi"
405   (and (match_code "const_int")
406        (match_test "IN_RANGE (INTVAL (op), 1, 8)")))
408 (define_predicate "aarch64_simd_shift_imm_offset_hi"
409   (and (match_code "const_int")
410        (match_test "IN_RANGE (INTVAL (op), 1, 16)")))
412 (define_predicate "aarch64_simd_shift_imm_offset_si"
413   (and (match_code "const_int")
414        (match_test "IN_RANGE (INTVAL (op), 1, 32)")))
416 (define_predicate "aarch64_simd_shift_imm_offset_di"
417   (and (match_code "const_int")
418        (match_test "IN_RANGE (INTVAL (op), 1, 64)")))
420 (define_predicate "aarch64_simd_shift_imm_bitsize_qi"
421   (and (match_code "const_int")
422        (match_test "IN_RANGE (INTVAL (op), 0, 8)")))
424 (define_predicate "aarch64_simd_shift_imm_bitsize_hi"
425   (and (match_code "const_int")
426        (match_test "IN_RANGE (INTVAL (op), 0, 16)")))
428 (define_predicate "aarch64_simd_shift_imm_bitsize_si"
429   (and (match_code "const_int")
430        (match_test "IN_RANGE (INTVAL (op), 0, 32)")))
432 (define_predicate "aarch64_simd_shift_imm_bitsize_di"
433   (and (match_code "const_int")
434        (match_test "IN_RANGE (INTVAL (op), 0, 64)")))
436 (define_predicate "aarch64_constant_pool_symref"
437    (and (match_code "symbol_ref")
438         (match_test "CONSTANT_POOL_ADDRESS_P (op)")))