Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/arm/predicates.md @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
rev | line source |
---|---|
0 | 1 ;; Predicate definitions for ARM and Thumb |
111 | 2 ;; Copyright (C) 2004-2017 Free Software Foundation, Inc. |
0 | 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 | |
9 ;; by the Free Software Foundation; either version 3, or (at your | |
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 | |
18 ;; along with GCC; see the file COPYING3. If not see | |
19 ;; <http://www.gnu.org/licenses/>. | |
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 ??? */ | |
111 | 29 return (REG_P (op) |
0 | 30 && (REGNO (op) >= FIRST_PSEUDO_REGISTER |
31 || REGNO_REG_CLASS (REGNO (op)) != NO_REGS)); | |
32 }) | |
33 | |
111 | 34 (define_predicate "imm_for_neon_inv_logic_operand" |
35 (match_code "const_vector") | |
36 { | |
37 return (TARGET_NEON | |
38 && neon_immediate_valid_for_logic (op, mode, 1, NULL, NULL)); | |
39 }) | |
40 | |
41 (define_predicate "neon_inv_logic_op2" | |
42 (ior (match_operand 0 "imm_for_neon_inv_logic_operand") | |
43 (match_operand 0 "s_register_operand"))) | |
44 | |
45 (define_predicate "imm_for_neon_logic_operand" | |
46 (match_code "const_vector") | |
47 { | |
48 return (TARGET_NEON | |
49 && neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL)); | |
50 }) | |
51 | |
52 (define_predicate "neon_logic_op2" | |
53 (ior (match_operand 0 "imm_for_neon_logic_operand") | |
54 (match_operand 0 "s_register_operand"))) | |
55 | |
56 ;; Any general register. | |
57 (define_predicate "arm_hard_general_register_operand" | |
0 | 58 (match_code "reg") |
59 { | |
111 | 60 return REGNO (op) <= LAST_ARM_REGNUM; |
0 | 61 }) |
62 | |
63 ;; A low register. | |
64 (define_predicate "low_register_operand" | |
65 (and (match_code "reg") | |
66 (match_test "REGNO (op) <= LAST_LO_REGNUM"))) | |
67 | |
68 ;; A low register or const_int. | |
69 (define_predicate "low_reg_or_int_operand" | |
70 (ior (match_code "const_int") | |
71 (match_operand 0 "low_register_operand"))) | |
72 | |
73 ;; Any core register, or any pseudo. */ | |
74 (define_predicate "arm_general_register_operand" | |
75 (match_code "reg,subreg") | |
76 { | |
77 if (GET_CODE (op) == SUBREG) | |
78 op = SUBREG_REG (op); | |
79 | |
111 | 80 return (REG_P (op) |
0 | 81 && (REGNO (op) <= LAST_ARM_REGNUM |
82 || REGNO (op) >= FIRST_PSEUDO_REGISTER)); | |
83 }) | |
84 | |
111 | 85 (define_predicate "arm_general_adddi_operand" |
86 (ior (match_operand 0 "arm_general_register_operand") | |
87 (and (match_code "const_int") | |
88 (match_test "const_ok_for_dimode_op (INTVAL (op), PLUS)")))) | |
0 | 89 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
90 (define_predicate "vfp_register_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
91 (match_code "reg,subreg") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
92 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
93 if (GET_CODE (op) == SUBREG) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
94 op = SUBREG_REG (op); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
95 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
96 /* We don't consider registers whose class is NO_REGS |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
97 to be a register operand. */ |
111 | 98 return (REG_P (op) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
99 && (REGNO (op) >= FIRST_PSEUDO_REGISTER |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
100 || REGNO_REG_CLASS (REGNO (op)) == VFP_D0_D7_REGS |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
101 || REGNO_REG_CLASS (REGNO (op)) == VFP_LO_REGS |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
102 || (TARGET_VFPD32 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
103 && REGNO_REG_CLASS (REGNO (op)) == VFP_REGS))); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
104 }) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
105 |
111 | 106 (define_predicate "vfp_hard_register_operand" |
107 (match_code "reg") | |
108 { | |
109 return (IS_VFP_REGNUM (REGNO (op))); | |
110 }) | |
111 | |
112 (define_predicate "zero_operand" | |
113 (and (match_code "const_int,const_double,const_vector") | |
114 (match_test "op == CONST0_RTX (mode)"))) | |
115 | |
116 ;; Match a register, or zero in the appropriate mode. | |
117 (define_predicate "reg_or_zero_operand" | |
118 (ior (match_operand 0 "s_register_operand") | |
119 (match_operand 0 "zero_operand"))) | |
120 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
121 (define_special_predicate "subreg_lowpart_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
122 (and (match_code "subreg") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
123 (match_test "subreg_lowpart_p (op)"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
124 |
0 | 125 ;; Reg, subreg(reg) or const_int. |
126 (define_predicate "reg_or_int_operand" | |
127 (ior (match_code "const_int") | |
128 (match_operand 0 "s_register_operand"))) | |
129 | |
130 (define_predicate "arm_immediate_operand" | |
131 (and (match_code "const_int") | |
132 (match_test "const_ok_for_arm (INTVAL (op))"))) | |
133 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
134 ;; A constant value which fits into two instructions, each taking |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
135 ;; an arithmetic constant operand for one of the words. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
136 (define_predicate "arm_immediate_di_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
137 (and (match_code "const_int,const_double") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
138 (match_test "arm_const_double_by_immediates (op)"))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
139 |
0 | 140 (define_predicate "arm_neg_immediate_operand" |
141 (and (match_code "const_int") | |
142 (match_test "const_ok_for_arm (-INTVAL (op))"))) | |
143 | |
144 (define_predicate "arm_not_immediate_operand" | |
145 (and (match_code "const_int") | |
146 (match_test "const_ok_for_arm (~INTVAL (op))"))) | |
147 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
148 (define_predicate "const0_operand" |
111 | 149 (match_test "op == CONST0_RTX (mode)")) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
150 |
0 | 151 ;; Something valid on the RHS of an ARM data-processing instruction |
152 (define_predicate "arm_rhs_operand" | |
153 (ior (match_operand 0 "s_register_operand") | |
154 (match_operand 0 "arm_immediate_operand"))) | |
155 | |
156 (define_predicate "arm_rhsm_operand" | |
157 (ior (match_operand 0 "arm_rhs_operand") | |
158 (match_operand 0 "memory_operand"))) | |
159 | |
111 | 160 (define_predicate "const_int_I_operand" |
161 (and (match_operand 0 "const_int_operand") | |
162 (match_test "satisfies_constraint_I (op)"))) | |
163 | |
164 (define_predicate "const_int_M_operand" | |
165 (and (match_operand 0 "const_int_operand") | |
166 (match_test "satisfies_constraint_M (op)"))) | |
167 | |
168 ;; This doesn't have to do much because the constant is already checked | |
169 ;; in the shift_operator predicate. | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
170 (define_predicate "shift_amount_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
171 (ior (and (match_test "TARGET_ARM") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
172 (match_operand 0 "s_register_operand")) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
173 (match_operand 0 "const_int_operand"))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
174 |
111 | 175 (define_predicate "const_neon_scalar_shift_amount_operand" |
176 (and (match_code "const_int") | |
177 (match_test "IN_RANGE (UINTVAL (op), 1, GET_MODE_BITSIZE (mode))"))) | |
178 | |
179 (define_predicate "ldrd_strd_offset_operand" | |
180 (and (match_operand 0 "const_int_operand") | |
181 (match_test "TARGET_LDRD && offset_ok_for_ldrd_strd (INTVAL (op))"))) | |
182 | |
0 | 183 (define_predicate "arm_add_operand" |
184 (ior (match_operand 0 "arm_rhs_operand") | |
185 (match_operand 0 "arm_neg_immediate_operand"))) | |
186 | |
111 | 187 (define_predicate "arm_anddi_operand_neon" |
188 (ior (match_operand 0 "s_register_operand") | |
189 (and (match_code "const_int") | |
190 (match_test "const_ok_for_dimode_op (INTVAL (op), AND)")) | |
191 (match_operand 0 "neon_inv_logic_op2"))) | |
192 | |
193 (define_predicate "arm_iordi_operand_neon" | |
194 (ior (match_operand 0 "s_register_operand") | |
195 (and (match_code "const_int") | |
196 (match_test "const_ok_for_dimode_op (INTVAL (op), IOR)")) | |
197 (match_operand 0 "neon_logic_op2"))) | |
198 | |
199 (define_predicate "arm_xordi_operand" | |
200 (ior (match_operand 0 "s_register_operand") | |
201 (and (match_code "const_int") | |
202 (match_test "const_ok_for_dimode_op (INTVAL (op), XOR)")))) | |
203 | |
204 (define_predicate "arm_adddi_operand" | |
205 (ior (match_operand 0 "s_register_operand") | |
206 (and (match_code "const_int") | |
207 (match_test "const_ok_for_dimode_op (INTVAL (op), PLUS)")))) | |
208 | |
0 | 209 (define_predicate "arm_addimm_operand" |
210 (ior (match_operand 0 "arm_immediate_operand") | |
211 (match_operand 0 "arm_neg_immediate_operand"))) | |
212 | |
213 (define_predicate "arm_not_operand" | |
214 (ior (match_operand 0 "arm_rhs_operand") | |
215 (match_operand 0 "arm_not_immediate_operand"))) | |
216 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
217 (define_predicate "arm_di_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
218 (ior (match_operand 0 "s_register_operand") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
219 (match_operand 0 "arm_immediate_di_operand"))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
220 |
0 | 221 ;; True if the operand is a memory reference which contains an |
222 ;; offsettable address. | |
223 (define_predicate "offsettable_memory_operand" | |
224 (and (match_code "mem") | |
225 (match_test | |
226 "offsettable_address_p (reload_completed | reload_in_progress, | |
227 mode, XEXP (op, 0))"))) | |
228 | |
229 ;; True if the operand is a memory operand that does not have an | |
230 ;; automodified base register (and thus will not generate output reloads). | |
231 (define_predicate "call_memory_operand" | |
232 (and (match_code "mem") | |
233 (and (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) | |
234 != RTX_AUTOINC") | |
235 (match_operand 0 "memory_operand")))) | |
236 | |
237 (define_predicate "arm_reload_memory_operand" | |
238 (and (match_code "mem,reg,subreg") | |
239 (match_test "(!CONSTANT_P (op) | |
240 && (true_regnum(op) == -1 | |
111 | 241 || (REG_P (op) |
0 | 242 && REGNO (op) >= FIRST_PSEUDO_REGISTER)))"))) |
243 | |
244 (define_predicate "vfp_compare_operand" | |
245 (ior (match_operand 0 "s_register_operand") | |
246 (and (match_code "const_double") | |
247 (match_test "arm_const_double_rtx (op)")))) | |
248 | |
249 ;; True for valid index operands. | |
250 (define_predicate "index_operand" | |
251 (ior (match_operand 0 "s_register_operand") | |
252 (and (match_operand 0 "immediate_operand") | |
111 | 253 (match_test "(!CONST_INT_P (op) |
0 | 254 || (INTVAL (op) < 4096 && INTVAL (op) > -4096))")))) |
255 | |
256 ;; True for operators that can be combined with a shift in ARM state. | |
257 (define_special_predicate "shiftable_operator" | |
258 (and (match_code "plus,minus,ior,xor,and") | |
259 (match_test "mode == GET_MODE (op)"))) | |
260 | |
111 | 261 (define_special_predicate "shiftable_operator_strict_it" |
262 (and (match_code "plus,and") | |
263 (match_test "mode == GET_MODE (op)"))) | |
264 | |
0 | 265 ;; True for logical binary operators. |
266 (define_special_predicate "logical_binary_operator" | |
267 (and (match_code "ior,xor,and") | |
268 (match_test "mode == GET_MODE (op)"))) | |
269 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
270 ;; True for commutative operators |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
271 (define_special_predicate "commutative_binary_operator" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
272 (and (match_code "ior,xor,and,plus") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
273 (match_test "mode == GET_MODE (op)"))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
274 |
0 | 275 ;; True for shift operators. |
111 | 276 ;; Notes: |
277 ;; * mult is only permitted with a constant shift amount | |
278 ;; * patterns that permit register shift amounts only in ARM mode use | |
279 ;; shift_amount_operand, patterns that always allow registers do not, | |
280 ;; so we don't have to worry about that sort of thing here. | |
0 | 281 (define_special_predicate "shift_operator" |
282 (and (ior (ior (and (match_code "mult") | |
283 (match_test "power_of_two_operand (XEXP (op, 1), mode)")) | |
284 (and (match_code "rotate") | |
111 | 285 (match_test "CONST_INT_P (XEXP (op, 1)) |
286 && (UINTVAL (XEXP (op, 1))) < 32"))) | |
287 (and (match_code "ashift,ashiftrt,lshiftrt,rotatert") | |
288 (match_test "!CONST_INT_P (XEXP (op, 1)) | |
289 || (UINTVAL (XEXP (op, 1))) < 32"))) | |
290 (match_test "mode == GET_MODE (op)"))) | |
291 | |
292 (define_special_predicate "shift_nomul_operator" | |
293 (and (ior (and (match_code "rotate") | |
294 (match_test "CONST_INT_P (XEXP (op, 1)) | |
295 && (UINTVAL (XEXP (op, 1))) < 32")) | |
296 (and (match_code "ashift,ashiftrt,lshiftrt,rotatert") | |
297 (match_test "!CONST_INT_P (XEXP (op, 1)) | |
298 || (UINTVAL (XEXP (op, 1))) < 32"))) | |
299 (match_test "mode == GET_MODE (op)"))) | |
300 | |
301 ;; True for shift operators which can be used with saturation instructions. | |
302 (define_special_predicate "sat_shift_operator" | |
303 (and (ior (and (match_code "mult") | |
304 (match_test "power_of_two_operand (XEXP (op, 1), mode)")) | |
305 (and (match_code "ashift,ashiftrt") | |
306 (match_test "CONST_INT_P (XEXP (op, 1)) | |
307 && (UINTVAL (XEXP (op, 1)) < 32)"))) | |
0 | 308 (match_test "mode == GET_MODE (op)"))) |
309 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
310 ;; True for MULT, to identify which variant of shift_operator is in use. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
311 (define_special_predicate "mult_operator" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
312 (match_code "mult")) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
313 |
0 | 314 ;; True for operators that have 16-bit thumb variants. */ |
315 (define_special_predicate "thumb_16bit_operator" | |
316 (match_code "plus,minus,and,ior,xor")) | |
317 | |
318 ;; True for EQ & NE | |
319 (define_special_predicate "equality_operator" | |
320 (match_code "eq,ne")) | |
321 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
322 ;; True for integer comparisons and, if FP is active, for comparisons |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
323 ;; other than LTGT or UNEQ. |
111 | 324 (define_special_predicate "expandable_comparison_operator" |
325 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu, | |
326 unordered,ordered,unlt,unle,unge,ungt")) | |
327 | |
328 ;; Likewise, but only accept comparisons that are directly supported | |
329 ;; by ARM condition codes. | |
0 | 330 (define_special_predicate "arm_comparison_operator" |
111 | 331 (and (match_operand 0 "expandable_comparison_operator") |
332 (match_test "maybe_get_arm_condition_code (op) != ARM_NV"))) | |
333 | |
334 ;; Likewise, but don't ignore the mode. | |
335 ;; RTL SET operations require their operands source and destination have | |
336 ;; the same modes, so we can't ignore the modes there. See PR target/69161. | |
337 (define_predicate "arm_comparison_operator_mode" | |
338 (and (match_operand 0 "expandable_comparison_operator") | |
339 (match_test "maybe_get_arm_condition_code (op) != ARM_NV"))) | |
0 | 340 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
341 (define_special_predicate "lt_ge_comparison_operator" |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
342 (match_code "lt,ge")) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
343 |
111 | 344 ;; The vsel instruction only accepts the ARM condition codes listed below. |
345 (define_special_predicate "arm_vsel_comparison_operator" | |
346 (and (match_operand 0 "expandable_comparison_operator") | |
347 (match_test "maybe_get_arm_condition_code (op) == ARM_GE | |
348 || maybe_get_arm_condition_code (op) == ARM_GT | |
349 || maybe_get_arm_condition_code (op) == ARM_EQ | |
350 || maybe_get_arm_condition_code (op) == ARM_VS | |
351 || maybe_get_arm_condition_code (op) == ARM_LT | |
352 || maybe_get_arm_condition_code (op) == ARM_LE | |
353 || maybe_get_arm_condition_code (op) == ARM_NE | |
354 || maybe_get_arm_condition_code (op) == ARM_VC"))) | |
355 | |
356 (define_special_predicate "arm_cond_move_operator" | |
357 (if_then_else (match_test "arm_restrict_it") | |
358 (and (match_test "TARGET_VFP5") | |
359 (match_operand 0 "arm_vsel_comparison_operator")) | |
360 (match_operand 0 "expandable_comparison_operator"))) | |
361 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
362 (define_special_predicate "noov_comparison_operator" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
363 (match_code "lt,ge,eq,ne")) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
364 |
0 | 365 (define_special_predicate "minmax_operator" |
366 (and (match_code "smin,smax,umin,umax") | |
367 (match_test "mode == GET_MODE (op)"))) | |
368 | |
369 (define_special_predicate "cc_register" | |
370 (and (match_code "reg") | |
371 (and (match_test "REGNO (op) == CC_REGNUM") | |
372 (ior (match_test "mode == GET_MODE (op)") | |
373 (match_test "mode == VOIDmode && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC"))))) | |
374 | |
375 (define_special_predicate "dominant_cc_register" | |
376 (match_code "reg") | |
377 { | |
378 if (mode == VOIDmode) | |
379 { | |
380 mode = GET_MODE (op); | |
381 | |
382 if (GET_MODE_CLASS (mode) != MODE_CC) | |
383 return false; | |
384 } | |
385 | |
386 return (cc_register (op, mode) | |
387 && (mode == CC_DNEmode | |
388 || mode == CC_DEQmode | |
389 || mode == CC_DLEmode | |
390 || mode == CC_DLTmode | |
391 || mode == CC_DGEmode | |
392 || mode == CC_DGTmode | |
393 || mode == CC_DLEUmode | |
394 || mode == CC_DLTUmode | |
395 || mode == CC_DGEUmode | |
396 || mode == CC_DGTUmode)); | |
397 }) | |
398 | |
111 | 399 ;; Any register, including CC |
400 (define_predicate "cc_register_operand" | |
401 (and (match_code "reg") | |
402 (ior (match_operand 0 "s_register_operand") | |
403 (match_operand 0 "cc_register")))) | |
404 | |
0 | 405 (define_special_predicate "arm_extendqisi_mem_op" |
406 (and (match_operand 0 "memory_operand") | |
111 | 407 (match_test "TARGET_ARM ? arm_legitimate_address_outer_p (mode, |
408 XEXP (op, 0), | |
409 SIGN_EXTEND, | |
410 0) | |
411 : memory_address_p (QImode, XEXP (op, 0))"))) | |
0 | 412 |
413 (define_special_predicate "arm_reg_or_extendqisi_mem_op" | |
414 (ior (match_operand 0 "arm_extendqisi_mem_op") | |
415 (match_operand 0 "s_register_operand"))) | |
416 | |
417 (define_predicate "power_of_two_operand" | |
418 (match_code "const_int") | |
419 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
420 unsigned HOST_WIDE_INT value = INTVAL (op) & 0xffffffff; |
0 | 421 |
422 return value != 0 && (value & (value - 1)) == 0; | |
423 }) | |
424 | |
425 (define_predicate "nonimmediate_di_operand" | |
426 (match_code "reg,subreg,mem") | |
427 { | |
428 if (s_register_operand (op, mode)) | |
429 return true; | |
430 | |
431 if (GET_CODE (op) == SUBREG) | |
432 op = SUBREG_REG (op); | |
433 | |
111 | 434 return MEM_P (op) && memory_address_p (DImode, XEXP (op, 0)); |
0 | 435 }) |
436 | |
437 (define_predicate "di_operand" | |
438 (ior (match_code "const_int,const_double") | |
439 (and (match_code "reg,subreg,mem") | |
440 (match_operand 0 "nonimmediate_di_operand")))) | |
441 | |
442 (define_predicate "nonimmediate_soft_df_operand" | |
443 (match_code "reg,subreg,mem") | |
444 { | |
445 if (s_register_operand (op, mode)) | |
446 return true; | |
447 | |
448 if (GET_CODE (op) == SUBREG) | |
449 op = SUBREG_REG (op); | |
450 | |
111 | 451 return MEM_P (op) && memory_address_p (DFmode, XEXP (op, 0)); |
0 | 452 }) |
453 | |
454 (define_predicate "soft_df_operand" | |
455 (ior (match_code "const_double") | |
456 (and (match_code "reg,subreg,mem") | |
457 (match_operand 0 "nonimmediate_soft_df_operand")))) | |
458 | |
459 (define_special_predicate "load_multiple_operation" | |
460 (match_code "parallel") | |
461 { | |
111 | 462 return ldm_stm_operation_p (op, /*load=*/true, SImode, |
463 /*consecutive=*/false, | |
464 /*return_pc=*/false); | |
0 | 465 }) |
466 | |
467 (define_special_predicate "store_multiple_operation" | |
468 (match_code "parallel") | |
469 { | |
111 | 470 return ldm_stm_operation_p (op, /*load=*/false, SImode, |
471 /*consecutive=*/false, | |
472 /*return_pc=*/false); | |
473 }) | |
0 | 474 |
111 | 475 (define_special_predicate "pop_multiple_return" |
476 (match_code "parallel") | |
477 { | |
478 return ldm_stm_operation_p (op, /*load=*/true, SImode, | |
479 /*consecutive=*/false, | |
480 /*return_pc=*/true); | |
481 }) | |
0 | 482 |
111 | 483 (define_special_predicate "pop_multiple_fp" |
484 (match_code "parallel") | |
485 { | |
486 return ldm_stm_operation_p (op, /*load=*/true, DFmode, | |
487 /*consecutive=*/true, | |
488 /*return_pc=*/false); | |
0 | 489 }) |
490 | |
491 (define_special_predicate "multi_register_push" | |
492 (match_code "parallel") | |
493 { | |
494 if ((GET_CODE (XVECEXP (op, 0, 0)) != SET) | |
495 || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC) | |
496 || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT)) | |
497 return false; | |
498 | |
499 return true; | |
500 }) | |
501 | |
111 | 502 (define_predicate "push_mult_memory_operand" |
503 (match_code "mem") | |
504 { | |
505 /* ??? Given how PUSH_MULT is generated in the prologues, is there | |
506 any point in testing for thumb1 specially? All of the variants | |
507 use the same form. */ | |
508 if (TARGET_THUMB1) | |
509 { | |
510 /* ??? No attempt is made to represent STMIA, or validate that | |
511 the stack adjustment matches the register count. This is | |
512 true of the ARM/Thumb2 path as well. */ | |
513 rtx x = XEXP (op, 0); | |
514 if (GET_CODE (x) != PRE_MODIFY) | |
515 return false; | |
516 if (XEXP (x, 0) != stack_pointer_rtx) | |
517 return false; | |
518 x = XEXP (x, 1); | |
519 if (GET_CODE (x) != PLUS) | |
520 return false; | |
521 if (XEXP (x, 0) != stack_pointer_rtx) | |
522 return false; | |
523 return CONST_INT_P (XEXP (x, 1)); | |
524 } | |
525 | |
526 /* ARM and Thumb2 handle pre-modify in their legitimate_address. */ | |
527 return memory_operand (op, mode); | |
528 }) | |
529 | |
0 | 530 ;;------------------------------------------------------------------------- |
531 ;; | |
532 ;; Thumb predicates | |
533 ;; | |
534 | |
535 (define_predicate "thumb1_cmp_operand" | |
536 (ior (and (match_code "reg,subreg") | |
537 (match_operand 0 "s_register_operand")) | |
538 (and (match_code "const_int") | |
111 | 539 (match_test "(UINTVAL (op)) < 256")))) |
0 | 540 |
541 (define_predicate "thumb1_cmpneg_operand" | |
542 (and (match_code "const_int") | |
543 (match_test "INTVAL (op) < 0 && INTVAL (op) > -256"))) | |
544 | |
545 ;; Return TRUE if a result can be stored in OP without clobbering the | |
546 ;; condition code register. Prior to reload we only accept a | |
547 ;; register. After reload we have to be able to handle memory as | |
548 ;; well, since a pseudo may not get a hard reg and reload cannot | |
549 ;; handle output-reloads on jump insns. | |
550 | |
551 ;; We could possibly handle mem before reload as well, but that might | |
552 ;; complicate things with the need to handle increment | |
553 ;; side-effects. | |
554 (define_predicate "thumb_cbrch_target_operand" | |
555 (and (match_code "reg,subreg,mem") | |
556 (ior (match_operand 0 "s_register_operand") | |
557 (and (match_test "reload_in_progress || reload_completed") | |
558 (match_operand 0 "memory_operand"))))) | |
559 | |
560 ;;------------------------------------------------------------------------- | |
561 ;; | |
111 | 562 ;; iWMMXt predicates |
0 | 563 ;; |
564 | |
111 | 565 (define_predicate "imm_or_reg_operand" |
566 (ior (match_operand 0 "immediate_operand") | |
567 (match_operand 0 "register_operand"))) | |
0 | 568 |
569 ;; Neon predicates | |
570 | |
571 (define_predicate "const_multiple_of_8_operand" | |
572 (match_code "const_int") | |
573 { | |
574 unsigned HOST_WIDE_INT val = INTVAL (op); | |
575 return (val & 7) == 0; | |
576 }) | |
577 | |
578 (define_predicate "imm_for_neon_mov_operand" | |
111 | 579 (match_code "const_vector,const_int") |
0 | 580 { |
581 return neon_immediate_valid_for_move (op, mode, NULL, NULL); | |
582 }) | |
583 | |
111 | 584 (define_predicate "imm_for_neon_lshift_operand" |
0 | 585 (match_code "const_vector") |
586 { | |
111 | 587 return neon_immediate_valid_for_shift (op, mode, NULL, NULL, true); |
0 | 588 }) |
589 | |
111 | 590 (define_predicate "imm_for_neon_rshift_operand" |
0 | 591 (match_code "const_vector") |
592 { | |
111 | 593 return neon_immediate_valid_for_shift (op, mode, NULL, NULL, false); |
0 | 594 }) |
595 | |
111 | 596 (define_predicate "imm_lshift_or_reg_neon" |
597 (ior (match_operand 0 "s_register_operand") | |
598 (match_operand 0 "imm_for_neon_lshift_operand"))) | |
0 | 599 |
111 | 600 (define_predicate "imm_rshift_or_reg_neon" |
601 (ior (match_operand 0 "s_register_operand") | |
602 (match_operand 0 "imm_for_neon_rshift_operand"))) | |
0 | 603 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
604 ;; Predicates for named expanders that overlap multiple ISAs. |
0 | 605 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
606 (define_predicate "cmpdi_operand" |
111 | 607 (and (match_test "TARGET_32BIT") |
608 (match_operand 0 "arm_di_operand"))) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
609 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
610 ;; True if the operand is memory reference suitable for a ldrex/strex. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
611 (define_predicate "arm_sync_memory_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
612 (and (match_operand 0 "memory_operand") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
613 (match_code "reg" "0"))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
614 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
615 ;; Predicates for parallel expanders based on mode. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
616 (define_special_predicate "vect_par_constant_high" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
617 (match_code "parallel") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
618 { |
111 | 619 return arm_simd_check_vect_par_cnst_half_p (op, mode, true); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
620 }) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
621 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
622 (define_special_predicate "vect_par_constant_low" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
623 (match_code "parallel") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
624 { |
111 | 625 return arm_simd_check_vect_par_cnst_half_p (op, mode, false); |
626 }) | |
627 | |
628 (define_predicate "const_double_vcvt_power_of_two_reciprocal" | |
629 (and (match_code "const_double") | |
630 (match_test "TARGET_32BIT | |
631 && vfp3_const_double_for_fract_bits (op)"))) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
632 |
111 | 633 (define_predicate "const_double_vcvt_power_of_two" |
634 (and (match_code "const_double") | |
635 (match_test "TARGET_32BIT | |
636 && vfp3_const_double_for_bits (op) > 0"))) | |
637 | |
638 (define_predicate "neon_struct_operand" | |
639 (and (match_code "mem") | |
640 (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2, true)"))) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
641 |
111 | 642 (define_predicate "neon_permissive_struct_operand" |
643 (and (match_code "mem") | |
644 (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2, false)"))) | |
645 | |
646 (define_predicate "neon_perm_struct_or_reg_operand" | |
647 (ior (match_operand 0 "neon_permissive_struct_operand") | |
648 (match_operand 0 "s_register_operand"))) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
649 |
111 | 650 (define_special_predicate "add_operator" |
651 (match_code "plus")) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
652 |
111 | 653 (define_predicate "mem_noofs_operand" |
654 (and (match_code "mem") | |
655 (match_code "reg" "0"))) | |
656 | |
657 (define_predicate "call_insn_operand" | |
658 (ior (and (match_code "symbol_ref") | |
659 (match_test "!arm_is_long_call_p (SYMBOL_REF_DECL (op))")) | |
660 (match_operand 0 "s_register_operand"))) |