OSDN Git Service

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