OSDN Git Service

Add NIOS2 support. Code from SourceyG++.
[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 (TARGET_SHMEDIA
398       && (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR)
399       && sh_rep_vec (op, mode))
400     return 1;
401   if (TARGET_SHMEDIA && 1
402       && GET_CODE (op) == SUBREG && GET_MODE (op) == mode
403       && SUBREG_REG (op) == const0_rtx && subreg_lowpart_p (op))
404     /* FIXME */ abort (); /* return 1; */
405   return general_operand (op, mode);
406 })
407
408 ;; Returns 1 if OP can be a destination of a move. Same as
409 ;; general_operand, but no preinc allowed.
410
411 (define_predicate "general_movdst_operand"
412   (match_code "subreg,reg,mem")
413 {
414   /* Only pre dec allowed.  */
415   if (MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC)
416     return 0;
417   if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG
418       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
419       && ! (high_life_started || reload_completed))
420     return 0;
421
422   return general_operand (op, mode);
423 })
424
425
426 ;; Returns 1 if OP is a POST_INC on stack pointer register.
427
428 (define_predicate "sh_no_delay_pop_operand"
429   (match_code "mem")
430 {
431   rtx inside;
432   inside = XEXP (op, 0);
433
434   if (GET_CODE (op) == MEM && GET_MODE (op) == SImode 
435       && GET_CODE (inside) == POST_INC 
436       && GET_CODE (XEXP (inside, 0)) == REG
437       && REGNO (XEXP (inside, 0)) == SP_REG)
438     return 1;
439
440   return 0;
441 })
442
443
444 ;; Returns 1 if OP is a MEM that can be source of a simple move operation.
445
446 (define_predicate "unaligned_load_operand"
447   (match_code "mem")
448 {
449   rtx inside;
450
451   if (!MEM_P (op) || GET_MODE (op) != mode)
452     return 0;
453
454   inside = XEXP (op, 0);
455
456   if (GET_CODE (inside) == POST_INC)
457     inside = XEXP (inside, 0);
458
459   if (REG_P (inside))
460     return 1;
461
462   return 0;
463 })
464
465 ;; TODO: Add a comment here.
466
467 (define_predicate "greater_comparison_operator"
468   (match_code "gt,ge,gtu,geu"))
469
470 ;; TODO: Add a comment here.
471
472 (define_predicate "inqhi_operand"
473   (match_code "truncate")
474 {
475   if (GET_CODE (op) != TRUNCATE || mode != GET_MODE (op))
476     return 0;
477   op = XEXP (op, 0);
478   /* Can't use true_regnum here because copy_cost wants to know about
479      SECONDARY_INPUT_RELOAD_CLASS.  */
480   return REG_P (op) && FP_REGISTER_P (REGNO (op));
481 })
482
483 ;; TODO: Add a comment here.
484
485 (define_special_predicate "int_gpr_dest"
486   (match_code "subreg,reg")
487 {
488   enum machine_mode op_mode = GET_MODE (op);
489
490   if (GET_MODE_CLASS (op_mode) != MODE_INT
491       || GET_MODE_SIZE (op_mode) >= UNITS_PER_WORD)
492     return 0;
493   if (! reload_completed)
494     return 0;
495   return true_regnum (op) <= LAST_GENERAL_REG;
496 })
497
498 ;; TODO: Add a comment here.
499
500 (define_predicate "less_comparison_operator"
501   (match_code "lt,le,ltu,leu"))
502
503 ;; Returns 1 if OP is a valid source operand for a logical operation.
504
505 (define_predicate "logical_operand"
506   (match_code "subreg,reg,const_int")
507 {
508   if (TARGET_SHMEDIA
509       && mode != DImode && GET_CODE (op) == SUBREG
510       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
511     return 0;
512
513   if (arith_reg_operand (op, mode))
514     return 1;
515
516   if (TARGET_SHMEDIA)
517     {
518       if (satisfies_constraint_I10 (op))
519         return 1;
520       else
521         return 0;
522     }
523   else if (satisfies_constraint_K08 (op))
524     return 1;
525
526   return 0;
527 })
528
529 ;; TODO: Add a comment here.
530
531 (define_predicate "logical_operator"
532   (match_code "and,ior,xor"))
533
534 ;; Like arith_reg_operand, but for register source operands of narrow
535 ;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs.
536
537 (define_predicate "logical_reg_operand"
538   (match_code "subreg,reg")
539 {
540   if (TARGET_SHMEDIA
541       && GET_CODE (op) == SUBREG
542       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4
543       && mode != DImode)
544     return 0;
545   return arith_reg_operand (op, mode);
546 })
547
548 ;; TODO: Add a comment here.
549
550 (define_predicate "mextr_bit_offset"
551   (match_code "const_int")
552 {
553   HOST_WIDE_INT i;
554
555   if (!CONST_INT_P (op))
556     return 0;
557   i = INTVAL (op);
558   return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0;
559 })
560
561 ;; TODO: Add a comment here.
562
563 (define_predicate "minuend_operand"
564   (match_code "subreg,reg,truncate,const_int")
565 {
566   return op == constm1_rtx || extend_reg_or_0_operand (op, mode);
567 })
568
569 ;; TODO: Add a comment here.
570
571 (define_predicate "noncommutative_float_operator"
572   (and (match_code "minus,div")
573        (match_test "GET_MODE (op) == mode")))
574
575 ;; UNORDERED is only supported on SHMEDIA.
576
577 (define_predicate "sh_float_comparison_operator"
578   (ior (match_operand 0 "ordered_comparison_operator")
579        (and (match_test "TARGET_SHMEDIA")
580             (match_code "unordered"))))
581
582 (define_predicate "shmedia_cbranch_comparison_operator"
583   (ior (match_operand 0 "equality_comparison_operator")
584        (match_operand 0 "greater_comparison_operator")))
585
586 ;; TODO: Add a comment here.
587
588 (define_predicate "sh_const_vec"
589   (match_code "const_vector")
590 {
591   int i;
592
593   if (GET_CODE (op) != CONST_VECTOR
594       || (GET_MODE (op) != mode && mode != VOIDmode))
595     return 0;
596   i = XVECLEN (op, 0) - 1;
597   for (; i >= 0; i--)
598     if (!CONST_INT_P (XVECEXP (op, 0, i)))
599       return 0;
600   return 1;
601 })
602
603 ;; Determine if OP is a constant vector matching MODE with only one
604 ;; element that is not a sign extension.  Two byte-sized elements
605 ;; count as one.
606
607 (define_predicate "sh_1el_vec"
608   (match_code "const_vector")
609 {
610   int unit_size;
611   int i, last, least, sign_ix;
612   rtx sign;
613
614   if (GET_CODE (op) != CONST_VECTOR
615       || (GET_MODE (op) != mode && mode != VOIDmode))
616     return 0;
617   /* Determine numbers of last and of least significant elements.  */
618   last = XVECLEN (op, 0) - 1;
619   least = TARGET_LITTLE_ENDIAN ? 0 : last;
620   if (!CONST_INT_P (XVECEXP (op, 0, least)))
621     return 0;
622   sign_ix = least;
623   if (GET_MODE_UNIT_SIZE (mode) == 1)
624     sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
625   if (!CONST_INT_P (XVECEXP (op, 0, sign_ix)))
626     return 0;
627   unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
628   sign = (INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
629           ? constm1_rtx : const0_rtx);
630   i = XVECLEN (op, 0) - 1;
631   do
632     if (i != least && i != sign_ix && XVECEXP (op, 0, i) != sign)
633       return 0;
634   while (--i);
635   return 1;
636 })
637
638 ;; Like register_operand, but take into account that SHMEDIA can use
639 ;; the constant zero like a general register.
640
641 (define_predicate "sh_register_operand"
642   (match_code "reg,subreg,const_int,const_double")
643 {
644   if (op == CONST0_RTX (mode) && TARGET_SHMEDIA)
645     return 1;
646   return register_operand (op, mode);
647 })
648
649 ;; TODO: Add a comment here.
650
651 (define_predicate "sh_rep_vec"
652   (match_code "const_vector,parallel")
653 {
654   int i;
655   rtx x, y;
656
657   if ((GET_CODE (op) != CONST_VECTOR && GET_CODE (op) != PARALLEL)
658       || (GET_MODE (op) != mode && mode != VOIDmode))
659     return 0;
660   i = XVECLEN (op, 0) - 2;
661   x = XVECEXP (op, 0, i + 1);
662   if (GET_MODE_UNIT_SIZE (mode) == 1)
663     {
664       y = XVECEXP (op, 0, i);
665       for (i -= 2; i >= 0; i -= 2)
666         if (! rtx_equal_p (XVECEXP (op, 0, i + 1), x)
667             || ! rtx_equal_p (XVECEXP (op, 0, i), y))
668           return 0;
669     }
670   else
671     for (; i >= 0; i--)
672       if (XVECEXP (op, 0, i) != x)
673         return 0;
674   return 1;
675 })
676
677 ;; TODO: Add a comment here.
678
679 (define_predicate "shift_count_operand"
680   (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,zero_extend,sign_extend")
681 {
682   return (CONSTANT_P (op)
683           ? (CONST_INT_P (op)
684              ? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode)
685              : nonmemory_operand (op, mode))
686           : shift_count_reg_operand (op, mode));
687 })
688
689 ;; TODO: Add a comment here.
690
691 (define_predicate "shift_count_reg_operand"
692   (match_code "subreg,reg,zero_extend,sign_extend")
693 {
694   if ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
695        || (GET_CODE (op) == SUBREG && SUBREG_BYTE (op) == 0))
696       && (mode == VOIDmode || mode == GET_MODE (op))
697       && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
698       && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT)
699     {
700       mode = VOIDmode;
701       do
702         op = XEXP (op, 0);
703       while ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
704               || GET_CODE (op) == TRUNCATE)
705              && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
706              && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT);
707
708     }
709   return arith_reg_operand (op, mode);
710 })
711
712 ;; TODO: Add a comment here.
713
714 (define_predicate "shift_operator"
715   (match_code "ashift,ashiftrt,lshiftrt"))
716
717 ;; TODO: Add a comment here.
718
719 (define_predicate "symbol_ref_operand"
720   (match_code "symbol_ref"))
721
722 ;; Same as target_reg_operand, except that label_refs and symbol_refs
723 ;; are accepted before reload.
724
725 (define_special_predicate "target_operand"
726   (match_code "subreg,reg,label_ref,symbol_ref,const,unspec")
727 {
728   if (mode != VOIDmode && mode != Pmode)
729     return 0;
730
731   if ((GET_MODE (op) == Pmode || GET_MODE (op) == VOIDmode)
732       && satisfies_constraint_Csy (op))
733     return ! reload_completed;
734
735   return target_reg_operand (op, mode);
736 })
737
738 ;; Accept pseudos and branch target registers.
739
740 (define_special_predicate "target_reg_operand"
741   (match_code "subreg,reg")
742 {
743   if (mode == VOIDmode
744      ? GET_MODE (op) != Pmode && GET_MODE (op) != PDImode
745      : mode != GET_MODE (op))
746     return 0;
747
748   if (GET_CODE (op) == SUBREG)
749     op = XEXP (op, 0);
750
751   if (!REG_P (op))
752     return 0;
753
754   /* We must protect ourselves from matching pseudos that are virtual
755      register, because they will eventually be replaced with hardware
756      registers that aren't branch-target registers.  */
757   if (REGNO (op) > LAST_VIRTUAL_REGISTER
758       || TARGET_REGISTER_P (REGNO (op)))
759     return 1;
760
761   return 0;
762 })
763
764 ;; TODO: Add a comment here.
765
766 (define_special_predicate "trunc_hi_operand"
767   (match_code "subreg,reg,truncate")
768 {
769   enum machine_mode op_mode = GET_MODE (op);
770
771   if (op_mode != SImode && op_mode != DImode
772       && op_mode != V4HImode && op_mode != V2SImode)
773     return 0;
774   return extend_reg_operand (op, mode);
775 })
776
777 ;; Return 1 of OP is an address suitable for an unaligned access instruction.
778
779 (define_special_predicate "ua_address_operand"
780   (match_code "subreg,reg,plus")
781 {
782   if (GET_CODE (op) == PLUS
783       && (! satisfies_constraint_I06 (XEXP (op, 1))))
784     return 0;
785   return address_operand (op, QImode);
786 })
787
788 ;; TODO: Add a comment here.
789
790 (define_predicate "ua_offset"
791   (match_code "const_int")
792 {
793   return satisfies_constraint_I06 (op);
794 })
795
796 ;; TODO: Add a comment here.
797
798 (define_predicate "unary_float_operator"
799   (and (match_code "abs,neg,sqrt")
800        (match_test "GET_MODE (op) == mode")))
801
802 ;; Return 1 if OP is a valid source operand for xor.
803
804 (define_predicate "xor_operand"
805   (match_code "subreg,reg,const_int")
806 {
807   if (CONST_INT_P (op))
808     return (TARGET_SHMEDIA
809             ? (satisfies_constraint_I06 (op)
810                || (!can_create_pseudo_p () && INTVAL (op) == 0xff))
811             : satisfies_constraint_K08 (op));
812   if (TARGET_SHMEDIA
813       && mode != DImode && GET_CODE (op) == SUBREG
814       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
815     return 0;
816   return arith_reg_operand (op, mode);
817 })
818
819 (define_predicate "bitwise_memory_operand"
820   (match_code "mem")
821 {
822   if (MEM_P (op))
823     {
824       if (REG_P (XEXP (op, 0)))
825         return 1;
826
827       if (GET_CODE (XEXP (op, 0)) == PLUS
828           && REG_P (XEXP (XEXP (op, 0), 0))
829           && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1)))
830         return 1;
831     }
832   return 0;
833 })