]>
Commit | Line | Data |
---|---|---|
df401d54 | 1 | ;; Machine description for AArch64 architecture. |
f1717362 | 2 | ;; Copyright (C) 2009-2016 Free Software Foundation, Inc. |
df401d54 | 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 | ||
1718b6c1 | 29 | (define_predicate "aarch64_call_insn_operand" |
30 | (ior (match_code "symbol_ref") | |
31 | (match_operand 0 "register_operand"))) | |
32 | ||
478473ed | 33 | ;; Return true if OP a (const_int 0) operand. |
34 | (define_predicate "const0_operand" | |
cac639db | 35 | (and (match_code "const_int") |
478473ed | 36 | (match_test "op == CONST0_RTX (mode)"))) |
37 | ||
5b1aa559 | 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 | ||
4ac2176a | 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 | ||
56741832 | 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 | ||
df401d54 | 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 | ||
6ba1316b | 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 | ||
7ff5a76f | 78 | (define_predicate "aarch64_reg_zero_or_m1_or_1" |
df401d54 | 79 | (and (match_code "reg,subreg,const_int") |
80 | (ior (match_operand 0 "register_operand") | |
81 | (ior (match_test "op == const0_rtx") | |
7ff5a76f | 82 | (ior (match_test "op == constm1_rtx") |
83 | (match_test "op == const1_rtx")))))) | |
df401d54 | 84 | |
85 | (define_predicate "aarch64_fp_compare_operand" | |
86 | (ior (match_operand 0 "register_operand") | |
87 | (and (match_code "const_double") | |
72841352 | 88 | (match_test "aarch64_float_const_zero_rtx_p (op)")))) |
df401d54 | 89 | |
ac80c076 | 90 | (define_predicate "aarch64_fp_pow2" |
91 | (and (match_code "const_double") | |
92 | (match_test "aarch64_fpconst_pow_of_2 (op) > 0"))) | |
93 | ||
94 | (define_predicate "aarch64_fp_vec_pow2" | |
95 | (match_test "aarch64_vec_fpconst_pow_of_2 (op) > 0")) | |
96 | ||
df401d54 | 97 | (define_predicate "aarch64_plus_immediate" |
98 | (and (match_code "const_int") | |
99 | (ior (match_test "aarch64_uimm12_shift (INTVAL (op))") | |
100 | (match_test "aarch64_uimm12_shift (-INTVAL (op))")))) | |
101 | ||
102 | (define_predicate "aarch64_plus_operand" | |
103 | (ior (match_operand 0 "register_operand") | |
104 | (match_operand 0 "aarch64_plus_immediate"))) | |
105 | ||
106 | (define_predicate "aarch64_pluslong_immediate" | |
107 | (and (match_code "const_int") | |
108 | (match_test "(INTVAL (op) < 0xffffff && INTVAL (op) > -0xffffff)"))) | |
109 | ||
110 | (define_predicate "aarch64_pluslong_operand" | |
111 | (ior (match_operand 0 "register_operand") | |
112 | (match_operand 0 "aarch64_pluslong_immediate"))) | |
113 | ||
114 | (define_predicate "aarch64_logical_immediate" | |
115 | (and (match_code "const_int") | |
116 | (match_test "aarch64_bitmask_imm (INTVAL (op), mode)"))) | |
117 | ||
118 | (define_predicate "aarch64_logical_operand" | |
119 | (ior (match_operand 0 "register_operand") | |
120 | (match_operand 0 "aarch64_logical_immediate"))) | |
121 | ||
122 | (define_predicate "aarch64_shift_imm_si" | |
123 | (and (match_code "const_int") | |
124 | (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 32"))) | |
125 | ||
126 | (define_predicate "aarch64_shift_imm_di" | |
127 | (and (match_code "const_int") | |
128 | (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 64"))) | |
129 | ||
33fb2095 | 130 | (define_predicate "aarch64_shift_imm64_di" |
131 | (and (match_code "const_int") | |
132 | (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 64"))) | |
133 | ||
df401d54 | 134 | (define_predicate "aarch64_reg_or_shift_imm_si" |
135 | (ior (match_operand 0 "register_operand") | |
136 | (match_operand 0 "aarch64_shift_imm_si"))) | |
137 | ||
138 | (define_predicate "aarch64_reg_or_shift_imm_di" | |
139 | (ior (match_operand 0 "register_operand") | |
140 | (match_operand 0 "aarch64_shift_imm_di"))) | |
141 | ||
142 | ;; The imm3 field is a 3-bit field that only accepts immediates in the | |
143 | ;; range 0..4. | |
144 | (define_predicate "aarch64_imm3" | |
145 | (and (match_code "const_int") | |
146 | (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 4"))) | |
147 | ||
51ba582e | 148 | ;; An immediate that fits into 24 bits. |
149 | (define_predicate "aarch64_imm24" | |
150 | (and (match_code "const_int") | |
151 | (match_test "IN_RANGE (UINTVAL (op), 0, 0xffffff)"))) | |
152 | ||
df401d54 | 153 | (define_predicate "aarch64_pwr_imm3" |
154 | (and (match_code "const_int") | |
155 | (match_test "INTVAL (op) != 0 | |
156 | && (unsigned) exact_log2 (INTVAL (op)) <= 4"))) | |
157 | ||
158 | (define_predicate "aarch64_pwr_2_si" | |
159 | (and (match_code "const_int") | |
160 | (match_test "INTVAL (op) != 0 | |
161 | && (unsigned) exact_log2 (INTVAL (op)) < 32"))) | |
162 | ||
163 | (define_predicate "aarch64_pwr_2_di" | |
164 | (and (match_code "const_int") | |
165 | (match_test "INTVAL (op) != 0 | |
166 | && (unsigned) exact_log2 (INTVAL (op)) < 64"))) | |
167 | ||
3ba73ce3 | 168 | (define_predicate "aarch64_mem_pair_offset" |
169 | (and (match_code "const_int") | |
170 | (match_test "aarch64_offset_7bit_signed_scaled_p (mode, INTVAL (op))"))) | |
171 | ||
df401d54 | 172 | (define_predicate "aarch64_mem_pair_operand" |
173 | (and (match_code "mem") | |
174 | (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL, | |
175 | 0)"))) | |
176 | ||
df401d54 | 177 | (define_predicate "aarch64_valid_symref" |
178 | (match_code "const, symbol_ref, label_ref") | |
179 | { | |
82882dbd | 180 | return (aarch64_classify_symbolic_expression (op) |
8fd61aba | 181 | != SYMBOL_FORCE_TO_MEM); |
df401d54 | 182 | }) |
183 | ||
184 | (define_predicate "aarch64_tls_ie_symref" | |
185 | (match_code "const, symbol_ref, label_ref") | |
186 | { | |
187 | switch (GET_CODE (op)) | |
188 | { | |
189 | case CONST: | |
190 | op = XEXP (op, 0); | |
191 | if (GET_CODE (op) != PLUS | |
192 | || GET_CODE (XEXP (op, 0)) != SYMBOL_REF | |
193 | || GET_CODE (XEXP (op, 1)) != CONST_INT) | |
194 | return false; | |
195 | op = XEXP (op, 0); | |
196 | ||
197 | case SYMBOL_REF: | |
198 | return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC; | |
199 | ||
200 | default: | |
201 | gcc_unreachable (); | |
202 | } | |
203 | }) | |
204 | ||
205 | (define_predicate "aarch64_tls_le_symref" | |
206 | (match_code "const, symbol_ref, label_ref") | |
207 | { | |
208 | switch (GET_CODE (op)) | |
209 | { | |
210 | case CONST: | |
211 | op = XEXP (op, 0); | |
212 | if (GET_CODE (op) != PLUS | |
213 | || GET_CODE (XEXP (op, 0)) != SYMBOL_REF | |
214 | || GET_CODE (XEXP (op, 1)) != CONST_INT) | |
215 | return false; | |
216 | op = XEXP (op, 0); | |
217 | ||
218 | case SYMBOL_REF: | |
219 | return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC; | |
220 | ||
221 | default: | |
222 | gcc_unreachable (); | |
223 | } | |
224 | }) | |
225 | ||
226 | (define_predicate "aarch64_mov_operand" | |
5137d3cb | 227 | (and (match_code "reg,subreg,mem,const,const_int,symbol_ref,label_ref,high") |
df401d54 | 228 | (ior (match_operand 0 "register_operand") |
229 | (ior (match_operand 0 "memory_operand") | |
82882dbd | 230 | (match_test "aarch64_mov_operand_p (op, mode)"))))) |
df401d54 | 231 | |
232 | (define_predicate "aarch64_movti_operand" | |
233 | (and (match_code "reg,subreg,mem,const_int") | |
234 | (ior (match_operand 0 "register_operand") | |
235 | (ior (match_operand 0 "memory_operand") | |
236 | (match_operand 0 "const_int_operand"))))) | |
237 | ||
238 | (define_predicate "aarch64_reg_or_imm" | |
239 | (and (match_code "reg,subreg,const_int") | |
240 | (ior (match_operand 0 "register_operand") | |
241 | (match_operand 0 "const_int_operand")))) | |
242 | ||
243 | ;; True for integer comparisons and for FP comparisons other than LTGT or UNEQ. | |
244 | (define_special_predicate "aarch64_comparison_operator" | |
245 | (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt")) | |
246 | ||
1e757156 | 247 | (define_special_predicate "aarch64_comparison_operation" |
248 | (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt") | |
249 | { | |
250 | if (XEXP (op, 1) != const0_rtx) | |
251 | return false; | |
252 | rtx op0 = XEXP (op, 0); | |
253 | if (!REG_P (op0) || REGNO (op0) != CC_REGNUM) | |
254 | return false; | |
255 | return aarch64_get_condition_code (op) >= 0; | |
256 | }) | |
257 | ||
258 | ||
df401d54 | 259 | ;; True if the operand is memory reference suitable for a load/store exclusive. |
260 | (define_predicate "aarch64_sync_memory_operand" | |
261 | (and (match_operand 0 "memory_operand") | |
262 | (match_code "reg" "0"))) | |
263 | ||
264 | ;; Predicates for parallel expanders based on mode. | |
265 | (define_special_predicate "vect_par_cnst_hi_half" | |
266 | (match_code "parallel") | |
267 | { | |
e71cd518 | 268 | return aarch64_simd_check_vect_par_cnst_half (op, mode, true); |
df401d54 | 269 | }) |
270 | ||
271 | (define_special_predicate "vect_par_cnst_lo_half" | |
272 | (match_code "parallel") | |
273 | { | |
e71cd518 | 274 | return aarch64_simd_check_vect_par_cnst_half (op, mode, false); |
df401d54 | 275 | }) |
276 | ||
df401d54 | 277 | (define_special_predicate "aarch64_simd_lshift_imm" |
278 | (match_code "const_vector") | |
279 | { | |
280 | return aarch64_simd_shift_imm_p (op, mode, true); | |
281 | }) | |
282 | ||
283 | (define_special_predicate "aarch64_simd_rshift_imm" | |
284 | (match_code "const_vector") | |
285 | { | |
286 | return aarch64_simd_shift_imm_p (op, mode, false); | |
287 | }) | |
288 | ||
289 | (define_predicate "aarch64_simd_reg_or_zero" | |
290 | (and (match_code "reg,subreg,const_int,const_vector") | |
291 | (ior (match_operand 0 "register_operand") | |
292 | (ior (match_test "op == const0_rtx") | |
293 | (match_test "aarch64_simd_imm_zero_p (op, mode)"))))) | |
294 | ||
295 | (define_predicate "aarch64_simd_struct_operand" | |
296 | (and (match_code "mem") | |
297 | (match_test "TARGET_SIMD && aarch64_simd_mem_operand_p (op)"))) | |
298 | ||
299 | ;; Like general_operand but allow only valid SIMD addressing modes. | |
300 | (define_predicate "aarch64_simd_general_operand" | |
301 | (and (match_operand 0 "general_operand") | |
302 | (match_test "!MEM_P (op) | |
303 | || GET_CODE (XEXP (op, 0)) == POST_INC | |
304 | || GET_CODE (XEXP (op, 0)) == REG"))) | |
305 | ||
306 | ;; Like nonimmediate_operand but allow only valid SIMD addressing modes. | |
307 | (define_predicate "aarch64_simd_nonimmediate_operand" | |
308 | (and (match_operand 0 "nonimmediate_operand") | |
309 | (match_test "!MEM_P (op) | |
310 | || GET_CODE (XEXP (op, 0)) == POST_INC | |
311 | || GET_CODE (XEXP (op, 0)) == REG"))) | |
312 | ||
313 | (define_special_predicate "aarch64_simd_imm_zero" | |
314 | (match_code "const_vector") | |
315 | { | |
316 | return aarch64_simd_imm_zero_p (op, mode); | |
317 | }) | |
bead021f | 318 | |
319 | (define_special_predicate "aarch64_simd_imm_minus_one" | |
320 | (match_code "const_vector") | |
321 | { | |
322 | return aarch64_const_vec_all_same_int_p (op, -1); | |
323 | }) | |
a92326b6 | 324 | |
325 | ;; Predicates used by the various SIMD shift operations. These | |
326 | ;; fall in to 3 categories. | |
327 | ;; Shifts with a range 0-(bit_size - 1) (aarch64_simd_shift_imm) | |
328 | ;; Shifts with a range 1-bit_size (aarch64_simd_shift_imm_offset) | |
329 | ;; Shifts with a range 0-bit_size (aarch64_simd_shift_imm_bitsize) | |
330 | (define_predicate "aarch64_simd_shift_imm_qi" | |
331 | (and (match_code "const_int") | |
332 | (match_test "IN_RANGE (INTVAL (op), 0, 7)"))) | |
333 | ||
334 | (define_predicate "aarch64_simd_shift_imm_hi" | |
335 | (and (match_code "const_int") | |
336 | (match_test "IN_RANGE (INTVAL (op), 0, 15)"))) | |
337 | ||
338 | (define_predicate "aarch64_simd_shift_imm_si" | |
339 | (and (match_code "const_int") | |
340 | (match_test "IN_RANGE (INTVAL (op), 0, 31)"))) | |
341 | ||
342 | (define_predicate "aarch64_simd_shift_imm_di" | |
343 | (and (match_code "const_int") | |
344 | (match_test "IN_RANGE (INTVAL (op), 0, 63)"))) | |
345 | ||
346 | (define_predicate "aarch64_simd_shift_imm_offset_qi" | |
347 | (and (match_code "const_int") | |
348 | (match_test "IN_RANGE (INTVAL (op), 1, 8)"))) | |
349 | ||
350 | (define_predicate "aarch64_simd_shift_imm_offset_hi" | |
351 | (and (match_code "const_int") | |
352 | (match_test "IN_RANGE (INTVAL (op), 1, 16)"))) | |
353 | ||
354 | (define_predicate "aarch64_simd_shift_imm_offset_si" | |
355 | (and (match_code "const_int") | |
356 | (match_test "IN_RANGE (INTVAL (op), 1, 32)"))) | |
357 | ||
358 | (define_predicate "aarch64_simd_shift_imm_offset_di" | |
359 | (and (match_code "const_int") | |
360 | (match_test "IN_RANGE (INTVAL (op), 1, 64)"))) | |
361 | ||
362 | (define_predicate "aarch64_simd_shift_imm_bitsize_qi" | |
363 | (and (match_code "const_int") | |
364 | (match_test "IN_RANGE (INTVAL (op), 0, 8)"))) | |
365 | ||
366 | (define_predicate "aarch64_simd_shift_imm_bitsize_hi" | |
367 | (and (match_code "const_int") | |
368 | (match_test "IN_RANGE (INTVAL (op), 0, 16)"))) | |
369 | ||
370 | (define_predicate "aarch64_simd_shift_imm_bitsize_si" | |
371 | (and (match_code "const_int") | |
372 | (match_test "IN_RANGE (INTVAL (op), 0, 32)"))) | |
373 | ||
374 | (define_predicate "aarch64_simd_shift_imm_bitsize_di" | |
375 | (and (match_code "const_int") | |
376 | (match_test "IN_RANGE (INTVAL (op), 0, 64)"))) | |
ae1cefe6 | 377 | |
378 | (define_predicate "aarch64_constant_pool_symref" | |
379 | (and (match_code "symbol_ref") | |
380 | (match_test "CONSTANT_POOL_ADDRESS_P (op)"))) |