OSDN Git Service

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