OSDN Git Service

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