]> gcc.gnu.org Git - gcc.git/blame - gcc/config/aarch64/predicates.md
Update copyright years.
[gcc.git] / gcc / config / aarch64 / predicates.md
CommitLineData
43e9d192 1;; Machine description for AArch64 architecture.
5624e564 2;; Copyright (C) 2009-2015 Free Software Foundation, Inc.
43e9d192
IB
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
fee9ba42
JW
29(define_predicate "aarch64_call_insn_operand"
30 (ior (match_code "symbol_ref")
31 (match_operand 0 "register_operand")))
32
cf670503
ZC
33;; Return true if OP a (const_int 0) operand.
34(define_predicate "const0_operand"
35 (and (match_code "const_int, const_double")
36 (match_test "op == CONST0_RTX (mode)")))
37
b56d6aa1
ZC
38(define_predicate "aarch64_ccmp_immediate"
39 (and (match_code "const_int")
40 (match_test "IN_RANGE (INTVAL (op), -31, 31)")))
41
42(define_predicate "aarch64_ccmp_operand"
43 (ior (match_operand 0 "register_operand")
44 (match_operand 0 "aarch64_ccmp_immediate")))
45
3dfa7055
ZC
46(define_special_predicate "ccmp_cc_register"
47 (and (match_code "reg")
48 (and (match_test "REGNO (op) == CC_REGNUM")
49 (ior (match_test "mode == GET_MODE (op)")
50 (match_test "mode == VOIDmode
51 && (GET_MODE (op) == CC_DNEmode
52 || GET_MODE (op) == CC_DEQmode
53 || GET_MODE (op) == CC_DLEmode
54 || GET_MODE (op) == CC_DLTmode
55 || GET_MODE (op) == CC_DGEmode
56 || GET_MODE (op) == CC_DGTmode
57 || GET_MODE (op) == CC_DLEUmode
58 || GET_MODE (op) == CC_DLTUmode
59 || GET_MODE (op) == CC_DGEUmode
60 || GET_MODE (op) == CC_DGTUmode)"))))
61)
62
2e100703
VP
63(define_predicate "aarch64_simd_register"
64 (and (match_code "reg")
65 (ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS")
66 (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_REGS"))))
67
43e9d192
IB
68(define_predicate "aarch64_reg_or_zero"
69 (and (match_code "reg,subreg,const_int")
70 (ior (match_operand 0 "register_operand")
71 (match_test "op == const0_rtx"))))
72
889b9412
JG
73(define_predicate "aarch64_reg_or_fp_zero"
74 (and (match_code "reg,subreg,const_double")
75 (ior (match_operand 0 "register_operand")
76 (match_test "aarch64_float_const_zero_rtx_p (op)"))))
77
06b1198f 78(define_predicate "aarch64_reg_zero_or_m1_or_1"
43e9d192
IB
79 (and (match_code "reg,subreg,const_int")
80 (ior (match_operand 0 "register_operand")
81 (ior (match_test "op == const0_rtx")
06b1198f
IB
82 (ior (match_test "op == constm1_rtx")
83 (match_test "op == const1_rtx"))))))
43e9d192
IB
84
85(define_predicate "aarch64_fp_compare_operand"
86 (ior (match_operand 0 "register_operand")
87 (and (match_code "const_double")
3520f7cc 88 (match_test "aarch64_float_const_zero_rtx_p (op)"))))
43e9d192
IB
89
90(define_predicate "aarch64_plus_immediate"
91 (and (match_code "const_int")
92 (ior (match_test "aarch64_uimm12_shift (INTVAL (op))")
93 (match_test "aarch64_uimm12_shift (-INTVAL (op))"))))
94
95(define_predicate "aarch64_plus_operand"
96 (ior (match_operand 0 "register_operand")
97 (match_operand 0 "aarch64_plus_immediate")))
98
99(define_predicate "aarch64_pluslong_immediate"
100 (and (match_code "const_int")
101 (match_test "(INTVAL (op) < 0xffffff && INTVAL (op) > -0xffffff)")))
102
103(define_predicate "aarch64_pluslong_operand"
104 (ior (match_operand 0 "register_operand")
105 (match_operand 0 "aarch64_pluslong_immediate")))
106
107(define_predicate "aarch64_logical_immediate"
108 (and (match_code "const_int")
109 (match_test "aarch64_bitmask_imm (INTVAL (op), mode)")))
110
111(define_predicate "aarch64_logical_operand"
112 (ior (match_operand 0 "register_operand")
113 (match_operand 0 "aarch64_logical_immediate")))
114
115(define_predicate "aarch64_shift_imm_si"
116 (and (match_code "const_int")
117 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 32")))
118
119(define_predicate "aarch64_shift_imm_di"
120 (and (match_code "const_int")
121 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 64")))
122
f9a4c9a6
AV
123(define_predicate "aarch64_shift_imm64_di"
124 (and (match_code "const_int")
125 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 64")))
126
43e9d192
IB
127(define_predicate "aarch64_reg_or_shift_imm_si"
128 (ior (match_operand 0 "register_operand")
129 (match_operand 0 "aarch64_shift_imm_si")))
130
131(define_predicate "aarch64_reg_or_shift_imm_di"
132 (ior (match_operand 0 "register_operand")
133 (match_operand 0 "aarch64_shift_imm_di")))
134
135;; The imm3 field is a 3-bit field that only accepts immediates in the
136;; range 0..4.
137(define_predicate "aarch64_imm3"
138 (and (match_code "const_int")
139 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 4")))
140
141(define_predicate "aarch64_pwr_imm3"
142 (and (match_code "const_int")
143 (match_test "INTVAL (op) != 0
144 && (unsigned) exact_log2 (INTVAL (op)) <= 4")))
145
146(define_predicate "aarch64_pwr_2_si"
147 (and (match_code "const_int")
148 (match_test "INTVAL (op) != 0
149 && (unsigned) exact_log2 (INTVAL (op)) < 32")))
150
151(define_predicate "aarch64_pwr_2_di"
152 (and (match_code "const_int")
153 (match_test "INTVAL (op) != 0
154 && (unsigned) exact_log2 (INTVAL (op)) < 64")))
155
44707478
JW
156(define_predicate "aarch64_mem_pair_offset"
157 (and (match_code "const_int")
158 (match_test "aarch64_offset_7bit_signed_scaled_p (mode, INTVAL (op))")))
159
43e9d192
IB
160(define_predicate "aarch64_mem_pair_operand"
161 (and (match_code "mem")
162 (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL,
163 0)")))
164
43e9d192
IB
165(define_predicate "aarch64_valid_symref"
166 (match_code "const, symbol_ref, label_ref")
167{
da4f13a4
MS
168 return (aarch64_classify_symbolic_expression (op, SYMBOL_CONTEXT_ADR)
169 != SYMBOL_FORCE_TO_MEM);
43e9d192
IB
170})
171
172(define_predicate "aarch64_tls_ie_symref"
173 (match_code "const, symbol_ref, label_ref")
174{
175 switch (GET_CODE (op))
176 {
177 case CONST:
178 op = XEXP (op, 0);
179 if (GET_CODE (op) != PLUS
180 || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
181 || GET_CODE (XEXP (op, 1)) != CONST_INT)
182 return false;
183 op = XEXP (op, 0);
184
185 case SYMBOL_REF:
186 return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC;
187
188 default:
189 gcc_unreachable ();
190 }
191})
192
193(define_predicate "aarch64_tls_le_symref"
194 (match_code "const, symbol_ref, label_ref")
195{
196 switch (GET_CODE (op))
197 {
198 case CONST:
199 op = XEXP (op, 0);
200 if (GET_CODE (op) != PLUS
201 || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
202 || GET_CODE (XEXP (op, 1)) != CONST_INT)
203 return false;
204 op = XEXP (op, 0);
205
206 case SYMBOL_REF:
207 return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC;
208
209 default:
210 gcc_unreachable ();
211 }
212})
213
214(define_predicate "aarch64_mov_operand"
a5350ddc 215 (and (match_code "reg,subreg,mem,const,const_int,symbol_ref,label_ref,high")
43e9d192
IB
216 (ior (match_operand 0 "register_operand")
217 (ior (match_operand 0 "memory_operand")
83f8c414 218 (match_test "aarch64_mov_operand_p (op, SYMBOL_CONTEXT_ADR, mode)")))))
43e9d192
IB
219
220(define_predicate "aarch64_movti_operand"
221 (and (match_code "reg,subreg,mem,const_int")
222 (ior (match_operand 0 "register_operand")
223 (ior (match_operand 0 "memory_operand")
224 (match_operand 0 "const_int_operand")))))
225
226(define_predicate "aarch64_reg_or_imm"
227 (and (match_code "reg,subreg,const_int")
228 (ior (match_operand 0 "register_operand")
229 (match_operand 0 "const_int_operand"))))
230
231;; True for integer comparisons and for FP comparisons other than LTGT or UNEQ.
232(define_special_predicate "aarch64_comparison_operator"
233 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt"))
234
cd5660ab
KT
235(define_special_predicate "aarch64_comparison_operation"
236 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt")
237{
238 if (XEXP (op, 1) != const0_rtx)
239 return false;
240 rtx op0 = XEXP (op, 0);
241 if (!REG_P (op0) || REGNO (op0) != CC_REGNUM)
242 return false;
243 return aarch64_get_condition_code (op) >= 0;
244})
245
246
43e9d192
IB
247;; True if the operand is memory reference suitable for a load/store exclusive.
248(define_predicate "aarch64_sync_memory_operand"
249 (and (match_operand 0 "memory_operand")
250 (match_code "reg" "0")))
251
252;; Predicates for parallel expanders based on mode.
253(define_special_predicate "vect_par_cnst_hi_half"
254 (match_code "parallel")
255{
988fa693 256 return aarch64_simd_check_vect_par_cnst_half (op, mode, true);
43e9d192
IB
257})
258
259(define_special_predicate "vect_par_cnst_lo_half"
260 (match_code "parallel")
261{
988fa693 262 return aarch64_simd_check_vect_par_cnst_half (op, mode, false);
43e9d192
IB
263})
264
43e9d192
IB
265(define_special_predicate "aarch64_simd_lshift_imm"
266 (match_code "const_vector")
267{
268 return aarch64_simd_shift_imm_p (op, mode, true);
269})
270
271(define_special_predicate "aarch64_simd_rshift_imm"
272 (match_code "const_vector")
273{
274 return aarch64_simd_shift_imm_p (op, mode, false);
275})
276
277(define_predicate "aarch64_simd_reg_or_zero"
278 (and (match_code "reg,subreg,const_int,const_vector")
279 (ior (match_operand 0 "register_operand")
280 (ior (match_test "op == const0_rtx")
281 (match_test "aarch64_simd_imm_zero_p (op, mode)")))))
282
283(define_predicate "aarch64_simd_struct_operand"
284 (and (match_code "mem")
285 (match_test "TARGET_SIMD && aarch64_simd_mem_operand_p (op)")))
286
287;; Like general_operand but allow only valid SIMD addressing modes.
288(define_predicate "aarch64_simd_general_operand"
289 (and (match_operand 0 "general_operand")
290 (match_test "!MEM_P (op)
291 || GET_CODE (XEXP (op, 0)) == POST_INC
292 || GET_CODE (XEXP (op, 0)) == REG")))
293
294;; Like nonimmediate_operand but allow only valid SIMD addressing modes.
295(define_predicate "aarch64_simd_nonimmediate_operand"
296 (and (match_operand 0 "nonimmediate_operand")
297 (match_test "!MEM_P (op)
298 || GET_CODE (XEXP (op, 0)) == POST_INC
299 || GET_CODE (XEXP (op, 0)) == REG")))
300
301(define_special_predicate "aarch64_simd_imm_zero"
302 (match_code "const_vector")
303{
304 return aarch64_simd_imm_zero_p (op, mode);
305})
ddeabd3e
AL
306
307(define_special_predicate "aarch64_simd_imm_minus_one"
308 (match_code "const_vector")
309{
310 return aarch64_const_vec_all_same_int_p (op, -1);
311})
cb23a30c
JG
312
313;; Predicates used by the various SIMD shift operations. These
314;; fall in to 3 categories.
315;; Shifts with a range 0-(bit_size - 1) (aarch64_simd_shift_imm)
316;; Shifts with a range 1-bit_size (aarch64_simd_shift_imm_offset)
317;; Shifts with a range 0-bit_size (aarch64_simd_shift_imm_bitsize)
318(define_predicate "aarch64_simd_shift_imm_qi"
319 (and (match_code "const_int")
320 (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
321
322(define_predicate "aarch64_simd_shift_imm_hi"
323 (and (match_code "const_int")
324 (match_test "IN_RANGE (INTVAL (op), 0, 15)")))
325
326(define_predicate "aarch64_simd_shift_imm_si"
327 (and (match_code "const_int")
328 (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
329
330(define_predicate "aarch64_simd_shift_imm_di"
331 (and (match_code "const_int")
332 (match_test "IN_RANGE (INTVAL (op), 0, 63)")))
333
334(define_predicate "aarch64_simd_shift_imm_offset_qi"
335 (and (match_code "const_int")
336 (match_test "IN_RANGE (INTVAL (op), 1, 8)")))
337
338(define_predicate "aarch64_simd_shift_imm_offset_hi"
339 (and (match_code "const_int")
340 (match_test "IN_RANGE (INTVAL (op), 1, 16)")))
341
342(define_predicate "aarch64_simd_shift_imm_offset_si"
343 (and (match_code "const_int")
344 (match_test "IN_RANGE (INTVAL (op), 1, 32)")))
345
346(define_predicate "aarch64_simd_shift_imm_offset_di"
347 (and (match_code "const_int")
348 (match_test "IN_RANGE (INTVAL (op), 1, 64)")))
349
350(define_predicate "aarch64_simd_shift_imm_bitsize_qi"
351 (and (match_code "const_int")
352 (match_test "IN_RANGE (INTVAL (op), 0, 8)")))
353
354(define_predicate "aarch64_simd_shift_imm_bitsize_hi"
355 (and (match_code "const_int")
356 (match_test "IN_RANGE (INTVAL (op), 0, 16)")))
357
358(define_predicate "aarch64_simd_shift_imm_bitsize_si"
359 (and (match_code "const_int")
360 (match_test "IN_RANGE (INTVAL (op), 0, 32)")))
361
362(define_predicate "aarch64_simd_shift_imm_bitsize_di"
363 (and (match_code "const_int")
364 (match_test "IN_RANGE (INTVAL (op), 0, 64)")))
This page took 0.66651 seconds and 5 git commands to generate.