OSDN Git Service

gcc/ChangeLog:
[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   if (MEM_P (x)
212       && MEM_EXPR (x)
213       && (!MEM_OFFSET (x)
214           || GET_CODE (MEM_OFFSET (x)) == CONST_INT))
215     {
216       tree decl = MEM_EXPR (x);
217       enum machine_mode mode = GET_MODE (x);
218       HOST_WIDE_INT offset = 0;
219
220       switch (TREE_CODE (decl))
221         {
222         default:
223           decl = NULL;
224           break;
225
226         case VAR_DECL:
227           break;
228
229         case ARRAY_REF:
230         case ARRAY_RANGE_REF:
231         case COMPONENT_REF:
232         case BIT_FIELD_REF:
233         case REALPART_EXPR:
234         case IMAGPART_EXPR:
235         case VIEW_CONVERT_EXPR:
236           {
237             HOST_WIDE_INT bitsize, bitpos;
238             tree toffset;
239             int unsignedp = 0, volatilep = 0;
240
241             decl = get_inner_reference (decl, &bitsize, &bitpos, &toffset,
242                                         &mode, &unsignedp, &volatilep, false);
243             if (bitsize != GET_MODE_BITSIZE (mode)
244                 || (bitpos % BITS_PER_UNIT)
245                 || (toffset && !host_integerp (toffset, 0)))
246               decl = NULL;
247             else
248               {
249                 offset += bitpos / BITS_PER_UNIT;
250                 if (toffset)
251                   offset += TREE_INT_CST_LOW (toffset);
252               }
253             break;
254           }
255         }
256
257       if (decl
258           && mode == GET_MODE (x)
259           && TREE_CODE (decl) == VAR_DECL
260           && (TREE_STATIC (decl)
261               || DECL_THREAD_LOCAL_P (decl))
262           && DECL_RTL_SET_P (decl)
263           && MEM_P (DECL_RTL (decl)))
264         {
265           rtx newx;
266
267           if (MEM_OFFSET (x))
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)