xref: /netbsd-src/external/gpl3/gcc/dist/gcc/config/sh/predicates.md (revision a24efa7dea9f1f56c3bdb15a927d3516792ace1c)
1;; Predicate definitions for Renesas / SuperH SH.
2;; Copyright (C) 2005-2015 Free Software Foundation, Inc.
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
8;; the Free Software Foundation; either version 3, or (at your option)
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
17;; along with GCC; see the file COPYING3.  If not see
18;; <http://www.gnu.org/licenses/>.
19
20;; TODO: Add a comment here.
21(define_predicate "trapping_target_operand"
22  (match_code "if_then_else")
23{
24  rtx cond, mem, res, tar, and_expr;
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);
31  if (!MEM_P (mem)
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);
41      if (!satisfies_constraint_Csy (tar))
42	return 0;
43      if (GET_CODE (tar) == CONST)
44	tar = XEXP (tar, 0);
45    }
46  else if (!arith_reg_operand (tar, VOIDmode)
47	   && ! satisfies_constraint_Csy (tar))
48    return 0;
49  if (GET_CODE (cond) != EQ)
50    return 0;
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))
55	  && CONST_INT_P (XEXP (cond, 1))
56	  && INTVAL (XEXP (and_expr, 1)) == 3
57	  && INTVAL (XEXP (cond, 1)) == 3);
58})
59
60;; A logical operand that can be used in an shmedia and insn.
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
70      && satisfies_constraint_J16 (op))
71    return 1;
72
73  return 0;
74})
75
76;; Like arith_reg_dest, but this predicate is defined with
77;; define_special_predicate, not define_predicate.
78(define_special_predicate "any_arith_reg_dest"
79  (match_code "subreg,reg")
80{
81  return arith_reg_dest (op, mode);
82})
83
84;; Like register_operand, but this predicate is defined with
85;; define_special_predicate, not define_predicate.
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.
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
102	 signed 16-bit here, but this causes reload_cse to crash when
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.  */
106      if (CONST_INT_P (op)
107	  || satisfies_constraint_Css (op))
108	return 1;
109      else if (GET_CODE (op) == TRUNCATE
110	       && REG_P (XEXP (op, 0))
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    }
121  else if (satisfies_constraint_I08 (op))
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.
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.
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
148      if (REG_P (op))
149	regno = REGNO (op);
150      else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
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)
157	      && regno != FPUL_REG && regno != FPSCR_REG
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
171      && REG_P (XEXP (op, 0))
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;; 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
198;; Returns 1 if OP is a valid source operand for a compare insn.
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
205  if (satisfies_constraint_Z (op))
206    return 1;
207
208  return 0;
209})
210
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
239;; Returns 1 if OP is a floating point operator with two operands.
240(define_predicate "binary_float_operator"
241  (and (match_code "plus,minus,mult,div")
242       (match_test "GET_MODE (op) == mode")))
243
244;; Returns 1 if OP is a logical operator with two operands.
245(define_predicate "binary_logical_operator"
246  (and (match_code "and,ior,xor")
247       (match_test "GET_MODE (op) == mode")))
248
249;; Return 1 if OP is an address suitable for a cache manipulation operation.
250;; MODE has the meaning as in address_operand.
251(define_special_predicate "cache_address_operand"
252  (match_code "plus,reg")
253{
254  if (GET_CODE (op) == PLUS)
255    {
256      if (!REG_P (XEXP (op, 0)))
257	return 0;
258      if (!CONST_INT_P (XEXP (op, 1))
259	  || (INTVAL (XEXP (op, 1)) & 31))
260	return 0;
261    }
262  else if (!REG_P (op))
263    return 0;
264  return address_operand (op, mode);
265})
266
267;; Returns 1 if OP is a valid source operand for shmedia cmpgt / cmpgtu.
268(define_predicate "cmp_operand"
269  (match_code "subreg,reg,const_int")
270{
271  if (satisfies_constraint_N (op))
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
280;; Returns true if OP is an operand that can be used as the first operand in
281;; the cstoresi4 expander pattern.
282(define_predicate "cmpsi_operand"
283  (match_code "subreg,reg,const_int")
284{
285  if (REG_P (op) && REGNO (op) == T_REG
286      && GET_MODE (op) == SImode
287      && TARGET_SH1)
288    return 1;
289  return arith_operand (op, mode);
290})
291
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")))
297
298;; Returns true if OP is a equal or not equal operator.
299(define_predicate "equality_comparison_operator"
300  (match_code "eq,ne"))
301
302;; Returns true if OP is an arithmetic operand that is zero extended during
303;; an operation.
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
312;; Like extend_reg_operand, but also allow a constant 0.
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.
322(define_predicate "ext_dest_operand"
323  (match_code "subreg,reg")
324{
325  return arith_reg_operand (op, mode);
326})
327
328;; Returns true if OP can be used as a destination register for shmedia floating
329;; point to integer conversions.
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
339;; Returns true if OP is a floating point register that can be used in floating
340;; point arithmetic operations.
341(define_predicate "fp_arith_reg_operand"
342  (match_code "subreg,reg")
343{
344  if (register_operand (op, mode))
345    {
346      int regno;
347
348      if (REG_P (op))
349	regno = REGNO (op);
350      else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
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
361;; Returns true if OP is the FPSCR.
362(define_predicate "fpscr_operand"
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")
369{
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;
384})
385
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.
390(define_predicate "fpul_operand"
391  (match_code "reg")
392{
393  if (TARGET_SHMEDIA)
394    return fp_arith_reg_operand (op, mode);
395
396  return (REG_P (op)
397	  && (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER)
398	  && GET_MODE (op) == mode);
399})
400
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
424;; Returns true if OP is an operand that is zero extended during an operation.
425(define_predicate "general_extend_operand"
426  (match_code "subreg,reg,mem,truncate")
427{
428  if (reload_completed && GET_CODE (op) == TRUNCATE)
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);
435})
436
437;; Returns 1 if OP is a simple register address.
438(define_predicate "simple_mem_operand"
439  (and (match_code "mem")
440       (match_code "reg" "0")
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")
446       (match_code "plus" "0")
447       (match_code "reg" "00")
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
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"
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)")))
460
461;; Returns 1 if the operand can be used in an SH2A movu.{b|w} insn.
462(define_predicate "zero_extend_movu_operand"
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"))))
467
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")
473	    (match_operand 0 "arith_reg_operand"))))
474
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.
478(define_predicate "general_movsrc_operand"
479  (match_code "subreg,reg,const_int,const_double,mem,symbol_ref,label_ref,
480	       const,const_vector")
481{
482  if (t_reg_operand (op, mode))
483    return 0;
484
485  if (fpscr_operand (op, mode))
486    return false;
487
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
493  if (MEM_P (op))
494    {
495      rtx inside = XEXP (op, 0);
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
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
512	  && CONST_INT_P (XEXP (inside, 1)))
513	return 1;
514
515      /* Only post inc allowed.  */
516      if (GET_CODE (inside) == PRE_DEC)
517	return 0;
518    }
519
520  if (mode == GET_MODE (op)
521      && (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))))
522    {
523      rtx mem_rtx = MEM_P (op) ? op : SUBREG_REG (op);
524      rtx x = XEXP (mem_rtx, 0);
525
526      if (! ALLOW_INDEXED_ADDRESS
527	  && GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1)))
528	return false;
529
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)
549	  && GET_CODE (x) == PLUS
550	  && REG_P (XEXP (x, 0))
551	  && CONST_INT_P (XEXP (x, 1)))
552	return sh_legitimate_index_p (mode, XEXP (x, 1), TARGET_SH2A, false);
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;
572    }
573
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; */
582
583  return general_operand (op, mode);
584})
585
586;; Returns 1 if OP is a MEM that does not use displacement addressing.
587(define_predicate "movsrc_no_disp_mem_operand"
588  (match_code "mem")
589{
590  return general_movsrc_operand (op, mode) && satisfies_constraint_Snd (op);
591})
592
593;; Returns 1 if OP can be a destination of a move. Same as
594;; general_operand, but no preinc allowed.
595(define_predicate "general_movdst_operand"
596  (match_code "subreg,reg,mem")
597{
598  if (t_reg_operand (op, mode))
599    return 0;
600
601  if (fpscr_operand (op, mode))
602    return false;
603
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
615  /* Only pre dec allowed.  */
616  if (MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC)
617    return 0;
618  if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG
619      && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
620      && ! (reload_in_progress || reload_completed))
621    return 0;
622
623  if (mode == GET_MODE (op)
624      && (MEM_P (op) || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))))
625    {
626      rtx mem_rtx = MEM_P (op) ? op : SUBREG_REG (op);
627      rtx x = XEXP (mem_rtx, 0);
628
629      if (! ALLOW_INDEXED_ADDRESS
630	  && GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1)))
631	return false;
632
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)
652	  && GET_CODE (x) == PLUS
653	  && REG_P (XEXP (x, 0))
654	  && CONST_INT_P (XEXP (x, 1)))
655	return sh_legitimate_index_p (mode, XEXP (x, 1), TARGET_SH2A, false);
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;
675    }
676
677  return general_operand (op, mode);
678})
679
680;; Returns 1 if OP is a POST_INC on stack pointer register.
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
696;; Returns 1 if OP is a MEM that can be source of a simple move operation.
697(define_predicate "unaligned_load_operand"
698  (match_code "mem")
699{
700  rtx inside;
701
702  if (!MEM_P (op) || GET_MODE (op) != mode)
703    return 0;
704
705  inside = XEXP (op, 0);
706
707  if (GET_CODE (inside) == POST_INC)
708    inside = XEXP (inside, 0);
709
710  if (REG_P (inside))
711    return 1;
712
713  return 0;
714})
715
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;
730  if (! arith_reg_operand (XEXP (plus1_rtx, 1), GET_MODE (XEXP (plus1_rtx, 1))))
731    return 0;
732
733  mult_rtx = XEXP (plus1_rtx, 0);
734  if (GET_CODE (mult_rtx) != MULT)
735    return 0;
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
741	 && sh_legitimate_index_p (mode, XEXP (plus0_rtx, 1), TARGET_SH2A, true);
742})
743
744;; Returns true if OP is some kind of greater comparision.
745(define_predicate "greater_comparison_operator"
746  (match_code "gt,ge,gtu,geu"))
747
748;; Returns true if OP is an operand suitable for shmedia reload_inqi and
749;; reload_inhi insns.
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.  */
758  return REG_P (op) && FP_REGISTER_P (REGNO (op));
759})
760
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;;{
766;;  machine_mode op_mode = GET_MODE (op);
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.
777(define_predicate "less_comparison_operator"
778  (match_code "lt,le,ltu,leu"))
779
780;; Returns 1 if OP is a valid source operand for a logical operation.
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    {
794      if (satisfies_constraint_I10 (op))
795	return 1;
796      else
797	return 0;
798    }
799  else if (satisfies_constraint_K08 (op))
800    return 1;
801
802  return 0;
803})
804
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
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
826;; Returns true if OP is a logical operator.
827(define_predicate "logical_operator"
828  (match_code "and,ior,xor"))
829
830;; Like arith_reg_operand, but for register source operands of narrow
831;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs.
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
843;; Returns true if OP is a valid bit offset value for the shmedia mextr insns.
844(define_predicate "mextr_bit_offset"
845  (match_code "const_int")
846{
847  HOST_WIDE_INT i;
848
849  if (!CONST_INT_P (op))
850    return 0;
851  i = INTVAL (op);
852  return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0;
853})
854
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.
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
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")))
868
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
880;; Returns true if OP is a constant vector.
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--)
891    if (!CONST_INT_P (XVECEXP (op, 0, i)))
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.
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;
912  if (!CONST_INT_P (XVECEXP (op, 0, least)))
913    return 0;
914  sign_ix = least;
915  if (GET_MODE_UNIT_SIZE (mode) == 1)
916    sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
917  if (!CONST_INT_P (XVECEXP (op, 0, sign_ix)))
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.
932(define_predicate "sh_register_operand"
933  (match_code "reg,subreg,const_int,const_double")
934{
935  if (op == CONST0_RTX (mode) && TARGET_SHMEDIA)
936    return 1;
937  return register_operand (op, mode);
938})
939
940;; Returns true if OP is a vector which is composed of one element that is
941;; repeated.
942(define_predicate "sh_rep_vec"
943  (match_code "const_vector,parallel")
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
968;; Returns true if OP is a valid shift count operand for shift operations.
969(define_predicate "shift_count_operand"
970  (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,
971	       zero_extend,sign_extend")
972{
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)
976    return const_int_operand (op, mode) || arith_reg_operand (op, mode)
977	   || (TARGET_DYNSHIFT && t_reg_operand (op, mode));
978
979  return (CONSTANT_P (op)
980	  ? (CONST_INT_P (op)
981	     ? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode)
982	     : nonmemory_operand (op, mode))
983	  : shift_count_reg_operand (op, mode));
984})
985
986;; Returns true if OP is a valid shift count operand in a register which can
987;; be used by shmedia shift insns.
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
1009;; Predicates for matching operands that are constant shift
1010;; amounts 1, 2, 8, 16.
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
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
1032;; Returns true if OP is some kind of a shift operator.
1033(define_predicate "shift_operator"
1034  (match_code "ashift,ashiftrt,lshiftrt"))
1035
1036;; Returns true if OP is a symbol reference.
1037(define_predicate "symbol_ref_operand"
1038  (match_code "symbol_ref"))
1039
1040;; Same as target_reg_operand, except that label_refs and symbol_refs
1041;; are accepted before reload.
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)
1049      && satisfies_constraint_Csy (op))
1050    return ! reload_completed;
1051
1052  return target_reg_operand (op, mode);
1053})
1054
1055;; A predicate that accepts pseudos and branch target registers.
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
1067  if (!REG_P (op))
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
1080;; Returns true if OP is a valid operand for the shmedia mperm.w insn.
1081(define_special_predicate "trunc_hi_operand"
1082  (match_code "subreg,reg,truncate")
1083{
1084  machine_mode op_mode = GET_MODE (op);
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
1092;; Returns true if OP is an address suitable for an unaligned access
1093;; instruction.
1094(define_special_predicate "ua_address_operand"
1095  (match_code "subreg,reg,plus")
1096{
1097  if (GET_CODE (op) == PLUS
1098      && (! satisfies_constraint_I06 (XEXP (op, 1))))
1099    return 0;
1100  return address_operand (op, QImode);
1101})
1102
1103;; Returns true if OP is a valid offset for an unaligned memory address.
1104(define_predicate "ua_offset"
1105  (match_code "const_int")
1106{
1107  return satisfies_constraint_I06 (op);
1108})
1109
1110;; Returns true if OP is a floating point operator with one operand.
1111(define_predicate "unary_float_operator"
1112  (and (match_code "abs,neg,sqrt")
1113       (match_test "GET_MODE (op) == mode")))
1114
1115;; Return 1 if OP is a valid source operand for xor.
1116(define_predicate "xor_operand"
1117  (match_code "subreg,reg,const_int")
1118{
1119  if (CONST_INT_P (op))
1120    return (TARGET_SHMEDIA
1121	    ? (satisfies_constraint_I06 (op)
1122	       || (!can_create_pseudo_p () && INTVAL (op) == 0xff))
1123	    : satisfies_constraint_K08 (op));
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})
1130
1131(define_predicate "bitwise_memory_operand"
1132  (match_code "mem")
1133{
1134  if (MEM_P (op))
1135    {
1136      if (REG_P (XEXP (op, 0)))
1137	return 1;
1138
1139      if (GET_CODE (XEXP (op, 0)) == PLUS
1140	  && REG_P (XEXP (XEXP (op, 0), 0))
1141	  && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1)))
1142        return 1;
1143    }
1144  return 0;
1145})
1146
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
1159;; A predicate describing the T bit register in any form.
1160(define_predicate "t_reg_operand"
1161  (match_code "reg,subreg,sign_extend,zero_extend")
1162{
1163  switch (GET_CODE (op))
1164    {
1165      case REG:
1166	return REGNO (op) == T_REG;
1167
1168      case SUBREG:
1169	return REG_P (SUBREG_REG (op)) && REGNO (SUBREG_REG (op)) == T_REG;
1170
1171      case ZERO_EXTEND:
1172      case SIGN_EXTEND:
1173        if (REG_P (XEXP (op, 0)) && REGNO (XEXP (op, 0)) == T_REG)
1174	  return true;
1175	return GET_CODE (XEXP (op, 0)) == SUBREG
1176	       && REG_P (SUBREG_REG (XEXP (op, 0)))
1177	       && REGNO (SUBREG_REG (XEXP (op, 0))) == T_REG;
1178
1179      default:
1180	return 0;
1181    }
1182})
1183
1184;; A predicate describing a negated T bit register.
1185(define_predicate "negt_reg_operand"
1186  (match_code "subreg,xor")
1187{
1188  switch (GET_CODE (op))
1189    {
1190      case XOR:
1191	return t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)))
1192	       && satisfies_constraint_M (XEXP (op, 1));
1193
1194      case SUBREG:
1195	return negt_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1196
1197      default:
1198	return 0;
1199    }
1200})
1201
1202;; A predicate that returns true if OP is a valid construct around the T bit
1203;; that can be used as an operand for conditional branches.
1204(define_predicate "cbranch_treg_value"
1205  (and (match_code "eq,ne,reg,subreg,xor,sign_extend,zero_extend")
1206       (match_test "sh_eval_treg_value (op) >= 0")))
1207
1208;; Returns true if OP is arith_reg_operand or t_reg_operand.
1209(define_predicate "arith_reg_or_t_reg_operand"
1210  (ior (match_operand 0 "arith_reg_operand")
1211       (match_operand 0 "t_reg_operand")))
1212
1213(define_predicate "arith_reg_or_treg_set_expr"
1214  (ior (match_operand 0 "arith_reg_operand")
1215       (match_operand 0 "treg_set_expr")))
1216
1217;; A predicate describing the negated value of the T bit register shifted
1218;; left by 31.
1219(define_predicate "negt_reg_shl31_operand"
1220  (match_code "plus,minus,if_then_else")
1221{
1222  /* (minus:SI (const_int -2147483648)  ;; 0xffffffff80000000
1223	       (ashift:SI (match_operand:SI 1 "t_reg_operand")
1224			  (const_int 31)))
1225  */
1226  if (GET_CODE (op) == MINUS && satisfies_constraint_Jhb (XEXP (op, 0))
1227      && GET_CODE (XEXP (op, 1)) == ASHIFT
1228      && t_reg_operand (XEXP (XEXP (op, 1), 0), SImode)
1229      && CONST_INT_P (XEXP (XEXP (op, 1), 1))
1230      && INTVAL (XEXP (XEXP (op, 1), 1)) == 31)
1231    return true;
1232
1233  /* (plus:SI (ashift:SI (match_operand:SI 1 "t_reg_operand")
1234			 (const_int 31))
1235	      (const_int -2147483648))  ;; 0xffffffff80000000
1236  */
1237  if (GET_CODE (op) == PLUS && satisfies_constraint_Jhb (XEXP (op, 1))
1238      && GET_CODE (XEXP (op, 0)) == ASHIFT
1239      && t_reg_operand (XEXP (XEXP (op, 0), 0), SImode)
1240      && CONST_INT_P (XEXP (XEXP (op, 0), 1))
1241      && INTVAL (XEXP (XEXP (op, 0), 1)) == 31)
1242    return true;
1243
1244  /* (plus:SI (mult:SI (match_operand:SI 1 "t_reg_operand")
1245		       (const_int -2147483648))  ;; 0xffffffff80000000
1246	      (const_int -2147483648))
1247  */
1248  if (GET_CODE (op) == PLUS && satisfies_constraint_Jhb (XEXP (op, 1))
1249      && GET_CODE (XEXP (op, 0)) == MULT
1250      && t_reg_operand (XEXP (XEXP (op, 0), 0), SImode)
1251      && satisfies_constraint_Jhb (XEXP (XEXP (op, 0), 1)))
1252    return true;
1253
1254  /* (minus:SI (const_int -2147483648)  ;; 0xffffffff80000000
1255	       (mult:SI (match_operand:SI 1 "t_reg_operand")
1256			(const_int -2147483648)))
1257  */
1258  if (GET_CODE (op) == MINUS
1259      && satisfies_constraint_Jhb (XEXP (op, 0))
1260      && GET_CODE (XEXP (op, 1)) == MULT
1261      && t_reg_operand (XEXP (XEXP (op, 1), 0), SImode)
1262      && satisfies_constraint_Jhb (XEXP (XEXP (op, 1), 1)))
1263    return true;
1264
1265  /*  (if_then_else:SI (match_operand:SI 1 "t_reg_operand")
1266		       (const_int 0)
1267		       (const_int -2147483648))  ;; 0xffffffff80000000
1268  */
1269  if (GET_CODE (op) == IF_THEN_ELSE && t_reg_operand (XEXP (op, 0), SImode)
1270      && satisfies_constraint_Z (XEXP (op, 1))
1271      && satisfies_constraint_Jhb (XEXP (op, 2)))
1272    return true;
1273
1274  return false;
1275})
1276
1277;; A predicate that determines whether a given constant is a valid
1278;; displacement for a GBR load/store of the specified mode.
1279(define_predicate "gbr_displacement"
1280  (match_code "const_int")
1281{
1282  const int mode_sz = GET_MODE_SIZE (mode);
1283  const int move_sz = mode_sz > GET_MODE_SIZE (SImode)
1284				? GET_MODE_SIZE (SImode)
1285				: mode_sz;
1286  int max_disp = 255 * move_sz;
1287  if (mode_sz > move_sz)
1288    max_disp -= mode_sz - move_sz;
1289
1290  return INTVAL (op) >= 0 && INTVAL (op) <= max_disp;
1291})
1292
1293;; A predicate that determines whether OP is a valid GBR addressing mode
1294;; memory reference.
1295(define_predicate "gbr_address_mem"
1296  (match_code "mem")
1297{
1298  rtx addr = XEXP (op, 0);
1299
1300  if (REG_P (addr) && REGNO (addr) == GBR_REG)
1301    return true;
1302  if (GET_CODE (addr) == PLUS
1303      && REG_P (XEXP (addr, 0)) && REGNO (XEXP (addr, 0)) == GBR_REG
1304      && gbr_displacement (XEXP (addr, 1), mode))
1305    return true;
1306
1307  return false;
1308})
1309