]>
Commit | Line | Data |
---|---|---|
a657c98a | 1 | ;; Predicate definitions for ARM and Thumb |
66647d44 | 2 | ;; Copyright (C) 2004, 2007, 2008 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 | |
86 | || REGNO_REG_CLASS (REGNO (op)) == VFP_LO_REGS | |
87 | || (TARGET_VFPD32 | |
88 | && REGNO_REG_CLASS (REGNO (op)) == VFP_REGS))); | |
89 | }) | |
90 | ||
fa01135d RE |
91 | (define_special_predicate "subreg_lowpart_operator" |
92 | (and (match_code "subreg") | |
93 | (match_test "subreg_lowpart_p (op)"))) | |
94 | ||
a657c98a RE |
95 | ;; Reg, subreg(reg) or const_int. |
96 | (define_predicate "reg_or_int_operand" | |
97 | (ior (match_code "const_int") | |
98 | (match_operand 0 "s_register_operand"))) | |
99 | ||
100 | (define_predicate "arm_immediate_operand" | |
101 | (and (match_code "const_int") | |
102 | (match_test "const_ok_for_arm (INTVAL (op))"))) | |
103 | ||
73160ba9 DJ |
104 | ;; A constant value which fits into two instructions, each taking |
105 | ;; an arithmetic constant operand for one of the words. | |
106 | (define_predicate "arm_immediate_di_operand" | |
107 | (and (match_code "const_int,const_double") | |
108 | (match_test "arm_const_double_by_immediates (op)"))) | |
109 | ||
a657c98a RE |
110 | (define_predicate "arm_neg_immediate_operand" |
111 | (and (match_code "const_int") | |
112 | (match_test "const_ok_for_arm (-INTVAL (op))"))) | |
113 | ||
114 | (define_predicate "arm_not_immediate_operand" | |
115 | (and (match_code "const_int") | |
116 | (match_test "const_ok_for_arm (~INTVAL (op))"))) | |
117 | ||
f0c6475a BS |
118 | (define_predicate "const0_operand" |
119 | (and (match_code "const_int") | |
120 | (match_test "INTVAL (op) == 0"))) | |
121 | ||
a657c98a RE |
122 | ;; Something valid on the RHS of an ARM data-processing instruction |
123 | (define_predicate "arm_rhs_operand" | |
124 | (ior (match_operand 0 "s_register_operand") | |
125 | (match_operand 0 "arm_immediate_operand"))) | |
126 | ||
127 | (define_predicate "arm_rhsm_operand" | |
128 | (ior (match_operand 0 "arm_rhs_operand") | |
129 | (match_operand 0 "memory_operand"))) | |
130 | ||
131 | (define_predicate "arm_add_operand" | |
132 | (ior (match_operand 0 "arm_rhs_operand") | |
133 | (match_operand 0 "arm_neg_immediate_operand"))) | |
134 | ||
135 | (define_predicate "arm_addimm_operand" | |
136 | (ior (match_operand 0 "arm_immediate_operand") | |
137 | (match_operand 0 "arm_neg_immediate_operand"))) | |
138 | ||
139 | (define_predicate "arm_not_operand" | |
140 | (ior (match_operand 0 "arm_rhs_operand") | |
141 | (match_operand 0 "arm_not_immediate_operand"))) | |
142 | ||
73160ba9 DJ |
143 | (define_predicate "arm_di_operand" |
144 | (ior (match_operand 0 "s_register_operand") | |
145 | (match_operand 0 "arm_immediate_di_operand"))) | |
146 | ||
a657c98a RE |
147 | ;; True if the operand is a memory reference which contains an |
148 | ;; offsettable address. | |
149 | (define_predicate "offsettable_memory_operand" | |
150 | (and (match_code "mem") | |
151 | (match_test | |
152 | "offsettable_address_p (reload_completed | reload_in_progress, | |
153 | mode, XEXP (op, 0))"))) | |
154 | ||
e6add59b RS |
155 | ;; True if the operand is a memory operand that does not have an |
156 | ;; automodified base register (and thus will not generate output reloads). | |
157 | (define_predicate "call_memory_operand" | |
158 | (and (match_code "mem") | |
159 | (and (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) | |
160 | != RTX_AUTOINC") | |
161 | (match_operand 0 "memory_operand")))) | |
162 | ||
a657c98a | 163 | (define_predicate "arm_reload_memory_operand" |
9d2da95b | 164 | (and (match_code "mem,reg,subreg") |
a657c98a RE |
165 | (match_test "(!CONSTANT_P (op) |
166 | && (true_regnum(op) == -1 | |
167 | || (GET_CODE (op) == REG | |
168 | && REGNO (op) >= FIRST_PSEUDO_REGISTER)))"))) | |
169 | ||
170 | ;; True for valid operands for the rhs of an floating point insns. | |
171 | ;; Allows regs or certain consts on FPA, just regs for everything else. | |
172 | (define_predicate "arm_float_rhs_operand" | |
173 | (ior (match_operand 0 "s_register_operand") | |
174 | (and (match_code "const_double") | |
175 | (match_test "TARGET_FPA && arm_const_double_rtx (op)")))) | |
176 | ||
177 | (define_predicate "arm_float_add_operand" | |
178 | (ior (match_operand 0 "arm_float_rhs_operand") | |
179 | (and (match_code "const_double") | |
180 | (match_test "TARGET_FPA && neg_const_double_rtx_ok_for_fpa (op)")))) | |
181 | ||
182 | (define_predicate "vfp_compare_operand" | |
183 | (ior (match_operand 0 "s_register_operand") | |
184 | (and (match_code "const_double") | |
185 | (match_test "arm_const_double_rtx (op)")))) | |
186 | ||
187 | (define_predicate "arm_float_compare_operand" | |
188 | (if_then_else (match_test "TARGET_VFP") | |
189 | (match_operand 0 "vfp_compare_operand") | |
190 | (match_operand 0 "arm_float_rhs_operand"))) | |
191 | ||
192 | ;; True for valid index operands. | |
193 | (define_predicate "index_operand" | |
194 | (ior (match_operand 0 "s_register_operand") | |
195 | (and (match_operand 0 "immediate_operand") | |
196 | (match_test "(GET_CODE (op) != CONST_INT | |
197 | || (INTVAL (op) < 4096 && INTVAL (op) > -4096))")))) | |
198 | ||
199 | ;; True for operators that can be combined with a shift in ARM state. | |
200 | (define_special_predicate "shiftable_operator" | |
201 | (and (match_code "plus,minus,ior,xor,and") | |
202 | (match_test "mode == GET_MODE (op)"))) | |
203 | ||
c112cf2b | 204 | ;; True for logical binary operators. |
a657c98a RE |
205 | (define_special_predicate "logical_binary_operator" |
206 | (and (match_code "ior,xor,and") | |
207 | (match_test "mode == GET_MODE (op)"))) | |
208 | ||
37119410 BS |
209 | ;; True for commutative operators |
210 | (define_special_predicate "commutative_binary_operator" | |
211 | (and (match_code "ior,xor,and,plus") | |
212 | (match_test "mode == GET_MODE (op)"))) | |
213 | ||
a657c98a RE |
214 | ;; True for shift operators. |
215 | (define_special_predicate "shift_operator" | |
216 | (and (ior (ior (and (match_code "mult") | |
217 | (match_test "power_of_two_operand (XEXP (op, 1), mode)")) | |
218 | (and (match_code "rotate") | |
219 | (match_test "GET_CODE (XEXP (op, 1)) == CONST_INT | |
220 | && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32"))) | |
221 | (match_code "ashift,ashiftrt,lshiftrt,rotatert")) | |
222 | (match_test "mode == GET_MODE (op)"))) | |
223 | ||
5b3e6663 PB |
224 | ;; True for operators that have 16-bit thumb variants. */ |
225 | (define_special_predicate "thumb_16bit_operator" | |
226 | (match_code "plus,minus,and,ior,xor")) | |
227 | ||
a657c98a RE |
228 | ;; True for EQ & NE |
229 | (define_special_predicate "equality_operator" | |
230 | (match_code "eq,ne")) | |
231 | ||
f90b7a5a PB |
232 | ;; True for integer comparisons and, if FP is active, for comparisons |
233 | ;; other than LTGT or UNEQ. | |
a657c98a | 234 | (define_special_predicate "arm_comparison_operator" |
f90b7a5a PB |
235 | (ior (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu") |
236 | (and (match_test "TARGET_32BIT && TARGET_HARD_FLOAT | |
237 | && (TARGET_FPA || TARGET_VFP)") | |
238 | (match_code "unordered,ordered,unlt,unle,unge,ungt")))) | |
a657c98a | 239 | |
f0c6475a BS |
240 | (define_special_predicate "lt_ge_comparison_operator" |
241 | (match_code "lt,ge")) | |
242 | ||
906668bb BS |
243 | (define_special_predicate "noov_comparison_operator" |
244 | (match_code "lt,ge,eq,ne")) | |
245 | ||
a657c98a RE |
246 | (define_special_predicate "minmax_operator" |
247 | (and (match_code "smin,smax,umin,umax") | |
248 | (match_test "mode == GET_MODE (op)"))) | |
249 | ||
250 | (define_special_predicate "cc_register" | |
251 | (and (match_code "reg") | |
252 | (and (match_test "REGNO (op) == CC_REGNUM") | |
253 | (ior (match_test "mode == GET_MODE (op)") | |
254 | (match_test "mode == VOIDmode && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC"))))) | |
255 | ||
256 | (define_special_predicate "dominant_cc_register" | |
257 | (match_code "reg") | |
258 | { | |
259 | if (mode == VOIDmode) | |
260 | { | |
261 | mode = GET_MODE (op); | |
262 | ||
263 | if (GET_MODE_CLASS (mode) != MODE_CC) | |
264 | return false; | |
265 | } | |
266 | ||
267 | return (cc_register (op, mode) | |
268 | && (mode == CC_DNEmode | |
269 | || mode == CC_DEQmode | |
270 | || mode == CC_DLEmode | |
271 | || mode == CC_DLTmode | |
272 | || mode == CC_DGEmode | |
273 | || mode == CC_DGTmode | |
274 | || mode == CC_DLEUmode | |
275 | || mode == CC_DLTUmode | |
276 | || mode == CC_DGEUmode | |
277 | || mode == CC_DGTUmode)); | |
278 | }) | |
279 | ||
280 | (define_special_predicate "arm_extendqisi_mem_op" | |
281 | (and (match_operand 0 "memory_operand") | |
c6c3dba9 PB |
282 | (match_test "arm_legitimate_address_outer_p (mode, XEXP (op, 0), |
283 | SIGN_EXTEND, 0)"))) | |
a657c98a | 284 | |
01577df7 RE |
285 | (define_special_predicate "arm_reg_or_extendqisi_mem_op" |
286 | (ior (match_operand 0 "arm_extendqisi_mem_op") | |
287 | (match_operand 0 "s_register_operand"))) | |
288 | ||
a657c98a RE |
289 | (define_predicate "power_of_two_operand" |
290 | (match_code "const_int") | |
291 | { | |
292 | HOST_WIDE_INT value = INTVAL (op); | |
293 | ||
294 | return value != 0 && (value & (value - 1)) == 0; | |
295 | }) | |
296 | ||
297 | (define_predicate "nonimmediate_di_operand" | |
298 | (match_code "reg,subreg,mem") | |
299 | { | |
300 | if (s_register_operand (op, mode)) | |
301 | return true; | |
302 | ||
303 | if (GET_CODE (op) == SUBREG) | |
304 | op = SUBREG_REG (op); | |
305 | ||
306 | return GET_CODE (op) == MEM && memory_address_p (DImode, XEXP (op, 0)); | |
307 | }) | |
308 | ||
309 | (define_predicate "di_operand" | |
310 | (ior (match_code "const_int,const_double") | |
311 | (and (match_code "reg,subreg,mem") | |
312 | (match_operand 0 "nonimmediate_di_operand")))) | |
313 | ||
314 | (define_predicate "nonimmediate_soft_df_operand" | |
315 | (match_code "reg,subreg,mem") | |
316 | { | |
317 | if (s_register_operand (op, mode)) | |
318 | return true; | |
319 | ||
320 | if (GET_CODE (op) == SUBREG) | |
321 | op = SUBREG_REG (op); | |
322 | ||
323 | return GET_CODE (op) == MEM && memory_address_p (DFmode, XEXP (op, 0)); | |
324 | }) | |
325 | ||
326 | (define_predicate "soft_df_operand" | |
327 | (ior (match_code "const_double") | |
328 | (and (match_code "reg,subreg,mem") | |
329 | (match_operand 0 "nonimmediate_soft_df_operand")))) | |
330 | ||
331 | (define_predicate "const_shift_operand" | |
332 | (and (match_code "const_int") | |
333 | (ior (match_operand 0 "power_of_two_operand") | |
334 | (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 32")))) | |
335 | ||
336 | ||
337 | (define_special_predicate "load_multiple_operation" | |
338 | (match_code "parallel") | |
339 | { | |
340 | HOST_WIDE_INT count = XVECLEN (op, 0); | |
37119410 | 341 | unsigned dest_regno; |
a657c98a RE |
342 | rtx src_addr; |
343 | HOST_WIDE_INT i = 1, base = 0; | |
37119410 | 344 | HOST_WIDE_INT offset = 0; |
a657c98a | 345 | rtx elt; |
37119410 BS |
346 | bool addr_reg_loaded = false; |
347 | bool update = false; | |
a657c98a RE |
348 | |
349 | if (count <= 1 | |
37119410 BS |
350 | || GET_CODE (XVECEXP (op, 0, 0)) != SET |
351 | || !REG_P (SET_DEST (XVECEXP (op, 0, 0)))) | |
a657c98a RE |
352 | return false; |
353 | ||
354 | /* Check to see if this might be a write-back. */ | |
355 | if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) | |
356 | { | |
357 | i++; | |
358 | base = 1; | |
37119410 | 359 | update = true; |
a657c98a RE |
360 | |
361 | /* Now check it more carefully. */ | |
362 | if (GET_CODE (SET_DEST (elt)) != REG | |
363 | || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG | |
364 | || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT | |
365 | || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4) | |
366 | return false; | |
367 | } | |
368 | ||
369 | /* Perform a quick check so we don't blow up below. */ | |
370 | if (count <= i | |
371 | || GET_CODE (XVECEXP (op, 0, i - 1)) != SET | |
372 | || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG | |
373 | || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM) | |
374 | return false; | |
375 | ||
376 | dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1))); | |
377 | src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0); | |
37119410 BS |
378 | if (GET_CODE (src_addr) == PLUS) |
379 | { | |
380 | if (GET_CODE (XEXP (src_addr, 1)) != CONST_INT) | |
381 | return false; | |
382 | offset = INTVAL (XEXP (src_addr, 1)); | |
383 | src_addr = XEXP (src_addr, 0); | |
384 | } | |
385 | if (!REG_P (src_addr)) | |
386 | return false; | |
a657c98a RE |
387 | |
388 | for (; i < count; i++) | |
389 | { | |
390 | elt = XVECEXP (op, 0, i); | |
391 | ||
392 | if (GET_CODE (elt) != SET | |
393 | || GET_CODE (SET_DEST (elt)) != REG | |
394 | || GET_MODE (SET_DEST (elt)) != SImode | |
37119410 | 395 | || REGNO (SET_DEST (elt)) <= dest_regno |
a657c98a RE |
396 | || GET_CODE (SET_SRC (elt)) != MEM |
397 | || GET_MODE (SET_SRC (elt)) != SImode | |
37119410 BS |
398 | || ((GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS |
399 | || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) | |
400 | || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT | |
401 | || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != offset + (i - base) * 4) | |
402 | && (!REG_P (XEXP (SET_SRC (elt), 0)) | |
403 | || offset + (i - base) * 4 != 0))) | |
a657c98a | 404 | return false; |
37119410 BS |
405 | dest_regno = REGNO (SET_DEST (elt)); |
406 | if (dest_regno == REGNO (src_addr)) | |
407 | addr_reg_loaded = true; | |
a657c98a | 408 | } |
37119410 BS |
409 | /* For Thumb, we only have updating instructions. If the pattern does |
410 | not describe an update, it must be because the address register is | |
411 | in the list of loaded registers - on the hardware, this has the effect | |
412 | of overriding the update. */ | |
413 | if (update && addr_reg_loaded) | |
414 | return false; | |
415 | if (TARGET_THUMB1) | |
416 | return update || addr_reg_loaded; | |
a657c98a RE |
417 | return true; |
418 | }) | |
419 | ||
420 | (define_special_predicate "store_multiple_operation" | |
421 | (match_code "parallel") | |
422 | { | |
423 | HOST_WIDE_INT count = XVECLEN (op, 0); | |
37119410 | 424 | unsigned src_regno; |
a657c98a | 425 | rtx dest_addr; |
37119410 | 426 | HOST_WIDE_INT i = 1, base = 0, offset = 0; |
a657c98a RE |
427 | rtx elt; |
428 | ||
429 | if (count <= 1 | |
430 | || GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
431 | return false; | |
432 | ||
433 | /* Check to see if this might be a write-back. */ | |
434 | if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) | |
435 | { | |
436 | i++; | |
437 | base = 1; | |
438 | ||
439 | /* Now check it more carefully. */ | |
440 | if (GET_CODE (SET_DEST (elt)) != REG | |
441 | || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG | |
442 | || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT | |
443 | || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4) | |
444 | return false; | |
445 | } | |
446 | ||
447 | /* Perform a quick check so we don't blow up below. */ | |
448 | if (count <= i | |
449 | || GET_CODE (XVECEXP (op, 0, i - 1)) != SET | |
450 | || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM | |
451 | || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG) | |
452 | return false; | |
453 | ||
454 | src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1))); | |
455 | dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0); | |
456 | ||
37119410 BS |
457 | if (GET_CODE (dest_addr) == PLUS) |
458 | { | |
459 | if (GET_CODE (XEXP (dest_addr, 1)) != CONST_INT) | |
460 | return false; | |
461 | offset = INTVAL (XEXP (dest_addr, 1)); | |
462 | dest_addr = XEXP (dest_addr, 0); | |
463 | } | |
464 | if (!REG_P (dest_addr)) | |
465 | return false; | |
466 | ||
a657c98a RE |
467 | for (; i < count; i++) |
468 | { | |
469 | elt = XVECEXP (op, 0, i); | |
470 | ||
471 | if (GET_CODE (elt) != SET | |
472 | || GET_CODE (SET_SRC (elt)) != REG | |
473 | || GET_MODE (SET_SRC (elt)) != SImode | |
37119410 | 474 | || REGNO (SET_SRC (elt)) <= src_regno |
a657c98a RE |
475 | || GET_CODE (SET_DEST (elt)) != MEM |
476 | || GET_MODE (SET_DEST (elt)) != SImode | |
37119410 BS |
477 | || ((GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS |
478 | || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) | |
479 | || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT | |
480 | || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != offset + (i - base) * 4) | |
481 | && (!REG_P (XEXP (SET_DEST (elt), 0)) | |
482 | || offset + (i - base) * 4 != 0))) | |
a657c98a | 483 | return false; |
37119410 | 484 | src_regno = REGNO (SET_SRC (elt)); |
a657c98a RE |
485 | } |
486 | ||
487 | return true; | |
488 | }) | |
489 | ||
490 | (define_special_predicate "multi_register_push" | |
491 | (match_code "parallel") | |
492 | { | |
493 | if ((GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
494 | || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC) | |
495 | || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT)) | |
496 | return false; | |
497 | ||
498 | return true; | |
499 | }) | |
500 | ||
501 | ;;------------------------------------------------------------------------- | |
502 | ;; | |
503 | ;; Thumb predicates | |
504 | ;; | |
505 | ||
5b3e6663 | 506 | (define_predicate "thumb1_cmp_operand" |
a657c98a RE |
507 | (ior (and (match_code "reg,subreg") |
508 | (match_operand 0 "s_register_operand")) | |
509 | (and (match_code "const_int") | |
510 | (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 256")))) | |
511 | ||
5b3e6663 | 512 | (define_predicate "thumb1_cmpneg_operand" |
a657c98a RE |
513 | (and (match_code "const_int") |
514 | (match_test "INTVAL (op) < 0 && INTVAL (op) > -256"))) | |
515 | ||
516 | ;; Return TRUE if a result can be stored in OP without clobbering the | |
517 | ;; condition code register. Prior to reload we only accept a | |
518 | ;; register. After reload we have to be able to handle memory as | |
519 | ;; well, since a pseudo may not get a hard reg and reload cannot | |
520 | ;; handle output-reloads on jump insns. | |
521 | ||
522 | ;; We could possibly handle mem before reload as well, but that might | |
523 | ;; complicate things with the need to handle increment | |
524 | ;; side-effects. | |
525 | (define_predicate "thumb_cbrch_target_operand" | |
526 | (and (match_code "reg,subreg,mem") | |
527 | (ior (match_operand 0 "s_register_operand") | |
528 | (and (match_test "reload_in_progress || reload_completed") | |
529 | (match_operand 0 "memory_operand"))))) | |
530 | ||
531 | ;;------------------------------------------------------------------------- | |
532 | ;; | |
533 | ;; MAVERICK predicates | |
534 | ;; | |
535 | ||
536 | (define_predicate "cirrus_register_operand" | |
537 | (match_code "reg,subreg") | |
538 | { | |
539 | if (GET_CODE (op) == SUBREG) | |
540 | op = SUBREG_REG (op); | |
541 | ||
542 | return (GET_CODE (op) == REG | |
543 | && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS | |
544 | || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS)); | |
545 | }) | |
546 | ||
547 | (define_predicate "cirrus_fp_register" | |
548 | (match_code "reg,subreg") | |
549 | { | |
550 | if (GET_CODE (op) == SUBREG) | |
551 | op = SUBREG_REG (op); | |
552 | ||
553 | return (GET_CODE (op) == REG | |
554 | && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
555 | || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS)); | |
556 | }) | |
557 | ||
558 | (define_predicate "cirrus_shift_const" | |
559 | (and (match_code "const_int") | |
560 | (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64"))) | |
561 | ||
562 | ||
88f77cba JB |
563 | ;; Neon predicates |
564 | ||
565 | (define_predicate "const_multiple_of_8_operand" | |
566 | (match_code "const_int") | |
567 | { | |
568 | unsigned HOST_WIDE_INT val = INTVAL (op); | |
569 | return (val & 7) == 0; | |
570 | }) | |
571 | ||
572 | (define_predicate "imm_for_neon_mov_operand" | |
573 | (match_code "const_vector") | |
574 | { | |
575 | return neon_immediate_valid_for_move (op, mode, NULL, NULL); | |
576 | }) | |
577 | ||
578 | (define_predicate "imm_for_neon_logic_operand" | |
579 | (match_code "const_vector") | |
580 | { | |
b3b7bbce SL |
581 | return (TARGET_NEON |
582 | && neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL)); | |
88f77cba JB |
583 | }) |
584 | ||
585 | (define_predicate "imm_for_neon_inv_logic_operand" | |
586 | (match_code "const_vector") | |
587 | { | |
b3b7bbce SL |
588 | return (TARGET_NEON |
589 | && neon_immediate_valid_for_logic (op, mode, 1, NULL, NULL)); | |
88f77cba JB |
590 | }) |
591 | ||
592 | (define_predicate "neon_logic_op2" | |
593 | (ior (match_operand 0 "imm_for_neon_logic_operand") | |
594 | (match_operand 0 "s_register_operand"))) | |
595 | ||
596 | (define_predicate "neon_inv_logic_op2" | |
597 | (ior (match_operand 0 "imm_for_neon_inv_logic_operand") | |
598 | (match_operand 0 "s_register_operand"))) | |
599 | ||
600 | ;; TODO: We could check lane numbers more precisely based on the mode. | |
601 | (define_predicate "neon_lane_number" | |
602 | (and (match_code "const_int") | |
603 | (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 7"))) | |
73160ba9 DJ |
604 | ;; Predicates for named expanders that overlap multiple ISAs. |
605 | ||
606 | (define_predicate "cmpdi_operand" | |
607 | (if_then_else (match_test "TARGET_HARD_FLOAT && TARGET_MAVERICK") | |
608 | (and (match_test "TARGET_ARM") | |
609 | (match_operand 0 "cirrus_fp_register")) | |
610 | (and (match_test "TARGET_32BIT") | |
611 | (match_operand 0 "arm_di_operand")))) | |
88f77cba | 612 |