OSDN Git Service

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