OSDN Git Service

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