OSDN Git Service

compiler: Move import of Go export data to gcc side of interface.
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / predicates.md
1 ;; Predicate definitions for Renesas / SuperH SH.
2 ;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
3 ;; Free Software Foundation, Inc.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 ;; TODO: Add a comment here.
22
23 (define_predicate "trapping_target_operand"
24   (match_code "if_then_else")
25 {
26   rtx cond, mem, res, tar, and_expr;
27
28   if (GET_MODE (op) != PDImode)
29     return 0;
30   cond = XEXP (op, 0);
31   mem = XEXP (op, 1);
32   res = XEXP (op, 2);
33   if (!MEM_P (mem)
34       || (GET_CODE (res) != SIGN_EXTEND && GET_CODE (res) != TRUNCATE))
35     return 0;
36   tar = XEXP (res, 0);
37   if (!rtx_equal_p (XEXP (mem, 0), tar)
38       || GET_MODE (tar) != Pmode)
39     return 0;
40   if (GET_CODE (cond) == CONST)
41     {
42       cond = XEXP (cond, 0);
43       if (!satisfies_constraint_Csy (tar))
44         return 0;
45       if (GET_CODE (tar) == CONST)
46         tar = XEXP (tar, 0);
47     }
48   else if (!arith_reg_operand (tar, VOIDmode)
49            && ! satisfies_constraint_Csy (tar))
50     return 0;
51   if (GET_CODE (cond) != EQ)
52     return 0;
53   and_expr = XEXP (cond, 0);
54   return (GET_CODE (and_expr) == AND
55           && rtx_equal_p (XEXP (and_expr, 0), tar)
56           && CONST_INT_P (XEXP (and_expr, 1))
57           && CONST_INT_P (XEXP (cond, 1))
58           && INTVAL (XEXP (and_expr, 1)) == 3
59           && INTVAL (XEXP (cond, 1)) == 3);
60 })
61
62 ;; TODO: Add a comment here.
63
64 (define_predicate "and_operand"
65   (match_code "subreg,reg,const_int")
66 {
67   if (logical_operand (op, mode))
68     return 1;
69
70   /* Check mshflo.l / mshflhi.l opportunities.  */
71   if (TARGET_SHMEDIA
72       && mode == DImode
73       && satisfies_constraint_J16 (op))
74     return 1;
75
76   return 0;
77 })
78
79 ;; Like arith_reg_dest, but this predicate is defined with
80 ;; define_special_predicate, not define_predicate.
81
82 (define_special_predicate "any_arith_reg_dest"
83   (match_code "subreg,reg")
84 {
85   return arith_reg_dest (op, mode);
86 })
87
88 ;; Like register_operand, but this predicate is defined with
89 ;; define_special_predicate, not define_predicate.
90
91 (define_special_predicate "any_register_operand"
92   (match_code "subreg,reg")
93 {
94   return register_operand (op, mode);
95 })
96
97 ;; Returns 1 if OP is a valid source operand for an arithmetic insn.
98
99 (define_predicate "arith_operand"
100   (match_code "subreg,reg,const_int,truncate")
101 {
102   if (arith_reg_operand (op, mode))
103     return 1;
104
105   if (TARGET_SHMEDIA)
106     {
107       /* FIXME: We should be checking whether the CONST_INT fits in a
108          signed 16-bit here, but this causes reload_cse to crash when
109          attempting to transform a sequence of two 64-bit sets of the
110          same register from literal constants into a set and an add,
111          when the difference is too wide for an add.  */
112       if (CONST_INT_P (op)
113           || satisfies_constraint_Css (op))
114         return 1;
115       else if (GET_CODE (op) == TRUNCATE
116                && REG_P (XEXP (op, 0))
117                && ! system_reg_operand (XEXP (op, 0), VOIDmode)
118                && (mode == VOIDmode || mode == GET_MODE (op))
119                && (GET_MODE_SIZE (GET_MODE (op))
120                    < GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
121                && (! FP_REGISTER_P (REGNO (XEXP (op, 0)))
122                    || GET_MODE_SIZE (GET_MODE (op)) == 4))
123         return register_operand (XEXP (op, 0), VOIDmode);
124       else
125         return 0;
126     }
127   else if (satisfies_constraint_I08 (op))
128     return 1;
129
130   return 0;
131 })
132
133 ;; Like above, but for DImode destinations: forbid paradoxical DImode
134 ;; subregs, because this would lead to missing sign extensions when
135 ;; truncating from DImode to SImode.
136
137 (define_predicate "arith_reg_dest"
138   (match_code "subreg,reg")
139 {
140   if (mode == DImode && GET_CODE (op) == SUBREG
141       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
142       && TARGET_SHMEDIA)
143     return 0;
144   return arith_reg_operand (op, mode);
145 })
146
147 ;; Returns 1 if OP is a normal arithmetic register.
148
149 (define_predicate "arith_reg_operand"
150   (match_code "subreg,reg,sign_extend")
151 {
152   if (register_operand (op, mode))
153     {
154       int regno;
155
156       if (REG_P (op))
157         regno = REGNO (op);
158       else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
159         regno = REGNO (SUBREG_REG (op));
160       else
161         return 1;
162
163       return (regno != T_REG && regno != PR_REG
164               && ! TARGET_REGISTER_P (regno)
165               && (regno != FPUL_REG || TARGET_SH4)
166               && regno != MACH_REG && regno != MACL_REG);
167     }
168   /* Allow a no-op sign extension - compare LOAD_EXTEND_OP.
169      We allow SImode here, as not using an FP register is just a matter of
170      proper register allocation.  */
171   if (TARGET_SHMEDIA
172       && GET_MODE (op) == DImode && GET_CODE (op) == SIGN_EXTEND
173       && GET_MODE (XEXP (op, 0)) == SImode
174       && GET_CODE (XEXP (op, 0)) != SUBREG)
175     return register_operand (XEXP (op, 0), VOIDmode);
176 #if 0 /* Can't do this because of PROMOTE_MODE for unsigned vars.  */
177   if (GET_MODE (op) == SImode && GET_CODE (op) == SIGN_EXTEND
178       && GET_MODE (XEXP (op, 0)) == HImode
179       && REG_P (XEXP (op, 0))
180       && REGNO (XEXP (op, 0)) <= LAST_GENERAL_REG)
181     return register_operand (XEXP (op, 0), VOIDmode);
182 #endif
183   if (GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT
184       && GET_CODE (op) == SUBREG
185       && GET_MODE (SUBREG_REG (op)) == DImode
186       && GET_CODE (SUBREG_REG (op)) == SIGN_EXTEND
187       && GET_MODE (XEXP (SUBREG_REG (op), 0)) == SImode
188       && GET_CODE (XEXP (SUBREG_REG (op), 0)) != SUBREG)
189     return register_operand (XEXP (SUBREG_REG (op), 0), VOIDmode);
190   return 0;
191 })
192
193 ;; Returns 1 if OP is a valid source operand for a compare insn.
194
195 (define_predicate "arith_reg_or_0_operand"
196   (match_code "subreg,reg,const_int,const_vector")
197 {
198   if (arith_reg_operand (op, mode))
199     return 1;
200
201   if (satisfies_constraint_Z (op))
202     return 1;
203
204   return 0;
205 })
206
207 ;; TODO: Add a comment here.
208
209 (define_predicate "binary_float_operator"
210   (and (match_code "plus,minus,mult,div")
211        (match_test "GET_MODE (op) == mode")))
212
213 ;; TODO: Add a comment here.
214
215 (define_predicate "binary_logical_operator"
216   (and (match_code "and,ior,xor")
217        (match_test "GET_MODE (op) == mode")))
218
219 ;; Return 1 of OP is an address suitable for a cache manipulation operation.
220 ;; MODE has the meaning as in address_operand.
221
222 (define_special_predicate "cache_address_operand"
223   (match_code "plus,reg")
224 {
225   if (GET_CODE (op) == PLUS)
226     {
227       if (!REG_P (XEXP (op, 0)))
228         return 0;
229       if (!CONST_INT_P (XEXP (op, 1))
230           || (INTVAL (XEXP (op, 1)) & 31))
231         return 0;
232     }
233   else if (!REG_P (op))
234     return 0;
235   return address_operand (op, mode);
236 })
237
238 ;; Return 1 if OP is a valid source operand for shmedia cmpgt / cmpgtu.
239
240 (define_predicate "cmp_operand"
241   (match_code "subreg,reg,const_int")
242 {
243   if (satisfies_constraint_N (op))
244     return 1;
245   if (TARGET_SHMEDIA
246       && mode != DImode && GET_CODE (op) == SUBREG
247       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
248     return 0;
249   return arith_reg_operand (op, mode);
250 })
251
252 ;; TODO: Add a comment here.
253
254 (define_predicate "cmpsi_operand"
255   (match_code "subreg,reg,const_int")
256 {
257   if (REG_P (op) && REGNO (op) == T_REG
258       && GET_MODE (op) == SImode
259       && TARGET_SH1)
260     return 1;
261   return arith_operand (op, mode);
262 })
263
264 ;; TODO: Add a comment here.
265
266 (define_predicate "commutative_float_operator"
267   (and (match_code "plus,mult")
268        (match_test "GET_MODE (op) == mode")))
269
270 ;; TODO: Add a comment here.
271
272 (define_predicate "equality_comparison_operator"
273   (match_code "eq,ne"))
274
275 ;; TODO: Add a comment here.
276
277 (define_predicate "extend_reg_operand"
278   (match_code "subreg,reg,truncate")
279 {
280   return (GET_CODE (op) == TRUNCATE
281           ? arith_operand
282           : arith_reg_operand) (op, mode);
283 })
284
285 ;; TODO: Add a comment here.
286
287 (define_predicate "extend_reg_or_0_operand"
288   (match_code "subreg,reg,truncate,const_int")
289 {
290   return (GET_CODE (op) == TRUNCATE
291           ? arith_operand
292           : arith_reg_or_0_operand) (op, mode);
293 })
294
295 ;; Like arith_reg_operand, but this predicate does not accept SIGN_EXTEND.
296
297 (define_predicate "ext_dest_operand"
298   (match_code "subreg,reg")
299 {
300   return arith_reg_operand (op, mode);
301 })
302
303 ;; TODO: Add a comment here.
304
305 (define_predicate "fp_arith_reg_dest"
306   (match_code "subreg,reg")
307 {
308   if (mode == DImode && GET_CODE (op) == SUBREG
309       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8)
310     return 0;
311   return fp_arith_reg_operand (op, mode);
312 })
313
314 ;; TODO: Add a comment here.
315
316 (define_predicate "fp_arith_reg_operand"
317   (match_code "subreg,reg")
318 {
319   if (register_operand (op, mode))
320     {
321       int regno;
322
323       if (REG_P (op))
324         regno = REGNO (op);
325       else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
326         regno = REGNO (SUBREG_REG (op));
327       else
328         return 1;
329
330       return (regno >= FIRST_PSEUDO_REGISTER
331               || FP_REGISTER_P (regno));
332     }
333   return 0;
334 })
335
336 ;; TODO: Add a comment here.
337
338 (define_predicate "fpscr_operand"
339   (match_code "reg")
340 {
341   return (REG_P (op)
342           && (REGNO (op) == FPSCR_REG
343               || (REGNO (op) >= FIRST_PSEUDO_REGISTER
344                   && !(reload_in_progress || reload_completed)))
345           && GET_MODE (op) == PSImode);
346 })
347
348 ;; TODO: Add a comment here.
349
350 (define_predicate "fpul_operand"
351   (match_code "reg")
352 {
353   if (TARGET_SHMEDIA)
354     return fp_arith_reg_operand (op, mode);
355
356   return (REG_P (op)
357           && (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER)
358           && GET_MODE (op) == mode);
359 })
360
361 ;; TODO: Add a comment here.
362
363 (define_predicate "general_extend_operand"
364   (match_code "subreg,reg,mem,truncate")
365 {
366   return (GET_CODE (op) == TRUNCATE
367           ? arith_operand
368           : nonimmediate_operand) (op, mode);
369 })
370
371 ;; Returns 1 if OP can be source of a simple move operation. Same as
372 ;; general_operand, but a LABEL_REF is valid, PRE_DEC is invalid as
373 ;; are subregs of system registers.
374
375 (define_predicate "general_movsrc_operand"
376   (match_code "subreg,reg,const_int,const_double,mem,symbol_ref,label_ref,const,const_vector")
377 {
378   if (MEM_P (op))
379     {
380       rtx inside = XEXP (op, 0);
381       if (GET_CODE (inside) == CONST)
382         inside = XEXP (inside, 0);
383
384       if (GET_CODE (inside) == LABEL_REF)
385         return 1;
386
387       if (GET_CODE (inside) == PLUS
388           && GET_CODE (XEXP (inside, 0)) == LABEL_REF
389           && CONST_INT_P (XEXP (inside, 1)))
390         return 1;
391
392       /* Only post inc allowed.  */
393       if (GET_CODE (inside) == PRE_DEC)
394         return 0;
395     }
396
397   if ((mode == QImode || mode == HImode)
398       && mode == GET_MODE (op)
399       && (MEM_P (op)
400           || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))))
401     {
402       rtx x = XEXP ((MEM_P (op) ? op : SUBREG_REG (op)), 0);
403
404       if (GET_CODE (x) == PLUS
405           && REG_P (XEXP (x, 0))
406           && CONST_INT_P (XEXP (x, 1)))
407         return sh_legitimate_index_p (mode, XEXP (x, 1));
408     }
409
410   if (TARGET_SHMEDIA
411       && (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR)
412       && sh_rep_vec (op, mode))
413     return 1;
414   if (TARGET_SHMEDIA && 1
415       && GET_CODE (op) == SUBREG && GET_MODE (op) == mode
416       && SUBREG_REG (op) == const0_rtx && subreg_lowpart_p (op))
417     /* FIXME */ abort (); /* return 1; */
418   return general_operand (op, mode);
419 })
420
421 ;; Returns 1 if OP can be a destination of a move. Same as
422 ;; general_operand, but no preinc allowed.
423
424 (define_predicate "general_movdst_operand"
425   (match_code "subreg,reg,mem")
426 {
427   /* Only pre dec allowed.  */
428   if (MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC)
429     return 0;
430   if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG
431       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
432       && ! (high_life_started || reload_completed))
433     return 0;
434
435   if ((mode == QImode || mode == HImode)
436       && mode == GET_MODE (op)
437       && (MEM_P (op)
438           || (GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))))
439     {
440       rtx x = XEXP ((MEM_P (op) ? op : SUBREG_REG (op)), 0);
441
442       if (GET_CODE (x) == PLUS
443           && REG_P (XEXP (x, 0))
444           && CONST_INT_P (XEXP (x, 1)))
445         return sh_legitimate_index_p (mode, XEXP (x, 1));
446     }
447
448   return general_operand (op, mode);
449 })
450
451
452 ;; Returns 1 if OP is a POST_INC on stack pointer register.
453
454 (define_predicate "sh_no_delay_pop_operand"
455   (match_code "mem")
456 {
457   rtx inside;
458   inside = XEXP (op, 0);
459
460   if (GET_CODE (op) == MEM && GET_MODE (op) == SImode 
461       && GET_CODE (inside) == POST_INC 
462       && GET_CODE (XEXP (inside, 0)) == REG
463       && REGNO (XEXP (inside, 0)) == SP_REG)
464     return 1;
465
466   return 0;
467 })
468
469
470 ;; Returns 1 if OP is a MEM that can be source of a simple move operation.
471
472 (define_predicate "unaligned_load_operand"
473   (match_code "mem")
474 {
475   rtx inside;
476
477   if (!MEM_P (op) || GET_MODE (op) != mode)
478     return 0;
479
480   inside = XEXP (op, 0);
481
482   if (GET_CODE (inside) == POST_INC)
483     inside = XEXP (inside, 0);
484
485   if (REG_P (inside))
486     return 1;
487
488   return 0;
489 })
490
491 ;; TODO: Add a comment here.
492
493 (define_predicate "greater_comparison_operator"
494   (match_code "gt,ge,gtu,geu"))
495
496 ;; TODO: Add a comment here.
497
498 (define_predicate "inqhi_operand"
499   (match_code "truncate")
500 {
501   if (GET_CODE (op) != TRUNCATE || mode != GET_MODE (op))
502     return 0;
503   op = XEXP (op, 0);
504   /* Can't use true_regnum here because copy_cost wants to know about
505      SECONDARY_INPUT_RELOAD_CLASS.  */
506   return REG_P (op) && FP_REGISTER_P (REGNO (op));
507 })
508
509 ;; TODO: Add a comment here.
510
511 (define_special_predicate "int_gpr_dest"
512   (match_code "subreg,reg")
513 {
514   enum machine_mode op_mode = GET_MODE (op);
515
516   if (GET_MODE_CLASS (op_mode) != MODE_INT
517       || GET_MODE_SIZE (op_mode) >= UNITS_PER_WORD)
518     return 0;
519   if (! reload_completed)
520     return 0;
521   return true_regnum (op) <= LAST_GENERAL_REG;
522 })
523
524 ;; TODO: Add a comment here.
525
526 (define_predicate "less_comparison_operator"
527   (match_code "lt,le,ltu,leu"))
528
529 ;; Returns 1 if OP is a valid source operand for a logical operation.
530
531 (define_predicate "logical_operand"
532   (match_code "subreg,reg,const_int")
533 {
534   if (TARGET_SHMEDIA
535       && mode != DImode && GET_CODE (op) == SUBREG
536       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
537     return 0;
538
539   if (arith_reg_operand (op, mode))
540     return 1;
541
542   if (TARGET_SHMEDIA)
543     {
544       if (satisfies_constraint_I10 (op))
545         return 1;
546       else
547         return 0;
548     }
549   else if (satisfies_constraint_K08 (op))
550     return 1;
551
552   return 0;
553 })
554
555 ;; TODO: Add a comment here.
556
557 (define_predicate "logical_operator"
558   (match_code "and,ior,xor"))
559
560 ;; Like arith_reg_operand, but for register source operands of narrow
561 ;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs.
562
563 (define_predicate "logical_reg_operand"
564   (match_code "subreg,reg")
565 {
566   if (TARGET_SHMEDIA
567       && GET_CODE (op) == SUBREG
568       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4
569       && mode != DImode)
570     return 0;
571   return arith_reg_operand (op, mode);
572 })
573
574 ;; TODO: Add a comment here.
575
576 (define_predicate "mextr_bit_offset"
577   (match_code "const_int")
578 {
579   HOST_WIDE_INT i;
580
581   if (!CONST_INT_P (op))
582     return 0;
583   i = INTVAL (op);
584   return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0;
585 })
586
587 ;; TODO: Add a comment here.
588
589 (define_predicate "minuend_operand"
590   (match_code "subreg,reg,truncate,const_int")
591 {
592   return op == constm1_rtx || extend_reg_or_0_operand (op, mode);
593 })
594
595 ;; TODO: Add a comment here.
596
597 (define_predicate "noncommutative_float_operator"
598   (and (match_code "minus,div")
599        (match_test "GET_MODE (op) == mode")))
600
601 ;; UNORDERED is only supported on SHMEDIA.
602
603 (define_predicate "sh_float_comparison_operator"
604   (ior (match_operand 0 "ordered_comparison_operator")
605        (and (match_test "TARGET_SHMEDIA")
606             (match_code "unordered"))))
607
608 (define_predicate "shmedia_cbranch_comparison_operator"
609   (ior (match_operand 0 "equality_comparison_operator")
610        (match_operand 0 "greater_comparison_operator")))
611
612 ;; TODO: Add a comment here.
613
614 (define_predicate "sh_const_vec"
615   (match_code "const_vector")
616 {
617   int i;
618
619   if (GET_CODE (op) != CONST_VECTOR
620       || (GET_MODE (op) != mode && mode != VOIDmode))
621     return 0;
622   i = XVECLEN (op, 0) - 1;
623   for (; i >= 0; i--)
624     if (!CONST_INT_P (XVECEXP (op, 0, i)))
625       return 0;
626   return 1;
627 })
628
629 ;; Determine if OP is a constant vector matching MODE with only one
630 ;; element that is not a sign extension.  Two byte-sized elements
631 ;; count as one.
632
633 (define_predicate "sh_1el_vec"
634   (match_code "const_vector")
635 {
636   int unit_size;
637   int i, last, least, sign_ix;
638   rtx sign;
639
640   if (GET_CODE (op) != CONST_VECTOR
641       || (GET_MODE (op) != mode && mode != VOIDmode))
642     return 0;
643   /* Determine numbers of last and of least significant elements.  */
644   last = XVECLEN (op, 0) - 1;
645   least = TARGET_LITTLE_ENDIAN ? 0 : last;
646   if (!CONST_INT_P (XVECEXP (op, 0, least)))
647     return 0;
648   sign_ix = least;
649   if (GET_MODE_UNIT_SIZE (mode) == 1)
650     sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
651   if (!CONST_INT_P (XVECEXP (op, 0, sign_ix)))
652     return 0;
653   unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
654   sign = (INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
655           ? constm1_rtx : const0_rtx);
656   i = XVECLEN (op, 0) - 1;
657   do
658     if (i != least && i != sign_ix && XVECEXP (op, 0, i) != sign)
659       return 0;
660   while (--i);
661   return 1;
662 })
663
664 ;; Like register_operand, but take into account that SHMEDIA can use
665 ;; the constant zero like a general register.
666
667 (define_predicate "sh_register_operand"
668   (match_code "reg,subreg,const_int,const_double")
669 {
670   if (op == CONST0_RTX (mode) && TARGET_SHMEDIA)
671     return 1;
672   return register_operand (op, mode);
673 })
674
675 ;; TODO: Add a comment here.
676
677 (define_predicate "sh_rep_vec"
678   (match_code "const_vector,parallel")
679 {
680   int i;
681   rtx x, y;
682
683   if ((GET_CODE (op) != CONST_VECTOR && GET_CODE (op) != PARALLEL)
684       || (GET_MODE (op) != mode && mode != VOIDmode))
685     return 0;
686   i = XVECLEN (op, 0) - 2;
687   x = XVECEXP (op, 0, i + 1);
688   if (GET_MODE_UNIT_SIZE (mode) == 1)
689     {
690       y = XVECEXP (op, 0, i);
691       for (i -= 2; i >= 0; i -= 2)
692         if (! rtx_equal_p (XVECEXP (op, 0, i + 1), x)
693             || ! rtx_equal_p (XVECEXP (op, 0, i), y))
694           return 0;
695     }
696   else
697     for (; i >= 0; i--)
698       if (XVECEXP (op, 0, i) != x)
699         return 0;
700   return 1;
701 })
702
703 ;; TODO: Add a comment here.
704
705 (define_predicate "shift_count_operand"
706   (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,zero_extend,sign_extend")
707 {
708   return (CONSTANT_P (op)
709           ? (CONST_INT_P (op)
710              ? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode)
711              : nonmemory_operand (op, mode))
712           : shift_count_reg_operand (op, mode));
713 })
714
715 ;; TODO: Add a comment here.
716
717 (define_predicate "shift_count_reg_operand"
718   (match_code "subreg,reg,zero_extend,sign_extend")
719 {
720   if ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
721        || (GET_CODE (op) == SUBREG && SUBREG_BYTE (op) == 0))
722       && (mode == VOIDmode || mode == GET_MODE (op))
723       && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
724       && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT)
725     {
726       mode = VOIDmode;
727       do
728         op = XEXP (op, 0);
729       while ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
730               || GET_CODE (op) == TRUNCATE)
731              && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
732              && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT);
733
734     }
735   return arith_reg_operand (op, mode);
736 })
737
738 ;; TODO: Add a comment here.
739
740 (define_predicate "shift_operator"
741   (match_code "ashift,ashiftrt,lshiftrt"))
742
743 ;; TODO: Add a comment here.
744
745 (define_predicate "symbol_ref_operand"
746   (match_code "symbol_ref"))
747
748 ;; Same as target_reg_operand, except that label_refs and symbol_refs
749 ;; are accepted before reload.
750
751 (define_special_predicate "target_operand"
752   (match_code "subreg,reg,label_ref,symbol_ref,const,unspec")
753 {
754   if (mode != VOIDmode && mode != Pmode)
755     return 0;
756
757   if ((GET_MODE (op) == Pmode || GET_MODE (op) == VOIDmode)
758       && satisfies_constraint_Csy (op))
759     return ! reload_completed;
760
761   return target_reg_operand (op, mode);
762 })
763
764 ;; Accept pseudos and branch target registers.
765
766 (define_special_predicate "target_reg_operand"
767   (match_code "subreg,reg")
768 {
769   if (mode == VOIDmode
770      ? GET_MODE (op) != Pmode && GET_MODE (op) != PDImode
771      : mode != GET_MODE (op))
772     return 0;
773
774   if (GET_CODE (op) == SUBREG)
775     op = XEXP (op, 0);
776
777   if (!REG_P (op))
778     return 0;
779
780   /* We must protect ourselves from matching pseudos that are virtual
781      register, because they will eventually be replaced with hardware
782      registers that aren't branch-target registers.  */
783   if (REGNO (op) > LAST_VIRTUAL_REGISTER
784       || TARGET_REGISTER_P (REGNO (op)))
785     return 1;
786
787   return 0;
788 })
789
790 ;; TODO: Add a comment here.
791
792 (define_special_predicate "trunc_hi_operand"
793   (match_code "subreg,reg,truncate")
794 {
795   enum machine_mode op_mode = GET_MODE (op);
796
797   if (op_mode != SImode && op_mode != DImode
798       && op_mode != V4HImode && op_mode != V2SImode)
799     return 0;
800   return extend_reg_operand (op, mode);
801 })
802
803 ;; Return 1 of OP is an address suitable for an unaligned access instruction.
804
805 (define_special_predicate "ua_address_operand"
806   (match_code "subreg,reg,plus")
807 {
808   if (GET_CODE (op) == PLUS
809       && (! satisfies_constraint_I06 (XEXP (op, 1))))
810     return 0;
811   return address_operand (op, QImode);
812 })
813
814 ;; TODO: Add a comment here.
815
816 (define_predicate "ua_offset"
817   (match_code "const_int")
818 {
819   return satisfies_constraint_I06 (op);
820 })
821
822 ;; TODO: Add a comment here.
823
824 (define_predicate "unary_float_operator"
825   (and (match_code "abs,neg,sqrt")
826        (match_test "GET_MODE (op) == mode")))
827
828 ;; Return 1 if OP is a valid source operand for xor.
829
830 (define_predicate "xor_operand"
831   (match_code "subreg,reg,const_int")
832 {
833   if (CONST_INT_P (op))
834     return (TARGET_SHMEDIA
835             ? (satisfies_constraint_I06 (op)
836                || (!can_create_pseudo_p () && INTVAL (op) == 0xff))
837             : satisfies_constraint_K08 (op));
838   if (TARGET_SHMEDIA
839       && mode != DImode && GET_CODE (op) == SUBREG
840       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
841     return 0;
842   return arith_reg_operand (op, mode);
843 })
844
845 (define_predicate "bitwise_memory_operand"
846   (match_code "mem")
847 {
848   if (MEM_P (op))
849     {
850       if (REG_P (XEXP (op, 0)))
851         return 1;
852
853       if (GET_CODE (XEXP (op, 0)) == PLUS
854           && REG_P (XEXP (XEXP (op, 0), 0))
855           && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1)))
856         return 1;
857     }
858   return 0;
859 })