OSDN Git Service

* simplify-rtx.c (avoid_constant_pool_reference): Coerce
[pf3gnuchains/gcc-fork.git] / gcc / simplify-rtx.c
1 /* RTL simplification functions for GNU compiler.
2    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC 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 2, or (at your option)
10 any later version.
11
12 GNU CC 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 GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22
23 #include "config.h"
24 #include "system.h"
25 #include <setjmp.h>
26
27 #include "rtl.h"
28 #include "tm_p.h"
29 #include "regs.h"
30 #include "hard-reg-set.h"
31 #include "flags.h"
32 #include "real.h"
33 #include "insn-config.h"
34 #include "recog.h"
35 #include "function.h"
36 #include "expr.h"
37 #include "toplev.h"
38 #include "output.h"
39 #include "ggc.h"
40
41 /* Simplification and canonicalization of RTL.  */
42
43 /* Nonzero if X has the form (PLUS frame-pointer integer).  We check for
44    virtual regs here because the simplify_*_operation routines are called
45    by integrate.c, which is called before virtual register instantiation.
46
47    ?!? FIXED_BASE_PLUS_P and NONZERO_BASE_PLUS_P need to move into 
48    a header file so that their definitions can be shared with the
49    simplification routines in simplify-rtx.c.  Until then, do not
50    change these macros without also changing the copy in simplify-rtx.c.  */
51
52 #define FIXED_BASE_PLUS_P(X)                                    \
53   ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx    \
54    || ((X) == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])\
55    || (X) == virtual_stack_vars_rtx                             \
56    || (X) == virtual_incoming_args_rtx                          \
57    || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
58        && (XEXP (X, 0) == frame_pointer_rtx                     \
59            || XEXP (X, 0) == hard_frame_pointer_rtx             \
60            || ((X) == arg_pointer_rtx                           \
61                && fixed_regs[ARG_POINTER_REGNUM])               \
62            || XEXP (X, 0) == virtual_stack_vars_rtx             \
63            || XEXP (X, 0) == virtual_incoming_args_rtx))        \
64    || GET_CODE (X) == ADDRESSOF)
65
66 /* Similar, but also allows reference to the stack pointer.
67
68    This used to include FIXED_BASE_PLUS_P, however, we can't assume that
69    arg_pointer_rtx by itself is nonzero, because on at least one machine,
70    the i960, the arg pointer is zero when it is unused.  */
71
72 #define NONZERO_BASE_PLUS_P(X)                                  \
73   ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx    \
74    || (X) == virtual_stack_vars_rtx                             \
75    || (X) == virtual_incoming_args_rtx                          \
76    || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
77        && (XEXP (X, 0) == frame_pointer_rtx                     \
78            || XEXP (X, 0) == hard_frame_pointer_rtx             \
79            || ((X) == arg_pointer_rtx                           \
80                && fixed_regs[ARG_POINTER_REGNUM])               \
81            || XEXP (X, 0) == virtual_stack_vars_rtx             \
82            || XEXP (X, 0) == virtual_incoming_args_rtx))        \
83    || (X) == stack_pointer_rtx                                  \
84    || (X) == virtual_stack_dynamic_rtx                          \
85    || (X) == virtual_outgoing_args_rtx                          \
86    || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
87        && (XEXP (X, 0) == stack_pointer_rtx                     \
88            || XEXP (X, 0) == virtual_stack_dynamic_rtx          \
89            || XEXP (X, 0) == virtual_outgoing_args_rtx))        \
90    || GET_CODE (X) == ADDRESSOF)
91
92 /* Much code operates on (low, high) pairs; the low value is an
93    unsigned wide int, the high value a signed wide int.  We
94    occasionally need to sign extend from low to high as if low were a
95    signed wide int.  */
96 #define HWI_SIGN_EXTEND(low) \
97  ((((HOST_WIDE_INT) low) < 0) ? ((HOST_WIDE_INT) -1) : ((HOST_WIDE_INT) 0))
98
99 static rtx simplify_plus_minus          PARAMS ((enum rtx_code,
100                                                  enum machine_mode, rtx, rtx));
101 static void check_fold_consts           PARAMS ((PTR));
102 static rtx avoid_constant_pool_reference PARAMS ((rtx));
103 \f
104 /* Make a binary operation by properly ordering the operands and 
105    seeing if the expression folds.  */
106
107 rtx
108 simplify_gen_binary (code, mode, op0, op1)
109      enum rtx_code code;
110      enum machine_mode mode;
111      rtx op0, op1;
112 {
113   rtx tem;
114
115   /* Put complex operands first and constants second if commutative.  */
116   if (GET_RTX_CLASS (code) == 'c'
117       && swap_commutative_operands_p (op0, op1))
118     tem = op0, op0 = op1, op1 = tem;
119
120   /* If this simplifies, do it.  */
121   tem = simplify_binary_operation (code, mode, op0, op1);
122
123   if (tem)
124     return tem;
125
126   /* Handle addition and subtraction of CONST_INT specially.  Otherwise,
127      just form the operation.  */
128
129   if (code == PLUS && GET_CODE (op1) == CONST_INT
130       && GET_MODE (op0) != VOIDmode)
131     return plus_constant (op0, INTVAL (op1));
132   else if (code == MINUS && GET_CODE (op1) == CONST_INT
133            && GET_MODE (op0) != VOIDmode)
134     return plus_constant (op0, - INTVAL (op1));
135   else
136     return gen_rtx_fmt_ee (code, mode, op0, op1);
137 }
138 \f
139 /* If X is a MEM referencing the constant pool, return the real value.
140    Otherwise return X.  */
141 static rtx
142 avoid_constant_pool_reference (x)
143      rtx x;
144 {
145   rtx c, addr;
146   enum machine_mode cmode;
147
148   if (GET_CODE (x) != MEM)
149     return x;
150   addr = XEXP (x, 0);
151
152   if (GET_CODE (addr) != SYMBOL_REF
153       || ! CONSTANT_POOL_ADDRESS_P (addr))
154     return x;
155
156   c = get_pool_constant (addr);
157   cmode = get_pool_mode (addr);
158
159   /* If we're accessing the constant in a different mode than it was
160      originally stored, attempt to fix that up via subreg simplifications.
161      If that fails we have no choice but to return the original memory.  */
162   if (cmode != GET_MODE (x))
163     {
164       c = simplify_subreg (GET_MODE (x), c, cmode, 0);
165       return c ? c : x;
166     }
167
168   return c;
169 }
170 \f
171 /* Make a unary operation by first seeing if it folds and otherwise making
172    the specified operation.  */
173
174 rtx
175 simplify_gen_unary (code, mode, op, op_mode)
176      enum rtx_code code;
177      enum machine_mode mode;
178      rtx op;
179      enum machine_mode op_mode;
180 {
181   rtx tem;
182
183   /* If this simplifies, use it.  */
184   if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
185     return tem;
186
187   return gen_rtx_fmt_e (code, mode, op);
188 }
189
190 /* Likewise for ternary operations.  */
191
192 rtx
193 simplify_gen_ternary (code, mode, op0_mode, op0, op1, op2)
194      enum rtx_code code;
195      enum machine_mode mode, op0_mode;
196      rtx op0, op1, op2;
197 {
198   rtx tem;
199
200   /* If this simplifies, use it.  */
201   if (0 != (tem = simplify_ternary_operation (code, mode, op0_mode,
202                                               op0, op1, op2)))
203     return tem;
204
205   return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
206 }
207 \f
208 /* Likewise, for relational operations.
209    CMP_MODE specifies mode comparison is done in.
210   */
211
212 rtx
213 simplify_gen_relational (code, mode, cmp_mode, op0, op1)
214      enum rtx_code code;
215      enum machine_mode mode;
216      enum machine_mode cmp_mode;
217      rtx op0, op1;
218 {
219   rtx tem;
220
221   if ((tem = simplify_relational_operation (code, cmp_mode, op0, op1)) != 0)
222     return tem;
223
224   /* Put complex operands first and constants second.  */
225   if (swap_commutative_operands_p (op0, op1))
226     tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
227
228   return gen_rtx_fmt_ee (code, mode, op0, op1);
229 }
230 \f
231 /* Replace all occurrences of OLD in X with NEW and try to simplify the
232    resulting RTX.  Return a new RTX which is as simplified as possible.  */
233
234 rtx
235 simplify_replace_rtx (x, old, new)
236      rtx x;
237      rtx old;
238      rtx new;
239 {
240   enum rtx_code code = GET_CODE (x);
241   enum machine_mode mode = GET_MODE (x);
242
243   /* If X is OLD, return NEW.  Otherwise, if this is an expression, try
244      to build a new expression substituting recursively.  If we can't do
245      anything, return our input.  */
246
247   if (x == old)
248     return new;
249
250   switch (GET_RTX_CLASS (code))
251     {
252     case '1':
253       {
254         enum machine_mode op_mode = GET_MODE (XEXP (x, 0));
255         rtx op = (XEXP (x, 0) == old
256                   ? new : simplify_replace_rtx (XEXP (x, 0), old, new));
257
258         return simplify_gen_unary (code, mode, op, op_mode);
259       }
260
261     case '2':
262     case 'c':
263       return
264         simplify_gen_binary (code, mode,
265                              simplify_replace_rtx (XEXP (x, 0), old, new),
266                              simplify_replace_rtx (XEXP (x, 1), old, new));
267     case '<':
268       {
269         enum machine_mode op_mode = (GET_MODE (XEXP (x, 0)) != VOIDmode
270                                      ? GET_MODE (XEXP (x, 0))
271                                      : GET_MODE (XEXP (x, 1)));
272         rtx op0 = simplify_replace_rtx (XEXP (x, 0), old, new);
273         rtx op1 = simplify_replace_rtx (XEXP (x, 1), old, new);
274
275         return
276           simplify_gen_relational (code, mode,
277                                    (op_mode != VOIDmode
278                                     ? op_mode
279                                     : GET_MODE (op0) != VOIDmode
280                                     ? GET_MODE (op0)
281                                     : GET_MODE (op1)),
282                                    op0, op1);
283       }
284
285     case '3':
286     case 'b':
287       {
288         enum machine_mode op_mode = GET_MODE (XEXP (x, 0));
289         rtx op0 = simplify_replace_rtx (XEXP (x, 0), old, new);
290
291         return
292           simplify_gen_ternary (code, mode, 
293                                 (op_mode != VOIDmode
294                                  ? op_mode
295                                  : GET_MODE (op0)),
296                                 op0,
297                                 simplify_replace_rtx (XEXP (x, 1), old, new),
298                                 simplify_replace_rtx (XEXP (x, 2), old, new));
299       }
300
301     case 'x':
302       /* The only case we try to handle is a SUBREG.  */
303       if (code == SUBREG)
304         {
305           rtx exp;
306           exp = simplify_gen_subreg (GET_MODE (x),
307                                      simplify_replace_rtx (SUBREG_REG (x),
308                                                            old, new),
309                                      GET_MODE (SUBREG_REG (x)),
310                                      SUBREG_BYTE (x));
311           if (exp)
312            x = exp;
313         }
314       return x;
315
316     default:
317       if (GET_CODE (x) == MEM)
318         return
319           replace_equiv_address_nv (x,
320                                     simplify_replace_rtx (XEXP (x, 0),
321                                                           old, new));
322
323       return x;
324     }
325   return x;
326 }
327 \f
328 /* Try to simplify a unary operation CODE whose output mode is to be
329    MODE with input operand OP whose mode was originally OP_MODE.
330    Return zero if no simplification can be made.  */
331
332 rtx
333 simplify_unary_operation (code, mode, op, op_mode)
334      enum rtx_code code;
335      enum machine_mode mode;
336      rtx op;
337      enum machine_mode op_mode;
338 {
339   unsigned int width = GET_MODE_BITSIZE (mode);
340   rtx trueop = avoid_constant_pool_reference (op);
341
342   /* The order of these tests is critical so that, for example, we don't
343      check the wrong mode (input vs. output) for a conversion operation,
344      such as FIX.  At some point, this should be simplified.  */
345
346 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
347
348   if (code == FLOAT && GET_MODE (trueop) == VOIDmode
349       && (GET_CODE (trueop) == CONST_DOUBLE || GET_CODE (trueop) == CONST_INT))
350     {
351       HOST_WIDE_INT hv, lv;
352       REAL_VALUE_TYPE d;
353
354       if (GET_CODE (trueop) == CONST_INT)
355         lv = INTVAL (trueop), hv = HWI_SIGN_EXTEND (lv);
356       else
357         lv = CONST_DOUBLE_LOW (trueop),  hv = CONST_DOUBLE_HIGH (trueop);
358
359 #ifdef REAL_ARITHMETIC
360       REAL_VALUE_FROM_INT (d, lv, hv, mode);
361 #else
362       if (hv < 0)
363         {
364           d = (double) (~ hv);
365           d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
366                 * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
367           d += (double) (unsigned HOST_WIDE_INT) (~ lv);
368           d = (- d - 1.0);
369         }
370       else
371         {
372           d = (double) hv;
373           d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
374                 * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
375           d += (double) (unsigned HOST_WIDE_INT) lv;
376         }
377 #endif  /* REAL_ARITHMETIC */
378       d = real_value_truncate (mode, d);
379       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
380     }
381   else if (code == UNSIGNED_FLOAT && GET_MODE (trueop) == VOIDmode
382            && (GET_CODE (trueop) == CONST_DOUBLE
383                || GET_CODE (trueop) == CONST_INT))
384     {
385       HOST_WIDE_INT hv, lv;
386       REAL_VALUE_TYPE d;
387
388       if (GET_CODE (trueop) == CONST_INT)
389         lv = INTVAL (trueop), hv = HWI_SIGN_EXTEND (lv);
390       else
391         lv = CONST_DOUBLE_LOW (trueop),  hv = CONST_DOUBLE_HIGH (trueop);
392
393       if (op_mode == VOIDmode)
394         {
395           /* We don't know how to interpret negative-looking numbers in
396              this case, so don't try to fold those.  */
397           if (hv < 0)
398             return 0;
399         }
400       else if (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT * 2)
401         ;
402       else
403         hv = 0, lv &= GET_MODE_MASK (op_mode);
404
405 #ifdef REAL_ARITHMETIC
406       REAL_VALUE_FROM_UNSIGNED_INT (d, lv, hv, mode);
407 #else
408
409       d = (double) (unsigned HOST_WIDE_INT) hv;
410       d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
411             * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
412       d += (double) (unsigned HOST_WIDE_INT) lv;
413 #endif  /* REAL_ARITHMETIC */
414       d = real_value_truncate (mode, d);
415       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
416     }
417 #endif
418
419   if (GET_CODE (trueop) == CONST_INT
420       && width <= HOST_BITS_PER_WIDE_INT && width > 0)
421     {
422       register HOST_WIDE_INT arg0 = INTVAL (trueop);
423       register HOST_WIDE_INT val;
424
425       switch (code)
426         {
427         case NOT:
428           val = ~ arg0;
429           break;
430
431         case NEG:
432           val = - arg0;
433           break;
434
435         case ABS:
436           val = (arg0 >= 0 ? arg0 : - arg0);
437           break;
438
439         case FFS:
440           /* Don't use ffs here.  Instead, get low order bit and then its
441              number.  If arg0 is zero, this will return 0, as desired.  */
442           arg0 &= GET_MODE_MASK (mode);
443           val = exact_log2 (arg0 & (- arg0)) + 1;
444           break;
445
446         case TRUNCATE:
447           val = arg0;
448           break;
449
450         case ZERO_EXTEND:
451           if (op_mode == VOIDmode)
452             op_mode = mode;
453           if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
454             {
455               /* If we were really extending the mode,
456                  we would have to distinguish between zero-extension
457                  and sign-extension.  */
458               if (width != GET_MODE_BITSIZE (op_mode))
459                 abort ();
460               val = arg0;
461             }
462           else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
463             val = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode));
464           else
465             return 0;
466           break;
467
468         case SIGN_EXTEND:
469           if (op_mode == VOIDmode)
470             op_mode = mode;
471           if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
472             {
473               /* If we were really extending the mode,
474                  we would have to distinguish between zero-extension
475                  and sign-extension.  */
476               if (width != GET_MODE_BITSIZE (op_mode))
477                 abort ();
478               val = arg0;
479             }
480           else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
481             {
482               val
483                 = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode));
484               if (val
485                   & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (op_mode) - 1)))
486                 val -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
487             }
488           else
489             return 0;
490           break;
491
492         case SQRT:
493         case FLOAT_EXTEND:
494         case FLOAT_TRUNCATE:
495           return 0;
496
497         default:
498           abort ();
499         }
500
501       val = trunc_int_for_mode (val, mode);
502
503       return GEN_INT (val);
504     }
505
506   /* We can do some operations on integer CONST_DOUBLEs.  Also allow
507      for a DImode operation on a CONST_INT.  */
508   else if (GET_MODE (trueop) == VOIDmode && width <= HOST_BITS_PER_INT * 2
509            && (GET_CODE (trueop) == CONST_DOUBLE
510                || GET_CODE (trueop) == CONST_INT))
511     {
512       unsigned HOST_WIDE_INT l1, lv;
513       HOST_WIDE_INT h1, hv;
514
515       if (GET_CODE (trueop) == CONST_DOUBLE)
516         l1 = CONST_DOUBLE_LOW (trueop), h1 = CONST_DOUBLE_HIGH (trueop);
517       else
518         l1 = INTVAL (trueop), h1 = HWI_SIGN_EXTEND (l1);
519
520       switch (code)
521         {
522         case NOT:
523           lv = ~ l1;
524           hv = ~ h1;
525           break;
526
527         case NEG:
528           neg_double (l1, h1, &lv, &hv);
529           break;
530
531         case ABS:
532           if (h1 < 0)
533             neg_double (l1, h1, &lv, &hv);
534           else
535             lv = l1, hv = h1;
536           break;
537
538         case FFS:
539           hv = 0;
540           if (l1 == 0)
541             lv = HOST_BITS_PER_WIDE_INT + exact_log2 (h1 & (-h1)) + 1;
542           else
543             lv = exact_log2 (l1 & (-l1)) + 1;
544           break;
545
546         case TRUNCATE:
547           /* This is just a change-of-mode, so do nothing.  */
548           lv = l1, hv = h1;
549           break;
550
551         case ZERO_EXTEND:
552           if (op_mode == VOIDmode
553               || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
554             return 0;
555
556           hv = 0;
557           lv = l1 & GET_MODE_MASK (op_mode);
558           break;
559
560         case SIGN_EXTEND:
561           if (op_mode == VOIDmode
562               || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
563             return 0;
564           else
565             {
566               lv = l1 & GET_MODE_MASK (op_mode);
567               if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT
568                   && (lv & ((HOST_WIDE_INT) 1
569                             << (GET_MODE_BITSIZE (op_mode) - 1))) != 0)
570                 lv -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
571
572               hv = HWI_SIGN_EXTEND (lv);
573             }
574           break;
575
576         case SQRT:
577           return 0;
578
579         default:
580           return 0;
581         }
582
583       return immed_double_const (lv, hv, mode);
584     }
585
586 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
587   else if (GET_CODE (trueop) == CONST_DOUBLE
588            && GET_MODE_CLASS (mode) == MODE_FLOAT)
589     {
590       REAL_VALUE_TYPE d;
591       jmp_buf handler;
592       rtx x;
593
594       if (setjmp (handler))
595         /* There used to be a warning here, but that is inadvisable.
596            People may want to cause traps, and the natural way
597            to do it should not get a warning.  */
598         return 0;
599
600       set_float_handler (handler);
601
602       REAL_VALUE_FROM_CONST_DOUBLE (d, trueop);
603
604       switch (code)
605         {
606         case NEG:
607           d = REAL_VALUE_NEGATE (d);
608           break;
609
610         case ABS:
611           if (REAL_VALUE_NEGATIVE (d))
612             d = REAL_VALUE_NEGATE (d);
613           break;
614
615         case FLOAT_TRUNCATE:
616           d = real_value_truncate (mode, d);
617           break;
618
619         case FLOAT_EXTEND:
620           /* All this does is change the mode.  */
621           break;
622
623         case FIX:
624           d = REAL_VALUE_RNDZINT (d);
625           break;
626
627         case UNSIGNED_FIX:
628           d = REAL_VALUE_UNSIGNED_RNDZINT (d);
629           break;
630
631         case SQRT:
632           return 0;
633
634         default:
635           abort ();
636         }
637
638       x = CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
639       set_float_handler (NULL);
640       return x;
641     }
642
643   else if (GET_CODE (trueop) == CONST_DOUBLE
644            && GET_MODE_CLASS (GET_MODE (trueop)) == MODE_FLOAT
645            && GET_MODE_CLASS (mode) == MODE_INT
646            && width <= HOST_BITS_PER_WIDE_INT && width > 0)
647     {
648       REAL_VALUE_TYPE d;
649       jmp_buf handler;
650       HOST_WIDE_INT val;
651
652       if (setjmp (handler))
653         return 0;
654
655       set_float_handler (handler);
656
657       REAL_VALUE_FROM_CONST_DOUBLE (d, trueop);
658
659       switch (code)
660         {
661         case FIX:
662           val = REAL_VALUE_FIX (d);
663           break;
664
665         case UNSIGNED_FIX:
666           val = REAL_VALUE_UNSIGNED_FIX (d);
667           break;
668
669         default:
670           abort ();
671         }
672
673       set_float_handler (NULL);
674
675       val = trunc_int_for_mode (val, mode);
676
677       return GEN_INT (val);
678     }
679 #endif
680   /* This was formerly used only for non-IEEE float.
681      eggert@twinsun.com says it is safe for IEEE also.  */
682   else
683     {
684       enum rtx_code reversed;
685       /* There are some simplifications we can do even if the operands
686          aren't constant.  */
687       switch (code)
688         {
689         case NOT:
690           /* (not (not X)) == X.  */
691           if (GET_CODE (op) == NOT)
692             return XEXP (op, 0);
693
694           /* (not (eq X Y)) == (ne X Y), etc.  */
695           if (mode == BImode && GET_RTX_CLASS (GET_CODE (op)) == '<'
696               && ((reversed = reversed_comparison_code (op, NULL_RTX))
697                   != UNKNOWN))
698             return gen_rtx_fmt_ee (reversed,
699                                    op_mode, XEXP (op, 0), XEXP (op, 1));
700           break;
701
702         case NEG:
703           /* (neg (neg X)) == X.  */
704           if (GET_CODE (op) == NEG)
705             return XEXP (op, 0);
706           break;
707
708         case SIGN_EXTEND:
709           /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
710              becomes just the MINUS if its mode is MODE.  This allows
711              folding switch statements on machines using casesi (such as
712              the Vax).  */
713           if (GET_CODE (op) == TRUNCATE
714               && GET_MODE (XEXP (op, 0)) == mode
715               && GET_CODE (XEXP (op, 0)) == MINUS
716               && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
717               && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
718             return XEXP (op, 0);
719
720 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
721           if (! POINTERS_EXTEND_UNSIGNED
722               && mode == Pmode && GET_MODE (op) == ptr_mode
723               && (CONSTANT_P (op)
724                   || (GET_CODE (op) == SUBREG
725                       && GET_CODE (SUBREG_REG (op)) == REG
726                       && REG_POINTER (SUBREG_REG (op))
727                       && GET_MODE (SUBREG_REG (op)) == Pmode)))
728             return convert_memory_address (Pmode, op);
729 #endif
730           break;
731
732 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
733         case ZERO_EXTEND:
734           if (POINTERS_EXTEND_UNSIGNED > 0
735               && mode == Pmode && GET_MODE (op) == ptr_mode
736               && (CONSTANT_P (op)
737                   || (GET_CODE (op) == SUBREG
738                       && GET_CODE (SUBREG_REG (op)) == REG
739                       && REG_POINTER (SUBREG_REG (op))
740                       && GET_MODE (SUBREG_REG (op)) == Pmode)))
741             return convert_memory_address (Pmode, op);
742           break;
743 #endif
744           
745         default:
746           break;
747         }
748
749       return 0;
750     }
751 }
752 \f
753 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
754    and OP1.  Return 0 if no simplification is possible.
755
756    Don't use this for relational operations such as EQ or LT.
757    Use simplify_relational_operation instead.  */
758
759 rtx
760 simplify_binary_operation (code, mode, op0, op1)
761      enum rtx_code code;
762      enum machine_mode mode;
763      rtx op0, op1;
764 {
765   register HOST_WIDE_INT arg0, arg1, arg0s, arg1s;
766   HOST_WIDE_INT val;
767   unsigned int width = GET_MODE_BITSIZE (mode);
768   rtx tem;
769   rtx trueop0 = avoid_constant_pool_reference (op0);
770   rtx trueop1 = avoid_constant_pool_reference (op1);
771
772   /* Relational operations don't work here.  We must know the mode
773      of the operands in order to do the comparison correctly.
774      Assuming a full word can give incorrect results.
775      Consider comparing 128 with -128 in QImode.  */
776
777   if (GET_RTX_CLASS (code) == '<')
778     abort ();
779
780   /* Make sure the constant is second.  */
781   if (GET_RTX_CLASS (code) == 'c'
782       && swap_commutative_operands_p (trueop0, trueop1))
783     {
784       tem = op0, op0 = op1, op1 = tem;
785       tem = trueop0, trueop0 = trueop1, trueop1 = tem;
786     }
787
788 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
789   if (GET_MODE_CLASS (mode) == MODE_FLOAT
790       && GET_CODE (trueop0) == CONST_DOUBLE
791       && GET_CODE (trueop1) == CONST_DOUBLE
792       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
793     {
794       REAL_VALUE_TYPE f0, f1, value;
795       jmp_buf handler;
796
797       if (setjmp (handler))
798         return 0;
799
800       set_float_handler (handler);
801
802       REAL_VALUE_FROM_CONST_DOUBLE (f0, trueop0);
803       REAL_VALUE_FROM_CONST_DOUBLE (f1, trueop1);
804       f0 = real_value_truncate (mode, f0);
805       f1 = real_value_truncate (mode, f1);
806
807 #ifdef REAL_ARITHMETIC
808 #ifndef REAL_INFINITY
809       if (code == DIV && REAL_VALUES_EQUAL (f1, dconst0))
810         return 0;
811 #endif
812       REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1);
813 #else
814       switch (code)
815         {
816         case PLUS:
817           value = f0 + f1;
818           break;
819         case MINUS:
820           value = f0 - f1;
821           break;
822         case MULT:
823           value = f0 * f1;
824           break;
825         case DIV:
826 #ifndef REAL_INFINITY
827           if (f1 == 0)
828             return 0;
829 #endif
830           value = f0 / f1;
831           break;
832         case SMIN:
833           value = MIN (f0, f1);
834           break;
835         case SMAX:
836           value = MAX (f0, f1);
837           break;
838         default:
839           abort ();
840         }
841 #endif
842
843       value = real_value_truncate (mode, value);
844       set_float_handler (NULL);
845       return CONST_DOUBLE_FROM_REAL_VALUE (value, mode);
846     }
847 #endif  /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
848
849   /* We can fold some multi-word operations.  */
850   if (GET_MODE_CLASS (mode) == MODE_INT
851       && width == HOST_BITS_PER_WIDE_INT * 2
852       && (GET_CODE (trueop0) == CONST_DOUBLE
853           || GET_CODE (trueop0) == CONST_INT)
854       && (GET_CODE (trueop1) == CONST_DOUBLE
855           || GET_CODE (trueop1) == CONST_INT))
856     {
857       unsigned HOST_WIDE_INT l1, l2, lv;
858       HOST_WIDE_INT h1, h2, hv;
859
860       if (GET_CODE (trueop0) == CONST_DOUBLE)
861         l1 = CONST_DOUBLE_LOW (trueop0), h1 = CONST_DOUBLE_HIGH (trueop0);
862       else
863         l1 = INTVAL (trueop0), h1 = HWI_SIGN_EXTEND (l1);
864
865       if (GET_CODE (trueop1) == CONST_DOUBLE)
866         l2 = CONST_DOUBLE_LOW (trueop1), h2 = CONST_DOUBLE_HIGH (trueop1);
867       else
868         l2 = INTVAL (trueop1), h2 = HWI_SIGN_EXTEND (l2);
869
870       switch (code)
871         {
872         case MINUS:
873           /* A - B == A + (-B).  */
874           neg_double (l2, h2, &lv, &hv);
875           l2 = lv, h2 = hv;
876
877           /* .. fall through ...  */
878
879         case PLUS:
880           add_double (l1, h1, l2, h2, &lv, &hv);
881           break;
882
883         case MULT:
884           mul_double (l1, h1, l2, h2, &lv, &hv);
885           break;
886
887         case DIV:  case MOD:   case UDIV:  case UMOD:
888           /* We'd need to include tree.h to do this and it doesn't seem worth
889              it.  */
890           return 0;
891
892         case AND:
893           lv = l1 & l2, hv = h1 & h2;
894           break;
895
896         case IOR:
897           lv = l1 | l2, hv = h1 | h2;
898           break;
899
900         case XOR:
901           lv = l1 ^ l2, hv = h1 ^ h2;
902           break;
903
904         case SMIN:
905           if (h1 < h2
906               || (h1 == h2
907                   && ((unsigned HOST_WIDE_INT) l1
908                       < (unsigned HOST_WIDE_INT) l2)))
909             lv = l1, hv = h1;
910           else
911             lv = l2, hv = h2;
912           break;
913
914         case SMAX:
915           if (h1 > h2
916               || (h1 == h2
917                   && ((unsigned HOST_WIDE_INT) l1
918                       > (unsigned HOST_WIDE_INT) l2)))
919             lv = l1, hv = h1;
920           else
921             lv = l2, hv = h2;
922           break;
923
924         case UMIN:
925           if ((unsigned HOST_WIDE_INT) h1 < (unsigned HOST_WIDE_INT) h2
926               || (h1 == h2
927                   && ((unsigned HOST_WIDE_INT) l1
928                       < (unsigned HOST_WIDE_INT) l2)))
929             lv = l1, hv = h1;
930           else
931             lv = l2, hv = h2;
932           break;
933
934         case UMAX:
935           if ((unsigned HOST_WIDE_INT) h1 > (unsigned HOST_WIDE_INT) h2
936               || (h1 == h2
937                   && ((unsigned HOST_WIDE_INT) l1
938                       > (unsigned HOST_WIDE_INT) l2)))
939             lv = l1, hv = h1;
940           else
941             lv = l2, hv = h2;
942           break;
943
944         case LSHIFTRT:   case ASHIFTRT:
945         case ASHIFT:
946         case ROTATE:     case ROTATERT:
947 #ifdef SHIFT_COUNT_TRUNCATED
948           if (SHIFT_COUNT_TRUNCATED)
949             l2 &= (GET_MODE_BITSIZE (mode) - 1), h2 = 0;
950 #endif
951
952           if (h2 != 0 || l2 >= GET_MODE_BITSIZE (mode))
953             return 0;
954
955           if (code == LSHIFTRT || code == ASHIFTRT)
956             rshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv,
957                            code == ASHIFTRT);
958           else if (code == ASHIFT)
959             lshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv, 1);
960           else if (code == ROTATE)
961             lrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
962           else /* code == ROTATERT */
963             rrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
964           break;
965
966         default:
967           return 0;
968         }
969
970       return immed_double_const (lv, hv, mode);
971     }
972
973   if (GET_CODE (op0) != CONST_INT || GET_CODE (op1) != CONST_INT
974       || width > HOST_BITS_PER_WIDE_INT || width == 0)
975     {
976       /* Even if we can't compute a constant result,
977          there are some cases worth simplifying.  */
978
979       switch (code)
980         {
981         case PLUS:
982           /* In IEEE floating point, x+0 is not the same as x.  Similarly
983              for the other optimizations below.  */
984           if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
985               && FLOAT_MODE_P (mode) && ! flag_unsafe_math_optimizations)
986             break;
987
988           if (trueop1 == CONST0_RTX (mode))
989             return op0;
990
991           /* ((-a) + b) -> (b - a) and similarly for (a + (-b)) */
992           if (GET_CODE (op0) == NEG)
993             return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
994           else if (GET_CODE (op1) == NEG)
995             return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
996
997           /* (~a) + 1 -> -a */
998           if (INTEGRAL_MODE_P (mode)
999               && GET_CODE (op0) == NOT
1000               && trueop1 == const1_rtx)
1001             return gen_rtx_NEG (mode, XEXP (op0, 0));
1002
1003           /* Handle both-operands-constant cases.  We can only add
1004              CONST_INTs to constants since the sum of relocatable symbols
1005              can't be handled by most assemblers.  Don't add CONST_INT
1006              to CONST_INT since overflow won't be computed properly if wider
1007              than HOST_BITS_PER_WIDE_INT.  */
1008
1009           if (CONSTANT_P (op0) && GET_MODE (op0) != VOIDmode
1010               && GET_CODE (op1) == CONST_INT)
1011             return plus_constant (op0, INTVAL (op1));
1012           else if (CONSTANT_P (op1) && GET_MODE (op1) != VOIDmode
1013                    && GET_CODE (op0) == CONST_INT)
1014             return plus_constant (op1, INTVAL (op0));
1015
1016           /* See if this is something like X * C - X or vice versa or
1017              if the multiplication is written as a shift.  If so, we can
1018              distribute and make a new multiply, shift, or maybe just
1019              have X (if C is 2 in the example above).  But don't make
1020              real multiply if we didn't have one before.  */
1021
1022           if (! FLOAT_MODE_P (mode))
1023             {
1024               HOST_WIDE_INT coeff0 = 1, coeff1 = 1;
1025               rtx lhs = op0, rhs = op1;
1026               int had_mult = 0;
1027
1028               if (GET_CODE (lhs) == NEG)
1029                 coeff0 = -1, lhs = XEXP (lhs, 0);
1030               else if (GET_CODE (lhs) == MULT
1031                        && GET_CODE (XEXP (lhs, 1)) == CONST_INT)
1032                 {
1033                   coeff0 = INTVAL (XEXP (lhs, 1)), lhs = XEXP (lhs, 0);
1034                   had_mult = 1;
1035                 }
1036               else if (GET_CODE (lhs) == ASHIFT
1037                        && GET_CODE (XEXP (lhs, 1)) == CONST_INT
1038                        && INTVAL (XEXP (lhs, 1)) >= 0
1039                        && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
1040                 {
1041                   coeff0 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
1042                   lhs = XEXP (lhs, 0);
1043                 }
1044
1045               if (GET_CODE (rhs) == NEG)
1046                 coeff1 = -1, rhs = XEXP (rhs, 0);
1047               else if (GET_CODE (rhs) == MULT
1048                        && GET_CODE (XEXP (rhs, 1)) == CONST_INT)
1049                 {
1050                   coeff1 = INTVAL (XEXP (rhs, 1)), rhs = XEXP (rhs, 0);
1051                   had_mult = 1;
1052                 }
1053               else if (GET_CODE (rhs) == ASHIFT
1054                        && GET_CODE (XEXP (rhs, 1)) == CONST_INT
1055                        && INTVAL (XEXP (rhs, 1)) >= 0
1056                        && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
1057                 {
1058                   coeff1 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
1059                   rhs = XEXP (rhs, 0);
1060                 }
1061
1062               if (rtx_equal_p (lhs, rhs))
1063                 {
1064                   tem = simplify_gen_binary (MULT, mode, lhs,
1065                                         GEN_INT (coeff0 + coeff1));
1066                   return (GET_CODE (tem) == MULT && ! had_mult) ? 0 : tem;
1067                 }
1068             }
1069
1070           /* If one of the operands is a PLUS or a MINUS, see if we can
1071              simplify this by the associative law. 
1072              Don't use the associative law for floating point.
1073              The inaccuracy makes it nonassociative,
1074              and subtle programs can break if operations are associated.  */
1075
1076           if (INTEGRAL_MODE_P (mode)
1077               && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
1078                   || GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS)
1079               && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
1080             return tem;
1081           break;
1082
1083         case COMPARE:
1084 #ifdef HAVE_cc0
1085           /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
1086              using cc0, in which case we want to leave it as a COMPARE
1087              so we can distinguish it from a register-register-copy.
1088
1089              In IEEE floating point, x-0 is not the same as x.  */
1090
1091           if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
1092                || ! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
1093               && trueop1 == CONST0_RTX (mode))
1094             return op0;
1095 #endif
1096
1097           /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags).  */
1098           if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
1099                || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
1100               && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx)
1101             {
1102               rtx xop00 = XEXP (op0, 0);
1103               rtx xop10 = XEXP (op1, 0);
1104
1105 #ifdef HAVE_cc0
1106               if (GET_CODE (xop00) == CC0 && GET_CODE (xop10) == CC0)
1107 #else
1108               if (GET_CODE (xop00) == REG && GET_CODE (xop10) == REG
1109                   && GET_MODE (xop00) == GET_MODE (xop10)
1110                   && REGNO (xop00) == REGNO (xop10)
1111                   && GET_MODE_CLASS (GET_MODE (xop00)) == MODE_CC
1112                   && GET_MODE_CLASS (GET_MODE (xop10)) == MODE_CC)
1113 #endif
1114                 return xop00;
1115             }
1116
1117           break;              
1118         case MINUS:
1119           /* None of these optimizations can be done for IEEE
1120              floating point.  */
1121           if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1122               && FLOAT_MODE_P (mode) && ! flag_unsafe_math_optimizations)
1123             break;
1124
1125           /* We can't assume x-x is 0 even with non-IEEE floating point,
1126              but since it is zero except in very strange circumstances, we
1127              will treat it as zero with -funsafe-math-optimizations.  */
1128           if (rtx_equal_p (trueop0, trueop1)
1129               && ! side_effects_p (op0)
1130               && (! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations))
1131             return CONST0_RTX (mode);
1132
1133           /* Change subtraction from zero into negation.  */
1134           if (trueop0 == CONST0_RTX (mode))
1135             return gen_rtx_NEG (mode, op1);
1136
1137           /* (-1 - a) is ~a.  */
1138           if (trueop0 == constm1_rtx)
1139             return gen_rtx_NOT (mode, op1);
1140
1141           /* Subtracting 0 has no effect.  */
1142           if (trueop1 == CONST0_RTX (mode))
1143             return op0;
1144
1145           /* See if this is something like X * C - X or vice versa or
1146              if the multiplication is written as a shift.  If so, we can
1147              distribute and make a new multiply, shift, or maybe just
1148              have X (if C is 2 in the example above).  But don't make
1149              real multiply if we didn't have one before.  */
1150
1151           if (! FLOAT_MODE_P (mode))
1152             {
1153               HOST_WIDE_INT coeff0 = 1, coeff1 = 1;
1154               rtx lhs = op0, rhs = op1;
1155               int had_mult = 0;
1156
1157               if (GET_CODE (lhs) == NEG)
1158                 coeff0 = -1, lhs = XEXP (lhs, 0);
1159               else if (GET_CODE (lhs) == MULT
1160                        && GET_CODE (XEXP (lhs, 1)) == CONST_INT)
1161                 {
1162                   coeff0 = INTVAL (XEXP (lhs, 1)), lhs = XEXP (lhs, 0);
1163                   had_mult = 1;
1164                 }
1165               else if (GET_CODE (lhs) == ASHIFT
1166                        && GET_CODE (XEXP (lhs, 1)) == CONST_INT
1167                        && INTVAL (XEXP (lhs, 1)) >= 0
1168                        && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
1169                 {
1170                   coeff0 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
1171                   lhs = XEXP (lhs, 0);
1172                 }
1173
1174               if (GET_CODE (rhs) == NEG)
1175                 coeff1 = - 1, rhs = XEXP (rhs, 0);
1176               else if (GET_CODE (rhs) == MULT
1177                        && GET_CODE (XEXP (rhs, 1)) == CONST_INT)
1178                 {
1179                   coeff1 = INTVAL (XEXP (rhs, 1)), rhs = XEXP (rhs, 0);
1180                   had_mult = 1;
1181                 }
1182               else if (GET_CODE (rhs) == ASHIFT
1183                        && GET_CODE (XEXP (rhs, 1)) == CONST_INT
1184                        && INTVAL (XEXP (rhs, 1)) >= 0
1185                        && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
1186                 {
1187                   coeff1 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
1188                   rhs = XEXP (rhs, 0);
1189                 }
1190
1191               if (rtx_equal_p (lhs, rhs))
1192                 {
1193                   tem = simplify_gen_binary (MULT, mode, lhs,
1194                                              GEN_INT (coeff0 - coeff1));
1195                   return (GET_CODE (tem) == MULT && ! had_mult) ? 0 : tem;
1196                 }
1197             }
1198
1199           /* (a - (-b)) -> (a + b).  */
1200           if (GET_CODE (op1) == NEG)
1201             return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
1202
1203           /* If one of the operands is a PLUS or a MINUS, see if we can
1204              simplify this by the associative law. 
1205              Don't use the associative law for floating point.
1206              The inaccuracy makes it nonassociative,
1207              and subtle programs can break if operations are associated.  */
1208
1209           if (INTEGRAL_MODE_P (mode)
1210               && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
1211                   || GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS)
1212               && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
1213             return tem;
1214
1215           /* Don't let a relocatable value get a negative coeff.  */
1216           if (GET_CODE (op1) == CONST_INT && GET_MODE (op0) != VOIDmode)
1217             return plus_constant (op0, - INTVAL (op1));
1218
1219           /* (x - (x & y)) -> (x & ~y) */
1220           if (GET_CODE (op1) == AND)
1221             {
1222              if (rtx_equal_p (op0, XEXP (op1, 0)))
1223                return simplify_gen_binary (AND, mode, op0,
1224                                            gen_rtx_NOT (mode, XEXP (op1, 1)));
1225              if (rtx_equal_p (op0, XEXP (op1, 1)))
1226                return simplify_gen_binary (AND, mode, op0,
1227                                            gen_rtx_NOT (mode, XEXP (op1, 0)));
1228            }
1229           break;
1230
1231         case MULT:
1232           if (trueop1 == constm1_rtx)
1233             {
1234               tem = simplify_unary_operation (NEG, mode, op0, mode);
1235
1236               return tem ? tem : gen_rtx_NEG (mode, op0);
1237             }
1238
1239           /* In IEEE floating point, x*0 is not always 0.  */
1240           if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
1241                || ! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
1242               && trueop1 == CONST0_RTX (mode)
1243               && ! side_effects_p (op0))
1244             return op1;
1245
1246           /* In IEEE floating point, x*1 is not equivalent to x for nans.
1247              However, ANSI says we can drop signals,
1248              so we can do this anyway.  */
1249           if (trueop1 == CONST1_RTX (mode))
1250             return op0;
1251
1252           /* Convert multiply by constant power of two into shift unless
1253              we are still generating RTL.  This test is a kludge.  */
1254           if (GET_CODE (trueop1) == CONST_INT
1255               && (val = exact_log2 (INTVAL (trueop1))) >= 0
1256               /* If the mode is larger than the host word size, and the
1257                  uppermost bit is set, then this isn't a power of two due
1258                  to implicit sign extension.  */
1259               && (width <= HOST_BITS_PER_WIDE_INT
1260                   || val != HOST_BITS_PER_WIDE_INT - 1)
1261               && ! rtx_equal_function_value_matters)
1262             return gen_rtx_ASHIFT (mode, op0, GEN_INT (val));
1263
1264           if (GET_CODE (trueop1) == CONST_DOUBLE
1265               && GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_FLOAT)
1266             {
1267               REAL_VALUE_TYPE d;
1268               jmp_buf handler;
1269               int op1is2, op1ism1;
1270
1271               if (setjmp (handler))
1272                 return 0;
1273
1274               set_float_handler (handler);
1275               REAL_VALUE_FROM_CONST_DOUBLE (d, trueop1);
1276               op1is2 = REAL_VALUES_EQUAL (d, dconst2);
1277               op1ism1 = REAL_VALUES_EQUAL (d, dconstm1);
1278               set_float_handler (NULL);
1279
1280               /* x*2 is x+x and x*(-1) is -x */
1281               if (op1is2 && GET_MODE (op0) == mode)
1282                 return gen_rtx_PLUS (mode, op0, copy_rtx (op0));
1283
1284               else if (op1ism1 && GET_MODE (op0) == mode)
1285                 return gen_rtx_NEG (mode, op0);
1286             }
1287           break;
1288
1289         case IOR:
1290           if (trueop1 == const0_rtx)
1291             return op0;
1292           if (GET_CODE (trueop1) == CONST_INT
1293               && ((INTVAL (trueop1) & GET_MODE_MASK (mode))
1294                   == GET_MODE_MASK (mode)))
1295             return op1;
1296           if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
1297             return op0;
1298           /* A | (~A) -> -1 */
1299           if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
1300                || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
1301               && ! side_effects_p (op0)
1302               && GET_MODE_CLASS (mode) != MODE_CC)
1303             return constm1_rtx;
1304           break;
1305
1306         case XOR:
1307           if (trueop1 == const0_rtx)
1308             return op0;
1309           if (GET_CODE (trueop1) == CONST_INT
1310               && ((INTVAL (trueop1) & GET_MODE_MASK (mode))
1311                   == GET_MODE_MASK (mode)))
1312             return gen_rtx_NOT (mode, op0);
1313           if (trueop0 == trueop1 && ! side_effects_p (op0)
1314               && GET_MODE_CLASS (mode) != MODE_CC)
1315             return const0_rtx;
1316           break;
1317
1318         case AND:
1319           if (trueop1 == const0_rtx && ! side_effects_p (op0))
1320             return const0_rtx;
1321           if (GET_CODE (trueop1) == CONST_INT
1322               && ((INTVAL (trueop1) & GET_MODE_MASK (mode))
1323                   == GET_MODE_MASK (mode)))
1324             return op0;
1325           if (trueop0 == trueop1 && ! side_effects_p (op0)
1326               && GET_MODE_CLASS (mode) != MODE_CC)
1327             return op0;
1328           /* A & (~A) -> 0 */
1329           if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
1330                || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
1331               && ! side_effects_p (op0)
1332               && GET_MODE_CLASS (mode) != MODE_CC)
1333             return const0_rtx;
1334           break;
1335
1336         case UDIV:
1337           /* Convert divide by power of two into shift (divide by 1 handled
1338              below).  */
1339           if (GET_CODE (trueop1) == CONST_INT
1340               && (arg1 = exact_log2 (INTVAL (trueop1))) > 0)
1341             return gen_rtx_LSHIFTRT (mode, op0, GEN_INT (arg1));
1342
1343           /* ... fall through ...  */
1344
1345         case DIV:
1346           if (trueop1 == CONST1_RTX (mode))
1347             return op0;
1348
1349           /* In IEEE floating point, 0/x is not always 0.  */
1350           if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
1351                || ! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
1352               && trueop0 == CONST0_RTX (mode)
1353               && ! side_effects_p (op1))
1354             return op0;
1355
1356 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1357           /* Change division by a constant into multiplication.  Only do
1358              this with -funsafe-math-optimizations.  */
1359           else if (GET_CODE (trueop1) == CONST_DOUBLE
1360                    && GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_FLOAT
1361                    && trueop1 != CONST0_RTX (mode)
1362                    && flag_unsafe_math_optimizations)
1363             {
1364               REAL_VALUE_TYPE d;
1365               REAL_VALUE_FROM_CONST_DOUBLE (d, trueop1);
1366
1367               if (! REAL_VALUES_EQUAL (d, dconst0))
1368                 {
1369 #if defined (REAL_ARITHMETIC)
1370                   REAL_ARITHMETIC (d, rtx_to_tree_code (DIV), dconst1, d);
1371                   return gen_rtx_MULT (mode, op0, 
1372                                        CONST_DOUBLE_FROM_REAL_VALUE (d, mode));
1373 #else
1374                   return
1375                     gen_rtx_MULT (mode, op0, 
1376                                   CONST_DOUBLE_FROM_REAL_VALUE (1./d, mode));
1377 #endif
1378                 }
1379             }
1380 #endif
1381           break;
1382
1383         case UMOD:
1384           /* Handle modulus by power of two (mod with 1 handled below).  */
1385           if (GET_CODE (trueop1) == CONST_INT
1386               && exact_log2 (INTVAL (trueop1)) > 0)
1387             return gen_rtx_AND (mode, op0, GEN_INT (INTVAL (op1) - 1));
1388
1389           /* ... fall through ...  */
1390
1391         case MOD:
1392           if ((trueop0 == const0_rtx || trueop1 == const1_rtx)
1393               && ! side_effects_p (op0) && ! side_effects_p (op1))
1394             return const0_rtx;
1395           break;
1396
1397         case ROTATERT:
1398         case ROTATE:
1399           /* Rotating ~0 always results in ~0.  */
1400           if (GET_CODE (trueop0) == CONST_INT && width <= HOST_BITS_PER_WIDE_INT
1401               && (unsigned HOST_WIDE_INT) INTVAL (trueop0) == GET_MODE_MASK (mode)
1402               && ! side_effects_p (op1))
1403             return op0;
1404
1405           /* ... fall through ...  */
1406
1407         case ASHIFT:
1408         case ASHIFTRT:
1409         case LSHIFTRT:
1410           if (trueop1 == const0_rtx)
1411             return op0;
1412           if (trueop0 == const0_rtx && ! side_effects_p (op1))
1413             return op0;
1414           break;
1415
1416         case SMIN:
1417           if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (trueop1) == CONST_INT 
1418               && INTVAL (trueop1) == (HOST_WIDE_INT) 1 << (width -1)
1419               && ! side_effects_p (op0))
1420             return op1;
1421           else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
1422             return op0;
1423           break;
1424            
1425         case SMAX:
1426           if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (trueop1) == CONST_INT
1427               && ((unsigned HOST_WIDE_INT) INTVAL (trueop1)
1428                   == (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode) >> 1)
1429               && ! side_effects_p (op0))
1430             return op1;
1431           else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
1432             return op0;
1433           break;
1434
1435         case UMIN:
1436           if (trueop1 == const0_rtx && ! side_effects_p (op0))
1437             return op1;
1438           else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
1439             return op0;
1440           break;
1441             
1442         case UMAX:
1443           if (trueop1 == constm1_rtx && ! side_effects_p (op0))
1444             return op1;
1445           else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
1446             return op0;
1447           break;
1448
1449         default:
1450           abort ();
1451         }
1452       
1453       return 0;
1454     }
1455
1456   /* Get the integer argument values in two forms:
1457      zero-extended in ARG0, ARG1 and sign-extended in ARG0S, ARG1S.  */
1458
1459   arg0 = INTVAL (trueop0);
1460   arg1 = INTVAL (trueop1);
1461
1462   if (width < HOST_BITS_PER_WIDE_INT)
1463     {
1464       arg0 &= ((HOST_WIDE_INT) 1 << width) - 1;
1465       arg1 &= ((HOST_WIDE_INT) 1 << width) - 1;
1466
1467       arg0s = arg0;
1468       if (arg0s & ((HOST_WIDE_INT) 1 << (width - 1)))
1469         arg0s |= ((HOST_WIDE_INT) (-1) << width);
1470
1471       arg1s = arg1;
1472       if (arg1s & ((HOST_WIDE_INT) 1 << (width - 1)))
1473         arg1s |= ((HOST_WIDE_INT) (-1) << width);
1474     }
1475   else
1476     {
1477       arg0s = arg0;
1478       arg1s = arg1;
1479     }
1480
1481   /* Compute the value of the arithmetic.  */
1482
1483   switch (code)
1484     {
1485     case PLUS:
1486       val = arg0s + arg1s;
1487       break;
1488
1489     case MINUS:
1490       val = arg0s - arg1s;
1491       break;
1492
1493     case MULT:
1494       val = arg0s * arg1s;
1495       break;
1496
1497     case DIV:
1498       if (arg1s == 0
1499           || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
1500               && arg1s == -1))
1501         return 0;
1502       val = arg0s / arg1s;
1503       break;
1504
1505     case MOD:
1506       if (arg1s == 0
1507           || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
1508               && arg1s == -1))
1509         return 0;
1510       val = arg0s % arg1s;
1511       break;
1512
1513     case UDIV:
1514       if (arg1 == 0
1515           || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
1516               && arg1s == -1))
1517         return 0;
1518       val = (unsigned HOST_WIDE_INT) arg0 / arg1;
1519       break;
1520
1521     case UMOD:
1522       if (arg1 == 0
1523           || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
1524               && arg1s == -1))
1525         return 0;
1526       val = (unsigned HOST_WIDE_INT) arg0 % arg1;
1527       break;
1528
1529     case AND:
1530       val = arg0 & arg1;
1531       break;
1532
1533     case IOR:
1534       val = arg0 | arg1;
1535       break;
1536
1537     case XOR:
1538       val = arg0 ^ arg1;
1539       break;
1540
1541     case LSHIFTRT:
1542       /* If shift count is undefined, don't fold it; let the machine do
1543          what it wants.  But truncate it if the machine will do that.  */
1544       if (arg1 < 0)
1545         return 0;
1546
1547 #ifdef SHIFT_COUNT_TRUNCATED
1548       if (SHIFT_COUNT_TRUNCATED)
1549         arg1 %= width;
1550 #endif
1551
1552       val = ((unsigned HOST_WIDE_INT) arg0) >> arg1;
1553       break;
1554
1555     case ASHIFT:
1556       if (arg1 < 0)
1557         return 0;
1558
1559 #ifdef SHIFT_COUNT_TRUNCATED
1560       if (SHIFT_COUNT_TRUNCATED)
1561         arg1 %= width;
1562 #endif
1563
1564       val = ((unsigned HOST_WIDE_INT) arg0) << arg1;
1565       break;
1566
1567     case ASHIFTRT:
1568       if (arg1 < 0)
1569         return 0;
1570
1571 #ifdef SHIFT_COUNT_TRUNCATED
1572       if (SHIFT_COUNT_TRUNCATED)
1573         arg1 %= width;
1574 #endif
1575
1576       val = arg0s >> arg1;
1577
1578       /* Bootstrap compiler may not have sign extended the right shift.
1579          Manually extend the sign to insure bootstrap cc matches gcc.  */
1580       if (arg0s < 0 && arg1 > 0)
1581         val |= ((HOST_WIDE_INT) -1) << (HOST_BITS_PER_WIDE_INT - arg1);
1582
1583       break;
1584
1585     case ROTATERT:
1586       if (arg1 < 0)
1587         return 0;
1588
1589       arg1 %= width;
1590       val = ((((unsigned HOST_WIDE_INT) arg0) << (width - arg1))
1591              | (((unsigned HOST_WIDE_INT) arg0) >> arg1));
1592       break;
1593
1594     case ROTATE:
1595       if (arg1 < 0)
1596         return 0;
1597
1598       arg1 %= width;
1599       val = ((((unsigned HOST_WIDE_INT) arg0) << arg1)
1600              | (((unsigned HOST_WIDE_INT) arg0) >> (width - arg1)));
1601       break;
1602
1603     case COMPARE:
1604       /* Do nothing here.  */
1605       return 0;
1606
1607     case SMIN:
1608       val = arg0s <= arg1s ? arg0s : arg1s;
1609       break;
1610
1611     case UMIN:
1612       val = ((unsigned HOST_WIDE_INT) arg0
1613              <= (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
1614       break;
1615
1616     case SMAX:
1617       val = arg0s > arg1s ? arg0s : arg1s;
1618       break;
1619
1620     case UMAX:
1621       val = ((unsigned HOST_WIDE_INT) arg0
1622              > (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
1623       break;
1624
1625     default:
1626       abort ();
1627     }
1628
1629   val = trunc_int_for_mode (val, mode);
1630
1631   return GEN_INT (val);
1632 }
1633 \f
1634 /* Simplify a PLUS or MINUS, at least one of whose operands may be another
1635    PLUS or MINUS.
1636
1637    Rather than test for specific case, we do this by a brute-force method
1638    and do all possible simplifications until no more changes occur.  Then
1639    we rebuild the operation.  */
1640
1641 static rtx
1642 simplify_plus_minus (code, mode, op0, op1)
1643      enum rtx_code code;
1644      enum machine_mode mode;
1645      rtx op0, op1;
1646 {
1647   rtx ops[8];
1648   int negs[8];
1649   rtx result, tem;
1650   int n_ops = 2, input_ops = 2, input_consts = 0, n_consts = 0;
1651   int first = 1, negate = 0, changed;
1652   int i, j;
1653
1654   memset ((char *) ops, 0, sizeof ops);
1655   
1656   /* Set up the two operands and then expand them until nothing has been
1657      changed.  If we run out of room in our array, give up; this should
1658      almost never happen.  */
1659
1660   ops[0] = op0, ops[1] = op1, negs[0] = 0, negs[1] = (code == MINUS);
1661
1662   changed = 1;
1663   while (changed)
1664     {
1665       changed = 0;
1666
1667       for (i = 0; i < n_ops; i++)
1668         switch (GET_CODE (ops[i]))
1669           {
1670           case PLUS:
1671           case MINUS:
1672             if (n_ops == 7)
1673               return 0;
1674
1675             ops[n_ops] = XEXP (ops[i], 1);
1676             negs[n_ops++] = GET_CODE (ops[i]) == MINUS ? !negs[i] : negs[i];
1677             ops[i] = XEXP (ops[i], 0);
1678             input_ops++;
1679             changed = 1;
1680             break;
1681
1682           case NEG:
1683             ops[i] = XEXP (ops[i], 0);
1684             negs[i] = ! negs[i];
1685             changed = 1;
1686             break;
1687
1688           case CONST:
1689             ops[i] = XEXP (ops[i], 0);
1690             input_consts++;
1691             changed = 1;
1692             break;
1693
1694           case NOT:
1695             /* ~a -> (-a - 1) */
1696             if (n_ops != 7)
1697               {
1698                 ops[n_ops] = constm1_rtx;
1699                 negs[n_ops++] = negs[i];
1700                 ops[i] = XEXP (ops[i], 0);
1701                 negs[i] = ! negs[i];
1702                 changed = 1;
1703               }
1704             break;
1705
1706           case CONST_INT:
1707             if (negs[i])
1708               ops[i] = GEN_INT (- INTVAL (ops[i])), negs[i] = 0, changed = 1;
1709             break;
1710
1711           default:
1712             break;
1713           }
1714     }
1715
1716   /* If we only have two operands, we can't do anything.  */
1717   if (n_ops <= 2)
1718     return 0;
1719
1720   /* Now simplify each pair of operands until nothing changes.  The first
1721      time through just simplify constants against each other.  */
1722
1723   changed = 1;
1724   while (changed)
1725     {
1726       changed = first;
1727
1728       for (i = 0; i < n_ops - 1; i++)
1729         for (j = i + 1; j < n_ops; j++)
1730           if (ops[i] != 0 && ops[j] != 0
1731               && (! first || (CONSTANT_P (ops[i]) && CONSTANT_P (ops[j]))))
1732             {
1733               rtx lhs = ops[i], rhs = ops[j];
1734               enum rtx_code ncode = PLUS;
1735
1736               if (negs[i] && ! negs[j])
1737                 lhs = ops[j], rhs = ops[i], ncode = MINUS;
1738               else if (! negs[i] && negs[j])
1739                 ncode = MINUS;
1740
1741               tem = simplify_binary_operation (ncode, mode, lhs, rhs);
1742               if (tem)
1743                 {
1744                   ops[i] = tem, ops[j] = 0;
1745                   negs[i] = negs[i] && negs[j];
1746                   if (GET_CODE (tem) == NEG)
1747                     ops[i] = XEXP (tem, 0), negs[i] = ! negs[i];
1748
1749                   if (GET_CODE (ops[i]) == CONST_INT && negs[i])
1750                     ops[i] = GEN_INT (- INTVAL (ops[i])), negs[i] = 0;
1751                   changed = 1;
1752                 }
1753             }
1754
1755       first = 0;
1756     }
1757
1758   /* Pack all the operands to the lower-numbered entries and give up if
1759      we didn't reduce the number of operands we had.  Make sure we
1760      count a CONST as two operands.  If we have the same number of
1761      operands, but have made more CONSTs than we had, this is also
1762      an improvement, so accept it.  */
1763
1764   for (i = 0, j = 0; j < n_ops; j++)
1765     if (ops[j] != 0)
1766       {
1767         ops[i] = ops[j], negs[i++] = negs[j];
1768         if (GET_CODE (ops[j]) == CONST)
1769           n_consts++;
1770       }
1771
1772   if (i + n_consts > input_ops
1773       || (i + n_consts == input_ops && n_consts <= input_consts))
1774     return 0;
1775
1776   n_ops = i;
1777
1778   /* If we have a CONST_INT, put it last.  */
1779   for (i = 0; i < n_ops - 1; i++)
1780     if (GET_CODE (ops[i]) == CONST_INT)
1781       {
1782         tem = ops[n_ops - 1], ops[n_ops - 1] = ops[i] , ops[i] = tem;
1783         j = negs[n_ops - 1], negs[n_ops - 1] = negs[i], negs[i] = j;
1784       }
1785
1786   /* Put a non-negated operand first.  If there aren't any, make all
1787      operands positive and negate the whole thing later.  */
1788   for (i = 0; i < n_ops && negs[i]; i++)
1789     ;
1790
1791   if (i == n_ops)
1792     {
1793       for (i = 0; i < n_ops; i++)
1794         negs[i] = 0;
1795       negate = 1;
1796     }
1797   else if (i != 0)
1798     {
1799       tem = ops[0], ops[0] = ops[i], ops[i] = tem;
1800       j = negs[0], negs[0] = negs[i], negs[i] = j;
1801     }
1802
1803   /* Now make the result by performing the requested operations.  */
1804   result = ops[0];
1805   for (i = 1; i < n_ops; i++)
1806     result = simplify_gen_binary (negs[i] ? MINUS : PLUS, mode, result, ops[i]);
1807
1808   return negate ? gen_rtx_NEG (mode, result) : result;
1809 }
1810
1811 struct cfc_args
1812 {
1813   rtx op0, op1;                 /* Input */
1814   int equal, op0lt, op1lt;      /* Output */
1815   int unordered;
1816 };
1817
1818 static void
1819 check_fold_consts (data)
1820   PTR data;
1821 {
1822   struct cfc_args *args = (struct cfc_args *) data;
1823   REAL_VALUE_TYPE d0, d1;
1824
1825   /* We may possibly raise an exception while reading the value.  */
1826   args->unordered = 1;
1827   REAL_VALUE_FROM_CONST_DOUBLE (d0, args->op0);
1828   REAL_VALUE_FROM_CONST_DOUBLE (d1, args->op1);
1829
1830   /* Comparisons of Inf versus Inf are ordered.  */
1831   if (REAL_VALUE_ISNAN (d0)
1832       || REAL_VALUE_ISNAN (d1))
1833     return;
1834   args->equal = REAL_VALUES_EQUAL (d0, d1);
1835   args->op0lt = REAL_VALUES_LESS (d0, d1);
1836   args->op1lt = REAL_VALUES_LESS (d1, d0);
1837   args->unordered = 0;
1838 }
1839
1840 /* Like simplify_binary_operation except used for relational operators.
1841    MODE is the mode of the operands, not that of the result.  If MODE
1842    is VOIDmode, both operands must also be VOIDmode and we compare the
1843    operands in "infinite precision".
1844
1845    If no simplification is possible, this function returns zero.  Otherwise,
1846    it returns either const_true_rtx or const0_rtx.  */
1847
1848 rtx
1849 simplify_relational_operation (code, mode, op0, op1)
1850      enum rtx_code code;
1851      enum machine_mode mode;
1852      rtx op0, op1;
1853 {
1854   int equal, op0lt, op0ltu, op1lt, op1ltu;
1855   rtx tem;
1856   rtx trueop0;
1857   rtx trueop1;
1858
1859   if (mode == VOIDmode
1860       && (GET_MODE (op0) != VOIDmode
1861           || GET_MODE (op1) != VOIDmode))
1862     abort ();
1863
1864   /* If op0 is a compare, extract the comparison arguments from it.  */
1865   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
1866     op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
1867
1868   trueop0 = avoid_constant_pool_reference (op0);
1869   trueop1 = avoid_constant_pool_reference (op1);
1870
1871   /* We can't simplify MODE_CC values since we don't know what the
1872      actual comparison is.  */
1873   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC
1874 #ifdef HAVE_cc0
1875       || op0 == cc0_rtx
1876 #endif
1877       )
1878     return 0;
1879
1880   /* Make sure the constant is second.  */
1881   if (swap_commutative_operands_p (trueop0, trueop1))
1882     {
1883       tem = op0, op0 = op1, op1 = tem;
1884       tem = trueop0, trueop0 = trueop1, trueop1 = tem;
1885       code = swap_condition (code);
1886     }
1887
1888   /* For integer comparisons of A and B maybe we can simplify A - B and can
1889      then simplify a comparison of that with zero.  If A and B are both either
1890      a register or a CONST_INT, this can't help; testing for these cases will
1891      prevent infinite recursion here and speed things up.
1892
1893      If CODE is an unsigned comparison, then we can never do this optimization,
1894      because it gives an incorrect result if the subtraction wraps around zero.
1895      ANSI C defines unsigned operations such that they never overflow, and
1896      thus such cases can not be ignored.  */
1897
1898   if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
1899       && ! ((GET_CODE (op0) == REG || GET_CODE (trueop0) == CONST_INT)
1900             && (GET_CODE (op1) == REG || GET_CODE (trueop1) == CONST_INT))
1901       && 0 != (tem = simplify_binary_operation (MINUS, mode, op0, op1))
1902       && code != GTU && code != GEU && code != LTU && code != LEU)
1903     return simplify_relational_operation (signed_condition (code),
1904                                           mode, tem, const0_rtx);
1905
1906   if (flag_unsafe_math_optimizations && code == ORDERED)
1907     return const_true_rtx;
1908
1909   if (flag_unsafe_math_optimizations && code == UNORDERED)
1910     return const0_rtx;
1911
1912   /* For non-IEEE floating-point, if the two operands are equal, we know the
1913      result.  */
1914   if (rtx_equal_p (trueop0, trueop1)
1915       && (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
1916           || ! FLOAT_MODE_P (GET_MODE (trueop0)) 
1917           || flag_unsafe_math_optimizations))
1918     equal = 1, op0lt = 0, op0ltu = 0, op1lt = 0, op1ltu = 0;
1919
1920   /* If the operands are floating-point constants, see if we can fold
1921      the result.  */
1922 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1923   else if (GET_CODE (trueop0) == CONST_DOUBLE
1924            && GET_CODE (trueop1) == CONST_DOUBLE
1925            && GET_MODE_CLASS (GET_MODE (trueop0)) == MODE_FLOAT)
1926     {
1927       struct cfc_args args;
1928
1929       /* Setup input for check_fold_consts() */
1930       args.op0 = trueop0;
1931       args.op1 = trueop1;
1932       
1933       
1934       if (!do_float_handler (check_fold_consts, (PTR) &args))
1935         args.unordered = 1;
1936
1937       if (args.unordered)
1938         switch (code)
1939           {
1940           case UNEQ:
1941           case UNLT:
1942           case UNGT:
1943           case UNLE:
1944           case UNGE:
1945           case NE:
1946           case UNORDERED:
1947             return const_true_rtx;
1948           case EQ:
1949           case LT:
1950           case GT:
1951           case LE:
1952           case GE:
1953           case LTGT:
1954           case ORDERED:
1955             return const0_rtx;
1956           default:
1957             return 0;
1958           }
1959
1960       /* Receive output from check_fold_consts() */
1961       equal = args.equal;
1962       op0lt = op0ltu = args.op0lt;
1963       op1lt = op1ltu = args.op1lt;
1964     }
1965 #endif  /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
1966
1967   /* Otherwise, see if the operands are both integers.  */
1968   else if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
1969            && (GET_CODE (trueop0) == CONST_DOUBLE
1970                || GET_CODE (trueop0) == CONST_INT)
1971            && (GET_CODE (trueop1) == CONST_DOUBLE
1972                || GET_CODE (trueop1) == CONST_INT))
1973     {
1974       int width = GET_MODE_BITSIZE (mode);
1975       HOST_WIDE_INT l0s, h0s, l1s, h1s;
1976       unsigned HOST_WIDE_INT l0u, h0u, l1u, h1u;
1977
1978       /* Get the two words comprising each integer constant.  */
1979       if (GET_CODE (trueop0) == CONST_DOUBLE)
1980         {
1981           l0u = l0s = CONST_DOUBLE_LOW (trueop0);
1982           h0u = h0s = CONST_DOUBLE_HIGH (trueop0);
1983         }
1984       else
1985         {
1986           l0u = l0s = INTVAL (trueop0);
1987           h0u = h0s = HWI_SIGN_EXTEND (l0s);
1988         }
1989           
1990       if (GET_CODE (trueop1) == CONST_DOUBLE)
1991         {
1992           l1u = l1s = CONST_DOUBLE_LOW (trueop1);
1993           h1u = h1s = CONST_DOUBLE_HIGH (trueop1);
1994         }
1995       else
1996         {
1997           l1u = l1s = INTVAL (trueop1);
1998           h1u = h1s = HWI_SIGN_EXTEND (l1s);
1999         }
2000
2001       /* If WIDTH is nonzero and smaller than HOST_BITS_PER_WIDE_INT,
2002          we have to sign or zero-extend the values.  */
2003       if (width != 0 && width < HOST_BITS_PER_WIDE_INT)
2004         {
2005           l0u &= ((HOST_WIDE_INT) 1 << width) - 1;
2006           l1u &= ((HOST_WIDE_INT) 1 << width) - 1;
2007
2008           if (l0s & ((HOST_WIDE_INT) 1 << (width - 1)))
2009             l0s |= ((HOST_WIDE_INT) (-1) << width);
2010
2011           if (l1s & ((HOST_WIDE_INT) 1 << (width - 1)))
2012             l1s |= ((HOST_WIDE_INT) (-1) << width);
2013         }
2014       if (width != 0 && width <= HOST_BITS_PER_WIDE_INT)
2015         h0u = h1u = 0, h0s = HWI_SIGN_EXTEND (l0s), h1s = HWI_SIGN_EXTEND (l1s);
2016
2017       equal = (h0u == h1u && l0u == l1u);
2018       op0lt = (h0s < h1s || (h0s == h1s && l0u < l1u));
2019       op1lt = (h1s < h0s || (h1s == h0s && l1u < l0u));
2020       op0ltu = (h0u < h1u || (h0u == h1u && l0u < l1u));
2021       op1ltu = (h1u < h0u || (h1u == h0u && l1u < l0u));
2022     }
2023
2024   /* Otherwise, there are some code-specific tests we can make.  */
2025   else
2026     {
2027       switch (code)
2028         {
2029         case EQ:
2030           /* References to the frame plus a constant or labels cannot
2031              be zero, but a SYMBOL_REF can due to #pragma weak.  */
2032           if (((NONZERO_BASE_PLUS_P (op0) && trueop1 == const0_rtx)
2033                || GET_CODE (trueop0) == LABEL_REF)
2034 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
2035               /* On some machines, the ap reg can be 0 sometimes.  */
2036               && op0 != arg_pointer_rtx
2037 #endif
2038                 )
2039             return const0_rtx;
2040           break;
2041
2042         case NE:
2043           if (((NONZERO_BASE_PLUS_P (op0) && trueop1 == const0_rtx)
2044                || GET_CODE (trueop0) == LABEL_REF)
2045 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
2046               && op0 != arg_pointer_rtx
2047 #endif
2048               )
2049             return const_true_rtx;
2050           break;
2051
2052         case GEU:
2053           /* Unsigned values are never negative.  */
2054           if (trueop1 == const0_rtx)
2055             return const_true_rtx;
2056           break;
2057
2058         case LTU:
2059           if (trueop1 == const0_rtx)
2060             return const0_rtx;
2061           break;
2062
2063         case LEU:
2064           /* Unsigned values are never greater than the largest
2065              unsigned value.  */
2066           if (GET_CODE (trueop1) == CONST_INT
2067               && (unsigned HOST_WIDE_INT) INTVAL (trueop1) == GET_MODE_MASK (mode)
2068             && INTEGRAL_MODE_P (mode))
2069           return const_true_rtx;
2070           break;
2071
2072         case GTU:
2073           if (GET_CODE (trueop1) == CONST_INT
2074               && (unsigned HOST_WIDE_INT) INTVAL (trueop1) == GET_MODE_MASK (mode)
2075               && INTEGRAL_MODE_P (mode))
2076             return const0_rtx;
2077           break;
2078           
2079         default:
2080           break;
2081         }
2082
2083       return 0;
2084     }
2085
2086   /* If we reach here, EQUAL, OP0LT, OP0LTU, OP1LT, and OP1LTU are set
2087      as appropriate.  */
2088   switch (code)
2089     {
2090     case EQ:
2091     case UNEQ:
2092       return equal ? const_true_rtx : const0_rtx;
2093     case NE:
2094     case LTGT:
2095       return ! equal ? const_true_rtx : const0_rtx;
2096     case LT:
2097     case UNLT:
2098       return op0lt ? const_true_rtx : const0_rtx;
2099     case GT:
2100     case UNGT:
2101       return op1lt ? const_true_rtx : const0_rtx;
2102     case LTU:
2103       return op0ltu ? const_true_rtx : const0_rtx;
2104     case GTU:
2105       return op1ltu ? const_true_rtx : const0_rtx;
2106     case LE:
2107     case UNLE:
2108       return equal || op0lt ? const_true_rtx : const0_rtx;
2109     case GE:
2110     case UNGE:
2111       return equal || op1lt ? const_true_rtx : const0_rtx;
2112     case LEU:
2113       return equal || op0ltu ? const_true_rtx : const0_rtx;
2114     case GEU:
2115       return equal || op1ltu ? const_true_rtx : const0_rtx;
2116     case ORDERED:
2117       return const_true_rtx;
2118     case UNORDERED:
2119       return const0_rtx;
2120     default:
2121       abort ();
2122     }
2123 }
2124 \f
2125 /* Simplify CODE, an operation with result mode MODE and three operands,
2126    OP0, OP1, and OP2.  OP0_MODE was the mode of OP0 before it became
2127    a constant.  Return 0 if no simplifications is possible.  */
2128
2129 rtx
2130 simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
2131      enum rtx_code code;
2132      enum machine_mode mode, op0_mode;
2133      rtx op0, op1, op2;
2134 {
2135   unsigned int width = GET_MODE_BITSIZE (mode);
2136
2137   /* VOIDmode means "infinite" precision.  */
2138   if (width == 0)
2139     width = HOST_BITS_PER_WIDE_INT;
2140
2141   switch (code)
2142     {
2143     case SIGN_EXTRACT:
2144     case ZERO_EXTRACT:
2145       if (GET_CODE (op0) == CONST_INT
2146           && GET_CODE (op1) == CONST_INT
2147           && GET_CODE (op2) == CONST_INT
2148           && ((unsigned) INTVAL (op1) + (unsigned) INTVAL (op2) <= width)
2149           && width <= (unsigned) HOST_BITS_PER_WIDE_INT)
2150         {
2151           /* Extracting a bit-field from a constant */
2152           HOST_WIDE_INT val = INTVAL (op0);
2153
2154           if (BITS_BIG_ENDIAN)
2155             val >>= (GET_MODE_BITSIZE (op0_mode)
2156                      - INTVAL (op2) - INTVAL (op1));
2157           else
2158             val >>= INTVAL (op2);
2159
2160           if (HOST_BITS_PER_WIDE_INT != INTVAL (op1))
2161             {
2162               /* First zero-extend.  */
2163               val &= ((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1;
2164               /* If desired, propagate sign bit.  */
2165               if (code == SIGN_EXTRACT
2166                   && (val & ((HOST_WIDE_INT) 1 << (INTVAL (op1) - 1))))
2167                 val |= ~ (((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1);
2168             }
2169
2170           /* Clear the bits that don't belong in our mode,
2171              unless they and our sign bit are all one.
2172              So we get either a reasonable negative value or a reasonable
2173              unsigned value for this mode.  */
2174           if (width < HOST_BITS_PER_WIDE_INT
2175               && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
2176                   != ((HOST_WIDE_INT) (-1) << (width - 1))))
2177             val &= ((HOST_WIDE_INT) 1 << width) - 1;
2178
2179           return GEN_INT (val);
2180         }
2181       break;
2182
2183     case IF_THEN_ELSE:
2184       if (GET_CODE (op0) == CONST_INT)
2185         return op0 != const0_rtx ? op1 : op2;
2186
2187       /* Convert a == b ? b : a to "a".  */
2188       if (GET_CODE (op0) == NE && ! side_effects_p (op0)
2189           && (! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
2190           && rtx_equal_p (XEXP (op0, 0), op1)
2191           && rtx_equal_p (XEXP (op0, 1), op2))
2192         return op1;
2193       else if (GET_CODE (op0) == EQ && ! side_effects_p (op0)
2194           && (! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
2195           && rtx_equal_p (XEXP (op0, 1), op1)
2196           && rtx_equal_p (XEXP (op0, 0), op2))
2197         return op2;
2198       else if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && ! side_effects_p (op0))
2199         {
2200           enum machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
2201                                         ? GET_MODE (XEXP (op0, 1))
2202                                         : GET_MODE (XEXP (op0, 0)));
2203           rtx temp;
2204           if (cmp_mode == VOIDmode)
2205             cmp_mode = op0_mode;
2206           temp = simplify_relational_operation (GET_CODE (op0), cmp_mode,
2207                                                 XEXP (op0, 0), XEXP (op0, 1));
2208
2209           /* See if any simplifications were possible.  */
2210           if (temp == const0_rtx)
2211             return op2;
2212           else if (temp == const1_rtx)
2213             return op1;
2214           else if (temp)
2215             op0 = temp;
2216
2217           /* Look for happy constants in op1 and op2.  */
2218           if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
2219             {
2220               HOST_WIDE_INT t = INTVAL (op1);
2221               HOST_WIDE_INT f = INTVAL (op2);
2222               
2223               if (t == STORE_FLAG_VALUE && f == 0)
2224                 code = GET_CODE (op0);
2225               else if (t == 0 && f == STORE_FLAG_VALUE)
2226                 {
2227                   enum rtx_code tmp;
2228                   tmp = reversed_comparison_code (op0, NULL_RTX);
2229                   if (tmp == UNKNOWN)
2230                     break;
2231                   code = tmp;
2232                 }
2233               else
2234                 break;
2235
2236               return gen_rtx_fmt_ee (code, mode, XEXP (op0, 0), XEXP (op0, 1));
2237             }
2238         }
2239       break;
2240
2241     default:
2242       abort ();
2243     }
2244
2245   return 0;
2246 }
2247
2248 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
2249    Return 0 if no simplifications is possible.  */
2250 rtx
2251 simplify_subreg (outermode, op, innermode, byte)
2252      rtx op;
2253      unsigned int byte;
2254      enum machine_mode outermode, innermode;
2255 {
2256   /* Little bit of sanity checking.  */
2257   if (innermode == VOIDmode || outermode == VOIDmode
2258       || innermode == BLKmode || outermode == BLKmode)
2259     abort ();
2260
2261   if (GET_MODE (op) != innermode
2262       && GET_MODE (op) != VOIDmode)
2263     abort ();
2264
2265   if (byte % GET_MODE_SIZE (outermode)
2266       || byte >= GET_MODE_SIZE (innermode))
2267     abort ();
2268
2269   if (outermode == innermode && !byte)
2270     return op;
2271
2272   /* Attempt to simplify constant to non-SUBREG expression.  */
2273   if (CONSTANT_P (op))
2274     {
2275       int offset, part;
2276       unsigned HOST_WIDE_INT val = 0;
2277
2278       /* ??? This code is partly redundant with code below, but can handle
2279          the subregs of floats and similar corner cases.
2280          Later it we should move all simplification code here and rewrite
2281          GEN_LOWPART_IF_POSSIBLE, GEN_HIGHPART, OPERAND_SUBWORD and friends
2282          using SIMPLIFY_SUBREG.  */
2283       if (subreg_lowpart_offset (outermode, innermode) == byte)
2284         {
2285           rtx new = gen_lowpart_if_possible (outermode, op);
2286           if (new)
2287             return new;
2288         }
2289
2290       /* Similar comment as above apply here.  */
2291       if (GET_MODE_SIZE (outermode) == UNITS_PER_WORD
2292           && GET_MODE_SIZE (innermode) > UNITS_PER_WORD
2293           && GET_MODE_CLASS (outermode) == MODE_INT)
2294         {
2295           rtx new = constant_subword (op,
2296                                       (byte / UNITS_PER_WORD),
2297                                       innermode);
2298           if (new)
2299             return new;
2300         }
2301
2302       offset = byte * BITS_PER_UNIT;
2303       switch (GET_CODE (op))
2304         {
2305         case CONST_DOUBLE:
2306           if (GET_MODE (op) != VOIDmode)
2307             break;
2308
2309           /* We can't handle this case yet.  */
2310           if (GET_MODE_BITSIZE (outermode) >= HOST_BITS_PER_WIDE_INT)
2311             return NULL_RTX;
2312
2313           part = offset >= HOST_BITS_PER_WIDE_INT;
2314           if ((BITS_PER_WORD > HOST_BITS_PER_WIDE_INT
2315                && BYTES_BIG_ENDIAN)
2316               || (BITS_PER_WORD <= HOST_BITS_PER_WIDE_INT
2317                   && WORDS_BIG_ENDIAN))
2318             part = !part;
2319           val = part ? CONST_DOUBLE_HIGH (op) : CONST_DOUBLE_LOW (op);
2320           offset %= HOST_BITS_PER_WIDE_INT;
2321
2322           /* We've already picked the word we want from a double, so 
2323              pretend this is actually an integer.  */
2324           innermode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
2325
2326           /* FALLTHROUGH */
2327         case CONST_INT:
2328           if (GET_CODE (op) == CONST_INT)
2329             val = INTVAL (op);
2330
2331           /* We don't handle synthetizing of non-integral constants yet.  */
2332           if (GET_MODE_CLASS (outermode) != MODE_INT)
2333             return NULL_RTX;
2334
2335           if (BYTES_BIG_ENDIAN || WORDS_BIG_ENDIAN)
2336             {
2337               if (WORDS_BIG_ENDIAN)
2338                 offset = (GET_MODE_BITSIZE (innermode)
2339                           - GET_MODE_BITSIZE (outermode) - offset);
2340               if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
2341                   && GET_MODE_SIZE (outermode) < UNITS_PER_WORD)
2342                 offset = (offset + BITS_PER_WORD - GET_MODE_BITSIZE (outermode)
2343                           - 2 * (offset % BITS_PER_WORD));
2344             }
2345
2346           if (offset >= HOST_BITS_PER_WIDE_INT)
2347             return ((HOST_WIDE_INT) val < 0) ? constm1_rtx : const0_rtx;
2348           else
2349             {
2350               val >>= offset;
2351               if (GET_MODE_BITSIZE (outermode) < HOST_BITS_PER_WIDE_INT)
2352                 val = trunc_int_for_mode (val, outermode);
2353               return GEN_INT (val);
2354             }
2355         default:
2356           break;
2357         }
2358     }
2359
2360   /* Changing mode twice with SUBREG => just change it once,
2361      or not at all if changing back op starting mode.  */
2362   if (GET_CODE (op) == SUBREG)
2363     {
2364       enum machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
2365       int final_offset = byte + SUBREG_BYTE (op);
2366       rtx new;
2367
2368       if (outermode == innermostmode
2369           && byte == 0 && SUBREG_BYTE (op) == 0)
2370         return SUBREG_REG (op);
2371
2372       /* The SUBREG_BYTE represents offset, as if the value were stored
2373          in memory.  Irritating exception is paradoxical subreg, where
2374          we define SUBREG_BYTE to be 0.  On big endian machines, this
2375          value should be negative.  For a moment, undo this exception. */
2376       if (byte == 0 && GET_MODE_SIZE (innermode) < GET_MODE_SIZE (outermode))
2377         {
2378           int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
2379           if (WORDS_BIG_ENDIAN)
2380             final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
2381           if (BYTES_BIG_ENDIAN)
2382             final_offset += difference % UNITS_PER_WORD;
2383         }
2384       if (SUBREG_BYTE (op) == 0
2385           && GET_MODE_SIZE (innermostmode) < GET_MODE_SIZE (innermode))
2386         {
2387           int difference = (GET_MODE_SIZE (innermostmode) - GET_MODE_SIZE (innermode));
2388           if (WORDS_BIG_ENDIAN)
2389             final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
2390           if (BYTES_BIG_ENDIAN)
2391             final_offset += difference % UNITS_PER_WORD;
2392         }
2393
2394       /* See whether resulting subreg will be paradoxical.  */
2395       if (GET_MODE_SIZE (innermostmode) > GET_MODE_SIZE (outermode))
2396         {
2397           /* In nonparadoxical subregs we can't handle negative offsets.  */
2398           if (final_offset < 0)
2399             return NULL_RTX;
2400           /* Bail out in case resulting subreg would be incorrect.  */
2401           if (final_offset % GET_MODE_SIZE (outermode)
2402               || (unsigned) final_offset >= GET_MODE_SIZE (innermostmode))
2403             return NULL_RTX;
2404         }
2405       else
2406         {
2407           int offset = 0;
2408           int difference = (GET_MODE_SIZE (innermostmode) - GET_MODE_SIZE (outermode));
2409
2410           /* In paradoxical subreg, see if we are still looking on lower part.
2411              If so, our SUBREG_BYTE will be 0.  */
2412           if (WORDS_BIG_ENDIAN)
2413             offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
2414           if (BYTES_BIG_ENDIAN)
2415             offset += difference % UNITS_PER_WORD;
2416           if (offset == final_offset)
2417             final_offset = 0;
2418           else
2419             return NULL_RTX;
2420         }
2421
2422       /* Recurse for futher possible simplifications.  */
2423       new = simplify_subreg (outermode, SUBREG_REG (op),
2424                              GET_MODE (SUBREG_REG (op)),
2425                              final_offset);
2426       if (new)
2427         return new;
2428       return gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
2429     }
2430
2431   /* SUBREG of a hard register => just change the register number
2432      and/or mode.  If the hard register is not valid in that mode,
2433      suppress this simplification.  If the hard register is the stack,
2434      frame, or argument pointer, leave this as a SUBREG.  */
2435
2436   if (REG_P (op)
2437       && (! REG_FUNCTION_VALUE_P (op)
2438           || ! rtx_equal_function_value_matters)
2439 #ifdef CLASS_CANNOT_CHANGE_MODE
2440       && ! (CLASS_CANNOT_CHANGE_MODE_P (outermode, innermode)
2441             && GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
2442             && GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT
2443             && (TEST_HARD_REG_BIT
2444                 (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
2445                  REGNO (op))))
2446 #endif
2447       && REGNO (op) < FIRST_PSEUDO_REGISTER
2448       && ((reload_completed && !frame_pointer_needed)
2449           || (REGNO (op) != FRAME_POINTER_REGNUM
2450 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
2451               && REGNO (op) != HARD_FRAME_POINTER_REGNUM
2452 #endif
2453              ))
2454 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
2455       && REGNO (op) != ARG_POINTER_REGNUM
2456 #endif
2457       && REGNO (op) != STACK_POINTER_REGNUM)
2458     {
2459       int final_regno = subreg_hard_regno (gen_rtx_SUBREG (outermode, op, byte),
2460                                            0);
2461
2462       /* ??? We do allow it if the current REG is not valid for
2463          its mode.  This is a kludge to work around how float/complex
2464          arguments are passed on 32-bit Sparc and should be fixed.  */
2465       if (HARD_REGNO_MODE_OK (final_regno, outermode)
2466           || ! HARD_REGNO_MODE_OK (REGNO (op), innermode))
2467         return gen_rtx_REG (outermode, final_regno);
2468     }
2469
2470   /* If we have a SUBREG of a register that we are replacing and we are
2471      replacing it with a MEM, make a new MEM and try replacing the
2472      SUBREG with it.  Don't do this if the MEM has a mode-dependent address
2473      or if we would be widening it.  */
2474
2475   if (GET_CODE (op) == MEM
2476       && ! mode_dependent_address_p (XEXP (op, 0))
2477       /* Allow splitting of volatile memory references in case we don't
2478          have instruction to move the whole thing.  */
2479       && (! MEM_VOLATILE_P (op)
2480           || (mov_optab->handlers[(int) innermode].insn_code
2481               == CODE_FOR_nothing))
2482       && GET_MODE_SIZE (outermode) <= GET_MODE_SIZE (GET_MODE (op)))
2483     return adjust_address_nv (op, outermode, byte);
2484
2485   /* Handle complex values represented as CONCAT
2486      of real and imaginary part.  */
2487   if (GET_CODE (op) == CONCAT)
2488     {
2489       int is_realpart = byte < GET_MODE_UNIT_SIZE (innermode);
2490       rtx part = is_realpart ? XEXP (op, 0) : XEXP (op, 1);
2491       unsigned int final_offset;
2492       rtx res;
2493
2494       final_offset = byte % (GET_MODE_UNIT_SIZE (innermode));
2495       res = simplify_subreg (outermode, part, GET_MODE (part), final_offset);
2496       if (res)
2497         return res;
2498       /* We can at least simplify it by referring directly to the relevent part. */
2499       return gen_rtx_SUBREG (outermode, part, final_offset);
2500     }
2501
2502   return NULL_RTX;
2503 }
2504 /* Make a SUBREG operation or equivalent if it folds.  */
2505
2506 rtx
2507 simplify_gen_subreg (outermode, op, innermode, byte)
2508      rtx op;
2509      unsigned int byte;
2510      enum machine_mode outermode, innermode;
2511 {
2512   rtx new;
2513   /* Little bit of sanity checking.  */
2514   if (innermode == VOIDmode || outermode == VOIDmode
2515       || innermode == BLKmode || outermode == BLKmode)
2516     abort ();
2517
2518   if (GET_MODE (op) != innermode
2519       && GET_MODE (op) != VOIDmode)
2520     abort ();
2521
2522   if (byte % GET_MODE_SIZE (outermode)
2523       || byte >= GET_MODE_SIZE (innermode))
2524     abort ();
2525
2526   if (GET_CODE (op) == QUEUED)
2527     return NULL_RTX;
2528
2529   new = simplify_subreg (outermode, op, innermode, byte);
2530   if (new)
2531     return new;
2532
2533   if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode)
2534     return NULL_RTX;
2535
2536   return gen_rtx_SUBREG (outermode, op, byte);
2537 }
2538 /* Simplify X, an rtx expression.
2539
2540    Return the simplified expression or NULL if no simplifications
2541    were possible.
2542
2543    This is the preferred entry point into the simplification routines;
2544    however, we still allow passes to call the more specific routines.
2545
2546    Right now GCC has three (yes, three) major bodies of RTL simplficiation
2547    code that need to be unified.
2548
2549         1. fold_rtx in cse.c.  This code uses various CSE specific
2550            information to aid in RTL simplification.
2551
2552         2. simplify_rtx in combine.c.  Similar to fold_rtx, except that
2553            it uses combine specific information to aid in RTL
2554            simplification.
2555
2556         3. The routines in this file.
2557
2558
2559    Long term we want to only have one body of simplification code; to
2560    get to that state I recommend the following steps:
2561
2562         1. Pour over fold_rtx & simplify_rtx and move any simplifications
2563            which are not pass dependent state into these routines.
2564
2565         2. As code is moved by #1, change fold_rtx & simplify_rtx to
2566            use this routine whenever possible.
2567
2568         3. Allow for pass dependent state to be provided to these
2569            routines and add simplifications based on the pass dependent
2570            state.  Remove code from cse.c & combine.c that becomes
2571            redundant/dead.
2572
2573     It will take time, but ultimately the compiler will be easier to
2574     maintain and improve.  It's totally silly that when we add a
2575     simplification that it needs to be added to 4 places (3 for RTL
2576     simplification and 1 for tree simplification.  */
2577            
2578 rtx
2579 simplify_rtx (x)
2580      rtx x;
2581 {
2582   enum rtx_code code = GET_CODE (x);
2583   enum machine_mode mode = GET_MODE (x);
2584
2585   switch (GET_RTX_CLASS (code))
2586     {
2587     case '1':
2588       return simplify_unary_operation (code, mode,
2589                                        XEXP (x, 0), GET_MODE (XEXP (x, 0)));
2590     case 'c':
2591       if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
2592         {
2593           rtx tem;
2594
2595           tem = XEXP (x, 0);
2596           XEXP (x, 0) = XEXP (x, 1);
2597           XEXP (x, 1) = tem;
2598           return simplify_binary_operation (code, mode,
2599                                             XEXP (x, 0), XEXP (x, 1));
2600         }
2601
2602     case '2':
2603       return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
2604
2605     case '3':
2606     case 'b':
2607       return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
2608                                          XEXP (x, 0), XEXP (x, 1),
2609                                          XEXP (x, 2));
2610
2611     case '<':
2612       return simplify_relational_operation (code,
2613                                             ((GET_MODE (XEXP (x, 0))
2614                                               != VOIDmode)
2615                                              ? GET_MODE (XEXP (x, 0))
2616                                              : GET_MODE (XEXP (x, 1))),
2617                                             XEXP (x, 0), XEXP (x, 1));
2618     case 'x':
2619       /* The only case we try to handle is a SUBREG.  */
2620       if (code == SUBREG)
2621         return simplify_gen_subreg (mode, SUBREG_REG (x),
2622                                     GET_MODE (SUBREG_REG (x)),
2623                                     SUBREG_BYTE (x));
2624       return NULL;
2625     default:
2626       return NULL;
2627     }
2628 }