OSDN Git Service

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