]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/sh/predicates.md
re PR c++/58700 (ICE declaring static bit-field)
[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
35d1b083
OE
553 if (mode == GET_MODE (op)
554 && (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))))
a700b5f0 555 {
35d1b083
OE
556 rtx mem_rtx = MEM_P (op) ? op : SUBREG_REG (op);
557 rtx x = XEXP (mem_rtx, 0);
a700b5f0 558
35d1b083
OE
559 if ((mode == QImode || mode == HImode)
560 && GET_CODE (x) == PLUS
a700b5f0
KK
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);
35d1b083
OE
564
565 /* Allow reg+reg addressing here without validating the register
566 numbers. Usually one of the regs must be R0 or a pseudo reg.
567 In some cases it can happen that arguments from hard regs are
568 propagated directly into address expressions. In this cases reload
569 will have to fix it up later. However, allow this only for native
570 1, 2 or 4 byte addresses. */
571 if (can_create_pseudo_p () && GET_CODE (x) == PLUS
572 && GET_MODE_SIZE (mode) <= 4
573 && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1)))
574 return true;
575
576 /* 'general_operand' does not allow volatile mems during RTL expansion to
577 avoid matching arithmetic that operates on mems, it seems.
578 On SH this leads to redundant sign extensions for QImode or HImode
579 stores. Thus we mimic the behavior but allow volatile mems. */
580 if (memory_address_addr_space_p (GET_MODE (mem_rtx), x,
581 MEM_ADDR_SPACE (mem_rtx)))
582 return true;
a700b5f0
KK
583 }
584
5546ac90
KH
585 return general_operand (op, mode);
586})
587
c11c09f9 588;; Returns 1 if OP is a POST_INC on stack pointer register.
c11c09f9
KP
589(define_predicate "sh_no_delay_pop_operand"
590 (match_code "mem")
591{
592 rtx inside;
593 inside = XEXP (op, 0);
594
595 if (GET_CODE (op) == MEM && GET_MODE (op) == SImode
596 && GET_CODE (inside) == POST_INC
597 && GET_CODE (XEXP (inside, 0)) == REG
598 && REGNO (XEXP (inside, 0)) == SP_REG)
599 return 1;
600
601 return 0;
602})
603
5546ac90 604;; Returns 1 if OP is a MEM that can be source of a simple move operation.
5546ac90
KH
605(define_predicate "unaligned_load_operand"
606 (match_code "mem")
607{
608 rtx inside;
609
f3536097 610 if (!MEM_P (op) || GET_MODE (op) != mode)
5546ac90
KH
611 return 0;
612
613 inside = XEXP (op, 0);
614
615 if (GET_CODE (inside) == POST_INC)
616 inside = XEXP (inside, 0);
617
f3536097 618 if (REG_P (inside))
5546ac90
KH
619 return 1;
620
621 return 0;
622})
623
b67b3838
OE
624;; Returns 1 if OP is a MEM that can be used in "index_disp" combiner
625;; patterns.
626(define_predicate "mem_index_disp_operand"
627 (match_code "mem")
628{
629 rtx plus0_rtx, plus1_rtx, mult_rtx;
630
631 plus0_rtx = XEXP (op, 0);
632 if (GET_CODE (plus0_rtx) != PLUS)
633 return 0;
634
635 plus1_rtx = XEXP (plus0_rtx, 0);
636 if (GET_CODE (plus1_rtx) != PLUS)
637 return 0;
05852a5f
OE
638 if (! arith_reg_operand (XEXP (plus1_rtx, 1), GET_MODE (XEXP (plus1_rtx, 1))))
639 return 0;
b67b3838
OE
640
641 mult_rtx = XEXP (plus1_rtx, 0);
642 if (GET_CODE (mult_rtx) != MULT)
643 return 0;
05852a5f
OE
644 if (! arith_reg_operand (XEXP (mult_rtx, 0), GET_MODE (XEXP (mult_rtx, 0)))
645 || ! CONST_INT_P (XEXP (mult_rtx, 1)))
646 return 0;
647
648 return exact_log2 (INTVAL (XEXP (mult_rtx, 1))) > 0
b67b3838
OE
649 && sh_legitimate_index_p (mode, XEXP (plus0_rtx, 1), TARGET_SH2A, true);
650})
651
50fe8924 652;; Returns true if OP is some kind of greater comparision.
5546ac90 653(define_predicate "greater_comparison_operator"
f289c6a1 654 (match_code "gt,ge,gtu,geu"))
5546ac90 655
50fe8924
OE
656;; Returns true if OP is an operand suitable for shmedia reload_inqi and
657;; reload_inhi insns.
5546ac90
KH
658(define_predicate "inqhi_operand"
659 (match_code "truncate")
660{
661 if (GET_CODE (op) != TRUNCATE || mode != GET_MODE (op))
662 return 0;
663 op = XEXP (op, 0);
664 /* Can't use true_regnum here because copy_cost wants to know about
665 SECONDARY_INPUT_RELOAD_CLASS. */
f3536097 666 return REG_P (op) && FP_REGISTER_P (REGNO (op));
5546ac90
KH
667})
668
50fe8924
OE
669;; Returns true if OP is a general purpose integer register.
670;; This predicate is currently unused.
671;;(define_special_predicate "int_gpr_dest"
672;; (match_code "subreg,reg")
673;;{
674;; enum machine_mode op_mode = GET_MODE (op);
675;;
676;; if (GET_MODE_CLASS (op_mode) != MODE_INT
677;; || GET_MODE_SIZE (op_mode) >= UNITS_PER_WORD)
678;; return 0;
679;; if (! reload_completed)
680;; return 0;
681;; return true_regnum (op) <= LAST_GENERAL_REG;
682;;})
683
684;; Returns true if OP is some kind of less comparison.
5546ac90 685(define_predicate "less_comparison_operator"
f289c6a1 686 (match_code "lt,le,ltu,leu"))
5546ac90
KH
687
688;; Returns 1 if OP is a valid source operand for a logical operation.
5546ac90
KH
689(define_predicate "logical_operand"
690 (match_code "subreg,reg,const_int")
691{
692 if (TARGET_SHMEDIA
693 && mode != DImode && GET_CODE (op) == SUBREG
694 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
695 return 0;
696
697 if (arith_reg_operand (op, mode))
698 return 1;
699
700 if (TARGET_SHMEDIA)
701 {
32a7ab3d 702 if (satisfies_constraint_I10 (op))
5546ac90
KH
703 return 1;
704 else
705 return 0;
706 }
32a7ab3d 707 else if (satisfies_constraint_K08 (op))
5546ac90
KH
708 return 1;
709
710 return 0;
711})
712
5e204a6e
OE
713;; Like logical_operand but allows additional constant values which can be
714;; done with zero extensions. Used for the second operand of and insns.
715(define_predicate "logical_and_operand"
716 (match_code "subreg,reg,const_int")
717{
718 if (logical_operand (op, mode))
719 return 1;
720
721 if (! TARGET_SHMEDIA
722 && (satisfies_constraint_Jmb (op) || satisfies_constraint_Jmw (op)))
723 return 1;
724
725 return 0;
726})
727
50fe8924 728;; Returns true if OP is a logical operator.
5546ac90 729(define_predicate "logical_operator"
f289c6a1 730 (match_code "and,ior,xor"))
5546ac90
KH
731
732;; Like arith_reg_operand, but for register source operands of narrow
733;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs.
5546ac90
KH
734(define_predicate "logical_reg_operand"
735 (match_code "subreg,reg")
736{
737 if (TARGET_SHMEDIA
738 && GET_CODE (op) == SUBREG
739 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4
740 && mode != DImode)
741 return 0;
742 return arith_reg_operand (op, mode);
743})
744
50fe8924 745;; Returns true if OP is a valid bit offset value for the shmedia mextr insns.
5546ac90
KH
746(define_predicate "mextr_bit_offset"
747 (match_code "const_int")
748{
749 HOST_WIDE_INT i;
750
f3536097 751 if (!CONST_INT_P (op))
5546ac90
KH
752 return 0;
753 i = INTVAL (op);
754 return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0;
755})
756
50fe8924
OE
757;; Returns true if OP is a constant -1, 0 or an zero extended register that
758;; can be used as an operator in the *subsi3_media insn.
5546ac90
KH
759(define_predicate "minuend_operand"
760 (match_code "subreg,reg,truncate,const_int")
761{
762 return op == constm1_rtx || extend_reg_or_0_operand (op, mode);
763})
764
50fe8924
OE
765;; Returns true if OP is a noncommutative floating point operator.
766;; This predicate is currently unused.
767;;(define_predicate "noncommutative_float_operator"
768;; (and (match_code "minus,div")
769;; (match_test "GET_MODE (op) == mode")))
5546ac90 770
f90b7a5a
PB
771;; UNORDERED is only supported on SHMEDIA.
772
773(define_predicate "sh_float_comparison_operator"
774 (ior (match_operand 0 "ordered_comparison_operator")
775 (and (match_test "TARGET_SHMEDIA")
776 (match_code "unordered"))))
777
778(define_predicate "shmedia_cbranch_comparison_operator"
779 (ior (match_operand 0 "equality_comparison_operator")
780 (match_operand 0 "greater_comparison_operator")))
781
50fe8924 782;; Returns true if OP is a constant vector.
5546ac90
KH
783(define_predicate "sh_const_vec"
784 (match_code "const_vector")
785{
786 int i;
787
788 if (GET_CODE (op) != CONST_VECTOR
789 || (GET_MODE (op) != mode && mode != VOIDmode))
790 return 0;
791 i = XVECLEN (op, 0) - 1;
792 for (; i >= 0; i--)
f3536097 793 if (!CONST_INT_P (XVECEXP (op, 0, i)))
5546ac90
KH
794 return 0;
795 return 1;
796})
797
798;; Determine if OP is a constant vector matching MODE with only one
799;; element that is not a sign extension. Two byte-sized elements
800;; count as one.
5546ac90
KH
801(define_predicate "sh_1el_vec"
802 (match_code "const_vector")
803{
804 int unit_size;
805 int i, last, least, sign_ix;
806 rtx sign;
807
808 if (GET_CODE (op) != CONST_VECTOR
809 || (GET_MODE (op) != mode && mode != VOIDmode))
810 return 0;
811 /* Determine numbers of last and of least significant elements. */
812 last = XVECLEN (op, 0) - 1;
813 least = TARGET_LITTLE_ENDIAN ? 0 : last;
f3536097 814 if (!CONST_INT_P (XVECEXP (op, 0, least)))
5546ac90
KH
815 return 0;
816 sign_ix = least;
817 if (GET_MODE_UNIT_SIZE (mode) == 1)
818 sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
f3536097 819 if (!CONST_INT_P (XVECEXP (op, 0, sign_ix)))
5546ac90
KH
820 return 0;
821 unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
822 sign = (INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
823 ? constm1_rtx : const0_rtx);
824 i = XVECLEN (op, 0) - 1;
825 do
826 if (i != least && i != sign_ix && XVECEXP (op, 0, i) != sign)
827 return 0;
828 while (--i);
829 return 1;
830})
831
832;; Like register_operand, but take into account that SHMEDIA can use
833;; the constant zero like a general register.
5546ac90 834(define_predicate "sh_register_operand"
ac42ec79 835 (match_code "reg,subreg,const_int,const_double")
5546ac90
KH
836{
837 if (op == CONST0_RTX (mode) && TARGET_SHMEDIA)
838 return 1;
839 return register_operand (op, mode);
840})
841
50fe8924
OE
842;; Returns true if OP is a vector which is composed of one element that is
843;; repeated.
5546ac90 844(define_predicate "sh_rep_vec"
b4060d3f 845 (match_code "const_vector,parallel")
5546ac90
KH
846{
847 int i;
848 rtx x, y;
849
850 if ((GET_CODE (op) != CONST_VECTOR && GET_CODE (op) != PARALLEL)
851 || (GET_MODE (op) != mode && mode != VOIDmode))
852 return 0;
853 i = XVECLEN (op, 0) - 2;
854 x = XVECEXP (op, 0, i + 1);
855 if (GET_MODE_UNIT_SIZE (mode) == 1)
856 {
857 y = XVECEXP (op, 0, i);
858 for (i -= 2; i >= 0; i -= 2)
859 if (! rtx_equal_p (XVECEXP (op, 0, i + 1), x)
860 || ! rtx_equal_p (XVECEXP (op, 0, i), y))
861 return 0;
862 }
863 else
864 for (; i >= 0; i--)
865 if (XVECEXP (op, 0, i) != x)
866 return 0;
867 return 1;
868})
869
50fe8924 870;; Returns true if OP is a valid shift count operand for shift operations.
5546ac90 871(define_predicate "shift_count_operand"
50fe8924
OE
872 (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,
873 zero_extend,sign_extend")
5546ac90 874{
d8a48c21
OE
875 /* Allow T_REG as shift count for dynamic shifts, although it is not
876 really possible. It will then be copied to a general purpose reg. */
877 if (! TARGET_SHMEDIA)
aadb5b43
OE
878 return const_int_operand (op, mode) || arith_reg_operand (op, mode)
879 || (TARGET_DYNSHIFT && t_reg_operand (op, mode));
d8a48c21 880
5546ac90 881 return (CONSTANT_P (op)
f3536097 882 ? (CONST_INT_P (op)
5546ac90
KH
883 ? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode)
884 : nonmemory_operand (op, mode))
885 : shift_count_reg_operand (op, mode));
886})
887
50fe8924
OE
888;; Returns true if OP is a valid shift count operand in a register which can
889;; be used by shmedia shift insns.
5546ac90
KH
890(define_predicate "shift_count_reg_operand"
891 (match_code "subreg,reg,zero_extend,sign_extend")
892{
893 if ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
894 || (GET_CODE (op) == SUBREG && SUBREG_BYTE (op) == 0))
895 && (mode == VOIDmode || mode == GET_MODE (op))
896 && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
897 && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT)
898 {
899 mode = VOIDmode;
900 do
901 op = XEXP (op, 0);
902 while ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
903 || GET_CODE (op) == TRUNCATE)
904 && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
905 && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT);
906
907 }
908 return arith_reg_operand (op, mode);
909})
910
6e01d526
OE
911;; Predicates for matching operands that are constant shift
912;; amounts 1, 2, 8, 16.
d8a48c21
OE
913(define_predicate "p27_shift_count_operand"
914 (and (match_code "const_int")
915 (match_test "satisfies_constraint_P27 (op)")))
916
917(define_predicate "not_p27_shift_count_operand"
918 (and (match_code "const_int")
919 (match_test "! satisfies_constraint_P27 (op)")))
920
6e01d526
OE
921;; For right shifts the constant 1 is a special case because the shlr insn
922;; clobbers the T_REG and is handled by the T_REG clobbering version of the
923;; insn, which is also used for non-P27 shift sequences.
924(define_predicate "p27_rshift_count_operand"
925 (and (match_code "const_int")
926 (match_test "satisfies_constraint_P27 (op)")
927 (match_test "! satisfies_constraint_M (op)")))
928
929(define_predicate "not_p27_rshift_count_operand"
930 (and (match_code "const_int")
931 (ior (match_test "! satisfies_constraint_P27 (op)")
932 (match_test "satisfies_constraint_M (op)"))))
933
50fe8924 934;; Returns true if OP is some kind of a shift operator.
5546ac90 935(define_predicate "shift_operator"
f289c6a1 936 (match_code "ashift,ashiftrt,lshiftrt"))
5546ac90 937
50fe8924 938;; Returns true if OP is a symbol reference.
5546ac90 939(define_predicate "symbol_ref_operand"
f289c6a1 940 (match_code "symbol_ref"))
5546ac90
KH
941
942;; Same as target_reg_operand, except that label_refs and symbol_refs
943;; are accepted before reload.
5546ac90
KH
944(define_special_predicate "target_operand"
945 (match_code "subreg,reg,label_ref,symbol_ref,const,unspec")
946{
947 if (mode != VOIDmode && mode != Pmode)
948 return 0;
949
950 if ((GET_MODE (op) == Pmode || GET_MODE (op) == VOIDmode)
32a7ab3d 951 && satisfies_constraint_Csy (op))
5546ac90
KH
952 return ! reload_completed;
953
954 return target_reg_operand (op, mode);
955})
956
50fe8924 957;; A predicate that accepts pseudos and branch target registers.
5546ac90
KH
958(define_special_predicate "target_reg_operand"
959 (match_code "subreg,reg")
960{
961 if (mode == VOIDmode
962 ? GET_MODE (op) != Pmode && GET_MODE (op) != PDImode
963 : mode != GET_MODE (op))
964 return 0;
965
966 if (GET_CODE (op) == SUBREG)
967 op = XEXP (op, 0);
968
f3536097 969 if (!REG_P (op))
5546ac90
KH
970 return 0;
971
972 /* We must protect ourselves from matching pseudos that are virtual
973 register, because they will eventually be replaced with hardware
974 registers that aren't branch-target registers. */
975 if (REGNO (op) > LAST_VIRTUAL_REGISTER
976 || TARGET_REGISTER_P (REGNO (op)))
977 return 1;
978
979 return 0;
980})
981
50fe8924 982;; Returns true if OP is a valid operand for the shmedia mperm.w insn.
5546ac90
KH
983(define_special_predicate "trunc_hi_operand"
984 (match_code "subreg,reg,truncate")
985{
986 enum machine_mode op_mode = GET_MODE (op);
987
988 if (op_mode != SImode && op_mode != DImode
989 && op_mode != V4HImode && op_mode != V2SImode)
990 return 0;
991 return extend_reg_operand (op, mode);
992})
993
50fe8924
OE
994;; Returns true if OP is an address suitable for an unaligned access
995;; instruction.
f705a9a0 996(define_special_predicate "ua_address_operand"
5546ac90
KH
997 (match_code "subreg,reg,plus")
998{
999 if (GET_CODE (op) == PLUS
32a7ab3d 1000 && (! satisfies_constraint_I06 (XEXP (op, 1))))
5546ac90
KH
1001 return 0;
1002 return address_operand (op, QImode);
1003})
1004
50fe8924 1005;; Returns true if OP is a valid offset for an unaligned memory address.
5546ac90
KH
1006(define_predicate "ua_offset"
1007 (match_code "const_int")
1008{
32a7ab3d 1009 return satisfies_constraint_I06 (op);
5546ac90
KH
1010})
1011
50fe8924 1012;; Returns true if OP is a floating point operator with one operand.
5546ac90 1013(define_predicate "unary_float_operator"
f289c6a1
KH
1014 (and (match_code "abs,neg,sqrt")
1015 (match_test "GET_MODE (op) == mode")))
5546ac90
KH
1016
1017;; Return 1 if OP is a valid source operand for xor.
5546ac90
KH
1018(define_predicate "xor_operand"
1019 (match_code "subreg,reg,const_int")
1020{
f3536097 1021 if (CONST_INT_P (op))
5546ac90 1022 return (TARGET_SHMEDIA
32a7ab3d 1023 ? (satisfies_constraint_I06 (op)
b3a13419 1024 || (!can_create_pseudo_p () && INTVAL (op) == 0xff))
32a7ab3d 1025 : satisfies_constraint_K08 (op));
5546ac90
KH
1026 if (TARGET_SHMEDIA
1027 && mode != DImode && GET_CODE (op) == SUBREG
1028 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
1029 return 0;
1030 return arith_reg_operand (op, mode);
1031})
9eb3a0dd
N
1032
1033(define_predicate "bitwise_memory_operand"
1034 (match_code "mem")
1035{
f3536097 1036 if (MEM_P (op))
9eb3a0dd
N
1037 {
1038 if (REG_P (XEXP (op, 0)))
1039 return 1;
1040
1041 if (GET_CODE (XEXP (op, 0)) == PLUS
f3536097 1042 && REG_P (XEXP (XEXP (op, 0), 0))
9eb3a0dd
N
1043 && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1)))
1044 return 1;
1045 }
1046 return 0;
1047})
c11394f8
OE
1048
1049;; The atomic_* operand predicates are used for the atomic patterns.
1050;; Depending on the particular pattern some operands can be immediate
1051;; values. Using these predicates avoids the usage of 'force_reg' in the
1052;; expanders.
1053(define_predicate "atomic_arith_operand"
1054 (ior (match_code "subreg,reg")
1055 (and (match_test "satisfies_constraint_I08 (op)")
1056 (match_test "mode != QImode")
1057 (match_test "mode != HImode")
1058 (match_test "TARGET_SH4A_ARCH"))))
1059
1060(define_predicate "atomic_logical_operand"
1061 (ior (match_code "subreg,reg")
1062 (and (match_test "satisfies_constraint_K08 (op)")
1063 (match_test "mode != QImode")
1064 (match_test "mode != HImode")
1065 (match_test "TARGET_SH4A_ARCH"))))
1066
f031c344
OE
1067;; A predicate describing the T bit register in any form.
1068(define_predicate "t_reg_operand"
1069 (match_code "reg,subreg,sign_extend,zero_extend")
1070{
1071 switch (GET_CODE (op))
1072 {
1073 case REG:
1074 return REGNO (op) == T_REG;
1075
1076 case SUBREG:
312f9b9d 1077 return REG_P (SUBREG_REG (op)) && REGNO (SUBREG_REG (op)) == T_REG;
f031c344
OE
1078
1079 case ZERO_EXTEND:
1080 case SIGN_EXTEND:
1081 return GET_CODE (XEXP (op, 0)) == SUBREG
312f9b9d 1082 && REG_P (SUBREG_REG (XEXP (op, 0)))
f031c344
OE
1083 && REGNO (SUBREG_REG (XEXP (op, 0))) == T_REG;
1084
1085 default:
1086 return 0;
1087 }
1088})
1089
1090;; A predicate describing a negated T bit register.
1091(define_predicate "negt_reg_operand"
1092 (match_code "subreg,xor")
1093{
1094 switch (GET_CODE (op))
1095 {
1096 case XOR:
1097 return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)))
1098 && satisfies_constraint_M (XEXP (op, 1));
1099
1100 case SUBREG:
1101 return negt_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1102
1103 default:
1104 return 0;
1105 }
1106})
4eddc42b 1107
b4eca9c8
OE
1108;; A predicate that returns true if OP is a valid construct around the T bit
1109;; that can be used as an operand for conditional branches.
1110(define_predicate "cbranch_treg_value"
1111 (match_code "eq,ne,reg,subreg,xor,sign_extend,zero_extend")
1112{
1113 return sh_eval_treg_value (op) >= 0;
1114})
1115
50fe8924 1116;; Returns true if OP is arith_reg_operand or t_reg_operand.
4eddc42b
OE
1117(define_predicate "arith_reg_or_t_reg_operand"
1118 (ior (match_operand 0 "arith_reg_operand")
1119 (match_operand 0 "t_reg_operand")))
78040535
OE
1120
1121;; A predicate describing the negated value of the T bit register shifted
1122;; left by 31.
1123(define_predicate "negt_reg_shl31_operand"
1124 (match_code "plus,minus,if_then_else")
1125{
1126 /* (plus:SI (mult:SI (match_operand:SI 1 "t_reg_operand")
1127 (const_int -2147483648)) ;; 0xffffffff80000000
1128 (const_int -2147483648))
1129 */
1130 if (GET_CODE (op) == PLUS && satisfies_constraint_Jhb (XEXP (op, 1))
1131 && GET_CODE (XEXP (op, 0)) == MULT
1132 && t_reg_operand (XEXP (XEXP (op, 0), 0), SImode)
1133 && satisfies_constraint_Jhb (XEXP (XEXP (op, 0), 1)))
1134 return true;
1135
1136 /* (minus:SI (const_int -2147483648) ;; 0xffffffff80000000
1137 (mult:SI (match_operand:SI 1 "t_reg_operand")
1138 (const_int -2147483648)))
1139 */
1140 if (GET_CODE (op) == MINUS
1141 && satisfies_constraint_Jhb (XEXP (op, 0))
1142 && GET_CODE (XEXP (op, 1)) == MULT
1143 && t_reg_operand (XEXP (XEXP (op, 1), 0), SImode)
1144 && satisfies_constraint_Jhb (XEXP (XEXP (op, 1), 1)))
1145 return true;
1146
1147 /* (if_then_else:SI (match_operand:SI 1 "t_reg_operand")
1148 (const_int 0)
1149 (const_int -2147483648)) ;; 0xffffffff80000000
1150 */
1151 if (GET_CODE (op) == IF_THEN_ELSE && t_reg_operand (XEXP (op, 0), SImode)
1152 && satisfies_constraint_Z (XEXP (op, 1))
1153 && satisfies_constraint_Jhb (XEXP (op, 2)))
1154 return true;
1155
1156 return false;
1157})
7bd76b9c
OE
1158
1159;; A predicate that determines whether a given constant is a valid
50fe8924 1160;; displacement for a GBR load/store of the specified mode.
7bd76b9c
OE
1161(define_predicate "gbr_displacement"
1162 (match_code "const_int")
1163{
1164 const int mode_sz = GET_MODE_SIZE (mode);
1165 const int move_sz = mode_sz > GET_MODE_SIZE (SImode)
1166 ? GET_MODE_SIZE (SImode)
1167 : mode_sz;
1168 int max_disp = 255 * move_sz;
1169 if (mode_sz > move_sz)
1170 max_disp -= mode_sz - move_sz;
1171
1172 return INTVAL (op) >= 0 && INTVAL (op) <= max_disp;
1173})
14df3f36
OE
1174
1175;; A predicate that determines whether OP is a valid GBR addressing mode
1176;; memory reference.
1177(define_predicate "gbr_address_mem"
1178 (match_code "mem")
1179{
1180 rtx addr = XEXP (op, 0);
1181
1182 if (REG_P (addr) && REGNO (addr) == GBR_REG)
1183 return true;
1184 if (GET_CODE (addr) == PLUS
1185 && REG_P (XEXP (addr, 0)) && REGNO (XEXP (addr, 0)) == GBR_REG
1186 && gbr_displacement (XEXP (addr, 1), mode))
1187 return true;
1188
1189 return false;
1190})