]>
Commit | Line | Data |
---|---|---|
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)"))) |