OSDN Git Service

4a8e3c6166726b76d0b33adde566b73d47a1fe00
[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, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4    Free Software Foundation, Inc.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
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 "insn-config.h"
34 #include "recog.h"
35 #include "function.h"
36 #include "expr.h"
37 #include "diagnostic-core.h"
38 #include "output.h"
39 #include "ggc.h"
40 #include "target.h"
41
42 /* Simplification and canonicalization of RTL.  */
43
44 /* Much code operates on (low, high) pairs; the low value is an
45    unsigned wide int, the high value a signed wide int.  We
46    occasionally need to sign extend from low to high as if low were a
47    signed wide int.  */
48 #define HWI_SIGN_EXTEND(low) \
49  ((((HOST_WIDE_INT) low) < 0) ? ((HOST_WIDE_INT) -1) : ((HOST_WIDE_INT) 0))
50
51 static rtx neg_const_int (enum machine_mode, const_rtx);
52 static bool plus_minus_operand_p (const_rtx);
53 static bool simplify_plus_minus_op_data_cmp (rtx, rtx);
54 static rtx simplify_plus_minus (enum rtx_code, enum machine_mode, rtx, rtx);
55 static rtx simplify_immed_subreg (enum machine_mode, rtx, enum machine_mode,
56                                   unsigned int);
57 static rtx simplify_associative_operation (enum rtx_code, enum machine_mode,
58                                            rtx, rtx);
59 static rtx simplify_relational_operation_1 (enum rtx_code, enum machine_mode,
60                                             enum machine_mode, rtx, rtx);
61 static rtx simplify_unary_operation_1 (enum rtx_code, enum machine_mode, rtx);
62 static rtx simplify_binary_operation_1 (enum rtx_code, enum machine_mode,
63                                         rtx, rtx, rtx, rtx);
64 \f
65 /* Negate a CONST_INT rtx, truncating (because a conversion from a
66    maximally negative number can overflow).  */
67 static rtx
68 neg_const_int (enum machine_mode mode, const_rtx i)
69 {
70   return gen_int_mode (- INTVAL (i), mode);
71 }
72
73 /* Test whether expression, X, is an immediate constant that represents
74    the most significant bit of machine mode MODE.  */
75
76 bool
77 mode_signbit_p (enum machine_mode mode, const_rtx x)
78 {
79   unsigned HOST_WIDE_INT val;
80   unsigned int width;
81
82   if (GET_MODE_CLASS (mode) != MODE_INT)
83     return false;
84
85   width = GET_MODE_BITSIZE (mode);
86   if (width == 0)
87     return false;
88
89   if (width <= HOST_BITS_PER_WIDE_INT
90       && CONST_INT_P (x))
91     val = INTVAL (x);
92   else if (width <= 2 * HOST_BITS_PER_WIDE_INT
93            && GET_CODE (x) == CONST_DOUBLE
94            && CONST_DOUBLE_LOW (x) == 0)
95     {
96       val = CONST_DOUBLE_HIGH (x);
97       width -= HOST_BITS_PER_WIDE_INT;
98     }
99   else
100     return false;
101
102   if (width < HOST_BITS_PER_WIDE_INT)
103     val &= ((unsigned HOST_WIDE_INT) 1 << width) - 1;
104   return val == ((unsigned HOST_WIDE_INT) 1 << (width - 1));
105 }
106 \f
107 /* Make a binary operation by properly ordering the operands and
108    seeing if the expression folds.  */
109
110 rtx
111 simplify_gen_binary (enum rtx_code code, enum machine_mode mode, rtx op0,
112                      rtx op1)
113 {
114   rtx tem;
115
116   /* If this simplifies, do it.  */
117   tem = simplify_binary_operation (code, mode, op0, op1);
118   if (tem)
119     return tem;
120
121   /* Put complex operands first and constants second if commutative.  */
122   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
123       && swap_commutative_operands_p (op0, op1))
124     tem = op0, op0 = op1, op1 = tem;
125
126   return gen_rtx_fmt_ee (code, mode, op0, op1);
127 }
128 \f
129 /* If X is a MEM referencing the constant pool, return the real value.
130    Otherwise return X.  */
131 rtx
132 avoid_constant_pool_reference (rtx x)
133 {
134   rtx c, tmp, addr;
135   enum machine_mode cmode;
136   HOST_WIDE_INT offset = 0;
137
138   switch (GET_CODE (x))
139     {
140     case MEM:
141       break;
142
143     case FLOAT_EXTEND:
144       /* Handle float extensions of constant pool references.  */
145       tmp = XEXP (x, 0);
146       c = avoid_constant_pool_reference (tmp);
147       if (c != tmp && GET_CODE (c) == CONST_DOUBLE)
148         {
149           REAL_VALUE_TYPE d;
150
151           REAL_VALUE_FROM_CONST_DOUBLE (d, c);
152           return CONST_DOUBLE_FROM_REAL_VALUE (d, GET_MODE (x));
153         }
154       return x;
155
156     default:
157       return x;
158     }
159
160   if (GET_MODE (x) == BLKmode)
161     return x;
162
163   addr = XEXP (x, 0);
164
165   /* Call target hook to avoid the effects of -fpic etc....  */
166   addr = targetm.delegitimize_address (addr);
167
168   /* Split the address into a base and integer offset.  */
169   if (GET_CODE (addr) == CONST
170       && GET_CODE (XEXP (addr, 0)) == PLUS
171       && CONST_INT_P (XEXP (XEXP (addr, 0), 1)))
172     {
173       offset = INTVAL (XEXP (XEXP (addr, 0), 1));
174       addr = XEXP (XEXP (addr, 0), 0);
175     }
176
177   if (GET_CODE (addr) == LO_SUM)
178     addr = XEXP (addr, 1);
179
180   /* If this is a constant pool reference, we can turn it into its
181      constant and hope that simplifications happen.  */
182   if (GET_CODE (addr) == SYMBOL_REF
183       && CONSTANT_POOL_ADDRESS_P (addr))
184     {
185       c = get_pool_constant (addr);
186       cmode = get_pool_mode (addr);
187
188       /* If we're accessing the constant in a different mode than it was
189          originally stored, attempt to fix that up via subreg simplifications.
190          If that fails we have no choice but to return the original memory.  */
191       if (offset != 0 || cmode != GET_MODE (x))
192         {
193           rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
194           if (tem && CONSTANT_P (tem))
195             return tem;
196         }
197       else
198         return c;
199     }
200
201   return x;
202 }
203 \f
204 /* Simplify a MEM based on its attributes.  This is the default
205    delegitimize_address target hook, and it's recommended that every
206    overrider call it.  */
207
208 rtx
209 delegitimize_mem_from_attrs (rtx x)
210 {
211   /* MEMs without MEM_OFFSETs may have been offset, so we can't just
212      use their base addresses as equivalent.  */
213   if (MEM_P (x)
214       && MEM_EXPR (x)
215       && MEM_OFFSET (x))
216     {
217       tree decl = MEM_EXPR (x);
218       enum machine_mode mode = GET_MODE (x);
219       HOST_WIDE_INT offset = 0;
220
221       switch (TREE_CODE (decl))
222         {
223         default:
224           decl = NULL;
225           break;
226
227         case VAR_DECL:
228           break;
229
230         case ARRAY_REF:
231         case ARRAY_RANGE_REF:
232         case COMPONENT_REF:
233         case BIT_FIELD_REF:
234         case REALPART_EXPR:
235         case IMAGPART_EXPR:
236         case VIEW_CONVERT_EXPR:
237           {
238             HOST_WIDE_INT bitsize, bitpos;
239             tree toffset;
240             int unsignedp = 0, volatilep = 0;
241
242             decl = get_inner_reference (decl, &bitsize, &bitpos, &toffset,
243                                         &mode, &unsignedp, &volatilep, false);
244             if (bitsize != GET_MODE_BITSIZE (mode)
245                 || (bitpos % BITS_PER_UNIT)
246                 || (toffset && !host_integerp (toffset, 0)))
247               decl = NULL;
248             else
249               {
250                 offset += bitpos / BITS_PER_UNIT;
251                 if (toffset)
252                   offset += TREE_INT_CST_LOW (toffset);
253               }
254             break;
255           }
256         }
257
258       if (decl
259           && mode == GET_MODE (x)
260           && TREE_CODE (decl) == VAR_DECL
261           && (TREE_STATIC (decl)
262               || DECL_THREAD_LOCAL_P (decl))
263           && DECL_RTL_SET_P (decl)
264           && MEM_P (DECL_RTL (decl)))
265         {
266           rtx newx;
267
268           offset += INTVAL (MEM_OFFSET (x));
269
270           newx = DECL_RTL (decl);
271
272           if (MEM_P (newx))
273             {
274               rtx n = XEXP (newx, 0), o = XEXP (x, 0);
275
276               /* Avoid creating a new MEM needlessly if we already had
277                  the same address.  We do if there's no OFFSET and the
278                  old address X is identical to NEWX, or if X is of the
279                  form (plus NEWX OFFSET), or the NEWX is of the form
280                  (plus Y (const_int Z)) and X is that with the offset
281                  added: (plus Y (const_int Z+OFFSET)).  */
282               if (!((offset == 0
283                      || (GET_CODE (o) == PLUS
284                          && GET_CODE (XEXP (o, 1)) == CONST_INT
285                          && (offset == INTVAL (XEXP (o, 1))
286                              || (GET_CODE (n) == PLUS
287                                  && GET_CODE (XEXP (n, 1)) == CONST_INT
288                                  && (INTVAL (XEXP (n, 1)) + offset
289                                      == INTVAL (XEXP (o, 1)))
290                                  && (n = XEXP (n, 0))))
291                          && (o = XEXP (o, 0))))
292                     && rtx_equal_p (o, n)))
293                 x = adjust_address_nv (newx, mode, offset);
294             }
295           else if (GET_MODE (x) == GET_MODE (newx)
296                    && offset == 0)
297             x = newx;
298         }
299     }
300
301   return x;
302 }
303 \f
304 /* Make a unary operation by first seeing if it folds and otherwise making
305    the specified operation.  */
306
307 rtx
308 simplify_gen_unary (enum rtx_code code, enum machine_mode mode, rtx op,
309                     enum machine_mode op_mode)
310 {
311   rtx tem;
312
313   /* If this simplifies, use it.  */
314   if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
315     return tem;
316
317   return gen_rtx_fmt_e (code, mode, op);
318 }
319
320 /* Likewise for ternary operations.  */
321
322 rtx
323 simplify_gen_ternary (enum rtx_code code, enum machine_mode mode,
324                       enum machine_mode op0_mode, rtx op0, rtx op1, rtx op2)
325 {
326   rtx tem;
327
328   /* If this simplifies, use it.  */
329   if (0 != (tem = simplify_ternary_operation (code, mode, op0_mode,
330                                               op0, op1, op2)))
331     return tem;
332
333   return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
334 }
335
336 /* Likewise, for relational operations.
337    CMP_MODE specifies mode comparison is done in.  */
338
339 rtx
340 simplify_gen_relational (enum rtx_code code, enum machine_mode mode,
341                          enum machine_mode cmp_mode, rtx op0, rtx op1)
342 {
343   rtx tem;
344
345   if (0 != (tem = simplify_relational_operation (code, mode, cmp_mode,
346                                                  op0, op1)))
347     return tem;
348
349   return gen_rtx_fmt_ee (code, mode, op0, op1);
350 }
351 \f
352 /* If FN is NULL, replace all occurrences of OLD_RTX in X with copy_rtx (DATA)
353    and simplify the result.  If FN is non-NULL, call this callback on each
354    X, if it returns non-NULL, replace X with its return value and simplify the
355    result.  */
356
357 rtx
358 simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
359                          rtx (*fn) (rtx, const_rtx, void *), void *data)
360 {
361   enum rtx_code code = GET_CODE (x);
362   enum machine_mode mode = GET_MODE (x);
363   enum machine_mode op_mode;
364   const char *fmt;
365   rtx op0, op1, op2, newx, op;
366   rtvec vec, newvec;
367   int i, j;
368
369   if (__builtin_expect (fn != NULL, 0))
370     {
371       newx = fn (x, old_rtx, data);
372       if (newx)
373         return newx;
374     }
375   else if (rtx_equal_p (x, old_rtx))
376     return copy_rtx ((rtx) data);
377
378   switch (GET_RTX_CLASS (code))
379     {
380     case RTX_UNARY:
381       op0 = XEXP (x, 0);
382       op_mode = GET_MODE (op0);
383       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
384       if (op0 == XEXP (x, 0))
385         return x;
386       return simplify_gen_unary (code, mode, op0, op_mode);
387
388     case RTX_BIN_ARITH:
389     case RTX_COMM_ARITH:
390       op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
391       op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
392       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
393         return x;
394       return simplify_gen_binary (code, mode, op0, op1);
395
396     case RTX_COMPARE:
397     case RTX_COMM_COMPARE:
398       op0 = XEXP (x, 0);
399       op1 = XEXP (x, 1);
400       op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
401       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
402       op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
403       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
404         return x;
405       return simplify_gen_relational (code, mode, op_mode, op0, op1);
406
407     case RTX_TERNARY:
408     case RTX_BITFIELD_OPS:
409       op0 = XEXP (x, 0);
410       op_mode = GET_MODE (op0);
411       op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
412       op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
413       op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
414       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
415         return x;
416       if (op_mode == VOIDmode)
417         op_mode = GET_MODE (op0);
418       return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
419
420     case RTX_EXTRA:
421       if (code == SUBREG)
422         {
423           op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
424           if (op0 == SUBREG_REG (x))
425             return x;
426           op0 = simplify_gen_subreg (GET_MODE (x), op0,
427                                      GET_MODE (SUBREG_REG (x)),
428                                      SUBREG_BYTE (x));
429           return op0 ? op0 : x;
430         }
431       break;
432
433     case RTX_OBJ:
434       if (code == MEM)
435         {
436           op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
437           if (op0 == XEXP (x, 0))
438             return x;
439           return replace_equiv_address_nv (x, op0);
440         }
441       else if (code == LO_SUM)
442         {
443           op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
444           op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
445
446           /* (lo_sum (high x) x) -> x  */
447           if (GET_CODE (op0) == HIGH && rtx_equal_p (XEXP (op0, 0), op1))
448             return op1;
449
450           if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
451             return x;
452           return gen_rtx_LO_SUM (mode, op0, op1);
453         }
454       break;
455
456     default:
457       break;
458     }
459
460   newx = x;
461   fmt = GET_RTX_FORMAT (code);
462   for (i = 0; fmt[i]; i++)
463     switch (fmt[i])
464       {
465       case 'E':
466         vec = XVEC (x, i);
467         newvec = XVEC (newx, i);
468         for (j = 0; j < GET_NUM_ELEM (vec); j++)
469           {
470             op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
471                                           old_rtx, fn, data);
472             if (op != RTVEC_ELT (vec, j))
473               {
474                 if (newvec == vec)
475                   {
476                     newvec = shallow_copy_rtvec (vec);
477                     if (x == newx)
478                       newx = shallow_copy_rtx (x);
479                     XVEC (newx, i) = newvec;
480                   }
481                 RTVEC_ELT (newvec, j) = op;
482               }
483           }
484         break;
485
486       case 'e':
487         if (XEXP (x, i))
488           {
489             op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
490             if (op != XEXP (x, i))
491               {
492                 if (x == newx)
493                   newx = shallow_copy_rtx (x);
494                 XEXP (newx, i) = op;
495               }
496           }
497         break;
498       }
499   return newx;
500 }
501
502 /* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the
503    resulting RTX.  Return a new RTX which is as simplified as possible.  */
504
505 rtx
506 simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
507 {
508   return simplify_replace_fn_rtx (x, old_rtx, 0, new_rtx);
509 }
510 \f
511 /* Try to simplify a unary operation CODE whose output mode is to be
512    MODE with input operand OP whose mode was originally OP_MODE.
513    Return zero if no simplification can be made.  */
514 rtx
515 simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
516                           rtx op, enum machine_mode op_mode)
517 {
518   rtx trueop, tem;
519
520   trueop = avoid_constant_pool_reference (op);
521
522   tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
523   if (tem)
524     return tem;
525
526   return simplify_unary_operation_1 (code, mode, op);
527 }
528
529 /* Perform some simplifications we can do even if the operands
530    aren't constant.  */
531 static rtx
532 simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
533 {
534   enum rtx_code reversed;
535   rtx temp;
536
537   switch (code)
538     {
539     case NOT:
540       /* (not (not X)) == X.  */
541       if (GET_CODE (op) == NOT)
542         return XEXP (op, 0);
543
544       /* (not (eq X Y)) == (ne X Y), etc. if BImode or the result of the
545          comparison is all ones.   */
546       if (COMPARISON_P (op)
547           && (mode == BImode || STORE_FLAG_VALUE == -1)
548           && ((reversed = reversed_comparison_code (op, NULL_RTX)) != UNKNOWN))
549         return simplify_gen_relational (reversed, mode, VOIDmode,
550                                         XEXP (op, 0), XEXP (op, 1));
551
552       /* (not (plus X -1)) can become (neg X).  */
553       if (GET_CODE (op) == PLUS
554           && XEXP (op, 1) == constm1_rtx)
555         return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
556
557       /* Similarly, (not (neg X)) is (plus X -1).  */
558       if (GET_CODE (op) == NEG)
559         return plus_constant (XEXP (op, 0), -1);
560
561       /* (not (xor X C)) for C constant is (xor X D) with D = ~C.  */
562       if (GET_CODE (op) == XOR
563           && CONST_INT_P (XEXP (op, 1))
564           && (temp = simplify_unary_operation (NOT, mode,
565                                                XEXP (op, 1), mode)) != 0)
566         return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
567
568       /* (not (plus X C)) for signbit C is (xor X D) with D = ~C.  */
569       if (GET_CODE (op) == PLUS
570           && CONST_INT_P (XEXP (op, 1))
571           && mode_signbit_p (mode, XEXP (op, 1))
572           && (temp = simplify_unary_operation (NOT, mode,
573                                                XEXP (op, 1), mode)) != 0)
574         return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
575
576
577       /* (not (ashift 1 X)) is (rotate ~1 X).  We used to do this for
578          operands other than 1, but that is not valid.  We could do a
579          similar simplification for (not (lshiftrt C X)) where C is
580          just the sign bit, but this doesn't seem common enough to
581          bother with.  */
582       if (GET_CODE (op) == ASHIFT
583           && XEXP (op, 0) == const1_rtx)
584         {
585           temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
586           return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
587         }
588
589       /* (not (ashiftrt foo C)) where C is the number of bits in FOO
590          minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
591          so we can perform the above simplification.  */
592
593       if (STORE_FLAG_VALUE == -1
594           && GET_CODE (op) == ASHIFTRT
595           && GET_CODE (XEXP (op, 1))
596           && INTVAL (XEXP (op, 1)) == GET_MODE_BITSIZE (mode) - 1)
597         return simplify_gen_relational (GE, mode, VOIDmode,
598                                         XEXP (op, 0), const0_rtx);
599
600
601       if (GET_CODE (op) == SUBREG
602           && subreg_lowpart_p (op)
603           && (GET_MODE_SIZE (GET_MODE (op))
604               < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))))
605           && GET_CODE (SUBREG_REG (op)) == ASHIFT
606           && XEXP (SUBREG_REG (op), 0) == const1_rtx)
607         {
608           enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
609           rtx x;
610
611           x = gen_rtx_ROTATE (inner_mode,
612                               simplify_gen_unary (NOT, inner_mode, const1_rtx,
613                                                   inner_mode),
614                               XEXP (SUBREG_REG (op), 1));
615           return rtl_hooks.gen_lowpart_no_emit (mode, x);
616         }
617
618       /* Apply De Morgan's laws to reduce number of patterns for machines
619          with negating logical insns (and-not, nand, etc.).  If result has
620          only one NOT, put it first, since that is how the patterns are
621          coded.  */
622
623       if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
624         {
625           rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
626           enum machine_mode op_mode;
627
628           op_mode = GET_MODE (in1);
629           in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
630
631           op_mode = GET_MODE (in2);
632           if (op_mode == VOIDmode)
633             op_mode = mode;
634           in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
635
636           if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
637             {
638               rtx tem = in2;
639               in2 = in1; in1 = tem;
640             }
641
642           return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
643                                  mode, in1, in2);
644         }
645       break;
646
647     case NEG:
648       /* (neg (neg X)) == X.  */
649       if (GET_CODE (op) == NEG)
650         return XEXP (op, 0);
651
652       /* (neg (plus X 1)) can become (not X).  */
653       if (GET_CODE (op) == PLUS
654           && XEXP (op, 1) == const1_rtx)
655         return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
656
657       /* Similarly, (neg (not X)) is (plus X 1).  */
658       if (GET_CODE (op) == NOT)
659         return plus_constant (XEXP (op, 0), 1);
660
661       /* (neg (minus X Y)) can become (minus Y X).  This transformation
662          isn't safe for modes with signed zeros, since if X and Y are
663          both +0, (minus Y X) is the same as (minus X Y).  If the
664          rounding mode is towards +infinity (or -infinity) then the two
665          expressions will be rounded differently.  */
666       if (GET_CODE (op) == MINUS
667           && !HONOR_SIGNED_ZEROS (mode)
668           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
669         return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
670
671       if (GET_CODE (op) == PLUS
672           && !HONOR_SIGNED_ZEROS (mode)
673           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
674         {
675           /* (neg (plus A C)) is simplified to (minus -C A).  */
676           if (CONST_INT_P (XEXP (op, 1))
677               || GET_CODE (XEXP (op, 1)) == CONST_DOUBLE)
678             {
679               temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
680               if (temp)
681                 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
682             }
683
684           /* (neg (plus A B)) is canonicalized to (minus (neg A) B).  */
685           temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
686           return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
687         }
688
689       /* (neg (mult A B)) becomes (mult (neg A) B).
690          This works even for floating-point values.  */
691       if (GET_CODE (op) == MULT
692           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
693         {
694           temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
695           return simplify_gen_binary (MULT, mode, temp, XEXP (op, 1));
696         }
697
698       /* NEG commutes with ASHIFT since it is multiplication.  Only do
699          this if we can then eliminate the NEG (e.g., if the operand
700          is a constant).  */
701       if (GET_CODE (op) == ASHIFT)
702         {
703           temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
704           if (temp)
705             return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
706         }
707
708       /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
709          C is equal to the width of MODE minus 1.  */
710       if (GET_CODE (op) == ASHIFTRT
711           && CONST_INT_P (XEXP (op, 1))
712           && INTVAL (XEXP (op, 1)) == GET_MODE_BITSIZE (mode) - 1)
713         return simplify_gen_binary (LSHIFTRT, mode,
714                                     XEXP (op, 0), XEXP (op, 1));
715
716       /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
717          C is equal to the width of MODE minus 1.  */
718       if (GET_CODE (op) == LSHIFTRT
719           && CONST_INT_P (XEXP (op, 1))
720           && INTVAL (XEXP (op, 1)) == GET_MODE_BITSIZE (mode) - 1)
721         return simplify_gen_binary (ASHIFTRT, mode,
722                                     XEXP (op, 0), XEXP (op, 1));
723
724       /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1.  */
725       if (GET_CODE (op) == XOR
726           && XEXP (op, 1) == const1_rtx
727           && nonzero_bits (XEXP (op, 0), mode) == 1)
728         return plus_constant (XEXP (op, 0), -1);
729
730       /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1.  */
731       /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1.  */
732       if (GET_CODE (op) == LT
733           && XEXP (op, 1) == const0_rtx
734           && SCALAR_INT_MODE_P (GET_MODE (XEXP (op, 0))))
735         {
736           enum machine_mode inner = GET_MODE (XEXP (op, 0));
737           int isize = GET_MODE_BITSIZE (inner);
738           if (STORE_FLAG_VALUE == 1)
739             {
740               temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
741                                           GEN_INT (isize - 1));
742               if (mode == inner)
743                 return temp;
744               if (GET_MODE_BITSIZE (mode) > isize)
745                 return simplify_gen_unary (SIGN_EXTEND, mode, temp, inner);
746               return simplify_gen_unary (TRUNCATE, mode, temp, inner);
747             }
748           else if (STORE_FLAG_VALUE == -1)
749             {
750               temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
751                                           GEN_INT (isize - 1));
752               if (mode == inner)
753                 return temp;
754               if (GET_MODE_BITSIZE (mode) > isize)
755                 return simplify_gen_unary (ZERO_EXTEND, mode, temp, inner);
756               return simplify_gen_unary (TRUNCATE, mode, temp, inner);
757             }
758         }
759       break;
760
761     case TRUNCATE:
762       /* We can't handle truncation to a partial integer mode here
763          because we don't know the real bitsize of the partial
764          integer mode.  */
765       if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
766         break;
767
768       /* (truncate:SI ({sign,zero}_extend:DI foo:SI)) == foo:SI.  */
769       if ((GET_CODE (op) == SIGN_EXTEND
770            || GET_CODE (op) == ZERO_EXTEND)
771           && GET_MODE (XEXP (op, 0)) == mode)
772         return XEXP (op, 0);
773
774       /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
775          (OP:SI foo:SI) if OP is NEG or ABS.  */
776       if ((GET_CODE (op) == ABS
777            || GET_CODE (op) == NEG)
778           && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
779               || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
780           && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
781         return simplify_gen_unary (GET_CODE (op), mode,
782                                    XEXP (XEXP (op, 0), 0), mode);
783
784       /* (truncate:A (subreg:B (truncate:C X) 0)) is
785          (truncate:A X).  */
786       if (GET_CODE (op) == SUBREG
787           && GET_CODE (SUBREG_REG (op)) == TRUNCATE
788           && subreg_lowpart_p (op))
789         return simplify_gen_unary (TRUNCATE, mode, XEXP (SUBREG_REG (op), 0),
790                                    GET_MODE (XEXP (SUBREG_REG (op), 0)));
791
792       /* If we know that the value is already truncated, we can
793          replace the TRUNCATE with a SUBREG.  Note that this is also
794          valid if TRULY_NOOP_TRUNCATION is false for the corresponding
795          modes we just have to apply a different definition for
796          truncation.  But don't do this for an (LSHIFTRT (MULT ...))
797          since this will cause problems with the umulXi3_highpart
798          patterns.  */
799       if ((TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
800                                  GET_MODE_BITSIZE (GET_MODE (op)))
801            ? (num_sign_bit_copies (op, GET_MODE (op))
802               > (unsigned int) (GET_MODE_BITSIZE (GET_MODE (op))
803                                 - GET_MODE_BITSIZE (mode)))
804            : truncated_to_mode (mode, op))
805           && ! (GET_CODE (op) == LSHIFTRT
806                 && GET_CODE (XEXP (op, 0)) == MULT))
807         return rtl_hooks.gen_lowpart_no_emit (mode, op);
808
809       /* A truncate of a comparison can be replaced with a subreg if
810          STORE_FLAG_VALUE permits.  This is like the previous test,
811          but it works even if the comparison is done in a mode larger
812          than HOST_BITS_PER_WIDE_INT.  */
813       if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
814           && COMPARISON_P (op)
815           && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0)
816         return rtl_hooks.gen_lowpart_no_emit (mode, op);
817       break;
818
819     case FLOAT_TRUNCATE:
820       if (DECIMAL_FLOAT_MODE_P (mode))
821         break;
822
823       /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF.  */
824       if (GET_CODE (op) == FLOAT_EXTEND
825           && GET_MODE (XEXP (op, 0)) == mode)
826         return XEXP (op, 0);
827
828       /* (float_truncate:SF (float_truncate:DF foo:XF))
829          = (float_truncate:SF foo:XF).
830          This may eliminate double rounding, so it is unsafe.
831
832          (float_truncate:SF (float_extend:XF foo:DF))
833          = (float_truncate:SF foo:DF).
834
835          (float_truncate:DF (float_extend:XF foo:SF))
836          = (float_extend:SF foo:DF).  */
837       if ((GET_CODE (op) == FLOAT_TRUNCATE
838            && flag_unsafe_math_optimizations)
839           || GET_CODE (op) == FLOAT_EXTEND)
840         return simplify_gen_unary (GET_MODE_SIZE (GET_MODE (XEXP (op,
841                                                             0)))
842                                    > GET_MODE_SIZE (mode)
843                                    ? FLOAT_TRUNCATE : FLOAT_EXTEND,
844                                    mode,
845                                    XEXP (op, 0), mode);
846
847       /*  (float_truncate (float x)) is (float x)  */
848       if (GET_CODE (op) == FLOAT
849           && (flag_unsafe_math_optimizations
850               || (SCALAR_FLOAT_MODE_P (GET_MODE (op))
851                   && ((unsigned)significand_size (GET_MODE (op))
852                       >= (GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0)))
853                           - num_sign_bit_copies (XEXP (op, 0),
854                                                  GET_MODE (XEXP (op, 0))))))))
855         return simplify_gen_unary (FLOAT, mode,
856                                    XEXP (op, 0),
857                                    GET_MODE (XEXP (op, 0)));
858
859       /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
860          (OP:SF foo:SF) if OP is NEG or ABS.  */
861       if ((GET_CODE (op) == ABS
862            || GET_CODE (op) == NEG)
863           && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
864           && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
865         return simplify_gen_unary (GET_CODE (op), mode,
866                                    XEXP (XEXP (op, 0), 0), mode);
867
868       /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
869          is (float_truncate:SF x).  */
870       if (GET_CODE (op) == SUBREG
871           && subreg_lowpart_p (op)
872           && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
873         return SUBREG_REG (op);
874       break;
875
876     case FLOAT_EXTEND:
877       if (DECIMAL_FLOAT_MODE_P (mode))
878         break;
879
880       /*  (float_extend (float_extend x)) is (float_extend x)
881
882           (float_extend (float x)) is (float x) assuming that double
883           rounding can't happen.
884           */
885       if (GET_CODE (op) == FLOAT_EXTEND
886           || (GET_CODE (op) == FLOAT
887               && SCALAR_FLOAT_MODE_P (GET_MODE (op))
888               && ((unsigned)significand_size (GET_MODE (op))
889                   >= (GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0)))
890                       - num_sign_bit_copies (XEXP (op, 0),
891                                              GET_MODE (XEXP (op, 0)))))))
892         return simplify_gen_unary (GET_CODE (op), mode,
893                                    XEXP (op, 0),
894                                    GET_MODE (XEXP (op, 0)));
895
896       break;
897
898     case ABS:
899       /* (abs (neg <foo>)) -> (abs <foo>) */
900       if (GET_CODE (op) == NEG)
901         return simplify_gen_unary (ABS, mode, XEXP (op, 0),
902                                    GET_MODE (XEXP (op, 0)));
903
904       /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
905          do nothing.  */
906       if (GET_MODE (op) == VOIDmode)
907         break;
908
909       /* If operand is something known to be positive, ignore the ABS.  */
910       if (GET_CODE (op) == FFS || GET_CODE (op) == ABS
911           || ((GET_MODE_BITSIZE (GET_MODE (op))
912                <= HOST_BITS_PER_WIDE_INT)
913               && ((nonzero_bits (op, GET_MODE (op))
914                    & ((unsigned HOST_WIDE_INT) 1
915                       << (GET_MODE_BITSIZE (GET_MODE (op)) - 1)))
916                   == 0)))
917         return op;
918
919       /* If operand is known to be only -1 or 0, convert ABS to NEG.  */
920       if (num_sign_bit_copies (op, mode) == GET_MODE_BITSIZE (mode))
921         return gen_rtx_NEG (mode, op);
922
923       break;
924
925     case FFS:
926       /* (ffs (*_extend <X>)) = (ffs <X>) */
927       if (GET_CODE (op) == SIGN_EXTEND
928           || GET_CODE (op) == ZERO_EXTEND)
929         return simplify_gen_unary (FFS, mode, XEXP (op, 0),
930                                    GET_MODE (XEXP (op, 0)));
931       break;
932
933     case POPCOUNT:
934       switch (GET_CODE (op))
935         {
936         case BSWAP:
937         case ZERO_EXTEND:
938           /* (popcount (zero_extend <X>)) = (popcount <X>) */
939           return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
940                                      GET_MODE (XEXP (op, 0)));
941
942         case ROTATE:
943         case ROTATERT:
944           /* Rotations don't affect popcount.  */
945           if (!side_effects_p (XEXP (op, 1)))
946             return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
947                                        GET_MODE (XEXP (op, 0)));
948           break;
949
950         default:
951           break;
952         }
953       break;
954
955     case PARITY:
956       switch (GET_CODE (op))
957         {
958         case NOT:
959         case BSWAP:
960         case ZERO_EXTEND:
961         case SIGN_EXTEND:
962           return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
963                                      GET_MODE (XEXP (op, 0)));
964
965         case ROTATE:
966         case ROTATERT:
967           /* Rotations don't affect parity.  */
968           if (!side_effects_p (XEXP (op, 1)))
969             return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
970                                        GET_MODE (XEXP (op, 0)));
971           break;
972
973         default:
974           break;
975         }
976       break;
977
978     case BSWAP:
979       /* (bswap (bswap x)) -> x.  */
980       if (GET_CODE (op) == BSWAP)
981         return XEXP (op, 0);
982       break;
983
984     case FLOAT:
985       /* (float (sign_extend <X>)) = (float <X>).  */
986       if (GET_CODE (op) == SIGN_EXTEND)
987         return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
988                                    GET_MODE (XEXP (op, 0)));
989       break;
990
991     case SIGN_EXTEND:
992       /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
993          becomes just the MINUS if its mode is MODE.  This allows
994          folding switch statements on machines using casesi (such as
995          the VAX).  */
996       if (GET_CODE (op) == TRUNCATE
997           && GET_MODE (XEXP (op, 0)) == mode
998           && GET_CODE (XEXP (op, 0)) == MINUS
999           && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1000           && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1001         return XEXP (op, 0);
1002
1003       /* Check for a sign extension of a subreg of a promoted
1004          variable, where the promotion is sign-extended, and the
1005          target mode is the same as the variable's promotion.  */
1006       if (GET_CODE (op) == SUBREG
1007           && SUBREG_PROMOTED_VAR_P (op)
1008           && ! SUBREG_PROMOTED_UNSIGNED_P (op)
1009           && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
1010         return rtl_hooks.gen_lowpart_no_emit (mode, op);
1011
1012       /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1013          (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
1014       if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1015         {
1016           gcc_assert (GET_MODE_BITSIZE (mode)
1017                       > GET_MODE_BITSIZE (GET_MODE (op)));
1018           return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1019                                      GET_MODE (XEXP (op, 0)));
1020         }
1021
1022       /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1023          is (sign_extend:M (subreg:O <X>)) if there is mode with
1024          GET_MODE_BITSIZE (N) - I bits.
1025          (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1026          is similarly (zero_extend:M (subreg:O <X>)).  */
1027       if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1028           && GET_CODE (XEXP (op, 0)) == ASHIFT
1029           && CONST_INT_P (XEXP (op, 1))
1030           && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1031           && GET_MODE_BITSIZE (GET_MODE (op)) > INTVAL (XEXP (op, 1)))
1032         {
1033           enum machine_mode tmode
1034             = mode_for_size (GET_MODE_BITSIZE (GET_MODE (op))
1035                              - INTVAL (XEXP (op, 1)), MODE_INT, 1);
1036           gcc_assert (GET_MODE_BITSIZE (mode)
1037                       > GET_MODE_BITSIZE (GET_MODE (op)));
1038           if (tmode != BLKmode)
1039             {
1040               rtx inner =
1041                 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1042               return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1043                                          ? SIGN_EXTEND : ZERO_EXTEND,
1044                                          mode, inner, tmode);
1045             }
1046         }
1047
1048 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
1049       /* As we do not know which address space the pointer is refering to,
1050          we can do this only if the target does not support different pointer
1051          or address modes depending on the address space.  */
1052       if (target_default_pointer_address_modes_p ()
1053           && ! POINTERS_EXTEND_UNSIGNED
1054           && mode == Pmode && GET_MODE (op) == ptr_mode
1055           && (CONSTANT_P (op)
1056               || (GET_CODE (op) == SUBREG
1057                   && REG_P (SUBREG_REG (op))
1058                   && REG_POINTER (SUBREG_REG (op))
1059                   && GET_MODE (SUBREG_REG (op)) == Pmode)))
1060         return convert_memory_address (Pmode, op);
1061 #endif
1062       break;
1063
1064     case ZERO_EXTEND:
1065       /* Check for a zero extension of a subreg of a promoted
1066          variable, where the promotion is zero-extended, and the
1067          target mode is the same as the variable's promotion.  */
1068       if (GET_CODE (op) == SUBREG
1069           && SUBREG_PROMOTED_VAR_P (op)
1070           && SUBREG_PROMOTED_UNSIGNED_P (op) > 0
1071           && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
1072         return rtl_hooks.gen_lowpart_no_emit (mode, op);
1073
1074       /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>).  */
1075       if (GET_CODE (op) == ZERO_EXTEND)
1076         return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1077                                    GET_MODE (XEXP (op, 0)));
1078
1079       /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1080          is (zero_extend:M (subreg:O <X>)) if there is mode with
1081          GET_MODE_BITSIZE (N) - I bits.  */
1082       if (GET_CODE (op) == LSHIFTRT
1083           && GET_CODE (XEXP (op, 0)) == ASHIFT
1084           && CONST_INT_P (XEXP (op, 1))
1085           && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1086           && GET_MODE_BITSIZE (GET_MODE (op)) > INTVAL (XEXP (op, 1)))
1087         {
1088           enum machine_mode tmode
1089             = mode_for_size (GET_MODE_BITSIZE (GET_MODE (op))
1090                              - INTVAL (XEXP (op, 1)), MODE_INT, 1);
1091           if (tmode != BLKmode)
1092             {
1093               rtx inner =
1094                 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1095               return simplify_gen_unary (ZERO_EXTEND, mode, inner, tmode);
1096             }
1097         }
1098
1099 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
1100       /* As we do not know which address space the pointer is refering to,
1101          we can do this only if the target does not support different pointer
1102          or address modes depending on the address space.  */
1103       if (target_default_pointer_address_modes_p ()
1104           && POINTERS_EXTEND_UNSIGNED > 0
1105           && mode == Pmode && GET_MODE (op) == ptr_mode
1106           && (CONSTANT_P (op)
1107               || (GET_CODE (op) == SUBREG
1108                   && REG_P (SUBREG_REG (op))
1109                   && REG_POINTER (SUBREG_REG (op))
1110                   && GET_MODE (SUBREG_REG (op)) == Pmode)))
1111         return convert_memory_address (Pmode, op);
1112 #endif
1113       break;
1114
1115     default:
1116       break;
1117     }
1118
1119   return 0;
1120 }
1121
1122 /* Try to compute the value of a unary operation CODE whose output mode is to
1123    be MODE with input operand OP whose mode was originally OP_MODE.
1124    Return zero if the value cannot be computed.  */
1125 rtx
1126 simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
1127                                 rtx op, enum machine_mode op_mode)
1128 {
1129   unsigned int width = GET_MODE_BITSIZE (mode);
1130
1131   if (code == VEC_DUPLICATE)
1132     {
1133       gcc_assert (VECTOR_MODE_P (mode));
1134       if (GET_MODE (op) != VOIDmode)
1135       {
1136         if (!VECTOR_MODE_P (GET_MODE (op)))
1137           gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1138         else
1139           gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1140                                                 (GET_MODE (op)));
1141       }
1142       if (CONST_INT_P (op) || GET_CODE (op) == CONST_DOUBLE
1143           || GET_CODE (op) == CONST_VECTOR)
1144         {
1145           int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
1146           unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
1147           rtvec v = rtvec_alloc (n_elts);
1148           unsigned int i;
1149
1150           if (GET_CODE (op) != CONST_VECTOR)
1151             for (i = 0; i < n_elts; i++)
1152               RTVEC_ELT (v, i) = op;
1153           else
1154             {
1155               enum machine_mode inmode = GET_MODE (op);
1156               int in_elt_size = GET_MODE_SIZE (GET_MODE_INNER (inmode));
1157               unsigned in_n_elts = (GET_MODE_SIZE (inmode) / in_elt_size);
1158
1159               gcc_assert (in_n_elts < n_elts);
1160               gcc_assert ((n_elts % in_n_elts) == 0);
1161               for (i = 0; i < n_elts; i++)
1162                 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op, i % in_n_elts);
1163             }
1164           return gen_rtx_CONST_VECTOR (mode, v);
1165         }
1166     }
1167
1168   if (VECTOR_MODE_P (mode) && GET_CODE (op) == CONST_VECTOR)
1169     {
1170       int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
1171       unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
1172       enum machine_mode opmode = GET_MODE (op);
1173       int op_elt_size = GET_MODE_SIZE (GET_MODE_INNER (opmode));
1174       unsigned op_n_elts = (GET_MODE_SIZE (opmode) / op_elt_size);
1175       rtvec v = rtvec_alloc (n_elts);
1176       unsigned int i;
1177
1178       gcc_assert (op_n_elts == n_elts);
1179       for (i = 0; i < n_elts; i++)
1180         {
1181           rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1182                                             CONST_VECTOR_ELT (op, i),
1183                                             GET_MODE_INNER (opmode));
1184           if (!x)
1185             return 0;
1186           RTVEC_ELT (v, i) = x;
1187         }
1188       return gen_rtx_CONST_VECTOR (mode, v);
1189     }
1190
1191   /* The order of these tests is critical so that, for example, we don't
1192      check the wrong mode (input vs. output) for a conversion operation,
1193      such as FIX.  At some point, this should be simplified.  */
1194
1195   if (code == FLOAT && GET_MODE (op) == VOIDmode
1196       && (GET_CODE (op) == CONST_DOUBLE || CONST_INT_P (op)))
1197     {
1198       HOST_WIDE_INT hv, lv;
1199       REAL_VALUE_TYPE d;
1200
1201       if (CONST_INT_P (op))
1202         lv = INTVAL (op), hv = HWI_SIGN_EXTEND (lv);
1203       else
1204         lv = CONST_DOUBLE_LOW (op),  hv = CONST_DOUBLE_HIGH (op);
1205
1206       REAL_VALUE_FROM_INT (d, lv, hv, mode);
1207       d = real_value_truncate (mode, d);
1208       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
1209     }
1210   else if (code == UNSIGNED_FLOAT && GET_MODE (op) == VOIDmode
1211            && (GET_CODE (op) == CONST_DOUBLE
1212                || CONST_INT_P (op)))
1213     {
1214       HOST_WIDE_INT hv, lv;
1215       REAL_VALUE_TYPE d;
1216
1217       if (CONST_INT_P (op))
1218         lv = INTVAL (op), hv = HWI_SIGN_EXTEND (lv);
1219       else
1220         lv = CONST_DOUBLE_LOW (op),  hv = CONST_DOUBLE_HIGH (op);
1221
1222       if (op_mode == VOIDmode)
1223         {
1224           /* We don't know how to interpret negative-looking numbers in
1225              this case, so don't try to fold those.  */
1226           if (hv < 0)
1227             return 0;
1228         }
1229       else if (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT * 2)
1230         ;
1231       else
1232         hv = 0, lv &= GET_MODE_MASK (op_mode);
1233
1234       REAL_VALUE_FROM_UNSIGNED_INT (d, lv, hv, mode);
1235       d = real_value_truncate (mode, d);
1236       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
1237     }
1238
1239   if (CONST_INT_P (op)
1240       && width <= HOST_BITS_PER_WIDE_INT && width > 0)
1241     {
1242       HOST_WIDE_INT arg0 = INTVAL (op);
1243       HOST_WIDE_INT val;
1244
1245       switch (code)
1246         {
1247         case NOT:
1248           val = ~ arg0;
1249           break;
1250
1251         case NEG:
1252           val = - arg0;
1253           break;
1254
1255         case ABS:
1256           val = (arg0 >= 0 ? arg0 : - arg0);
1257           break;
1258
1259         case FFS:
1260           arg0 &= GET_MODE_MASK (mode);
1261           val = ffs_hwi (arg0);
1262           break;
1263
1264         case CLZ:
1265           arg0 &= GET_MODE_MASK (mode);
1266           if (arg0 == 0 && CLZ_DEFINED_VALUE_AT_ZERO (mode, val))
1267             ;
1268           else
1269             val = GET_MODE_BITSIZE (mode) - floor_log2 (arg0) - 1;
1270           break;
1271
1272         case CTZ:
1273           arg0 &= GET_MODE_MASK (mode);
1274           if (arg0 == 0)
1275             {
1276               /* Even if the value at zero is undefined, we have to come
1277                  up with some replacement.  Seems good enough.  */
1278               if (! CTZ_DEFINED_VALUE_AT_ZERO (mode, val))
1279                 val = GET_MODE_BITSIZE (mode);
1280             }
1281           else
1282             val = ctz_hwi (arg0);
1283           break;
1284
1285         case POPCOUNT:
1286           arg0 &= GET_MODE_MASK (mode);
1287           val = 0;
1288           while (arg0)
1289             val++, arg0 &= arg0 - 1;
1290           break;
1291
1292         case PARITY:
1293           arg0 &= GET_MODE_MASK (mode);
1294           val = 0;
1295           while (arg0)
1296             val++, arg0 &= arg0 - 1;
1297           val &= 1;
1298           break;
1299
1300         case BSWAP:
1301           {
1302             unsigned int s;
1303
1304             val = 0;
1305             for (s = 0; s < width; s += 8)
1306               {
1307                 unsigned int d = width - s - 8;
1308                 unsigned HOST_WIDE_INT byte;
1309                 byte = (arg0 >> s) & 0xff;
1310                 val |= byte << d;
1311               }
1312           }
1313           break;
1314
1315         case TRUNCATE:
1316           val = arg0;
1317           break;
1318
1319         case ZERO_EXTEND:
1320           /* When zero-extending a CONST_INT, we need to know its
1321              original mode.  */
1322           gcc_assert (op_mode != VOIDmode);
1323           if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
1324             {
1325               /* If we were really extending the mode,
1326                  we would have to distinguish between zero-extension
1327                  and sign-extension.  */
1328               gcc_assert (width == GET_MODE_BITSIZE (op_mode));
1329               val = arg0;
1330             }
1331           else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
1332             val = arg0 & ~((unsigned HOST_WIDE_INT) (-1)
1333                            << GET_MODE_BITSIZE (op_mode));
1334           else
1335             return 0;
1336           break;
1337
1338         case SIGN_EXTEND:
1339           if (op_mode == VOIDmode)
1340             op_mode = mode;
1341           if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
1342             {
1343               /* If we were really extending the mode,
1344                  we would have to distinguish between zero-extension
1345                  and sign-extension.  */
1346               gcc_assert (width == GET_MODE_BITSIZE (op_mode));
1347               val = arg0;
1348             }
1349           else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
1350             {
1351               val
1352                 = arg0 & ~((unsigned HOST_WIDE_INT) (-1)
1353                            << GET_MODE_BITSIZE (op_mode));
1354               if (val & ((unsigned HOST_WIDE_INT) 1
1355                          << (GET_MODE_BITSIZE (op_mode) - 1)))
1356                 val
1357                   -= (unsigned HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
1358             }
1359           else
1360             return 0;
1361           break;
1362
1363         case SQRT:
1364         case FLOAT_EXTEND:
1365         case FLOAT_TRUNCATE:
1366         case SS_TRUNCATE:
1367         case US_TRUNCATE:
1368         case SS_NEG:
1369         case US_NEG:
1370         case SS_ABS:
1371           return 0;
1372
1373         default:
1374           gcc_unreachable ();
1375         }
1376
1377       return gen_int_mode (val, mode);
1378     }
1379
1380   /* We can do some operations on integer CONST_DOUBLEs.  Also allow
1381      for a DImode operation on a CONST_INT.  */
1382   else if (GET_MODE (op) == VOIDmode
1383            && width <= HOST_BITS_PER_WIDE_INT * 2
1384            && (GET_CODE (op) == CONST_DOUBLE
1385                || CONST_INT_P (op)))
1386     {
1387       unsigned HOST_WIDE_INT l1, lv;
1388       HOST_WIDE_INT h1, hv;
1389
1390       if (GET_CODE (op) == CONST_DOUBLE)
1391         l1 = CONST_DOUBLE_LOW (op), h1 = CONST_DOUBLE_HIGH (op);
1392       else
1393         l1 = INTVAL (op), h1 = HWI_SIGN_EXTEND (l1);
1394
1395       switch (code)
1396         {
1397         case NOT:
1398           lv = ~ l1;
1399           hv = ~ h1;
1400           break;
1401
1402         case NEG:
1403           neg_double (l1, h1, &lv, &hv);
1404           break;
1405
1406         case ABS:
1407           if (h1 < 0)
1408             neg_double (l1, h1, &lv, &hv);
1409           else
1410             lv = l1, hv = h1;
1411           break;
1412
1413         case FFS:
1414           hv = 0;
1415           if (l1 != 0)
1416             lv = ffs_hwi (l1);
1417           else if (h1 != 0)
1418             lv = HOST_BITS_PER_WIDE_INT + ffs_hwi (h1);
1419           else
1420             lv = 0;
1421           break;
1422
1423         case CLZ:
1424           hv = 0;
1425           if (h1 != 0)
1426             lv = GET_MODE_BITSIZE (mode) - floor_log2 (h1) - 1
1427               - HOST_BITS_PER_WIDE_INT;
1428           else if (l1 != 0)
1429             lv = GET_MODE_BITSIZE (mode) - floor_log2 (l1) - 1;
1430           else if (! CLZ_DEFINED_VALUE_AT_ZERO (mode, lv))
1431             lv = GET_MODE_BITSIZE (mode);
1432           break;
1433
1434         case CTZ:
1435           hv = 0;
1436           if (l1 != 0)
1437             lv = ctz_hwi (l1);
1438           else if (h1 != 0)
1439             lv = HOST_BITS_PER_WIDE_INT + ctz_hwi (h1);
1440           else if (! CTZ_DEFINED_VALUE_AT_ZERO (mode, lv))
1441             lv = GET_MODE_BITSIZE (mode);
1442           break;
1443
1444         case POPCOUNT:
1445           hv = 0;
1446           lv = 0;
1447           while (l1)
1448             lv++, l1 &= l1 - 1;
1449           while (h1)
1450             lv++, h1 &= h1 - 1;
1451           break;
1452
1453         case PARITY:
1454           hv = 0;
1455           lv = 0;
1456           while (l1)
1457             lv++, l1 &= l1 - 1;
1458           while (h1)
1459             lv++, h1 &= h1 - 1;
1460           lv &= 1;
1461           break;
1462
1463         case BSWAP:
1464           {
1465             unsigned int s;
1466
1467             hv = 0;
1468             lv = 0;
1469             for (s = 0; s < width; s += 8)
1470               {
1471                 unsigned int d = width - s - 8;
1472                 unsigned HOST_WIDE_INT byte;
1473
1474                 if (s < HOST_BITS_PER_WIDE_INT)
1475                   byte = (l1 >> s) & 0xff;
1476                 else
1477                   byte = (h1 >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
1478
1479                 if (d < HOST_BITS_PER_WIDE_INT)
1480                   lv |= byte << d;
1481                 else
1482                   hv |= byte << (d - HOST_BITS_PER_WIDE_INT);
1483               }
1484           }
1485           break;
1486
1487         case TRUNCATE:
1488           /* This is just a change-of-mode, so do nothing.  */
1489           lv = l1, hv = h1;
1490           break;
1491
1492         case ZERO_EXTEND:
1493           gcc_assert (op_mode != VOIDmode);
1494
1495           if (GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
1496             return 0;
1497
1498           hv = 0;
1499           lv = l1 & GET_MODE_MASK (op_mode);
1500           break;
1501
1502         case SIGN_EXTEND:
1503           if (op_mode == VOIDmode
1504               || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
1505             return 0;
1506           else
1507             {
1508               lv = l1 & GET_MODE_MASK (op_mode);
1509               if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT
1510                   && (lv & ((unsigned HOST_WIDE_INT) 1
1511                             << (GET_MODE_BITSIZE (op_mode) - 1))) != 0)
1512                 lv -= (unsigned HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
1513
1514               hv = HWI_SIGN_EXTEND (lv);
1515             }
1516           break;
1517
1518         case SQRT:
1519           return 0;
1520
1521         default:
1522           return 0;
1523         }
1524
1525       return immed_double_const (lv, hv, mode);
1526     }
1527
1528   else if (GET_CODE (op) == CONST_DOUBLE
1529            && SCALAR_FLOAT_MODE_P (mode))
1530     {
1531       REAL_VALUE_TYPE d, t;
1532       REAL_VALUE_FROM_CONST_DOUBLE (d, op);
1533
1534       switch (code)
1535         {
1536         case SQRT:
1537           if (HONOR_SNANS (mode) && real_isnan (&d))
1538             return 0;
1539           real_sqrt (&t, mode, &d);
1540           d = t;
1541           break;
1542         case ABS:
1543           d = real_value_abs (&d);
1544           break;
1545         case NEG:
1546           d = real_value_negate (&d);
1547           break;
1548         case FLOAT_TRUNCATE:
1549           d = real_value_truncate (mode, d);
1550           break;
1551         case FLOAT_EXTEND:
1552           /* All this does is change the mode.  */
1553           break;
1554         case FIX:
1555           real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
1556           break;
1557         case NOT:
1558           {
1559             long tmp[4];
1560             int i;
1561
1562             real_to_target (tmp, &d, GET_MODE (op));
1563             for (i = 0; i < 4; i++)
1564               tmp[i] = ~tmp[i];
1565             real_from_target (&d, tmp, mode);
1566             break;
1567           }
1568         default:
1569           gcc_unreachable ();
1570         }
1571       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
1572     }
1573
1574   else if (GET_CODE (op) == CONST_DOUBLE
1575            && SCALAR_FLOAT_MODE_P (GET_MODE (op))
1576            && GET_MODE_CLASS (mode) == MODE_INT
1577            && width <= 2*HOST_BITS_PER_WIDE_INT && width > 0)
1578     {
1579       /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
1580          operators are intentionally left unspecified (to ease implementation
1581          by target backends), for consistency, this routine implements the
1582          same semantics for constant folding as used by the middle-end.  */
1583
1584       /* This was formerly used only for non-IEEE float.
1585          eggert@twinsun.com says it is safe for IEEE also.  */
1586       HOST_WIDE_INT xh, xl, th, tl;
1587       REAL_VALUE_TYPE x, t;
1588       REAL_VALUE_FROM_CONST_DOUBLE (x, op);
1589       switch (code)
1590         {
1591         case FIX:
1592           if (REAL_VALUE_ISNAN (x))
1593             return const0_rtx;
1594
1595           /* Test against the signed upper bound.  */
1596           if (width > HOST_BITS_PER_WIDE_INT)
1597             {
1598               th = ((unsigned HOST_WIDE_INT) 1
1599                     << (width - HOST_BITS_PER_WIDE_INT - 1)) - 1;
1600               tl = -1;
1601             }
1602           else
1603             {
1604               th = 0;
1605               tl = ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1;
1606             }
1607           real_from_integer (&t, VOIDmode, tl, th, 0);
1608           if (REAL_VALUES_LESS (t, x))
1609             {
1610               xh = th;
1611               xl = tl;
1612               break;
1613             }
1614
1615           /* Test against the signed lower bound.  */
1616           if (width > HOST_BITS_PER_WIDE_INT)
1617             {
1618               th = (unsigned HOST_WIDE_INT) (-1)
1619                    << (width - HOST_BITS_PER_WIDE_INT - 1);
1620               tl = 0;
1621             }
1622           else
1623             {
1624               th = -1;
1625               tl = (unsigned HOST_WIDE_INT) (-1) << (width - 1);
1626             }
1627           real_from_integer (&t, VOIDmode, tl, th, 0);
1628           if (REAL_VALUES_LESS (x, t))
1629             {
1630               xh = th;
1631               xl = tl;
1632               break;
1633             }
1634           REAL_VALUE_TO_INT (&xl, &xh, x);
1635           break;
1636
1637         case UNSIGNED_FIX:
1638           if (REAL_VALUE_ISNAN (x) || REAL_VALUE_NEGATIVE (x))
1639             return const0_rtx;
1640
1641           /* Test against the unsigned upper bound.  */
1642           if (width == 2*HOST_BITS_PER_WIDE_INT)
1643             {
1644               th = -1;
1645               tl = -1;
1646             }
1647           else if (width >= HOST_BITS_PER_WIDE_INT)
1648             {
1649               th = ((unsigned HOST_WIDE_INT) 1
1650                     << (width - HOST_BITS_PER_WIDE_INT)) - 1;
1651               tl = -1;
1652             }
1653           else
1654             {
1655               th = 0;
1656               tl = ((unsigned HOST_WIDE_INT) 1 << width) - 1;
1657             }
1658           real_from_integer (&t, VOIDmode, tl, th, 1);
1659           if (REAL_VALUES_LESS (t, x))
1660             {
1661               xh = th;
1662               xl = tl;
1663               break;
1664             }
1665
1666           REAL_VALUE_TO_INT (&xl, &xh, x);
1667           break;
1668
1669         default:
1670           gcc_unreachable ();
1671         }
1672       return immed_double_const (xl, xh, mode);
1673     }
1674
1675   return NULL_RTX;
1676 }
1677 \f
1678 /* Subroutine of simplify_binary_operation to simplify a commutative,
1679    associative binary operation CODE with result mode MODE, operating
1680    on OP0 and OP1.  CODE is currently one of PLUS, MULT, AND, IOR, XOR,
1681    SMIN, SMAX, UMIN or UMAX.  Return zero if no simplification or
1682    canonicalization is possible.  */
1683
1684 static rtx
1685 simplify_associative_operation (enum rtx_code code, enum machine_mode mode,
1686                                 rtx op0, rtx op1)
1687 {
1688   rtx tem;
1689
1690   /* Linearize the operator to the left.  */
1691   if (GET_CODE (op1) == code)
1692     {
1693       /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)".  */
1694       if (GET_CODE (op0) == code)
1695         {
1696           tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
1697           return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
1698         }
1699
1700       /* "a op (b op c)" becomes "(b op c) op a".  */
1701       if (! swap_commutative_operands_p (op1, op0))
1702         return simplify_gen_binary (code, mode, op1, op0);
1703
1704       tem = op0;
1705       op0 = op1;
1706       op1 = tem;
1707     }
1708
1709   if (GET_CODE (op0) == code)
1710     {
1711       /* Canonicalize "(x op c) op y" as "(x op y) op c".  */
1712       if (swap_commutative_operands_p (XEXP (op0, 1), op1))
1713         {
1714           tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
1715           return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
1716         }
1717
1718       /* Attempt to simplify "(a op b) op c" as "a op (b op c)".  */
1719       tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
1720       if (tem != 0)
1721         return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
1722
1723       /* Attempt to simplify "(a op b) op c" as "(a op c) op b".  */
1724       tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
1725       if (tem != 0)
1726         return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
1727     }
1728
1729   return 0;
1730 }
1731
1732
1733 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
1734    and OP1.  Return 0 if no simplification is possible.
1735
1736    Don't use this for relational operations such as EQ or LT.
1737    Use simplify_relational_operation instead.  */
1738 rtx
1739 simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
1740                            rtx op0, rtx op1)
1741 {
1742   rtx trueop0, trueop1;
1743   rtx tem;
1744
1745   /* Relational operations don't work here.  We must know the mode
1746      of the operands in order to do the comparison correctly.
1747      Assuming a full word can give incorrect results.
1748      Consider comparing 128 with -128 in QImode.  */
1749   gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
1750   gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
1751
1752   /* Make sure the constant is second.  */
1753   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
1754       && swap_commutative_operands_p (op0, op1))
1755     {
1756       tem = op0, op0 = op1, op1 = tem;
1757     }
1758
1759   trueop0 = avoid_constant_pool_reference (op0);
1760   trueop1 = avoid_constant_pool_reference (op1);
1761
1762   tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
1763   if (tem)
1764     return tem;
1765   return simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
1766 }
1767
1768 /* Subroutine of simplify_binary_operation.  Simplify a binary operation
1769    CODE with result mode MODE, operating on OP0 and OP1.  If OP0 and/or
1770    OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
1771    actual constants.  */
1772
1773 static rtx
1774 simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
1775                              rtx op0, rtx op1, rtx trueop0, rtx trueop1)
1776 {
1777   rtx tem, reversed, opleft, opright;
1778   HOST_WIDE_INT val;
1779   unsigned int width = GET_MODE_BITSIZE (mode);
1780
1781   /* Even if we can't compute a constant result,
1782      there are some cases worth simplifying.  */
1783
1784   switch (code)
1785     {
1786     case PLUS:
1787       /* Maybe simplify x + 0 to x.  The two expressions are equivalent
1788          when x is NaN, infinite, or finite and nonzero.  They aren't
1789          when x is -0 and the rounding mode is not towards -infinity,
1790          since (-0) + 0 is then 0.  */
1791       if (!HONOR_SIGNED_ZEROS (mode) && trueop1 == CONST0_RTX (mode))
1792         return op0;
1793
1794       /* ((-a) + b) -> (b - a) and similarly for (a + (-b)).  These
1795          transformations are safe even for IEEE.  */
1796       if (GET_CODE (op0) == NEG)
1797         return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
1798       else if (GET_CODE (op1) == NEG)
1799         return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
1800
1801       /* (~a) + 1 -> -a */
1802       if (INTEGRAL_MODE_P (mode)
1803           && GET_CODE (op0) == NOT
1804           && trueop1 == const1_rtx)
1805         return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
1806
1807       /* Handle both-operands-constant cases.  We can only add
1808          CONST_INTs to constants since the sum of relocatable symbols
1809          can't be handled by most assemblers.  Don't add CONST_INT
1810          to CONST_INT since overflow won't be computed properly if wider
1811          than HOST_BITS_PER_WIDE_INT.  */
1812
1813       if ((GET_CODE (op0) == CONST
1814            || GET_CODE (op0) == SYMBOL_REF
1815            || GET_CODE (op0) == LABEL_REF)
1816           && CONST_INT_P (op1))
1817         return plus_constant (op0, INTVAL (op1));
1818       else if ((GET_CODE (op1) == CONST
1819                 || GET_CODE (op1) == SYMBOL_REF
1820                 || GET_CODE (op1) == LABEL_REF)
1821                && CONST_INT_P (op0))
1822         return plus_constant (op1, INTVAL (op0));
1823
1824       /* See if this is something like X * C - X or vice versa or
1825          if the multiplication is written as a shift.  If so, we can
1826          distribute and make a new multiply, shift, or maybe just
1827          have X (if C is 2 in the example above).  But don't make
1828          something more expensive than we had before.  */
1829
1830       if (SCALAR_INT_MODE_P (mode))
1831         {
1832           double_int coeff0, coeff1;
1833           rtx lhs = op0, rhs = op1;
1834
1835           coeff0 = double_int_one;
1836           coeff1 = double_int_one;
1837
1838           if (GET_CODE (lhs) == NEG)
1839             {
1840               coeff0 = double_int_minus_one;
1841               lhs = XEXP (lhs, 0);
1842             }
1843           else if (GET_CODE (lhs) == MULT
1844                    && CONST_INT_P (XEXP (lhs, 1)))
1845             {
1846               coeff0 = shwi_to_double_int (INTVAL (XEXP (lhs, 1)));
1847               lhs = XEXP (lhs, 0);
1848             }
1849           else if (GET_CODE (lhs) == ASHIFT
1850                    && CONST_INT_P (XEXP (lhs, 1))
1851                    && INTVAL (XEXP (lhs, 1)) >= 0
1852                    && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
1853             {
1854               coeff0 = double_int_setbit (double_int_zero,
1855                                           INTVAL (XEXP (lhs, 1)));
1856               lhs = XEXP (lhs, 0);
1857             }
1858
1859           if (GET_CODE (rhs) == NEG)
1860             {
1861               coeff1 = double_int_minus_one;
1862               rhs = XEXP (rhs, 0);
1863             }
1864           else if (GET_CODE (rhs) == MULT
1865                    && CONST_INT_P (XEXP (rhs, 1)))
1866             {
1867               coeff1 = shwi_to_double_int (INTVAL (XEXP (rhs, 1)));
1868               rhs = XEXP (rhs, 0);
1869             }
1870           else if (GET_CODE (rhs) == ASHIFT
1871                    && CONST_INT_P (XEXP (rhs, 1))
1872                    && INTVAL (XEXP (rhs, 1)) >= 0
1873                    && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
1874             {
1875               coeff1 = double_int_setbit (double_int_zero,
1876                                           INTVAL (XEXP (rhs, 1)));
1877               rhs = XEXP (rhs, 0);
1878             }
1879
1880           if (rtx_equal_p (lhs, rhs))
1881             {
1882               rtx orig = gen_rtx_PLUS (mode, op0, op1);
1883               rtx coeff;
1884               double_int val;
1885               bool speed = optimize_function_for_speed_p (cfun);
1886
1887               val = double_int_add (coeff0, coeff1);
1888               coeff = immed_double_int_const (val, mode);
1889
1890               tem = simplify_gen_binary (MULT, mode, lhs, coeff);
1891               return rtx_cost (tem, SET, speed) <= rtx_cost (orig, SET, speed)
1892                 ? tem : 0;
1893             }
1894         }
1895
1896       /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit.  */
1897       if ((CONST_INT_P (op1)
1898            || GET_CODE (op1) == CONST_DOUBLE)
1899           && GET_CODE (op0) == XOR
1900           && (CONST_INT_P (XEXP (op0, 1))
1901               || GET_CODE (XEXP (op0, 1)) == CONST_DOUBLE)
1902           && mode_signbit_p (mode, op1))
1903         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
1904                                     simplify_gen_binary (XOR, mode, op1,
1905                                                          XEXP (op0, 1)));
1906
1907       /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)).  */
1908       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
1909           && GET_CODE (op0) == MULT
1910           && GET_CODE (XEXP (op0, 0)) == NEG)
1911         {
1912           rtx in1, in2;
1913
1914           in1 = XEXP (XEXP (op0, 0), 0);
1915           in2 = XEXP (op0, 1);
1916           return simplify_gen_binary (MINUS, mode, op1,
1917                                       simplify_gen_binary (MULT, mode,
1918                                                            in1, in2));
1919         }
1920
1921       /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
1922          C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
1923          is 1.  */
1924       if (COMPARISON_P (op0)
1925           && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
1926               || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
1927           && (reversed = reversed_comparison (op0, mode)))
1928         return
1929           simplify_gen_unary (NEG, mode, reversed, mode);
1930
1931       /* If one of the operands is a PLUS or a MINUS, see if we can
1932          simplify this by the associative law.
1933          Don't use the associative law for floating point.
1934          The inaccuracy makes it nonassociative,
1935          and subtle programs can break if operations are associated.  */
1936
1937       if (INTEGRAL_MODE_P (mode)
1938           && (plus_minus_operand_p (op0)
1939               || plus_minus_operand_p (op1))
1940           && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
1941         return tem;
1942
1943       /* Reassociate floating point addition only when the user
1944          specifies associative math operations.  */
1945       if (FLOAT_MODE_P (mode)
1946           && flag_associative_math)
1947         {
1948           tem = simplify_associative_operation (code, mode, op0, op1);
1949           if (tem)
1950             return tem;
1951         }
1952       break;
1953
1954     case COMPARE:
1955       /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags).  */
1956       if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
1957            || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
1958           && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx)
1959         {
1960           rtx xop00 = XEXP (op0, 0);
1961           rtx xop10 = XEXP (op1, 0);
1962
1963 #ifdef HAVE_cc0
1964           if (GET_CODE (xop00) == CC0 && GET_CODE (xop10) == CC0)
1965 #else
1966             if (REG_P (xop00) && REG_P (xop10)
1967                 && GET_MODE (xop00) == GET_MODE (xop10)
1968                 && REGNO (xop00) == REGNO (xop10)
1969                 && GET_MODE_CLASS (GET_MODE (xop00)) == MODE_CC
1970                 && GET_MODE_CLASS (GET_MODE (xop10)) == MODE_CC)
1971 #endif
1972               return xop00;
1973         }
1974       break;
1975
1976     case MINUS:
1977       /* We can't assume x-x is 0 even with non-IEEE floating point,
1978          but since it is zero except in very strange circumstances, we
1979          will treat it as zero with -ffinite-math-only.  */
1980       if (rtx_equal_p (trueop0, trueop1)
1981           && ! side_effects_p (op0)
1982           && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
1983         return CONST0_RTX (mode);
1984
1985       /* Change subtraction from zero into negation.  (0 - x) is the
1986          same as -x when x is NaN, infinite, or finite and nonzero.
1987          But if the mode has signed zeros, and does not round towards
1988          -infinity, then 0 - 0 is 0, not -0.  */
1989       if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
1990         return simplify_gen_unary (NEG, mode, op1, mode);
1991
1992       /* (-1 - a) is ~a.  */
1993       if (trueop0 == constm1_rtx)
1994         return simplify_gen_unary (NOT, mode, op1, mode);
1995
1996       /* Subtracting 0 has no effect unless the mode has signed zeros
1997          and supports rounding towards -infinity.  In such a case,
1998          0 - 0 is -0.  */
1999       if (!(HONOR_SIGNED_ZEROS (mode)
2000             && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2001           && trueop1 == CONST0_RTX (mode))
2002         return op0;
2003
2004       /* See if this is something like X * C - X or vice versa or
2005          if the multiplication is written as a shift.  If so, we can
2006          distribute and make a new multiply, shift, or maybe just
2007          have X (if C is 2 in the example above).  But don't make
2008          something more expensive than we had before.  */
2009
2010       if (SCALAR_INT_MODE_P (mode))
2011         {
2012           double_int coeff0, negcoeff1;
2013           rtx lhs = op0, rhs = op1;
2014
2015           coeff0 = double_int_one;
2016           negcoeff1 = double_int_minus_one;
2017
2018           if (GET_CODE (lhs) == NEG)
2019             {
2020               coeff0 = double_int_minus_one;
2021               lhs = XEXP (lhs, 0);
2022             }
2023           else if (GET_CODE (lhs) == MULT
2024                    && CONST_INT_P (XEXP (lhs, 1)))
2025             {
2026               coeff0 = shwi_to_double_int (INTVAL (XEXP (lhs, 1)));
2027               lhs = XEXP (lhs, 0);
2028             }
2029           else if (GET_CODE (lhs) == ASHIFT
2030                    && CONST_INT_P (XEXP (lhs, 1))
2031                    && INTVAL (XEXP (lhs, 1)) >= 0
2032                    && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
2033             {
2034               coeff0 = double_int_setbit (double_int_zero,
2035                                           INTVAL (XEXP (lhs, 1)));
2036               lhs = XEXP (lhs, 0);
2037             }
2038
2039           if (GET_CODE (rhs) == NEG)
2040             {
2041               negcoeff1 = double_int_one;
2042               rhs = XEXP (rhs, 0);
2043             }
2044           else if (GET_CODE (rhs) == MULT
2045                    && CONST_INT_P (XEXP (rhs, 1)))
2046             {
2047               negcoeff1 = shwi_to_double_int (-INTVAL (XEXP (rhs, 1)));
2048               rhs = XEXP (rhs, 0);
2049             }
2050           else if (GET_CODE (rhs) == ASHIFT
2051                    && CONST_INT_P (XEXP (rhs, 1))
2052                    && INTVAL (XEXP (rhs, 1)) >= 0
2053                    && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
2054             {
2055               negcoeff1 = double_int_setbit (double_int_zero,
2056                                              INTVAL (XEXP (rhs, 1)));
2057               negcoeff1 = double_int_neg (negcoeff1);
2058               rhs = XEXP (rhs, 0);
2059             }
2060
2061           if (rtx_equal_p (lhs, rhs))
2062             {
2063               rtx orig = gen_rtx_MINUS (mode, op0, op1);
2064               rtx coeff;
2065               double_int val;
2066               bool speed = optimize_function_for_speed_p (cfun);
2067
2068               val = double_int_add (coeff0, negcoeff1);
2069               coeff = immed_double_int_const (val, mode);
2070
2071               tem = simplify_gen_binary (MULT, mode, lhs, coeff);
2072               return rtx_cost (tem, SET, speed) <= rtx_cost (orig, SET, speed)
2073                 ? tem : 0;
2074             }
2075         }
2076
2077       /* (a - (-b)) -> (a + b).  True even for IEEE.  */
2078       if (GET_CODE (op1) == NEG)
2079         return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
2080
2081       /* (-x - c) may be simplified as (-c - x).  */
2082       if (GET_CODE (op0) == NEG
2083           && (CONST_INT_P (op1)
2084               || GET_CODE (op1) == CONST_DOUBLE))
2085         {
2086           tem = simplify_unary_operation (NEG, mode, op1, mode);
2087           if (tem)
2088             return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
2089         }
2090
2091       /* Don't let a relocatable value get a negative coeff.  */
2092       if (CONST_INT_P (op1) && GET_MODE (op0) != VOIDmode)
2093         return simplify_gen_binary (PLUS, mode,
2094                                     op0,
2095                                     neg_const_int (mode, op1));
2096
2097       /* (x - (x & y)) -> (x & ~y) */
2098       if (GET_CODE (op1) == AND)
2099         {
2100           if (rtx_equal_p (op0, XEXP (op1, 0)))
2101             {
2102               tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
2103                                         GET_MODE (XEXP (op1, 1)));
2104               return simplify_gen_binary (AND, mode, op0, tem);
2105             }
2106           if (rtx_equal_p (op0, XEXP (op1, 1)))
2107             {
2108               tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
2109                                         GET_MODE (XEXP (op1, 0)));
2110               return simplify_gen_binary (AND, mode, op0, tem);
2111             }
2112         }
2113
2114       /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
2115          by reversing the comparison code if valid.  */
2116       if (STORE_FLAG_VALUE == 1
2117           && trueop0 == const1_rtx
2118           && COMPARISON_P (op1)
2119           && (reversed = reversed_comparison (op1, mode)))
2120         return reversed;
2121
2122       /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A).  */
2123       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2124           && GET_CODE (op1) == MULT
2125           && GET_CODE (XEXP (op1, 0)) == NEG)
2126         {
2127           rtx in1, in2;
2128
2129           in1 = XEXP (XEXP (op1, 0), 0);
2130           in2 = XEXP (op1, 1);
2131           return simplify_gen_binary (PLUS, mode,
2132                                       simplify_gen_binary (MULT, mode,
2133                                                            in1, in2),
2134                                       op0);
2135         }
2136
2137       /* Canonicalize (minus (neg A) (mult B C)) to
2138          (minus (mult (neg B) C) A).  */
2139       if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2140           && GET_CODE (op1) == MULT
2141           && GET_CODE (op0) == NEG)
2142         {
2143           rtx in1, in2;
2144
2145           in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
2146           in2 = XEXP (op1, 1);
2147           return simplify_gen_binary (MINUS, mode,
2148                                       simplify_gen_binary (MULT, mode,
2149                                                            in1, in2),
2150                                       XEXP (op0, 0));
2151         }
2152
2153       /* If one of the operands is a PLUS or a MINUS, see if we can
2154          simplify this by the associative law.  This will, for example,
2155          canonicalize (minus A (plus B C)) to (minus (minus A B) C).
2156          Don't use the associative law for floating point.
2157          The inaccuracy makes it nonassociative,
2158          and subtle programs can break if operations are associated.  */
2159
2160       if (INTEGRAL_MODE_P (mode)
2161           && (plus_minus_operand_p (op0)
2162               || plus_minus_operand_p (op1))
2163           && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
2164         return tem;
2165       break;
2166
2167     case MULT:
2168       if (trueop1 == constm1_rtx)
2169         return simplify_gen_unary (NEG, mode, op0, mode);
2170
2171       if (GET_CODE (op0) == NEG)
2172         {
2173           rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
2174           if (temp)
2175             return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
2176         }
2177       if (GET_CODE (op1) == NEG)
2178         {
2179           rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
2180           if (temp)
2181             return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
2182         }
2183
2184       /* Maybe simplify x * 0 to 0.  The reduction is not valid if
2185          x is NaN, since x * 0 is then also NaN.  Nor is it valid
2186          when the mode has signed zeros, since multiplying a negative
2187          number by 0 will give -0, not 0.  */
2188       if (!HONOR_NANS (mode)
2189           && !HONOR_SIGNED_ZEROS (mode)
2190           && trueop1 == CONST0_RTX (mode)
2191           && ! side_effects_p (op0))
2192         return op1;
2193
2194       /* In IEEE floating point, x*1 is not equivalent to x for
2195          signalling NaNs.  */
2196       if (!HONOR_SNANS (mode)
2197           && trueop1 == CONST1_RTX (mode))
2198         return op0;
2199
2200       /* Convert multiply by constant power of two into shift unless
2201          we are still generating RTL.  This test is a kludge.  */
2202       if (CONST_INT_P (trueop1)
2203           && (val = exact_log2 (UINTVAL (trueop1))) >= 0
2204           /* If the mode is larger than the host word size, and the
2205              uppermost bit is set, then this isn't a power of two due
2206              to implicit sign extension.  */
2207           && (width <= HOST_BITS_PER_WIDE_INT
2208               || val != HOST_BITS_PER_WIDE_INT - 1))
2209         return simplify_gen_binary (ASHIFT, mode, op0, GEN_INT (val));
2210
2211       /* Likewise for multipliers wider than a word.  */
2212       if (GET_CODE (trueop1) == CONST_DOUBLE
2213           && (GET_MODE (trueop1) == VOIDmode
2214               || GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_INT)
2215           && GET_MODE (op0) == mode
2216           && CONST_DOUBLE_LOW (trueop1) == 0
2217           && (val = exact_log2 (CONST_DOUBLE_HIGH (trueop1))) >= 0)
2218         return simplify_gen_binary (ASHIFT, mode, op0,
2219                                     GEN_INT (val + HOST_BITS_PER_WIDE_INT));
2220
2221       /* x*2 is x+x and x*(-1) is -x */
2222       if (GET_CODE (trueop1) == CONST_DOUBLE
2223           && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
2224           && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
2225           && GET_MODE (op0) == mode)
2226         {
2227           REAL_VALUE_TYPE d;
2228           REAL_VALUE_FROM_CONST_DOUBLE (d, trueop1);
2229
2230           if (REAL_VALUES_EQUAL (d, dconst2))
2231             return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
2232
2233           if (!HONOR_SNANS (mode)
2234               && REAL_VALUES_EQUAL (d, dconstm1))
2235             return simplify_gen_unary (NEG, mode, op0, mode);
2236         }
2237
2238       /* Optimize -x * -x as x * x.  */
2239       if (FLOAT_MODE_P (mode)
2240           && GET_CODE (op0) == NEG
2241           && GET_CODE (op1) == NEG
2242           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2243           && !side_effects_p (XEXP (op0, 0)))
2244         return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
2245
2246       /* Likewise, optimize abs(x) * abs(x) as x * x.  */
2247       if (SCALAR_FLOAT_MODE_P (mode)
2248           && GET_CODE (op0) == ABS
2249           && GET_CODE (op1) == ABS
2250           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2251           && !side_effects_p (XEXP (op0, 0)))
2252         return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
2253
2254       /* Reassociate multiplication, but for floating point MULTs
2255          only when the user specifies unsafe math optimizations.  */
2256       if (! FLOAT_MODE_P (mode)
2257           || flag_unsafe_math_optimizations)
2258         {
2259           tem = simplify_associative_operation (code, mode, op0, op1);
2260           if (tem)
2261             return tem;
2262         }
2263       break;
2264
2265     case IOR:
2266       if (trueop1 == CONST0_RTX (mode))
2267         return op0;
2268       if (CONST_INT_P (trueop1)
2269           && ((UINTVAL (trueop1) & GET_MODE_MASK (mode))
2270               == GET_MODE_MASK (mode)))
2271         return op1;
2272       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2273         return op0;
2274       /* A | (~A) -> -1 */
2275       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
2276            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
2277           && ! side_effects_p (op0)
2278           && SCALAR_INT_MODE_P (mode))
2279         return constm1_rtx;
2280
2281       /* (ior A C) is C if all bits of A that might be nonzero are on in C.  */
2282       if (CONST_INT_P (op1)
2283           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2284           && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0)
2285         return op1;
2286
2287       /* Canonicalize (X & C1) | C2.  */
2288       if (GET_CODE (op0) == AND
2289           && CONST_INT_P (trueop1)
2290           && CONST_INT_P (XEXP (op0, 1)))
2291         {
2292           HOST_WIDE_INT mask = GET_MODE_MASK (mode);
2293           HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
2294           HOST_WIDE_INT c2 = INTVAL (trueop1);
2295
2296           /* If (C1&C2) == C1, then (X&C1)|C2 becomes X.  */
2297           if ((c1 & c2) == c1
2298               && !side_effects_p (XEXP (op0, 0)))
2299             return trueop1;
2300
2301           /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2.  */
2302           if (((c1|c2) & mask) == mask)
2303             return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
2304
2305           /* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2.  */
2306           if (((c1 & ~c2) & mask) != (c1 & mask))
2307             {
2308               tem = simplify_gen_binary (AND, mode, XEXP (op0, 0),
2309                                          gen_int_mode (c1 & ~c2, mode));
2310               return simplify_gen_binary (IOR, mode, tem, op1);
2311             }
2312         }
2313
2314       /* Convert (A & B) | A to A.  */
2315       if (GET_CODE (op0) == AND
2316           && (rtx_equal_p (XEXP (op0, 0), op1)
2317               || rtx_equal_p (XEXP (op0, 1), op1))
2318           && ! side_effects_p (XEXP (op0, 0))
2319           && ! side_effects_p (XEXP (op0, 1)))
2320         return op1;
2321
2322       /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
2323          mode size to (rotate A CX).  */
2324
2325       if (GET_CODE (op1) == ASHIFT
2326           || GET_CODE (op1) == SUBREG)
2327         {
2328           opleft = op1;
2329           opright = op0;
2330         }
2331       else
2332         {
2333           opright = op1;
2334           opleft = op0;
2335         }
2336
2337       if (GET_CODE (opleft) == ASHIFT && GET_CODE (opright) == LSHIFTRT
2338           && rtx_equal_p (XEXP (opleft, 0), XEXP (opright, 0))
2339           && CONST_INT_P (XEXP (opleft, 1))
2340           && CONST_INT_P (XEXP (opright, 1))
2341           && (INTVAL (XEXP (opleft, 1)) + INTVAL (XEXP (opright, 1))
2342               == GET_MODE_BITSIZE (mode)))
2343         return gen_rtx_ROTATE (mode, XEXP (opright, 0), XEXP (opleft, 1));
2344
2345       /* Same, but for ashift that has been "simplified" to a wider mode
2346         by simplify_shift_const.  */
2347
2348       if (GET_CODE (opleft) == SUBREG
2349           && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
2350           && GET_CODE (opright) == LSHIFTRT
2351           && GET_CODE (XEXP (opright, 0)) == SUBREG
2352           && GET_MODE (opleft) == GET_MODE (XEXP (opright, 0))
2353           && SUBREG_BYTE (opleft) == SUBREG_BYTE (XEXP (opright, 0))
2354           && (GET_MODE_SIZE (GET_MODE (opleft))
2355               < GET_MODE_SIZE (GET_MODE (SUBREG_REG (opleft))))
2356           && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
2357                           SUBREG_REG (XEXP (opright, 0)))
2358           && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
2359           && CONST_INT_P (XEXP (opright, 1))
2360           && (INTVAL (XEXP (SUBREG_REG (opleft), 1)) + INTVAL (XEXP (opright, 1))
2361               == GET_MODE_BITSIZE (mode)))
2362         return gen_rtx_ROTATE (mode, XEXP (opright, 0),
2363                                XEXP (SUBREG_REG (opleft), 1));
2364
2365       /* If we have (ior (and (X C1) C2)), simplify this by making
2366          C1 as small as possible if C1 actually changes.  */
2367       if (CONST_INT_P (op1)
2368           && (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2369               || INTVAL (op1) > 0)
2370           && GET_CODE (op0) == AND
2371           && CONST_INT_P (XEXP (op0, 1))
2372           && CONST_INT_P (op1)
2373           && (UINTVAL (XEXP (op0, 1)) & UINTVAL (op1)) != 0)
2374         return simplify_gen_binary (IOR, mode,
2375                                     simplify_gen_binary
2376                                           (AND, mode, XEXP (op0, 0),
2377                                            GEN_INT (UINTVAL (XEXP (op0, 1))
2378                                                     & ~UINTVAL (op1))),
2379                                     op1);
2380
2381       /* If OP0 is (ashiftrt (plus ...) C), it might actually be
2382          a (sign_extend (plus ...)).  Then check if OP1 is a CONST_INT and
2383          the PLUS does not affect any of the bits in OP1: then we can do
2384          the IOR as a PLUS and we can associate.  This is valid if OP1
2385          can be safely shifted left C bits.  */
2386       if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
2387           && GET_CODE (XEXP (op0, 0)) == PLUS
2388           && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
2389           && CONST_INT_P (XEXP (op0, 1))
2390           && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
2391         {
2392           int count = INTVAL (XEXP (op0, 1));
2393           HOST_WIDE_INT mask = INTVAL (trueop1) << count;
2394
2395           if (mask >> count == INTVAL (trueop1)
2396               && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
2397             return simplify_gen_binary (ASHIFTRT, mode,
2398                                         plus_constant (XEXP (op0, 0), mask),
2399                                         XEXP (op0, 1));
2400         }
2401
2402       tem = simplify_associative_operation (code, mode, op0, op1);
2403       if (tem)
2404         return tem;
2405       break;
2406
2407     case XOR:
2408       if (trueop1 == CONST0_RTX (mode))
2409         return op0;
2410       if (CONST_INT_P (trueop1)
2411           && ((UINTVAL (trueop1) & GET_MODE_MASK (mode))
2412               == GET_MODE_MASK (mode)))
2413         return simplify_gen_unary (NOT, mode, op0, mode);
2414       if (rtx_equal_p (trueop0, trueop1)
2415           && ! side_effects_p (op0)
2416           && GET_MODE_CLASS (mode) != MODE_CC)
2417          return CONST0_RTX (mode);
2418
2419       /* Canonicalize XOR of the most significant bit to PLUS.  */
2420       if ((CONST_INT_P (op1)
2421            || GET_CODE (op1) == CONST_DOUBLE)
2422           && mode_signbit_p (mode, op1))
2423         return simplify_gen_binary (PLUS, mode, op0, op1);
2424       /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit.  */
2425       if ((CONST_INT_P (op1)
2426            || GET_CODE (op1) == CONST_DOUBLE)
2427           && GET_CODE (op0) == PLUS
2428           && (CONST_INT_P (XEXP (op0, 1))
2429               || GET_CODE (XEXP (op0, 1)) == CONST_DOUBLE)
2430           && mode_signbit_p (mode, XEXP (op0, 1)))
2431         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
2432                                     simplify_gen_binary (XOR, mode, op1,
2433                                                          XEXP (op0, 1)));
2434
2435       /* If we are XORing two things that have no bits in common,
2436          convert them into an IOR.  This helps to detect rotation encoded
2437          using those methods and possibly other simplifications.  */
2438
2439       if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2440           && (nonzero_bits (op0, mode)
2441               & nonzero_bits (op1, mode)) == 0)
2442         return (simplify_gen_binary (IOR, mode, op0, op1));
2443
2444       /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
2445          Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
2446          (NOT y).  */
2447       {
2448         int num_negated = 0;
2449
2450         if (GET_CODE (op0) == NOT)
2451           num_negated++, op0 = XEXP (op0, 0);
2452         if (GET_CODE (op1) == NOT)
2453           num_negated++, op1 = XEXP (op1, 0);
2454
2455         if (num_negated == 2)
2456           return simplify_gen_binary (XOR, mode, op0, op1);
2457         else if (num_negated == 1)
2458           return simplify_gen_unary (NOT, mode,
2459                                      simplify_gen_binary (XOR, mode, op0, op1),
2460                                      mode);
2461       }
2462
2463       /* Convert (xor (and A B) B) to (and (not A) B).  The latter may
2464          correspond to a machine insn or result in further simplifications
2465          if B is a constant.  */
2466
2467       if (GET_CODE (op0) == AND
2468           && rtx_equal_p (XEXP (op0, 1), op1)
2469           && ! side_effects_p (op1))
2470         return simplify_gen_binary (AND, mode,
2471                                     simplify_gen_unary (NOT, mode,
2472                                                         XEXP (op0, 0), mode),
2473                                     op1);
2474
2475       else if (GET_CODE (op0) == AND
2476                && rtx_equal_p (XEXP (op0, 0), op1)
2477                && ! side_effects_p (op1))
2478         return simplify_gen_binary (AND, mode,
2479                                     simplify_gen_unary (NOT, mode,
2480                                                         XEXP (op0, 1), mode),
2481                                     op1);
2482
2483       /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
2484          we can transform like this:
2485             (A&B)^C == ~(A&B)&C | ~C&(A&B)
2486                     == (~A|~B)&C | ~C&(A&B)    * DeMorgan's Law
2487                     == ~A&C | ~B&C | A&(~C&B)  * Distribute and re-order
2488          Attempt a few simplifications when B and C are both constants.  */
2489       if (GET_CODE (op0) == AND
2490           && CONST_INT_P (op1)
2491           && CONST_INT_P (XEXP (op0, 1)))
2492         {
2493           rtx a = XEXP (op0, 0);
2494           rtx b = XEXP (op0, 1);
2495           rtx c = op1;
2496           HOST_WIDE_INT bval = INTVAL (b);
2497           HOST_WIDE_INT cval = INTVAL (c);
2498
2499           rtx na_c
2500             = simplify_binary_operation (AND, mode,
2501                                          simplify_gen_unary (NOT, mode, a, mode),
2502                                          c);
2503           if ((~cval & bval) == 0)
2504             {
2505               /* Try to simplify ~A&C | ~B&C.  */
2506               if (na_c != NULL_RTX)
2507                 return simplify_gen_binary (IOR, mode, na_c,
2508                                             GEN_INT (~bval & cval));
2509             }
2510           else
2511             {
2512               /* If ~A&C is zero, simplify A&(~C&B) | ~B&C.  */
2513               if (na_c == const0_rtx)
2514                 {
2515                   rtx a_nc_b = simplify_gen_binary (AND, mode, a,
2516                                                     GEN_INT (~cval & bval));
2517                   return simplify_gen_binary (IOR, mode, a_nc_b,
2518                                               GEN_INT (~bval & cval));
2519                 }
2520             }
2521         }
2522
2523       /* (xor (comparison foo bar) (const_int 1)) can become the reversed
2524          comparison if STORE_FLAG_VALUE is 1.  */
2525       if (STORE_FLAG_VALUE == 1
2526           && trueop1 == const1_rtx
2527           && COMPARISON_P (op0)
2528           && (reversed = reversed_comparison (op0, mode)))
2529         return reversed;
2530
2531       /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
2532          is (lt foo (const_int 0)), so we can perform the above
2533          simplification if STORE_FLAG_VALUE is 1.  */
2534
2535       if (STORE_FLAG_VALUE == 1
2536           && trueop1 == const1_rtx
2537           && GET_CODE (op0) == LSHIFTRT
2538           && CONST_INT_P (XEXP (op0, 1))
2539           && INTVAL (XEXP (op0, 1)) == GET_MODE_BITSIZE (mode) - 1)
2540         return gen_rtx_GE (mode, XEXP (op0, 0), const0_rtx);
2541
2542       /* (xor (comparison foo bar) (const_int sign-bit))
2543          when STORE_FLAG_VALUE is the sign bit.  */
2544       if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2545           && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
2546               == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
2547           && trueop1 == const_true_rtx
2548           && COMPARISON_P (op0)
2549           && (reversed = reversed_comparison (op0, mode)))
2550         return reversed;
2551
2552       tem = simplify_associative_operation (code, mode, op0, op1);
2553       if (tem)
2554         return tem;
2555       break;
2556
2557     case AND:
2558       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
2559         return trueop1;
2560       if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
2561         {
2562           HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
2563           HOST_WIDE_INT nzop1;
2564           if (CONST_INT_P (trueop1))
2565             {
2566               HOST_WIDE_INT val1 = INTVAL (trueop1);
2567               /* If we are turning off bits already known off in OP0, we need
2568                  not do an AND.  */
2569               if ((nzop0 & ~val1) == 0)
2570                 return op0;
2571             }
2572           nzop1 = nonzero_bits (trueop1, mode);
2573           /* If we are clearing all the nonzero bits, the result is zero.  */
2574           if ((nzop1 & nzop0) == 0
2575               && !side_effects_p (op0) && !side_effects_p (op1))
2576             return CONST0_RTX (mode);
2577         }
2578       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
2579           && GET_MODE_CLASS (mode) != MODE_CC)
2580         return op0;
2581       /* A & (~A) -> 0 */
2582       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
2583            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
2584           && ! side_effects_p (op0)
2585           && GET_MODE_CLASS (mode) != MODE_CC)
2586         return CONST0_RTX (mode);
2587
2588       /* Transform (and (extend X) C) into (zero_extend (and X C)) if
2589          there are no nonzero bits of C outside of X's mode.  */
2590       if ((GET_CODE (op0) == SIGN_EXTEND
2591            || GET_CODE (op0) == ZERO_EXTEND)
2592           && CONST_INT_P (trueop1)
2593           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2594           && (~GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))
2595               & UINTVAL (trueop1)) == 0)
2596         {
2597           enum machine_mode imode = GET_MODE (XEXP (op0, 0));
2598           tem = simplify_gen_binary (AND, imode, XEXP (op0, 0),
2599                                      gen_int_mode (INTVAL (trueop1),
2600                                                    imode));
2601           return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
2602         }
2603
2604       /* Transform (and (truncate X) C) into (truncate (and X C)).  This way
2605          we might be able to further simplify the AND with X and potentially
2606          remove the truncation altogether.  */
2607       if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
2608         {
2609           rtx x = XEXP (op0, 0);
2610           enum machine_mode xmode = GET_MODE (x);
2611           tem = simplify_gen_binary (AND, xmode, x,
2612                                      gen_int_mode (INTVAL (trueop1), xmode));
2613           return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
2614         }
2615
2616       /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2).  */
2617       if (GET_CODE (op0) == IOR
2618           && CONST_INT_P (trueop1)
2619           && CONST_INT_P (XEXP (op0, 1)))
2620         {
2621           HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
2622           return simplify_gen_binary (IOR, mode,
2623                                       simplify_gen_binary (AND, mode,
2624                                                            XEXP (op0, 0), op1),
2625                                       gen_int_mode (tmp, mode));
2626         }
2627
2628       /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
2629          insn (and may simplify more).  */
2630       if (GET_CODE (op0) == XOR
2631           && rtx_equal_p (XEXP (op0, 0), op1)
2632           && ! side_effects_p (op1))
2633         return simplify_gen_binary (AND, mode,
2634                                     simplify_gen_unary (NOT, mode,
2635                                                         XEXP (op0, 1), mode),
2636                                     op1);
2637
2638       if (GET_CODE (op0) == XOR
2639           && rtx_equal_p (XEXP (op0, 1), op1)
2640           && ! side_effects_p (op1))
2641         return simplify_gen_binary (AND, mode,
2642                                     simplify_gen_unary (NOT, mode,
2643                                                         XEXP (op0, 0), mode),
2644                                     op1);
2645
2646       /* Similarly for (~(A ^ B)) & A.  */
2647       if (GET_CODE (op0) == NOT
2648           && GET_CODE (XEXP (op0, 0)) == XOR
2649           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
2650           && ! side_effects_p (op1))
2651         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
2652
2653       if (GET_CODE (op0) == NOT
2654           && GET_CODE (XEXP (op0, 0)) == XOR
2655           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
2656           && ! side_effects_p (op1))
2657         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
2658
2659       /* Convert (A | B) & A to A.  */
2660       if (GET_CODE (op0) == IOR
2661           && (rtx_equal_p (XEXP (op0, 0), op1)
2662               || rtx_equal_p (XEXP (op0, 1), op1))
2663           && ! side_effects_p (XEXP (op0, 0))
2664           && ! side_effects_p (XEXP (op0, 1)))
2665         return op1;
2666
2667       /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
2668          ((A & N) + B) & M -> (A + B) & M
2669          Similarly if (N & M) == 0,
2670          ((A | N) + B) & M -> (A + B) & M
2671          and for - instead of + and/or ^ instead of |.
2672          Also, if (N & M) == 0, then
2673          (A +- N) & M -> A & M.  */
2674       if (CONST_INT_P (trueop1)
2675           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2676           && ~UINTVAL (trueop1)
2677           && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
2678           && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
2679         {
2680           rtx pmop[2];
2681           int which;
2682
2683           pmop[0] = XEXP (op0, 0);
2684           pmop[1] = XEXP (op0, 1);
2685
2686           if (CONST_INT_P (pmop[1])
2687               && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
2688             return simplify_gen_binary (AND, mode, pmop[0], op1);
2689
2690           for (which = 0; which < 2; which++)
2691             {
2692               tem = pmop[which];
2693               switch (GET_CODE (tem))
2694                 {
2695                 case AND:
2696                   if (CONST_INT_P (XEXP (tem, 1))
2697                       && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
2698                       == UINTVAL (trueop1))
2699                     pmop[which] = XEXP (tem, 0);
2700                   break;
2701                 case IOR:
2702                 case XOR:
2703                   if (CONST_INT_P (XEXP (tem, 1))
2704                       && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
2705                     pmop[which] = XEXP (tem, 0);
2706                   break;
2707                 default:
2708                   break;
2709                 }
2710             }
2711
2712           if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
2713             {
2714               tem = simplify_gen_binary (GET_CODE (op0), mode,
2715                                          pmop[0], pmop[1]);
2716               return simplify_gen_binary (code, mode, tem, op1);
2717             }
2718         }
2719
2720       /* (and X (ior (not X) Y) -> (and X Y) */
2721       if (GET_CODE (op1) == IOR
2722           && GET_CODE (XEXP (op1, 0)) == NOT
2723           && op0 == XEXP (XEXP (op1, 0), 0))
2724        return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
2725
2726       /* (and (ior (not X) Y) X) -> (and X Y) */
2727       if (GET_CODE (op0) == IOR
2728           && GET_CODE (XEXP (op0, 0)) == NOT
2729           && op1 == XEXP (XEXP (op0, 0), 0))
2730         return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
2731
2732       tem = simplify_associative_operation (code, mode, op0, op1);
2733       if (tem)
2734         return tem;
2735       break;
2736
2737     case UDIV:
2738       /* 0/x is 0 (or x&0 if x has side-effects).  */
2739       if (trueop0 == CONST0_RTX (mode))
2740         {
2741           if (side_effects_p (op1))
2742             return simplify_gen_binary (AND, mode, op1, trueop0);
2743           return trueop0;
2744         }
2745       /* x/1 is x.  */
2746       if (trueop1 == CONST1_RTX (mode))
2747         return rtl_hooks.gen_lowpart_no_emit (mode, op0);
2748       /* Convert divide by power of two into shift.  */
2749       if (CONST_INT_P (trueop1)
2750           && (val = exact_log2 (UINTVAL (trueop1))) > 0)
2751         return simplify_gen_binary (LSHIFTRT, mode, op0, GEN_INT (val));
2752       break;
2753
2754     case DIV:
2755       /* Handle floating point and integers separately.  */
2756       if (SCALAR_FLOAT_MODE_P (mode))
2757         {
2758           /* Maybe change 0.0 / x to 0.0.  This transformation isn't
2759              safe for modes with NaNs, since 0.0 / 0.0 will then be
2760              NaN rather than 0.0.  Nor is it safe for modes with signed
2761              zeros, since dividing 0 by a negative number gives -0.0  */
2762           if (trueop0 == CONST0_RTX (mode)
2763               && !HONOR_NANS (mode)
2764               && !HONOR_SIGNED_ZEROS (mode)
2765               && ! side_effects_p (op1))
2766             return op0;
2767           /* x/1.0 is x.  */
2768           if (trueop1 == CONST1_RTX (mode)
2769               && !HONOR_SNANS (mode))
2770             return op0;
2771
2772           if (GET_CODE (trueop1) == CONST_DOUBLE
2773               && trueop1 != CONST0_RTX (mode))
2774             {
2775               REAL_VALUE_TYPE d;
2776               REAL_VALUE_FROM_CONST_DOUBLE (d, trueop1);
2777
2778               /* x/-1.0 is -x.  */
2779               if (REAL_VALUES_EQUAL (d, dconstm1)
2780                   && !HONOR_SNANS (mode))
2781                 return simplify_gen_unary (NEG, mode, op0, mode);
2782
2783               /* Change FP division by a constant into multiplication.
2784                  Only do this with -freciprocal-math.  */
2785               if (flag_reciprocal_math
2786                   && !REAL_VALUES_EQUAL (d, dconst0))
2787                 {
2788                   REAL_ARITHMETIC (d, RDIV_EXPR, dconst1, d);
2789                   tem = CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
2790                   return simplify_gen_binary (MULT, mode, op0, tem);
2791                 }
2792             }
2793         }
2794       else
2795         {
2796           /* 0/x is 0 (or x&0 if x has side-effects).  */
2797           if (trueop0 == CONST0_RTX (mode)
2798               && !cfun->can_throw_non_call_exceptions)
2799             {
2800               if (side_effects_p (op1))
2801                 return simplify_gen_binary (AND, mode, op1, trueop0);
2802               return trueop0;
2803             }
2804           /* x/1 is x.  */
2805           if (trueop1 == CONST1_RTX (mode))
2806             return rtl_hooks.gen_lowpart_no_emit (mode, op0);
2807           /* x/-1 is -x.  */
2808           if (trueop1 == constm1_rtx)
2809             {
2810               rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
2811               return simplify_gen_unary (NEG, mode, x, mode);
2812             }
2813         }
2814       break;
2815
2816     case UMOD:
2817       /* 0%x is 0 (or x&0 if x has side-effects).  */
2818       if (trueop0 == CONST0_RTX (mode))
2819         {
2820           if (side_effects_p (op1))
2821             return simplify_gen_binary (AND, mode, op1, trueop0);
2822           return trueop0;
2823         }
2824       /* x%1 is 0 (of x&0 if x has side-effects).  */
2825       if (trueop1 == CONST1_RTX (mode))
2826         {
2827           if (side_effects_p (op0))
2828             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
2829           return CONST0_RTX (mode);
2830         }
2831       /* Implement modulus by power of two as AND.  */
2832       if (CONST_INT_P (trueop1)
2833           && exact_log2 (UINTVAL (trueop1)) > 0)
2834         return simplify_gen_binary (AND, mode, op0,
2835                                     GEN_INT (INTVAL (op1) - 1));
2836       break;
2837
2838     case MOD:
2839       /* 0%x is 0 (or x&0 if x has side-effects).  */
2840       if (trueop0 == CONST0_RTX (mode))
2841         {
2842           if (side_effects_p (op1))
2843             return simplify_gen_binary (AND, mode, op1, trueop0);
2844           return trueop0;
2845         }
2846       /* x%1 and x%-1 is 0 (or x&0 if x has side-effects).  */
2847       if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
2848         {
2849           if (side_effects_p (op0))
2850             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
2851           return CONST0_RTX (mode);
2852         }
2853       break;
2854
2855     case ROTATERT:
2856     case ROTATE:
2857     case ASHIFTRT:
2858       if (trueop1 == CONST0_RTX (mode))
2859         return op0;
2860       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
2861         return op0;
2862       /* Rotating ~0 always results in ~0.  */
2863       if (CONST_INT_P (trueop0) && width <= HOST_BITS_PER_WIDE_INT
2864           && UINTVAL (trueop0) == GET_MODE_MASK (mode)
2865           && ! side_effects_p (op1))
2866         return op0;
2867     canonicalize_shift:
2868       if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
2869         {
2870           val = INTVAL (op1) & (GET_MODE_BITSIZE (mode) - 1);
2871           if (val != INTVAL (op1))
2872             return simplify_gen_binary (code, mode, op0, GEN_INT (val));
2873         }
2874       break;
2875
2876     case ASHIFT:
2877     case SS_ASHIFT:
2878     case US_ASHIFT:
2879       if (trueop1 == CONST0_RTX (mode))
2880         return op0;
2881       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
2882         return op0;
2883       goto canonicalize_shift;
2884
2885     case LSHIFTRT:
2886       if (trueop1 == CONST0_RTX (mode))
2887         return op0;
2888       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
2889         return op0;
2890       /* Optimize (lshiftrt (clz X) C) as (eq X 0).  */
2891       if (GET_CODE (op0) == CLZ
2892           && CONST_INT_P (trueop1)
2893           && STORE_FLAG_VALUE == 1
2894           && INTVAL (trueop1) < (HOST_WIDE_INT)width)
2895         {
2896           enum machine_mode imode = GET_MODE (XEXP (op0, 0));
2897           unsigned HOST_WIDE_INT zero_val = 0;
2898
2899           if (CLZ_DEFINED_VALUE_AT_ZERO (imode, zero_val)
2900               && zero_val == GET_MODE_BITSIZE (imode)
2901               && INTVAL (trueop1) == exact_log2 (zero_val))
2902             return simplify_gen_relational (EQ, mode, imode,
2903                                             XEXP (op0, 0), const0_rtx);
2904         }
2905       goto canonicalize_shift;
2906
2907     case SMIN:
2908       if (width <= HOST_BITS_PER_WIDE_INT
2909           && CONST_INT_P (trueop1)
2910           && UINTVAL (trueop1) == (unsigned HOST_WIDE_INT) 1 << (width -1)
2911           && ! side_effects_p (op0))
2912         return op1;
2913       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2914         return op0;
2915       tem = simplify_associative_operation (code, mode, op0, op1);
2916       if (tem)
2917         return tem;
2918       break;
2919
2920     case SMAX:
2921       if (width <= HOST_BITS_PER_WIDE_INT
2922           && CONST_INT_P (trueop1)
2923           && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
2924           && ! side_effects_p (op0))
2925         return op1;
2926       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2927         return op0;
2928       tem = simplify_associative_operation (code, mode, op0, op1);
2929       if (tem)
2930         return tem;
2931       break;
2932
2933     case UMIN:
2934       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
2935         return op1;
2936       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2937         return op0;
2938       tem = simplify_associative_operation (code, mode, op0, op1);
2939       if (tem)
2940         return tem;
2941       break;
2942
2943     case UMAX:
2944       if (trueop1 == constm1_rtx && ! side_effects_p (op0))
2945         return op1;
2946       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2947         return op0;
2948       tem = simplify_associative_operation (code, mode, op0, op1);
2949       if (tem)
2950         return tem;
2951       break;
2952
2953     case SS_PLUS:
2954     case US_PLUS:
2955     case SS_MINUS:
2956     case US_MINUS:
2957     case SS_MULT:
2958     case US_MULT:
2959     case SS_DIV:
2960     case US_DIV:
2961       /* ??? There are simplifications that can be done.  */
2962       return 0;
2963
2964     case VEC_SELECT:
2965       if (!VECTOR_MODE_P (mode))
2966         {
2967           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
2968           gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
2969           gcc_assert (GET_CODE (trueop1) == PARALLEL);
2970           gcc_assert (XVECLEN (trueop1, 0) == 1);
2971           gcc_assert (CONST_INT_P (XVECEXP (trueop1, 0, 0)));
2972
2973           if (GET_CODE (trueop0) == CONST_VECTOR)
2974             return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
2975                                                       (trueop1, 0, 0)));
2976
2977           /* Extract a scalar element from a nested VEC_SELECT expression
2978              (with optional nested VEC_CONCAT expression).  Some targets
2979              (i386) extract scalar element from a vector using chain of
2980              nested VEC_SELECT expressions.  When input operand is a memory
2981              operand, this operation can be simplified to a simple scalar
2982              load from an offseted memory address.  */
2983           if (GET_CODE (trueop0) == VEC_SELECT)
2984             {
2985               rtx op0 = XEXP (trueop0, 0);
2986               rtx op1 = XEXP (trueop0, 1);
2987
2988               enum machine_mode opmode = GET_MODE (op0);
2989               int elt_size = GET_MODE_SIZE (GET_MODE_INNER (opmode));
2990               int n_elts = GET_MODE_SIZE (opmode) / elt_size;
2991
2992               int i = INTVAL (XVECEXP (trueop1, 0, 0));
2993               int elem;
2994
2995               rtvec vec;
2996               rtx tmp_op, tmp;
2997
2998               gcc_assert (GET_CODE (op1) == PARALLEL);
2999               gcc_assert (i < n_elts);
3000
3001               /* Select element, pointed by nested selector.  */
3002               elem = INTVAL (XVECEXP (op1, 0, i));
3003
3004               /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT.  */
3005               if (GET_CODE (op0) == VEC_CONCAT)
3006                 {
3007                   rtx op00 = XEXP (op0, 0);
3008                   rtx op01 = XEXP (op0, 1);
3009
3010                   enum machine_mode mode00, mode01;
3011                   int n_elts00, n_elts01;
3012
3013                   mode00 = GET_MODE (op00);
3014                   mode01 = GET_MODE (op01);
3015
3016                   /* Find out number of elements of each operand.  */
3017                   if (VECTOR_MODE_P (mode00))
3018                     {
3019                       elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode00));
3020                       n_elts00 = GET_MODE_SIZE (mode00) / elt_size;
3021                     }
3022                   else
3023                     n_elts00 = 1;
3024
3025                   if (VECTOR_MODE_P (mode01))
3026                     {
3027                       elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode01));
3028                       n_elts01 = GET_MODE_SIZE (mode01) / elt_size;
3029                     }
3030                   else
3031                     n_elts01 = 1;
3032
3033                   gcc_assert (n_elts == n_elts00 + n_elts01);
3034
3035                   /* Select correct operand of VEC_CONCAT
3036                      and adjust selector. */
3037                   if (elem < n_elts01)
3038                     tmp_op = op00;
3039                   else
3040                     {
3041                       tmp_op = op01;
3042                       elem -= n_elts00;
3043                     }
3044                 }
3045               else
3046                 tmp_op = op0;
3047
3048               vec = rtvec_alloc (1);
3049               RTVEC_ELT (vec, 0) = GEN_INT (elem);
3050
3051               tmp = gen_rtx_fmt_ee (code, mode,
3052                                     tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
3053               return tmp;
3054             }
3055           if (GET_CODE (trueop0) == VEC_DUPLICATE
3056               && GET_MODE (XEXP (trueop0, 0)) == mode)
3057             return XEXP (trueop0, 0);
3058         }
3059       else
3060         {
3061           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
3062           gcc_assert (GET_MODE_INNER (mode)
3063                       == GET_MODE_INNER (GET_MODE (trueop0)));
3064           gcc_assert (GET_CODE (trueop1) == PARALLEL);
3065
3066           if (GET_CODE (trueop0) == CONST_VECTOR)
3067             {
3068               int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
3069               unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
3070               rtvec v = rtvec_alloc (n_elts);
3071               unsigned int i;
3072
3073               gcc_assert (XVECLEN (trueop1, 0) == (int) n_elts);
3074               for (i = 0; i < n_elts; i++)
3075                 {
3076                   rtx x = XVECEXP (trueop1, 0, i);
3077
3078                   gcc_assert (CONST_INT_P (x));
3079                   RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
3080                                                        INTVAL (x));
3081                 }
3082
3083               return gen_rtx_CONST_VECTOR (mode, v);
3084             }
3085         }
3086
3087       if (XVECLEN (trueop1, 0) == 1
3088           && CONST_INT_P (XVECEXP (trueop1, 0, 0))
3089           && GET_CODE (trueop0) == VEC_CONCAT)
3090         {
3091           rtx vec = trueop0;
3092           int offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
3093
3094           /* Try to find the element in the VEC_CONCAT.  */
3095           while (GET_MODE (vec) != mode
3096                  && GET_CODE (vec) == VEC_CONCAT)
3097             {
3098               HOST_WIDE_INT vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
3099               if (offset < vec_size)
3100                 vec = XEXP (vec, 0);
3101               else
3102                 {
3103                   offset -= vec_size;
3104                   vec = XEXP (vec, 1);
3105                 }
3106               vec = avoid_constant_pool_reference (vec);
3107             }
3108
3109           if (GET_MODE (vec) == mode)
3110             return vec;
3111         }
3112
3113       return 0;
3114     case VEC_CONCAT:
3115       {
3116         enum machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
3117                                       ? GET_MODE (trueop0)
3118                                       : GET_MODE_INNER (mode));
3119         enum machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
3120                                       ? GET_MODE (trueop1)
3121                                       : GET_MODE_INNER (mode));
3122
3123         gcc_assert (VECTOR_MODE_P (mode));
3124         gcc_assert (GET_MODE_SIZE (op0_mode) + GET_MODE_SIZE (op1_mode)
3125                     == GET_MODE_SIZE (mode));
3126
3127         if (VECTOR_MODE_P (op0_mode))
3128           gcc_assert (GET_MODE_INNER (mode)
3129                       == GET_MODE_INNER (op0_mode));
3130         else
3131           gcc_assert (GET_MODE_INNER (mode) == op0_mode);
3132
3133         if (VECTOR_MODE_P (op1_mode))
3134           gcc_assert (GET_MODE_INNER (mode)
3135                       == GET_MODE_INNER (op1_mode));
3136         else
3137           gcc_assert (GET_MODE_INNER (mode) == op1_mode);
3138
3139         if ((GET_CODE (trueop0) == CONST_VECTOR
3140              || CONST_INT_P (trueop0)
3141              || GET_CODE (trueop0) == CONST_DOUBLE)
3142             && (GET_CODE (trueop1) == CONST_VECTOR
3143                 || CONST_INT_P (trueop1)
3144                 || GET_CODE (trueop1) == CONST_DOUBLE))
3145           {
3146             int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
3147             unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
3148             rtvec v = rtvec_alloc (n_elts);
3149             unsigned int i;
3150             unsigned in_n_elts = 1;
3151
3152             if (VECTOR_MODE_P (op0_mode))
3153               in_n_elts = (GET_MODE_SIZE (op0_mode) / elt_size);
3154             for (i = 0; i < n_elts; i++)
3155               {
3156                 if (i < in_n_elts)
3157                   {
3158                     if (!VECTOR_MODE_P (op0_mode))
3159                       RTVEC_ELT (v, i) = trueop0;
3160                     else
3161                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
3162                   }
3163                 else
3164                   {
3165                     if (!VECTOR_MODE_P (op1_mode))
3166                       RTVEC_ELT (v, i) = trueop1;
3167                     else
3168                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
3169                                                            i - in_n_elts);
3170                   }
3171               }
3172
3173             return gen_rtx_CONST_VECTOR (mode, v);
3174           }
3175       }
3176       return 0;
3177
3178     default:
3179       gcc_unreachable ();
3180     }
3181
3182   return 0;
3183 }
3184
3185 rtx
3186 simplify_const_binary_operation (enum rtx_code code, enum machine_mode mode,
3187                                  rtx op0, rtx op1)
3188 {
3189   HOST_WIDE_INT arg0, arg1, arg0s, arg1s;
3190   HOST_WIDE_INT val;
3191   unsigned int width = GET_MODE_BITSIZE (mode);
3192
3193   if (VECTOR_MODE_P (mode)
3194       && code != VEC_CONCAT
3195       && GET_CODE (op0) == CONST_VECTOR
3196       && GET_CODE (op1) == CONST_VECTOR)
3197     {
3198       unsigned n_elts = GET_MODE_NUNITS (mode);
3199       enum machine_mode op0mode = GET_MODE (op0);
3200       unsigned op0_n_elts = GET_MODE_NUNITS (op0mode);
3201       enum machine_mode op1mode = GET_MODE (op1);
3202       unsigned op1_n_elts = GET_MODE_NUNITS (op1mode);
3203       rtvec v = rtvec_alloc (n_elts);
3204       unsigned int i;
3205
3206       gcc_assert (op0_n_elts == n_elts);
3207       gcc_assert (op1_n_elts == n_elts);
3208       for (i = 0; i < n_elts; i++)
3209         {
3210           rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
3211                                              CONST_VECTOR_ELT (op0, i),
3212                                              CONST_VECTOR_ELT (op1, i));
3213           if (!x)
3214             return 0;
3215           RTVEC_ELT (v, i) = x;
3216         }
3217
3218       return gen_rtx_CONST_VECTOR (mode, v);
3219     }
3220
3221   if (VECTOR_MODE_P (mode)
3222       && code == VEC_CONCAT
3223       && (CONST_INT_P (op0)
3224           || GET_CODE (op0) == CONST_DOUBLE
3225           || GET_CODE (op0) == CONST_FIXED)
3226       && (CONST_INT_P (op1)
3227           || GET_CODE (op1) == CONST_DOUBLE
3228           || GET_CODE (op1) == CONST_FIXED))
3229     {
3230       unsigned n_elts = GET_MODE_NUNITS (mode);
3231       rtvec v = rtvec_alloc (n_elts);
3232
3233       gcc_assert (n_elts >= 2);
3234       if (n_elts == 2)
3235         {
3236           gcc_assert (GET_CODE (op0) != CONST_VECTOR);
3237           gcc_assert (GET_CODE (op1) != CONST_VECTOR);
3238
3239           RTVEC_ELT (v, 0) = op0;
3240           RTVEC_ELT (v, 1) = op1;
3241         }
3242       else
3243         {
3244           unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0));
3245           unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1));
3246           unsigned i;
3247
3248           gcc_assert (GET_CODE (op0) == CONST_VECTOR);
3249           gcc_assert (GET_CODE (op1) == CONST_VECTOR);
3250           gcc_assert (op0_n_elts + op1_n_elts == n_elts);
3251
3252           for (i = 0; i < op0_n_elts; ++i)
3253             RTVEC_ELT (v, i) = XVECEXP (op0, 0, i);
3254           for (i = 0; i < op1_n_elts; ++i)
3255             RTVEC_ELT (v, op0_n_elts+i) = XVECEXP (op1, 0, i);
3256         }
3257
3258       return gen_rtx_CONST_VECTOR (mode, v);
3259     }
3260
3261   if (SCALAR_FLOAT_MODE_P (mode)
3262       && GET_CODE (op0) == CONST_DOUBLE
3263       && GET_CODE (op1) == CONST_DOUBLE
3264       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
3265     {
3266       if (code == AND
3267           || code == IOR
3268           || code == XOR)
3269         {
3270           long tmp0[4];
3271           long tmp1[4];
3272           REAL_VALUE_TYPE r;
3273           int i;
3274
3275           real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
3276                           GET_MODE (op0));
3277           real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
3278                           GET_MODE (op1));
3279           for (i = 0; i < 4; i++)
3280             {
3281               switch (code)
3282               {
3283               case AND:
3284                 tmp0[i] &= tmp1[i];
3285                 break;
3286               case IOR:
3287                 tmp0[i] |= tmp1[i];
3288                 break;
3289               case XOR:
3290                 tmp0[i] ^= tmp1[i];
3291                 break;
3292               default:
3293                 gcc_unreachable ();
3294               }
3295             }
3296            real_from_target (&r, tmp0, mode);
3297            return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
3298         }
3299       else
3300         {
3301           REAL_VALUE_TYPE f0, f1, value, result;
3302           bool inexact;
3303
3304           REAL_VALUE_FROM_CONST_DOUBLE (f0, op0);
3305           REAL_VALUE_FROM_CONST_DOUBLE (f1, op1);
3306           real_convert (&f0, mode, &f0);
3307           real_convert (&f1, mode, &f1);
3308
3309           if (HONOR_SNANS (mode)
3310               && (REAL_VALUE_ISNAN (f0) || REAL_VALUE_ISNAN (f1)))
3311             return 0;
3312
3313           if (code == DIV
3314               && REAL_VALUES_EQUAL (f1, dconst0)
3315               && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
3316             return 0;
3317
3318           if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
3319               && flag_trapping_math
3320               && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
3321             {
3322               int s0 = REAL_VALUE_NEGATIVE (f0);
3323               int s1 = REAL_VALUE_NEGATIVE (f1);
3324
3325               switch (code)
3326                 {
3327                 case PLUS:
3328                   /* Inf + -Inf = NaN plus exception.  */
3329                   if (s0 != s1)
3330                     return 0;
3331                   break;
3332                 case MINUS:
3333                   /* Inf - Inf = NaN plus exception.  */
3334                   if (s0 == s1)
3335                     return 0;
3336                   break;
3337                 case DIV:
3338                   /* Inf / Inf = NaN plus exception.  */
3339                   return 0;
3340                 default:
3341                   break;
3342                 }
3343             }
3344
3345           if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
3346               && flag_trapping_math
3347               && ((REAL_VALUE_ISINF (f0) && REAL_VALUES_EQUAL (f1, dconst0))
3348                   || (REAL_VALUE_ISINF (f1)
3349                       && REAL_VALUES_EQUAL (f0, dconst0))))
3350             /* Inf * 0 = NaN plus exception.  */
3351             return 0;
3352
3353           inexact = real_arithmetic (&value, rtx_to_tree_code (code),
3354                                      &f0, &f1);
3355           real_convert (&result, mode, &value);
3356
3357           /* Don't constant fold this floating point operation if
3358              the result has overflowed and flag_trapping_math.  */
3359
3360           if (flag_trapping_math
3361               && MODE_HAS_INFINITIES (mode)
3362               && REAL_VALUE_ISINF (result)
3363               && !REAL_VALUE_ISINF (f0)
3364               && !REAL_VALUE_ISINF (f1))
3365             /* Overflow plus exception.  */
3366             return 0;
3367
3368           /* Don't constant fold this floating point operation if the
3369              result may dependent upon the run-time rounding mode and
3370              flag_rounding_math is set, or if GCC's software emulation
3371              is unable to accurately represent the result.  */
3372
3373           if ((flag_rounding_math
3374                || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
3375               && (inexact || !real_identical (&result, &value)))
3376             return NULL_RTX;
3377
3378           return CONST_DOUBLE_FROM_REAL_VALUE (result, mode);
3379         }
3380     }
3381
3382   /* We can fold some multi-word operations.  */
3383   if (GET_MODE_CLASS (mode) == MODE_INT
3384       && width == HOST_BITS_PER_DOUBLE_INT
3385       && (CONST_DOUBLE_P (op0) || CONST_INT_P (op0))
3386       && (CONST_DOUBLE_P (op1) || CONST_INT_P (op1)))
3387     {
3388       double_int o0, o1, res, tmp;
3389
3390       o0 = rtx_to_double_int (op0);
3391       o1 = rtx_to_double_int (op1);
3392
3393       switch (code)
3394         {
3395         case MINUS:
3396           /* A - B == A + (-B).  */
3397           o1 = double_int_neg (o1);
3398
3399           /* Fall through....  */
3400
3401         case PLUS:
3402           res = double_int_add (o0, o1);
3403           break;
3404
3405         case MULT:
3406           res = double_int_mul (o0, o1);
3407           break;
3408
3409         case DIV:
3410           if (div_and_round_double (TRUNC_DIV_EXPR, 0,
3411                                     o0.low, o0.high, o1.low, o1.high,
3412                                     &res.low, &res.high,
3413                                     &tmp.low, &tmp.high))
3414             return 0;
3415           break;
3416
3417         case MOD:
3418           if (div_and_round_double (TRUNC_DIV_EXPR, 0,
3419                                     o0.low, o0.high, o1.low, o1.high,
3420                                     &tmp.low, &tmp.high,
3421                                     &res.low, &res.high))
3422             return 0;
3423           break;
3424
3425         case UDIV:
3426           if (div_and_round_double (TRUNC_DIV_EXPR, 1,
3427                                     o0.low, o0.high, o1.low, o1.high,
3428                                     &res.low, &res.high,
3429                                     &tmp.low, &tmp.high))
3430             return 0;
3431           break;
3432
3433         case UMOD:
3434           if (div_and_round_double (TRUNC_DIV_EXPR, 1,
3435                                     o0.low, o0.high, o1.low, o1.high,
3436                                     &tmp.low, &tmp.high,
3437                                     &res.low, &res.high))
3438             return 0;
3439           break;
3440
3441         case AND:
3442           res = double_int_and (o0, o1);
3443           break;
3444
3445         case IOR:
3446           res = double_int_ior (o0, o1);
3447           break;
3448
3449         case XOR:
3450           res = double_int_xor (o0, o1);
3451           break;
3452
3453         case SMIN:
3454           res = double_int_smin (o0, o1);
3455           break;
3456
3457         case SMAX:
3458           res = double_int_smax (o0, o1);
3459           break;
3460
3461         case UMIN:
3462           res = double_int_umin (o0, o1);
3463           break;
3464
3465         case UMAX:
3466           res = double_int_umax (o0, o1);
3467           break;
3468
3469         case LSHIFTRT:   case ASHIFTRT:
3470         case ASHIFT:
3471         case ROTATE:     case ROTATERT:
3472           {
3473             unsigned HOST_WIDE_INT cnt;
3474
3475             if (SHIFT_COUNT_TRUNCATED)
3476               o1 = double_int_zext (o1, GET_MODE_BITSIZE (mode));
3477
3478             if (!double_int_fits_in_uhwi_p (o1)
3479                 || double_int_to_uhwi (o1) >= GET_MODE_BITSIZE (mode))
3480               return 0;
3481
3482             cnt = double_int_to_uhwi (o1);
3483
3484             if (code == LSHIFTRT || code == ASHIFTRT)
3485               res = double_int_rshift (o0, cnt, GET_MODE_BITSIZE (mode),
3486                                        code == ASHIFTRT);
3487             else if (code == ASHIFT)
3488               res = double_int_lshift (o0, cnt, GET_MODE_BITSIZE (mode),
3489                                        true);
3490             else if (code == ROTATE)
3491               res = double_int_lrotate (o0, cnt, GET_MODE_BITSIZE (mode));
3492             else /* code == ROTATERT */
3493               res = double_int_rrotate (o0, cnt, GET_MODE_BITSIZE (mode));
3494           }
3495           break;
3496
3497         default:
3498           return 0;
3499         }
3500
3501       return immed_double_int_const (res, mode);
3502     }
3503
3504   if (CONST_INT_P (op0) && CONST_INT_P (op1)
3505       && width <= HOST_BITS_PER_WIDE_INT && width != 0)
3506     {
3507       /* Get the integer argument values in two forms:
3508          zero-extended in ARG0, ARG1 and sign-extended in ARG0S, ARG1S.  */
3509
3510       arg0 = INTVAL (op0);
3511       arg1 = INTVAL (op1);
3512
3513       if (width < HOST_BITS_PER_WIDE_INT)
3514         {
3515           arg0 &= ((unsigned HOST_WIDE_INT) 1 << width) - 1;
3516           arg1 &= ((unsigned HOST_WIDE_INT) 1 << width) - 1;
3517
3518           arg0s = arg0;
3519           if (arg0s & ((unsigned HOST_WIDE_INT) 1 << (width - 1)))
3520             arg0s |= ((unsigned HOST_WIDE_INT) (-1) << width);
3521
3522           arg1s = arg1;
3523           if (arg1s & ((unsigned HOST_WIDE_INT) 1 << (width - 1)))
3524             arg1s |= ((unsigned HOST_WIDE_INT) (-1) << width);
3525         }
3526       else
3527         {
3528           arg0s = arg0;
3529           arg1s = arg1;
3530         }
3531
3532       /* Compute the value of the arithmetic.  */
3533
3534       switch (code)
3535         {
3536         case PLUS:
3537           val = arg0s + arg1s;
3538           break;
3539
3540         case MINUS:
3541           val = arg0s - arg1s;
3542           break;
3543
3544         case MULT:
3545           val = arg0s * arg1s;
3546           break;
3547
3548         case DIV:
3549           if (arg1s == 0
3550               || ((unsigned HOST_WIDE_INT) arg0s
3551                   == (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
3552                   && arg1s == -1))
3553             return 0;
3554           val = arg0s / arg1s;
3555           break;
3556
3557         case MOD:
3558           if (arg1s == 0
3559               || ((unsigned HOST_WIDE_INT) arg0s
3560                   == (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
3561                   && arg1s == -1))
3562             return 0;
3563           val = arg0s % arg1s;
3564           break;
3565
3566         case UDIV:
3567           if (arg1 == 0
3568               || ((unsigned HOST_WIDE_INT) arg0s
3569                   == (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
3570                   && arg1s == -1))
3571             return 0;
3572           val = (unsigned HOST_WIDE_INT) arg0 / arg1;
3573           break;
3574
3575         case UMOD:
3576           if (arg1 == 0
3577               || ((unsigned HOST_WIDE_INT) arg0s
3578                   == (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
3579                   && arg1s == -1))
3580             return 0;
3581           val = (unsigned HOST_WIDE_INT) arg0 % arg1;
3582           break;
3583
3584         case AND:
3585           val = arg0 & arg1;
3586           break;
3587
3588         case IOR:
3589           val = arg0 | arg1;
3590           break;
3591
3592         case XOR:
3593           val = arg0 ^ arg1;
3594           break;
3595
3596         case LSHIFTRT:
3597         case ASHIFT:
3598         case ASHIFTRT:
3599           /* Truncate the shift if SHIFT_COUNT_TRUNCATED, otherwise make sure
3600              the value is in range.  We can't return any old value for
3601              out-of-range arguments because either the middle-end (via
3602              shift_truncation_mask) or the back-end might be relying on
3603              target-specific knowledge.  Nor can we rely on
3604              shift_truncation_mask, since the shift might not be part of an
3605              ashlM3, lshrM3 or ashrM3 instruction.  */
3606           if (SHIFT_COUNT_TRUNCATED)
3607             arg1 = (unsigned HOST_WIDE_INT) arg1 % width;
3608           else if (arg1 < 0 || arg1 >= GET_MODE_BITSIZE (mode))
3609             return 0;
3610
3611           val = (code == ASHIFT
3612                  ? ((unsigned HOST_WIDE_INT) arg0) << arg1
3613                  : ((unsigned HOST_WIDE_INT) arg0) >> arg1);
3614
3615           /* Sign-extend the result for arithmetic right shifts.  */
3616           if (code == ASHIFTRT && arg0s < 0 && arg1 > 0)
3617             val |= ((unsigned HOST_WIDE_INT) (-1)) << (width - arg1);
3618           break;
3619
3620         case ROTATERT:
3621           if (arg1 < 0)
3622             return 0;
3623
3624           arg1 %= width;
3625           val = ((((unsigned HOST_WIDE_INT) arg0) << (width - arg1))
3626                  | (((unsigned HOST_WIDE_INT) arg0) >> arg1));
3627           break;
3628
3629         case ROTATE:
3630           if (arg1 < 0)
3631             return 0;
3632
3633           arg1 %= width;
3634           val = ((((unsigned HOST_WIDE_INT) arg0) << arg1)
3635                  | (((unsigned HOST_WIDE_INT) arg0) >> (width - arg1)));
3636           break;
3637
3638         case COMPARE:
3639           /* Do nothing here.  */
3640           return 0;
3641
3642         case SMIN:
3643           val = arg0s <= arg1s ? arg0s : arg1s;
3644           break;
3645
3646         case UMIN:
3647           val = ((unsigned HOST_WIDE_INT) arg0
3648                  <= (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
3649           break;
3650
3651         case SMAX:
3652           val = arg0s > arg1s ? arg0s : arg1s;
3653           break;
3654
3655         case UMAX:
3656           val = ((unsigned HOST_WIDE_INT) arg0
3657                  > (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
3658           break;
3659
3660         case SS_PLUS:
3661         case US_PLUS:
3662         case SS_MINUS:
3663         case US_MINUS:
3664         case SS_MULT:
3665         case US_MULT:
3666         case SS_DIV:
3667         case US_DIV:
3668         case SS_ASHIFT:
3669         case US_ASHIFT:
3670           /* ??? There are simplifications that can be done.  */
3671           return 0;
3672
3673         default:
3674           gcc_unreachable ();
3675         }
3676
3677       return gen_int_mode (val, mode);
3678     }
3679
3680   return NULL_RTX;
3681 }
3682
3683
3684 \f
3685 /* Simplify a PLUS or MINUS, at least one of whose operands may be another
3686    PLUS or MINUS.
3687
3688    Rather than test for specific case, we do this by a brute-force method
3689    and do all possible simplifications until no more changes occur.  Then
3690    we rebuild the operation.  */
3691
3692 struct simplify_plus_minus_op_data
3693 {
3694   rtx op;
3695   short neg;
3696 };
3697
3698 static bool
3699 simplify_plus_minus_op_data_cmp (rtx x, rtx y)
3700 {
3701   int result;
3702
3703   result = (commutative_operand_precedence (y)
3704             - commutative_operand_precedence (x));
3705   if (result)
3706     return result > 0;
3707
3708   /* Group together equal REGs to do more simplification.  */
3709   if (REG_P (x) && REG_P (y))
3710     return REGNO (x) > REGNO (y);
3711   else
3712     return false;
3713 }
3714
3715 static rtx
3716 simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
3717                      rtx op1)
3718 {
3719   struct simplify_plus_minus_op_data ops[8];
3720   rtx result, tem;
3721   int n_ops = 2, input_ops = 2;
3722   int changed, n_constants = 0, canonicalized = 0;
3723   int i, j;
3724
3725   memset (ops, 0, sizeof ops);
3726
3727   /* Set up the two operands and then expand them until nothing has been
3728      changed.  If we run out of room in our array, give up; this should
3729      almost never happen.  */
3730
3731   ops[0].op = op0;
3732   ops[0].neg = 0;
3733   ops[1].op = op1;
3734   ops[1].neg = (code == MINUS);
3735
3736   do
3737     {
3738       changed = 0;
3739
3740       for (i = 0; i < n_ops; i++)
3741         {
3742           rtx this_op = ops[i].op;
3743           int this_neg = ops[i].neg;
3744           enum rtx_code this_code = GET_CODE (this_op);
3745
3746           switch (this_code)
3747             {
3748             case PLUS:
3749             case MINUS:
3750               if (n_ops == 7)
3751                 return NULL_RTX;
3752
3753               ops[n_ops].op = XEXP (this_op, 1);
3754               ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
3755               n_ops++;
3756
3757               ops[i].op = XEXP (this_op, 0);
3758               input_ops++;
3759               changed = 1;
3760               canonicalized |= this_neg;
3761               break;
3762
3763             case NEG:
3764               ops[i].op = XEXP (this_op, 0);
3765               ops[i].neg = ! this_neg;
3766               changed = 1;
3767               canonicalized = 1;
3768               break;
3769
3770             case CONST:
3771               if (n_ops < 7
3772                   && GET_CODE (XEXP (this_op, 0)) == PLUS
3773                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
3774                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
3775                 {
3776                   ops[i].op = XEXP (XEXP (this_op, 0), 0);
3777                   ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
3778                   ops[n_ops].neg = this_neg;
3779                   n_ops++;
3780                   changed = 1;
3781                   canonicalized = 1;
3782                 }
3783               break;
3784
3785             case NOT:
3786               /* ~a -> (-a - 1) */
3787               if (n_ops != 7)
3788                 {
3789                   ops[n_ops].op = constm1_rtx;
3790                   ops[n_ops++].neg = this_neg;
3791                   ops[i].op = XEXP (this_op, 0);
3792                   ops[i].neg = !this_neg;
3793                   changed = 1;
3794                   canonicalized = 1;
3795                 }
3796               break;
3797
3798             case CONST_INT:
3799               n_constants++;
3800               if (this_neg)
3801                 {
3802                   ops[i].op = neg_const_int (mode, this_op);
3803                   ops[i].neg = 0;
3804                   changed = 1;
3805                   canonicalized = 1;
3806                 }
3807               break;
3808
3809             default:
3810               break;
3811             }
3812         }
3813     }
3814   while (changed);
3815
3816   if (n_constants > 1)
3817     canonicalized = 1;
3818
3819   gcc_assert (n_ops >= 2);
3820
3821   /* If we only have two operands, we can avoid the loops.  */
3822   if (n_ops == 2)
3823     {
3824       enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
3825       rtx lhs, rhs;
3826
3827       /* Get the two operands.  Be careful with the order, especially for
3828          the cases where code == MINUS.  */
3829       if (ops[0].neg && ops[1].neg)
3830         {
3831           lhs = gen_rtx_NEG (mode, ops[0].op);
3832           rhs = ops[1].op;
3833         }
3834       else if (ops[0].neg)
3835         {
3836           lhs = ops[1].op;
3837           rhs = ops[0].op;
3838         }
3839       else
3840         {
3841           lhs = ops[0].op;
3842           rhs = ops[1].op;
3843         }
3844
3845       return simplify_const_binary_operation (code, mode, lhs, rhs);
3846     }
3847
3848   /* Now simplify each pair of operands until nothing changes.  */
3849   do
3850     {
3851       /* Insertion sort is good enough for an eight-element array.  */
3852       for (i = 1; i < n_ops; i++)
3853         {
3854           struct simplify_plus_minus_op_data save;
3855           j = i - 1;
3856           if (!simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op))
3857             continue;
3858
3859           canonicalized = 1;
3860           save = ops[i];
3861           do
3862             ops[j + 1] = ops[j];
3863           while (j-- && simplify_plus_minus_op_data_cmp (ops[j].op, save.op));
3864           ops[j + 1] = save;
3865         }
3866
3867       changed = 0;
3868       for (i = n_ops - 1; i > 0; i--)
3869         for (j = i - 1; j >= 0; j--)
3870           {
3871             rtx lhs = ops[j].op, rhs = ops[i].op;
3872             int lneg = ops[j].neg, rneg = ops[i].neg;
3873
3874             if (lhs != 0 && rhs != 0)
3875               {
3876                 enum rtx_code ncode = PLUS;
3877
3878                 if (lneg != rneg)
3879                   {
3880                     ncode = MINUS;
3881                     if (lneg)
3882                       tem = lhs, lhs = rhs, rhs = tem;
3883                   }
3884                 else if (swap_commutative_operands_p (lhs, rhs))
3885                   tem = lhs, lhs = rhs, rhs = tem;
3886
3887                 if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
3888                     && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
3889                   {
3890                     rtx tem_lhs, tem_rhs;
3891
3892                     tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
3893                     tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
3894                     tem = simplify_binary_operation (ncode, mode, tem_lhs, tem_rhs);
3895
3896                     if (tem && !CONSTANT_P (tem))
3897                       tem = gen_rtx_CONST (GET_MODE (tem), tem);
3898                   }
3899                 else
3900                   tem = simplify_binary_operation (ncode, mode, lhs, rhs);
3901
3902                 /* Reject "simplifications" that just wrap the two
3903                    arguments in a CONST.  Failure to do so can result
3904                    in infinite recursion with simplify_binary_operation
3905                    when it calls us to simplify CONST operations.  */
3906                 if (tem
3907                     && ! (GET_CODE (tem) == CONST
3908                           && GET_CODE (XEXP (tem, 0)) == ncode
3909                           && XEXP (XEXP (tem, 0), 0) == lhs
3910                           && XEXP (XEXP (tem, 0), 1) == rhs))
3911                   {
3912                     lneg &= rneg;
3913                     if (GET_CODE (tem) == NEG)
3914                       tem = XEXP (tem, 0), lneg = !lneg;
3915                     if (CONST_INT_P (tem) && lneg)
3916                       tem = neg_const_int (mode, tem), lneg = 0;
3917
3918                     ops[i].op = tem;
3919                     ops[i].neg = lneg;
3920                     ops[j].op = NULL_RTX;
3921                     changed = 1;
3922                     canonicalized = 1;
3923                   }
3924               }
3925           }
3926
3927       /* If nothing changed, fail.  */
3928       if (!canonicalized)
3929         return NULL_RTX;
3930
3931       /* Pack all the operands to the lower-numbered entries.  */
3932       for (i = 0, j = 0; j < n_ops; j++)
3933         if (ops[j].op)
3934           {
3935             ops[i] = ops[j];
3936             i++;
3937           }
3938       n_ops = i;
3939     }
3940   while (changed);
3941
3942   /* Create (minus -C X) instead of (neg (const (plus X C))).  */
3943   if (n_ops == 2
3944       && CONST_INT_P (ops[1].op)
3945       && CONSTANT_P (ops[0].op)
3946       && ops[0].neg)
3947     return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
3948
3949   /* We suppressed creation of trivial CONST expressions in the
3950      combination loop to avoid recursion.  Create one manually now.
3951      The combination loop should have ensured that there is exactly
3952      one CONST_INT, and the sort will have ensured that it is last
3953      in the array and that any other constant will be next-to-last.  */
3954
3955   if (n_ops > 1
3956       && CONST_INT_P (ops[n_ops - 1].op)
3957       && CONSTANT_P (ops[n_ops - 2].op))
3958     {
3959       rtx value = ops[n_ops - 1].op;
3960       if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
3961         value = neg_const_int (mode, value);
3962       ops[n_ops - 2].op = plus_constant (ops[n_ops - 2].op, INTVAL (value));
3963       n_ops--;
3964     }
3965
3966   /* Put a non-negated operand first, if possible.  */
3967
3968   for (i = 0; i < n_ops && ops[i].neg; i++)
3969     continue;
3970   if (i == n_ops)
3971     ops[0].op = gen_rtx_NEG (mode, ops[0].op);
3972   else if (i != 0)
3973     {
3974       tem = ops[0].op;
3975       ops[0] = ops[i];
3976       ops[i].op = tem;
3977       ops[i].neg = 1;
3978     }
3979
3980   /* Now make the result by performing the requested operations.  */
3981   result = ops[0].op;
3982   for (i = 1; i < n_ops; i++)
3983     result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
3984                              mode, result, ops[i].op);
3985
3986   return result;
3987 }
3988
3989 /* Check whether an operand is suitable for calling simplify_plus_minus.  */
3990 static bool
3991 plus_minus_operand_p (const_rtx x)
3992 {
3993   return GET_CODE (x) == PLUS
3994          || GET_CODE (x) == MINUS
3995          || (GET_CODE (x) == CONST
3996              && GET_CODE (XEXP (x, 0)) == PLUS
3997              && CONSTANT_P (XEXP (XEXP (x, 0), 0))
3998              && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
3999 }
4000
4001 /* Like simplify_binary_operation except used for relational operators.
4002    MODE is the mode of the result. If MODE is VOIDmode, both operands must
4003    not also be VOIDmode.
4004
4005    CMP_MODE specifies in which mode the comparison is done in, so it is
4006    the mode of the operands.  If CMP_MODE is VOIDmode, it is taken from
4007    the operands or, if both are VOIDmode, the operands are compared in
4008    "infinite precision".  */
4009 rtx
4010 simplify_relational_operation (enum rtx_code code, enum machine_mode mode,
4011                                enum machine_mode cmp_mode, rtx op0, rtx op1)
4012 {
4013   rtx tem, trueop0, trueop1;
4014
4015   if (cmp_mode == VOIDmode)
4016     cmp_mode = GET_MODE (op0);
4017   if (cmp_mode == VOIDmode)
4018     cmp_mode = GET_MODE (op1);
4019
4020   tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
4021   if (tem)
4022     {
4023       if (SCALAR_FLOAT_MODE_P (mode))
4024         {
4025           if (tem == const0_rtx)
4026             return CONST0_RTX (mode);
4027 #ifdef FLOAT_STORE_FLAG_VALUE
4028           {
4029             REAL_VALUE_TYPE val;
4030             val = FLOAT_STORE_FLAG_VALUE (mode);
4031             return CONST_DOUBLE_FROM_REAL_VALUE (val, mode);
4032           }
4033 #else
4034           return NULL_RTX;
4035 #endif
4036         }
4037       if (VECTOR_MODE_P (mode))
4038         {
4039           if (tem == const0_rtx)
4040             return CONST0_RTX (mode);
4041 #ifdef VECTOR_STORE_FLAG_VALUE
4042           {
4043             int i, units;
4044             rtvec v;
4045
4046             rtx val = VECTOR_STORE_FLAG_VALUE (mode);
4047             if (val == NULL_RTX)
4048               return NULL_RTX;
4049             if (val == const1_rtx)
4050               return CONST1_RTX (mode);
4051
4052             units = GET_MODE_NUNITS (mode);
4053             v = rtvec_alloc (units);
4054             for (i = 0; i < units; i++)
4055               RTVEC_ELT (v, i) = val;
4056             return gen_rtx_raw_CONST_VECTOR (mode, v);
4057           }
4058 #else
4059           return NULL_RTX;
4060 #endif
4061         }
4062
4063       return tem;
4064     }
4065
4066   /* For the following tests, ensure const0_rtx is op1.  */
4067   if (swap_commutative_operands_p (op0, op1)
4068       || (op0 == const0_rtx && op1 != const0_rtx))
4069     tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
4070
4071   /* If op0 is a compare, extract the comparison arguments from it.  */
4072   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
4073     return simplify_gen_relational (code, mode, VOIDmode,
4074                                     XEXP (op0, 0), XEXP (op0, 1));
4075
4076   if (GET_MODE_CLASS (cmp_mode) == MODE_CC
4077       || CC0_P (op0))
4078     return NULL_RTX;
4079
4080   trueop0 = avoid_constant_pool_reference (op0);
4081   trueop1 = avoid_constant_pool_reference (op1);
4082   return simplify_relational_operation_1 (code, mode, cmp_mode,
4083                                           trueop0, trueop1);
4084 }
4085
4086 /* This part of simplify_relational_operation is only used when CMP_MODE
4087    is not in class MODE_CC (i.e. it is a real comparison).
4088
4089    MODE is the mode of the result, while CMP_MODE specifies in which
4090    mode the comparison is done in, so it is the mode of the operands.  */
4091
4092 static rtx
4093 simplify_relational_operation_1 (enum rtx_code code, enum machine_mode mode,
4094                                  enum machine_mode cmp_mode, rtx op0, rtx op1)
4095 {
4096   enum rtx_code op0code = GET_CODE (op0);
4097
4098   if (op1 == const0_rtx && COMPARISON_P (op0))
4099     {
4100       /* If op0 is a comparison, extract the comparison arguments
4101          from it.  */
4102       if (code == NE)
4103         {
4104           if (GET_MODE (op0) == mode)
4105             return simplify_rtx (op0);
4106           else
4107             return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
4108                                             XEXP (op0, 0), XEXP (op0, 1));
4109         }
4110       else if (code == EQ)
4111         {
4112           enum rtx_code new_code = reversed_comparison_code (op0, NULL_RTX);
4113           if (new_code != UNKNOWN)
4114             return simplify_gen_relational (new_code, mode, VOIDmode,
4115                                             XEXP (op0, 0), XEXP (op0, 1));
4116         }
4117     }
4118
4119   /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
4120      (GEU/LTU a -C).  Likewise for (LTU/GEU (PLUS a C) a).  */
4121   if ((code == LTU || code == GEU)
4122       && GET_CODE (op0) == PLUS
4123       && CONST_INT_P (XEXP (op0, 1))
4124       && (rtx_equal_p (op1, XEXP (op0, 0))
4125           || rtx_equal_p (op1, XEXP (op0, 1))))
4126     {
4127       rtx new_cmp
4128         = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
4129       return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
4130                                       cmp_mode, XEXP (op0, 0), new_cmp);
4131     }
4132
4133   /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a).  */
4134   if ((code == LTU || code == GEU)
4135       && GET_CODE (op0) == PLUS
4136       && rtx_equal_p (op1, XEXP (op0, 1))
4137       /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b).  */
4138       && !rtx_equal_p (op1, XEXP (op0, 0)))
4139     return simplify_gen_relational (code, mode, cmp_mode, op0,
4140                                     copy_rtx (XEXP (op0, 0)));
4141
4142   if (op1 == const0_rtx)
4143     {
4144       /* Canonicalize (GTU x 0) as (NE x 0).  */
4145       if (code == GTU)
4146         return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
4147       /* Canonicalize (LEU x 0) as (EQ x 0).  */
4148       if (code == LEU)
4149         return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
4150     }
4151   else if (op1 == const1_rtx)
4152     {
4153       switch (code)
4154         {
4155         case GE:
4156           /* Canonicalize (GE x 1) as (GT x 0).  */
4157           return simplify_gen_relational (GT, mode, cmp_mode,
4158                                           op0, const0_rtx);
4159         case GEU:
4160           /* Canonicalize (GEU x 1) as (NE x 0).  */
4161           return simplify_gen_relational (NE, mode, cmp_mode,
4162                                           op0, const0_rtx);
4163         case LT:
4164           /* Canonicalize (LT x 1) as (LE x 0).  */
4165           return simplify_gen_relational (LE, mode, cmp_mode,
4166                                           op0, const0_rtx);
4167         case LTU:
4168           /* Canonicalize (LTU x 1) as (EQ x 0).  */
4169           return simplify_gen_relational (EQ, mode, cmp_mode,
4170                                           op0, const0_rtx);
4171         default:
4172           break;
4173         }
4174     }
4175   else if (op1 == constm1_rtx)
4176     {
4177       /* Canonicalize (LE x -1) as (LT x 0).  */
4178       if (code == LE)
4179         return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
4180       /* Canonicalize (GT x -1) as (GE x 0).  */
4181       if (code == GT)
4182         return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
4183     }
4184
4185   /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1))  */
4186   if ((code == EQ || code == NE)
4187       && (op0code == PLUS || op0code == MINUS)
4188       && CONSTANT_P (op1)
4189       && CONSTANT_P (XEXP (op0, 1))
4190       && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
4191     {
4192       rtx x = XEXP (op0, 0);
4193       rtx c = XEXP (op0, 1);
4194
4195       c = simplify_gen_binary (op0code == PLUS ? MINUS : PLUS,
4196                                cmp_mode, op1, c);
4197       return simplify_gen_relational (code, mode, cmp_mode, x, c);
4198     }
4199
4200   /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
4201      the same as (zero_extract:SI FOO (const_int 1) BAR).  */
4202   if (code == NE
4203       && op1 == const0_rtx
4204       && GET_MODE_CLASS (mode) == MODE_INT
4205       && cmp_mode != VOIDmode
4206       /* ??? Work-around BImode bugs in the ia64 backend.  */
4207       && mode != BImode
4208       && cmp_mode != BImode
4209       && nonzero_bits (op0, cmp_mode) == 1
4210       && STORE_FLAG_VALUE == 1)
4211     return GET_MODE_SIZE (mode) > GET_MODE_SIZE (cmp_mode)
4212            ? simplify_gen_unary (ZERO_EXTEND, mode, op0, cmp_mode)
4213            : lowpart_subreg (mode, op0, cmp_mode);
4214
4215   /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y).  */
4216   if ((code == EQ || code == NE)
4217       && op1 == const0_rtx
4218       && op0code == XOR)
4219     return simplify_gen_relational (code, mode, cmp_mode,
4220                                     XEXP (op0, 0), XEXP (op0, 1));
4221
4222   /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0).  */
4223   if ((code == EQ || code == NE)
4224       && op0code == XOR
4225       && rtx_equal_p (XEXP (op0, 0), op1)
4226       && !side_effects_p (XEXP (op0, 0)))
4227     return simplify_gen_relational (code, mode, cmp_mode,
4228                                     XEXP (op0, 1), const0_rtx);
4229
4230   /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0).  */
4231   if ((code == EQ || code == NE)
4232       && op0code == XOR
4233       && rtx_equal_p (XEXP (op0, 1), op1)
4234       && !side_effects_p (XEXP (op0, 1)))
4235     return simplify_gen_relational (code, mode, cmp_mode,
4236                                     XEXP (op0, 0), const0_rtx);
4237
4238   /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)).  */
4239   if ((code == EQ || code == NE)
4240       && op0code == XOR
4241       && (CONST_INT_P (op1)
4242           || GET_CODE (op1) == CONST_DOUBLE)
4243       && (CONST_INT_P (XEXP (op0, 1))
4244           || GET_CODE (XEXP (op0, 1)) == CONST_DOUBLE))
4245     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
4246                                     simplify_gen_binary (XOR, cmp_mode,
4247                                                          XEXP (op0, 1), op1));
4248
4249   if (op0code == POPCOUNT && op1 == const0_rtx)
4250     switch (code)
4251       {
4252       case EQ:
4253       case LE:
4254       case LEU:
4255         /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)).  */
4256         return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
4257                                         XEXP (op0, 0), const0_rtx);
4258
4259       case NE:
4260       case GT:
4261       case GTU:
4262         /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)).  */
4263         return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
4264                                         XEXP (op0, 0), const0_rtx);
4265
4266       default:
4267         break;
4268       }
4269
4270   return NULL_RTX;
4271 }
4272
4273 enum
4274 {
4275   CMP_EQ = 1,
4276   CMP_LT = 2,
4277   CMP_GT = 4,
4278   CMP_LTU = 8,
4279   CMP_GTU = 16
4280 };
4281
4282
4283 /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
4284    KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
4285    For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
4286    logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
4287    For floating-point comparisons, assume that the operands were ordered.  */
4288
4289 static rtx
4290 comparison_result (enum rtx_code code, int known_results)
4291 {
4292   switch (code)
4293     {
4294     case EQ:
4295     case UNEQ:
4296       return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
4297     case NE:
4298     case LTGT:
4299       return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
4300
4301     case LT:
4302     case UNLT:
4303       return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
4304     case GE:
4305     case UNGE:
4306       return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
4307
4308     case GT:
4309     case UNGT:
4310       return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
4311     case LE:
4312     case UNLE:
4313       return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
4314
4315     case LTU:
4316       return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
4317     case GEU:
4318       return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
4319
4320     case GTU:
4321       return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
4322     case LEU:
4323       return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
4324
4325     case ORDERED:
4326       return const_true_rtx;
4327     case UNORDERED:
4328       return const0_rtx;
4329     default:
4330       gcc_unreachable ();
4331     }
4332 }
4333
4334 /* Check if the given comparison (done in the given MODE) is actually a
4335    tautology or a contradiction.
4336    If no simplification is possible, this function returns zero.
4337    Otherwise, it returns either const_true_rtx or const0_rtx.  */
4338
4339 rtx
4340 simplify_const_relational_operation (enum rtx_code code,
4341                                      enum machine_mode mode,
4342                                      rtx op0, rtx op1)
4343 {
4344   rtx tem;
4345   rtx trueop0;
4346   rtx trueop1;
4347
4348   gcc_assert (mode != VOIDmode
4349               || (GET_MODE (op0) == VOIDmode
4350                   && GET_MODE (op1) == VOIDmode));
4351
4352   /* If op0 is a compare, extract the comparison arguments from it.  */
4353   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
4354     {
4355       op1 = XEXP (op0, 1);
4356       op0 = XEXP (op0, 0);
4357
4358       if (GET_MODE (op0) != VOIDmode)
4359         mode = GET_MODE (op0);
4360       else if (GET_MODE (op1) != VOIDmode)
4361         mode = GET_MODE (op1);
4362       else
4363         return 0;
4364     }
4365
4366   /* We can't simplify MODE_CC values since we don't know what the
4367      actual comparison is.  */
4368   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC || CC0_P (op0))
4369     return 0;
4370
4371   /* Make sure the constant is second.  */
4372   if (swap_commutative_operands_p (op0, op1))
4373     {
4374       tem = op0, op0 = op1, op1 = tem;
4375       code = swap_condition (code);
4376     }
4377
4378   trueop0 = avoid_constant_pool_reference (op0);
4379   trueop1 = avoid_constant_pool_reference (op1);
4380
4381   /* For integer comparisons of A and B maybe we can simplify A - B and can
4382      then simplify a comparison of that with zero.  If A and B are both either
4383      a register or a CONST_INT, this can't help; testing for these cases will
4384      prevent infinite recursion here and speed things up.
4385
4386      We can only do this for EQ and NE comparisons as otherwise we may
4387      lose or introduce overflow which we cannot disregard as undefined as
4388      we do not know the signedness of the operation on either the left or
4389      the right hand side of the comparison.  */
4390
4391   if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
4392       && (code == EQ || code == NE)
4393       && ! ((REG_P (op0) || CONST_INT_P (trueop0))
4394             && (REG_P (op1) || CONST_INT_P (trueop1)))
4395       && 0 != (tem = simplify_binary_operation (MINUS, mode, op0, op1))
4396       /* We cannot do this if tem is a nonzero address.  */
4397       && ! nonzero_address_p (tem))
4398     return simplify_const_relational_operation (signed_condition (code),
4399                                                 mode, tem, const0_rtx);
4400
4401   if (! HONOR_NANS (mode) && code == ORDERED)
4402     return const_true_rtx;
4403
4404   if (! HONOR_NANS (mode) && code == UNORDERED)
4405     return const0_rtx;
4406
4407   /* For modes without NaNs, if the two operands are equal, we know the
4408      result except if they have side-effects.  Even with NaNs we know
4409      the result of unordered comparisons and, if signaling NaNs are
4410      irrelevant, also the result of LT/GT/LTGT.  */
4411   if ((! HONOR_NANS (GET_MODE (trueop0))
4412        || code == UNEQ || code == UNLE || code == UNGE
4413        || ((code == LT || code == GT || code == LTGT)
4414            && ! HONOR_SNANS (GET_MODE (trueop0))))
4415       && rtx_equal_p (trueop0, trueop1)
4416       && ! side_effects_p (trueop0))
4417     return comparison_result (code, CMP_EQ);
4418
4419   /* If the operands are floating-point constants, see if we can fold
4420      the result.  */
4421   if (GET_CODE (trueop0) == CONST_DOUBLE
4422       && GET_CODE (trueop1) == CONST_DOUBLE
4423       && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
4424     {
4425       REAL_VALUE_TYPE d0, d1;
4426
4427       REAL_VALUE_FROM_CONST_DOUBLE (d0, trueop0);
4428       REAL_VALUE_FROM_CONST_DOUBLE (d1, trueop1);
4429
4430       /* Comparisons are unordered iff at least one of the values is NaN.  */
4431       if (REAL_VALUE_ISNAN (d0) || REAL_VALUE_ISNAN (d1))
4432         switch (code)
4433           {
4434           case UNEQ:
4435           case UNLT:
4436           case UNGT:
4437           case UNLE:
4438           case UNGE:
4439           case NE:
4440           case UNORDERED:
4441             return const_true_rtx;
4442           case EQ:
4443           case LT:
4444           case GT:
4445           case LE:
4446           case GE:
4447           case LTGT:
4448           case ORDERED:
4449             return const0_rtx;
4450           default:
4451             return 0;
4452           }
4453
4454       return comparison_result (code,
4455                                 (REAL_VALUES_EQUAL (d0, d1) ? CMP_EQ :
4456                                  REAL_VALUES_LESS (d0, d1) ? CMP_LT : CMP_GT));
4457     }
4458
4459   /* Otherwise, see if the operands are both integers.  */
4460   if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
4461        && (GET_CODE (trueop0) == CONST_DOUBLE
4462            || CONST_INT_P (trueop0))
4463        && (GET_CODE (trueop1) == CONST_DOUBLE
4464            || CONST_INT_P (trueop1)))
4465     {
4466       int width = GET_MODE_BITSIZE (mode);
4467       HOST_WIDE_INT l0s, h0s, l1s, h1s;
4468       unsigned HOST_WIDE_INT l0u, h0u, l1u, h1u;
4469
4470       /* Get the two words comprising each integer constant.  */
4471       if (GET_CODE (trueop0) == CONST_DOUBLE)
4472         {
4473           l0u = l0s = CONST_DOUBLE_LOW (trueop0);
4474           h0u = h0s = CONST_DOUBLE_HIGH (trueop0);
4475         }
4476       else
4477         {
4478           l0u = l0s = INTVAL (trueop0);
4479           h0u = h0s = HWI_SIGN_EXTEND (l0s);
4480         }
4481
4482       if (GET_CODE (trueop1) == CONST_DOUBLE)
4483         {
4484           l1u = l1s = CONST_DOUBLE_LOW (trueop1);
4485           h1u = h1s = CONST_DOUBLE_HIGH (trueop1);
4486         }
4487       else
4488         {
4489           l1u = l1s = INTVAL (trueop1);
4490           h1u = h1s = HWI_SIGN_EXTEND (l1s);
4491         }
4492
4493       /* If WIDTH is nonzero and smaller than HOST_BITS_PER_WIDE_INT,
4494          we have to sign or zero-extend the values.  */
4495       if (width != 0 && width < HOST_BITS_PER_WIDE_INT)
4496         {
4497           l0u &= ((unsigned HOST_WIDE_INT) 1 << width) - 1;
4498           l1u &= ((unsigned HOST_WIDE_INT) 1 << width) - 1;
4499
4500           if (l0s & ((unsigned HOST_WIDE_INT) 1 << (width - 1)))
4501             l0s |= ((unsigned HOST_WIDE_INT) (-1) << width);
4502
4503           if (l1s & ((unsigned HOST_WIDE_INT) 1 << (width - 1)))
4504             l1s |= ((unsigned HOST_WIDE_INT) (-1) << width);
4505         }
4506       if (width != 0 && width <= HOST_BITS_PER_WIDE_INT)
4507         h0u = h1u = 0, h0s = HWI_SIGN_EXTEND (l0s), h1s = HWI_SIGN_EXTEND (l1s);
4508
4509       if (h0u == h1u && l0u == l1u)
4510         return comparison_result (code, CMP_EQ);
4511       else
4512         {
4513           int cr;
4514           cr = (h0s < h1s || (h0s == h1s && l0u < l1u)) ? CMP_LT : CMP_GT;
4515           cr |= (h0u < h1u || (h0u == h1u && l0u < l1u)) ? CMP_LTU : CMP_GTU;
4516           return comparison_result (code, cr);
4517         }
4518     }
4519
4520   /* Optimize comparisons with upper and lower bounds.  */
4521   if (SCALAR_INT_MODE_P (mode)
4522       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
4523       && CONST_INT_P (trueop1))
4524     {
4525       int sign;
4526       unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, mode);
4527       HOST_WIDE_INT val = INTVAL (trueop1);
4528       HOST_WIDE_INT mmin, mmax;
4529
4530       if (code == GEU
4531           || code == LEU
4532           || code == GTU
4533           || code == LTU)
4534         sign = 0;
4535       else
4536         sign = 1;
4537
4538       /* Get a reduced range if the sign bit is zero.  */
4539       if (nonzero <= (GET_MODE_MASK (mode) >> 1))
4540         {
4541           mmin = 0;
4542           mmax = nonzero;
4543         }
4544       else
4545         {
4546           rtx mmin_rtx, mmax_rtx;
4547           get_mode_bounds (mode, sign, mode, &mmin_rtx, &mmax_rtx);
4548
4549           mmin = INTVAL (mmin_rtx);
4550           mmax = INTVAL (mmax_rtx);
4551           if (sign)
4552             {
4553               unsigned int sign_copies = num_sign_bit_copies (trueop0, mode);
4554
4555               mmin >>= (sign_copies - 1);
4556               mmax >>= (sign_copies - 1);
4557             }
4558         }
4559
4560       switch (code)
4561         {
4562         /* x >= y is always true for y <= mmin, always false for y > mmax.  */
4563         case GEU:
4564           if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
4565             return const_true_rtx;
4566           if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
4567             return const0_rtx;
4568           break;
4569         case GE:
4570           if (val <= mmin)
4571             return const_true_rtx;
4572           if (val > mmax)
4573             return const0_rtx;
4574           break;
4575
4576         /* x <= y is always true for y >= mmax, always false for y < mmin.  */
4577         case LEU:
4578           if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
4579             return const_true_rtx;
4580           if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
4581             return const0_rtx;
4582           break;
4583         case LE:
4584           if (val >= mmax)
4585             return const_true_rtx;
4586           if (val < mmin)
4587             return const0_rtx;
4588           break;
4589
4590         case EQ:
4591           /* x == y is always false for y out of range.  */
4592           if (val < mmin || val > mmax)
4593             return const0_rtx;
4594           break;
4595
4596         /* x > y is always false for y >= mmax, always true for y < mmin.  */
4597         case GTU:
4598           if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
4599             return const0_rtx;
4600           if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
4601             return const_true_rtx;
4602           break;
4603         case GT:
4604           if (val >= mmax)
4605             return const0_rtx;
4606           if (val < mmin)
4607             return const_true_rtx;
4608           break;
4609
4610         /* x < y is always false for y <= mmin, always true for y > mmax.  */
4611         case LTU:
4612           if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
4613             return const0_rtx;
4614           if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
4615             return const_true_rtx;
4616           break;
4617         case LT:
4618           if (val <= mmin)
4619             return const0_rtx;
4620           if (val > mmax)
4621             return const_true_rtx;
4622           break;
4623
4624         case NE:
4625           /* x != y is always true for y out of range.  */
4626           if (val < mmin || val > mmax)
4627             return const_true_rtx;
4628           break;
4629
4630         default:
4631           break;
4632         }
4633     }
4634
4635   /* Optimize integer comparisons with zero.  */
4636   if (trueop1 == const0_rtx)
4637     {
4638       /* Some addresses are known to be nonzero.  We don't know
4639          their sign, but equality comparisons are known.  */
4640       if (nonzero_address_p (trueop0))
4641         {
4642           if (code == EQ || code == LEU)
4643             return const0_rtx;
4644           if (code == NE || code == GTU)
4645             return const_true_rtx;
4646         }
4647
4648       /* See if the first operand is an IOR with a constant.  If so, we
4649          may be able to determine the result of this comparison.  */
4650       if (GET_CODE (op0) == IOR)
4651         {
4652           rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
4653           if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
4654             {
4655               int sign_bitnum = GET_MODE_BITSIZE (mode) - 1;
4656               int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
4657                               && (UINTVAL (inner_const)
4658                                   & ((unsigned HOST_WIDE_INT) 1
4659                                      << sign_bitnum)));
4660
4661               switch (code)
4662                 {
4663                 case EQ:
4664                 case LEU:
4665                   return const0_rtx;
4666                 case NE:
4667                 case GTU:
4668                   return const_true_rtx;
4669                 case LT:
4670                 case LE:
4671                   if (has_sign)
4672                     return const_true_rtx;
4673                   break;
4674                 case GT:
4675                 case GE:
4676                   if (has_sign)
4677                     return const0_rtx;
4678                   break;
4679                 default:
4680                   break;
4681                 }
4682             }
4683         }
4684     }
4685
4686   /* Optimize comparison of ABS with zero.  */
4687   if (trueop1 == CONST0_RTX (mode)
4688       && (GET_CODE (trueop0) == ABS
4689           || (GET_CODE (trueop0) == FLOAT_EXTEND
4690               && GET_CODE (XEXP (trueop0, 0)) == ABS)))
4691     {
4692       switch (code)
4693         {
4694         case LT:
4695           /* Optimize abs(x) < 0.0.  */
4696           if (!HONOR_SNANS (mode)
4697               && (!INTEGRAL_MODE_P (mode)
4698                   || (!flag_wrapv && !flag_trapv && flag_strict_overflow)))
4699             {
4700               if (INTEGRAL_MODE_P (mode)
4701                   && (issue_strict_overflow_warning
4702                       (WARN_STRICT_OVERFLOW_CONDITIONAL)))
4703                 warning (OPT_Wstrict_overflow,
4704                          ("assuming signed overflow does not occur when "
4705                           "assuming abs (x) < 0 is false"));
4706                return const0_rtx;
4707             }
4708           break;
4709
4710         case GE:
4711           /* Optimize abs(x) >= 0.0.  */
4712           if (!HONOR_NANS (mode)
4713               && (!INTEGRAL_MODE_P (mode)
4714                   || (!flag_wrapv && !flag_trapv && flag_strict_overflow)))
4715             {
4716               if (INTEGRAL_MODE_P (mode)
4717                   && (issue_strict_overflow_warning
4718                   (WARN_STRICT_OVERFLOW_CONDITIONAL)))
4719                 warning (OPT_Wstrict_overflow,
4720                          ("assuming signed overflow does not occur when "
4721                           "assuming abs (x) >= 0 is true"));
4722               return const_true_rtx;
4723             }
4724           break;
4725
4726         case UNGE:
4727           /* Optimize ! (abs(x) < 0.0).  */
4728           return const_true_rtx;
4729
4730         default:
4731           break;
4732         }
4733     }
4734
4735   return 0;
4736 }
4737 \f
4738 /* Simplify CODE, an operation with result mode MODE and three operands,
4739    OP0, OP1, and OP2.  OP0_MODE was the mode of OP0 before it became
4740    a constant.  Return 0 if no simplifications is possible.  */
4741
4742 rtx
4743 simplify_ternary_operation (enum rtx_code code, enum machine_mode mode,
4744                             enum machine_mode op0_mode, rtx op0, rtx op1,
4745                             rtx op2)
4746 {
4747   unsigned int width = GET_MODE_BITSIZE (mode);
4748   bool any_change = false;
4749   rtx tem;
4750
4751   /* VOIDmode means "infinite" precision.  */
4752   if (width == 0)
4753     width = HOST_BITS_PER_WIDE_INT;
4754
4755   switch (code)
4756     {
4757     case FMA:
4758       /* Simplify negations around the multiplication.  */
4759       /* -a * -b + c  =>  a * b + c.  */
4760       if (GET_CODE (op0) == NEG)
4761         {
4762           tem = simplify_unary_operation (NEG, mode, op1, mode);
4763           if (tem)
4764             op1 = tem, op0 = XEXP (op0, 0), any_change = true;
4765         }
4766       else if (GET_CODE (op1) == NEG)
4767         {
4768           tem = simplify_unary_operation (NEG, mode, op0, mode);
4769           if (tem)
4770             op0 = tem, op1 = XEXP (op1, 0), any_change = true;
4771         }
4772
4773       /* Canonicalize the two multiplication operands.  */
4774       /* a * -b + c  =>  -b * a + c.  */
4775       if (swap_commutative_operands_p (op0, op1))
4776         tem = op0, op0 = op1, op1 = tem, any_change = true;
4777
4778       if (any_change)
4779         return gen_rtx_FMA (mode, op0, op1, op2);
4780       return NULL_RTX;
4781
4782     case SIGN_EXTRACT:
4783     case ZERO_EXTRACT:
4784       if (CONST_INT_P (op0)
4785           && CONST_INT_P (op1)
4786           && CONST_INT_P (op2)
4787           && ((unsigned) INTVAL (op1) + (unsigned) INTVAL (op2) <= width)
4788           && width <= (unsigned) HOST_BITS_PER_WIDE_INT)
4789         {
4790           /* Extracting a bit-field from a constant */
4791           unsigned HOST_WIDE_INT val = UINTVAL (op0);
4792
4793           if (BITS_BIG_ENDIAN)
4794             val >>= GET_MODE_BITSIZE (op0_mode) - INTVAL (op2) - INTVAL (op1);
4795           else
4796             val >>= INTVAL (op2);
4797
4798           if (HOST_BITS_PER_WIDE_INT != INTVAL (op1))
4799             {
4800               /* First zero-extend.  */
4801               val &= ((unsigned HOST_WIDE_INT) 1 << INTVAL (op1)) - 1;
4802               /* If desired, propagate sign bit.  */
4803               if (code == SIGN_EXTRACT
4804                   && (val & ((unsigned HOST_WIDE_INT) 1 << (INTVAL (op1) - 1)))
4805                      != 0)
4806                 val |= ~ (((unsigned HOST_WIDE_INT) 1 << INTVAL (op1)) - 1);
4807             }
4808
4809           /* Clear the bits that don't belong in our mode,
4810              unless they and our sign bit are all one.
4811              So we get either a reasonable negative value or a reasonable
4812              unsigned value for this mode.  */
4813           if (width < HOST_BITS_PER_WIDE_INT
4814               && ((val & ((unsigned HOST_WIDE_INT) (-1) << (width - 1)))
4815                   != ((unsigned HOST_WIDE_INT) (-1) << (width - 1))))
4816             val &= ((unsigned HOST_WIDE_INT) 1 << width) - 1;
4817
4818           return gen_int_mode (val, mode);
4819         }
4820       break;
4821
4822     case IF_THEN_ELSE:
4823       if (CONST_INT_P (op0))
4824         return op0 != const0_rtx ? op1 : op2;
4825
4826       /* Convert c ? a : a into "a".  */
4827       if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
4828         return op1;
4829
4830       /* Convert a != b ? a : b into "a".  */
4831       if (GET_CODE (op0) == NE
4832           && ! side_effects_p (op0)
4833           && ! HONOR_NANS (mode)
4834           && ! HONOR_SIGNED_ZEROS (mode)
4835           && ((rtx_equal_p (XEXP (op0, 0), op1)
4836                && rtx_equal_p (XEXP (op0, 1), op2))
4837               || (rtx_equal_p (XEXP (op0, 0), op2)
4838                   && rtx_equal_p (XEXP (op0, 1), op1))))
4839         return op1;
4840
4841       /* Convert a == b ? a : b into "b".  */
4842       if (GET_CODE (op0) == EQ
4843           && ! side_effects_p (op0)
4844           && ! HONOR_NANS (mode)
4845           && ! HONOR_SIGNED_ZEROS (mode)
4846           && ((rtx_equal_p (XEXP (op0, 0), op1)
4847                && rtx_equal_p (XEXP (op0, 1), op2))
4848               || (rtx_equal_p (XEXP (op0, 0), op2)
4849                   && rtx_equal_p (XEXP (op0, 1), op1))))
4850         return op2;
4851
4852       if (COMPARISON_P (op0) && ! side_effects_p (op0))
4853         {
4854           enum machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
4855                                         ? GET_MODE (XEXP (op0, 1))
4856                                         : GET_MODE (XEXP (op0, 0)));
4857           rtx temp;
4858
4859           /* Look for happy constants in op1 and op2.  */
4860           if (CONST_INT_P (op1) && CONST_INT_P (op2))
4861             {
4862               HOST_WIDE_INT t = INTVAL (op1);
4863               HOST_WIDE_INT f = INTVAL (op2);
4864
4865               if (t == STORE_FLAG_VALUE && f == 0)
4866                 code = GET_CODE (op0);
4867               else if (t == 0 && f == STORE_FLAG_VALUE)
4868                 {
4869                   enum rtx_code tmp;
4870                   tmp = reversed_comparison_code (op0, NULL_RTX);
4871                   if (tmp == UNKNOWN)
4872                     break;
4873                   code = tmp;
4874                 }
4875               else
4876                 break;
4877
4878               return simplify_gen_relational (code, mode, cmp_mode,
4879                                               XEXP (op0, 0), XEXP (op0, 1));
4880             }
4881
4882           if (cmp_mode == VOIDmode)
4883             cmp_mode = op0_mode;
4884           temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
4885                                                 cmp_mode, XEXP (op0, 0),
4886                                                 XEXP (op0, 1));
4887
4888           /* See if any simplifications were possible.  */
4889           if (temp)
4890             {
4891               if (CONST_INT_P (temp))
4892                 return temp == const0_rtx ? op2 : op1;
4893               else if (temp)
4894                 return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
4895             }
4896         }
4897       break;
4898
4899     case VEC_MERGE:
4900       gcc_assert (GET_MODE (op0) == mode);
4901       gcc_assert (GET_MODE (op1) == mode);
4902       gcc_assert (VECTOR_MODE_P (mode));
4903       op2 = avoid_constant_pool_reference (op2);
4904       if (CONST_INT_P (op2))
4905         {
4906           int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
4907           unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
4908           int mask = (1 << n_elts) - 1;
4909
4910           if (!(INTVAL (op2) & mask))
4911             return op1;
4912           if ((INTVAL (op2) & mask) == mask)
4913             return op0;
4914
4915           op0 = avoid_constant_pool_reference (op0);
4916           op1 = avoid_constant_pool_reference (op1);
4917           if (GET_CODE (op0) == CONST_VECTOR
4918               && GET_CODE (op1) == CONST_VECTOR)
4919             {
4920               rtvec v = rtvec_alloc (n_elts);
4921               unsigned int i;
4922
4923               for (i = 0; i < n_elts; i++)
4924                 RTVEC_ELT (v, i) = (INTVAL (op2) & (1 << i)
4925                                     ? CONST_VECTOR_ELT (op0, i)
4926                                     : CONST_VECTOR_ELT (op1, i));
4927               return gen_rtx_CONST_VECTOR (mode, v);
4928             }
4929         }
4930       break;
4931
4932     default:
4933       gcc_unreachable ();
4934     }
4935
4936   return 0;
4937 }
4938
4939 /* Evaluate a SUBREG of a CONST_INT or CONST_DOUBLE or CONST_FIXED
4940    or CONST_VECTOR,
4941    returning another CONST_INT or CONST_DOUBLE or CONST_FIXED or CONST_VECTOR.
4942
4943    Works by unpacking OP into a collection of 8-bit values
4944    represented as a little-endian array of 'unsigned char', selecting by BYTE,
4945    and then repacking them again for OUTERMODE.  */
4946
4947 static rtx
4948 simplify_immed_subreg (enum machine_mode outermode, rtx op,
4949                        enum machine_mode innermode, unsigned int byte)
4950 {
4951   /* We support up to 512-bit values (for V8DFmode).  */
4952   enum {
4953     max_bitsize = 512,
4954     value_bit = 8,
4955     value_mask = (1 << value_bit) - 1
4956   };
4957   unsigned char value[max_bitsize / value_bit];
4958   int value_start;
4959   int i;
4960   int elem;
4961
4962   int num_elem;
4963   rtx * elems;
4964   int elem_bitsize;
4965   rtx result_s;
4966   rtvec result_v = NULL;
4967   enum mode_class outer_class;
4968   enum machine_mode outer_submode;
4969
4970   /* Some ports misuse CCmode.  */
4971   if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (op))
4972     return op;
4973
4974   /* We have no way to represent a complex constant at the rtl level.  */
4975   if (COMPLEX_MODE_P (outermode))
4976     return NULL_RTX;
4977
4978   /* Unpack the value.  */
4979
4980   if (GET_CODE (op) == CONST_VECTOR)
4981     {
4982       num_elem = CONST_VECTOR_NUNITS (op);
4983       elems = &CONST_VECTOR_ELT (op, 0);
4984       elem_bitsize = GET_MODE_BITSIZE (GET_MODE_INNER (innermode));
4985     }
4986   else
4987     {
4988       num_elem = 1;
4989       elems = &op;
4990       elem_bitsize = max_bitsize;
4991     }
4992   /* If this asserts, it is too complicated; reducing value_bit may help.  */
4993   gcc_assert (BITS_PER_UNIT % value_bit == 0);
4994   /* I don't know how to handle endianness of sub-units.  */
4995   gcc_assert (elem_bitsize % BITS_PER_UNIT == 0);
4996
4997   for (elem = 0; elem < num_elem; elem++)
4998     {
4999       unsigned char * vp;
5000       rtx el = elems[elem];
5001
5002       /* Vectors are kept in target memory order.  (This is probably
5003          a mistake.)  */
5004       {
5005         unsigned byte = (elem * elem_bitsize) / BITS_PER_UNIT;
5006         unsigned ibyte = (((num_elem - 1 - elem) * elem_bitsize)
5007                           / BITS_PER_UNIT);
5008         unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
5009         unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
5010         unsigned bytele = (subword_byte % UNITS_PER_WORD
5011                          + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
5012         vp = value + (bytele * BITS_PER_UNIT) / value_bit;
5013       }
5014
5015       switch (GET_CODE (el))
5016         {
5017         case CONST_INT:
5018           for (i = 0;
5019                i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
5020                i += value_bit)
5021             *vp++ = INTVAL (el) >> i;
5022           /* CONST_INTs are always logically sign-extended.  */
5023           for (; i < elem_bitsize; i += value_bit)
5024             *vp++ = INTVAL (el) < 0 ? -1 : 0;
5025           break;
5026
5027         case CONST_DOUBLE:
5028           if (GET_MODE (el) == VOIDmode)
5029             {
5030               /* If this triggers, someone should have generated a
5031                  CONST_INT instead.  */
5032               gcc_assert (elem_bitsize > HOST_BITS_PER_WIDE_INT);
5033
5034               for (i = 0; i < HOST_BITS_PER_WIDE_INT; i += value_bit)
5035                 *vp++ = CONST_DOUBLE_LOW (el) >> i;
5036               while (i < HOST_BITS_PER_WIDE_INT * 2 && i < elem_bitsize)
5037                 {
5038                   *vp++
5039                     = CONST_DOUBLE_HIGH (el) >> (i - HOST_BITS_PER_WIDE_INT);
5040                   i += value_bit;
5041                 }
5042               /* It shouldn't matter what's done here, so fill it with
5043                  zero.  */
5044               for (; i < elem_bitsize; i += value_bit)
5045                 *vp++ = 0;
5046             }
5047           else
5048             {
5049               long tmp[max_bitsize / 32];
5050               int bitsize = GET_MODE_BITSIZE (GET_MODE (el));
5051
5052               gcc_assert (SCALAR_FLOAT_MODE_P (GET_MODE (el)));
5053               gcc_assert (bitsize <= elem_bitsize);
5054               gcc_assert (bitsize % value_bit == 0);
5055
5056               real_to_target (tmp, CONST_DOUBLE_REAL_VALUE (el),
5057                               GET_MODE (el));
5058
5059               /* real_to_target produces its result in words affected by
5060                  FLOAT_WORDS_BIG_ENDIAN.  However, we ignore this,
5061                  and use WORDS_BIG_ENDIAN instead; see the documentation
5062                  of SUBREG in rtl.texi.  */
5063               for (i = 0; i < bitsize; i += value_bit)
5064                 {
5065                   int ibase;
5066                   if (WORDS_BIG_ENDIAN)
5067                     ibase = bitsize - 1 - i;
5068                   else
5069                     ibase = i;
5070                   *vp++ = tmp[ibase / 32] >> i % 32;
5071                 }
5072
5073               /* It shouldn't matter what's done here, so fill it with
5074                  zero.  */
5075               for (; i < elem_bitsize; i += value_bit)
5076                 *vp++ = 0;
5077             }
5078           break;
5079
5080         case CONST_FIXED:
5081           if (elem_bitsize <= HOST_BITS_PER_WIDE_INT)
5082             {
5083               for (i = 0; i < elem_bitsize; i += value_bit)
5084                 *vp++ = CONST_FIXED_VALUE_LOW (el) >> i;
5085             }
5086           else
5087             {
5088               for (i = 0; i < HOST_BITS_PER_WIDE_INT; i += value_bit)
5089                 *vp++ = CONST_FIXED_VALUE_LOW (el) >> i;
5090               for (; i < 2 * HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
5091                    i += value_bit)
5092                 *vp++ = CONST_FIXED_VALUE_HIGH (el)
5093                         >> (i - HOST_BITS_PER_WIDE_INT);
5094               for (; i < elem_bitsize; i += value_bit)
5095                 *vp++ = 0;
5096             }
5097           break;
5098
5099         default:
5100           gcc_unreachable ();
5101         }
5102     }
5103
5104   /* Now, pick the right byte to start with.  */
5105   /* Renumber BYTE so that the least-significant byte is byte 0.  A special
5106      case is paradoxical SUBREGs, which shouldn't be adjusted since they
5107      will already have offset 0.  */
5108   if (GET_MODE_SIZE (innermode) >= GET_MODE_SIZE (outermode))
5109     {
5110       unsigned ibyte = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode)
5111                         - byte);
5112       unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
5113       unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
5114       byte = (subword_byte % UNITS_PER_WORD
5115               + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
5116     }
5117
5118   /* BYTE should still be inside OP.  (Note that BYTE is unsigned,
5119      so if it's become negative it will instead be very large.)  */
5120   gcc_assert (byte < GET_MODE_SIZE (innermode));
5121
5122   /* Convert from bytes to chunks of size value_bit.  */
5123   value_start = byte * (BITS_PER_UNIT / value_bit);
5124
5125   /* Re-pack the value.  */
5126
5127   if (VECTOR_MODE_P (outermode))
5128     {
5129       num_elem = GET_MODE_NUNITS (outermode);
5130       result_v = rtvec_alloc (num_elem);
5131       elems = &RTVEC_ELT (result_v, 0);
5132       outer_submode = GET_MODE_INNER (outermode);
5133     }
5134   else
5135     {
5136       num_elem = 1;
5137       elems = &result_s;
5138       outer_submode = outermode;
5139     }
5140
5141   outer_class = GET_MODE_CLASS (outer_submode);
5142   elem_bitsize = GET_MODE_BITSIZE (outer_submode);
5143
5144   gcc_assert (elem_bitsize % value_bit == 0);
5145   gcc_assert (elem_bitsize + value_start * value_bit <= max_bitsize);
5146
5147   for (elem = 0; elem < num_elem; elem++)
5148     {
5149       unsigned char *vp;
5150
5151       /* Vectors are stored in target memory order.  (This is probably
5152          a mistake.)  */
5153       {
5154         unsigned byte = (elem * elem_bitsize) / BITS_PER_UNIT;
5155         unsigned ibyte = (((num_elem - 1 - elem) * elem_bitsize)
5156                           / BITS_PER_UNIT);
5157         unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
5158         unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
5159         unsigned bytele = (subword_byte % UNITS_PER_WORD
5160                          + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
5161         vp = value + value_start + (bytele * BITS_PER_UNIT) / value_bit;
5162       }
5163
5164       switch (outer_class)
5165         {
5166         case MODE_INT:
5167         case MODE_PARTIAL_INT:
5168           {
5169             unsigned HOST_WIDE_INT hi = 0, lo = 0;
5170
5171             for (i = 0;
5172                  i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
5173                  i += value_bit)
5174               lo |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask) << i;
5175             for (; i < elem_bitsize; i += value_bit)
5176               hi |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask)
5177                      << (i - HOST_BITS_PER_WIDE_INT);
5178
5179             /* immed_double_const doesn't call trunc_int_for_mode.  I don't
5180                know why.  */
5181             if (elem_bitsize <= HOST_BITS_PER_WIDE_INT)
5182               elems[elem] = gen_int_mode (lo, outer_submode);
5183             else if (elem_bitsize <= 2 * HOST_BITS_PER_WIDE_INT)
5184               elems[elem] = immed_double_const (lo, hi, outer_submode);
5185             else
5186               return NULL_RTX;
5187           }
5188           break;
5189
5190         case MODE_FLOAT:
5191         case MODE_DECIMAL_FLOAT:
5192           {
5193             REAL_VALUE_TYPE r;
5194             long tmp[max_bitsize / 32];
5195
5196             /* real_from_target wants its input in words affected by
5197                FLOAT_WORDS_BIG_ENDIAN.  However, we ignore this,
5198                and use WORDS_BIG_ENDIAN instead; see the documentation
5199                of SUBREG in rtl.texi.  */
5200             for (i = 0; i < max_bitsize / 32; i++)
5201               tmp[i] = 0;
5202             for (i = 0; i < elem_bitsize; i += value_bit)
5203               {
5204                 int ibase;
5205                 if (WORDS_BIG_ENDIAN)
5206                   ibase = elem_bitsize - 1 - i;
5207                 else
5208                   ibase = i;
5209                 tmp[ibase / 32] |= (*vp++ & value_mask) << i % 32;
5210               }
5211
5212             real_from_target (&r, tmp, outer_submode);
5213             elems[elem] = CONST_DOUBLE_FROM_REAL_VALUE (r, outer_submode);
5214           }
5215           break;
5216
5217         case MODE_FRACT:
5218         case MODE_UFRACT:
5219         case MODE_ACCUM:
5220         case MODE_UACCUM:
5221           {
5222             FIXED_VALUE_TYPE f;
5223             f.data.low = 0;
5224             f.data.high = 0;
5225             f.mode = outer_submode;
5226
5227             for (i = 0;
5228                  i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
5229                  i += value_bit)
5230               f.data.low |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask) << i;
5231             for (; i < elem_bitsize; i += value_bit)
5232               f.data.high |= ((unsigned HOST_WIDE_INT)(*vp++ & value_mask)
5233                              << (i - HOST_BITS_PER_WIDE_INT));
5234
5235             elems[elem] = CONST_FIXED_FROM_FIXED_VALUE (f, outer_submode);
5236           }
5237           break;
5238
5239         default:
5240           gcc_unreachable ();
5241         }
5242     }
5243   if (VECTOR_MODE_P (outermode))
5244     return gen_rtx_CONST_VECTOR (outermode, result_v);
5245   else
5246     return result_s;
5247 }
5248
5249 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
5250    Return 0 if no simplifications are possible.  */
5251 rtx
5252 simplify_subreg (enum machine_mode outermode, rtx op,
5253                  enum machine_mode innermode, unsigned int byte)
5254 {
5255   /* Little bit of sanity checking.  */
5256   gcc_assert (innermode != VOIDmode);
5257   gcc_assert (outermode != VOIDmode);
5258   gcc_assert (innermode != BLKmode);
5259   gcc_assert (outermode != BLKmode);
5260
5261   gcc_assert (GET_MODE (op) == innermode
5262               || GET_MODE (op) == VOIDmode);
5263
5264   gcc_assert ((byte % GET_MODE_SIZE (outermode)) == 0);
5265   gcc_assert (byte < GET_MODE_SIZE (innermode));
5266
5267   if (outermode == innermode && !byte)
5268     return op;
5269
5270   if (CONST_INT_P (op)
5271       || GET_CODE (op) == CONST_DOUBLE
5272       || GET_CODE (op) == CONST_FIXED
5273       || GET_CODE (op) == CONST_VECTOR)
5274     return simplify_immed_subreg (outermode, op, innermode, byte);
5275
5276   /* Changing mode twice with SUBREG => just change it once,
5277      or not at all if changing back op starting mode.  */
5278   if (GET_CODE (op) == SUBREG)
5279     {
5280       enum machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
5281       int final_offset = byte + SUBREG_BYTE (op);
5282       rtx newx;
5283
5284       if (outermode == innermostmode
5285           && byte == 0 && SUBREG_BYTE (op) == 0)
5286         return SUBREG_REG (op);
5287
5288       /* The SUBREG_BYTE represents offset, as if the value were stored
5289          in memory.  Irritating exception is paradoxical subreg, where
5290          we define SUBREG_BYTE to be 0.  On big endian machines, this
5291          value should be negative.  For a moment, undo this exception.  */
5292       if (byte == 0 && GET_MODE_SIZE (innermode) < GET_MODE_SIZE (outermode))
5293         {
5294           int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
5295           if (WORDS_BIG_ENDIAN)
5296             final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
5297           if (BYTES_BIG_ENDIAN)
5298             final_offset += difference % UNITS_PER_WORD;
5299         }
5300       if (SUBREG_BYTE (op) == 0
5301           && GET_MODE_SIZE (innermostmode) < GET_MODE_SIZE (innermode))
5302         {
5303           int difference = (GET_MODE_SIZE (innermostmode) - GET_MODE_SIZE (innermode));
5304           if (WORDS_BIG_ENDIAN)
5305             final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
5306           if (BYTES_BIG_ENDIAN)
5307             final_offset += difference % UNITS_PER_WORD;
5308         }
5309
5310       /* See whether resulting subreg will be paradoxical.  */
5311       if (GET_MODE_SIZE (innermostmode) > GET_MODE_SIZE (outermode))
5312         {
5313           /* In nonparadoxical subregs we can't handle negative offsets.  */
5314           if (final_offset < 0)
5315             return NULL_RTX;
5316           /* Bail out in case resulting subreg would be incorrect.  */
5317           if (final_offset % GET_MODE_SIZE (outermode)
5318               || (unsigned) final_offset >= GET_MODE_SIZE (innermostmode))
5319             return NULL_RTX;
5320         }
5321       else
5322         {
5323           int offset = 0;
5324           int difference = (GET_MODE_SIZE (innermostmode) - GET_MODE_SIZE (outermode));
5325
5326           /* In paradoxical subreg, see if we are still looking on lower part.
5327              If so, our SUBREG_BYTE will be 0.  */
5328           if (WORDS_BIG_ENDIAN)
5329             offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
5330           if (BYTES_BIG_ENDIAN)
5331             offset += difference % UNITS_PER_WORD;
5332           if (offset == final_offset)
5333             final_offset = 0;
5334           else
5335             return NULL_RTX;
5336         }
5337
5338       /* Recurse for further possible simplifications.  */
5339       newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
5340                               final_offset);
5341       if (newx)
5342         return newx;
5343       if (validate_subreg (outermode, innermostmode,
5344                            SUBREG_REG (op), final_offset))
5345         {
5346           newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
5347           if (SUBREG_PROMOTED_VAR_P (op)
5348               && SUBREG_PROMOTED_UNSIGNED_P (op) >= 0
5349               && GET_MODE_CLASS (outermode) == MODE_INT
5350               && IN_RANGE (GET_MODE_SIZE (outermode),
5351                            GET_MODE_SIZE (innermode),
5352                            GET_MODE_SIZE (innermostmode))
5353               && subreg_lowpart_p (newx))
5354             {
5355               SUBREG_PROMOTED_VAR_P (newx) = 1;
5356               SUBREG_PROMOTED_UNSIGNED_SET
5357                 (newx, SUBREG_PROMOTED_UNSIGNED_P (op));
5358             }
5359           return newx;
5360         }
5361       return NULL_RTX;
5362     }
5363
5364   /* Merge implicit and explicit truncations.  */
5365
5366   if (GET_CODE (op) == TRUNCATE
5367       && GET_MODE_SIZE (outermode) < GET_MODE_SIZE (innermode)
5368       && subreg_lowpart_offset (outermode, innermode) == byte)
5369     return simplify_gen_unary (TRUNCATE, outermode, XEXP (op, 0),
5370                                GET_MODE (XEXP (op, 0)));
5371
5372   /* SUBREG of a hard register => just change the register number
5373      and/or mode.  If the hard register is not valid in that mode,
5374      suppress this simplification.  If the hard register is the stack,
5375      frame, or argument pointer, leave this as a SUBREG.  */
5376
5377   if (REG_P (op) && HARD_REGISTER_P (op))
5378     {
5379       unsigned int regno, final_regno;
5380
5381       regno = REGNO (op);
5382       final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
5383       if (HARD_REGISTER_NUM_P (final_regno))
5384         {
5385           rtx x;
5386           int final_offset = byte;
5387
5388           /* Adjust offset for paradoxical subregs.  */
5389           if (byte == 0
5390               && GET_MODE_SIZE (innermode) < GET_MODE_SIZE (outermode))
5391             {
5392               int difference = (GET_MODE_SIZE (innermode)
5393                                 - GET_MODE_SIZE (outermode));
5394               if (WORDS_BIG_ENDIAN)
5395                 final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
5396               if (BYTES_BIG_ENDIAN)
5397                 final_offset += difference % UNITS_PER_WORD;
5398             }
5399
5400           x = gen_rtx_REG_offset (op, outermode, final_regno, final_offset);
5401
5402           /* Propagate original regno.  We don't have any way to specify
5403              the offset inside original regno, so do so only for lowpart.
5404              The information is used only by alias analysis that can not
5405              grog partial register anyway.  */
5406
5407           if (subreg_lowpart_offset (outermode, innermode) == byte)
5408             ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
5409           return x;
5410         }
5411     }
5412
5413   /* If we have a SUBREG of a register that we are replacing and we are
5414      replacing it with a MEM, make a new MEM and try replacing the
5415      SUBREG with it.  Don't do this if the MEM has a mode-dependent address
5416      or if we would be widening it.  */
5417
5418   if (MEM_P (op)
5419       && ! mode_dependent_address_p (XEXP (op, 0))
5420       /* Allow splitting of volatile memory references in case we don't
5421          have instruction to move the whole thing.  */
5422       && (! MEM_VOLATILE_P (op)
5423           || ! have_insn_for (SET, innermode))
5424       && GET_MODE_SIZE (outermode) <= GET_MODE_SIZE (GET_MODE (op)))
5425     return adjust_address_nv (op, outermode, byte);
5426
5427   /* Handle complex values represented as CONCAT
5428      of real and imaginary part.  */
5429   if (GET_CODE (op) == CONCAT)
5430     {
5431       unsigned int part_size, final_offset;
5432       rtx part, res;
5433
5434       part_size = GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)));
5435       if (byte < part_size)
5436         {
5437           part = XEXP (op, 0);
5438           final_offset = byte;
5439         }
5440       else
5441         {
5442           part = XEXP (op, 1);
5443           final_offset = byte - part_size;
5444         }
5445
5446       if (final_offset + GET_MODE_SIZE (outermode) > part_size)
5447         return NULL_RTX;
5448
5449       res = simplify_subreg (outermode, part, GET_MODE (part), final_offset);
5450       if (res)
5451         return res;
5452       if (validate_subreg (outermode, GET_MODE (part), part, final_offset))
5453         return gen_rtx_SUBREG (outermode, part, final_offset);
5454       return NULL_RTX;
5455     }
5456
5457   /* Optimize SUBREG truncations of zero and sign extended values.  */
5458   if ((GET_CODE (op) == ZERO_EXTEND
5459        || GET_CODE (op) == SIGN_EXTEND)
5460       && GET_MODE_BITSIZE (outermode) < GET_MODE_BITSIZE (innermode))
5461     {
5462       unsigned int bitpos = subreg_lsb_1 (outermode, innermode, byte);
5463
5464       /* If we're requesting the lowpart of a zero or sign extension,
5465          there are three possibilities.  If the outermode is the same
5466          as the origmode, we can omit both the extension and the subreg.
5467          If the outermode is not larger than the origmode, we can apply
5468          the truncation without the extension.  Finally, if the outermode
5469          is larger than the origmode, but both are integer modes, we
5470          can just extend to the appropriate mode.  */
5471       if (bitpos == 0)
5472         {
5473           enum machine_mode origmode = GET_MODE (XEXP (op, 0));
5474           if (outermode == origmode)
5475             return XEXP (op, 0);
5476           if (GET_MODE_BITSIZE (outermode) <= GET_MODE_BITSIZE (origmode))
5477             return simplify_gen_subreg (outermode, XEXP (op, 0), origmode,
5478                                         subreg_lowpart_offset (outermode,
5479                                                                origmode));
5480           if (SCALAR_INT_MODE_P (outermode))
5481             return simplify_gen_unary (GET_CODE (op), outermode,
5482                                        XEXP (op, 0), origmode);
5483         }
5484
5485       /* A SUBREG resulting from a zero extension may fold to zero if
5486          it extracts higher bits that the ZERO_EXTEND's source bits.  */
5487       if (GET_CODE (op) == ZERO_EXTEND
5488           && bitpos >= GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))))
5489         return CONST0_RTX (outermode);
5490     }
5491
5492   /* Simplify (subreg:QI (lshiftrt:SI (sign_extend:SI (x:QI)) C), 0) into
5493      to (ashiftrt:QI (x:QI) C), where C is a suitable small constant and
5494      the outer subreg is effectively a truncation to the original mode.  */
5495   if ((GET_CODE (op) == LSHIFTRT
5496        || GET_CODE (op) == ASHIFTRT)
5497       && SCALAR_INT_MODE_P (outermode)
5498       /* Ensure that OUTERMODE is at least twice as wide as the INNERMODE
5499          to avoid the possibility that an outer LSHIFTRT shifts by more
5500          than the sign extension's sign_bit_copies and introduces zeros
5501          into the high bits of the result.  */
5502       && (2 * GET_MODE_BITSIZE (outermode)) <= GET_MODE_BITSIZE (innermode)
5503       && CONST_INT_P (XEXP (op, 1))
5504       && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
5505       && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
5506       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (outermode)
5507       && subreg_lsb_1 (outermode, innermode, byte) == 0)
5508     return simplify_gen_binary (ASHIFTRT, outermode,
5509                                 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
5510
5511   /* Likewise (subreg:QI (lshiftrt:SI (zero_extend:SI (x:QI)) C), 0) into
5512      to (lshiftrt:QI (x:QI) C), where C is a suitable small constant and
5513      the outer subreg is effectively a truncation to the original mode.  */
5514   if ((GET_CODE (op) == LSHIFTRT
5515        || GET_CODE (op) == ASHIFTRT)
5516       && SCALAR_INT_MODE_P (outermode)
5517       && GET_MODE_BITSIZE (outermode) < GET_MODE_BITSIZE (innermode)
5518       && CONST_INT_P (XEXP (op, 1))
5519       && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
5520       && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
5521       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (outermode)
5522       && subreg_lsb_1 (outermode, innermode, byte) == 0)
5523     return simplify_gen_binary (LSHIFTRT, outermode,
5524                                 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
5525
5526   /* Likewise (subreg:QI (ashift:SI (zero_extend:SI (x:QI)) C), 0) into
5527      to (ashift:QI (x:QI) C), where C is a suitable small constant and
5528      the outer subreg is effectively a truncation to the original mode.  */
5529   if (GET_CODE (op) == ASHIFT
5530       && SCALAR_INT_MODE_P (outermode)
5531       && GET_MODE_BITSIZE (outermode) < GET_MODE_BITSIZE (innermode)
5532       && CONST_INT_P (XEXP (op, 1))
5533       && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
5534           || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
5535       && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
5536       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (outermode)
5537       && subreg_lsb_1 (outermode, innermode, byte) == 0)
5538     return simplify_gen_binary (ASHIFT, outermode,
5539                                 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
5540
5541   /* Recognize a word extraction from a multi-word subreg.  */
5542   if ((GET_CODE (op) == LSHIFTRT
5543        || GET_CODE (op) == ASHIFTRT)
5544       && SCALAR_INT_MODE_P (outermode)
5545       && GET_MODE_BITSIZE (outermode) >= BITS_PER_WORD
5546       && GET_MODE_BITSIZE (innermode) >= (2 * GET_MODE_BITSIZE (outermode))
5547       && CONST_INT_P (XEXP (op, 1))
5548       && (INTVAL (XEXP (op, 1)) & (GET_MODE_BITSIZE (outermode) - 1)) == 0
5549       && INTVAL (XEXP (op, 1)) >= 0
5550       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (innermode)
5551       && byte == subreg_lowpart_offset (outermode, innermode))
5552     {
5553       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
5554       return simplify_gen_subreg (outermode, XEXP (op, 0), innermode,
5555                                   (WORDS_BIG_ENDIAN
5556                                    ? byte - shifted_bytes
5557                                    : byte + shifted_bytes));
5558     }
5559
5560   /* If we have a lowpart SUBREG of a right shift of MEM, make a new MEM
5561      and try replacing the SUBREG and shift with it.  Don't do this if
5562      the MEM has a mode-dependent address or if we would be widening it.  */
5563
5564   if ((GET_CODE (op) == LSHIFTRT
5565        || GET_CODE (op) == ASHIFTRT)
5566       && MEM_P (XEXP (op, 0))
5567       && CONST_INT_P (XEXP (op, 1))
5568       && GET_MODE_SIZE (outermode) < GET_MODE_SIZE (GET_MODE (op))
5569       && (INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (outermode)) == 0
5570       && INTVAL (XEXP (op, 1)) > 0
5571       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (innermode)
5572       && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0))
5573       && ! MEM_VOLATILE_P (XEXP (op, 0))
5574       && byte == subreg_lowpart_offset (outermode, innermode)
5575       && (GET_MODE_SIZE (outermode) >= UNITS_PER_WORD
5576           || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
5577     {
5578       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
5579       return adjust_address_nv (XEXP (op, 0), outermode,
5580                                 (WORDS_BIG_ENDIAN
5581                                  ? byte - shifted_bytes
5582                                  : byte + shifted_bytes));
5583     }
5584
5585   return NULL_RTX;
5586 }
5587
5588 /* Make a SUBREG operation or equivalent if it folds.  */
5589
5590 rtx
5591 simplify_gen_subreg (enum machine_mode outermode, rtx op,
5592                      enum machine_mode innermode, unsigned int byte)
5593 {
5594   rtx newx;
5595
5596   newx = simplify_subreg (outermode, op, innermode, byte);
5597   if (newx)
5598     return newx;
5599
5600   if (GET_CODE (op) == SUBREG
5601       || GET_CODE (op) == CONCAT
5602       || GET_MODE (op) == VOIDmode)
5603     return NULL_RTX;
5604
5605   if (validate_subreg (outermode, innermode, op, byte))
5606     return gen_rtx_SUBREG (outermode, op, byte);
5607
5608   return NULL_RTX;
5609 }
5610
5611 /* Simplify X, an rtx expression.
5612
5613    Return the simplified expression or NULL if no simplifications
5614    were possible.
5615
5616    This is the preferred entry point into the simplification routines;
5617    however, we still allow passes to call the more specific routines.
5618
5619    Right now GCC has three (yes, three) major bodies of RTL simplification
5620    code that need to be unified.
5621
5622         1. fold_rtx in cse.c.  This code uses various CSE specific
5623            information to aid in RTL simplification.
5624
5625         2. simplify_rtx in combine.c.  Similar to fold_rtx, except that
5626            it uses combine specific information to aid in RTL
5627            simplification.
5628
5629         3. The routines in this file.
5630
5631
5632    Long term we want to only have one body of simplification code; to
5633    get to that state I recommend the following steps:
5634
5635         1. Pour over fold_rtx & simplify_rtx and move any simplifications
5636            which are not pass dependent state into these routines.
5637
5638         2. As code is moved by #1, change fold_rtx & simplify_rtx to
5639            use this routine whenever possible.
5640
5641         3. Allow for pass dependent state to be provided to these
5642            routines and add simplifications based on the pass dependent
5643            state.  Remove code from cse.c & combine.c that becomes
5644            redundant/dead.
5645
5646     It will take time, but ultimately the compiler will be easier to
5647     maintain and improve.  It's totally silly that when we add a
5648     simplification that it needs to be added to 4 places (3 for RTL
5649     simplification and 1 for tree simplification.  */
5650
5651 rtx
5652 simplify_rtx (const_rtx x)
5653 {
5654   const enum rtx_code code = GET_CODE (x);
5655   const enum machine_mode mode = GET_MODE (x);
5656
5657   switch (GET_RTX_CLASS (code))
5658     {
5659     case RTX_UNARY:
5660       return simplify_unary_operation (code, mode,
5661                                        XEXP (x, 0), GET_MODE (XEXP (x, 0)));
5662     case RTX_COMM_ARITH:
5663       if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
5664         return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
5665
5666       /* Fall through....  */
5667
5668     case RTX_BIN_ARITH:
5669       return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
5670
5671     case RTX_TERNARY:
5672     case RTX_BITFIELD_OPS:
5673       return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
5674                                          XEXP (x, 0), XEXP (x, 1),
5675                                          XEXP (x, 2));
5676
5677     case RTX_COMPARE:
5678     case RTX_COMM_COMPARE:
5679       return simplify_relational_operation (code, mode,
5680                                             ((GET_MODE (XEXP (x, 0))
5681                                              != VOIDmode)
5682                                             ? GET_MODE (XEXP (x, 0))
5683                                             : GET_MODE (XEXP (x, 1))),
5684                                             XEXP (x, 0),
5685                                             XEXP (x, 1));
5686
5687     case RTX_EXTRA:
5688       if (code == SUBREG)
5689         return simplify_subreg (mode, SUBREG_REG (x),
5690                                 GET_MODE (SUBREG_REG (x)),
5691                                 SUBREG_BYTE (x));
5692       break;
5693
5694     case RTX_OBJ:
5695       if (code == LO_SUM)
5696         {
5697           /* Convert (lo_sum (high FOO) FOO) to FOO.  */
5698           if (GET_CODE (XEXP (x, 0)) == HIGH
5699               && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
5700           return XEXP (x, 1);
5701         }
5702       break;
5703
5704     default:
5705       break;
5706     }
5707   return NULL;
5708 }