OSDN Git Service

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