]>
Commit | Line | Data |
---|---|---|
a657c98a | 1 | ;; Predicate definitions for ARM and Thumb |
d652f226 | 2 | ;; Copyright (C) 2004, 2007, 2008, 2010 Free Software Foundation, Inc. |
a657c98a RE |
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 | |
2f83c7d6 | 9 | ;; by the Free Software Foundation; either version 3, or (at your |
a657c98a RE |
10 | ;; option) any later version. |
11 | ||
12 | ;; GCC is distributed in the hope that it will be useful, but WITHOUT | |
13 | ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
14 | ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
15 | ;; License for more details. | |
16 | ||
17 | ;; You should have received a copy of the GNU General Public License | |
2f83c7d6 NC |
18 | ;; along with GCC; see the file COPYING3. If not see |
19 | ;; <http://www.gnu.org/licenses/>. | |
a657c98a RE |
20 | |
21 | (define_predicate "s_register_operand" | |
22 | (match_code "reg,subreg") | |
23 | { | |
24 | if (GET_CODE (op) == SUBREG) | |
25 | op = SUBREG_REG (op); | |
26 | /* We don't consider registers whose class is NO_REGS | |
27 | to be a register operand. */ | |
28 | /* XXX might have to check for lo regs only for thumb ??? */ | |
29 | return (GET_CODE (op) == REG | |
30 | && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
31 | || REGNO_REG_CLASS (REGNO (op)) != NO_REGS)); | |
32 | }) | |
33 | ||
34 | ;; Any hard register. | |
35 | (define_predicate "arm_hard_register_operand" | |
36 | (match_code "reg") | |
37 | { | |
38 | return REGNO (op) < FIRST_PSEUDO_REGISTER; | |
39 | }) | |
40 | ||
5b3e6663 PB |
41 | ;; A low register. |
42 | (define_predicate "low_register_operand" | |
43 | (and (match_code "reg") | |
44 | (match_test "REGNO (op) <= LAST_LO_REGNUM"))) | |
45 | ||
46 | ;; A low register or const_int. | |
47 | (define_predicate "low_reg_or_int_operand" | |
48 | (ior (match_code "const_int") | |
49 | (match_operand 0 "low_register_operand"))) | |
50 | ||
a657c98a RE |
51 | ;; Any core register, or any pseudo. */ |
52 | (define_predicate "arm_general_register_operand" | |
53 | (match_code "reg,subreg") | |
54 | { | |
55 | if (GET_CODE (op) == SUBREG) | |
56 | op = SUBREG_REG (op); | |
57 | ||
58 | return (GET_CODE (op) == REG | |
59 | && (REGNO (op) <= LAST_ARM_REGNUM | |
60 | || REGNO (op) >= FIRST_PSEUDO_REGISTER)); | |
61 | }) | |
62 | ||
63 | (define_predicate "f_register_operand" | |
64 | (match_code "reg,subreg") | |
65 | { | |
66 | if (GET_CODE (op) == SUBREG) | |
67 | op = SUBREG_REG (op); | |
68 | ||
69 | /* We don't consider registers whose class is NO_REGS | |
70 | to be a register operand. */ | |
71 | return (GET_CODE (op) == REG | |
72 | && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
73 | || REGNO_REG_CLASS (REGNO (op)) == FPA_REGS)); | |
74 | }) | |
75 | ||
4e6f5666 JZ |
76 | (define_predicate "vfp_register_operand" |
77 | (match_code "reg,subreg") | |
78 | { | |
79 | if (GET_CODE (op) == SUBREG) | |
80 | op = SUBREG_REG (op); | |
81 | ||
82 | /* We don't consider registers whose class is NO_REGS | |
83 | to be a register operand. */ | |
84 | return (GET_CODE (op) == REG | |
85 | && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
34db4735 | 86 | || REGNO_REG_CLASS (REGNO (op)) == VFP_D0_D7_REGS |
4e6f5666 JZ |
87 | || REGNO_REG_CLASS (REGNO (op)) == VFP_LO_REGS |
88 | || (TARGET_VFPD32 | |
89 | && REGNO_REG_CLASS (REGNO (op)) == VFP_REGS))); | |
90 | }) | |
91 | ||
fa01135d RE |
92 | (define_special_predicate "subreg_lowpart_operator" |
93 | (and (match_code "subreg") | |
94 | (match_test "subreg_lowpart_p (op)"))) | |
95 | ||
a657c98a RE |
96 | ;; Reg, subreg(reg) or const_int. |
97 | (define_predicate "reg_or_int_operand" | |
98 | (ior (match_code "const_int") | |
99 | (match_operand 0 "s_register_operand"))) | |
100 | ||
101 | (define_predicate "arm_immediate_operand" | |
102 | (and (match_code "const_int") | |
103 | (match_test "const_ok_for_arm (INTVAL (op))"))) | |
104 | ||
73160ba9 DJ |
105 | ;; A constant value which fits into two instructions, each taking |
106 | ;; an arithmetic constant operand for one of the words. | |
107 | (define_predicate "arm_immediate_di_operand" | |
108 | (and (match_code "const_int,const_double") | |
109 | (match_test "arm_const_double_by_immediates (op)"))) | |
110 | ||
a657c98a RE |
111 | (define_predicate "arm_neg_immediate_operand" |
112 | (and (match_code "const_int") | |
113 | (match_test "const_ok_for_arm (-INTVAL (op))"))) | |
114 | ||
115 | (define_predicate "arm_not_immediate_operand" | |
116 | (and (match_code "const_int") | |
117 | (match_test "const_ok_for_arm (~INTVAL (op))"))) | |
118 | ||
f0c6475a BS |
119 | (define_predicate "const0_operand" |
120 | (and (match_code "const_int") | |
121 | (match_test "INTVAL (op) == 0"))) | |
122 | ||
a657c98a RE |
123 | ;; Something valid on the RHS of an ARM data-processing instruction |
124 | (define_predicate "arm_rhs_operand" | |
125 | (ior (match_operand 0 "s_register_operand") | |
126 | (match_operand 0 "arm_immediate_operand"))) | |
127 | ||
128 | (define_predicate "arm_rhsm_operand" | |
129 | (ior (match_operand 0 "arm_rhs_operand") | |
130 | (match_operand 0 "memory_operand"))) | |
131 | ||
c29e2982 BS |
132 | (define_predicate "shift_amount_operand" |
133 | (ior (and (match_test "TARGET_ARM") | |
134 | (match_operand 0 "s_register_operand")) | |
135 | (match_operand 0 "const_int_operand"))) | |
136 | ||
a657c98a RE |
137 | (define_predicate "arm_add_operand" |
138 | (ior (match_operand 0 "arm_rhs_operand") | |
139 | (match_operand 0 "arm_neg_immediate_operand"))) | |
140 | ||
141 | (define_predicate "arm_addimm_operand" | |
142 | (ior (match_operand 0 "arm_immediate_operand") | |
143 | (match_operand 0 "arm_neg_immediate_operand"))) | |
144 | ||
145 | (define_predicate "arm_not_operand" | |
146 | (ior (match_operand 0 "arm_rhs_operand") | |
147 | (match_operand 0 "arm_not_immediate_operand"))) | |
148 | ||
73160ba9 DJ |
149 | (define_predicate "arm_di_operand" |
150 | (ior (match_operand 0 "s_register_operand") | |
151 | (match_operand 0 "arm_immediate_di_operand"))) | |
152 | ||
a657c98a RE |
153 | ;; True if the operand is a memory reference which contains an |
154 | ;; offsettable address. | |
155 | (define_predicate "offsettable_memory_operand" | |
156 | (and (match_code "mem") | |
157 | (match_test | |
158 | "offsettable_address_p (reload_completed | reload_in_progress, | |
159 | mode, XEXP (op, 0))"))) | |
160 | ||
e6add59b RS |
161 | ;; True if the operand is a memory operand that does not have an |
162 | ;; automodified base register (and thus will not generate output reloads). | |
163 | (define_predicate "call_memory_operand" | |
164 | (and (match_code "mem") | |
165 | (and (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) | |
166 | != RTX_AUTOINC") | |
167 | (match_operand 0 "memory_operand")))) | |
168 | ||
a657c98a | 169 | (define_predicate "arm_reload_memory_operand" |
9d2da95b | 170 | (and (match_code "mem,reg,subreg") |
a657c98a RE |
171 | (match_test "(!CONSTANT_P (op) |
172 | && (true_regnum(op) == -1 | |
173 | || (GET_CODE (op) == REG | |
174 | && REGNO (op) >= FIRST_PSEUDO_REGISTER)))"))) | |
175 | ||
176 | ;; True for valid operands for the rhs of an floating point insns. | |
177 | ;; Allows regs or certain consts on FPA, just regs for everything else. | |
178 | (define_predicate "arm_float_rhs_operand" | |
179 | (ior (match_operand 0 "s_register_operand") | |
180 | (and (match_code "const_double") | |
181 | (match_test "TARGET_FPA && arm_const_double_rtx (op)")))) | |
182 | ||
183 | (define_predicate "arm_float_add_operand" | |
184 | (ior (match_operand 0 "arm_float_rhs_operand") | |
185 | (and (match_code "const_double") | |
186 | (match_test "TARGET_FPA && neg_const_double_rtx_ok_for_fpa (op)")))) | |
187 | ||
188 | (define_predicate "vfp_compare_operand" | |
189 | (ior (match_operand 0 "s_register_operand") | |
190 | (and (match_code "const_double") | |
191 | (match_test "arm_const_double_rtx (op)")))) | |
192 | ||
193 | (define_predicate "arm_float_compare_operand" | |
194 | (if_then_else (match_test "TARGET_VFP") | |
195 | (match_operand 0 "vfp_compare_operand") | |
196 | (match_operand 0 "arm_float_rhs_operand"))) | |
197 | ||
198 | ;; True for valid index operands. | |
199 | (define_predicate "index_operand" | |
200 | (ior (match_operand 0 "s_register_operand") | |
201 | (and (match_operand 0 "immediate_operand") | |
202 | (match_test "(GET_CODE (op) != CONST_INT | |
203 | || (INTVAL (op) < 4096 && INTVAL (op) > -4096))")))) | |
204 | ||
205 | ;; True for operators that can be combined with a shift in ARM state. | |
206 | (define_special_predicate "shiftable_operator" | |
207 | (and (match_code "plus,minus,ior,xor,and") | |
208 | (match_test "mode == GET_MODE (op)"))) | |
209 | ||
c112cf2b | 210 | ;; True for logical binary operators. |
a657c98a RE |
211 | (define_special_predicate "logical_binary_operator" |
212 | (and (match_code "ior,xor,and") | |
213 | (match_test "mode == GET_MODE (op)"))) | |
214 | ||
37119410 BS |
215 | ;; True for commutative operators |
216 | (define_special_predicate "commutative_binary_operator" | |
217 | (and (match_code "ior,xor,and,plus") | |
218 | (match_test "mode == GET_MODE (op)"))) | |
219 | ||
a657c98a RE |
220 | ;; True for shift operators. |
221 | (define_special_predicate "shift_operator" | |
222 | (and (ior (ior (and (match_code "mult") | |
223 | (match_test "power_of_two_operand (XEXP (op, 1), mode)")) | |
224 | (and (match_code "rotate") | |
225 | (match_test "GET_CODE (XEXP (op, 1)) == CONST_INT | |
226 | && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32"))) | |
227 | (match_code "ashift,ashiftrt,lshiftrt,rotatert")) | |
228 | (match_test "mode == GET_MODE (op)"))) | |
229 | ||
c29e2982 BS |
230 | ;; True for MULT, to identify which variant of shift_operator is in use. |
231 | (define_special_predicate "mult_operator" | |
232 | (match_code "mult")) | |
233 | ||
5b3e6663 PB |
234 | ;; True for operators that have 16-bit thumb variants. */ |
235 | (define_special_predicate "thumb_16bit_operator" | |
236 | (match_code "plus,minus,and,ior,xor")) | |
237 | ||
a657c98a RE |
238 | ;; True for EQ & NE |
239 | (define_special_predicate "equality_operator" | |
240 | (match_code "eq,ne")) | |
241 | ||
f90b7a5a PB |
242 | ;; True for integer comparisons and, if FP is active, for comparisons |
243 | ;; other than LTGT or UNEQ. | |
a657c98a | 244 | (define_special_predicate "arm_comparison_operator" |
f90b7a5a PB |
245 | (ior (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu") |
246 | (and (match_test "TARGET_32BIT && TARGET_HARD_FLOAT | |
247 | && (TARGET_FPA || TARGET_VFP)") | |
248 | (match_code "unordered,ordered,unlt,unle,unge,ungt")))) | |
a657c98a | 249 | |
f0c6475a BS |
250 | (define_special_predicate "lt_ge_comparison_operator" |
251 | (match_code "lt,ge")) | |
252 | ||
906668bb BS |
253 | (define_special_predicate "noov_comparison_operator" |
254 | (match_code "lt,ge,eq,ne")) | |
255 | ||
a657c98a RE |
256 | (define_special_predicate "minmax_operator" |
257 | (and (match_code "smin,smax,umin,umax") | |
258 | (match_test "mode == GET_MODE (op)"))) | |
259 | ||
260 | (define_special_predicate "cc_register" | |
261 | (and (match_code "reg") | |
262 | (and (match_test "REGNO (op) == CC_REGNUM") | |
263 | (ior (match_test "mode == GET_MODE (op)") | |
264 | (match_test "mode == VOIDmode && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC"))))) | |
265 | ||
266 | (define_special_predicate "dominant_cc_register" | |
267 | (match_code "reg") | |
268 | { | |
269 | if (mode == VOIDmode) | |
270 | { | |
271 | mode = GET_MODE (op); | |
272 | ||
273 | if (GET_MODE_CLASS (mode) != MODE_CC) | |
274 | return false; | |
275 | } | |
276 | ||
277 | return (cc_register (op, mode) | |
278 | && (mode == CC_DNEmode | |
279 | || mode == CC_DEQmode | |
280 | || mode == CC_DLEmode | |
281 | || mode == CC_DLTmode | |
282 | || mode == CC_DGEmode | |
283 | || mode == CC_DGTmode | |
284 | || mode == CC_DLEUmode | |
285 | || mode == CC_DLTUmode | |
286 | || mode == CC_DGEUmode | |
287 | || mode == CC_DGTUmode)); | |
288 | }) | |
289 | ||
290 | (define_special_predicate "arm_extendqisi_mem_op" | |
291 | (and (match_operand 0 "memory_operand") | |
c6c3dba9 PB |
292 | (match_test "arm_legitimate_address_outer_p (mode, XEXP (op, 0), |
293 | SIGN_EXTEND, 0)"))) | |
a657c98a | 294 | |
01577df7 RE |
295 | (define_special_predicate "arm_reg_or_extendqisi_mem_op" |
296 | (ior (match_operand 0 "arm_extendqisi_mem_op") | |
297 | (match_operand 0 "s_register_operand"))) | |
298 | ||
a657c98a RE |
299 | (define_predicate "power_of_two_operand" |
300 | (match_code "const_int") | |
301 | { | |
29b40d79 | 302 | unsigned HOST_WIDE_INT value = INTVAL (op) & 0xffffffff; |
a657c98a RE |
303 | |
304 | return value != 0 && (value & (value - 1)) == 0; | |
305 | }) | |
306 | ||
307 | (define_predicate "nonimmediate_di_operand" | |
308 | (match_code "reg,subreg,mem") | |
309 | { | |
310 | if (s_register_operand (op, mode)) | |
311 | return true; | |
312 | ||
313 | if (GET_CODE (op) == SUBREG) | |
314 | op = SUBREG_REG (op); | |
315 | ||
316 | return GET_CODE (op) == MEM && memory_address_p (DImode, XEXP (op, 0)); | |
317 | }) | |
318 | ||
319 | (define_predicate "di_operand" | |
320 | (ior (match_code "const_int,const_double") | |
321 | (and (match_code "reg,subreg,mem") | |
322 | (match_operand 0 "nonimmediate_di_operand")))) | |
323 | ||
324 | (define_predicate "nonimmediate_soft_df_operand" | |
325 | (match_code "reg,subreg,mem") | |
326 | { | |
327 | if (s_register_operand (op, mode)) | |
328 | return true; | |
329 | ||
330 | if (GET_CODE (op) == SUBREG) | |
331 | op = SUBREG_REG (op); | |
332 | ||
333 | return GET_CODE (op) == MEM && memory_address_p (DFmode, XEXP (op, 0)); | |
334 | }) | |
335 | ||
336 | (define_predicate "soft_df_operand" | |
337 | (ior (match_code "const_double") | |
338 | (and (match_code "reg,subreg,mem") | |
339 | (match_operand 0 "nonimmediate_soft_df_operand")))) | |
340 | ||
341 | (define_predicate "const_shift_operand" | |
342 | (and (match_code "const_int") | |
343 | (ior (match_operand 0 "power_of_two_operand") | |
344 | (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 32")))) | |
345 | ||
346 | ||
347 | (define_special_predicate "load_multiple_operation" | |
348 | (match_code "parallel") | |
349 | { | |
350 | HOST_WIDE_INT count = XVECLEN (op, 0); | |
37119410 | 351 | unsigned dest_regno; |
a657c98a RE |
352 | rtx src_addr; |
353 | HOST_WIDE_INT i = 1, base = 0; | |
37119410 | 354 | HOST_WIDE_INT offset = 0; |
a657c98a | 355 | rtx elt; |
37119410 BS |
356 | bool addr_reg_loaded = false; |
357 | bool update = false; | |
a657c98a RE |
358 | |
359 | if (count <= 1 | |
37119410 BS |
360 | || GET_CODE (XVECEXP (op, 0, 0)) != SET |
361 | || !REG_P (SET_DEST (XVECEXP (op, 0, 0)))) | |
a657c98a RE |
362 | return false; |
363 | ||
364 | /* Check to see if this might be a write-back. */ | |
365 | if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) | |
366 | { | |
367 | i++; | |
368 | base = 1; | |
37119410 | 369 | update = true; |
a657c98a RE |
370 | |
371 | /* Now check it more carefully. */ | |
372 | if (GET_CODE (SET_DEST (elt)) != REG | |
373 | || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG | |
374 | || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT | |
375 | || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4) | |
376 | return false; | |
377 | } | |
378 | ||
379 | /* Perform a quick check so we don't blow up below. */ | |
380 | if (count <= i | |
381 | || GET_CODE (XVECEXP (op, 0, i - 1)) != SET | |
382 | || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG | |
383 | || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM) | |
384 | return false; | |
385 | ||
386 | dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1))); | |
387 | src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0); | |
37119410 BS |
388 | if (GET_CODE (src_addr) == PLUS) |
389 | { | |
390 | if (GET_CODE (XEXP (src_addr, 1)) != CONST_INT) | |
391 | return false; | |
392 | offset = INTVAL (XEXP (src_addr, 1)); | |
393 | src_addr = XEXP (src_addr, 0); | |
394 | } | |
395 | if (!REG_P (src_addr)) | |
396 | return false; | |
a657c98a RE |
397 | |
398 | for (; i < count; i++) | |
399 | { | |
400 | elt = XVECEXP (op, 0, i); | |
401 | ||
402 | if (GET_CODE (elt) != SET | |
403 | || GET_CODE (SET_DEST (elt)) != REG | |
404 | || GET_MODE (SET_DEST (elt)) != SImode | |
37119410 | 405 | || REGNO (SET_DEST (elt)) <= dest_regno |
a657c98a RE |
406 | || GET_CODE (SET_SRC (elt)) != MEM |
407 | || GET_MODE (SET_SRC (elt)) != SImode | |
37119410 BS |
408 | || ((GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS |
409 | || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) | |
410 | || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT | |
411 | || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != offset + (i - base) * 4) | |
412 | && (!REG_P (XEXP (SET_SRC (elt), 0)) | |
413 | || offset + (i - base) * 4 != 0))) | |
a657c98a | 414 | return false; |
37119410 BS |
415 | dest_regno = REGNO (SET_DEST (elt)); |
416 | if (dest_regno == REGNO (src_addr)) | |
417 | addr_reg_loaded = true; | |
a657c98a | 418 | } |
37119410 BS |
419 | /* For Thumb, we only have updating instructions. If the pattern does |
420 | not describe an update, it must be because the address register is | |
421 | in the list of loaded registers - on the hardware, this has the effect | |
422 | of overriding the update. */ | |
423 | if (update && addr_reg_loaded) | |
424 | return false; | |
425 | if (TARGET_THUMB1) | |
426 | return update || addr_reg_loaded; | |
a657c98a RE |
427 | return true; |
428 | }) | |
429 | ||
430 | (define_special_predicate "store_multiple_operation" | |
431 | (match_code "parallel") | |
432 | { | |
433 | HOST_WIDE_INT count = XVECLEN (op, 0); | |
37119410 | 434 | unsigned src_regno; |
a657c98a | 435 | rtx dest_addr; |
37119410 | 436 | HOST_WIDE_INT i = 1, base = 0, offset = 0; |
a657c98a RE |
437 | rtx elt; |
438 | ||
439 | if (count <= 1 | |
440 | || GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
441 | return false; | |
442 | ||
443 | /* Check to see if this might be a write-back. */ | |
444 | if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) | |
445 | { | |
446 | i++; | |
447 | base = 1; | |
448 | ||
449 | /* Now check it more carefully. */ | |
450 | if (GET_CODE (SET_DEST (elt)) != REG | |
451 | || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG | |
452 | || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT | |
453 | || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4) | |
454 | return false; | |
455 | } | |
456 | ||
457 | /* Perform a quick check so we don't blow up below. */ | |
458 | if (count <= i | |
459 | || GET_CODE (XVECEXP (op, 0, i - 1)) != SET | |
460 | || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM | |
461 | || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG) | |
462 | return false; | |
463 | ||
464 | src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1))); | |
465 | dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0); | |
466 | ||
37119410 BS |
467 | if (GET_CODE (dest_addr) == PLUS) |
468 | { | |
469 | if (GET_CODE (XEXP (dest_addr, 1)) != CONST_INT) | |
470 | return false; | |
471 | offset = INTVAL (XEXP (dest_addr, 1)); | |
472 | dest_addr = XEXP (dest_addr, 0); | |
473 | } | |
474 | if (!REG_P (dest_addr)) | |
475 | return false; | |
476 | ||
a657c98a RE |
477 | for (; i < count; i++) |
478 | { | |
479 | elt = XVECEXP (op, 0, i); | |
480 | ||
481 | if (GET_CODE (elt) != SET | |
482 | || GET_CODE (SET_SRC (elt)) != REG | |
483 | || GET_MODE (SET_SRC (elt)) != SImode | |
37119410 | 484 | || REGNO (SET_SRC (elt)) <= src_regno |
a657c98a RE |
485 | || GET_CODE (SET_DEST (elt)) != MEM |
486 | || GET_MODE (SET_DEST (elt)) != SImode | |
37119410 BS |
487 | || ((GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS |
488 | || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) | |
489 | || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT | |
490 | || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != offset + (i - base) * 4) | |
491 | && (!REG_P (XEXP (SET_DEST (elt), 0)) | |
492 | || offset + (i - base) * 4 != 0))) | |
a657c98a | 493 | return false; |
37119410 | 494 | src_regno = REGNO (SET_SRC (elt)); |
a657c98a RE |
495 | } |
496 | ||
497 | return true; | |
498 | }) | |
499 | ||
500 | (define_special_predicate "multi_register_push" | |
501 | (match_code "parallel") | |
502 | { | |
503 | if ((GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
504 | || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC) | |
505 | || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT)) | |
506 | return false; | |
507 | ||
508 | return true; | |
509 | }) | |
510 | ||
511 | ;;------------------------------------------------------------------------- | |
512 | ;; | |
513 | ;; Thumb predicates | |
514 | ;; | |
515 | ||
5b3e6663 | 516 | (define_predicate "thumb1_cmp_operand" |
a657c98a RE |
517 | (ior (and (match_code "reg,subreg") |
518 | (match_operand 0 "s_register_operand")) | |
519 | (and (match_code "const_int") | |
520 | (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 256")))) | |
521 | ||
5b3e6663 | 522 | (define_predicate "thumb1_cmpneg_operand" |
a657c98a RE |
523 | (and (match_code "const_int") |
524 | (match_test "INTVAL (op) < 0 && INTVAL (op) > -256"))) | |
525 | ||
526 | ;; Return TRUE if a result can be stored in OP without clobbering the | |
527 | ;; condition code register. Prior to reload we only accept a | |
528 | ;; register. After reload we have to be able to handle memory as | |
529 | ;; well, since a pseudo may not get a hard reg and reload cannot | |
530 | ;; handle output-reloads on jump insns. | |
531 | ||
532 | ;; We could possibly handle mem before reload as well, but that might | |
533 | ;; complicate things with the need to handle increment | |
534 | ;; side-effects. | |
535 | (define_predicate "thumb_cbrch_target_operand" | |
536 | (and (match_code "reg,subreg,mem") | |
537 | (ior (match_operand 0 "s_register_operand") | |
538 | (and (match_test "reload_in_progress || reload_completed") | |
539 | (match_operand 0 "memory_operand"))))) | |
540 | ||
541 | ;;------------------------------------------------------------------------- | |
542 | ;; | |
543 | ;; MAVERICK predicates | |
544 | ;; | |
545 | ||
546 | (define_predicate "cirrus_register_operand" | |
547 | (match_code "reg,subreg") | |
548 | { | |
549 | if (GET_CODE (op) == SUBREG) | |
550 | op = SUBREG_REG (op); | |
551 | ||
552 | return (GET_CODE (op) == REG | |
553 | && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS | |
554 | || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS)); | |
555 | }) | |
556 | ||
557 | (define_predicate "cirrus_fp_register" | |
558 | (match_code "reg,subreg") | |
559 | { | |
560 | if (GET_CODE (op) == SUBREG) | |
561 | op = SUBREG_REG (op); | |
562 | ||
563 | return (GET_CODE (op) == REG | |
564 | && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
565 | || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS)); | |
566 | }) | |
567 | ||
568 | (define_predicate "cirrus_shift_const" | |
569 | (and (match_code "const_int") | |
570 | (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64"))) | |
571 | ||
572 | ||
88f77cba JB |
573 | ;; Neon predicates |
574 | ||
575 | (define_predicate "const_multiple_of_8_operand" | |
576 | (match_code "const_int") | |
577 | { | |
578 | unsigned HOST_WIDE_INT val = INTVAL (op); | |
579 | return (val & 7) == 0; | |
580 | }) | |
581 | ||
582 | (define_predicate "imm_for_neon_mov_operand" | |
583 | (match_code "const_vector") | |
584 | { | |
585 | return neon_immediate_valid_for_move (op, mode, NULL, NULL); | |
586 | }) | |
587 | ||
588 | (define_predicate "imm_for_neon_logic_operand" | |
589 | (match_code "const_vector") | |
590 | { | |
b3b7bbce SL |
591 | return (TARGET_NEON |
592 | && neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL)); | |
88f77cba JB |
593 | }) |
594 | ||
595 | (define_predicate "imm_for_neon_inv_logic_operand" | |
596 | (match_code "const_vector") | |
597 | { | |
b3b7bbce SL |
598 | return (TARGET_NEON |
599 | && neon_immediate_valid_for_logic (op, mode, 1, NULL, NULL)); | |
88f77cba JB |
600 | }) |
601 | ||
602 | (define_predicate "neon_logic_op2" | |
603 | (ior (match_operand 0 "imm_for_neon_logic_operand") | |
604 | (match_operand 0 "s_register_operand"))) | |
605 | ||
606 | (define_predicate "neon_inv_logic_op2" | |
607 | (ior (match_operand 0 "imm_for_neon_inv_logic_operand") | |
608 | (match_operand 0 "s_register_operand"))) | |
609 | ||
610 | ;; TODO: We could check lane numbers more precisely based on the mode. | |
611 | (define_predicate "neon_lane_number" | |
612 | (and (match_code "const_int") | |
3460fdf3 | 613 | (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 15"))) |
73160ba9 DJ |
614 | ;; Predicates for named expanders that overlap multiple ISAs. |
615 | ||
616 | (define_predicate "cmpdi_operand" | |
617 | (if_then_else (match_test "TARGET_HARD_FLOAT && TARGET_MAVERICK") | |
618 | (and (match_test "TARGET_ARM") | |
619 | (match_operand 0 "cirrus_fp_register")) | |
620 | (and (match_test "TARGET_32BIT") | |
621 | (match_operand 0 "arm_di_operand")))) | |
88f77cba | 622 | |
999a9cc5 MS |
623 | ;; True if the operand is memory reference suitable for a ldrex/strex. |
624 | (define_predicate "arm_sync_memory_operand" | |
625 | (and (match_operand 0 "memory_operand") | |
626 | (match_code "reg" "0"))) | |
627 | ||
46b57af1 TB |
628 | ;; Predicates for parallel expanders based on mode. |
629 | (define_special_predicate "vect_par_constant_high" | |
630 | (match_code "parallel") | |
631 | { | |
632 | HOST_WIDE_INT count = XVECLEN (op, 0); | |
633 | int i; | |
634 | int base = GET_MODE_NUNITS (mode); | |
635 | ||
636 | if ((count < 1) | |
637 | || (count != base/2)) | |
638 | return false; | |
639 | ||
640 | if (!VECTOR_MODE_P (mode)) | |
641 | return false; | |
642 | ||
643 | for (i = 0; i < count; i++) | |
644 | { | |
645 | rtx elt = XVECEXP (op, 0, i); | |
646 | int val; | |
647 | ||
648 | if (GET_CODE (elt) != CONST_INT) | |
649 | return false; | |
650 | ||
651 | val = INTVAL (elt); | |
652 | if (val != (base/2) + i) | |
653 | return false; | |
654 | } | |
655 | return true; | |
656 | }) | |
657 | ||
658 | (define_special_predicate "vect_par_constant_low" | |
659 | (match_code "parallel") | |
660 | { | |
661 | HOST_WIDE_INT count = XVECLEN (op, 0); | |
662 | int i; | |
663 | int base = GET_MODE_NUNITS (mode); | |
664 | ||
665 | if ((count < 1) | |
666 | || (count != base/2)) | |
667 | return false; | |
668 | ||
669 | if (!VECTOR_MODE_P (mode)) | |
670 | return false; | |
671 | ||
672 | for (i = 0; i < count; i++) | |
673 | { | |
674 | rtx elt = XVECEXP (op, 0, i); | |
675 | int val; | |
676 | ||
677 | if (GET_CODE (elt) != CONST_INT) | |
678 | return false; | |
679 | ||
680 | val = INTVAL (elt); | |
681 | if (val != i) | |
682 | return false; | |
683 | } | |
684 | return true; | |
685 | }) | |
6308e208 RS |
686 | |
687 | (define_special_predicate "neon_struct_operand" | |
688 | (and (match_code "mem") | |
689 | (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2)"))) |