OSDN Git Service

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