Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/aarch64/predicates.md @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
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. | |
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 | |
29 (define_predicate "aarch64_call_insn_operand" | |
30 (ior (match_code "symbol_ref") | |
31 (match_operand 0 "register_operand"))) | |
32 | |
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)"))) | |
37 | |
38 (define_special_predicate "subreg_lowpart_operator" | |
39 (and (match_code "subreg") | |
40 (match_test "subreg_lowpart_p (op)"))) | |
41 | |
42 (define_predicate "aarch64_ccmp_immediate" | |
43 (and (match_code "const_int") | |
44 (match_test "IN_RANGE (INTVAL (op), -31, 31)"))) | |
45 | |
46 (define_predicate "aarch64_ccmp_operand" | |
47 (ior (match_operand 0 "register_operand") | |
48 (match_operand 0 "aarch64_ccmp_immediate"))) | |
49 | |
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")))) | |
54 | |
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")))) | |
59 | |
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)")))) | |
64 | |
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")))))) | |
71 | |
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)")))) | |
77 | |
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)")))) | |
83 | |
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)")))) | |
88 | |
89 (define_predicate "aarch64_fp_pow2" | |
90 (and (match_code "const_double") | |
91 (match_test "aarch64_fpconst_pow_of_2 (op) > 0"))) | |
92 | |
93 (define_predicate "aarch64_fp_vec_pow2" | |
94 (match_test "aarch64_vec_fpconst_pow_of_2 (op) > 0")) | |
95 | |
96 (define_predicate "aarch64_sub_immediate" | |
97 (and (match_code "const_int") | |
98 (match_test "aarch64_uimm12_shift (-INTVAL (op))"))) | |
99 | |
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))")))) | |
104 | |
105 (define_predicate "aarch64_plus_operand" | |
106 (ior (match_operand 0 "register_operand") | |
107 (match_operand 0 "aarch64_plus_immediate"))) | |
108 | |
109 (define_predicate "aarch64_pluslong_immediate" | |
110 (and (match_code "const_int") | |
111 (match_test "(INTVAL (op) < 0xffffff && INTVAL (op) > -0xffffff)"))) | |
112 | |
113 (define_predicate "aarch64_pluslong_strict_immedate" | |
114 (and (match_operand 0 "aarch64_pluslong_immediate") | |
115 (not (match_operand 0 "aarch64_plus_immediate")))) | |
116 | |
117 (define_predicate "aarch64_pluslong_operand" | |
118 (ior (match_operand 0 "register_operand") | |
119 (match_operand 0 "aarch64_pluslong_immediate"))) | |
120 | |
121 (define_predicate "aarch64_logical_immediate" | |
122 (and (match_code "const_int") | |
123 (match_test "aarch64_bitmask_imm (INTVAL (op), mode)"))) | |
124 | |
125 (define_predicate "aarch64_logical_operand" | |
126 (ior (match_operand 0 "register_operand") | |
127 (match_operand 0 "aarch64_logical_immediate"))) | |
128 | |
129 (define_predicate "aarch64_mov_imm_operand" | |
130 (and (match_code "const_int") | |
131 (match_test "aarch64_move_imm (INTVAL (op), mode)"))) | |
132 | |
133 (define_predicate "aarch64_logical_and_immediate" | |
134 (and (match_code "const_int") | |
135 (match_test "aarch64_and_bitmask_imm (INTVAL (op), mode)"))) | |
136 | |
137 (define_predicate "aarch64_shift_imm_si" | |
138 (and (match_code "const_int") | |
139 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 32"))) | |
140 | |
141 (define_predicate "aarch64_shift_imm_di" | |
142 (and (match_code "const_int") | |
143 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 64"))) | |
144 | |
145 (define_predicate "aarch64_shift_imm64_di" | |
146 (and (match_code "const_int") | |
147 (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 64"))) | |
148 | |
149 (define_predicate "aarch64_reg_or_shift_imm_si" | |
150 (ior (match_operand 0 "register_operand") | |
151 (match_operand 0 "aarch64_shift_imm_si"))) | |
152 | |
153 (define_predicate "aarch64_reg_or_shift_imm_di" | |
154 (ior (match_operand 0 "register_operand") | |
155 (match_operand 0 "aarch64_shift_imm_di"))) | |
156 | |
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"))) | |
162 | |
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)"))) | |
167 | |
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"))) | |
172 | |
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"))) | |
177 | |
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"))) | |
182 | |
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))"))) | |
186 | |
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)"))) | |
191 | |
192 (define_predicate "aarch64_prefetch_operand" | |
193 (match_test "aarch64_address_valid_for_prefetch_p (op, false)")) | |
194 | |
195 (define_predicate "aarch64_valid_symref" | |
196 (match_code "const, symbol_ref, label_ref") | |
197 { | |
198 return (aarch64_classify_symbolic_expression (op) | |
199 != SYMBOL_FORCE_TO_MEM); | |
200 }) | |
201 | |
202 (define_predicate "aarch64_tls_ie_symref" | |
203 (match_code "const, symbol_ref, label_ref") | |
204 { | |
205 switch (GET_CODE (op)) | |
206 { | |
207 case CONST: | |
208 op = XEXP (op, 0); | |
209 if (GET_CODE (op) != PLUS | |
210 || GET_CODE (XEXP (op, 0)) != SYMBOL_REF | |
211 || GET_CODE (XEXP (op, 1)) != CONST_INT) | |
212 return false; | |
213 op = XEXP (op, 0); | |
214 /* FALLTHRU */ | |
215 | |
216 case SYMBOL_REF: | |
217 return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC; | |
218 | |
219 default: | |
220 gcc_unreachable (); | |
221 } | |
222 }) | |
223 | |
224 (define_predicate "aarch64_tls_le_symref" | |
225 (match_code "const, symbol_ref, label_ref") | |
226 { | |
227 switch (GET_CODE (op)) | |
228 { | |
229 case CONST: | |
230 op = XEXP (op, 0); | |
231 if (GET_CODE (op) != PLUS | |
232 || GET_CODE (XEXP (op, 0)) != SYMBOL_REF | |
233 || GET_CODE (XEXP (op, 1)) != CONST_INT) | |
234 return false; | |
235 op = XEXP (op, 0); | |
236 /* FALLTHRU */ | |
237 | |
238 case SYMBOL_REF: | |
239 return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC; | |
240 | |
241 default: | |
242 gcc_unreachable (); | |
243 } | |
244 }) | |
245 | |
246 (define_predicate "aarch64_mov_operand" | |
247 (and (match_code "reg,subreg,mem,const,const_int,symbol_ref,label_ref,high") | |
248 (ior (match_operand 0 "register_operand") | |
249 (ior (match_operand 0 "memory_operand") | |
250 (match_test "aarch64_mov_operand_p (op, mode)"))))) | |
251 | |
252 (define_predicate "aarch64_movti_operand" | |
253 (and (match_code "reg,subreg,mem,const_int") | |
254 (ior (match_operand 0 "register_operand") | |
255 (ior (match_operand 0 "memory_operand") | |
256 (match_operand 0 "const_int_operand"))))) | |
257 | |
258 (define_predicate "aarch64_reg_or_imm" | |
259 (and (match_code "reg,subreg,const_int") | |
260 (ior (match_operand 0 "register_operand") | |
261 (match_operand 0 "const_int_operand")))) | |
262 | |
263 ;; True for integer comparisons and for FP comparisons other than LTGT or UNEQ. | |
264 (define_special_predicate "aarch64_comparison_operator" | |
265 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered, | |
266 ordered,unlt,unle,unge,ungt")) | |
267 | |
268 ;; Same as aarch64_comparison_operator but don't ignore the mode. | |
269 ;; RTL SET operations require their operands source and destination have | |
270 ;; the same modes, so we can't ignore the modes there. See PR target/69161. | |
271 (define_predicate "aarch64_comparison_operator_mode" | |
272 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered, | |
273 ordered,unlt,unle,unge,ungt")) | |
274 | |
275 (define_special_predicate "aarch64_comparison_operation" | |
276 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered, | |
277 ordered,unlt,unle,unge,ungt") | |
278 { | |
279 if (XEXP (op, 1) != const0_rtx) | |
280 return false; | |
281 rtx op0 = XEXP (op, 0); | |
282 if (!REG_P (op0) || REGNO (op0) != CC_REGNUM) | |
283 return false; | |
284 return aarch64_get_condition_code (op) >= 0; | |
285 }) | |
286 | |
287 (define_special_predicate "aarch64_carry_operation" | |
288 (match_code "ne,geu") | |
289 { | |
290 if (XEXP (op, 1) != const0_rtx) | |
291 return false; | |
292 machine_mode ccmode = (GET_CODE (op) == NE ? CC_Cmode : CCmode); | |
293 rtx op0 = XEXP (op, 0); | |
294 return REG_P (op0) && REGNO (op0) == CC_REGNUM && GET_MODE (op0) == ccmode; | |
295 }) | |
296 | |
297 (define_special_predicate "aarch64_borrow_operation" | |
298 (match_code "eq,ltu") | |
299 { | |
300 if (XEXP (op, 1) != const0_rtx) | |
301 return false; | |
302 machine_mode ccmode = (GET_CODE (op) == EQ ? CC_Cmode : CCmode); | |
303 rtx op0 = XEXP (op, 0); | |
304 return REG_P (op0) && REGNO (op0) == CC_REGNUM && GET_MODE (op0) == ccmode; | |
305 }) | |
306 | |
307 ;; True if the operand is memory reference suitable for a load/store exclusive. | |
308 (define_predicate "aarch64_sync_memory_operand" | |
309 (and (match_operand 0 "memory_operand") | |
310 (match_code "reg" "0"))) | |
311 | |
312 ;; Predicates for parallel expanders based on mode. | |
313 (define_special_predicate "vect_par_cnst_hi_half" | |
314 (match_code "parallel") | |
315 { | |
316 return aarch64_simd_check_vect_par_cnst_half (op, mode, true); | |
317 }) | |
318 | |
319 (define_special_predicate "vect_par_cnst_lo_half" | |
320 (match_code "parallel") | |
321 { | |
322 return aarch64_simd_check_vect_par_cnst_half (op, mode, false); | |
323 }) | |
324 | |
325 (define_special_predicate "aarch64_simd_lshift_imm" | |
326 (match_code "const_vector") | |
327 { | |
328 return aarch64_simd_shift_imm_p (op, mode, true); | |
329 }) | |
330 | |
331 (define_special_predicate "aarch64_simd_rshift_imm" | |
332 (match_code "const_vector") | |
333 { | |
334 return aarch64_simd_shift_imm_p (op, mode, false); | |
335 }) | |
336 | |
337 (define_predicate "aarch64_simd_reg_or_zero" | |
338 (and (match_code "reg,subreg,const_int,const_double,const_vector") | |
339 (ior (match_operand 0 "register_operand") | |
340 (ior (match_test "op == const0_rtx") | |
341 (match_test "aarch64_simd_imm_zero_p (op, mode)"))))) | |
342 | |
343 (define_predicate "aarch64_simd_struct_operand" | |
344 (and (match_code "mem") | |
345 (match_test "TARGET_SIMD && aarch64_simd_mem_operand_p (op)"))) | |
346 | |
347 ;; Like general_operand but allow only valid SIMD addressing modes. | |
348 (define_predicate "aarch64_simd_general_operand" | |
349 (and (match_operand 0 "general_operand") | |
350 (match_test "!MEM_P (op) | |
351 || GET_CODE (XEXP (op, 0)) == POST_INC | |
352 || GET_CODE (XEXP (op, 0)) == REG"))) | |
353 | |
354 ;; Like nonimmediate_operand but allow only valid SIMD addressing modes. | |
355 (define_predicate "aarch64_simd_nonimmediate_operand" | |
356 (and (match_operand 0 "nonimmediate_operand") | |
357 (match_test "!MEM_P (op) | |
358 || GET_CODE (XEXP (op, 0)) == POST_INC | |
359 || GET_CODE (XEXP (op, 0)) == REG"))) | |
360 | |
361 (define_special_predicate "aarch64_simd_imm_zero" | |
362 (match_code "const_vector") | |
363 { | |
364 return aarch64_simd_imm_zero_p (op, mode); | |
365 }) | |
366 | |
367 (define_special_predicate "aarch64_simd_imm_minus_one" | |
368 (match_code "const_vector") | |
369 { | |
370 return aarch64_const_vec_all_same_int_p (op, -1); | |
371 }) | |
372 | |
373 ;; Predicates used by the various SIMD shift operations. These | |
374 ;; fall in to 3 categories. | |
375 ;; Shifts with a range 0-(bit_size - 1) (aarch64_simd_shift_imm) | |
376 ;; Shifts with a range 1-bit_size (aarch64_simd_shift_imm_offset) | |
377 ;; Shifts with a range 0-bit_size (aarch64_simd_shift_imm_bitsize) | |
378 (define_predicate "aarch64_simd_shift_imm_qi" | |
379 (and (match_code "const_int") | |
380 (match_test "IN_RANGE (INTVAL (op), 0, 7)"))) | |
381 | |
382 (define_predicate "aarch64_simd_shift_imm_hi" | |
383 (and (match_code "const_int") | |
384 (match_test "IN_RANGE (INTVAL (op), 0, 15)"))) | |
385 | |
386 (define_predicate "aarch64_simd_shift_imm_si" | |
387 (and (match_code "const_int") | |
388 (match_test "IN_RANGE (INTVAL (op), 0, 31)"))) | |
389 | |
390 (define_predicate "aarch64_simd_shift_imm_di" | |
391 (and (match_code "const_int") | |
392 (match_test "IN_RANGE (INTVAL (op), 0, 63)"))) | |
393 | |
394 (define_predicate "aarch64_simd_shift_imm_offset_qi" | |
395 (and (match_code "const_int") | |
396 (match_test "IN_RANGE (INTVAL (op), 1, 8)"))) | |
397 | |
398 (define_predicate "aarch64_simd_shift_imm_offset_hi" | |
399 (and (match_code "const_int") | |
400 (match_test "IN_RANGE (INTVAL (op), 1, 16)"))) | |
401 | |
402 (define_predicate "aarch64_simd_shift_imm_offset_si" | |
403 (and (match_code "const_int") | |
404 (match_test "IN_RANGE (INTVAL (op), 1, 32)"))) | |
405 | |
406 (define_predicate "aarch64_simd_shift_imm_offset_di" | |
407 (and (match_code "const_int") | |
408 (match_test "IN_RANGE (INTVAL (op), 1, 64)"))) | |
409 | |
410 (define_predicate "aarch64_simd_shift_imm_bitsize_qi" | |
411 (and (match_code "const_int") | |
412 (match_test "IN_RANGE (INTVAL (op), 0, 8)"))) | |
413 | |
414 (define_predicate "aarch64_simd_shift_imm_bitsize_hi" | |
415 (and (match_code "const_int") | |
416 (match_test "IN_RANGE (INTVAL (op), 0, 16)"))) | |
417 | |
418 (define_predicate "aarch64_simd_shift_imm_bitsize_si" | |
419 (and (match_code "const_int") | |
420 (match_test "IN_RANGE (INTVAL (op), 0, 32)"))) | |
421 | |
422 (define_predicate "aarch64_simd_shift_imm_bitsize_di" | |
423 (and (match_code "const_int") | |
424 (match_test "IN_RANGE (INTVAL (op), 0, 64)"))) | |
425 | |
426 (define_predicate "aarch64_constant_pool_symref" | |
427 (and (match_code "symbol_ref") | |
428 (match_test "CONSTANT_POOL_ADDRESS_P (op)"))) |