]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/sh/predicates.md
revert: lra-spills.c (lra_final_code_change): Remove useless move insns.
[thirdparty/gcc.git] / gcc / config / sh / predicates.md
CommitLineData
5546ac90 1;; Predicate definitions for Renesas / SuperH SH.
d1e082c2 2;; Copyright (C) 2005-2013 Free Software Foundation, Inc.
5546ac90
KH
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
2f83c7d6 8;; the Free Software Foundation; either version 3, or (at your option)
5546ac90
KH
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
2f83c7d6
NC
17;; along with GCC; see the file COPYING3. If not see
18;; <http://www.gnu.org/licenses/>.
5546ac90
KH
19
20;; TODO: Add a comment here.
73a4d10b
R
21(define_predicate "trapping_target_operand"
22 (match_code "if_then_else")
23{
5a82ecd9 24 rtx cond, mem, res, tar, and_expr;
73a4d10b
R
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);
f3536097 31 if (!MEM_P (mem)
73a4d10b
R
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);
32a7ab3d 41 if (!satisfies_constraint_Csy (tar))
73a4d10b
R
42 return 0;
43 if (GET_CODE (tar) == CONST)
44 tar = XEXP (tar, 0);
45 }
46 else if (!arith_reg_operand (tar, VOIDmode)
32a7ab3d 47 && ! satisfies_constraint_Csy (tar))
73a4d10b
R
48 return 0;
49 if (GET_CODE (cond) != EQ)
50 return 0;
5a82ecd9
ILT
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))
f3536097 55 && CONST_INT_P (XEXP (cond, 1))
5a82ecd9 56 && INTVAL (XEXP (and_expr, 1)) == 3
73a4d10b
R
57 && INTVAL (XEXP (cond, 1)) == 3);
58})
5546ac90 59
50fe8924 60;; A logical operand that can be used in an shmedia and insn.
5546ac90
KH
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
32a7ab3d 70 && satisfies_constraint_J16 (op))
5546ac90
KH
71 return 1;
72
73 return 0;
74})
75
c2acaf06
KH
76;; Like arith_reg_dest, but this predicate is defined with
77;; define_special_predicate, not define_predicate.
5546ac90
KH
78(define_special_predicate "any_arith_reg_dest"
79 (match_code "subreg,reg")
80{
81 return arith_reg_dest (op, mode);
82})
83
c2acaf06
KH
84;; Like register_operand, but this predicate is defined with
85;; define_special_predicate, not define_predicate.
5546ac90
KH
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.
5546ac90
KH
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
32a7ab3d 102 signed 16-bit here, but this causes reload_cse to crash when
5546ac90
KH
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. */
f3536097 106 if (CONST_INT_P (op)
32a7ab3d 107 || satisfies_constraint_Css (op))
5546ac90
KH
108 return 1;
109 else if (GET_CODE (op) == TRUNCATE
f3536097 110 && REG_P (XEXP (op, 0))
5546ac90
KH
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 }
32a7ab3d 121 else if (satisfies_constraint_I08 (op))
5546ac90
KH
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.
5546ac90
KH
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.
5546ac90
KH
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
f3536097 148 if (REG_P (op))
5546ac90 149 regno = REGNO (op);
f3536097 150 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
5546ac90
KH
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)
0e26cf79 157 && regno != FPUL_REG
5546ac90
KH
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
f3536097 171 && REG_P (XEXP (op, 0))
5546ac90
KH
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
185;; Returns 1 if OP is a valid source operand for a compare insn.
5546ac90
KH
186(define_predicate "arith_reg_or_0_operand"
187 (match_code "subreg,reg,const_int,const_vector")
188{
189 if (arith_reg_operand (op, mode))
190 return 1;
191
32a7ab3d 192 if (satisfies_constraint_Z (op))
5546ac90
KH
193 return 1;
194
195 return 0;
196})
197
2353515d
OE
198;; Returns true if OP is either a register or constant 0 or constant 1.
199(define_predicate "arith_reg_or_0_or_1_operand"
200 (match_code "subreg,reg,const_int,const_vector")
201{
202 return arith_reg_or_0_operand (op, mode) || satisfies_constraint_M (op);
203})
204
205;; Returns true if OP is a suitable constant for the minimum value of a
206;; clips.b or clips.w insn.
207(define_predicate "clips_min_const_int"
208 (and (match_code "const_int")
209 (ior (match_test "INTVAL (op) == -128")
210 (match_test "INTVAL (op) == -32768"))))
211
212;; Returns true if OP is a suitable constant for the maximum value of a
213;; clips.b or clips.w insn.
214(define_predicate "clips_max_const_int"
215 (and (match_code "const_int")
216 (ior (match_test "INTVAL (op) == 127")
217 (match_test "INTVAL (op) == 32767"))))
218
219;; Returns true if OP is a suitable constant for the maximum value of a
220;; clipu.b or clipu.w insn.
221(define_predicate "clipu_max_const_int"
222 (and (match_code "const_int")
223 (ior (match_test "INTVAL (op) == 255")
224 (match_test "INTVAL (op) == 65535"))))
225
50fe8924 226;; Returns 1 if OP is a floating point operator with two operands.
5546ac90 227(define_predicate "binary_float_operator"
f289c6a1
KH
228 (and (match_code "plus,minus,mult,div")
229 (match_test "GET_MODE (op) == mode")))
5546ac90 230
50fe8924 231;; Returns 1 if OP is a logical operator with two operands.
5546ac90 232(define_predicate "binary_logical_operator"
f289c6a1
KH
233 (and (match_code "and,ior,xor")
234 (match_test "GET_MODE (op) == mode")))
5546ac90 235
50fe8924 236;; Return 1 if OP is an address suitable for a cache manipulation operation.
f705a9a0 237;; MODE has the meaning as in address_operand.
f705a9a0 238(define_special_predicate "cache_address_operand"
5546ac90
KH
239 (match_code "plus,reg")
240{
241 if (GET_CODE (op) == PLUS)
242 {
f3536097 243 if (!REG_P (XEXP (op, 0)))
5546ac90 244 return 0;
f3536097 245 if (!CONST_INT_P (XEXP (op, 1))
5546ac90
KH
246 || (INTVAL (XEXP (op, 1)) & 31))
247 return 0;
248 }
f3536097 249 else if (!REG_P (op))
5546ac90
KH
250 return 0;
251 return address_operand (op, mode);
252})
253
50fe8924 254;; Returns 1 if OP is a valid source operand for shmedia cmpgt / cmpgtu.
5546ac90
KH
255(define_predicate "cmp_operand"
256 (match_code "subreg,reg,const_int")
257{
32a7ab3d 258 if (satisfies_constraint_N (op))
5546ac90
KH
259 return 1;
260 if (TARGET_SHMEDIA
261 && mode != DImode && GET_CODE (op) == SUBREG
262 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
263 return 0;
264 return arith_reg_operand (op, mode);
265})
266
50fe8924
OE
267;; Returns true if OP is an operand that can be used as the first operand in
268;; the cstoresi4 expander pattern.
5546ac90
KH
269(define_predicate "cmpsi_operand"
270 (match_code "subreg,reg,const_int")
271{
f3536097 272 if (REG_P (op) && REGNO (op) == T_REG
5546ac90
KH
273 && GET_MODE (op) == SImode
274 && TARGET_SH1)
275 return 1;
276 return arith_operand (op, mode);
277})
278
50fe8924
OE
279;; Returns true if OP is a comutative float operator.
280;; This predicate is currently unused.
281;;(define_predicate "commutative_float_operator"
282;; (and (match_code "plus,mult")
283;; (match_test "GET_MODE (op) == mode")))
5546ac90 284
50fe8924 285;; Returns true if OP is a equal or not equal operator.
5546ac90 286(define_predicate "equality_comparison_operator"
f289c6a1 287 (match_code "eq,ne"))
5546ac90 288
50fe8924
OE
289;; Returns true if OP is an arithmetic operand that is zero extended during
290;; an operation.
5546ac90
KH
291(define_predicate "extend_reg_operand"
292 (match_code "subreg,reg,truncate")
293{
294 return (GET_CODE (op) == TRUNCATE
295 ? arith_operand
296 : arith_reg_operand) (op, mode);
297})
298
50fe8924 299;; Like extend_reg_operand, but also allow a constant 0.
5546ac90
KH
300(define_predicate "extend_reg_or_0_operand"
301 (match_code "subreg,reg,truncate,const_int")
302{
303 return (GET_CODE (op) == TRUNCATE
304 ? arith_operand
305 : arith_reg_or_0_operand) (op, mode);
306})
307
308;; Like arith_reg_operand, but this predicate does not accept SIGN_EXTEND.
5546ac90
KH
309(define_predicate "ext_dest_operand"
310 (match_code "subreg,reg")
311{
312 return arith_reg_operand (op, mode);
313})
314
50fe8924
OE
315;; Returns true if OP can be used as a destination register for shmedia floating
316;; point to integer conversions.
5546ac90
KH
317(define_predicate "fp_arith_reg_dest"
318 (match_code "subreg,reg")
319{
320 if (mode == DImode && GET_CODE (op) == SUBREG
321 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8)
322 return 0;
323 return fp_arith_reg_operand (op, mode);
324})
325
50fe8924
OE
326;; Returns true if OP is a floating point register that can be used in floating
327;; point arithmetic operations.
5546ac90
KH
328(define_predicate "fp_arith_reg_operand"
329 (match_code "subreg,reg")
330{
331 if (register_operand (op, mode))
332 {
333 int regno;
334
f3536097 335 if (REG_P (op))
5546ac90 336 regno = REGNO (op);
f3536097 337 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
5546ac90
KH
338 regno = REGNO (SUBREG_REG (op));
339 else
340 return 1;
341
342 return (regno >= FIRST_PSEUDO_REGISTER
343 || FP_REGISTER_P (regno));
344 }
345 return 0;
346})
347
50fe8924 348;; Returns true if OP is the FPSCR.
5546ac90
KH
349(define_predicate "fpscr_operand"
350 (match_code "reg")
351{
f3536097 352 return (REG_P (op)
5546ac90
KH
353 && (REGNO (op) == FPSCR_REG
354 || (REGNO (op) >= FIRST_PSEUDO_REGISTER
355 && !(reload_in_progress || reload_completed)))
356 && GET_MODE (op) == PSImode);
357})
358
db292b0e
OE
359;; Returns true if OP is an operand that is either the fpul hard reg or
360;; a pseudo. This prevents combine from propagating function arguments
361;; in hard regs into insns that need the operand in fpul. If it's a pseudo
362;; reload can fix it up.
5546ac90
KH
363(define_predicate "fpul_operand"
364 (match_code "reg")
365{
366 if (TARGET_SHMEDIA)
367 return fp_arith_reg_operand (op, mode);
368
f3536097 369 return (REG_P (op)
5546ac90
KH
370 && (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER)
371 && GET_MODE (op) == mode);
372})
373
db292b0e
OE
374;; Returns true if OP is a valid fpul input operand for the fsca insn.
375;; The value in fpul is a fixed-point value and its scaling is described
376;; in the fsca insn by a mult:SF. To allow pre-scaled fixed-point inputs
377;; in fpul we have to permit things like
378;; (reg:SI)
379;; (fix:SF (float:SF (reg:SI)))
380(define_predicate "fpul_fsca_operand"
381 (match_code "fix,reg")
382{
383 if (fpul_operand (op, SImode))
384 return true;
385 if (GET_CODE (op) == FIX && GET_MODE (op) == SImode
386 && GET_CODE (XEXP (op, 0)) == FLOAT && GET_MODE (XEXP (op, 0)) == SFmode)
387 return fpul_fsca_operand (XEXP (XEXP (op, 0), 0),
388 GET_MODE (XEXP (XEXP (op, 0), 0)));
389 return false;
390})
391
392;; Returns true if OP is a valid constant scale factor for the fsca insn.
393(define_predicate "fsca_scale_factor"
394 (and (match_code "const_double")
395 (match_test "op == sh_fsca_int2sf ()")))
396
50fe8924 397;; Returns true if OP is an operand that is zero extended during an operation.
5546ac90
KH
398(define_predicate "general_extend_operand"
399 (match_code "subreg,reg,mem,truncate")
400{
0bcf9a09
OE
401 if (GET_CODE (op) == TRUNCATE)
402 return arith_operand (op, mode);
403
404 if (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op))))
405 return general_movsrc_operand (op, mode);
406
407 return nonimmediate_operand (op, mode);
5546ac90
KH
408})
409
24c18ad8
OE
410;; Returns 1 if OP is a simple register address.
411(define_predicate "simple_mem_operand"
412 (and (match_code "mem")
413 (match_test "arith_reg_operand (XEXP (op, 0), SImode)")))
414
415;; Returns 1 if OP is a valid displacement address.
416(define_predicate "displacement_mem_operand"
417 (and (match_code "mem")
418 (match_test "GET_CODE (XEXP (op, 0)) == PLUS")
419 (match_test "arith_reg_operand (XEXP (XEXP (op, 0), 0), SImode)")
420 (match_test "sh_legitimate_index_p (GET_MODE (op),
421 XEXP (XEXP (op, 0), 1),
422 TARGET_SH2A, true)")))
423
424;; Returns 1 if the operand can be used in an SH2A movu.{b|w} insn.
425(define_predicate "zero_extend_movu_operand"
426 (and (match_operand 0 "displacement_mem_operand")
427 (match_test "GET_MODE (op) == QImode || GET_MODE (op) == HImode")))
428
33344a62
OE
429;; Returns 1 if the operand can be used in a zero_extend.
430(define_predicate "zero_extend_operand"
431 (ior (and (match_test "TARGET_SHMEDIA")
432 (match_operand 0 "general_extend_operand"))
433 (and (match_test "! TARGET_SHMEDIA")
24c18ad8
OE
434 (match_operand 0 "arith_reg_operand"))
435 (and (match_test "TARGET_SH2A")
436 (match_operand 0 "zero_extend_movu_operand"))))
33344a62 437
5546ac90
KH
438;; Returns 1 if OP can be source of a simple move operation. Same as
439;; general_operand, but a LABEL_REF is valid, PRE_DEC is invalid as
440;; are subregs of system registers.
5546ac90 441(define_predicate "general_movsrc_operand"
50fe8924
OE
442 (match_code "subreg,reg,const_int,const_double,mem,symbol_ref,label_ref,
443 const,const_vector")
5546ac90 444{
ef812306
OE
445 if (t_reg_operand (op, mode))
446 return 0;
447
f3536097 448 if (MEM_P (op))
5546ac90
KH
449 {
450 rtx inside = XEXP (op, 0);
fce1e5fb
OE
451
452 /* Disallow mems with GBR address here. They have to go through
453 separate special patterns. */
454 if ((REG_P (inside) && REGNO (inside) == GBR_REG)
455 || (GET_CODE (inside) == PLUS && REG_P (XEXP (inside, 0))
456 && REGNO (XEXP (inside, 0)) == GBR_REG))
457 return 0;
458
5546ac90
KH
459 if (GET_CODE (inside) == CONST)
460 inside = XEXP (inside, 0);
461
462 if (GET_CODE (inside) == LABEL_REF)
463 return 1;
464
465 if (GET_CODE (inside) == PLUS
466 && GET_CODE (XEXP (inside, 0)) == LABEL_REF
f3536097 467 && CONST_INT_P (XEXP (inside, 1)))
5546ac90
KH
468 return 1;
469
470 /* Only post inc allowed. */
471 if (GET_CODE (inside) == PRE_DEC)
472 return 0;
473 }
474
0bcf9a09
OE
475 if (mode == GET_MODE (op)
476 && (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))))
a700b5f0 477 {
0bcf9a09
OE
478 rtx mem_rtx = MEM_P (op) ? op : SUBREG_REG (op);
479 rtx x = XEXP (mem_rtx, 0);
a700b5f0 480
0bcf9a09
OE
481 if ((mode == QImode || mode == HImode)
482 && GET_CODE (x) == PLUS
a700b5f0
KK
483 && REG_P (XEXP (x, 0))
484 && CONST_INT_P (XEXP (x, 1)))
8c2a3f3b 485 return sh_legitimate_index_p (mode, XEXP (x, 1), TARGET_SH2A, false);
0bcf9a09
OE
486
487 /* Allow reg+reg addressing here without validating the register
488 numbers. Usually one of the regs must be R0 or a pseudo reg.
489 In some cases it can happen that arguments from hard regs are
490 propagated directly into address expressions. In this cases reload
491 will have to fix it up later. However, allow this only for native
492 1, 2 or 4 byte addresses. */
493 if (can_create_pseudo_p () && GET_CODE (x) == PLUS
494 && GET_MODE_SIZE (mode) <= 4
495 && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1)))
496 return true;
497
498 /* 'general_operand' does not allow volatile mems during RTL expansion to
499 avoid matching arithmetic that operates on mems, it seems.
500 On SH this leads to redundant sign extensions for QImode or HImode
501 loads. Thus we mimic the behavior but allow volatile mems. */
502 if (memory_address_addr_space_p (GET_MODE (mem_rtx), x,
503 MEM_ADDR_SPACE (mem_rtx)))
504 return true;
a700b5f0
KK
505 }
506
5546ac90
KH
507 if (TARGET_SHMEDIA
508 && (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR)
509 && sh_rep_vec (op, mode))
510 return 1;
511 if (TARGET_SHMEDIA && 1
512 && GET_CODE (op) == SUBREG && GET_MODE (op) == mode
513 && SUBREG_REG (op) == const0_rtx && subreg_lowpart_p (op))
514 /* FIXME */ abort (); /* return 1; */
0bcf9a09 515
5546ac90
KH
516 return general_operand (op, mode);
517})
518
284c32cf 519;; Returns 1 if OP is a MEM that does not use displacement addressing.
344332e8 520(define_predicate "movsrc_no_disp_mem_operand"
284c32cf 521 (match_code "mem")
344332e8 522{
284c32cf 523 return general_movsrc_operand (op, mode) && satisfies_constraint_Snd (op);
344332e8
OE
524})
525
5546ac90
KH
526;; Returns 1 if OP can be a destination of a move. Same as
527;; general_operand, but no preinc allowed.
5546ac90
KH
528(define_predicate "general_movdst_operand"
529 (match_code "subreg,reg,mem")
530{
ef812306
OE
531 if (t_reg_operand (op, mode))
532 return 0;
533
fce1e5fb
OE
534 if (MEM_P (op))
535 {
536 rtx inside = XEXP (op, 0);
537 /* Disallow mems with GBR address here. They have to go through
538 separate special patterns. */
539 if ((REG_P (inside) && REGNO (inside) == GBR_REG)
540 || (GET_CODE (inside) == PLUS && REG_P (XEXP (inside, 0))
541 && REGNO (XEXP (inside, 0)) == GBR_REG))
542 return 0;
543 }
544
5546ac90 545 /* Only pre dec allowed. */
f3536097 546 if (MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC)
5546ac90
KH
547 return 0;
548 if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG
549 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
fae61228 550 && ! (reload_in_progress || reload_completed))
5546ac90
KH
551 return 0;
552
a700b5f0 553 if ((mode == QImode || mode == HImode)
409fed48 554 && mode == GET_MODE (op)
a700b5f0
KK
555 && (MEM_P (op)
556 || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))))
557 {
558 rtx x = XEXP ((MEM_P (op) ? op : SUBREG_REG (op)), 0);
559
560 if (GET_CODE (x) == PLUS
561 && REG_P (XEXP (x, 0))
562 && CONST_INT_P (XEXP (x, 1)))
8c2a3f3b 563 return sh_legitimate_index_p (mode, XEXP (x, 1), TARGET_SH2A, false);
a700b5f0
KK
564 }
565
5546ac90
KH
566 return general_operand (op, mode);
567})
568
c11c09f9 569;; Returns 1 if OP is a POST_INC on stack pointer register.
c11c09f9
KP
570(define_predicate "sh_no_delay_pop_operand"
571 (match_code "mem")
572{
573 rtx inside;
574 inside = XEXP (op, 0);
575
576 if (GET_CODE (op) == MEM && GET_MODE (op) == SImode
577 && GET_CODE (inside) == POST_INC
578 && GET_CODE (XEXP (inside, 0)) == REG
579 && REGNO (XEXP (inside, 0)) == SP_REG)
580 return 1;
581
582 return 0;
583})
584
5546ac90 585;; Returns 1 if OP is a MEM that can be source of a simple move operation.
5546ac90
KH
586(define_predicate "unaligned_load_operand"
587 (match_code "mem")
588{
589 rtx inside;
590
f3536097 591 if (!MEM_P (op) || GET_MODE (op) != mode)
5546ac90
KH
592 return 0;
593
594 inside = XEXP (op, 0);
595
596 if (GET_CODE (inside) == POST_INC)
597 inside = XEXP (inside, 0);
598
f3536097 599 if (REG_P (inside))
5546ac90
KH
600 return 1;
601
602 return 0;
603})
604
b67b3838
OE
605;; Returns 1 if OP is a MEM that can be used in "index_disp" combiner
606;; patterns.
607(define_predicate "mem_index_disp_operand"
608 (match_code "mem")
609{
610 rtx plus0_rtx, plus1_rtx, mult_rtx;
611
612 plus0_rtx = XEXP (op, 0);
613 if (GET_CODE (plus0_rtx) != PLUS)
614 return 0;
615
616 plus1_rtx = XEXP (plus0_rtx, 0);
617 if (GET_CODE (plus1_rtx) != PLUS)
618 return 0;
05852a5f
OE
619 if (! arith_reg_operand (XEXP (plus1_rtx, 1), GET_MODE (XEXP (plus1_rtx, 1))))
620 return 0;
b67b3838
OE
621
622 mult_rtx = XEXP (plus1_rtx, 0);
623 if (GET_CODE (mult_rtx) != MULT)
624 return 0;
05852a5f
OE
625 if (! arith_reg_operand (XEXP (mult_rtx, 0), GET_MODE (XEXP (mult_rtx, 0)))
626 || ! CONST_INT_P (XEXP (mult_rtx, 1)))
627 return 0;
628
629 return exact_log2 (INTVAL (XEXP (mult_rtx, 1))) > 0
b67b3838
OE
630 && sh_legitimate_index_p (mode, XEXP (plus0_rtx, 1), TARGET_SH2A, true);
631})
632
50fe8924 633;; Returns true if OP is some kind of greater comparision.
5546ac90 634(define_predicate "greater_comparison_operator"
f289c6a1 635 (match_code "gt,ge,gtu,geu"))
5546ac90 636
50fe8924
OE
637;; Returns true if OP is an operand suitable for shmedia reload_inqi and
638;; reload_inhi insns.
5546ac90
KH
639(define_predicate "inqhi_operand"
640 (match_code "truncate")
641{
642 if (GET_CODE (op) != TRUNCATE || mode != GET_MODE (op))
643 return 0;
644 op = XEXP (op, 0);
645 /* Can't use true_regnum here because copy_cost wants to know about
646 SECONDARY_INPUT_RELOAD_CLASS. */
f3536097 647 return REG_P (op) && FP_REGISTER_P (REGNO (op));
5546ac90
KH
648})
649
50fe8924
OE
650;; Returns true if OP is a general purpose integer register.
651;; This predicate is currently unused.
652;;(define_special_predicate "int_gpr_dest"
653;; (match_code "subreg,reg")
654;;{
655;; enum machine_mode op_mode = GET_MODE (op);
656;;
657;; if (GET_MODE_CLASS (op_mode) != MODE_INT
658;; || GET_MODE_SIZE (op_mode) >= UNITS_PER_WORD)
659;; return 0;
660;; if (! reload_completed)
661;; return 0;
662;; return true_regnum (op) <= LAST_GENERAL_REG;
663;;})
664
665;; Returns true if OP is some kind of less comparison.
5546ac90 666(define_predicate "less_comparison_operator"
f289c6a1 667 (match_code "lt,le,ltu,leu"))
5546ac90
KH
668
669;; Returns 1 if OP is a valid source operand for a logical operation.
5546ac90
KH
670(define_predicate "logical_operand"
671 (match_code "subreg,reg,const_int")
672{
673 if (TARGET_SHMEDIA
674 && mode != DImode && GET_CODE (op) == SUBREG
675 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
676 return 0;
677
678 if (arith_reg_operand (op, mode))
679 return 1;
680
681 if (TARGET_SHMEDIA)
682 {
32a7ab3d 683 if (satisfies_constraint_I10 (op))
5546ac90
KH
684 return 1;
685 else
686 return 0;
687 }
32a7ab3d 688 else if (satisfies_constraint_K08 (op))
5546ac90
KH
689 return 1;
690
691 return 0;
692})
693
5e204a6e
OE
694;; Like logical_operand but allows additional constant values which can be
695;; done with zero extensions. Used for the second operand of and insns.
696(define_predicate "logical_and_operand"
697 (match_code "subreg,reg,const_int")
698{
699 if (logical_operand (op, mode))
700 return 1;
701
702 if (! TARGET_SHMEDIA
703 && (satisfies_constraint_Jmb (op) || satisfies_constraint_Jmw (op)))
704 return 1;
705
706 return 0;
707})
708
50fe8924 709;; Returns true if OP is a logical operator.
5546ac90 710(define_predicate "logical_operator"
f289c6a1 711 (match_code "and,ior,xor"))
5546ac90
KH
712
713;; Like arith_reg_operand, but for register source operands of narrow
714;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs.
5546ac90
KH
715(define_predicate "logical_reg_operand"
716 (match_code "subreg,reg")
717{
718 if (TARGET_SHMEDIA
719 && GET_CODE (op) == SUBREG
720 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4
721 && mode != DImode)
722 return 0;
723 return arith_reg_operand (op, mode);
724})
725
50fe8924 726;; Returns true if OP is a valid bit offset value for the shmedia mextr insns.
5546ac90
KH
727(define_predicate "mextr_bit_offset"
728 (match_code "const_int")
729{
730 HOST_WIDE_INT i;
731
f3536097 732 if (!CONST_INT_P (op))
5546ac90
KH
733 return 0;
734 i = INTVAL (op);
735 return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0;
736})
737
50fe8924
OE
738;; Returns true if OP is a constant -1, 0 or an zero extended register that
739;; can be used as an operator in the *subsi3_media insn.
5546ac90
KH
740(define_predicate "minuend_operand"
741 (match_code "subreg,reg,truncate,const_int")
742{
743 return op == constm1_rtx || extend_reg_or_0_operand (op, mode);
744})
745
50fe8924
OE
746;; Returns true if OP is a noncommutative floating point operator.
747;; This predicate is currently unused.
748;;(define_predicate "noncommutative_float_operator"
749;; (and (match_code "minus,div")
750;; (match_test "GET_MODE (op) == mode")))
5546ac90 751
f90b7a5a
PB
752;; UNORDERED is only supported on SHMEDIA.
753
754(define_predicate "sh_float_comparison_operator"
755 (ior (match_operand 0 "ordered_comparison_operator")
756 (and (match_test "TARGET_SHMEDIA")
757 (match_code "unordered"))))
758
759(define_predicate "shmedia_cbranch_comparison_operator"
760 (ior (match_operand 0 "equality_comparison_operator")
761 (match_operand 0 "greater_comparison_operator")))
762
50fe8924 763;; Returns true if OP is a constant vector.
5546ac90
KH
764(define_predicate "sh_const_vec"
765 (match_code "const_vector")
766{
767 int i;
768
769 if (GET_CODE (op) != CONST_VECTOR
770 || (GET_MODE (op) != mode && mode != VOIDmode))
771 return 0;
772 i = XVECLEN (op, 0) - 1;
773 for (; i >= 0; i--)
f3536097 774 if (!CONST_INT_P (XVECEXP (op, 0, i)))
5546ac90
KH
775 return 0;
776 return 1;
777})
778
779;; Determine if OP is a constant vector matching MODE with only one
780;; element that is not a sign extension. Two byte-sized elements
781;; count as one.
5546ac90
KH
782(define_predicate "sh_1el_vec"
783 (match_code "const_vector")
784{
785 int unit_size;
786 int i, last, least, sign_ix;
787 rtx sign;
788
789 if (GET_CODE (op) != CONST_VECTOR
790 || (GET_MODE (op) != mode && mode != VOIDmode))
791 return 0;
792 /* Determine numbers of last and of least significant elements. */
793 last = XVECLEN (op, 0) - 1;
794 least = TARGET_LITTLE_ENDIAN ? 0 : last;
f3536097 795 if (!CONST_INT_P (XVECEXP (op, 0, least)))
5546ac90
KH
796 return 0;
797 sign_ix = least;
798 if (GET_MODE_UNIT_SIZE (mode) == 1)
799 sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
f3536097 800 if (!CONST_INT_P (XVECEXP (op, 0, sign_ix)))
5546ac90
KH
801 return 0;
802 unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
803 sign = (INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
804 ? constm1_rtx : const0_rtx);
805 i = XVECLEN (op, 0) - 1;
806 do
807 if (i != least && i != sign_ix && XVECEXP (op, 0, i) != sign)
808 return 0;
809 while (--i);
810 return 1;
811})
812
813;; Like register_operand, but take into account that SHMEDIA can use
814;; the constant zero like a general register.
5546ac90 815(define_predicate "sh_register_operand"
ac42ec79 816 (match_code "reg,subreg,const_int,const_double")
5546ac90
KH
817{
818 if (op == CONST0_RTX (mode) && TARGET_SHMEDIA)
819 return 1;
820 return register_operand (op, mode);
821})
822
50fe8924
OE
823;; Returns true if OP is a vector which is composed of one element that is
824;; repeated.
5546ac90 825(define_predicate "sh_rep_vec"
b4060d3f 826 (match_code "const_vector,parallel")
5546ac90
KH
827{
828 int i;
829 rtx x, y;
830
831 if ((GET_CODE (op) != CONST_VECTOR && GET_CODE (op) != PARALLEL)
832 || (GET_MODE (op) != mode && mode != VOIDmode))
833 return 0;
834 i = XVECLEN (op, 0) - 2;
835 x = XVECEXP (op, 0, i + 1);
836 if (GET_MODE_UNIT_SIZE (mode) == 1)
837 {
838 y = XVECEXP (op, 0, i);
839 for (i -= 2; i >= 0; i -= 2)
840 if (! rtx_equal_p (XVECEXP (op, 0, i + 1), x)
841 || ! rtx_equal_p (XVECEXP (op, 0, i), y))
842 return 0;
843 }
844 else
845 for (; i >= 0; i--)
846 if (XVECEXP (op, 0, i) != x)
847 return 0;
848 return 1;
849})
850
50fe8924 851;; Returns true if OP is a valid shift count operand for shift operations.
5546ac90 852(define_predicate "shift_count_operand"
50fe8924
OE
853 (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,
854 zero_extend,sign_extend")
5546ac90 855{
d8a48c21
OE
856 /* Allow T_REG as shift count for dynamic shifts, although it is not
857 really possible. It will then be copied to a general purpose reg. */
858 if (! TARGET_SHMEDIA)
aadb5b43
OE
859 return const_int_operand (op, mode) || arith_reg_operand (op, mode)
860 || (TARGET_DYNSHIFT && t_reg_operand (op, mode));
d8a48c21 861
5546ac90 862 return (CONSTANT_P (op)
f3536097 863 ? (CONST_INT_P (op)
5546ac90
KH
864 ? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode)
865 : nonmemory_operand (op, mode))
866 : shift_count_reg_operand (op, mode));
867})
868
50fe8924
OE
869;; Returns true if OP is a valid shift count operand in a register which can
870;; be used by shmedia shift insns.
5546ac90
KH
871(define_predicate "shift_count_reg_operand"
872 (match_code "subreg,reg,zero_extend,sign_extend")
873{
874 if ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
875 || (GET_CODE (op) == SUBREG && SUBREG_BYTE (op) == 0))
876 && (mode == VOIDmode || mode == GET_MODE (op))
877 && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
878 && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT)
879 {
880 mode = VOIDmode;
881 do
882 op = XEXP (op, 0);
883 while ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
884 || GET_CODE (op) == TRUNCATE)
885 && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
886 && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT);
887
888 }
889 return arith_reg_operand (op, mode);
890})
891
6e01d526
OE
892;; Predicates for matching operands that are constant shift
893;; amounts 1, 2, 8, 16.
d8a48c21
OE
894(define_predicate "p27_shift_count_operand"
895 (and (match_code "const_int")
896 (match_test "satisfies_constraint_P27 (op)")))
897
898(define_predicate "not_p27_shift_count_operand"
899 (and (match_code "const_int")
900 (match_test "! satisfies_constraint_P27 (op)")))
901
6e01d526
OE
902;; For right shifts the constant 1 is a special case because the shlr insn
903;; clobbers the T_REG and is handled by the T_REG clobbering version of the
904;; insn, which is also used for non-P27 shift sequences.
905(define_predicate "p27_rshift_count_operand"
906 (and (match_code "const_int")
907 (match_test "satisfies_constraint_P27 (op)")
908 (match_test "! satisfies_constraint_M (op)")))
909
910(define_predicate "not_p27_rshift_count_operand"
911 (and (match_code "const_int")
912 (ior (match_test "! satisfies_constraint_P27 (op)")
913 (match_test "satisfies_constraint_M (op)"))))
914
50fe8924 915;; Returns true if OP is some kind of a shift operator.
5546ac90 916(define_predicate "shift_operator"
f289c6a1 917 (match_code "ashift,ashiftrt,lshiftrt"))
5546ac90 918
50fe8924 919;; Returns true if OP is a symbol reference.
5546ac90 920(define_predicate "symbol_ref_operand"
f289c6a1 921 (match_code "symbol_ref"))
5546ac90
KH
922
923;; Same as target_reg_operand, except that label_refs and symbol_refs
924;; are accepted before reload.
5546ac90
KH
925(define_special_predicate "target_operand"
926 (match_code "subreg,reg,label_ref,symbol_ref,const,unspec")
927{
928 if (mode != VOIDmode && mode != Pmode)
929 return 0;
930
931 if ((GET_MODE (op) == Pmode || GET_MODE (op) == VOIDmode)
32a7ab3d 932 && satisfies_constraint_Csy (op))
5546ac90
KH
933 return ! reload_completed;
934
935 return target_reg_operand (op, mode);
936})
937
50fe8924 938;; A predicate that accepts pseudos and branch target registers.
5546ac90
KH
939(define_special_predicate "target_reg_operand"
940 (match_code "subreg,reg")
941{
942 if (mode == VOIDmode
943 ? GET_MODE (op) != Pmode && GET_MODE (op) != PDImode
944 : mode != GET_MODE (op))
945 return 0;
946
947 if (GET_CODE (op) == SUBREG)
948 op = XEXP (op, 0);
949
f3536097 950 if (!REG_P (op))
5546ac90
KH
951 return 0;
952
953 /* We must protect ourselves from matching pseudos that are virtual
954 register, because they will eventually be replaced with hardware
955 registers that aren't branch-target registers. */
956 if (REGNO (op) > LAST_VIRTUAL_REGISTER
957 || TARGET_REGISTER_P (REGNO (op)))
958 return 1;
959
960 return 0;
961})
962
50fe8924 963;; Returns true if OP is a valid operand for the shmedia mperm.w insn.
5546ac90
KH
964(define_special_predicate "trunc_hi_operand"
965 (match_code "subreg,reg,truncate")
966{
967 enum machine_mode op_mode = GET_MODE (op);
968
969 if (op_mode != SImode && op_mode != DImode
970 && op_mode != V4HImode && op_mode != V2SImode)
971 return 0;
972 return extend_reg_operand (op, mode);
973})
974
50fe8924
OE
975;; Returns true if OP is an address suitable for an unaligned access
976;; instruction.
f705a9a0 977(define_special_predicate "ua_address_operand"
5546ac90
KH
978 (match_code "subreg,reg,plus")
979{
980 if (GET_CODE (op) == PLUS
32a7ab3d 981 && (! satisfies_constraint_I06 (XEXP (op, 1))))
5546ac90
KH
982 return 0;
983 return address_operand (op, QImode);
984})
985
50fe8924 986;; Returns true if OP is a valid offset for an unaligned memory address.
5546ac90
KH
987(define_predicate "ua_offset"
988 (match_code "const_int")
989{
32a7ab3d 990 return satisfies_constraint_I06 (op);
5546ac90
KH
991})
992
50fe8924 993;; Returns true if OP is a floating point operator with one operand.
5546ac90 994(define_predicate "unary_float_operator"
f289c6a1
KH
995 (and (match_code "abs,neg,sqrt")
996 (match_test "GET_MODE (op) == mode")))
5546ac90
KH
997
998;; Return 1 if OP is a valid source operand for xor.
5546ac90
KH
999(define_predicate "xor_operand"
1000 (match_code "subreg,reg,const_int")
1001{
f3536097 1002 if (CONST_INT_P (op))
5546ac90 1003 return (TARGET_SHMEDIA
32a7ab3d 1004 ? (satisfies_constraint_I06 (op)
b3a13419 1005 || (!can_create_pseudo_p () && INTVAL (op) == 0xff))
32a7ab3d 1006 : satisfies_constraint_K08 (op));
5546ac90
KH
1007 if (TARGET_SHMEDIA
1008 && mode != DImode && GET_CODE (op) == SUBREG
1009 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
1010 return 0;
1011 return arith_reg_operand (op, mode);
1012})
9eb3a0dd
N
1013
1014(define_predicate "bitwise_memory_operand"
1015 (match_code "mem")
1016{
f3536097 1017 if (MEM_P (op))
9eb3a0dd
N
1018 {
1019 if (REG_P (XEXP (op, 0)))
1020 return 1;
1021
1022 if (GET_CODE (XEXP (op, 0)) == PLUS
f3536097 1023 && REG_P (XEXP (XEXP (op, 0), 0))
9eb3a0dd
N
1024 && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1)))
1025 return 1;
1026 }
1027 return 0;
1028})
c11394f8
OE
1029
1030;; The atomic_* operand predicates are used for the atomic patterns.
1031;; Depending on the particular pattern some operands can be immediate
1032;; values. Using these predicates avoids the usage of 'force_reg' in the
1033;; expanders.
1034(define_predicate "atomic_arith_operand"
1035 (ior (match_code "subreg,reg")
1036 (and (match_test "satisfies_constraint_I08 (op)")
1037 (match_test "mode != QImode")
1038 (match_test "mode != HImode")
1039 (match_test "TARGET_SH4A_ARCH"))))
1040
1041(define_predicate "atomic_logical_operand"
1042 (ior (match_code "subreg,reg")
1043 (and (match_test "satisfies_constraint_K08 (op)")
1044 (match_test "mode != QImode")
1045 (match_test "mode != HImode")
1046 (match_test "TARGET_SH4A_ARCH"))))
1047
f031c344
OE
1048;; A predicate describing the T bit register in any form.
1049(define_predicate "t_reg_operand"
1050 (match_code "reg,subreg,sign_extend,zero_extend")
1051{
1052 switch (GET_CODE (op))
1053 {
1054 case REG:
1055 return REGNO (op) == T_REG;
1056
1057 case SUBREG:
312f9b9d 1058 return REG_P (SUBREG_REG (op)) && REGNO (SUBREG_REG (op)) == T_REG;
f031c344
OE
1059
1060 case ZERO_EXTEND:
1061 case SIGN_EXTEND:
1062 return GET_CODE (XEXP (op, 0)) == SUBREG
312f9b9d 1063 && REG_P (SUBREG_REG (XEXP (op, 0)))
f031c344
OE
1064 && REGNO (SUBREG_REG (XEXP (op, 0))) == T_REG;
1065
1066 default:
1067 return 0;
1068 }
1069})
1070
1071;; A predicate describing a negated T bit register.
1072(define_predicate "negt_reg_operand"
1073 (match_code "subreg,xor")
1074{
1075 switch (GET_CODE (op))
1076 {
1077 case XOR:
1078 return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)))
1079 && satisfies_constraint_M (XEXP (op, 1));
1080
1081 case SUBREG:
1082 return negt_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1083
1084 default:
1085 return 0;
1086 }
1087})
4eddc42b 1088
b4eca9c8
OE
1089;; A predicate that returns true if OP is a valid construct around the T bit
1090;; that can be used as an operand for conditional branches.
1091(define_predicate "cbranch_treg_value"
1092 (match_code "eq,ne,reg,subreg,xor,sign_extend,zero_extend")
1093{
1094 return sh_eval_treg_value (op) >= 0;
1095})
1096
50fe8924 1097;; Returns true if OP is arith_reg_operand or t_reg_operand.
4eddc42b
OE
1098(define_predicate "arith_reg_or_t_reg_operand"
1099 (ior (match_operand 0 "arith_reg_operand")
1100 (match_operand 0 "t_reg_operand")))
78040535
OE
1101
1102;; A predicate describing the negated value of the T bit register shifted
1103;; left by 31.
1104(define_predicate "negt_reg_shl31_operand"
1105 (match_code "plus,minus,if_then_else")
1106{
1107 /* (plus:SI (mult:SI (match_operand:SI 1 "t_reg_operand")
1108 (const_int -2147483648)) ;; 0xffffffff80000000
1109 (const_int -2147483648))
1110 */
1111 if (GET_CODE (op) == PLUS && satisfies_constraint_Jhb (XEXP (op, 1))
1112 && GET_CODE (XEXP (op, 0)) == MULT
1113 && t_reg_operand (XEXP (XEXP (op, 0), 0), SImode)
1114 && satisfies_constraint_Jhb (XEXP (XEXP (op, 0), 1)))
1115 return true;
1116
1117 /* (minus:SI (const_int -2147483648) ;; 0xffffffff80000000
1118 (mult:SI (match_operand:SI 1 "t_reg_operand")
1119 (const_int -2147483648)))
1120 */
1121 if (GET_CODE (op) == MINUS
1122 && satisfies_constraint_Jhb (XEXP (op, 0))
1123 && GET_CODE (XEXP (op, 1)) == MULT
1124 && t_reg_operand (XEXP (XEXP (op, 1), 0), SImode)
1125 && satisfies_constraint_Jhb (XEXP (XEXP (op, 1), 1)))
1126 return true;
1127
1128 /* (if_then_else:SI (match_operand:SI 1 "t_reg_operand")
1129 (const_int 0)
1130 (const_int -2147483648)) ;; 0xffffffff80000000
1131 */
1132 if (GET_CODE (op) == IF_THEN_ELSE && t_reg_operand (XEXP (op, 0), SImode)
1133 && satisfies_constraint_Z (XEXP (op, 1))
1134 && satisfies_constraint_Jhb (XEXP (op, 2)))
1135 return true;
1136
1137 return false;
1138})
7bd76b9c
OE
1139
1140;; A predicate that determines whether a given constant is a valid
50fe8924 1141;; displacement for a GBR load/store of the specified mode.
7bd76b9c
OE
1142(define_predicate "gbr_displacement"
1143 (match_code "const_int")
1144{
1145 const int mode_sz = GET_MODE_SIZE (mode);
1146 const int move_sz = mode_sz > GET_MODE_SIZE (SImode)
1147 ? GET_MODE_SIZE (SImode)
1148 : mode_sz;
1149 int max_disp = 255 * move_sz;
1150 if (mode_sz > move_sz)
1151 max_disp -= mode_sz - move_sz;
1152
1153 return INTVAL (op) >= 0 && INTVAL (op) <= max_disp;
1154})
14df3f36
OE
1155
1156;; A predicate that determines whether OP is a valid GBR addressing mode
1157;; memory reference.
1158(define_predicate "gbr_address_mem"
1159 (match_code "mem")
1160{
1161 rtx addr = XEXP (op, 0);
1162
1163 if (REG_P (addr) && REGNO (addr) == GBR_REG)
1164 return true;
1165 if (GET_CODE (addr) == PLUS
1166 && REG_P (XEXP (addr, 0)) && REGNO (XEXP (addr, 0)) == GBR_REG
1167 && gbr_displacement (XEXP (addr, 1), mode))
1168 return true;
1169
1170 return false;
1171})