]>
Commit | Line | Data |
---|---|---|
138814fb | 1 | ;; Predicate definitions for Renesas / SuperH SH. |
f1717362 | 2 | ;; Copyright (C) 2005-2016 Free Software Foundation, Inc. |
138814fb | 3 | ;; |
4 | ;; This file is part of GCC. | |
5 | ;; | |
6 | ;; GCC is free software; you can redistribute it and/or modify | |
7 | ;; it under the terms of the GNU General Public License as published by | |
038d1e19 | 8 | ;; the Free Software Foundation; either version 3, or (at your option) |
138814fb | 9 | ;; any later version. |
10 | ;; | |
11 | ;; GCC is distributed in the hope that it will be useful, | |
12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | ;; GNU General Public License for more details. | |
15 | ;; | |
16 | ;; You should have received a copy of the GNU General Public License | |
038d1e19 | 17 | ;; along with GCC; see the file COPYING3. If not see |
18 | ;; <http://www.gnu.org/licenses/>. | |
138814fb | 19 | |
20 | ;; TODO: Add a comment here. | |
59312820 | 21 | (define_predicate "trapping_target_operand" |
22 | (match_code "if_then_else") | |
23 | { | |
ef51d1e3 | 24 | rtx cond, mem, res, tar, and_expr; |
59312820 | 25 | |
26 | if (GET_MODE (op) != PDImode) | |
27 | return 0; | |
28 | cond = XEXP (op, 0); | |
29 | mem = XEXP (op, 1); | |
30 | res = XEXP (op, 2); | |
cbb16986 | 31 | if (!MEM_P (mem) |
59312820 | 32 | || (GET_CODE (res) != SIGN_EXTEND && GET_CODE (res) != TRUNCATE)) |
33 | return 0; | |
34 | tar = XEXP (res, 0); | |
35 | if (!rtx_equal_p (XEXP (mem, 0), tar) | |
36 | || GET_MODE (tar) != Pmode) | |
37 | return 0; | |
38 | if (GET_CODE (cond) == CONST) | |
39 | { | |
40 | cond = XEXP (cond, 0); | |
abff7a2e | 41 | if (!satisfies_constraint_Csy (tar)) |
59312820 | 42 | return 0; |
43 | if (GET_CODE (tar) == CONST) | |
44 | tar = XEXP (tar, 0); | |
45 | } | |
46 | else if (!arith_reg_operand (tar, VOIDmode) | |
abff7a2e | 47 | && ! satisfies_constraint_Csy (tar)) |
59312820 | 48 | return 0; |
49 | if (GET_CODE (cond) != EQ) | |
50 | return 0; | |
ef51d1e3 | 51 | and_expr = XEXP (cond, 0); |
52 | return (GET_CODE (and_expr) == AND | |
53 | && rtx_equal_p (XEXP (and_expr, 0), tar) | |
54 | && CONST_INT_P (XEXP (and_expr, 1)) | |
cbb16986 | 55 | && CONST_INT_P (XEXP (cond, 1)) |
ef51d1e3 | 56 | && INTVAL (XEXP (and_expr, 1)) == 3 |
59312820 | 57 | && INTVAL (XEXP (cond, 1)) == 3); |
58 | }) | |
138814fb | 59 | |
6c049e03 | 60 | ;; A logical operand that can be used in an shmedia and insn. |
138814fb | 61 | (define_predicate "and_operand" |
62 | (match_code "subreg,reg,const_int") | |
63 | { | |
64 | if (logical_operand (op, mode)) | |
65 | return 1; | |
66 | ||
67 | /* Check mshflo.l / mshflhi.l opportunities. */ | |
68 | if (TARGET_SHMEDIA | |
69 | && mode == DImode | |
abff7a2e | 70 | && satisfies_constraint_J16 (op)) |
138814fb | 71 | return 1; |
72 | ||
73 | return 0; | |
74 | }) | |
75 | ||
63dfe6b8 | 76 | ;; Like arith_reg_dest, but this predicate is defined with |
77 | ;; define_special_predicate, not define_predicate. | |
138814fb | 78 | (define_special_predicate "any_arith_reg_dest" |
79 | (match_code "subreg,reg") | |
80 | { | |
81 | return arith_reg_dest (op, mode); | |
82 | }) | |
83 | ||
63dfe6b8 | 84 | ;; Like register_operand, but this predicate is defined with |
85 | ;; define_special_predicate, not define_predicate. | |
138814fb | 86 | (define_special_predicate "any_register_operand" |
87 | (match_code "subreg,reg") | |
88 | { | |
89 | return register_operand (op, mode); | |
90 | }) | |
91 | ||
92 | ;; Returns 1 if OP is a valid source operand for an arithmetic insn. | |
138814fb | 93 | (define_predicate "arith_operand" |
94 | (match_code "subreg,reg,const_int,truncate") | |
95 | { | |
96 | if (arith_reg_operand (op, mode)) | |
97 | return 1; | |
98 | ||
99 | if (TARGET_SHMEDIA) | |
100 | { | |
101 | /* FIXME: We should be checking whether the CONST_INT fits in a | |
abff7a2e | 102 | signed 16-bit here, but this causes reload_cse to crash when |
138814fb | 103 | attempting to transform a sequence of two 64-bit sets of the |
104 | same register from literal constants into a set and an add, | |
105 | when the difference is too wide for an add. */ | |
cbb16986 | 106 | if (CONST_INT_P (op) |
abff7a2e | 107 | || satisfies_constraint_Css (op)) |
138814fb | 108 | return 1; |
109 | else if (GET_CODE (op) == TRUNCATE | |
cbb16986 | 110 | && REG_P (XEXP (op, 0)) |
138814fb | 111 | && ! system_reg_operand (XEXP (op, 0), VOIDmode) |
112 | && (mode == VOIDmode || mode == GET_MODE (op)) | |
113 | && (GET_MODE_SIZE (GET_MODE (op)) | |
114 | < GET_MODE_SIZE (GET_MODE (XEXP (op, 0)))) | |
115 | && (! FP_REGISTER_P (REGNO (XEXP (op, 0))) | |
116 | || GET_MODE_SIZE (GET_MODE (op)) == 4)) | |
117 | return register_operand (XEXP (op, 0), VOIDmode); | |
118 | else | |
119 | return 0; | |
120 | } | |
abff7a2e | 121 | else if (satisfies_constraint_I08 (op)) |
138814fb | 122 | return 1; |
123 | ||
124 | return 0; | |
125 | }) | |
126 | ||
127 | ;; Like above, but for DImode destinations: forbid paradoxical DImode | |
128 | ;; subregs, because this would lead to missing sign extensions when | |
129 | ;; truncating from DImode to SImode. | |
138814fb | 130 | (define_predicate "arith_reg_dest" |
131 | (match_code "subreg,reg") | |
132 | { | |
133 | if (mode == DImode && GET_CODE (op) == SUBREG | |
134 | && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8 | |
135 | && TARGET_SHMEDIA) | |
136 | return 0; | |
137 | return arith_reg_operand (op, mode); | |
138 | }) | |
139 | ||
140 | ;; Returns 1 if OP is a normal arithmetic register. | |
138814fb | 141 | (define_predicate "arith_reg_operand" |
142 | (match_code "subreg,reg,sign_extend") | |
143 | { | |
144 | if (register_operand (op, mode)) | |
145 | { | |
146 | int regno; | |
147 | ||
cbb16986 | 148 | if (REG_P (op)) |
138814fb | 149 | regno = REGNO (op); |
cbb16986 | 150 | else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op))) |
138814fb | 151 | regno = REGNO (SUBREG_REG (op)); |
152 | else | |
153 | return 1; | |
154 | ||
155 | return (regno != T_REG && regno != PR_REG | |
156 | && ! TARGET_REGISTER_P (regno) | |
81298240 | 157 | && regno != FPUL_REG && regno != FPSCR_REG |
138814fb | 158 | && regno != MACH_REG && regno != MACL_REG); |
159 | } | |
160 | /* Allow a no-op sign extension - compare LOAD_EXTEND_OP. | |
161 | We allow SImode here, as not using an FP register is just a matter of | |
162 | proper register allocation. */ | |
163 | if (TARGET_SHMEDIA | |
164 | && GET_MODE (op) == DImode && GET_CODE (op) == SIGN_EXTEND | |
165 | && GET_MODE (XEXP (op, 0)) == SImode | |
166 | && GET_CODE (XEXP (op, 0)) != SUBREG) | |
167 | return register_operand (XEXP (op, 0), VOIDmode); | |
168 | #if 0 /* Can't do this because of PROMOTE_MODE for unsigned vars. */ | |
169 | if (GET_MODE (op) == SImode && GET_CODE (op) == SIGN_EXTEND | |
170 | && GET_MODE (XEXP (op, 0)) == HImode | |
cbb16986 | 171 | && REG_P (XEXP (op, 0)) |
138814fb | 172 | && REGNO (XEXP (op, 0)) <= LAST_GENERAL_REG) |
173 | return register_operand (XEXP (op, 0), VOIDmode); | |
174 | #endif | |
175 | if (GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT | |
176 | && GET_CODE (op) == SUBREG | |
177 | && GET_MODE (SUBREG_REG (op)) == DImode | |
178 | && GET_CODE (SUBREG_REG (op)) == SIGN_EXTEND | |
179 | && GET_MODE (XEXP (SUBREG_REG (op), 0)) == SImode | |
180 | && GET_CODE (XEXP (SUBREG_REG (op), 0)) != SUBREG) | |
181 | return register_operand (XEXP (SUBREG_REG (op), 0), VOIDmode); | |
182 | return 0; | |
183 | }) | |
184 | ||
6e0d3dbd | 185 | ;; Likewise arith_operand but always permits const_int. |
186 | (define_predicate "arith_or_int_operand" | |
187 | (match_code "subreg,reg,const_int,const_vector") | |
188 | { | |
189 | if (arith_operand (op, mode)) | |
190 | return 1; | |
191 | ||
192 | if (CONST_INT_P (op)) | |
193 | return 1; | |
194 | ||
195 | return 0; | |
196 | }) | |
197 | ||
138814fb | 198 | ;; Returns 1 if OP is a valid source operand for a compare insn. |
138814fb | 199 | (define_predicate "arith_reg_or_0_operand" |
200 | (match_code "subreg,reg,const_int,const_vector") | |
201 | { | |
202 | if (arith_reg_operand (op, mode)) | |
203 | return 1; | |
204 | ||
abff7a2e | 205 | if (satisfies_constraint_Z (op)) |
138814fb | 206 | return 1; |
207 | ||
208 | return 0; | |
209 | }) | |
210 | ||
a61eea5a | 211 | ;; Returns true if OP is either a register or constant 0 or constant 1. |
212 | (define_predicate "arith_reg_or_0_or_1_operand" | |
213 | (match_code "subreg,reg,const_int,const_vector") | |
214 | { | |
215 | return arith_reg_or_0_operand (op, mode) || satisfies_constraint_M (op); | |
216 | }) | |
217 | ||
218 | ;; Returns true if OP is a suitable constant for the minimum value of a | |
219 | ;; clips.b or clips.w insn. | |
220 | (define_predicate "clips_min_const_int" | |
221 | (and (match_code "const_int") | |
222 | (ior (match_test "INTVAL (op) == -128") | |
223 | (match_test "INTVAL (op) == -32768")))) | |
224 | ||
225 | ;; Returns true if OP is a suitable constant for the maximum value of a | |
226 | ;; clips.b or clips.w insn. | |
227 | (define_predicate "clips_max_const_int" | |
228 | (and (match_code "const_int") | |
229 | (ior (match_test "INTVAL (op) == 127") | |
230 | (match_test "INTVAL (op) == 32767")))) | |
231 | ||
232 | ;; Returns true if OP is a suitable constant for the maximum value of a | |
233 | ;; clipu.b or clipu.w insn. | |
234 | (define_predicate "clipu_max_const_int" | |
235 | (and (match_code "const_int") | |
236 | (ior (match_test "INTVAL (op) == 255") | |
237 | (match_test "INTVAL (op) == 65535")))) | |
238 | ||
6c049e03 | 239 | ;; Returns 1 if OP is a floating point operator with two operands. |
138814fb | 240 | (define_predicate "binary_float_operator" |
9f3fa8ba | 241 | (and (match_code "plus,minus,mult,div") |
242 | (match_test "GET_MODE (op) == mode"))) | |
138814fb | 243 | |
6c049e03 | 244 | ;; Returns 1 if OP is a logical operator with two operands. |
138814fb | 245 | (define_predicate "binary_logical_operator" |
9f3fa8ba | 246 | (and (match_code "and,ior,xor") |
247 | (match_test "GET_MODE (op) == mode"))) | |
138814fb | 248 | |
6c049e03 | 249 | ;; Return 1 if OP is an address suitable for a cache manipulation operation. |
3d533137 | 250 | ;; MODE has the meaning as in address_operand. |
3d533137 | 251 | (define_special_predicate "cache_address_operand" |
138814fb | 252 | (match_code "plus,reg") |
253 | { | |
254 | if (GET_CODE (op) == PLUS) | |
255 | { | |
cbb16986 | 256 | if (!REG_P (XEXP (op, 0))) |
138814fb | 257 | return 0; |
cbb16986 | 258 | if (!CONST_INT_P (XEXP (op, 1)) |
138814fb | 259 | || (INTVAL (XEXP (op, 1)) & 31)) |
260 | return 0; | |
261 | } | |
cbb16986 | 262 | else if (!REG_P (op)) |
138814fb | 263 | return 0; |
264 | return address_operand (op, mode); | |
265 | }) | |
266 | ||
6c049e03 | 267 | ;; Returns 1 if OP is a valid source operand for shmedia cmpgt / cmpgtu. |
138814fb | 268 | (define_predicate "cmp_operand" |
269 | (match_code "subreg,reg,const_int") | |
270 | { | |
abff7a2e | 271 | if (satisfies_constraint_N (op)) |
138814fb | 272 | return 1; |
273 | if (TARGET_SHMEDIA | |
274 | && mode != DImode && GET_CODE (op) == SUBREG | |
275 | && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4) | |
276 | return 0; | |
277 | return arith_reg_operand (op, mode); | |
278 | }) | |
279 | ||
6c049e03 | 280 | ;; Returns true if OP is an operand that can be used as the first operand in |
281 | ;; the cstoresi4 expander pattern. | |
138814fb | 282 | (define_predicate "cmpsi_operand" |
283 | (match_code "subreg,reg,const_int") | |
284 | { | |
cbb16986 | 285 | if (REG_P (op) && REGNO (op) == T_REG |
138814fb | 286 | && GET_MODE (op) == SImode |
287 | && TARGET_SH1) | |
288 | return 1; | |
289 | return arith_operand (op, mode); | |
290 | }) | |
291 | ||
6c049e03 | 292 | ;; Returns true if OP is a comutative float operator. |
293 | ;; This predicate is currently unused. | |
294 | ;;(define_predicate "commutative_float_operator" | |
295 | ;; (and (match_code "plus,mult") | |
296 | ;; (match_test "GET_MODE (op) == mode"))) | |
138814fb | 297 | |
6c049e03 | 298 | ;; Returns true if OP is a equal or not equal operator. |
138814fb | 299 | (define_predicate "equality_comparison_operator" |
9f3fa8ba | 300 | (match_code "eq,ne")) |
138814fb | 301 | |
6c049e03 | 302 | ;; Returns true if OP is an arithmetic operand that is zero extended during |
303 | ;; an operation. | |
138814fb | 304 | (define_predicate "extend_reg_operand" |
305 | (match_code "subreg,reg,truncate") | |
306 | { | |
307 | return (GET_CODE (op) == TRUNCATE | |
308 | ? arith_operand | |
309 | : arith_reg_operand) (op, mode); | |
310 | }) | |
311 | ||
6c049e03 | 312 | ;; Like extend_reg_operand, but also allow a constant 0. |
138814fb | 313 | (define_predicate "extend_reg_or_0_operand" |
314 | (match_code "subreg,reg,truncate,const_int") | |
315 | { | |
316 | return (GET_CODE (op) == TRUNCATE | |
317 | ? arith_operand | |
318 | : arith_reg_or_0_operand) (op, mode); | |
319 | }) | |
320 | ||
321 | ;; Like arith_reg_operand, but this predicate does not accept SIGN_EXTEND. | |
138814fb | 322 | (define_predicate "ext_dest_operand" |
323 | (match_code "subreg,reg") | |
324 | { | |
325 | return arith_reg_operand (op, mode); | |
326 | }) | |
327 | ||
6c049e03 | 328 | ;; Returns true if OP can be used as a destination register for shmedia floating |
329 | ;; point to integer conversions. | |
138814fb | 330 | (define_predicate "fp_arith_reg_dest" |
331 | (match_code "subreg,reg") | |
332 | { | |
333 | if (mode == DImode && GET_CODE (op) == SUBREG | |
334 | && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8) | |
335 | return 0; | |
336 | return fp_arith_reg_operand (op, mode); | |
337 | }) | |
338 | ||
6c049e03 | 339 | ;; Returns true if OP is a floating point register that can be used in floating |
340 | ;; point arithmetic operations. | |
138814fb | 341 | (define_predicate "fp_arith_reg_operand" |
342 | (match_code "subreg,reg") | |
343 | { | |
344 | if (register_operand (op, mode)) | |
345 | { | |
346 | int regno; | |
347 | ||
cbb16986 | 348 | if (REG_P (op)) |
138814fb | 349 | regno = REGNO (op); |
cbb16986 | 350 | else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op))) |
138814fb | 351 | regno = REGNO (SUBREG_REG (op)); |
352 | else | |
353 | return 1; | |
354 | ||
355 | return (regno >= FIRST_PSEUDO_REGISTER | |
356 | || FP_REGISTER_P (regno)); | |
357 | } | |
358 | return 0; | |
359 | }) | |
360 | ||
6c049e03 | 361 | ;; Returns true if OP is the FPSCR. |
138814fb | 362 | (define_predicate "fpscr_operand" |
81298240 | 363 | (and (match_code "reg") |
364 | (match_test "REGNO (op) == FPSCR_REG"))) | |
365 | ||
366 | ;; Returns true if OP is a valid source operand for a FPSCR move insn. | |
367 | (define_predicate "fpscr_movsrc_operand" | |
368 | (match_code "reg,subreg,mem") | |
138814fb | 369 | { |
81298240 | 370 | if (arith_reg_operand (op, mode)) |
371 | return true; | |
372 | ||
373 | return MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC; | |
374 | }) | |
375 | ||
376 | ;; Returns true if OP is a valid destination operand for a FPSCR move insn. | |
377 | (define_predicate "fpscr_movdst_operand" | |
378 | (match_code "reg,subreg,mem") | |
379 | { | |
380 | if (arith_reg_dest (op, mode)) | |
381 | return true; | |
382 | ||
383 | return MEM_P (op) && GET_CODE (XEXP (op, 0)) == PRE_DEC; | |
138814fb | 384 | }) |
385 | ||
14c9d678 | 386 | ;; Returns true if OP is an operand that is either the fpul hard reg or |
387 | ;; a pseudo. This prevents combine from propagating function arguments | |
388 | ;; in hard regs into insns that need the operand in fpul. If it's a pseudo | |
389 | ;; reload can fix it up. | |
138814fb | 390 | (define_predicate "fpul_operand" |
391 | (match_code "reg") | |
392 | { | |
393 | if (TARGET_SHMEDIA) | |
394 | return fp_arith_reg_operand (op, mode); | |
395 | ||
cbb16986 | 396 | return (REG_P (op) |
138814fb | 397 | && (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER) |
398 | && GET_MODE (op) == mode); | |
399 | }) | |
400 | ||
14c9d678 | 401 | ;; Returns true if OP is a valid fpul input operand for the fsca insn. |
402 | ;; The value in fpul is a fixed-point value and its scaling is described | |
403 | ;; in the fsca insn by a mult:SF. To allow pre-scaled fixed-point inputs | |
404 | ;; in fpul we have to permit things like | |
405 | ;; (reg:SI) | |
406 | ;; (fix:SF (float:SF (reg:SI))) | |
407 | (define_predicate "fpul_fsca_operand" | |
408 | (match_code "fix,reg") | |
409 | { | |
410 | if (fpul_operand (op, SImode)) | |
411 | return true; | |
412 | if (GET_CODE (op) == FIX && GET_MODE (op) == SImode | |
413 | && GET_CODE (XEXP (op, 0)) == FLOAT && GET_MODE (XEXP (op, 0)) == SFmode) | |
414 | return fpul_fsca_operand (XEXP (XEXP (op, 0), 0), | |
415 | GET_MODE (XEXP (XEXP (op, 0), 0))); | |
416 | return false; | |
417 | }) | |
418 | ||
419 | ;; Returns true if OP is a valid constant scale factor for the fsca insn. | |
420 | (define_predicate "fsca_scale_factor" | |
421 | (and (match_code "const_double") | |
422 | (match_test "op == sh_fsca_int2sf ()"))) | |
423 | ||
6c049e03 | 424 | ;; Returns true if OP is an operand that is zero extended during an operation. |
138814fb | 425 | (define_predicate "general_extend_operand" |
426 | (match_code "subreg,reg,mem,truncate") | |
427 | { | |
0bad5c9c | 428 | if (reload_completed && GET_CODE (op) == TRUNCATE) |
640c5f1f | 429 | return arith_operand (op, mode); |
430 | ||
431 | if (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))) | |
432 | return general_movsrc_operand (op, mode); | |
433 | ||
434 | return nonimmediate_operand (op, mode); | |
138814fb | 435 | }) |
436 | ||
031c81fb | 437 | ;; Returns 1 if OP is a simple register address. |
438 | (define_predicate "simple_mem_operand" | |
439 | (and (match_code "mem") | |
dfc7d67d | 440 | (match_code "reg" "0") |
031c81fb | 441 | (match_test "arith_reg_operand (XEXP (op, 0), SImode)"))) |
442 | ||
443 | ;; Returns 1 if OP is a valid displacement address. | |
444 | (define_predicate "displacement_mem_operand" | |
445 | (and (match_code "mem") | |
dfc7d67d | 446 | (match_code "plus" "0") |
447 | (match_code "reg" "00") | |
031c81fb | 448 | (match_test "arith_reg_operand (XEXP (XEXP (op, 0), 0), SImode)") |
449 | (match_test "sh_legitimate_index_p (GET_MODE (op), | |
450 | XEXP (XEXP (op, 0), 1), | |
451 | TARGET_SH2A, true)"))) | |
452 | ||
9db63610 | 453 | ;; Returns true if OP is a displacement address that can fit into a |
454 | ;; 16 bit (non-SH2A) memory load / store insn. | |
455 | (define_predicate "short_displacement_mem_operand" | |
dfc7d67d | 456 | (and (match_code "mem") |
457 | (match_operand 0 "displacement_mem_operand") | |
458 | (match_test "sh_disp_addr_displacement (op) | |
459 | <= sh_max_mov_insn_displacement (GET_MODE (op), false)"))) | |
9db63610 | 460 | |
031c81fb | 461 | ;; Returns 1 if the operand can be used in an SH2A movu.{b|w} insn. |
462 | (define_predicate "zero_extend_movu_operand" | |
6c97af1b | 463 | (and (ior (match_operand 0 "displacement_mem_operand") |
464 | (match_operand 0 "simple_mem_operand")) | |
465 | (ior (match_test "GET_MODE (op) == QImode") | |
466 | (match_test "GET_MODE (op) == HImode")))) | |
031c81fb | 467 | |
392e1ee8 | 468 | ;; Returns 1 if the operand can be used in a zero_extend. |
469 | (define_predicate "zero_extend_operand" | |
470 | (ior (and (match_test "TARGET_SHMEDIA") | |
471 | (match_operand 0 "general_extend_operand")) | |
472 | (and (match_test "! TARGET_SHMEDIA") | |
6c97af1b | 473 | (match_operand 0 "arith_reg_operand")))) |
392e1ee8 | 474 | |
138814fb | 475 | ;; Returns 1 if OP can be source of a simple move operation. Same as |
476 | ;; general_operand, but a LABEL_REF is valid, PRE_DEC is invalid as | |
477 | ;; are subregs of system registers. | |
138814fb | 478 | (define_predicate "general_movsrc_operand" |
6c049e03 | 479 | (match_code "subreg,reg,const_int,const_double,mem,symbol_ref,label_ref, |
480 | const,const_vector") | |
138814fb | 481 | { |
61af3583 | 482 | if (t_reg_operand (op, mode)) |
483 | return 0; | |
484 | ||
81298240 | 485 | if (fpscr_operand (op, mode)) |
486 | return false; | |
487 | ||
9db63610 | 488 | /* Disallow PC relative QImode loads, since these is no insn to do that |
489 | and an imm8 load should be used instead. */ | |
490 | if (IS_PC_RELATIVE_LOAD_ADDR_P (op) && GET_MODE (op) == QImode) | |
491 | return false; | |
492 | ||
cbb16986 | 493 | if (MEM_P (op)) |
138814fb | 494 | { |
495 | rtx inside = XEXP (op, 0); | |
3ea038fc | 496 | |
497 | /* Disallow mems with GBR address here. They have to go through | |
498 | separate special patterns. */ | |
499 | if ((REG_P (inside) && REGNO (inside) == GBR_REG) | |
500 | || (GET_CODE (inside) == PLUS && REG_P (XEXP (inside, 0)) | |
501 | && REGNO (XEXP (inside, 0)) == GBR_REG)) | |
502 | return 0; | |
503 | ||
138814fb | 504 | if (GET_CODE (inside) == CONST) |
505 | inside = XEXP (inside, 0); | |
506 | ||
507 | if (GET_CODE (inside) == LABEL_REF) | |
508 | return 1; | |
509 | ||
510 | if (GET_CODE (inside) == PLUS | |
511 | && GET_CODE (XEXP (inside, 0)) == LABEL_REF | |
cbb16986 | 512 | && CONST_INT_P (XEXP (inside, 1))) |
138814fb | 513 | return 1; |
514 | ||
515 | /* Only post inc allowed. */ | |
516 | if (GET_CODE (inside) == PRE_DEC) | |
517 | return 0; | |
518 | } | |
519 | ||
640c5f1f | 520 | if (mode == GET_MODE (op) |
521 | && (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op))))) | |
cb022464 | 522 | { |
640c5f1f | 523 | rtx mem_rtx = MEM_P (op) ? op : SUBREG_REG (op); |
524 | rtx x = XEXP (mem_rtx, 0); | |
cb022464 | 525 | |
3a51c3c9 | 526 | if (! ALLOW_INDEXED_ADDRESS |
527 | && GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1))) | |
528 | return false; | |
529 | ||
ea68d4ba | 530 | if (GET_CODE (x) == PLUS) |
531 | { | |
532 | rtx y = XEXP (x, 0); | |
533 | ||
534 | if (! REG_P (y) | |
535 | && ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y)))) | |
536 | return false; | |
537 | y = XEXP (x, 1); | |
538 | if (! REG_P (y) | |
539 | && ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y))) | |
540 | && ! CONST_INT_P (y)) | |
541 | return false; | |
542 | } | |
543 | ||
544 | /* LRA will try to satisfy the constraints for the memory displacements | |
545 | and thus we must not reject invalid displacements in the predicate, | |
546 | or else LRA will bail out. | |
547 | FIXME: maybe remove this check completely? */ | |
548 | if (!lra_in_progress && (mode == QImode || mode == HImode) | |
640c5f1f | 549 | && GET_CODE (x) == PLUS |
cb022464 | 550 | && REG_P (XEXP (x, 0)) |
551 | && CONST_INT_P (XEXP (x, 1))) | |
51bc6b40 | 552 | return sh_legitimate_index_p (mode, XEXP (x, 1), TARGET_SH2A, false); |
640c5f1f | 553 | |
554 | /* Allow reg+reg addressing here without validating the register | |
555 | numbers. Usually one of the regs must be R0 or a pseudo reg. | |
556 | In some cases it can happen that arguments from hard regs are | |
557 | propagated directly into address expressions. In this cases reload | |
558 | will have to fix it up later. However, allow this only for native | |
559 | 1, 2 or 4 byte addresses. */ | |
560 | if (can_create_pseudo_p () && GET_CODE (x) == PLUS | |
561 | && GET_MODE_SIZE (mode) <= 4 | |
562 | && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1))) | |
563 | return true; | |
564 | ||
565 | /* 'general_operand' does not allow volatile mems during RTL expansion to | |
566 | avoid matching arithmetic that operates on mems, it seems. | |
567 | On SH this leads to redundant sign extensions for QImode or HImode | |
568 | loads. Thus we mimic the behavior but allow volatile mems. */ | |
569 | if (memory_address_addr_space_p (GET_MODE (mem_rtx), x, | |
570 | MEM_ADDR_SPACE (mem_rtx))) | |
571 | return true; | |
cb022464 | 572 | } |
573 | ||
138814fb | 574 | if (TARGET_SHMEDIA |
575 | && (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR) | |
576 | && sh_rep_vec (op, mode)) | |
577 | return 1; | |
578 | if (TARGET_SHMEDIA && 1 | |
579 | && GET_CODE (op) == SUBREG && GET_MODE (op) == mode | |
580 | && SUBREG_REG (op) == const0_rtx && subreg_lowpart_p (op)) | |
581 | /* FIXME */ abort (); /* return 1; */ | |
640c5f1f | 582 | |
138814fb | 583 | return general_operand (op, mode); |
584 | }) | |
585 | ||
5e8ad22e | 586 | ;; Returns 1 if OP is a MEM that does not use displacement addressing. |
89cace00 | 587 | (define_predicate "movsrc_no_disp_mem_operand" |
5e8ad22e | 588 | (match_code "mem") |
89cace00 | 589 | { |
5e8ad22e | 590 | return general_movsrc_operand (op, mode) && satisfies_constraint_Snd (op); |
89cace00 | 591 | }) |
592 | ||
138814fb | 593 | ;; Returns 1 if OP can be a destination of a move. Same as |
594 | ;; general_operand, but no preinc allowed. | |
138814fb | 595 | (define_predicate "general_movdst_operand" |
596 | (match_code "subreg,reg,mem") | |
597 | { | |
61af3583 | 598 | if (t_reg_operand (op, mode)) |
599 | return 0; | |
600 | ||
81298240 | 601 | if (fpscr_operand (op, mode)) |
602 | return false; | |
603 | ||
3ea038fc | 604 | if (MEM_P (op)) |
605 | { | |
606 | rtx inside = XEXP (op, 0); | |
607 | /* Disallow mems with GBR address here. They have to go through | |
608 | separate special patterns. */ | |
609 | if ((REG_P (inside) && REGNO (inside) == GBR_REG) | |
610 | || (GET_CODE (inside) == PLUS && REG_P (XEXP (inside, 0)) | |
611 | && REGNO (XEXP (inside, 0)) == GBR_REG)) | |
612 | return 0; | |
613 | } | |
614 | ||
138814fb | 615 | /* Only pre dec allowed. */ |
cbb16986 | 616 | if (MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC) |
138814fb | 617 | return 0; |
618 | if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG | |
619 | && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8 | |
278fc7da | 620 | && ! (reload_in_progress || reload_completed)) |
138814fb | 621 | return 0; |
622 | ||
6415e1ab | 623 | if (mode == GET_MODE (op) |
624 | && (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op))))) | |
cb022464 | 625 | { |
6415e1ab | 626 | rtx mem_rtx = MEM_P (op) ? op : SUBREG_REG (op); |
627 | rtx x = XEXP (mem_rtx, 0); | |
cb022464 | 628 | |
3a51c3c9 | 629 | if (! ALLOW_INDEXED_ADDRESS |
630 | && GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1))) | |
631 | return false; | |
632 | ||
ea68d4ba | 633 | if (GET_CODE (x) == PLUS) |
634 | { | |
635 | rtx y = XEXP (x, 0); | |
636 | ||
637 | if (! REG_P (y) | |
638 | && ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y)))) | |
639 | return false; | |
640 | y = XEXP (x, 1); | |
641 | if (! REG_P (y) | |
642 | && ! (GET_CODE (y) == SUBREG && REG_P (SUBREG_REG (y))) | |
643 | && ! CONST_INT_P (y)) | |
644 | return false; | |
645 | } | |
646 | ||
647 | /* LRA will try to satisfy the constraints for the memory displacements | |
648 | and thus we must not reject invalid displacements in the predicate, | |
649 | or else LRA will bail out. | |
650 | FIXME: maybe remove this check completely? */ | |
651 | if (!lra_in_progress && (mode == QImode || mode == HImode) | |
6415e1ab | 652 | && GET_CODE (x) == PLUS |
cb022464 | 653 | && REG_P (XEXP (x, 0)) |
654 | && CONST_INT_P (XEXP (x, 1))) | |
51bc6b40 | 655 | return sh_legitimate_index_p (mode, XEXP (x, 1), TARGET_SH2A, false); |
6415e1ab | 656 | |
657 | /* Allow reg+reg addressing here without validating the register | |
658 | numbers. Usually one of the regs must be R0 or a pseudo reg. | |
659 | In some cases it can happen that arguments from hard regs are | |
660 | propagated directly into address expressions. In this cases reload | |
661 | will have to fix it up later. However, allow this only for native | |
662 | 1, 2 or 4 byte addresses. */ | |
663 | if (can_create_pseudo_p () && GET_CODE (x) == PLUS | |
664 | && GET_MODE_SIZE (mode) <= 4 | |
665 | && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1))) | |
666 | return true; | |
667 | ||
668 | /* 'general_operand' does not allow volatile mems during RTL expansion to | |
669 | avoid matching arithmetic that operates on mems, it seems. | |
670 | On SH this leads to redundant sign extensions for QImode or HImode | |
671 | stores. Thus we mimic the behavior but allow volatile mems. */ | |
672 | if (memory_address_addr_space_p (GET_MODE (mem_rtx), x, | |
673 | MEM_ADDR_SPACE (mem_rtx))) | |
674 | return true; | |
cb022464 | 675 | } |
676 | ||
138814fb | 677 | return general_operand (op, mode); |
678 | }) | |
679 | ||
973cd123 | 680 | ;; Returns 1 if OP is a POST_INC on stack pointer register. |
973cd123 | 681 | (define_predicate "sh_no_delay_pop_operand" |
682 | (match_code "mem") | |
683 | { | |
684 | rtx inside; | |
685 | inside = XEXP (op, 0); | |
686 | ||
687 | if (GET_CODE (op) == MEM && GET_MODE (op) == SImode | |
688 | && GET_CODE (inside) == POST_INC | |
689 | && GET_CODE (XEXP (inside, 0)) == REG | |
690 | && REGNO (XEXP (inside, 0)) == SP_REG) | |
691 | return 1; | |
692 | ||
693 | return 0; | |
694 | }) | |
695 | ||
138814fb | 696 | ;; Returns 1 if OP is a MEM that can be source of a simple move operation. |
138814fb | 697 | (define_predicate "unaligned_load_operand" |
698 | (match_code "mem") | |
699 | { | |
700 | rtx inside; | |
701 | ||
cbb16986 | 702 | if (!MEM_P (op) || GET_MODE (op) != mode) |
138814fb | 703 | return 0; |
704 | ||
705 | inside = XEXP (op, 0); | |
706 | ||
707 | if (GET_CODE (inside) == POST_INC) | |
708 | inside = XEXP (inside, 0); | |
709 | ||
cbb16986 | 710 | if (REG_P (inside)) |
138814fb | 711 | return 1; |
712 | ||
713 | return 0; | |
714 | }) | |
715 | ||
572e04f2 | 716 | ;; Returns 1 if OP is a MEM that can be used in "index_disp" combiner |
717 | ;; patterns. | |
718 | (define_predicate "mem_index_disp_operand" | |
719 | (match_code "mem") | |
720 | { | |
721 | rtx plus0_rtx, plus1_rtx, mult_rtx; | |
722 | ||
723 | plus0_rtx = XEXP (op, 0); | |
724 | if (GET_CODE (plus0_rtx) != PLUS) | |
725 | return 0; | |
726 | ||
727 | plus1_rtx = XEXP (plus0_rtx, 0); | |
728 | if (GET_CODE (plus1_rtx) != PLUS) | |
729 | return 0; | |
26e8d76f | 730 | if (! arith_reg_operand (XEXP (plus1_rtx, 1), GET_MODE (XEXP (plus1_rtx, 1)))) |
731 | return 0; | |
572e04f2 | 732 | |
733 | mult_rtx = XEXP (plus1_rtx, 0); | |
734 | if (GET_CODE (mult_rtx) != MULT) | |
735 | return 0; | |
26e8d76f | 736 | if (! arith_reg_operand (XEXP (mult_rtx, 0), GET_MODE (XEXP (mult_rtx, 0))) |
737 | || ! CONST_INT_P (XEXP (mult_rtx, 1))) | |
738 | return 0; | |
739 | ||
740 | return exact_log2 (INTVAL (XEXP (mult_rtx, 1))) > 0 | |
572e04f2 | 741 | && sh_legitimate_index_p (mode, XEXP (plus0_rtx, 1), TARGET_SH2A, true); |
742 | }) | |
743 | ||
6c049e03 | 744 | ;; Returns true if OP is some kind of greater comparision. |
138814fb | 745 | (define_predicate "greater_comparison_operator" |
9f3fa8ba | 746 | (match_code "gt,ge,gtu,geu")) |
138814fb | 747 | |
6c049e03 | 748 | ;; Returns true if OP is an operand suitable for shmedia reload_inqi and |
749 | ;; reload_inhi insns. | |
138814fb | 750 | (define_predicate "inqhi_operand" |
751 | (match_code "truncate") | |
752 | { | |
753 | if (GET_CODE (op) != TRUNCATE || mode != GET_MODE (op)) | |
754 | return 0; | |
755 | op = XEXP (op, 0); | |
756 | /* Can't use true_regnum here because copy_cost wants to know about | |
757 | SECONDARY_INPUT_RELOAD_CLASS. */ | |
cbb16986 | 758 | return REG_P (op) && FP_REGISTER_P (REGNO (op)); |
138814fb | 759 | }) |
760 | ||
6c049e03 | 761 | ;; Returns true if OP is a general purpose integer register. |
762 | ;; This predicate is currently unused. | |
763 | ;;(define_special_predicate "int_gpr_dest" | |
764 | ;; (match_code "subreg,reg") | |
765 | ;;{ | |
3754d046 | 766 | ;; machine_mode op_mode = GET_MODE (op); |
6c049e03 | 767 | ;; |
768 | ;; if (GET_MODE_CLASS (op_mode) != MODE_INT | |
769 | ;; || GET_MODE_SIZE (op_mode) >= UNITS_PER_WORD) | |
770 | ;; return 0; | |
771 | ;; if (! reload_completed) | |
772 | ;; return 0; | |
773 | ;; return true_regnum (op) <= LAST_GENERAL_REG; | |
774 | ;;}) | |
775 | ||
776 | ;; Returns true if OP is some kind of less comparison. | |
138814fb | 777 | (define_predicate "less_comparison_operator" |
9f3fa8ba | 778 | (match_code "lt,le,ltu,leu")) |
138814fb | 779 | |
780 | ;; Returns 1 if OP is a valid source operand for a logical operation. | |
138814fb | 781 | (define_predicate "logical_operand" |
782 | (match_code "subreg,reg,const_int") | |
783 | { | |
784 | if (TARGET_SHMEDIA | |
785 | && mode != DImode && GET_CODE (op) == SUBREG | |
786 | && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4) | |
787 | return 0; | |
788 | ||
789 | if (arith_reg_operand (op, mode)) | |
790 | return 1; | |
791 | ||
792 | if (TARGET_SHMEDIA) | |
793 | { | |
abff7a2e | 794 | if (satisfies_constraint_I10 (op)) |
138814fb | 795 | return 1; |
796 | else | |
797 | return 0; | |
798 | } | |
abff7a2e | 799 | else if (satisfies_constraint_K08 (op)) |
138814fb | 800 | return 1; |
801 | ||
802 | return 0; | |
803 | }) | |
804 | ||
e13062e7 | 805 | ;; Returns true if OP is a valid constant source operand for a logical |
806 | ;; operations tst/and/or/xor #imm,r0. | |
807 | (define_predicate "const_logical_operand" | |
808 | (and (match_code "const_int") | |
809 | (match_test "satisfies_constraint_K08 (op)"))) | |
810 | ||
48d72ad2 | 811 | ;; Like logical_operand but allows additional constant values which can be |
812 | ;; done with zero extensions. Used for the second operand of and insns. | |
813 | (define_predicate "logical_and_operand" | |
814 | (match_code "subreg,reg,const_int") | |
815 | { | |
816 | if (logical_operand (op, mode)) | |
817 | return 1; | |
818 | ||
819 | if (! TARGET_SHMEDIA | |
820 | && (satisfies_constraint_Jmb (op) || satisfies_constraint_Jmw (op))) | |
821 | return 1; | |
822 | ||
823 | return 0; | |
824 | }) | |
825 | ||
6c049e03 | 826 | ;; Returns true if OP is a logical operator. |
138814fb | 827 | (define_predicate "logical_operator" |
9f3fa8ba | 828 | (match_code "and,ior,xor")) |
138814fb | 829 | |
830 | ;; Like arith_reg_operand, but for register source operands of narrow | |
831 | ;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs. | |
138814fb | 832 | (define_predicate "logical_reg_operand" |
833 | (match_code "subreg,reg") | |
834 | { | |
835 | if (TARGET_SHMEDIA | |
836 | && GET_CODE (op) == SUBREG | |
837 | && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4 | |
838 | && mode != DImode) | |
839 | return 0; | |
840 | return arith_reg_operand (op, mode); | |
841 | }) | |
842 | ||
6c049e03 | 843 | ;; Returns true if OP is a valid bit offset value for the shmedia mextr insns. |
138814fb | 844 | (define_predicate "mextr_bit_offset" |
845 | (match_code "const_int") | |
846 | { | |
847 | HOST_WIDE_INT i; | |
848 | ||
cbb16986 | 849 | if (!CONST_INT_P (op)) |
138814fb | 850 | return 0; |
851 | i = INTVAL (op); | |
852 | return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0; | |
853 | }) | |
854 | ||
6c049e03 | 855 | ;; Returns true if OP is a constant -1, 0 or an zero extended register that |
856 | ;; can be used as an operator in the *subsi3_media insn. | |
138814fb | 857 | (define_predicate "minuend_operand" |
858 | (match_code "subreg,reg,truncate,const_int") | |
859 | { | |
860 | return op == constm1_rtx || extend_reg_or_0_operand (op, mode); | |
861 | }) | |
862 | ||
6c049e03 | 863 | ;; Returns true if OP is a noncommutative floating point operator. |
864 | ;; This predicate is currently unused. | |
865 | ;;(define_predicate "noncommutative_float_operator" | |
866 | ;; (and (match_code "minus,div") | |
867 | ;; (match_test "GET_MODE (op) == mode"))) | |
138814fb | 868 | |
74f4459c | 869 | ;; UNORDERED is only supported on SHMEDIA. |
870 | ||
871 | (define_predicate "sh_float_comparison_operator" | |
872 | (ior (match_operand 0 "ordered_comparison_operator") | |
873 | (and (match_test "TARGET_SHMEDIA") | |
874 | (match_code "unordered")))) | |
875 | ||
876 | (define_predicate "shmedia_cbranch_comparison_operator" | |
877 | (ior (match_operand 0 "equality_comparison_operator") | |
878 | (match_operand 0 "greater_comparison_operator"))) | |
879 | ||
6c049e03 | 880 | ;; Returns true if OP is a constant vector. |
138814fb | 881 | (define_predicate "sh_const_vec" |
882 | (match_code "const_vector") | |
883 | { | |
884 | int i; | |
885 | ||
886 | if (GET_CODE (op) != CONST_VECTOR | |
887 | || (GET_MODE (op) != mode && mode != VOIDmode)) | |
888 | return 0; | |
889 | i = XVECLEN (op, 0) - 1; | |
890 | for (; i >= 0; i--) | |
cbb16986 | 891 | if (!CONST_INT_P (XVECEXP (op, 0, i))) |
138814fb | 892 | return 0; |
893 | return 1; | |
894 | }) | |
895 | ||
896 | ;; Determine if OP is a constant vector matching MODE with only one | |
897 | ;; element that is not a sign extension. Two byte-sized elements | |
898 | ;; count as one. | |
138814fb | 899 | (define_predicate "sh_1el_vec" |
900 | (match_code "const_vector") | |
901 | { | |
902 | int unit_size; | |
903 | int i, last, least, sign_ix; | |
904 | rtx sign; | |
905 | ||
906 | if (GET_CODE (op) != CONST_VECTOR | |
907 | || (GET_MODE (op) != mode && mode != VOIDmode)) | |
908 | return 0; | |
909 | /* Determine numbers of last and of least significant elements. */ | |
910 | last = XVECLEN (op, 0) - 1; | |
911 | least = TARGET_LITTLE_ENDIAN ? 0 : last; | |
cbb16986 | 912 | if (!CONST_INT_P (XVECEXP (op, 0, least))) |
138814fb | 913 | return 0; |
914 | sign_ix = least; | |
915 | if (GET_MODE_UNIT_SIZE (mode) == 1) | |
916 | sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1; | |
cbb16986 | 917 | if (!CONST_INT_P (XVECEXP (op, 0, sign_ix))) |
138814fb | 918 | return 0; |
919 | unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op)); | |
920 | sign = (INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1) | |
921 | ? constm1_rtx : const0_rtx); | |
922 | i = XVECLEN (op, 0) - 1; | |
923 | do | |
924 | if (i != least && i != sign_ix && XVECEXP (op, 0, i) != sign) | |
925 | return 0; | |
926 | while (--i); | |
927 | return 1; | |
928 | }) | |
929 | ||
930 | ;; Like register_operand, but take into account that SHMEDIA can use | |
931 | ;; the constant zero like a general register. | |
138814fb | 932 | (define_predicate "sh_register_operand" |
81aeb577 | 933 | (match_code "reg,subreg,const_int,const_double") |
138814fb | 934 | { |
935 | if (op == CONST0_RTX (mode) && TARGET_SHMEDIA) | |
936 | return 1; | |
937 | return register_operand (op, mode); | |
938 | }) | |
939 | ||
6c049e03 | 940 | ;; Returns true if OP is a vector which is composed of one element that is |
941 | ;; repeated. | |
138814fb | 942 | (define_predicate "sh_rep_vec" |
5a9f17cc | 943 | (match_code "const_vector,parallel") |
138814fb | 944 | { |
945 | int i; | |
946 | rtx x, y; | |
947 | ||
948 | if ((GET_CODE (op) != CONST_VECTOR && GET_CODE (op) != PARALLEL) | |
949 | || (GET_MODE (op) != mode && mode != VOIDmode)) | |
950 | return 0; | |
951 | i = XVECLEN (op, 0) - 2; | |
952 | x = XVECEXP (op, 0, i + 1); | |
953 | if (GET_MODE_UNIT_SIZE (mode) == 1) | |
954 | { | |
955 | y = XVECEXP (op, 0, i); | |
956 | for (i -= 2; i >= 0; i -= 2) | |
957 | if (! rtx_equal_p (XVECEXP (op, 0, i + 1), x) | |
958 | || ! rtx_equal_p (XVECEXP (op, 0, i), y)) | |
959 | return 0; | |
960 | } | |
961 | else | |
962 | for (; i >= 0; i--) | |
963 | if (XVECEXP (op, 0, i) != x) | |
964 | return 0; | |
965 | return 1; | |
966 | }) | |
967 | ||
6c049e03 | 968 | ;; Returns true if OP is a valid shift count operand for shift operations. |
138814fb | 969 | (define_predicate "shift_count_operand" |
6c049e03 | 970 | (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg, |
971 | zero_extend,sign_extend") | |
138814fb | 972 | { |
bb8e9728 | 973 | /* Allow T_REG as shift count for dynamic shifts, although it is not |
974 | really possible. It will then be copied to a general purpose reg. */ | |
975 | if (! TARGET_SHMEDIA) | |
6e7c6395 | 976 | return const_int_operand (op, mode) || arith_reg_operand (op, mode) |
977 | || (TARGET_DYNSHIFT && t_reg_operand (op, mode)); | |
bb8e9728 | 978 | |
138814fb | 979 | return (CONSTANT_P (op) |
cbb16986 | 980 | ? (CONST_INT_P (op) |
138814fb | 981 | ? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode) |
982 | : nonmemory_operand (op, mode)) | |
983 | : shift_count_reg_operand (op, mode)); | |
984 | }) | |
985 | ||
6c049e03 | 986 | ;; Returns true if OP is a valid shift count operand in a register which can |
987 | ;; be used by shmedia shift insns. | |
138814fb | 988 | (define_predicate "shift_count_reg_operand" |
989 | (match_code "subreg,reg,zero_extend,sign_extend") | |
990 | { | |
991 | if ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND | |
992 | || (GET_CODE (op) == SUBREG && SUBREG_BYTE (op) == 0)) | |
993 | && (mode == VOIDmode || mode == GET_MODE (op)) | |
994 | && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6 | |
995 | && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT) | |
996 | { | |
997 | mode = VOIDmode; | |
998 | do | |
999 | op = XEXP (op, 0); | |
1000 | while ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND | |
1001 | || GET_CODE (op) == TRUNCATE) | |
1002 | && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6 | |
1003 | && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT); | |
1004 | ||
1005 | } | |
1006 | return arith_reg_operand (op, mode); | |
1007 | }) | |
1008 | ||
be3ab97a | 1009 | ;; Predicates for matching operands that are constant shift |
1010 | ;; amounts 1, 2, 8, 16. | |
bb8e9728 | 1011 | (define_predicate "p27_shift_count_operand" |
1012 | (and (match_code "const_int") | |
1013 | (match_test "satisfies_constraint_P27 (op)"))) | |
1014 | ||
1015 | (define_predicate "not_p27_shift_count_operand" | |
1016 | (and (match_code "const_int") | |
1017 | (match_test "! satisfies_constraint_P27 (op)"))) | |
1018 | ||
be3ab97a | 1019 | ;; For right shifts the constant 1 is a special case because the shlr insn |
1020 | ;; clobbers the T_REG and is handled by the T_REG clobbering version of the | |
1021 | ;; insn, which is also used for non-P27 shift sequences. | |
1022 | (define_predicate "p27_rshift_count_operand" | |
1023 | (and (match_code "const_int") | |
1024 | (match_test "satisfies_constraint_P27 (op)") | |
1025 | (match_test "! satisfies_constraint_M (op)"))) | |
1026 | ||
1027 | (define_predicate "not_p27_rshift_count_operand" | |
1028 | (and (match_code "const_int") | |
1029 | (ior (match_test "! satisfies_constraint_P27 (op)") | |
1030 | (match_test "satisfies_constraint_M (op)")))) | |
1031 | ||
6c049e03 | 1032 | ;; Returns true if OP is some kind of a shift operator. |
138814fb | 1033 | (define_predicate "shift_operator" |
9f3fa8ba | 1034 | (match_code "ashift,ashiftrt,lshiftrt")) |
138814fb | 1035 | |
6c049e03 | 1036 | ;; Returns true if OP is a symbol reference. |
138814fb | 1037 | (define_predicate "symbol_ref_operand" |
9f3fa8ba | 1038 | (match_code "symbol_ref")) |
138814fb | 1039 | |
1040 | ;; Same as target_reg_operand, except that label_refs and symbol_refs | |
1041 | ;; are accepted before reload. | |
138814fb | 1042 | (define_special_predicate "target_operand" |
1043 | (match_code "subreg,reg,label_ref,symbol_ref,const,unspec") | |
1044 | { | |
1045 | if (mode != VOIDmode && mode != Pmode) | |
1046 | return 0; | |
1047 | ||
1048 | if ((GET_MODE (op) == Pmode || GET_MODE (op) == VOIDmode) | |
abff7a2e | 1049 | && satisfies_constraint_Csy (op)) |
138814fb | 1050 | return ! reload_completed; |
1051 | ||
1052 | return target_reg_operand (op, mode); | |
1053 | }) | |
1054 | ||
6c049e03 | 1055 | ;; A predicate that accepts pseudos and branch target registers. |
138814fb | 1056 | (define_special_predicate "target_reg_operand" |
1057 | (match_code "subreg,reg") | |
1058 | { | |
1059 | if (mode == VOIDmode | |
1060 | ? GET_MODE (op) != Pmode && GET_MODE (op) != PDImode | |
1061 | : mode != GET_MODE (op)) | |
1062 | return 0; | |
1063 | ||
1064 | if (GET_CODE (op) == SUBREG) | |
1065 | op = XEXP (op, 0); | |
1066 | ||
cbb16986 | 1067 | if (!REG_P (op)) |
138814fb | 1068 | return 0; |
1069 | ||
1070 | /* We must protect ourselves from matching pseudos that are virtual | |
1071 | register, because they will eventually be replaced with hardware | |
1072 | registers that aren't branch-target registers. */ | |
1073 | if (REGNO (op) > LAST_VIRTUAL_REGISTER | |
1074 | || TARGET_REGISTER_P (REGNO (op))) | |
1075 | return 1; | |
1076 | ||
1077 | return 0; | |
1078 | }) | |
1079 | ||
6c049e03 | 1080 | ;; Returns true if OP is a valid operand for the shmedia mperm.w insn. |
138814fb | 1081 | (define_special_predicate "trunc_hi_operand" |
1082 | (match_code "subreg,reg,truncate") | |
1083 | { | |
3754d046 | 1084 | machine_mode op_mode = GET_MODE (op); |
138814fb | 1085 | |
1086 | if (op_mode != SImode && op_mode != DImode | |
1087 | && op_mode != V4HImode && op_mode != V2SImode) | |
1088 | return 0; | |
1089 | return extend_reg_operand (op, mode); | |
1090 | }) | |
1091 | ||
6c049e03 | 1092 | ;; Returns true if OP is an address suitable for an unaligned access |
1093 | ;; instruction. | |
3d533137 | 1094 | (define_special_predicate "ua_address_operand" |
138814fb | 1095 | (match_code "subreg,reg,plus") |
1096 | { | |
1097 | if (GET_CODE (op) == PLUS | |
abff7a2e | 1098 | && (! satisfies_constraint_I06 (XEXP (op, 1)))) |
138814fb | 1099 | return 0; |
1100 | return address_operand (op, QImode); | |
1101 | }) | |
1102 | ||
6c049e03 | 1103 | ;; Returns true if OP is a valid offset for an unaligned memory address. |
138814fb | 1104 | (define_predicate "ua_offset" |
1105 | (match_code "const_int") | |
1106 | { | |
abff7a2e | 1107 | return satisfies_constraint_I06 (op); |
138814fb | 1108 | }) |
1109 | ||
6c049e03 | 1110 | ;; Returns true if OP is a floating point operator with one operand. |
138814fb | 1111 | (define_predicate "unary_float_operator" |
9f3fa8ba | 1112 | (and (match_code "abs,neg,sqrt") |
1113 | (match_test "GET_MODE (op) == mode"))) | |
138814fb | 1114 | |
1115 | ;; Return 1 if OP is a valid source operand for xor. | |
138814fb | 1116 | (define_predicate "xor_operand" |
1117 | (match_code "subreg,reg,const_int") | |
1118 | { | |
cbb16986 | 1119 | if (CONST_INT_P (op)) |
138814fb | 1120 | return (TARGET_SHMEDIA |
abff7a2e | 1121 | ? (satisfies_constraint_I06 (op) |
e1ba4a27 | 1122 | || (!can_create_pseudo_p () && INTVAL (op) == 0xff)) |
abff7a2e | 1123 | : satisfies_constraint_K08 (op)); |
138814fb | 1124 | if (TARGET_SHMEDIA |
1125 | && mode != DImode && GET_CODE (op) == SUBREG | |
1126 | && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4) | |
1127 | return 0; | |
1128 | return arith_reg_operand (op, mode); | |
1129 | }) | |
96a7f216 | 1130 | |
1131 | (define_predicate "bitwise_memory_operand" | |
1132 | (match_code "mem") | |
1133 | { | |
cbb16986 | 1134 | if (MEM_P (op)) |
96a7f216 | 1135 | { |
1136 | if (REG_P (XEXP (op, 0))) | |
1137 | return 1; | |
1138 | ||
1139 | if (GET_CODE (XEXP (op, 0)) == PLUS | |
cbb16986 | 1140 | && REG_P (XEXP (XEXP (op, 0), 0)) |
96a7f216 | 1141 | && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1))) |
1142 | return 1; | |
1143 | } | |
1144 | return 0; | |
1145 | }) | |
e10782c9 | 1146 | |
6c97af1b | 1147 | ;; A predicate that matches any expression for which there is an |
1148 | ;; insn pattern that sets the T bit. | |
1149 | (define_predicate "treg_set_expr" | |
1150 | (match_test "sh_recog_treg_set_expr (op, mode)")) | |
1151 | ||
1152 | ;; Same as treg_set_expr but disallow constants 0 and 1 which can be loaded | |
1153 | ;; into the T bit. | |
1154 | (define_predicate "treg_set_expr_not_const01" | |
1155 | (and (match_test "op != const0_rtx") | |
1156 | (match_test "op != const1_rtx") | |
1157 | (match_operand 0 "treg_set_expr"))) | |
1158 | ||
a6be7821 | 1159 | ;; A predicate describing the T bit register in any form. |
1160 | (define_predicate "t_reg_operand" | |
a6753a08 | 1161 | (match_code "reg,subreg,sign_extend,zero_extend,ne,eq") |
a6be7821 | 1162 | { |
1163 | switch (GET_CODE (op)) | |
1164 | { | |
a6753a08 | 1165 | case EQ: |
1166 | return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0))) | |
1167 | && XEXP (op, 1) == const1_rtx; | |
1168 | ||
1169 | case NE: | |
1170 | return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0))) | |
1171 | && XEXP (op, 1) == const0_rtx; | |
1172 | ||
a6be7821 | 1173 | case REG: |
1174 | return REGNO (op) == T_REG; | |
1175 | ||
1176 | case SUBREG: | |
c53274a5 | 1177 | return REG_P (SUBREG_REG (op)) && REGNO (SUBREG_REG (op)) == T_REG; |
a6be7821 | 1178 | |
1179 | case ZERO_EXTEND: | |
1180 | case SIGN_EXTEND: | |
ea68d4ba | 1181 | if (REG_P (XEXP (op, 0)) && REGNO (XEXP (op, 0)) == T_REG) |
1182 | return true; | |
a6be7821 | 1183 | return GET_CODE (XEXP (op, 0)) == SUBREG |
c53274a5 | 1184 | && REG_P (SUBREG_REG (XEXP (op, 0))) |
a6be7821 | 1185 | && REGNO (SUBREG_REG (XEXP (op, 0))) == T_REG; |
1186 | ||
1187 | default: | |
1188 | return 0; | |
1189 | } | |
1190 | }) | |
1191 | ||
1192 | ;; A predicate describing a negated T bit register. | |
1193 | (define_predicate "negt_reg_operand" | |
a6753a08 | 1194 | (match_code "subreg,xor,ne,eq") |
a6be7821 | 1195 | { |
1196 | switch (GET_CODE (op)) | |
1197 | { | |
a6753a08 | 1198 | case EQ: |
1199 | return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0))) | |
1200 | && XEXP (op, 1) == const0_rtx; | |
1201 | ||
1202 | case NE: | |
1203 | return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0))) | |
1204 | && XEXP (op, 1) == const1_rtx; | |
1205 | ||
a6be7821 | 1206 | case XOR: |
1207 | return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0))) | |
a6753a08 | 1208 | && XEXP (op, 1) == const1_rtx; |
a6be7821 | 1209 | |
1210 | case SUBREG: | |
1211 | return negt_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0))); | |
1212 | ||
1213 | default: | |
1214 | return 0; | |
1215 | } | |
1216 | }) | |
1e94341b | 1217 | |
21910658 | 1218 | ;; A predicate that returns true if OP is a valid construct around the T bit |
1219 | ;; that can be used as an operand for conditional branches. | |
1220 | (define_predicate "cbranch_treg_value" | |
a02ddf20 | 1221 | (and (match_code "eq,ne,reg,subreg,xor,sign_extend,zero_extend") |
1222 | (match_test "sh_eval_treg_value (op) >= 0"))) | |
21910658 | 1223 | |
6c049e03 | 1224 | ;; Returns true if OP is arith_reg_operand or t_reg_operand. |
1e94341b | 1225 | (define_predicate "arith_reg_or_t_reg_operand" |
1226 | (ior (match_operand 0 "arith_reg_operand") | |
1227 | (match_operand 0 "t_reg_operand"))) | |
4d6e7ebc | 1228 | |
6c97af1b | 1229 | (define_predicate "arith_reg_or_treg_set_expr" |
1230 | (ior (match_operand 0 "arith_reg_operand") | |
1231 | (match_operand 0 "treg_set_expr"))) | |
1232 | ||
4d6e7ebc | 1233 | ;; A predicate describing the negated value of the T bit register shifted |
1234 | ;; left by 31. | |
1235 | (define_predicate "negt_reg_shl31_operand" | |
1236 | (match_code "plus,minus,if_then_else") | |
1237 | { | |
25cc2065 | 1238 | /* (minus:SI (const_int -2147483648) ;; 0xffffffff80000000 |
1239 | (ashift:SI (match_operand:SI 1 "t_reg_operand") | |
1240 | (const_int 31))) | |
1241 | */ | |
1242 | if (GET_CODE (op) == MINUS && satisfies_constraint_Jhb (XEXP (op, 0)) | |
1243 | && GET_CODE (XEXP (op, 1)) == ASHIFT | |
1244 | && t_reg_operand (XEXP (XEXP (op, 1), 0), SImode) | |
1245 | && CONST_INT_P (XEXP (XEXP (op, 1), 1)) | |
1246 | && INTVAL (XEXP (XEXP (op, 1), 1)) == 31) | |
1247 | return true; | |
1248 | ||
1249 | /* (plus:SI (ashift:SI (match_operand:SI 1 "t_reg_operand") | |
1250 | (const_int 31)) | |
1251 | (const_int -2147483648)) ;; 0xffffffff80000000 | |
1252 | */ | |
1253 | if (GET_CODE (op) == PLUS && satisfies_constraint_Jhb (XEXP (op, 1)) | |
1254 | && GET_CODE (XEXP (op, 0)) == ASHIFT | |
1255 | && t_reg_operand (XEXP (XEXP (op, 0), 0), SImode) | |
1256 | && CONST_INT_P (XEXP (XEXP (op, 0), 1)) | |
1257 | && INTVAL (XEXP (XEXP (op, 0), 1)) == 31) | |
1258 | return true; | |
1259 | ||
4d6e7ebc | 1260 | /* (plus:SI (mult:SI (match_operand:SI 1 "t_reg_operand") |
1261 | (const_int -2147483648)) ;; 0xffffffff80000000 | |
1262 | (const_int -2147483648)) | |
1263 | */ | |
1264 | if (GET_CODE (op) == PLUS && satisfies_constraint_Jhb (XEXP (op, 1)) | |
1265 | && GET_CODE (XEXP (op, 0)) == MULT | |
1266 | && t_reg_operand (XEXP (XEXP (op, 0), 0), SImode) | |
1267 | && satisfies_constraint_Jhb (XEXP (XEXP (op, 0), 1))) | |
1268 | return true; | |
1269 | ||
1270 | /* (minus:SI (const_int -2147483648) ;; 0xffffffff80000000 | |
1271 | (mult:SI (match_operand:SI 1 "t_reg_operand") | |
1272 | (const_int -2147483648))) | |
1273 | */ | |
1274 | if (GET_CODE (op) == MINUS | |
1275 | && satisfies_constraint_Jhb (XEXP (op, 0)) | |
1276 | && GET_CODE (XEXP (op, 1)) == MULT | |
1277 | && t_reg_operand (XEXP (XEXP (op, 1), 0), SImode) | |
1278 | && satisfies_constraint_Jhb (XEXP (XEXP (op, 1), 1))) | |
1279 | return true; | |
1280 | ||
1281 | /* (if_then_else:SI (match_operand:SI 1 "t_reg_operand") | |
1282 | (const_int 0) | |
1283 | (const_int -2147483648)) ;; 0xffffffff80000000 | |
1284 | */ | |
1285 | if (GET_CODE (op) == IF_THEN_ELSE && t_reg_operand (XEXP (op, 0), SImode) | |
1286 | && satisfies_constraint_Z (XEXP (op, 1)) | |
1287 | && satisfies_constraint_Jhb (XEXP (op, 2))) | |
1288 | return true; | |
1289 | ||
1290 | return false; | |
1291 | }) | |
7928e854 | 1292 | |
1293 | ;; A predicate that determines whether a given constant is a valid | |
6c049e03 | 1294 | ;; displacement for a GBR load/store of the specified mode. |
7928e854 | 1295 | (define_predicate "gbr_displacement" |
1296 | (match_code "const_int") | |
1297 | { | |
1298 | const int mode_sz = GET_MODE_SIZE (mode); | |
1299 | const int move_sz = mode_sz > GET_MODE_SIZE (SImode) | |
1300 | ? GET_MODE_SIZE (SImode) | |
1301 | : mode_sz; | |
1302 | int max_disp = 255 * move_sz; | |
1303 | if (mode_sz > move_sz) | |
1304 | max_disp -= mode_sz - move_sz; | |
1305 | ||
1306 | return INTVAL (op) >= 0 && INTVAL (op) <= max_disp; | |
1307 | }) | |
8b6f9b96 | 1308 | |
1309 | ;; A predicate that determines whether OP is a valid GBR addressing mode | |
1310 | ;; memory reference. | |
1311 | (define_predicate "gbr_address_mem" | |
1312 | (match_code "mem") | |
1313 | { | |
1314 | rtx addr = XEXP (op, 0); | |
1315 | ||
1316 | if (REG_P (addr) && REGNO (addr) == GBR_REG) | |
1317 | return true; | |
1318 | if (GET_CODE (addr) == PLUS | |
1319 | && REG_P (XEXP (addr, 0)) && REGNO (XEXP (addr, 0)) == GBR_REG | |
1320 | && gbr_displacement (XEXP (addr, 1), mode)) | |
1321 | return true; | |
1322 | ||
1323 | return false; | |
1324 | }) |