OSDN Git Service

Fix copyrights.
[pf3gnuchains/gcc-fork.git] / gcc / simplify-rtx.c
1 /* Common subexpression elimination for GNU compiler.
2    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000 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 /* stdio.h must precede rtl.h for FFS.  */
25 #include "system.h"
26 #include <setjmp.h>
27
28 #include "rtl.h"
29 #include "tm_p.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "flags.h"
33 #include "real.h"
34 #include "insn-config.h"
35 #include "recog.h"
36 #include "function.h"
37 #include "expr.h"
38 #include "toplev.h"
39 #include "output.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
93 static rtx simplify_plus_minus  PARAMS ((enum rtx_code, enum machine_mode,
94                                        rtx, rtx));
95 static void check_fold_consts   PARAMS ((PTR));
96
97 /* Make a binary operation by properly ordering the operands and 
98    seeing if the expression folds.  */
99
100 rtx
101 simplify_gen_binary (code, mode, op0, op1)
102      enum rtx_code code;
103      enum machine_mode mode;
104      rtx op0, op1;
105 {
106   rtx tem;
107
108   /* Put complex operands first and constants second if commutative.  */
109   if (GET_RTX_CLASS (code) == 'c'
110       && ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT)
111           || (GET_RTX_CLASS (GET_CODE (op0)) == 'o'
112               && GET_RTX_CLASS (GET_CODE (op1)) != 'o')
113           || (GET_CODE (op0) == SUBREG
114               && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o'
115               && GET_RTX_CLASS (GET_CODE (op1)) != 'o')))
116     tem = op0, op0 = op1, op1 = tem;
117
118   /* If this simplifies, do it.  */
119   tem = simplify_binary_operation (code, mode, op0, op1);
120
121   if (tem)
122     return tem;
123
124   /* Handle addition and subtraction of CONST_INT specially.  Otherwise,
125      just form the operation.  */
126
127   if (code == PLUS && GET_CODE (op1) == CONST_INT
128       && GET_MODE (op0) != VOIDmode)
129     return plus_constant (op0, INTVAL (op1));
130   else if (code == MINUS && GET_CODE (op1) == CONST_INT
131            && GET_MODE (op0) != VOIDmode)
132     return plus_constant (op0, - INTVAL (op1));
133   else
134     return gen_rtx_fmt_ee (code, mode, op0, op1);
135 }
136 \f
137 /* Try to simplify a unary operation CODE whose output mode is to be
138    MODE with input operand OP whose mode was originally OP_MODE.
139    Return zero if no simplification can be made.  */
140
141 rtx
142 simplify_unary_operation (code, mode, op, op_mode)
143      enum rtx_code code;
144      enum machine_mode mode;
145      rtx op;
146      enum machine_mode op_mode;
147 {
148   register int width = GET_MODE_BITSIZE (mode);
149
150   /* The order of these tests is critical so that, for example, we don't
151      check the wrong mode (input vs. output) for a conversion operation,
152      such as FIX.  At some point, this should be simplified.  */
153
154 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
155
156   if (code == FLOAT && GET_MODE (op) == VOIDmode
157       && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
158     {
159       HOST_WIDE_INT hv, lv;
160       REAL_VALUE_TYPE d;
161
162       if (GET_CODE (op) == CONST_INT)
163         lv = INTVAL (op), hv = INTVAL (op) < 0 ? -1 : 0;
164       else
165         lv = CONST_DOUBLE_LOW (op),  hv = CONST_DOUBLE_HIGH (op);
166
167 #ifdef REAL_ARITHMETIC
168       REAL_VALUE_FROM_INT (d, lv, hv, mode);
169 #else
170       if (hv < 0)
171         {
172           d = (double) (~ hv);
173           d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
174                 * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
175           d += (double) (unsigned HOST_WIDE_INT) (~ lv);
176           d = (- d - 1.0);
177         }
178       else
179         {
180           d = (double) hv;
181           d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
182                 * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
183           d += (double) (unsigned HOST_WIDE_INT) lv;
184         }
185 #endif  /* REAL_ARITHMETIC */
186       d = real_value_truncate (mode, d);
187       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
188     }
189   else if (code == UNSIGNED_FLOAT && GET_MODE (op) == VOIDmode
190            && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
191     {
192       HOST_WIDE_INT hv, lv;
193       REAL_VALUE_TYPE d;
194
195       if (GET_CODE (op) == CONST_INT)
196         lv = INTVAL (op), hv = INTVAL (op) < 0 ? -1 : 0;
197       else
198         lv = CONST_DOUBLE_LOW (op),  hv = CONST_DOUBLE_HIGH (op);
199
200       if (op_mode == VOIDmode)
201         {
202           /* We don't know how to interpret negative-looking numbers in
203              this case, so don't try to fold those.  */
204           if (hv < 0)
205             return 0;
206         }
207       else if (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT * 2)
208         ;
209       else
210         hv = 0, lv &= GET_MODE_MASK (op_mode);
211
212 #ifdef REAL_ARITHMETIC
213       REAL_VALUE_FROM_UNSIGNED_INT (d, lv, hv, mode);
214 #else
215
216       d = (double) (unsigned HOST_WIDE_INT) hv;
217       d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
218             * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
219       d += (double) (unsigned HOST_WIDE_INT) lv;
220 #endif  /* REAL_ARITHMETIC */
221       d = real_value_truncate (mode, d);
222       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
223     }
224 #endif
225
226   if (GET_CODE (op) == CONST_INT
227       && width <= HOST_BITS_PER_WIDE_INT && width > 0)
228     {
229       register HOST_WIDE_INT arg0 = INTVAL (op);
230       register HOST_WIDE_INT val;
231
232       switch (code)
233         {
234         case NOT:
235           val = ~ arg0;
236           break;
237
238         case NEG:
239           val = - arg0;
240           break;
241
242         case ABS:
243           val = (arg0 >= 0 ? arg0 : - arg0);
244           break;
245
246         case FFS:
247           /* Don't use ffs here.  Instead, get low order bit and then its
248              number.  If arg0 is zero, this will return 0, as desired.  */
249           arg0 &= GET_MODE_MASK (mode);
250           val = exact_log2 (arg0 & (- arg0)) + 1;
251           break;
252
253         case TRUNCATE:
254           val = arg0;
255           break;
256
257         case ZERO_EXTEND:
258           if (op_mode == VOIDmode)
259             op_mode = mode;
260           if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
261             {
262               /* If we were really extending the mode,
263                  we would have to distinguish between zero-extension
264                  and sign-extension.  */
265               if (width != GET_MODE_BITSIZE (op_mode))
266                 abort ();
267               val = arg0;
268             }
269           else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
270             val = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode));
271           else
272             return 0;
273           break;
274
275         case SIGN_EXTEND:
276           if (op_mode == VOIDmode)
277             op_mode = mode;
278           if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
279             {
280               /* If we were really extending the mode,
281                  we would have to distinguish between zero-extension
282                  and sign-extension.  */
283               if (width != GET_MODE_BITSIZE (op_mode))
284                 abort ();
285               val = arg0;
286             }
287           else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
288             {
289               val
290                 = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode));
291               if (val
292                   & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (op_mode) - 1)))
293                 val -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
294             }
295           else
296             return 0;
297           break;
298
299         case SQRT:
300           return 0;
301
302         default:
303           abort ();
304         }
305
306       val = trunc_int_for_mode (val, mode);
307
308       return GEN_INT (val);
309     }
310
311   /* We can do some operations on integer CONST_DOUBLEs.  Also allow
312      for a DImode operation on a CONST_INT.  */
313   else if (GET_MODE (op) == VOIDmode && width <= HOST_BITS_PER_INT * 2
314            && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
315     {
316       HOST_WIDE_INT l1, h1, lv, hv;
317
318       if (GET_CODE (op) == CONST_DOUBLE)
319         l1 = CONST_DOUBLE_LOW (op), h1 = CONST_DOUBLE_HIGH (op);
320       else
321         l1 = INTVAL (op), h1 = l1 < 0 ? -1 : 0;
322
323       switch (code)
324         {
325         case NOT:
326           lv = ~ l1;
327           hv = ~ h1;
328           break;
329
330         case NEG:
331           neg_double (l1, h1, &lv, &hv);
332           break;
333
334         case ABS:
335           if (h1 < 0)
336             neg_double (l1, h1, &lv, &hv);
337           else
338             lv = l1, hv = h1;
339           break;
340
341         case FFS:
342           hv = 0;
343           if (l1 == 0)
344             lv = HOST_BITS_PER_WIDE_INT + exact_log2 (h1 & (-h1)) + 1;
345           else
346             lv = exact_log2 (l1 & (-l1)) + 1;
347           break;
348
349         case TRUNCATE:
350           /* This is just a change-of-mode, so do nothing.  */
351           lv = l1, hv = h1;
352           break;
353
354         case ZERO_EXTEND:
355           if (op_mode == VOIDmode
356               || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
357             return 0;
358
359           hv = 0;
360           lv = l1 & GET_MODE_MASK (op_mode);
361           break;
362
363         case SIGN_EXTEND:
364           if (op_mode == VOIDmode
365               || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
366             return 0;
367           else
368             {
369               lv = l1 & GET_MODE_MASK (op_mode);
370               if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT
371                   && (lv & ((HOST_WIDE_INT) 1
372                             << (GET_MODE_BITSIZE (op_mode) - 1))) != 0)
373                 lv -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
374
375               hv = (lv < 0) ? ~ (HOST_WIDE_INT) 0 : 0;
376             }
377           break;
378
379         case SQRT:
380           return 0;
381
382         default:
383           return 0;
384         }
385
386       return immed_double_const (lv, hv, mode);
387     }
388
389 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
390   else if (GET_CODE (op) == CONST_DOUBLE
391            && GET_MODE_CLASS (mode) == MODE_FLOAT)
392     {
393       REAL_VALUE_TYPE d;
394       jmp_buf handler;
395       rtx x;
396
397       if (setjmp (handler))
398         /* There used to be a warning here, but that is inadvisable.
399            People may want to cause traps, and the natural way
400            to do it should not get a warning.  */
401         return 0;
402
403       set_float_handler (handler);
404
405       REAL_VALUE_FROM_CONST_DOUBLE (d, op);
406
407       switch (code)
408         {
409         case NEG:
410           d = REAL_VALUE_NEGATE (d);
411           break;
412
413         case ABS:
414           if (REAL_VALUE_NEGATIVE (d))
415             d = REAL_VALUE_NEGATE (d);
416           break;
417
418         case FLOAT_TRUNCATE:
419           d = real_value_truncate (mode, d);
420           break;
421
422         case FLOAT_EXTEND:
423           /* All this does is change the mode.  */
424           break;
425
426         case FIX:
427           d = REAL_VALUE_RNDZINT (d);
428           break;
429
430         case UNSIGNED_FIX:
431           d = REAL_VALUE_UNSIGNED_RNDZINT (d);
432           break;
433
434         case SQRT:
435           return 0;
436
437         default:
438           abort ();
439         }
440
441       x = CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
442       set_float_handler (NULL_PTR);
443       return x;
444     }
445
446   else if (GET_CODE (op) == CONST_DOUBLE
447            && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
448            && GET_MODE_CLASS (mode) == MODE_INT
449            && width <= HOST_BITS_PER_WIDE_INT && width > 0)
450     {
451       REAL_VALUE_TYPE d;
452       jmp_buf handler;
453       HOST_WIDE_INT val;
454
455       if (setjmp (handler))
456         return 0;
457
458       set_float_handler (handler);
459
460       REAL_VALUE_FROM_CONST_DOUBLE (d, op);
461
462       switch (code)
463         {
464         case FIX:
465           val = REAL_VALUE_FIX (d);
466           break;
467
468         case UNSIGNED_FIX:
469           val = REAL_VALUE_UNSIGNED_FIX (d);
470           break;
471
472         default:
473           abort ();
474         }
475
476       set_float_handler (NULL_PTR);
477
478       val = trunc_int_for_mode (val, mode);
479
480       return GEN_INT (val);
481     }
482 #endif
483   /* This was formerly used only for non-IEEE float.
484      eggert@twinsun.com says it is safe for IEEE also.  */
485   else
486     {
487       /* There are some simplifications we can do even if the operands
488          aren't constant.  */
489       switch (code)
490         {
491         case NEG:
492         case NOT:
493           /* (not (not X)) == X, similarly for NEG.  */
494           if (GET_CODE (op) == code)
495             return XEXP (op, 0);
496           break;
497
498         case SIGN_EXTEND:
499           /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
500              becomes just the MINUS if its mode is MODE.  This allows
501              folding switch statements on machines using casesi (such as
502              the Vax).  */
503           if (GET_CODE (op) == TRUNCATE
504               && GET_MODE (XEXP (op, 0)) == mode
505               && GET_CODE (XEXP (op, 0)) == MINUS
506               && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
507               && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
508             return XEXP (op, 0);
509
510 #ifdef POINTERS_EXTEND_UNSIGNED
511           if (! POINTERS_EXTEND_UNSIGNED
512               && mode == Pmode && GET_MODE (op) == ptr_mode
513               && CONSTANT_P (op))
514             return convert_memory_address (Pmode, op);
515 #endif
516           break;
517
518 #ifdef POINTERS_EXTEND_UNSIGNED
519         case ZERO_EXTEND:
520           if (POINTERS_EXTEND_UNSIGNED
521               && mode == Pmode && GET_MODE (op) == ptr_mode
522               && CONSTANT_P (op))
523             return convert_memory_address (Pmode, op);
524           break;
525 #endif
526           
527         default:
528           break;
529         }
530
531       return 0;
532     }
533 }
534 \f
535 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
536    and OP1.  Return 0 if no simplification is possible.
537
538    Don't use this for relational operations such as EQ or LT.
539    Use simplify_relational_operation instead.  */
540
541 rtx
542 simplify_binary_operation (code, mode, op0, op1)
543      enum rtx_code code;
544      enum machine_mode mode;
545      rtx op0, op1;
546 {
547   register HOST_WIDE_INT arg0, arg1, arg0s, arg1s;
548   HOST_WIDE_INT val;
549   int width = GET_MODE_BITSIZE (mode);
550   rtx tem;
551
552   /* Relational operations don't work here.  We must know the mode
553      of the operands in order to do the comparison correctly.
554      Assuming a full word can give incorrect results.
555      Consider comparing 128 with -128 in QImode.  */
556
557   if (GET_RTX_CLASS (code) == '<')
558     abort ();
559
560 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
561   if (GET_MODE_CLASS (mode) == MODE_FLOAT
562       && GET_CODE (op0) == CONST_DOUBLE && GET_CODE (op1) == CONST_DOUBLE
563       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
564     {
565       REAL_VALUE_TYPE f0, f1, value;
566       jmp_buf handler;
567
568       if (setjmp (handler))
569         return 0;
570
571       set_float_handler (handler);
572
573       REAL_VALUE_FROM_CONST_DOUBLE (f0, op0);
574       REAL_VALUE_FROM_CONST_DOUBLE (f1, op1);
575       f0 = real_value_truncate (mode, f0);
576       f1 = real_value_truncate (mode, f1);
577
578 #ifdef REAL_ARITHMETIC
579 #ifndef REAL_INFINITY
580       if (code == DIV && REAL_VALUES_EQUAL (f1, dconst0))
581         return 0;
582 #endif
583       REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1);
584 #else
585       switch (code)
586         {
587         case PLUS:
588           value = f0 + f1;
589           break;
590         case MINUS:
591           value = f0 - f1;
592           break;
593         case MULT:
594           value = f0 * f1;
595           break;
596         case DIV:
597 #ifndef REAL_INFINITY
598           if (f1 == 0)
599             return 0;
600 #endif
601           value = f0 / f1;
602           break;
603         case SMIN:
604           value = MIN (f0, f1);
605           break;
606         case SMAX:
607           value = MAX (f0, f1);
608           break;
609         default:
610           abort ();
611         }
612 #endif
613
614       value = real_value_truncate (mode, value);
615       set_float_handler (NULL_PTR);
616       return CONST_DOUBLE_FROM_REAL_VALUE (value, mode);
617     }
618 #endif  /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
619
620   /* We can fold some multi-word operations.  */
621   if (GET_MODE_CLASS (mode) == MODE_INT
622       && width == HOST_BITS_PER_WIDE_INT * 2
623       && (GET_CODE (op0) == CONST_DOUBLE || GET_CODE (op0) == CONST_INT)
624       && (GET_CODE (op1) == CONST_DOUBLE || GET_CODE (op1) == CONST_INT))
625     {
626       HOST_WIDE_INT l1, l2, h1, h2, lv, hv;
627
628       if (GET_CODE (op0) == CONST_DOUBLE)
629         l1 = CONST_DOUBLE_LOW (op0), h1 = CONST_DOUBLE_HIGH (op0);
630       else
631         l1 = INTVAL (op0), h1 = l1 < 0 ? -1 : 0;
632
633       if (GET_CODE (op1) == CONST_DOUBLE)
634         l2 = CONST_DOUBLE_LOW (op1), h2 = CONST_DOUBLE_HIGH (op1);
635       else
636         l2 = INTVAL (op1), h2 = l2 < 0 ? -1 : 0;
637
638       switch (code)
639         {
640         case MINUS:
641           /* A - B == A + (-B).  */
642           neg_double (l2, h2, &lv, &hv);
643           l2 = lv, h2 = hv;
644
645           /* .. fall through ...  */
646
647         case PLUS:
648           add_double (l1, h1, l2, h2, &lv, &hv);
649           break;
650
651         case MULT:
652           mul_double (l1, h1, l2, h2, &lv, &hv);
653           break;
654
655         case DIV:  case MOD:   case UDIV:  case UMOD:
656           /* We'd need to include tree.h to do this and it doesn't seem worth
657              it.  */
658           return 0;
659
660         case AND:
661           lv = l1 & l2, hv = h1 & h2;
662           break;
663
664         case IOR:
665           lv = l1 | l2, hv = h1 | h2;
666           break;
667
668         case XOR:
669           lv = l1 ^ l2, hv = h1 ^ h2;
670           break;
671
672         case SMIN:
673           if (h1 < h2
674               || (h1 == h2
675                   && ((unsigned HOST_WIDE_INT) l1
676                       < (unsigned HOST_WIDE_INT) l2)))
677             lv = l1, hv = h1;
678           else
679             lv = l2, hv = h2;
680           break;
681
682         case SMAX:
683           if (h1 > h2
684               || (h1 == h2
685                   && ((unsigned HOST_WIDE_INT) l1
686                       > (unsigned HOST_WIDE_INT) l2)))
687             lv = l1, hv = h1;
688           else
689             lv = l2, hv = h2;
690           break;
691
692         case UMIN:
693           if ((unsigned HOST_WIDE_INT) h1 < (unsigned HOST_WIDE_INT) h2
694               || (h1 == h2
695                   && ((unsigned HOST_WIDE_INT) l1
696                       < (unsigned HOST_WIDE_INT) l2)))
697             lv = l1, hv = h1;
698           else
699             lv = l2, hv = h2;
700           break;
701
702         case UMAX:
703           if ((unsigned HOST_WIDE_INT) h1 > (unsigned HOST_WIDE_INT) h2
704               || (h1 == h2
705                   && ((unsigned HOST_WIDE_INT) l1
706                       > (unsigned HOST_WIDE_INT) l2)))
707             lv = l1, hv = h1;
708           else
709             lv = l2, hv = h2;
710           break;
711
712         case LSHIFTRT:   case ASHIFTRT:
713         case ASHIFT:
714         case ROTATE:     case ROTATERT:
715 #ifdef SHIFT_COUNT_TRUNCATED
716           if (SHIFT_COUNT_TRUNCATED)
717             l2 &= (GET_MODE_BITSIZE (mode) - 1), h2 = 0;
718 #endif
719
720           if (h2 != 0 || l2 < 0 || l2 >= GET_MODE_BITSIZE (mode))
721             return 0;
722
723           if (code == LSHIFTRT || code == ASHIFTRT)
724             rshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv,
725                            code == ASHIFTRT);
726           else if (code == ASHIFT)
727             lshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv, 1);
728           else if (code == ROTATE)
729             lrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
730           else /* code == ROTATERT */
731             rrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
732           break;
733
734         default:
735           return 0;
736         }
737
738       return immed_double_const (lv, hv, mode);
739     }
740
741   if (GET_CODE (op0) != CONST_INT || GET_CODE (op1) != CONST_INT
742       || width > HOST_BITS_PER_WIDE_INT || width == 0)
743     {
744       /* Even if we can't compute a constant result,
745          there are some cases worth simplifying.  */
746
747       switch (code)
748         {
749         case PLUS:
750           /* In IEEE floating point, x+0 is not the same as x.  Similarly
751              for the other optimizations below.  */
752           if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
753               && FLOAT_MODE_P (mode) && ! flag_fast_math)
754             break;
755
756           if (op1 == CONST0_RTX (mode))
757             return op0;
758
759           /* ((-a) + b) -> (b - a) and similarly for (a + (-b)) */
760           if (GET_CODE (op0) == NEG)
761             return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
762           else if (GET_CODE (op1) == NEG)
763             return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
764
765           /* Handle both-operands-constant cases.  We can only add
766              CONST_INTs to constants since the sum of relocatable symbols
767              can't be handled by most assemblers.  Don't add CONST_INT
768              to CONST_INT since overflow won't be computed properly if wider
769              than HOST_BITS_PER_WIDE_INT.  */
770
771           if (CONSTANT_P (op0) && GET_MODE (op0) != VOIDmode
772               && GET_CODE (op1) == CONST_INT)
773             return plus_constant (op0, INTVAL (op1));
774           else if (CONSTANT_P (op1) && GET_MODE (op1) != VOIDmode
775                    && GET_CODE (op0) == CONST_INT)
776             return plus_constant (op1, INTVAL (op0));
777
778           /* See if this is something like X * C - X or vice versa or
779              if the multiplication is written as a shift.  If so, we can
780              distribute and make a new multiply, shift, or maybe just
781              have X (if C is 2 in the example above).  But don't make
782              real multiply if we didn't have one before.  */
783
784           if (! FLOAT_MODE_P (mode))
785             {
786               HOST_WIDE_INT coeff0 = 1, coeff1 = 1;
787               rtx lhs = op0, rhs = op1;
788               int had_mult = 0;
789
790               if (GET_CODE (lhs) == NEG)
791                 coeff0 = -1, lhs = XEXP (lhs, 0);
792               else if (GET_CODE (lhs) == MULT
793                        && GET_CODE (XEXP (lhs, 1)) == CONST_INT)
794                 {
795                   coeff0 = INTVAL (XEXP (lhs, 1)), lhs = XEXP (lhs, 0);
796                   had_mult = 1;
797                 }
798               else if (GET_CODE (lhs) == ASHIFT
799                        && GET_CODE (XEXP (lhs, 1)) == CONST_INT
800                        && INTVAL (XEXP (lhs, 1)) >= 0
801                        && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
802                 {
803                   coeff0 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
804                   lhs = XEXP (lhs, 0);
805                 }
806
807               if (GET_CODE (rhs) == NEG)
808                 coeff1 = -1, rhs = XEXP (rhs, 0);
809               else if (GET_CODE (rhs) == MULT
810                        && GET_CODE (XEXP (rhs, 1)) == CONST_INT)
811                 {
812                   coeff1 = INTVAL (XEXP (rhs, 1)), rhs = XEXP (rhs, 0);
813                   had_mult = 1;
814                 }
815               else if (GET_CODE (rhs) == ASHIFT
816                        && GET_CODE (XEXP (rhs, 1)) == CONST_INT
817                        && INTVAL (XEXP (rhs, 1)) >= 0
818                        && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
819                 {
820                   coeff1 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
821                   rhs = XEXP (rhs, 0);
822                 }
823
824               if (rtx_equal_p (lhs, rhs))
825                 {
826                   tem = simplify_gen_binary (MULT, mode, lhs,
827                                         GEN_INT (coeff0 + coeff1));
828                   return (GET_CODE (tem) == MULT && ! had_mult) ? 0 : tem;
829                 }
830             }
831
832           /* If one of the operands is a PLUS or a MINUS, see if we can
833              simplify this by the associative law. 
834              Don't use the associative law for floating point.
835              The inaccuracy makes it nonassociative,
836              and subtle programs can break if operations are associated.  */
837
838           if (INTEGRAL_MODE_P (mode)
839               && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
840                   || GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS)
841               && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
842             return tem;
843           break;
844
845         case COMPARE:
846 #ifdef HAVE_cc0
847           /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
848              using cc0, in which case we want to leave it as a COMPARE
849              so we can distinguish it from a register-register-copy.
850
851              In IEEE floating point, x-0 is not the same as x.  */
852
853           if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
854                || ! FLOAT_MODE_P (mode) || flag_fast_math)
855               && op1 == CONST0_RTX (mode))
856             return op0;
857 #else
858           /* Do nothing here.  */
859 #endif
860           break;
861               
862         case MINUS:
863           /* None of these optimizations can be done for IEEE
864              floating point.  */
865           if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
866               && FLOAT_MODE_P (mode) && ! flag_fast_math)
867             break;
868
869           /* We can't assume x-x is 0 even with non-IEEE floating point,
870              but since it is zero except in very strange circumstances, we
871              will treat it as zero with -ffast-math.  */
872           if (rtx_equal_p (op0, op1)
873               && ! side_effects_p (op0)
874               && (! FLOAT_MODE_P (mode) || flag_fast_math))
875             return CONST0_RTX (mode);
876
877           /* Change subtraction from zero into negation.  */
878           if (op0 == CONST0_RTX (mode))
879             return gen_rtx_NEG (mode, op1);
880
881           /* (-1 - a) is ~a.  */
882           if (op0 == constm1_rtx)
883             return gen_rtx_NOT (mode, op1);
884
885           /* Subtracting 0 has no effect.  */
886           if (op1 == CONST0_RTX (mode))
887             return op0;
888
889           /* See if this is something like X * C - X or vice versa or
890              if the multiplication is written as a shift.  If so, we can
891              distribute and make a new multiply, shift, or maybe just
892              have X (if C is 2 in the example above).  But don't make
893              real multiply if we didn't have one before.  */
894
895           if (! FLOAT_MODE_P (mode))
896             {
897               HOST_WIDE_INT coeff0 = 1, coeff1 = 1;
898               rtx lhs = op0, rhs = op1;
899               int had_mult = 0;
900
901               if (GET_CODE (lhs) == NEG)
902                 coeff0 = -1, lhs = XEXP (lhs, 0);
903               else if (GET_CODE (lhs) == MULT
904                        && GET_CODE (XEXP (lhs, 1)) == CONST_INT)
905                 {
906                   coeff0 = INTVAL (XEXP (lhs, 1)), lhs = XEXP (lhs, 0);
907                   had_mult = 1;
908                 }
909               else if (GET_CODE (lhs) == ASHIFT
910                        && GET_CODE (XEXP (lhs, 1)) == CONST_INT
911                        && INTVAL (XEXP (lhs, 1)) >= 0
912                        && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
913                 {
914                   coeff0 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
915                   lhs = XEXP (lhs, 0);
916                 }
917
918               if (GET_CODE (rhs) == NEG)
919                 coeff1 = - 1, rhs = XEXP (rhs, 0);
920               else if (GET_CODE (rhs) == MULT
921                        && GET_CODE (XEXP (rhs, 1)) == CONST_INT)
922                 {
923                   coeff1 = INTVAL (XEXP (rhs, 1)), rhs = XEXP (rhs, 0);
924                   had_mult = 1;
925                 }
926               else if (GET_CODE (rhs) == ASHIFT
927                        && GET_CODE (XEXP (rhs, 1)) == CONST_INT
928                        && INTVAL (XEXP (rhs, 1)) >= 0
929                        && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
930                 {
931                   coeff1 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
932                   rhs = XEXP (rhs, 0);
933                 }
934
935               if (rtx_equal_p (lhs, rhs))
936                 {
937                   tem = simplify_gen_binary (MULT, mode, lhs,
938                                              GEN_INT (coeff0 - coeff1));
939                   return (GET_CODE (tem) == MULT && ! had_mult) ? 0 : tem;
940                 }
941             }
942
943           /* (a - (-b)) -> (a + b).  */
944           if (GET_CODE (op1) == NEG)
945             return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
946
947           /* If one of the operands is a PLUS or a MINUS, see if we can
948              simplify this by the associative law. 
949              Don't use the associative law for floating point.
950              The inaccuracy makes it nonassociative,
951              and subtle programs can break if operations are associated.  */
952
953           if (INTEGRAL_MODE_P (mode)
954               && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
955                   || GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS)
956               && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
957             return tem;
958
959           /* Don't let a relocatable value get a negative coeff.  */
960           if (GET_CODE (op1) == CONST_INT && GET_MODE (op0) != VOIDmode)
961             return plus_constant (op0, - INTVAL (op1));
962
963           /* (x - (x & y)) -> (x & ~y) */
964           if (GET_CODE (op1) == AND)
965             {
966              if (rtx_equal_p (op0, XEXP (op1, 0)))
967                return simplify_gen_binary (AND, mode, op0,
968                                            gen_rtx_NOT (mode, XEXP (op1, 1)));
969              if (rtx_equal_p (op0, XEXP (op1, 1)))
970                return simplify_gen_binary (AND, mode, op0,
971                                            gen_rtx_NOT (mode, XEXP (op1, 0)));
972            }
973           break;
974
975         case MULT:
976           if (op1 == constm1_rtx)
977             {
978               tem = simplify_unary_operation (NEG, mode, op0, mode);
979
980               return tem ? tem : gen_rtx_NEG (mode, op0);
981             }
982
983           /* In IEEE floating point, x*0 is not always 0.  */
984           if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
985                || ! FLOAT_MODE_P (mode) || flag_fast_math)
986               && op1 == CONST0_RTX (mode)
987               && ! side_effects_p (op0))
988             return op1;
989
990           /* In IEEE floating point, x*1 is not equivalent to x for nans.
991              However, ANSI says we can drop signals,
992              so we can do this anyway.  */
993           if (op1 == CONST1_RTX (mode))
994             return op0;
995
996           /* Convert multiply by constant power of two into shift unless
997              we are still generating RTL.  This test is a kludge.  */
998           if (GET_CODE (op1) == CONST_INT
999               && (val = exact_log2 (INTVAL (op1))) >= 0
1000               /* If the mode is larger than the host word size, and the
1001                  uppermost bit is set, then this isn't a power of two due
1002                  to implicit sign extension.  */
1003               && (width <= HOST_BITS_PER_WIDE_INT
1004                   || val != HOST_BITS_PER_WIDE_INT - 1)
1005               && ! rtx_equal_function_value_matters)
1006             return gen_rtx_ASHIFT (mode, op0, GEN_INT (val));
1007
1008           if (GET_CODE (op1) == CONST_DOUBLE
1009               && GET_MODE_CLASS (GET_MODE (op1)) == MODE_FLOAT)
1010             {
1011               REAL_VALUE_TYPE d;
1012               jmp_buf handler;
1013               int op1is2, op1ism1;
1014
1015               if (setjmp (handler))
1016                 return 0;
1017
1018               set_float_handler (handler);
1019               REAL_VALUE_FROM_CONST_DOUBLE (d, op1);
1020               op1is2 = REAL_VALUES_EQUAL (d, dconst2);
1021               op1ism1 = REAL_VALUES_EQUAL (d, dconstm1);
1022               set_float_handler (NULL_PTR);
1023
1024               /* x*2 is x+x and x*(-1) is -x */
1025               if (op1is2 && GET_MODE (op0) == mode)
1026                 return gen_rtx_PLUS (mode, op0, copy_rtx (op0));
1027
1028               else if (op1ism1 && GET_MODE (op0) == mode)
1029                 return gen_rtx_NEG (mode, op0);
1030             }
1031           break;
1032
1033         case IOR:
1034           if (op1 == const0_rtx)
1035             return op0;
1036           if (GET_CODE (op1) == CONST_INT
1037               && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode))
1038             return op1;
1039           if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
1040             return op0;
1041           /* A | (~A) -> -1 */
1042           if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
1043                || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
1044               && ! side_effects_p (op0)
1045               && GET_MODE_CLASS (mode) != MODE_CC)
1046             return constm1_rtx;
1047           break;
1048
1049         case XOR:
1050           if (op1 == const0_rtx)
1051             return op0;
1052           if (GET_CODE (op1) == CONST_INT
1053               && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode))
1054             return gen_rtx_NOT (mode, op0);
1055           if (op0 == op1 && ! side_effects_p (op0)
1056               && GET_MODE_CLASS (mode) != MODE_CC)
1057             return const0_rtx;
1058           break;
1059
1060         case AND:
1061           if (op1 == const0_rtx && ! side_effects_p (op0))
1062             return const0_rtx;
1063           if (GET_CODE (op1) == CONST_INT
1064               && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode))
1065             return op0;
1066           if (op0 == op1 && ! side_effects_p (op0)
1067               && GET_MODE_CLASS (mode) != MODE_CC)
1068             return op0;
1069           /* A & (~A) -> 0 */
1070           if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
1071                || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
1072               && ! side_effects_p (op0)
1073               && GET_MODE_CLASS (mode) != MODE_CC)
1074             return const0_rtx;
1075           break;
1076
1077         case UDIV:
1078           /* Convert divide by power of two into shift (divide by 1 handled
1079              below).  */
1080           if (GET_CODE (op1) == CONST_INT
1081               && (arg1 = exact_log2 (INTVAL (op1))) > 0)
1082             return gen_rtx_LSHIFTRT (mode, op0, GEN_INT (arg1));
1083
1084           /* ... fall through ...  */
1085
1086         case DIV:
1087           if (op1 == CONST1_RTX (mode))
1088             return op0;
1089
1090           /* In IEEE floating point, 0/x is not always 0.  */
1091           if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
1092                || ! FLOAT_MODE_P (mode) || flag_fast_math)
1093               && op0 == CONST0_RTX (mode)
1094               && ! side_effects_p (op1))
1095             return op0;
1096
1097 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1098           /* Change division by a constant into multiplication.  Only do
1099              this with -ffast-math until an expert says it is safe in
1100              general.  */
1101           else if (GET_CODE (op1) == CONST_DOUBLE
1102                    && GET_MODE_CLASS (GET_MODE (op1)) == MODE_FLOAT
1103                    && op1 != CONST0_RTX (mode)
1104                    && flag_fast_math)
1105             {
1106               REAL_VALUE_TYPE d;
1107               REAL_VALUE_FROM_CONST_DOUBLE (d, op1);
1108
1109               if (! REAL_VALUES_EQUAL (d, dconst0))
1110                 {
1111 #if defined (REAL_ARITHMETIC)
1112                   REAL_ARITHMETIC (d, rtx_to_tree_code (DIV), dconst1, d);
1113                   return gen_rtx_MULT (mode, op0, 
1114                                        CONST_DOUBLE_FROM_REAL_VALUE (d, mode));
1115 #else
1116                   return
1117                     gen_rtx_MULT (mode, op0, 
1118                                   CONST_DOUBLE_FROM_REAL_VALUE (1./d, mode));
1119 #endif
1120                 }
1121             }
1122 #endif
1123           break;
1124
1125         case UMOD:
1126           /* Handle modulus by power of two (mod with 1 handled below).  */
1127           if (GET_CODE (op1) == CONST_INT
1128               && exact_log2 (INTVAL (op1)) > 0)
1129             return gen_rtx_AND (mode, op0, GEN_INT (INTVAL (op1) - 1));
1130
1131           /* ... fall through ...  */
1132
1133         case MOD:
1134           if ((op0 == const0_rtx || op1 == const1_rtx)
1135               && ! side_effects_p (op0) && ! side_effects_p (op1))
1136             return const0_rtx;
1137           break;
1138
1139         case ROTATERT:
1140         case ROTATE:
1141           /* Rotating ~0 always results in ~0.  */
1142           if (GET_CODE (op0) == CONST_INT && width <= HOST_BITS_PER_WIDE_INT
1143               && (unsigned HOST_WIDE_INT) INTVAL (op0) == GET_MODE_MASK (mode)
1144               && ! side_effects_p (op1))
1145             return op0;
1146
1147           /* ... fall through ...  */
1148
1149         case ASHIFT:
1150         case ASHIFTRT:
1151         case LSHIFTRT:
1152           if (op1 == const0_rtx)
1153             return op0;
1154           if (op0 == const0_rtx && ! side_effects_p (op1))
1155             return op0;
1156           break;
1157
1158         case SMIN:
1159           if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (op1) == CONST_INT 
1160               && INTVAL (op1) == (HOST_WIDE_INT) 1 << (width -1)
1161               && ! side_effects_p (op0))
1162             return op1;
1163           else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
1164             return op0;
1165           break;
1166            
1167         case SMAX:
1168           if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (op1) == CONST_INT
1169               && ((unsigned HOST_WIDE_INT) INTVAL (op1)
1170                   == (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode) >> 1)
1171               && ! side_effects_p (op0))
1172             return op1;
1173           else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
1174             return op0;
1175           break;
1176
1177         case UMIN:
1178           if (op1 == const0_rtx && ! side_effects_p (op0))
1179             return op1;
1180           else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
1181             return op0;
1182           break;
1183             
1184         case UMAX:
1185           if (op1 == constm1_rtx && ! side_effects_p (op0))
1186             return op1;
1187           else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
1188             return op0;
1189           break;
1190
1191         default:
1192           abort ();
1193         }
1194       
1195       return 0;
1196     }
1197
1198   /* Get the integer argument values in two forms:
1199      zero-extended in ARG0, ARG1 and sign-extended in ARG0S, ARG1S.  */
1200
1201   arg0 = INTVAL (op0);
1202   arg1 = INTVAL (op1);
1203
1204   if (width < HOST_BITS_PER_WIDE_INT)
1205     {
1206       arg0 &= ((HOST_WIDE_INT) 1 << width) - 1;
1207       arg1 &= ((HOST_WIDE_INT) 1 << width) - 1;
1208
1209       arg0s = arg0;
1210       if (arg0s & ((HOST_WIDE_INT) 1 << (width - 1)))
1211         arg0s |= ((HOST_WIDE_INT) (-1) << width);
1212
1213       arg1s = arg1;
1214       if (arg1s & ((HOST_WIDE_INT) 1 << (width - 1)))
1215         arg1s |= ((HOST_WIDE_INT) (-1) << width);
1216     }
1217   else
1218     {
1219       arg0s = arg0;
1220       arg1s = arg1;
1221     }
1222
1223   /* Compute the value of the arithmetic.  */
1224
1225   switch (code)
1226     {
1227     case PLUS:
1228       val = arg0s + arg1s;
1229       break;
1230
1231     case MINUS:
1232       val = arg0s - arg1s;
1233       break;
1234
1235     case MULT:
1236       val = arg0s * arg1s;
1237       break;
1238
1239     case DIV:
1240       if (arg1s == 0)
1241         return 0;
1242       val = arg0s / arg1s;
1243       break;
1244
1245     case MOD:
1246       if (arg1s == 0)
1247         return 0;
1248       val = arg0s % arg1s;
1249       break;
1250
1251     case UDIV:
1252       if (arg1 == 0)
1253         return 0;
1254       val = (unsigned HOST_WIDE_INT) arg0 / arg1;
1255       break;
1256
1257     case UMOD:
1258       if (arg1 == 0)
1259         return 0;
1260       val = (unsigned HOST_WIDE_INT) arg0 % arg1;
1261       break;
1262
1263     case AND:
1264       val = arg0 & arg1;
1265       break;
1266
1267     case IOR:
1268       val = arg0 | arg1;
1269       break;
1270
1271     case XOR:
1272       val = arg0 ^ arg1;
1273       break;
1274
1275     case LSHIFTRT:
1276       /* If shift count is undefined, don't fold it; let the machine do
1277          what it wants.  But truncate it if the machine will do that.  */
1278       if (arg1 < 0)
1279         return 0;
1280
1281 #ifdef SHIFT_COUNT_TRUNCATED
1282       if (SHIFT_COUNT_TRUNCATED)
1283         arg1 %= width;
1284 #endif
1285
1286       val = ((unsigned HOST_WIDE_INT) arg0) >> arg1;
1287       break;
1288
1289     case ASHIFT:
1290       if (arg1 < 0)
1291         return 0;
1292
1293 #ifdef SHIFT_COUNT_TRUNCATED
1294       if (SHIFT_COUNT_TRUNCATED)
1295         arg1 %= width;
1296 #endif
1297
1298       val = ((unsigned HOST_WIDE_INT) arg0) << arg1;
1299       break;
1300
1301     case ASHIFTRT:
1302       if (arg1 < 0)
1303         return 0;
1304
1305 #ifdef SHIFT_COUNT_TRUNCATED
1306       if (SHIFT_COUNT_TRUNCATED)
1307         arg1 %= width;
1308 #endif
1309
1310       val = arg0s >> arg1;
1311
1312       /* Bootstrap compiler may not have sign extended the right shift.
1313          Manually extend the sign to insure bootstrap cc matches gcc.  */
1314       if (arg0s < 0 && arg1 > 0)
1315         val |= ((HOST_WIDE_INT) -1) << (HOST_BITS_PER_WIDE_INT - arg1);
1316
1317       break;
1318
1319     case ROTATERT:
1320       if (arg1 < 0)
1321         return 0;
1322
1323       arg1 %= width;
1324       val = ((((unsigned HOST_WIDE_INT) arg0) << (width - arg1))
1325              | (((unsigned HOST_WIDE_INT) arg0) >> arg1));
1326       break;
1327
1328     case ROTATE:
1329       if (arg1 < 0)
1330         return 0;
1331
1332       arg1 %= width;
1333       val = ((((unsigned HOST_WIDE_INT) arg0) << arg1)
1334              | (((unsigned HOST_WIDE_INT) arg0) >> (width - arg1)));
1335       break;
1336
1337     case COMPARE:
1338       /* Do nothing here.  */
1339       return 0;
1340
1341     case SMIN:
1342       val = arg0s <= arg1s ? arg0s : arg1s;
1343       break;
1344
1345     case UMIN:
1346       val = ((unsigned HOST_WIDE_INT) arg0
1347              <= (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
1348       break;
1349
1350     case SMAX:
1351       val = arg0s > arg1s ? arg0s : arg1s;
1352       break;
1353
1354     case UMAX:
1355       val = ((unsigned HOST_WIDE_INT) arg0
1356              > (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
1357       break;
1358
1359     default:
1360       abort ();
1361     }
1362
1363   val = trunc_int_for_mode (val, mode);
1364
1365   return GEN_INT (val);
1366 }
1367 \f
1368 /* Simplify a PLUS or MINUS, at least one of whose operands may be another
1369    PLUS or MINUS.
1370
1371    Rather than test for specific case, we do this by a brute-force method
1372    and do all possible simplifications until no more changes occur.  Then
1373    we rebuild the operation.  */
1374
1375 static rtx
1376 simplify_plus_minus (code, mode, op0, op1)
1377      enum rtx_code code;
1378      enum machine_mode mode;
1379      rtx op0, op1;
1380 {
1381   rtx ops[8];
1382   int negs[8];
1383   rtx result, tem;
1384   int n_ops = 2, input_ops = 2, input_consts = 0, n_consts = 0;
1385   int first = 1, negate = 0, changed;
1386   int i, j;
1387
1388   bzero ((char *) ops, sizeof ops);
1389   
1390   /* Set up the two operands and then expand them until nothing has been
1391      changed.  If we run out of room in our array, give up; this should
1392      almost never happen.  */
1393
1394   ops[0] = op0, ops[1] = op1, negs[0] = 0, negs[1] = (code == MINUS);
1395
1396   changed = 1;
1397   while (changed)
1398     {
1399       changed = 0;
1400
1401       for (i = 0; i < n_ops; i++)
1402         switch (GET_CODE (ops[i]))
1403           {
1404           case PLUS:
1405           case MINUS:
1406             if (n_ops == 7)
1407               return 0;
1408
1409             ops[n_ops] = XEXP (ops[i], 1);
1410             negs[n_ops++] = GET_CODE (ops[i]) == MINUS ? !negs[i] : negs[i];
1411             ops[i] = XEXP (ops[i], 0);
1412             input_ops++;
1413             changed = 1;
1414             break;
1415
1416           case NEG:
1417             ops[i] = XEXP (ops[i], 0);
1418             negs[i] = ! negs[i];
1419             changed = 1;
1420             break;
1421
1422           case CONST:
1423             ops[i] = XEXP (ops[i], 0);
1424             input_consts++;
1425             changed = 1;
1426             break;
1427
1428           case NOT:
1429             /* ~a -> (-a - 1) */
1430             if (n_ops != 7)
1431               {
1432                 ops[n_ops] = constm1_rtx;
1433                 negs[n_ops++] = negs[i];
1434                 ops[i] = XEXP (ops[i], 0);
1435                 negs[i] = ! negs[i];
1436                 changed = 1;
1437               }
1438             break;
1439
1440           case CONST_INT:
1441             if (negs[i])
1442               ops[i] = GEN_INT (- INTVAL (ops[i])), negs[i] = 0, changed = 1;
1443             break;
1444
1445           default:
1446             break;
1447           }
1448     }
1449
1450   /* If we only have two operands, we can't do anything.  */
1451   if (n_ops <= 2)
1452     return 0;
1453
1454   /* Now simplify each pair of operands until nothing changes.  The first
1455      time through just simplify constants against each other.  */
1456
1457   changed = 1;
1458   while (changed)
1459     {
1460       changed = first;
1461
1462       for (i = 0; i < n_ops - 1; i++)
1463         for (j = i + 1; j < n_ops; j++)
1464           if (ops[i] != 0 && ops[j] != 0
1465               && (! first || (CONSTANT_P (ops[i]) && CONSTANT_P (ops[j]))))
1466             {
1467               rtx lhs = ops[i], rhs = ops[j];
1468               enum rtx_code ncode = PLUS;
1469
1470               if (negs[i] && ! negs[j])
1471                 lhs = ops[j], rhs = ops[i], ncode = MINUS;
1472               else if (! negs[i] && negs[j])
1473                 ncode = MINUS;
1474
1475               tem = simplify_binary_operation (ncode, mode, lhs, rhs);
1476               if (tem)
1477                 {
1478                   ops[i] = tem, ops[j] = 0;
1479                   negs[i] = negs[i] && negs[j];
1480                   if (GET_CODE (tem) == NEG)
1481                     ops[i] = XEXP (tem, 0), negs[i] = ! negs[i];
1482
1483                   if (GET_CODE (ops[i]) == CONST_INT && negs[i])
1484                     ops[i] = GEN_INT (- INTVAL (ops[i])), negs[i] = 0;
1485                   changed = 1;
1486                 }
1487             }
1488
1489       first = 0;
1490     }
1491
1492   /* Pack all the operands to the lower-numbered entries and give up if
1493      we didn't reduce the number of operands we had.  Make sure we
1494      count a CONST as two operands.  If we have the same number of
1495      operands, but have made more CONSTs than we had, this is also
1496      an improvement, so accept it.  */
1497
1498   for (i = 0, j = 0; j < n_ops; j++)
1499     if (ops[j] != 0)
1500       {
1501         ops[i] = ops[j], negs[i++] = negs[j];
1502         if (GET_CODE (ops[j]) == CONST)
1503           n_consts++;
1504       }
1505
1506   if (i + n_consts > input_ops
1507       || (i + n_consts == input_ops && n_consts <= input_consts))
1508     return 0;
1509
1510   n_ops = i;
1511
1512   /* If we have a CONST_INT, put it last.  */
1513   for (i = 0; i < n_ops - 1; i++)
1514     if (GET_CODE (ops[i]) == CONST_INT)
1515       {
1516         tem = ops[n_ops - 1], ops[n_ops - 1] = ops[i] , ops[i] = tem;
1517         j = negs[n_ops - 1], negs[n_ops - 1] = negs[i], negs[i] = j;
1518       }
1519
1520   /* Put a non-negated operand first.  If there aren't any, make all
1521      operands positive and negate the whole thing later.  */
1522   for (i = 0; i < n_ops && negs[i]; i++)
1523     ;
1524
1525   if (i == n_ops)
1526     {
1527       for (i = 0; i < n_ops; i++)
1528         negs[i] = 0;
1529       negate = 1;
1530     }
1531   else if (i != 0)
1532     {
1533       tem = ops[0], ops[0] = ops[i], ops[i] = tem;
1534       j = negs[0], negs[0] = negs[i], negs[i] = j;
1535     }
1536
1537   /* Now make the result by performing the requested operations.  */
1538   result = ops[0];
1539   for (i = 1; i < n_ops; i++)
1540     result = simplify_gen_binary (negs[i] ? MINUS : PLUS, mode, result, ops[i]);
1541
1542   return negate ? gen_rtx_NEG (mode, result) : result;
1543 }
1544
1545 struct cfc_args
1546 {
1547   rtx op0, op1;                 /* Input */
1548   int equal, op0lt, op1lt;      /* Output */
1549 };
1550
1551 static void
1552 check_fold_consts (data)
1553   PTR data;
1554 {
1555   struct cfc_args *args = (struct cfc_args *) data;
1556   REAL_VALUE_TYPE d0, d1;
1557
1558   REAL_VALUE_FROM_CONST_DOUBLE (d0, args->op0);
1559   REAL_VALUE_FROM_CONST_DOUBLE (d1, args->op1);
1560   args->equal = REAL_VALUES_EQUAL (d0, d1);
1561   args->op0lt = REAL_VALUES_LESS (d0, d1);
1562   args->op1lt = REAL_VALUES_LESS (d1, d0);
1563 }
1564
1565 /* Like simplify_binary_operation except used for relational operators.
1566    MODE is the mode of the operands, not that of the result.  If MODE
1567    is VOIDmode, both operands must also be VOIDmode and we compare the
1568    operands in "infinite precision".
1569
1570    If no simplification is possible, this function returns zero.  Otherwise,
1571    it returns either const_true_rtx or const0_rtx.  */
1572
1573 rtx
1574 simplify_relational_operation (code, mode, op0, op1)
1575      enum rtx_code code;
1576      enum machine_mode mode;
1577      rtx op0, op1;
1578 {
1579   int equal, op0lt, op0ltu, op1lt, op1ltu;
1580   rtx tem;
1581
1582   /* If op0 is a compare, extract the comparison arguments from it.  */
1583   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
1584     op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
1585
1586   /* We can't simplify MODE_CC values since we don't know what the
1587      actual comparison is.  */
1588   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC
1589 #ifdef HAVE_cc0
1590       || op0 == cc0_rtx
1591 #endif
1592       )
1593     return 0;
1594
1595   /* Make sure the constant is second.  */
1596   if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
1597       || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
1598     {
1599       tem = op0, op0 = op1, op1 = tem;
1600       code = swap_condition (code);
1601     }
1602
1603   /* For integer comparisons of A and B maybe we can simplify A - B and can
1604      then simplify a comparison of that with zero.  If A and B are both either
1605      a register or a CONST_INT, this can't help; testing for these cases will
1606      prevent infinite recursion here and speed things up.
1607
1608      If CODE is an unsigned comparison, then we can never do this optimization,
1609      because it gives an incorrect result if the subtraction wraps around zero.
1610      ANSI C defines unsigned operations such that they never overflow, and
1611      thus such cases can not be ignored.  */
1612
1613   if (INTEGRAL_MODE_P (mode) && op1 != const0_rtx
1614       && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == CONST_INT)
1615             && (GET_CODE (op1) == REG || GET_CODE (op1) == CONST_INT))
1616       && 0 != (tem = simplify_binary_operation (MINUS, mode, op0, op1))
1617       && code != GTU && code != GEU && code != LTU && code != LEU)
1618     return simplify_relational_operation (signed_condition (code),
1619                                           mode, tem, const0_rtx);
1620
1621   /* For non-IEEE floating-point, if the two operands are equal, we know the
1622      result.  */
1623   if (rtx_equal_p (op0, op1)
1624       && (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
1625           || ! FLOAT_MODE_P (GET_MODE (op0)) || flag_fast_math))
1626     equal = 1, op0lt = 0, op0ltu = 0, op1lt = 0, op1ltu = 0;
1627
1628   /* If the operands are floating-point constants, see if we can fold
1629      the result.  */
1630 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1631   else if (GET_CODE (op0) == CONST_DOUBLE && GET_CODE (op1) == CONST_DOUBLE
1632            && GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
1633     {
1634       struct cfc_args args;
1635
1636       /* Setup input for check_fold_consts() */
1637       args.op0 = op0;
1638       args.op1 = op1;
1639       
1640       if (do_float_handler(check_fold_consts, (PTR) &args) == 0)
1641         /* We got an exception from check_fold_consts() */
1642         return 0;
1643
1644       /* Receive output from check_fold_consts() */
1645       equal = args.equal;
1646       op0lt = op0ltu = args.op0lt;
1647       op1lt = op1ltu = args.op1lt;
1648     }
1649 #endif  /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
1650
1651   /* Otherwise, see if the operands are both integers.  */
1652   else if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
1653            && (GET_CODE (op0) == CONST_DOUBLE || GET_CODE (op0) == CONST_INT)
1654            && (GET_CODE (op1) == CONST_DOUBLE || GET_CODE (op1) == CONST_INT))
1655     {
1656       int width = GET_MODE_BITSIZE (mode);
1657       HOST_WIDE_INT l0s, h0s, l1s, h1s;
1658       unsigned HOST_WIDE_INT l0u, h0u, l1u, h1u;
1659
1660       /* Get the two words comprising each integer constant.  */
1661       if (GET_CODE (op0) == CONST_DOUBLE)
1662         {
1663           l0u = l0s = CONST_DOUBLE_LOW (op0);
1664           h0u = h0s = CONST_DOUBLE_HIGH (op0);
1665         }
1666       else
1667         {
1668           l0u = l0s = INTVAL (op0);
1669           h0u = h0s = l0s < 0 ? -1 : 0;
1670         }
1671           
1672       if (GET_CODE (op1) == CONST_DOUBLE)
1673         {
1674           l1u = l1s = CONST_DOUBLE_LOW (op1);
1675           h1u = h1s = CONST_DOUBLE_HIGH (op1);
1676         }
1677       else
1678         {
1679           l1u = l1s = INTVAL (op1);
1680           h1u = h1s = l1s < 0 ? -1 : 0;
1681         }
1682
1683       /* If WIDTH is nonzero and smaller than HOST_BITS_PER_WIDE_INT,
1684          we have to sign or zero-extend the values.  */
1685       if (width != 0 && width <= HOST_BITS_PER_WIDE_INT)
1686         h0u = h1u = 0, h0s = l0s < 0 ? -1 : 0, h1s = l1s < 0 ? -1 : 0;
1687
1688       if (width != 0 && width < HOST_BITS_PER_WIDE_INT)
1689         {
1690           l0u &= ((HOST_WIDE_INT) 1 << width) - 1;
1691           l1u &= ((HOST_WIDE_INT) 1 << width) - 1;
1692
1693           if (l0s & ((HOST_WIDE_INT) 1 << (width - 1)))
1694             l0s |= ((HOST_WIDE_INT) (-1) << width);
1695
1696           if (l1s & ((HOST_WIDE_INT) 1 << (width - 1)))
1697             l1s |= ((HOST_WIDE_INT) (-1) << width);
1698         }
1699
1700       equal = (h0u == h1u && l0u == l1u);
1701       op0lt = (h0s < h1s || (h0s == h1s && l0s < l1s));
1702       op1lt = (h1s < h0s || (h1s == h0s && l1s < l0s));
1703       op0ltu = (h0u < h1u || (h0u == h1u && l0u < l1u));
1704       op1ltu = (h1u < h0u || (h1u == h0u && l1u < l0u));
1705     }
1706
1707   /* Otherwise, there are some code-specific tests we can make.  */
1708   else
1709     {
1710       switch (code)
1711         {
1712         case EQ:
1713           /* References to the frame plus a constant or labels cannot
1714              be zero, but a SYMBOL_REF can due to #pragma weak.  */
1715           if (((NONZERO_BASE_PLUS_P (op0) && op1 == const0_rtx)
1716                || GET_CODE (op0) == LABEL_REF)
1717 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
1718               /* On some machines, the ap reg can be 0 sometimes.  */
1719               && op0 != arg_pointer_rtx
1720 #endif
1721                 )
1722             return const0_rtx;
1723           break;
1724
1725         case NE:
1726           if (((NONZERO_BASE_PLUS_P (op0) && op1 == const0_rtx)
1727                || GET_CODE (op0) == LABEL_REF)
1728 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
1729               && op0 != arg_pointer_rtx
1730 #endif
1731               )
1732             return const_true_rtx;
1733           break;
1734
1735         case GEU:
1736           /* Unsigned values are never negative.  */
1737           if (op1 == const0_rtx)
1738             return const_true_rtx;
1739           break;
1740
1741         case LTU:
1742           if (op1 == const0_rtx)
1743             return const0_rtx;
1744           break;
1745
1746         case LEU:
1747           /* Unsigned values are never greater than the largest
1748              unsigned value.  */
1749           if (GET_CODE (op1) == CONST_INT
1750               && (unsigned HOST_WIDE_INT) INTVAL (op1) == GET_MODE_MASK (mode)
1751             && INTEGRAL_MODE_P (mode))
1752           return const_true_rtx;
1753           break;
1754
1755         case GTU:
1756           if (GET_CODE (op1) == CONST_INT
1757               && (unsigned HOST_WIDE_INT) INTVAL (op1) == GET_MODE_MASK (mode)
1758               && INTEGRAL_MODE_P (mode))
1759             return const0_rtx;
1760           break;
1761           
1762         default:
1763           break;
1764         }
1765
1766       return 0;
1767     }
1768
1769   /* If we reach here, EQUAL, OP0LT, OP0LTU, OP1LT, and OP1LTU are set
1770      as appropriate.  */
1771   switch (code)
1772     {
1773     case EQ:
1774       return equal ? const_true_rtx : const0_rtx;
1775     case NE:
1776       return ! equal ? const_true_rtx : const0_rtx;
1777     case LT:
1778       return op0lt ? const_true_rtx : const0_rtx;
1779     case GT:
1780       return op1lt ? const_true_rtx : const0_rtx;
1781     case LTU:
1782       return op0ltu ? const_true_rtx : const0_rtx;
1783     case GTU:
1784       return op1ltu ? const_true_rtx : const0_rtx;
1785     case LE:
1786       return equal || op0lt ? const_true_rtx : const0_rtx;
1787     case GE:
1788       return equal || op1lt ? const_true_rtx : const0_rtx;
1789     case LEU:
1790       return equal || op0ltu ? const_true_rtx : const0_rtx;
1791     case GEU:
1792       return equal || op1ltu ? const_true_rtx : const0_rtx;
1793     default:
1794       abort ();
1795     }
1796 }
1797 \f
1798 /* Simplify CODE, an operation with result mode MODE and three operands,
1799    OP0, OP1, and OP2.  OP0_MODE was the mode of OP0 before it became
1800    a constant.  Return 0 if no simplifications is possible.  */
1801
1802 rtx
1803 simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
1804      enum rtx_code code;
1805      enum machine_mode mode, op0_mode;
1806      rtx op0, op1, op2;
1807 {
1808   int width = GET_MODE_BITSIZE (mode);
1809
1810   /* VOIDmode means "infinite" precision.  */
1811   if (width == 0)
1812     width = HOST_BITS_PER_WIDE_INT;
1813
1814   switch (code)
1815     {
1816     case SIGN_EXTRACT:
1817     case ZERO_EXTRACT:
1818       if (GET_CODE (op0) == CONST_INT
1819           && GET_CODE (op1) == CONST_INT
1820           && GET_CODE (op2) == CONST_INT
1821           && INTVAL (op1) + INTVAL (op2) <= GET_MODE_BITSIZE (op0_mode)
1822           && width <= HOST_BITS_PER_WIDE_INT)
1823         {
1824           /* Extracting a bit-field from a constant */
1825           HOST_WIDE_INT val = INTVAL (op0);
1826
1827           if (BITS_BIG_ENDIAN)
1828             val >>= (GET_MODE_BITSIZE (op0_mode)
1829                      - INTVAL (op2) - INTVAL (op1));
1830           else
1831             val >>= INTVAL (op2);
1832
1833           if (HOST_BITS_PER_WIDE_INT != INTVAL (op1))
1834             {
1835               /* First zero-extend.  */
1836               val &= ((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1;
1837               /* If desired, propagate sign bit.  */
1838               if (code == SIGN_EXTRACT
1839                   && (val & ((HOST_WIDE_INT) 1 << (INTVAL (op1) - 1))))
1840                 val |= ~ (((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1);
1841             }
1842
1843           /* Clear the bits that don't belong in our mode,
1844              unless they and our sign bit are all one.
1845              So we get either a reasonable negative value or a reasonable
1846              unsigned value for this mode.  */
1847           if (width < HOST_BITS_PER_WIDE_INT
1848               && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
1849                   != ((HOST_WIDE_INT) (-1) << (width - 1))))
1850             val &= ((HOST_WIDE_INT) 1 << width) - 1;
1851
1852           return GEN_INT (val);
1853         }
1854       break;
1855
1856     case IF_THEN_ELSE:
1857       if (GET_CODE (op0) == CONST_INT)
1858         return op0 != const0_rtx ? op1 : op2;
1859
1860       /* Convert a == b ? b : a to "a".  */
1861       if (GET_CODE (op0) == NE && ! side_effects_p (op0)
1862           && rtx_equal_p (XEXP (op0, 0), op1)
1863           && rtx_equal_p (XEXP (op0, 1), op2))
1864         return op1;
1865       else if (GET_CODE (op0) == EQ && ! side_effects_p (op0)
1866           && rtx_equal_p (XEXP (op0, 1), op1)
1867           && rtx_equal_p (XEXP (op0, 0), op2))
1868         return op2;
1869       else if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && ! side_effects_p (op0))
1870         {
1871           rtx temp;
1872           temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
1873                                                 XEXP (op0, 0), XEXP (op0, 1));
1874           /* See if any simplifications were possible.  */
1875           if (temp == const0_rtx)
1876             return op2;
1877           else if (temp == const1_rtx)
1878             return op1;
1879         }
1880       break;
1881
1882     default:
1883       abort ();
1884     }
1885
1886   return 0;
1887 }
1888
1889 /* Simplify X, an rtx expression.
1890
1891    Return the simplified expression or NULL if no simplifications
1892    were possible.
1893
1894    This is the preferred entry point into the simplification routines;
1895    however, we still allow passes to call the more specific routines.
1896
1897    Right now GCC has three (yes, three) major bodies of RTL simplficiation
1898    code that need to be unified.
1899
1900         1. fold_rtx in cse.c.  This code uses various CSE specific
1901            information to aid in RTL simplification.
1902
1903         2. simplify_rtx in combine.c.  Similar to fold_rtx, except that
1904            it uses combine specific information to aid in RTL
1905            simplification.
1906
1907         3. The routines in this file.
1908
1909
1910    Long term we want to only have one body of simplification code; to
1911    get to that state I recommend the following steps:
1912
1913         1. Pour over fold_rtx & simplify_rtx and move any simplifications
1914            which are not pass dependent state into these routines.
1915
1916         2. As code is moved by #1, change fold_rtx & simplify_rtx to
1917            use this routine whenever possible.
1918
1919         3. Allow for pass dependent state to be provided to these
1920            routines and add simplifications based on the pass dependent
1921            state.  Remove code from cse.c & combine.c that becomes
1922            redundant/dead.
1923
1924     It will take time, but ultimately the compiler will be easier to
1925     maintain and improve.  It's totally silly that when we add a
1926     simplification that it needs to be added to 4 places (3 for RTL
1927     simplification and 1 for tree simplification.  */
1928            
1929 rtx
1930 simplify_rtx (x)
1931      rtx x;
1932 {
1933   enum rtx_code code;
1934   enum machine_mode mode;
1935
1936   mode = GET_MODE (x);
1937   code = GET_CODE (x);
1938
1939   switch (GET_RTX_CLASS (code))
1940     {
1941     case '1':
1942       return simplify_unary_operation (code, mode,
1943                                        XEXP (x, 0), GET_MODE (XEXP (x, 0)));
1944     case '2':
1945     case 'c':
1946       return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
1947
1948     case '3':
1949     case 'b':
1950       return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
1951                                          XEXP (x, 0), XEXP (x, 1), XEXP (x, 2));
1952
1953     case '<':
1954       return simplify_relational_operation (code, GET_MODE (XEXP (x, 0)),
1955                                             XEXP (x, 0), XEXP (x, 1));
1956     default:
1957       return NULL;
1958     }
1959 }