Upgrade GCC from 4.4.2 to 4.4.5 on the vendor branch.
[dragonfly.git] / contrib / gcc-4.4 / gcc / simplify-rtx.c
1 /* RTL simplification functions for GNU compiler.
2    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4    Free Software Foundation, Inc.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "tm_p.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "flags.h"
33 #include "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           && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
2013           && GET_MODE (op0) == mode)
2014         {
2015           REAL_VALUE_TYPE d;
2016           REAL_VALUE_FROM_CONST_DOUBLE (d, trueop1);
2017
2018           if (REAL_VALUES_EQUAL (d, dconst2))
2019             return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
2020
2021           if (!HONOR_SNANS (mode)
2022               && REAL_VALUES_EQUAL (d, dconstm1))
2023             return simplify_gen_unary (NEG, mode, op0, mode);
2024         }
2025
2026       /* Optimize -x * -x as x * x.  */
2027       if (FLOAT_MODE_P (mode)
2028           && GET_CODE (op0) == NEG
2029           && GET_CODE (op1) == NEG
2030           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2031           && !side_effects_p (XEXP (op0, 0)))
2032         return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
2033
2034       /* Likewise, optimize abs(x) * abs(x) as x * x.  */
2035       if (SCALAR_FLOAT_MODE_P (mode)
2036           && GET_CODE (op0) == ABS
2037           && GET_CODE (op1) == ABS
2038           && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2039           && !side_effects_p (XEXP (op0, 0)))
2040         return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
2041
2042       /* Reassociate multiplication, but for floating point MULTs
2043          only when the user specifies unsafe math optimizations.  */
2044       if (! FLOAT_MODE_P (mode)
2045           || flag_unsafe_math_optimizations)
2046         {
2047           tem = simplify_associative_operation (code, mode, op0, op1);
2048           if (tem)
2049             return tem;
2050         }
2051       break;
2052
2053     case IOR:
2054       if (trueop1 == const0_rtx)
2055         return op0;
2056       if (GET_CODE (trueop1) == CONST_INT
2057           && ((INTVAL (trueop1) & GET_MODE_MASK (mode))
2058               == GET_MODE_MASK (mode)))
2059         return op1;
2060       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2061         return op0;
2062       /* A | (~A) -> -1 */
2063       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
2064            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
2065           && ! side_effects_p (op0)
2066           && SCALAR_INT_MODE_P (mode))
2067         return constm1_rtx;
2068
2069       /* (ior A C) is C if all bits of A that might be nonzero are on in C.  */
2070       if (GET_CODE (op1) == CONST_INT
2071           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2072           && (nonzero_bits (op0, mode) & ~INTVAL (op1)) == 0)
2073         return op1;
2074  
2075       /* Canonicalize (X & C1) | C2.  */
2076       if (GET_CODE (op0) == AND
2077           && GET_CODE (trueop1) == CONST_INT
2078           && GET_CODE (XEXP (op0, 1)) == CONST_INT)
2079         {
2080           HOST_WIDE_INT mask = GET_MODE_MASK (mode);
2081           HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
2082           HOST_WIDE_INT c2 = INTVAL (trueop1);
2083
2084           /* If (C1&C2) == C1, then (X&C1)|C2 becomes X.  */
2085           if ((c1 & c2) == c1
2086               && !side_effects_p (XEXP (op0, 0)))
2087             return trueop1;
2088
2089           /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2.  */
2090           if (((c1|c2) & mask) == mask)
2091             return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
2092
2093           /* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2.  */
2094           if (((c1 & ~c2) & mask) != (c1 & mask))
2095             {
2096               tem = simplify_gen_binary (AND, mode, XEXP (op0, 0),
2097                                          gen_int_mode (c1 & ~c2, mode));
2098               return simplify_gen_binary (IOR, mode, tem, op1);
2099             }
2100         }
2101
2102       /* Convert (A & B) | A to A.  */
2103       if (GET_CODE (op0) == AND
2104           && (rtx_equal_p (XEXP (op0, 0), op1)
2105               || rtx_equal_p (XEXP (op0, 1), op1))
2106           && ! side_effects_p (XEXP (op0, 0))
2107           && ! side_effects_p (XEXP (op0, 1)))
2108         return op1;
2109
2110       /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
2111          mode size to (rotate A CX).  */
2112
2113       if (GET_CODE (op1) == ASHIFT
2114           || GET_CODE (op1) == SUBREG)
2115         {
2116           opleft = op1;
2117           opright = op0;
2118         }
2119       else
2120         {
2121           opright = op1;
2122           opleft = op0;
2123         }
2124
2125       if (GET_CODE (opleft) == ASHIFT && GET_CODE (opright) == LSHIFTRT
2126           && rtx_equal_p (XEXP (opleft, 0), XEXP (opright, 0))
2127           && GET_CODE (XEXP (opleft, 1)) == CONST_INT
2128           && GET_CODE (XEXP (opright, 1)) == CONST_INT
2129           && (INTVAL (XEXP (opleft, 1)) + INTVAL (XEXP (opright, 1))
2130               == GET_MODE_BITSIZE (mode)))
2131         return gen_rtx_ROTATE (mode, XEXP (opright, 0), XEXP (opleft, 1));
2132
2133       /* Same, but for ashift that has been "simplified" to a wider mode
2134         by simplify_shift_const.  */
2135
2136       if (GET_CODE (opleft) == SUBREG
2137           && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
2138           && GET_CODE (opright) == LSHIFTRT
2139           && GET_CODE (XEXP (opright, 0)) == SUBREG
2140           && GET_MODE (opleft) == GET_MODE (XEXP (opright, 0))
2141           && SUBREG_BYTE (opleft) == SUBREG_BYTE (XEXP (opright, 0))
2142           && (GET_MODE_SIZE (GET_MODE (opleft))
2143               < GET_MODE_SIZE (GET_MODE (SUBREG_REG (opleft))))
2144           && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
2145                           SUBREG_REG (XEXP (opright, 0)))
2146           && GET_CODE (XEXP (SUBREG_REG (opleft), 1)) == CONST_INT
2147           && GET_CODE (XEXP (opright, 1)) == CONST_INT
2148           && (INTVAL (XEXP (SUBREG_REG (opleft), 1)) + INTVAL (XEXP (opright, 1))
2149               == GET_MODE_BITSIZE (mode)))
2150         return gen_rtx_ROTATE (mode, XEXP (opright, 0),
2151                                XEXP (SUBREG_REG (opleft), 1));
2152
2153       /* If we have (ior (and (X C1) C2)), simplify this by making
2154          C1 as small as possible if C1 actually changes.  */
2155       if (GET_CODE (op1) == CONST_INT
2156           && (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2157               || INTVAL (op1) > 0)
2158           && GET_CODE (op0) == AND
2159           && GET_CODE (XEXP (op0, 1)) == CONST_INT
2160           && GET_CODE (op1) == CONST_INT
2161           && (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) != 0)
2162         return simplify_gen_binary (IOR, mode,
2163                                     simplify_gen_binary
2164                                           (AND, mode, XEXP (op0, 0),
2165                                            GEN_INT (INTVAL (XEXP (op0, 1))
2166                                                     & ~INTVAL (op1))),
2167                                     op1);
2168
2169       /* If OP0 is (ashiftrt (plus ...) C), it might actually be
2170          a (sign_extend (plus ...)).  Then check if OP1 is a CONST_INT and
2171          the PLUS does not affect any of the bits in OP1: then we can do
2172          the IOR as a PLUS and we can associate.  This is valid if OP1
2173          can be safely shifted left C bits.  */
2174       if (GET_CODE (trueop1) == CONST_INT && GET_CODE (op0) == ASHIFTRT
2175           && GET_CODE (XEXP (op0, 0)) == PLUS
2176           && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
2177           && GET_CODE (XEXP (op0, 1)) == CONST_INT
2178           && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
2179         {
2180           int count = INTVAL (XEXP (op0, 1));
2181           HOST_WIDE_INT mask = INTVAL (trueop1) << count;
2182
2183           if (mask >> count == INTVAL (trueop1)
2184               && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
2185             return simplify_gen_binary (ASHIFTRT, mode,
2186                                         plus_constant (XEXP (op0, 0), mask),
2187                                         XEXP (op0, 1));
2188         }
2189
2190       tem = simplify_associative_operation (code, mode, op0, op1);
2191       if (tem)
2192         return tem;
2193       break;
2194
2195     case XOR:
2196       if (trueop1 == const0_rtx)
2197         return op0;
2198       if (GET_CODE (trueop1) == CONST_INT
2199           && ((INTVAL (trueop1) & GET_MODE_MASK (mode))
2200               == GET_MODE_MASK (mode)))
2201         return simplify_gen_unary (NOT, mode, op0, mode);
2202       if (rtx_equal_p (trueop0, trueop1)
2203           && ! side_effects_p (op0)
2204           && GET_MODE_CLASS (mode) != MODE_CC)
2205          return CONST0_RTX (mode);
2206
2207       /* Canonicalize XOR of the most significant bit to PLUS.  */
2208       if ((GET_CODE (op1) == CONST_INT
2209            || GET_CODE (op1) == CONST_DOUBLE)
2210           && mode_signbit_p (mode, op1))
2211         return simplify_gen_binary (PLUS, mode, op0, op1);
2212       /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit.  */
2213       if ((GET_CODE (op1) == CONST_INT
2214            || GET_CODE (op1) == CONST_DOUBLE)
2215           && GET_CODE (op0) == PLUS
2216           && (GET_CODE (XEXP (op0, 1)) == CONST_INT
2217               || GET_CODE (XEXP (op0, 1)) == CONST_DOUBLE)
2218           && mode_signbit_p (mode, XEXP (op0, 1)))
2219         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
2220                                     simplify_gen_binary (XOR, mode, op1,
2221                                                          XEXP (op0, 1)));
2222
2223       /* If we are XORing two things that have no bits in common,
2224          convert them into an IOR.  This helps to detect rotation encoded
2225          using those methods and possibly other simplifications.  */
2226
2227       if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2228           && (nonzero_bits (op0, mode)
2229               & nonzero_bits (op1, mode)) == 0)
2230         return (simplify_gen_binary (IOR, mode, op0, op1));
2231
2232       /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
2233          Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
2234          (NOT y).  */
2235       {
2236         int num_negated = 0;
2237
2238         if (GET_CODE (op0) == NOT)
2239           num_negated++, op0 = XEXP (op0, 0);
2240         if (GET_CODE (op1) == NOT)
2241           num_negated++, op1 = XEXP (op1, 0);
2242
2243         if (num_negated == 2)
2244           return simplify_gen_binary (XOR, mode, op0, op1);
2245         else if (num_negated == 1)
2246           return simplify_gen_unary (NOT, mode,
2247                                      simplify_gen_binary (XOR, mode, op0, op1),
2248                                      mode);
2249       }
2250
2251       /* Convert (xor (and A B) B) to (and (not A) B).  The latter may
2252          correspond to a machine insn or result in further simplifications
2253          if B is a constant.  */
2254
2255       if (GET_CODE (op0) == AND
2256           && rtx_equal_p (XEXP (op0, 1), op1)
2257           && ! side_effects_p (op1))
2258         return simplify_gen_binary (AND, mode,
2259                                     simplify_gen_unary (NOT, mode,
2260                                                         XEXP (op0, 0), mode),
2261                                     op1);
2262
2263       else if (GET_CODE (op0) == AND
2264                && rtx_equal_p (XEXP (op0, 0), op1)
2265                && ! side_effects_p (op1))
2266         return simplify_gen_binary (AND, mode,
2267                                     simplify_gen_unary (NOT, mode,
2268                                                         XEXP (op0, 1), mode),
2269                                     op1);
2270
2271       /* (xor (comparison foo bar) (const_int 1)) can become the reversed
2272          comparison if STORE_FLAG_VALUE is 1.  */
2273       if (STORE_FLAG_VALUE == 1
2274           && trueop1 == const1_rtx
2275           && COMPARISON_P (op0)
2276           && (reversed = reversed_comparison (op0, mode)))
2277         return reversed;
2278
2279       /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
2280          is (lt foo (const_int 0)), so we can perform the above
2281          simplification if STORE_FLAG_VALUE is 1.  */
2282
2283       if (STORE_FLAG_VALUE == 1
2284           && trueop1 == const1_rtx
2285           && GET_CODE (op0) == LSHIFTRT
2286           && GET_CODE (XEXP (op0, 1)) == CONST_INT
2287           && INTVAL (XEXP (op0, 1)) == GET_MODE_BITSIZE (mode) - 1)
2288         return gen_rtx_GE (mode, XEXP (op0, 0), const0_rtx);
2289
2290       /* (xor (comparison foo bar) (const_int sign-bit))
2291          when STORE_FLAG_VALUE is the sign bit.  */
2292       if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2293           && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
2294               == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
2295           && trueop1 == const_true_rtx
2296           && COMPARISON_P (op0)
2297           && (reversed = reversed_comparison (op0, mode)))
2298         return reversed;
2299
2300       tem = simplify_associative_operation (code, mode, op0, op1);
2301       if (tem)
2302         return tem;
2303       break;
2304
2305     case AND:
2306       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
2307         return trueop1;
2308       if (GET_CODE (trueop1) == CONST_INT
2309           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
2310         {
2311           HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
2312           HOST_WIDE_INT val1 = INTVAL (trueop1);
2313           /* If we are turning off bits already known off in OP0, we need
2314              not do an AND.  */
2315           if ((nzop0 & ~val1) == 0)
2316             return op0;
2317           /* If we are clearing all the nonzero bits, the result is zero.  */
2318           if ((val1 & nzop0) == 0 && !side_effects_p (op0))
2319             return CONST0_RTX (mode);
2320         }
2321       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
2322           && GET_MODE_CLASS (mode) != MODE_CC)
2323         return op0;
2324       /* A & (~A) -> 0 */
2325       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
2326            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
2327           && ! side_effects_p (op0)
2328           && GET_MODE_CLASS (mode) != MODE_CC)
2329         return CONST0_RTX (mode);
2330
2331       /* Transform (and (extend X) C) into (zero_extend (and X C)) if
2332          there are no nonzero bits of C outside of X's mode.  */
2333       if ((GET_CODE (op0) == SIGN_EXTEND
2334            || GET_CODE (op0) == ZERO_EXTEND)
2335           && GET_CODE (trueop1) == CONST_INT
2336           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2337           && (~GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))
2338               & INTVAL (trueop1)) == 0)
2339         {
2340           enum machine_mode imode = GET_MODE (XEXP (op0, 0));
2341           tem = simplify_gen_binary (AND, imode, XEXP (op0, 0),
2342                                      gen_int_mode (INTVAL (trueop1),
2343                                                    imode));
2344           return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
2345         }
2346
2347       /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2).  */
2348       if (GET_CODE (op0) == IOR
2349           && GET_CODE (trueop1) == CONST_INT
2350           && GET_CODE (XEXP (op0, 1)) == CONST_INT)
2351         {
2352           HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
2353           return simplify_gen_binary (IOR, mode,
2354                                       simplify_gen_binary (AND, mode,
2355                                                            XEXP (op0, 0), op1),
2356                                       gen_int_mode (tmp, mode));
2357         }
2358
2359       /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
2360          insn (and may simplify more).  */
2361       if (GET_CODE (op0) == XOR
2362           && rtx_equal_p (XEXP (op0, 0), op1)
2363           && ! side_effects_p (op1))
2364         return simplify_gen_binary (AND, mode,
2365                                     simplify_gen_unary (NOT, mode,
2366                                                         XEXP (op0, 1), mode),
2367                                     op1);
2368
2369       if (GET_CODE (op0) == XOR
2370           && rtx_equal_p (XEXP (op0, 1), op1)
2371           && ! side_effects_p (op1))
2372         return simplify_gen_binary (AND, mode,
2373                                     simplify_gen_unary (NOT, mode,
2374                                                         XEXP (op0, 0), mode),
2375                                     op1);
2376
2377       /* Similarly for (~(A ^ B)) & A.  */
2378       if (GET_CODE (op0) == NOT
2379           && GET_CODE (XEXP (op0, 0)) == XOR
2380           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
2381           && ! side_effects_p (op1))
2382         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
2383
2384       if (GET_CODE (op0) == NOT
2385           && GET_CODE (XEXP (op0, 0)) == XOR
2386           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
2387           && ! side_effects_p (op1))
2388         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
2389
2390       /* Convert (A | B) & A to A.  */
2391       if (GET_CODE (op0) == IOR
2392           && (rtx_equal_p (XEXP (op0, 0), op1)
2393               || rtx_equal_p (XEXP (op0, 1), op1))
2394           && ! side_effects_p (XEXP (op0, 0))
2395           && ! side_effects_p (XEXP (op0, 1)))
2396         return op1;
2397
2398       /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
2399          ((A & N) + B) & M -> (A + B) & M
2400          Similarly if (N & M) == 0,
2401          ((A | N) + B) & M -> (A + B) & M
2402          and for - instead of + and/or ^ instead of |.
2403          Also, if (N & M) == 0, then
2404          (A +- N) & M -> A & M.  */
2405       if (GET_CODE (trueop1) == CONST_INT
2406           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2407           && ~INTVAL (trueop1)
2408           && (INTVAL (trueop1) & (INTVAL (trueop1) + 1)) == 0
2409           && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
2410         {
2411           rtx pmop[2];
2412           int which;
2413
2414           pmop[0] = XEXP (op0, 0);
2415           pmop[1] = XEXP (op0, 1);
2416
2417           if (GET_CODE (pmop[1]) == CONST_INT
2418               && (INTVAL (pmop[1]) & INTVAL (trueop1)) == 0)
2419             return simplify_gen_binary (AND, mode, pmop[0], op1);
2420
2421           for (which = 0; which < 2; which++)
2422             {
2423               tem = pmop[which];
2424               switch (GET_CODE (tem))
2425                 {
2426                 case AND:
2427                   if (GET_CODE (XEXP (tem, 1)) == CONST_INT
2428                       && (INTVAL (XEXP (tem, 1)) & INTVAL (trueop1))
2429                       == INTVAL (trueop1))
2430                     pmop[which] = XEXP (tem, 0);
2431                   break;
2432                 case IOR:
2433                 case XOR:
2434                   if (GET_CODE (XEXP (tem, 1)) == CONST_INT
2435                       && (INTVAL (XEXP (tem, 1)) & INTVAL (trueop1)) == 0)
2436                     pmop[which] = XEXP (tem, 0);
2437                   break;
2438                 default:
2439                   break;
2440                 }
2441             }
2442
2443           if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
2444             {
2445               tem = simplify_gen_binary (GET_CODE (op0), mode,
2446                                          pmop[0], pmop[1]);
2447               return simplify_gen_binary (code, mode, tem, op1);
2448             }
2449         }
2450
2451       /* (and X (ior (not X) Y) -> (and X Y) */
2452       if (GET_CODE (op1) == IOR
2453           && GET_CODE (XEXP (op1, 0)) == NOT
2454           && op0 == XEXP (XEXP (op1, 0), 0))
2455        return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
2456
2457       /* (and (ior (not X) Y) X) -> (and X Y) */
2458       if (GET_CODE (op0) == IOR
2459           && GET_CODE (XEXP (op0, 0)) == NOT
2460           && op1 == XEXP (XEXP (op0, 0), 0))
2461         return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
2462
2463       tem = simplify_associative_operation (code, mode, op0, op1);
2464       if (tem)
2465         return tem;
2466       break;
2467
2468     case UDIV:
2469       /* 0/x is 0 (or x&0 if x has side-effects).  */
2470       if (trueop0 == CONST0_RTX (mode))
2471         {
2472           if (side_effects_p (op1))
2473             return simplify_gen_binary (AND, mode, op1, trueop0);
2474           return trueop0;
2475         }
2476       /* x/1 is x.  */
2477       if (trueop1 == CONST1_RTX (mode))
2478         return rtl_hooks.gen_lowpart_no_emit (mode, op0);
2479       /* Convert divide by power of two into shift.  */
2480       if (GET_CODE (trueop1) == CONST_INT
2481           && (val = exact_log2 (INTVAL (trueop1))) > 0)
2482         return simplify_gen_binary (LSHIFTRT, mode, op0, GEN_INT (val));
2483       break;
2484
2485     case DIV:
2486       /* Handle floating point and integers separately.  */
2487       if (SCALAR_FLOAT_MODE_P (mode))
2488         {
2489           /* Maybe change 0.0 / x to 0.0.  This transformation isn't
2490              safe for modes with NaNs, since 0.0 / 0.0 will then be
2491              NaN rather than 0.0.  Nor is it safe for modes with signed
2492              zeros, since dividing 0 by a negative number gives -0.0  */
2493           if (trueop0 == CONST0_RTX (mode)
2494               && !HONOR_NANS (mode)
2495               && !HONOR_SIGNED_ZEROS (mode)
2496               && ! side_effects_p (op1))
2497             return op0;
2498           /* x/1.0 is x.  */
2499           if (trueop1 == CONST1_RTX (mode)
2500               && !HONOR_SNANS (mode))
2501             return op0;
2502
2503           if (GET_CODE (trueop1) == CONST_DOUBLE
2504               && trueop1 != CONST0_RTX (mode))
2505             {
2506               REAL_VALUE_TYPE d;
2507               REAL_VALUE_FROM_CONST_DOUBLE (d, trueop1);
2508
2509               /* x/-1.0 is -x.  */
2510               if (REAL_VALUES_EQUAL (d, dconstm1)
2511                   && !HONOR_SNANS (mode))
2512                 return simplify_gen_unary (NEG, mode, op0, mode);
2513
2514               /* Change FP division by a constant into multiplication.
2515                  Only do this with -freciprocal-math.  */
2516               if (flag_reciprocal_math
2517                   && !REAL_VALUES_EQUAL (d, dconst0))
2518                 {
2519                   REAL_ARITHMETIC (d, RDIV_EXPR, dconst1, d);
2520                   tem = CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
2521                   return simplify_gen_binary (MULT, mode, op0, tem);
2522                 }
2523             }
2524         }
2525       else
2526         {
2527           /* 0/x is 0 (or x&0 if x has side-effects).  */
2528           if (trueop0 == CONST0_RTX (mode))
2529             {
2530               if (side_effects_p (op1))
2531                 return simplify_gen_binary (AND, mode, op1, trueop0);
2532               return trueop0;
2533             }
2534           /* x/1 is x.  */
2535           if (trueop1 == CONST1_RTX (mode))
2536             return rtl_hooks.gen_lowpart_no_emit (mode, op0);
2537           /* x/-1 is -x.  */
2538           if (trueop1 == constm1_rtx)
2539             {
2540               rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
2541               return simplify_gen_unary (NEG, mode, x, mode);
2542             }
2543         }
2544       break;
2545
2546     case UMOD:
2547       /* 0%x is 0 (or x&0 if x has side-effects).  */
2548       if (trueop0 == CONST0_RTX (mode))
2549         {
2550           if (side_effects_p (op1))
2551             return simplify_gen_binary (AND, mode, op1, trueop0);
2552           return trueop0;
2553         }
2554       /* x%1 is 0 (of x&0 if x has side-effects).  */
2555       if (trueop1 == CONST1_RTX (mode))
2556         {
2557           if (side_effects_p (op0))
2558             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
2559           return CONST0_RTX (mode);
2560         }
2561       /* Implement modulus by power of two as AND.  */
2562       if (GET_CODE (trueop1) == CONST_INT
2563           && exact_log2 (INTVAL (trueop1)) > 0)
2564         return simplify_gen_binary (AND, mode, op0,
2565                                     GEN_INT (INTVAL (op1) - 1));
2566       break;
2567
2568     case MOD:
2569       /* 0%x is 0 (or x&0 if x has side-effects).  */
2570       if (trueop0 == CONST0_RTX (mode))
2571         {
2572           if (side_effects_p (op1))
2573             return simplify_gen_binary (AND, mode, op1, trueop0);
2574           return trueop0;
2575         }
2576       /* x%1 and x%-1 is 0 (or x&0 if x has side-effects).  */
2577       if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
2578         {
2579           if (side_effects_p (op0))
2580             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
2581           return CONST0_RTX (mode);
2582         }
2583       break;
2584
2585     case ROTATERT:
2586     case ROTATE:
2587     case ASHIFTRT:
2588       if (trueop1 == CONST0_RTX (mode))
2589         return op0;
2590       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
2591         return op0;
2592       /* Rotating ~0 always results in ~0.  */
2593       if (GET_CODE (trueop0) == CONST_INT && width <= HOST_BITS_PER_WIDE_INT
2594           && (unsigned HOST_WIDE_INT) INTVAL (trueop0) == GET_MODE_MASK (mode)
2595           && ! side_effects_p (op1))
2596         return op0;
2597     canonicalize_shift:
2598       if (SHIFT_COUNT_TRUNCATED && GET_CODE (op1) == CONST_INT)
2599         {
2600           val = INTVAL (op1) & (GET_MODE_BITSIZE (mode) - 1);
2601           if (val != INTVAL (op1))
2602             return simplify_gen_binary (code, mode, op0, GEN_INT (val));
2603         }
2604       break;
2605
2606     case ASHIFT:
2607     case SS_ASHIFT:
2608     case US_ASHIFT:
2609       if (trueop1 == CONST0_RTX (mode))
2610         return op0;
2611       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
2612         return op0;
2613       goto canonicalize_shift;
2614
2615     case LSHIFTRT:
2616       if (trueop1 == CONST0_RTX (mode))
2617         return op0;
2618       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
2619         return op0;
2620       /* Optimize (lshiftrt (clz X) C) as (eq X 0).  */
2621       if (GET_CODE (op0) == CLZ
2622           && GET_CODE (trueop1) == CONST_INT
2623           && STORE_FLAG_VALUE == 1
2624           && INTVAL (trueop1) < (HOST_WIDE_INT)width)
2625         {
2626           enum machine_mode imode = GET_MODE (XEXP (op0, 0));
2627           unsigned HOST_WIDE_INT zero_val = 0;
2628
2629           if (CLZ_DEFINED_VALUE_AT_ZERO (imode, zero_val)
2630               && zero_val == GET_MODE_BITSIZE (imode)
2631               && INTVAL (trueop1) == exact_log2 (zero_val))
2632             return simplify_gen_relational (EQ, mode, imode,
2633                                             XEXP (op0, 0), const0_rtx);
2634         }
2635       goto canonicalize_shift;
2636
2637     case SMIN:
2638       if (width <= HOST_BITS_PER_WIDE_INT
2639           && GET_CODE (trueop1) == CONST_INT
2640           && INTVAL (trueop1) == (HOST_WIDE_INT) 1 << (width -1)
2641           && ! side_effects_p (op0))
2642         return op1;
2643       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2644         return op0;
2645       tem = simplify_associative_operation (code, mode, op0, op1);
2646       if (tem)
2647         return tem;
2648       break;
2649
2650     case SMAX:
2651       if (width <= HOST_BITS_PER_WIDE_INT
2652           && GET_CODE (trueop1) == CONST_INT
2653           && ((unsigned HOST_WIDE_INT) INTVAL (trueop1)
2654               == (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode) >> 1)
2655           && ! side_effects_p (op0))
2656         return op1;
2657       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2658         return op0;
2659       tem = simplify_associative_operation (code, mode, op0, op1);
2660       if (tem)
2661         return tem;
2662       break;
2663
2664     case UMIN:
2665       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
2666         return op1;
2667       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2668         return op0;
2669       tem = simplify_associative_operation (code, mode, op0, op1);
2670       if (tem)
2671         return tem;
2672       break;
2673
2674     case UMAX:
2675       if (trueop1 == constm1_rtx && ! side_effects_p (op0))
2676         return op1;
2677       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2678         return op0;
2679       tem = simplify_associative_operation (code, mode, op0, op1);
2680       if (tem)
2681         return tem;
2682       break;
2683
2684     case SS_PLUS:
2685     case US_PLUS:
2686     case SS_MINUS:
2687     case US_MINUS:
2688     case SS_MULT:
2689     case US_MULT:
2690     case SS_DIV:
2691     case US_DIV:
2692       /* ??? There are simplifications that can be done.  */
2693       return 0;
2694
2695     case VEC_SELECT:
2696       if (!VECTOR_MODE_P (mode))
2697         {
2698           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
2699           gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
2700           gcc_assert (GET_CODE (trueop1) == PARALLEL);
2701           gcc_assert (XVECLEN (trueop1, 0) == 1);
2702           gcc_assert (GET_CODE (XVECEXP (trueop1, 0, 0)) == CONST_INT);
2703
2704           if (GET_CODE (trueop0) == CONST_VECTOR)
2705             return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
2706                                                       (trueop1, 0, 0)));
2707
2708           /* Extract a scalar element from a nested VEC_SELECT expression
2709              (with optional nested VEC_CONCAT expression).  Some targets
2710              (i386) extract scalar element from a vector using chain of
2711              nested VEC_SELECT expressions.  When input operand is a memory
2712              operand, this operation can be simplified to a simple scalar
2713              load from an offseted memory address.  */
2714           if (GET_CODE (trueop0) == VEC_SELECT)
2715             {
2716               rtx op0 = XEXP (trueop0, 0);
2717               rtx op1 = XEXP (trueop0, 1);
2718
2719               enum machine_mode opmode = GET_MODE (op0);
2720               int elt_size = GET_MODE_SIZE (GET_MODE_INNER (opmode));
2721               int n_elts = GET_MODE_SIZE (opmode) / elt_size;
2722
2723               int i = INTVAL (XVECEXP (trueop1, 0, 0));
2724               int elem;
2725
2726               rtvec vec;
2727               rtx tmp_op, tmp;
2728
2729               gcc_assert (GET_CODE (op1) == PARALLEL);
2730               gcc_assert (i < n_elts);
2731
2732               /* Select element, pointed by nested selector.  */
2733               elem = INTVAL (XVECEXP (op1, 0, i));
2734
2735               /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT.  */
2736               if (GET_CODE (op0) == VEC_CONCAT)
2737                 {
2738                   rtx op00 = XEXP (op0, 0);
2739                   rtx op01 = XEXP (op0, 1);
2740
2741                   enum machine_mode mode00, mode01;
2742                   int n_elts00, n_elts01;
2743
2744                   mode00 = GET_MODE (op00);
2745                   mode01 = GET_MODE (op01);
2746
2747                   /* Find out number of elements of each operand.  */
2748                   if (VECTOR_MODE_P (mode00))
2749                     {
2750                       elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode00));
2751                       n_elts00 = GET_MODE_SIZE (mode00) / elt_size;
2752                     }
2753                   else
2754                     n_elts00 = 1;
2755
2756                   if (VECTOR_MODE_P (mode01))
2757                     {
2758                       elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode01));
2759                       n_elts01 = GET_MODE_SIZE (mode01) / elt_size;
2760                     }
2761                   else
2762                     n_elts01 = 1;
2763
2764                   gcc_assert (n_elts == n_elts00 + n_elts01);
2765
2766                   /* Select correct operand of VEC_CONCAT
2767                      and adjust selector. */
2768                   if (elem < n_elts01)
2769                     tmp_op = op00;
2770                   else
2771                     {
2772                       tmp_op = op01;
2773                       elem -= n_elts00;
2774                     }
2775                 }
2776               else
2777                 tmp_op = op0;
2778
2779               vec = rtvec_alloc (1);
2780               RTVEC_ELT (vec, 0) = GEN_INT (elem);
2781
2782               tmp = gen_rtx_fmt_ee (code, mode,
2783                                     tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
2784               return tmp;
2785             }
2786         }
2787       else
2788         {
2789           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
2790           gcc_assert (GET_MODE_INNER (mode)
2791                       == GET_MODE_INNER (GET_MODE (trueop0)));
2792           gcc_assert (GET_CODE (trueop1) == PARALLEL);
2793
2794           if (GET_CODE (trueop0) == CONST_VECTOR)
2795             {
2796               int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
2797               unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
2798               rtvec v = rtvec_alloc (n_elts);
2799               unsigned int i;
2800
2801               gcc_assert (XVECLEN (trueop1, 0) == (int) n_elts);
2802               for (i = 0; i < n_elts; i++)
2803                 {
2804                   rtx x = XVECEXP (trueop1, 0, i);
2805
2806                   gcc_assert (GET_CODE (x) == CONST_INT);
2807                   RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
2808                                                        INTVAL (x));
2809                 }
2810
2811               return gen_rtx_CONST_VECTOR (mode, v);
2812             }
2813         }
2814
2815       if (XVECLEN (trueop1, 0) == 1
2816           && GET_CODE (XVECEXP (trueop1, 0, 0)) == CONST_INT
2817           && GET_CODE (trueop0) == VEC_CONCAT)
2818         {
2819           rtx vec = trueop0;
2820           int offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
2821
2822           /* Try to find the element in the VEC_CONCAT.  */
2823           while (GET_MODE (vec) != mode
2824                  && GET_CODE (vec) == VEC_CONCAT)
2825             {
2826               HOST_WIDE_INT vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
2827               if (offset < vec_size)
2828                 vec = XEXP (vec, 0);
2829               else
2830                 {
2831                   offset -= vec_size;
2832                   vec = XEXP (vec, 1);
2833                 }
2834               vec = avoid_constant_pool_reference (vec);
2835             }
2836
2837           if (GET_MODE (vec) == mode)
2838             return vec;
2839         }
2840
2841       return 0;
2842     case VEC_CONCAT:
2843       {
2844         enum machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
2845                                       ? GET_MODE (trueop0)
2846                                       : GET_MODE_INNER (mode));
2847         enum machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
2848                                       ? GET_MODE (trueop1)
2849                                       : GET_MODE_INNER (mode));
2850
2851         gcc_assert (VECTOR_MODE_P (mode));
2852         gcc_assert (GET_MODE_SIZE (op0_mode) + GET_MODE_SIZE (op1_mode)
2853                     == GET_MODE_SIZE (mode));
2854
2855         if (VECTOR_MODE_P (op0_mode))
2856           gcc_assert (GET_MODE_INNER (mode)
2857                       == GET_MODE_INNER (op0_mode));
2858         else
2859           gcc_assert (GET_MODE_INNER (mode) == op0_mode);
2860
2861         if (VECTOR_MODE_P (op1_mode))
2862           gcc_assert (GET_MODE_INNER (mode)
2863                       == GET_MODE_INNER (op1_mode));
2864         else
2865           gcc_assert (GET_MODE_INNER (mode) == op1_mode);
2866
2867         if ((GET_CODE (trueop0) == CONST_VECTOR
2868              || GET_CODE (trueop0) == CONST_INT
2869              || GET_CODE (trueop0) == CONST_DOUBLE)
2870             && (GET_CODE (trueop1) == CONST_VECTOR
2871                 || GET_CODE (trueop1) == CONST_INT
2872                 || GET_CODE (trueop1) == CONST_DOUBLE))
2873           {
2874             int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
2875             unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
2876             rtvec v = rtvec_alloc (n_elts);
2877             unsigned int i;
2878             unsigned in_n_elts = 1;
2879
2880             if (VECTOR_MODE_P (op0_mode))
2881               in_n_elts = (GET_MODE_SIZE (op0_mode) / elt_size);
2882             for (i = 0; i < n_elts; i++)
2883               {
2884                 if (i < in_n_elts)
2885                   {
2886                     if (!VECTOR_MODE_P (op0_mode))
2887                       RTVEC_ELT (v, i) = trueop0;
2888                     else
2889                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
2890                   }
2891                 else
2892                   {
2893                     if (!VECTOR_MODE_P (op1_mode))
2894                       RTVEC_ELT (v, i) = trueop1;
2895                     else
2896                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
2897                                                            i - in_n_elts);
2898                   }
2899               }
2900
2901             return gen_rtx_CONST_VECTOR (mode, v);
2902           }
2903       }
2904       return 0;
2905
2906     default:
2907       gcc_unreachable ();
2908     }
2909
2910   return 0;
2911 }
2912
2913 rtx
2914 simplify_const_binary_operation (enum rtx_code code, enum machine_mode mode,
2915                                  rtx op0, rtx op1)
2916 {
2917   HOST_WIDE_INT arg0, arg1, arg0s, arg1s;
2918   HOST_WIDE_INT val;
2919   unsigned int width = GET_MODE_BITSIZE (mode);
2920
2921   if (VECTOR_MODE_P (mode)
2922       && code != VEC_CONCAT
2923       && GET_CODE (op0) == CONST_VECTOR
2924       && GET_CODE (op1) == CONST_VECTOR)
2925     {
2926       unsigned n_elts = GET_MODE_NUNITS (mode);
2927       enum machine_mode op0mode = GET_MODE (op0);
2928       unsigned op0_n_elts = GET_MODE_NUNITS (op0mode);
2929       enum machine_mode op1mode = GET_MODE (op1);
2930       unsigned op1_n_elts = GET_MODE_NUNITS (op1mode);
2931       rtvec v = rtvec_alloc (n_elts);
2932       unsigned int i;
2933
2934       gcc_assert (op0_n_elts == n_elts);
2935       gcc_assert (op1_n_elts == n_elts);
2936       for (i = 0; i < n_elts; i++)
2937         {
2938           rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
2939                                              CONST_VECTOR_ELT (op0, i),
2940                                              CONST_VECTOR_ELT (op1, i));
2941           if (!x)
2942             return 0;
2943           RTVEC_ELT (v, i) = x;
2944         }
2945
2946       return gen_rtx_CONST_VECTOR (mode, v);
2947     }
2948
2949   if (VECTOR_MODE_P (mode)
2950       && code == VEC_CONCAT
2951       && (CONST_INT_P (op0)
2952           || GET_CODE (op0) == CONST_DOUBLE
2953           || GET_CODE (op0) == CONST_FIXED)
2954       && (CONST_INT_P (op1)
2955           || GET_CODE (op1) == CONST_DOUBLE
2956           || GET_CODE (op1) == CONST_FIXED))
2957     {
2958       unsigned n_elts = GET_MODE_NUNITS (mode);
2959       rtvec v = rtvec_alloc (n_elts);
2960
2961       gcc_assert (n_elts >= 2);
2962       if (n_elts == 2)
2963         {
2964           gcc_assert (GET_CODE (op0) != CONST_VECTOR);
2965           gcc_assert (GET_CODE (op1) != CONST_VECTOR);
2966
2967           RTVEC_ELT (v, 0) = op0;
2968           RTVEC_ELT (v, 1) = op1;
2969         }
2970       else
2971         {
2972           unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0));
2973           unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1));
2974           unsigned i;
2975
2976           gcc_assert (GET_CODE (op0) == CONST_VECTOR);
2977           gcc_assert (GET_CODE (op1) == CONST_VECTOR);
2978           gcc_assert (op0_n_elts + op1_n_elts == n_elts);
2979
2980           for (i = 0; i < op0_n_elts; ++i)
2981             RTVEC_ELT (v, i) = XVECEXP (op0, 0, i);
2982           for (i = 0; i < op1_n_elts; ++i)
2983             RTVEC_ELT (v, op0_n_elts+i) = XVECEXP (op1, 0, i);
2984         }
2985
2986       return gen_rtx_CONST_VECTOR (mode, v);
2987     }
2988
2989   if (SCALAR_FLOAT_MODE_P (mode)
2990       && GET_CODE (op0) == CONST_DOUBLE
2991       && GET_CODE (op1) == CONST_DOUBLE
2992       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
2993     {
2994       if (code == AND
2995           || code == IOR
2996           || code == XOR)
2997         {
2998           long tmp0[4];
2999           long tmp1[4];
3000           REAL_VALUE_TYPE r;
3001           int i;
3002
3003           real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
3004                           GET_MODE (op0));
3005           real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
3006                           GET_MODE (op1));
3007           for (i = 0; i < 4; i++)
3008             {
3009               switch (code)
3010               {
3011               case AND:
3012                 tmp0[i] &= tmp1[i];
3013                 break;
3014               case IOR:
3015                 tmp0[i] |= tmp1[i];
3016                 break;
3017               case XOR:
3018                 tmp0[i] ^= tmp1[i];
3019                 break;
3020               default:
3021                 gcc_unreachable ();
3022               }
3023             }
3024            real_from_target (&r, tmp0, mode);
3025            return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
3026         }
3027       else
3028         {
3029           REAL_VALUE_TYPE f0, f1, value, result;
3030           bool inexact;
3031
3032           REAL_VALUE_FROM_CONST_DOUBLE (f0, op0);
3033           REAL_VALUE_FROM_CONST_DOUBLE (f1, op1);
3034           real_convert (&f0, mode, &f0);
3035           real_convert (&f1, mode, &f1);
3036
3037           if (HONOR_SNANS (mode)
3038               && (REAL_VALUE_ISNAN (f0) || REAL_VALUE_ISNAN (f1)))
3039             return 0;
3040
3041           if (code == DIV
3042               && REAL_VALUES_EQUAL (f1, dconst0)
3043               && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
3044             return 0;
3045
3046           if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
3047               && flag_trapping_math
3048               && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
3049             {
3050               int s0 = REAL_VALUE_NEGATIVE (f0);
3051               int s1 = REAL_VALUE_NEGATIVE (f1);
3052
3053               switch (code)
3054                 {
3055                 case PLUS:
3056                   /* Inf + -Inf = NaN plus exception.  */
3057                   if (s0 != s1)
3058                     return 0;
3059                   break;
3060                 case MINUS:
3061                   /* Inf - Inf = NaN plus exception.  */
3062                   if (s0 == s1)
3063                     return 0;
3064                   break;
3065                 case DIV:
3066                   /* Inf / Inf = NaN plus exception.  */
3067                   return 0;
3068                 default:
3069                   break;
3070                 }
3071             }
3072
3073           if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
3074               && flag_trapping_math
3075               && ((REAL_VALUE_ISINF (f0) && REAL_VALUES_EQUAL (f1, dconst0))
3076                   || (REAL_VALUE_ISINF (f1)
3077                       && REAL_VALUES_EQUAL (f0, dconst0))))
3078             /* Inf * 0 = NaN plus exception.  */
3079             return 0;
3080
3081           inexact = real_arithmetic (&value, rtx_to_tree_code (code),
3082                                      &f0, &f1);
3083           real_convert (&result, mode, &value);
3084
3085           /* Don't constant fold this floating point operation if
3086              the result has overflowed and flag_trapping_math.  */
3087
3088           if (flag_trapping_math
3089               && MODE_HAS_INFINITIES (mode)
3090               && REAL_VALUE_ISINF (result)
3091               && !REAL_VALUE_ISINF (f0)
3092               && !REAL_VALUE_ISINF (f1))
3093             /* Overflow plus exception.  */
3094             return 0;
3095
3096           /* Don't constant fold this floating point operation if the
3097              result may dependent upon the run-time rounding mode and
3098              flag_rounding_math is set, or if GCC's software emulation
3099              is unable to accurately represent the result.  */
3100
3101           if ((flag_rounding_math
3102                || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
3103               && (inexact || !real_identical (&result, &value)))
3104             return NULL_RTX;
3105
3106           return CONST_DOUBLE_FROM_REAL_VALUE (result, mode);
3107         }
3108     }
3109
3110   /* We can fold some multi-word operations.  */
3111   if (GET_MODE_CLASS (mode) == MODE_INT
3112       && width == HOST_BITS_PER_WIDE_INT * 2
3113       && (GET_CODE (op0) == CONST_DOUBLE || GET_CODE (op0) == CONST_INT)
3114       && (GET_CODE (op1) == CONST_DOUBLE || GET_CODE (op1) == CONST_INT))
3115     {
3116       unsigned HOST_WIDE_INT l1, l2, lv, lt;
3117       HOST_WIDE_INT h1, h2, hv, ht;
3118
3119       if (GET_CODE (op0) == CONST_DOUBLE)
3120         l1 = CONST_DOUBLE_LOW (op0), h1 = CONST_DOUBLE_HIGH (op0);
3121       else
3122         l1 = INTVAL (op0), h1 = HWI_SIGN_EXTEND (l1);
3123
3124       if (GET_CODE (op1) == CONST_DOUBLE)
3125         l2 = CONST_DOUBLE_LOW (op1), h2 = CONST_DOUBLE_HIGH (op1);
3126       else
3127         l2 = INTVAL (op1), h2 = HWI_SIGN_EXTEND (l2);
3128
3129       switch (code)
3130         {
3131         case MINUS:
3132           /* A - B == A + (-B).  */
3133           neg_double (l2, h2, &lv, &hv);
3134           l2 = lv, h2 = hv;
3135
3136           /* Fall through....  */
3137
3138         case PLUS:
3139           add_double (l1, h1, l2, h2, &lv, &hv);
3140           break;
3141
3142         case MULT:
3143           mul_double (l1, h1, l2, h2, &lv, &hv);
3144           break;
3145
3146         case DIV:
3147           if (div_and_round_double (TRUNC_DIV_EXPR, 0, l1, h1, l2, h2,
3148                                     &lv, &hv, &lt, &ht))
3149             return 0;
3150           break;
3151
3152         case MOD:
3153           if (div_and_round_double (TRUNC_DIV_EXPR, 0, l1, h1, l2, h2,
3154                                     &lt, &ht, &lv, &hv))
3155             return 0;
3156           break;
3157
3158         case UDIV:
3159           if (div_and_round_double (TRUNC_DIV_EXPR, 1, l1, h1, l2, h2,
3160                                     &lv, &hv, &lt, &ht))
3161             return 0;
3162           break;
3163
3164         case UMOD:
3165           if (div_and_round_double (TRUNC_DIV_EXPR, 1, l1, h1, l2, h2,
3166                                     &lt, &ht, &lv, &hv))
3167             return 0;
3168           break;
3169
3170         case AND:
3171           lv = l1 & l2, hv = h1 & h2;
3172           break;
3173
3174         case IOR:
3175           lv = l1 | l2, hv = h1 | h2;
3176           break;
3177
3178         case XOR:
3179           lv = l1 ^ l2, hv = h1 ^ h2;
3180           break;
3181
3182         case SMIN:
3183           if (h1 < h2
3184               || (h1 == h2
3185                   && ((unsigned HOST_WIDE_INT) l1
3186                       < (unsigned HOST_WIDE_INT) l2)))
3187             lv = l1, hv = h1;
3188           else
3189             lv = l2, hv = h2;
3190           break;
3191
3192         case SMAX:
3193           if (h1 > h2
3194               || (h1 == h2
3195                   && ((unsigned HOST_WIDE_INT) l1
3196                       > (unsigned HOST_WIDE_INT) l2)))
3197             lv = l1, hv = h1;
3198           else
3199             lv = l2, hv = h2;
3200           break;
3201
3202         case UMIN:
3203           if ((unsigned HOST_WIDE_INT) h1 < (unsigned HOST_WIDE_INT) h2
3204               || (h1 == h2
3205                   && ((unsigned HOST_WIDE_INT) l1
3206                       < (unsigned HOST_WIDE_INT) l2)))
3207             lv = l1, hv = h1;
3208           else
3209             lv = l2, hv = h2;
3210           break;
3211
3212         case UMAX:
3213           if ((unsigned HOST_WIDE_INT) h1 > (unsigned HOST_WIDE_INT) h2
3214               || (h1 == h2
3215                   && ((unsigned HOST_WIDE_INT) l1
3216                       > (unsigned HOST_WIDE_INT) l2)))
3217             lv = l1, hv = h1;
3218           else
3219             lv = l2, hv = h2;
3220           break;
3221
3222         case LSHIFTRT:   case ASHIFTRT:
3223         case ASHIFT:
3224         case ROTATE:     case ROTATERT:
3225           if (SHIFT_COUNT_TRUNCATED)
3226             l2 &= (GET_MODE_BITSIZE (mode) - 1), h2 = 0;
3227
3228           if (h2 != 0 || l2 >= GET_MODE_BITSIZE (mode))
3229             return 0;
3230
3231           if (code == LSHIFTRT || code == ASHIFTRT)
3232             rshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv,
3233                            code == ASHIFTRT);
3234           else if (code == ASHIFT)
3235             lshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv, 1);
3236           else if (code == ROTATE)
3237             lrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
3238           else /* code == ROTATERT */
3239             rrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
3240           break;
3241
3242         default:
3243           return 0;
3244         }
3245
3246       return immed_double_const (lv, hv, mode);
3247     }
3248
3249   if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == CONST_INT
3250       && width <= HOST_BITS_PER_WIDE_INT && width != 0)
3251     {
3252       /* Get the integer argument values in two forms:
3253          zero-extended in ARG0, ARG1 and sign-extended in ARG0S, ARG1S.  */
3254
3255       arg0 = INTVAL (op0);
3256       arg1 = INTVAL (op1);
3257
3258       if (width < HOST_BITS_PER_WIDE_INT)
3259         {
3260           arg0 &= ((HOST_WIDE_INT) 1 << width) - 1;
3261           arg1 &= ((HOST_WIDE_INT) 1 << width) - 1;
3262
3263           arg0s = arg0;
3264           if (arg0s & ((HOST_WIDE_INT) 1 << (width - 1)))
3265             arg0s |= ((HOST_WIDE_INT) (-1) << width);
3266
3267           arg1s = arg1;
3268           if (arg1s & ((HOST_WIDE_INT) 1 << (width - 1)))
3269             arg1s |= ((HOST_WIDE_INT) (-1) << width);
3270         }
3271       else
3272         {
3273           arg0s = arg0;
3274           arg1s = arg1;
3275         }
3276       
3277       /* Compute the value of the arithmetic.  */
3278       
3279       switch (code)
3280         {
3281         case PLUS:
3282           val = arg0s + arg1s;
3283           break;
3284           
3285         case MINUS:
3286           val = arg0s - arg1s;
3287           break;
3288           
3289         case MULT:
3290           val = arg0s * arg1s;
3291           break;
3292           
3293         case DIV:
3294           if (arg1s == 0
3295               || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
3296                   && arg1s == -1))
3297             return 0;
3298           val = arg0s / arg1s;
3299           break;
3300           
3301         case MOD:
3302           if (arg1s == 0
3303               || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
3304                   && arg1s == -1))
3305             return 0;
3306           val = arg0s % arg1s;
3307           break;
3308           
3309         case UDIV:
3310           if (arg1 == 0
3311               || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
3312                   && arg1s == -1))
3313             return 0;
3314           val = (unsigned HOST_WIDE_INT) arg0 / arg1;
3315           break;
3316           
3317         case UMOD:
3318           if (arg1 == 0
3319               || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
3320                   && arg1s == -1))
3321             return 0;
3322           val = (unsigned HOST_WIDE_INT) arg0 % arg1;
3323           break;
3324           
3325         case AND:
3326           val = arg0 & arg1;
3327           break;
3328           
3329         case IOR:
3330           val = arg0 | arg1;
3331           break;
3332           
3333         case XOR:
3334           val = arg0 ^ arg1;
3335           break;
3336           
3337         case LSHIFTRT:
3338         case ASHIFT:
3339         case ASHIFTRT:
3340           /* Truncate the shift if SHIFT_COUNT_TRUNCATED, otherwise make sure
3341              the value is in range.  We can't return any old value for
3342              out-of-range arguments because either the middle-end (via
3343              shift_truncation_mask) or the back-end might be relying on
3344              target-specific knowledge.  Nor can we rely on
3345              shift_truncation_mask, since the shift might not be part of an
3346              ashlM3, lshrM3 or ashrM3 instruction.  */
3347           if (SHIFT_COUNT_TRUNCATED)
3348             arg1 = (unsigned HOST_WIDE_INT) arg1 % width;
3349           else if (arg1 < 0 || arg1 >= GET_MODE_BITSIZE (mode))
3350             return 0;
3351           
3352           val = (code == ASHIFT
3353                  ? ((unsigned HOST_WIDE_INT) arg0) << arg1
3354                  : ((unsigned HOST_WIDE_INT) arg0) >> arg1);
3355           
3356           /* Sign-extend the result for arithmetic right shifts.  */
3357           if (code == ASHIFTRT && arg0s < 0 && arg1 > 0)
3358             val |= ((HOST_WIDE_INT) -1) << (width - arg1);
3359           break;
3360           
3361         case ROTATERT:
3362           if (arg1 < 0)
3363             return 0;
3364           
3365           arg1 %= width;
3366           val = ((((unsigned HOST_WIDE_INT) arg0) << (width - arg1))
3367                  | (((unsigned HOST_WIDE_INT) arg0) >> arg1));
3368           break;
3369           
3370         case ROTATE:
3371           if (arg1 < 0)
3372             return 0;
3373           
3374           arg1 %= width;
3375           val = ((((unsigned HOST_WIDE_INT) arg0) << arg1)
3376                  | (((unsigned HOST_WIDE_INT) arg0) >> (width - arg1)));
3377           break;
3378           
3379         case COMPARE:
3380           /* Do nothing here.  */
3381           return 0;
3382           
3383         case SMIN:
3384           val = arg0s <= arg1s ? arg0s : arg1s;
3385           break;
3386           
3387         case UMIN:
3388           val = ((unsigned HOST_WIDE_INT) arg0
3389                  <= (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
3390           break;
3391           
3392         case SMAX:
3393           val = arg0s > arg1s ? arg0s : arg1s;
3394           break;
3395           
3396         case UMAX:
3397           val = ((unsigned HOST_WIDE_INT) arg0
3398                  > (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
3399           break;
3400           
3401         case SS_PLUS:
3402         case US_PLUS:
3403         case SS_MINUS:
3404         case US_MINUS:
3405         case SS_MULT:
3406         case US_MULT:
3407         case SS_DIV:
3408         case US_DIV:
3409         case SS_ASHIFT:
3410         case US_ASHIFT:
3411           /* ??? There are simplifications that can be done.  */
3412           return 0;
3413           
3414         default:
3415           gcc_unreachable ();
3416         }
3417
3418       return gen_int_mode (val, mode);
3419     }
3420
3421   return NULL_RTX;
3422 }
3423
3424
3425 \f
3426 /* Simplify a PLUS or MINUS, at least one of whose operands may be another
3427    PLUS or MINUS.
3428
3429    Rather than test for specific case, we do this by a brute-force method
3430    and do all possible simplifications until no more changes occur.  Then
3431    we rebuild the operation.  */
3432
3433 struct simplify_plus_minus_op_data
3434 {
3435   rtx op;
3436   short neg;
3437 };
3438
3439 static bool
3440 simplify_plus_minus_op_data_cmp (rtx x, rtx y)
3441 {
3442   int result;
3443
3444   result = (commutative_operand_precedence (y)
3445             - commutative_operand_precedence (x));
3446   if (result)
3447     return result > 0;
3448
3449   /* Group together equal REGs to do more simplification.  */
3450   if (REG_P (x) && REG_P (y))
3451     return REGNO (x) > REGNO (y);
3452   else
3453     return false;
3454 }
3455
3456 static rtx
3457 simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
3458                      rtx op1)
3459 {
3460   struct simplify_plus_minus_op_data ops[8];
3461   rtx result, tem;
3462   int n_ops = 2, input_ops = 2;
3463   int changed, n_constants = 0, canonicalized = 0;
3464   int i, j;
3465
3466   memset (ops, 0, sizeof ops);
3467
3468   /* Set up the two operands and then expand them until nothing has been
3469      changed.  If we run out of room in our array, give up; this should
3470      almost never happen.  */
3471
3472   ops[0].op = op0;
3473   ops[0].neg = 0;
3474   ops[1].op = op1;
3475   ops[1].neg = (code == MINUS);
3476
3477   do
3478     {
3479       changed = 0;
3480
3481       for (i = 0; i < n_ops; i++)
3482         {
3483           rtx this_op = ops[i].op;
3484           int this_neg = ops[i].neg;
3485           enum rtx_code this_code = GET_CODE (this_op);
3486
3487           switch (this_code)
3488             {
3489             case PLUS:
3490             case MINUS:
3491               if (n_ops == 7)
3492                 return NULL_RTX;
3493
3494               ops[n_ops].op = XEXP (this_op, 1);
3495               ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
3496               n_ops++;
3497
3498               ops[i].op = XEXP (this_op, 0);
3499               input_ops++;
3500               changed = 1;
3501               canonicalized |= this_neg;
3502               break;
3503
3504             case NEG:
3505               ops[i].op = XEXP (this_op, 0);
3506               ops[i].neg = ! this_neg;
3507               changed = 1;
3508               canonicalized = 1;
3509               break;
3510
3511             case CONST:
3512               if (n_ops < 7
3513                   && GET_CODE (XEXP (this_op, 0)) == PLUS
3514                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
3515                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
3516                 {
3517                   ops[i].op = XEXP (XEXP (this_op, 0), 0);
3518                   ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
3519                   ops[n_ops].neg = this_neg;
3520                   n_ops++;
3521                   changed = 1;
3522                   canonicalized = 1;
3523                 }
3524               break;
3525
3526             case NOT:
3527               /* ~a -> (-a - 1) */
3528               if (n_ops != 7)
3529                 {
3530                   ops[n_ops].op = constm1_rtx;
3531                   ops[n_ops++].neg = this_neg;
3532                   ops[i].op = XEXP (this_op, 0);
3533                   ops[i].neg = !this_neg;
3534                   changed = 1;
3535                   canonicalized = 1;
3536                 }
3537               break;
3538
3539             case CONST_INT:
3540               n_constants++;
3541               if (this_neg)
3542                 {
3543                   ops[i].op = neg_const_int (mode, this_op);
3544                   ops[i].neg = 0;
3545                   changed = 1;
3546                   canonicalized = 1;
3547                 }
3548               break;
3549
3550             default:
3551               break;
3552             }
3553         }
3554     }
3555   while (changed);
3556
3557   if (n_constants > 1)
3558     canonicalized = 1;
3559
3560   gcc_assert (n_ops >= 2);
3561
3562   /* If we only have two operands, we can avoid the loops.  */
3563   if (n_ops == 2)
3564     {
3565       enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
3566       rtx lhs, rhs;
3567
3568       /* Get the two operands.  Be careful with the order, especially for
3569          the cases where code == MINUS.  */
3570       if (ops[0].neg && ops[1].neg)
3571         {
3572           lhs = gen_rtx_NEG (mode, ops[0].op);
3573           rhs = ops[1].op;
3574         }
3575       else if (ops[0].neg)
3576         {
3577           lhs = ops[1].op;
3578           rhs = ops[0].op;
3579         }
3580       else
3581         {
3582           lhs = ops[0].op;
3583           rhs = ops[1].op;
3584         }
3585
3586       return simplify_const_binary_operation (code, mode, lhs, rhs);
3587     }
3588
3589   /* Now simplify each pair of operands until nothing changes.  */
3590   do
3591     {
3592       /* Insertion sort is good enough for an eight-element array.  */
3593       for (i = 1; i < n_ops; i++)
3594         {
3595           struct simplify_plus_minus_op_data save;
3596           j = i - 1;
3597           if (!simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op))
3598             continue;
3599
3600           canonicalized = 1;
3601           save = ops[i];
3602           do
3603             ops[j + 1] = ops[j];
3604           while (j-- && simplify_plus_minus_op_data_cmp (ops[j].op, save.op));
3605           ops[j + 1] = save;
3606         }
3607
3608       changed = 0;
3609       for (i = n_ops - 1; i > 0; i--)
3610         for (j = i - 1; j >= 0; j--)
3611           {
3612             rtx lhs = ops[j].op, rhs = ops[i].op;
3613             int lneg = ops[j].neg, rneg = ops[i].neg;
3614
3615             if (lhs != 0 && rhs != 0)
3616               {
3617                 enum rtx_code ncode = PLUS;
3618
3619                 if (lneg != rneg)
3620                   {
3621                     ncode = MINUS;
3622                     if (lneg)
3623                       tem = lhs, lhs = rhs, rhs = tem;
3624                   }
3625                 else if (swap_commutative_operands_p (lhs, rhs))
3626                   tem = lhs, lhs = rhs, rhs = tem;
3627
3628                 if ((GET_CODE (lhs) == CONST || GET_CODE (lhs) == CONST_INT)
3629                     && (GET_CODE (rhs) == CONST || GET_CODE (rhs) == CONST_INT))
3630                   {
3631                     rtx tem_lhs, tem_rhs;
3632
3633                     tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
3634                     tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
3635                     tem = simplify_binary_operation (ncode, mode, tem_lhs, tem_rhs);
3636
3637                     if (tem && !CONSTANT_P (tem))
3638                       tem = gen_rtx_CONST (GET_MODE (tem), tem);
3639                   }
3640                 else
3641                   tem = simplify_binary_operation (ncode, mode, lhs, rhs);
3642                 
3643                 /* Reject "simplifications" that just wrap the two
3644                    arguments in a CONST.  Failure to do so can result
3645                    in infinite recursion with simplify_binary_operation
3646                    when it calls us to simplify CONST operations.  */
3647                 if (tem
3648                     && ! (GET_CODE (tem) == CONST
3649                           && GET_CODE (XEXP (tem, 0)) == ncode
3650                           && XEXP (XEXP (tem, 0), 0) == lhs
3651                           && XEXP (XEXP (tem, 0), 1) == rhs))
3652                   {
3653                     lneg &= rneg;
3654                     if (GET_CODE (tem) == NEG)
3655                       tem = XEXP (tem, 0), lneg = !lneg;
3656                     if (GET_CODE (tem) == CONST_INT && lneg)
3657                       tem = neg_const_int (mode, tem), lneg = 0;
3658
3659                     ops[i].op = tem;
3660                     ops[i].neg = lneg;
3661                     ops[j].op = NULL_RTX;
3662                     changed = 1;
3663                     canonicalized = 1;
3664                   }
3665               }
3666           }
3667
3668       /* If nothing changed, fail.  */
3669       if (!canonicalized)
3670         return NULL_RTX;
3671
3672       /* Pack all the operands to the lower-numbered entries.  */
3673       for (i = 0, j = 0; j < n_ops; j++)
3674         if (ops[j].op)
3675           {
3676             ops[i] = ops[j];
3677             i++;
3678           }
3679       n_ops = i;
3680     }
3681   while (changed);
3682
3683   /* Create (minus -C X) instead of (neg (const (plus X C))).  */
3684   if (n_ops == 2
3685       && GET_CODE (ops[1].op) == CONST_INT
3686       && CONSTANT_P (ops[0].op)
3687       && ops[0].neg)
3688     return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
3689   
3690   /* We suppressed creation of trivial CONST expressions in the
3691      combination loop to avoid recursion.  Create one manually now.
3692      The combination loop should have ensured that there is exactly
3693      one CONST_INT, and the sort will have ensured that it is last
3694      in the array and that any other constant will be next-to-last.  */
3695
3696   if (n_ops > 1
3697       && GET_CODE (ops[n_ops - 1].op) == CONST_INT
3698       && CONSTANT_P (ops[n_ops - 2].op))
3699     {
3700       rtx value = ops[n_ops - 1].op;
3701       if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
3702         value = neg_const_int (mode, value);
3703       ops[n_ops - 2].op = plus_constant (ops[n_ops - 2].op, INTVAL (value));
3704       n_ops--;
3705     }
3706
3707   /* Put a non-negated operand first, if possible.  */
3708
3709   for (i = 0; i < n_ops && ops[i].neg; i++)
3710     continue;
3711   if (i == n_ops)
3712     ops[0].op = gen_rtx_NEG (mode, ops[0].op);
3713   else if (i != 0)
3714     {
3715       tem = ops[0].op;
3716       ops[0] = ops[i];
3717       ops[i].op = tem;
3718       ops[i].neg = 1;
3719     }
3720
3721   /* Now make the result by performing the requested operations.  */
3722   result = ops[0].op;
3723   for (i = 1; i < n_ops; i++)
3724     result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
3725                              mode, result, ops[i].op);
3726
3727   return result;
3728 }
3729
3730 /* Check whether an operand is suitable for calling simplify_plus_minus.  */
3731 static bool
3732 plus_minus_operand_p (const_rtx x)
3733 {
3734   return GET_CODE (x) == PLUS
3735          || GET_CODE (x) == MINUS
3736          || (GET_CODE (x) == CONST
3737              && GET_CODE (XEXP (x, 0)) == PLUS
3738              && CONSTANT_P (XEXP (XEXP (x, 0), 0))
3739              && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
3740 }
3741
3742 /* Like simplify_binary_operation except used for relational operators.
3743    MODE is the mode of the result. If MODE is VOIDmode, both operands must
3744    not also be VOIDmode.
3745
3746    CMP_MODE specifies in which mode the comparison is done in, so it is
3747    the mode of the operands.  If CMP_MODE is VOIDmode, it is taken from
3748    the operands or, if both are VOIDmode, the operands are compared in
3749    "infinite precision".  */
3750 rtx
3751 simplify_relational_operation (enum rtx_code code, enum machine_mode mode,
3752                                enum machine_mode cmp_mode, rtx op0, rtx op1)
3753 {
3754   rtx tem, trueop0, trueop1;
3755
3756   if (cmp_mode == VOIDmode)
3757     cmp_mode = GET_MODE (op0);
3758   if (cmp_mode == VOIDmode)
3759     cmp_mode = GET_MODE (op1);
3760
3761   tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
3762   if (tem)
3763     {
3764       if (SCALAR_FLOAT_MODE_P (mode))
3765         {
3766           if (tem == const0_rtx)
3767             return CONST0_RTX (mode);
3768 #ifdef FLOAT_STORE_FLAG_VALUE
3769           {
3770             REAL_VALUE_TYPE val;
3771             val = FLOAT_STORE_FLAG_VALUE (mode);
3772             return CONST_DOUBLE_FROM_REAL_VALUE (val, mode);
3773           }
3774 #else
3775           return NULL_RTX;
3776 #endif 
3777         }
3778       if (VECTOR_MODE_P (mode))
3779         {
3780           if (tem == const0_rtx)
3781             return CONST0_RTX (mode);
3782 #ifdef VECTOR_STORE_FLAG_VALUE
3783           {
3784             int i, units;
3785             rtvec v;
3786
3787             rtx val = VECTOR_STORE_FLAG_VALUE (mode);
3788             if (val == NULL_RTX)
3789               return NULL_RTX;
3790             if (val == const1_rtx)
3791               return CONST1_RTX (mode);
3792
3793             units = GET_MODE_NUNITS (mode);
3794             v = rtvec_alloc (units);
3795             for (i = 0; i < units; i++)
3796               RTVEC_ELT (v, i) = val;
3797             return gen_rtx_raw_CONST_VECTOR (mode, v);
3798           }
3799 #else
3800           return NULL_RTX;
3801 #endif
3802         }
3803
3804       return tem;
3805     }
3806
3807   /* For the following tests, ensure const0_rtx is op1.  */
3808   if (swap_commutative_operands_p (op0, op1)
3809       || (op0 == const0_rtx && op1 != const0_rtx))
3810     tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
3811
3812   /* If op0 is a compare, extract the comparison arguments from it.  */
3813   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
3814     return simplify_relational_operation (code, mode, VOIDmode,
3815                                           XEXP (op0, 0), XEXP (op0, 1));
3816
3817   if (GET_MODE_CLASS (cmp_mode) == MODE_CC
3818       || CC0_P (op0))
3819     return NULL_RTX;
3820
3821   trueop0 = avoid_constant_pool_reference (op0);
3822   trueop1 = avoid_constant_pool_reference (op1);
3823   return simplify_relational_operation_1 (code, mode, cmp_mode,
3824                                           trueop0, trueop1);
3825 }
3826
3827 /* This part of simplify_relational_operation is only used when CMP_MODE
3828    is not in class MODE_CC (i.e. it is a real comparison).
3829
3830    MODE is the mode of the result, while CMP_MODE specifies in which
3831    mode the comparison is done in, so it is the mode of the operands.  */
3832
3833 static rtx
3834 simplify_relational_operation_1 (enum rtx_code code, enum machine_mode mode,
3835                                  enum machine_mode cmp_mode, rtx op0, rtx op1)
3836 {
3837   enum rtx_code op0code = GET_CODE (op0);
3838
3839   if (op1 == const0_rtx && COMPARISON_P (op0))
3840     {
3841       /* If op0 is a comparison, extract the comparison arguments
3842          from it.  */
3843       if (code == NE)
3844         {
3845           if (GET_MODE (op0) == mode)
3846             return simplify_rtx (op0);
3847           else
3848             return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
3849                                             XEXP (op0, 0), XEXP (op0, 1));
3850         }
3851       else if (code == EQ)
3852         {
3853           enum rtx_code new_code = reversed_comparison_code (op0, NULL_RTX);
3854           if (new_code != UNKNOWN)
3855             return simplify_gen_relational (new_code, mode, VOIDmode,
3856                                             XEXP (op0, 0), XEXP (op0, 1));
3857         }
3858     }
3859
3860   /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a).  */
3861   if ((code == LTU || code == GEU)
3862       && GET_CODE (op0) == PLUS
3863       && rtx_equal_p (op1, XEXP (op0, 1))
3864       /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b).  */
3865       && !rtx_equal_p (op1, XEXP (op0, 0)))
3866     return simplify_gen_relational (code, mode, cmp_mode, op0,
3867                                     copy_rtx (XEXP (op0, 0)));
3868
3869   if (op1 == const0_rtx)
3870     {
3871       /* Canonicalize (GTU x 0) as (NE x 0).  */
3872       if (code == GTU)
3873         return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
3874       /* Canonicalize (LEU x 0) as (EQ x 0).  */
3875       if (code == LEU)
3876         return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
3877     }
3878   else if (op1 == const1_rtx)
3879     {
3880       switch (code)
3881         {
3882         case GE:
3883           /* Canonicalize (GE x 1) as (GT x 0).  */
3884           return simplify_gen_relational (GT, mode, cmp_mode,
3885                                           op0, const0_rtx);
3886         case GEU:
3887           /* Canonicalize (GEU x 1) as (NE x 0).  */
3888           return simplify_gen_relational (NE, mode, cmp_mode,
3889                                           op0, const0_rtx);
3890         case LT:
3891           /* Canonicalize (LT x 1) as (LE x 0).  */
3892           return simplify_gen_relational (LE, mode, cmp_mode,
3893                                           op0, const0_rtx);
3894         case LTU:
3895           /* Canonicalize (LTU x 1) as (EQ x 0).  */
3896           return simplify_gen_relational (EQ, mode, cmp_mode,
3897                                           op0, const0_rtx);
3898         default:
3899           break;
3900         }
3901     }
3902   else if (op1 == constm1_rtx)
3903     {
3904       /* Canonicalize (LE x -1) as (LT x 0).  */
3905       if (code == LE)
3906         return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
3907       /* Canonicalize (GT x -1) as (GE x 0).  */
3908       if (code == GT)
3909         return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
3910     }
3911
3912   /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1))  */
3913   if ((code == EQ || code == NE)
3914       && (op0code == PLUS || op0code == MINUS)
3915       && CONSTANT_P (op1)
3916       && CONSTANT_P (XEXP (op0, 1))
3917       && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
3918     {
3919       rtx x = XEXP (op0, 0);
3920       rtx c = XEXP (op0, 1);
3921
3922       c = simplify_gen_binary (op0code == PLUS ? MINUS : PLUS,
3923                                cmp_mode, op1, c);
3924       return simplify_gen_relational (code, mode, cmp_mode, x, c);
3925     }
3926
3927   /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
3928      the same as (zero_extract:SI FOO (const_int 1) BAR).  */
3929   if (code == NE
3930       && op1 == const0_rtx
3931       && GET_MODE_CLASS (mode) == MODE_INT
3932       && cmp_mode != VOIDmode
3933       /* ??? Work-around BImode bugs in the ia64 backend.  */
3934       && mode != BImode
3935       && cmp_mode != BImode
3936       && nonzero_bits (op0, cmp_mode) == 1
3937       && STORE_FLAG_VALUE == 1)
3938     return GET_MODE_SIZE (mode) > GET_MODE_SIZE (cmp_mode)
3939            ? simplify_gen_unary (ZERO_EXTEND, mode, op0, cmp_mode)
3940            : lowpart_subreg (mode, op0, cmp_mode);
3941
3942   /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y).  */
3943   if ((code == EQ || code == NE)
3944       && op1 == const0_rtx
3945       && op0code == XOR)
3946     return simplify_gen_relational (code, mode, cmp_mode,
3947                                     XEXP (op0, 0), XEXP (op0, 1));
3948
3949   /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0).  */
3950   if ((code == EQ || code == NE)
3951       && op0code == XOR
3952       && rtx_equal_p (XEXP (op0, 0), op1)
3953       && !side_effects_p (XEXP (op0, 0)))
3954     return simplify_gen_relational (code, mode, cmp_mode,
3955                                     XEXP (op0, 1), const0_rtx);
3956
3957   /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0).  */
3958   if ((code == EQ || code == NE)
3959       && op0code == XOR
3960       && rtx_equal_p (XEXP (op0, 1), op1)
3961       && !side_effects_p (XEXP (op0, 1)))
3962     return simplify_gen_relational (code, mode, cmp_mode,
3963                                     XEXP (op0, 0), const0_rtx);
3964
3965   /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)).  */
3966   if ((code == EQ || code == NE)
3967       && op0code == XOR
3968       && (GET_CODE (op1) == CONST_INT
3969           || GET_CODE (op1) == CONST_DOUBLE)
3970       && (GET_CODE (XEXP (op0, 1)) == CONST_INT
3971           || GET_CODE (XEXP (op0, 1)) == CONST_DOUBLE))
3972     return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
3973                                     simplify_gen_binary (XOR, cmp_mode,
3974                                                          XEXP (op0, 1), op1));
3975
3976   if (op0code == POPCOUNT && op1 == const0_rtx)
3977     switch (code)
3978       {
3979       case EQ:
3980       case LE:
3981       case LEU:
3982         /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)).  */
3983         return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
3984                                         XEXP (op0, 0), const0_rtx);
3985
3986       case NE:
3987       case GT:
3988       case GTU:
3989         /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)).  */
3990         return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
3991                                         XEXP (op0, 0), const0_rtx);
3992
3993       default:
3994         break;
3995       }
3996
3997   return NULL_RTX;
3998 }
3999
4000 enum 
4001 {
4002   CMP_EQ = 1,
4003   CMP_LT = 2,
4004   CMP_GT = 4,
4005   CMP_LTU = 8,
4006   CMP_GTU = 16
4007 };
4008
4009
4010 /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
4011    KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
4012    For KNOWN_RESULT to make sense it should be either CMP_EQ, or the 
4013    logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
4014    For floating-point comparisons, assume that the operands were ordered.  */
4015
4016 static rtx
4017 comparison_result (enum rtx_code code, int known_results)
4018 {
4019   switch (code)
4020     {
4021     case EQ:
4022     case UNEQ:
4023       return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
4024     case NE:
4025     case LTGT:
4026       return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
4027
4028     case LT:
4029     case UNLT:
4030       return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
4031     case GE:
4032     case UNGE:
4033       return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
4034
4035     case GT:
4036     case UNGT:
4037       return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
4038     case LE:
4039     case UNLE:
4040       return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
4041
4042     case LTU:
4043       return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
4044     case GEU:
4045       return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
4046
4047     case GTU:
4048       return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
4049     case LEU:
4050       return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
4051
4052     case ORDERED:
4053       return const_true_rtx;
4054     case UNORDERED:
4055       return const0_rtx;
4056     default:
4057       gcc_unreachable ();
4058     }
4059 }
4060
4061 /* Check if the given comparison (done in the given MODE) is actually a
4062    tautology or a contradiction.
4063    If no simplification is possible, this function returns zero.
4064    Otherwise, it returns either const_true_rtx or const0_rtx.  */
4065
4066 rtx
4067 simplify_const_relational_operation (enum rtx_code code,
4068                                      enum machine_mode mode,
4069                                      rtx op0, rtx op1)
4070 {
4071   rtx tem;
4072   rtx trueop0;
4073   rtx trueop1;
4074
4075   gcc_assert (mode != VOIDmode
4076               || (GET_MODE (op0) == VOIDmode
4077                   && GET_MODE (op1) == VOIDmode));
4078
4079   /* If op0 is a compare, extract the comparison arguments from it.  */
4080   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
4081     {
4082       op1 = XEXP (op0, 1);
4083       op0 = XEXP (op0, 0);
4084
4085       if (GET_MODE (op0) != VOIDmode)
4086         mode = GET_MODE (op0);
4087       else if (GET_MODE (op1) != VOIDmode)
4088         mode = GET_MODE (op1);
4089       else
4090         return 0;
4091     }
4092
4093   /* We can't simplify MODE_CC values since we don't know what the
4094      actual comparison is.  */
4095   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC || CC0_P (op0))
4096     return 0;
4097
4098   /* Make sure the constant is second.  */
4099   if (swap_commutative_operands_p (op0, op1))
4100     {
4101       tem = op0, op0 = op1, op1 = tem;
4102       code = swap_condition (code);
4103     }
4104
4105   trueop0 = avoid_constant_pool_reference (op0);
4106   trueop1 = avoid_constant_pool_reference (op1);
4107
4108   /* For integer comparisons of A and B maybe we can simplify A - B and can
4109      then simplify a comparison of that with zero.  If A and B are both either
4110      a register or a CONST_INT, this can't help; testing for these cases will
4111      prevent infinite recursion here and speed things up.
4112
4113      We can only do this for EQ and NE comparisons as otherwise we may
4114      lose or introduce overflow which we cannot disregard as undefined as
4115      we do not know the signedness of the operation on either the left or
4116      the right hand side of the comparison.  */
4117
4118   if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
4119       && (code == EQ || code == NE)
4120       && ! ((REG_P (op0) || GET_CODE (trueop0) == CONST_INT)
4121             && (REG_P (op1) || GET_CODE (trueop1) == CONST_INT))
4122       && 0 != (tem = simplify_binary_operation (MINUS, mode, op0, op1))
4123       /* We cannot do this if tem is a nonzero address.  */
4124       && ! nonzero_address_p (tem))
4125     return simplify_const_relational_operation (signed_condition (code),
4126                                                 mode, tem, const0_rtx);
4127
4128   if (! HONOR_NANS (mode) && code == ORDERED)
4129     return const_true_rtx;
4130
4131   if (! HONOR_NANS (mode) && code == UNORDERED)
4132     return const0_rtx;
4133
4134   /* For modes without NaNs, if the two operands are equal, we know the
4135      result except if they have side-effects.  Even with NaNs we know
4136      the result of unordered comparisons and, if signaling NaNs are
4137      irrelevant, also the result of LT/GT/LTGT.  */
4138   if ((! HONOR_NANS (GET_MODE (trueop0))
4139        || code == UNEQ || code == UNLE || code == UNGE
4140        || ((code == LT || code == GT || code == LTGT)
4141            && ! HONOR_SNANS (GET_MODE (trueop0))))
4142       && rtx_equal_p (trueop0, trueop1)
4143       && ! side_effects_p (trueop0))
4144     return comparison_result (code, CMP_EQ);
4145
4146   /* If the operands are floating-point constants, see if we can fold
4147      the result.  */
4148   if (GET_CODE (trueop0) == CONST_DOUBLE
4149       && GET_CODE (trueop1) == CONST_DOUBLE
4150       && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
4151     {
4152       REAL_VALUE_TYPE d0, d1;
4153
4154       REAL_VALUE_FROM_CONST_DOUBLE (d0, trueop0);
4155       REAL_VALUE_FROM_CONST_DOUBLE (d1, trueop1);
4156
4157       /* Comparisons are unordered iff at least one of the values is NaN.  */
4158       if (REAL_VALUE_ISNAN (d0) || REAL_VALUE_ISNAN (d1))
4159         switch (code)
4160           {
4161           case UNEQ:
4162           case UNLT:
4163           case UNGT:
4164           case UNLE:
4165           case UNGE:
4166           case NE:
4167           case UNORDERED:
4168             return const_true_rtx;
4169           case EQ:
4170           case LT:
4171           case GT:
4172           case LE:
4173           case GE:
4174           case LTGT:
4175           case ORDERED:
4176             return const0_rtx;
4177           default:
4178             return 0;
4179           }
4180
4181       return comparison_result (code,
4182                                 (REAL_VALUES_EQUAL (d0, d1) ? CMP_EQ :
4183                                  REAL_VALUES_LESS (d0, d1) ? CMP_LT : CMP_GT));
4184     }
4185
4186   /* Otherwise, see if the operands are both integers.  */
4187   if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
4188        && (GET_CODE (trueop0) == CONST_DOUBLE
4189            || GET_CODE (trueop0) == CONST_INT)
4190        && (GET_CODE (trueop1) == CONST_DOUBLE
4191            || GET_CODE (trueop1) == CONST_INT))
4192     {
4193       int width = GET_MODE_BITSIZE (mode);
4194       HOST_WIDE_INT l0s, h0s, l1s, h1s;
4195       unsigned HOST_WIDE_INT l0u, h0u, l1u, h1u;
4196
4197       /* Get the two words comprising each integer constant.  */
4198       if (GET_CODE (trueop0) == CONST_DOUBLE)
4199         {
4200           l0u = l0s = CONST_DOUBLE_LOW (trueop0);
4201           h0u = h0s = CONST_DOUBLE_HIGH (trueop0);
4202         }
4203       else
4204         {
4205           l0u = l0s = INTVAL (trueop0);
4206           h0u = h0s = HWI_SIGN_EXTEND (l0s);
4207         }
4208
4209       if (GET_CODE (trueop1) == CONST_DOUBLE)
4210         {
4211           l1u = l1s = CONST_DOUBLE_LOW (trueop1);
4212           h1u = h1s = CONST_DOUBLE_HIGH (trueop1);
4213         }
4214       else
4215         {
4216           l1u = l1s = INTVAL (trueop1);
4217           h1u = h1s = HWI_SIGN_EXTEND (l1s);
4218         }
4219
4220       /* If WIDTH is nonzero and smaller than HOST_BITS_PER_WIDE_INT,
4221          we have to sign or zero-extend the values.  */
4222       if (width != 0 && width < HOST_BITS_PER_WIDE_INT)
4223         {
4224           l0u &= ((HOST_WIDE_INT) 1 << width) - 1;
4225           l1u &= ((HOST_WIDE_INT) 1 << width) - 1;
4226
4227           if (l0s & ((HOST_WIDE_INT) 1 << (width - 1)))
4228             l0s |= ((HOST_WIDE_INT) (-1) << width);
4229
4230           if (l1s & ((HOST_WIDE_INT) 1 << (width - 1)))
4231             l1s |= ((HOST_WIDE_INT) (-1) << width);
4232         }
4233       if (width != 0 && width <= HOST_BITS_PER_WIDE_INT)
4234         h0u = h1u = 0, h0s = HWI_SIGN_EXTEND (l0s), h1s = HWI_SIGN_EXTEND (l1s);
4235
4236       if (h0u == h1u && l0u == l1u)
4237         return comparison_result (code, CMP_EQ);
4238       else
4239         {
4240           int cr;
4241           cr = (h0s < h1s || (h0s == h1s && l0u < l1u)) ? CMP_LT : CMP_GT;
4242           cr |= (h0u < h1u || (h0u == h1u && l0u < l1u)) ? CMP_LTU : CMP_GTU;
4243           return comparison_result (code, cr);
4244         }
4245     }
4246
4247   /* Optimize comparisons with upper and lower bounds.  */
4248   if (SCALAR_INT_MODE_P (mode)
4249       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
4250       && GET_CODE (trueop1) == CONST_INT)
4251     {
4252       int sign;
4253       unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, mode);
4254       HOST_WIDE_INT val = INTVAL (trueop1);
4255       HOST_WIDE_INT mmin, mmax;
4256
4257       if (code == GEU
4258           || code == LEU
4259           || code == GTU
4260           || code == LTU)
4261         sign = 0;
4262       else
4263         sign = 1;
4264
4265       /* Get a reduced range if the sign bit is zero.  */
4266       if (nonzero <= (GET_MODE_MASK (mode) >> 1))
4267         {
4268           mmin = 0;
4269           mmax = nonzero;
4270         }
4271       else
4272         {
4273           rtx mmin_rtx, mmax_rtx;
4274           get_mode_bounds (mode, sign, mode, &mmin_rtx, &mmax_rtx);
4275
4276           mmin = INTVAL (mmin_rtx);
4277           mmax = INTVAL (mmax_rtx);
4278           if (sign)
4279             {
4280               unsigned int sign_copies = num_sign_bit_copies (trueop0, mode);
4281
4282               mmin >>= (sign_copies - 1);
4283               mmax >>= (sign_copies - 1);
4284             }
4285         }
4286
4287       switch (code)
4288         {
4289         /* x >= y is always true for y <= mmin, always false for y > mmax.  */
4290         case GEU:
4291           if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
4292             return const_true_rtx;
4293           if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
4294             return const0_rtx;
4295           break;
4296         case GE:
4297           if (val <= mmin)
4298             return const_true_rtx;
4299           if (val > mmax)
4300             return const0_rtx;
4301           break;
4302
4303         /* x <= y is always true for y >= mmax, always false for y < mmin.  */
4304         case LEU:
4305           if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
4306             return const_true_rtx;
4307           if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
4308             return const0_rtx;
4309           break;
4310         case LE:
4311           if (val >= mmax)
4312             return const_true_rtx;
4313           if (val < mmin)
4314             return const0_rtx;
4315           break;
4316
4317         case EQ:
4318           /* x == y is always false for y out of range.  */
4319           if (val < mmin || val > mmax)
4320             return const0_rtx;
4321           break;
4322
4323         /* x > y is always false for y >= mmax, always true for y < mmin.  */
4324         case GTU:
4325           if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
4326             return const0_rtx;
4327           if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
4328             return const_true_rtx;
4329           break;
4330         case GT:
4331           if (val >= mmax)
4332             return const0_rtx;
4333           if (val < mmin)
4334             return const_true_rtx;
4335           break;
4336
4337         /* x < y is always false for y <= mmin, always true for y > mmax.  */
4338         case LTU:
4339           if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
4340             return const0_rtx;
4341           if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
4342             return const_true_rtx;
4343           break;
4344         case LT:
4345           if (val <= mmin)
4346             return const0_rtx;
4347           if (val > mmax)
4348             return const_true_rtx;
4349           break;
4350
4351         case NE:
4352           /* x != y is always true for y out of range.  */
4353           if (val < mmin || val > mmax)
4354             return const_true_rtx;
4355           break;
4356
4357         default:
4358           break;
4359         }
4360     }
4361
4362   /* Optimize integer comparisons with zero.  */
4363   if (trueop1 == const0_rtx)
4364     {
4365       /* Some addresses are known to be nonzero.  We don't know
4366          their sign, but equality comparisons are known.  */
4367       if (nonzero_address_p (trueop0))
4368         {
4369           if (code == EQ || code == LEU)
4370             return const0_rtx;
4371           if (code == NE || code == GTU)
4372             return const_true_rtx;
4373         }
4374
4375       /* See if the first operand is an IOR with a constant.  If so, we
4376          may be able to determine the result of this comparison.  */
4377       if (GET_CODE (op0) == IOR)
4378         {
4379           rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
4380           if (GET_CODE (inner_const) == CONST_INT && inner_const != const0_rtx)
4381             {
4382               int sign_bitnum = GET_MODE_BITSIZE (mode) - 1;
4383               int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
4384                               && (INTVAL (inner_const)
4385                                   & ((HOST_WIDE_INT) 1 << sign_bitnum)));
4386
4387               switch (code)
4388                 {
4389                 case EQ:
4390                 case LEU:
4391                   return const0_rtx;
4392                 case NE:
4393                 case GTU:
4394                   return const_true_rtx;
4395                 case LT:
4396                 case LE:
4397                   if (has_sign)
4398                     return const_true_rtx;
4399                   break;
4400                 case GT:
4401                 case GE:
4402                   if (has_sign)
4403                     return const0_rtx;
4404                   break;
4405                 default:
4406                   break;
4407                 }
4408             }
4409         }
4410     }
4411
4412   /* Optimize comparison of ABS with zero.  */
4413   if (trueop1 == CONST0_RTX (mode)
4414       && (GET_CODE (trueop0) == ABS
4415           || (GET_CODE (trueop0) == FLOAT_EXTEND
4416               && GET_CODE (XEXP (trueop0, 0)) == ABS)))
4417     {
4418       switch (code)
4419         {
4420         case LT:
4421           /* Optimize abs(x) < 0.0.  */
4422           if (!HONOR_SNANS (mode)
4423               && (!INTEGRAL_MODE_P (mode)
4424                   || (!flag_wrapv && !flag_trapv && flag_strict_overflow)))
4425             {
4426               if (INTEGRAL_MODE_P (mode)
4427                   && (issue_strict_overflow_warning
4428                       (WARN_STRICT_OVERFLOW_CONDITIONAL)))
4429                 warning (OPT_Wstrict_overflow,
4430                          ("assuming signed overflow does not occur when "
4431                           "assuming abs (x) < 0 is false"));
4432                return const0_rtx;
4433             }
4434           break;
4435
4436         case GE:
4437           /* Optimize abs(x) >= 0.0.  */
4438           if (!HONOR_NANS (mode)
4439               && (!INTEGRAL_MODE_P (mode)
4440                   || (!flag_wrapv && !flag_trapv && flag_strict_overflow)))
4441             {
4442               if (INTEGRAL_MODE_P (mode)
4443                   && (issue_strict_overflow_warning
4444                   (WARN_STRICT_OVERFLOW_CONDITIONAL)))
4445                 warning (OPT_Wstrict_overflow,
4446                          ("assuming signed overflow does not occur when "
4447                           "assuming abs (x) >= 0 is true"));
4448               return const_true_rtx;
4449             }
4450           break;
4451
4452         case UNGE:
4453           /* Optimize ! (abs(x) < 0.0).  */
4454           return const_true_rtx;
4455
4456         default:
4457           break;
4458         }
4459     }
4460
4461   return 0;
4462 }
4463 \f
4464 /* Simplify CODE, an operation with result mode MODE and three operands,
4465    OP0, OP1, and OP2.  OP0_MODE was the mode of OP0 before it became
4466    a constant.  Return 0 if no simplifications is possible.  */
4467
4468 rtx
4469 simplify_ternary_operation (enum rtx_code code, enum machine_mode mode,
4470                             enum machine_mode op0_mode, rtx op0, rtx op1,
4471                             rtx op2)
4472 {
4473   unsigned int width = GET_MODE_BITSIZE (mode);
4474
4475   /* VOIDmode means "infinite" precision.  */
4476   if (width == 0)
4477     width = HOST_BITS_PER_WIDE_INT;
4478
4479   switch (code)
4480     {
4481     case SIGN_EXTRACT:
4482     case ZERO_EXTRACT:
4483       if (GET_CODE (op0) == CONST_INT
4484           && GET_CODE (op1) == CONST_INT
4485           && GET_CODE (op2) == CONST_INT
4486           && ((unsigned) INTVAL (op1) + (unsigned) INTVAL (op2) <= width)
4487           && width <= (unsigned) HOST_BITS_PER_WIDE_INT)
4488         {
4489           /* Extracting a bit-field from a constant */
4490           HOST_WIDE_INT val = INTVAL (op0);
4491
4492           if (BITS_BIG_ENDIAN)
4493             val >>= (GET_MODE_BITSIZE (op0_mode)
4494                      - INTVAL (op2) - INTVAL (op1));
4495           else
4496             val >>= INTVAL (op2);
4497
4498           if (HOST_BITS_PER_WIDE_INT != INTVAL (op1))
4499             {
4500               /* First zero-extend.  */
4501               val &= ((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1;
4502               /* If desired, propagate sign bit.  */
4503               if (code == SIGN_EXTRACT
4504                   && (val & ((HOST_WIDE_INT) 1 << (INTVAL (op1) - 1))))
4505                 val |= ~ (((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1);
4506             }
4507
4508           /* Clear the bits that don't belong in our mode,
4509              unless they and our sign bit are all one.
4510              So we get either a reasonable negative value or a reasonable
4511              unsigned value for this mode.  */
4512           if (width < HOST_BITS_PER_WIDE_INT
4513               && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
4514                   != ((HOST_WIDE_INT) (-1) << (width - 1))))
4515             val &= ((HOST_WIDE_INT) 1 << width) - 1;
4516
4517           return gen_int_mode (val, mode);
4518         }
4519       break;
4520
4521     case IF_THEN_ELSE:
4522       if (GET_CODE (op0) == CONST_INT)
4523         return op0 != const0_rtx ? op1 : op2;
4524
4525       /* Convert c ? a : a into "a".  */
4526       if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
4527         return op1;
4528
4529       /* Convert a != b ? a : b into "a".  */
4530       if (GET_CODE (op0) == NE
4531           && ! side_effects_p (op0)
4532           && ! HONOR_NANS (mode)
4533           && ! HONOR_SIGNED_ZEROS (mode)
4534           && ((rtx_equal_p (XEXP (op0, 0), op1)
4535                && rtx_equal_p (XEXP (op0, 1), op2))
4536               || (rtx_equal_p (XEXP (op0, 0), op2)
4537                   && rtx_equal_p (XEXP (op0, 1), op1))))
4538         return op1;
4539
4540       /* Convert a == b ? a : b into "b".  */
4541       if (GET_CODE (op0) == EQ
4542           && ! side_effects_p (op0)
4543           && ! HONOR_NANS (mode)
4544           && ! HONOR_SIGNED_ZEROS (mode)
4545           && ((rtx_equal_p (XEXP (op0, 0), op1)
4546                && rtx_equal_p (XEXP (op0, 1), op2))
4547               || (rtx_equal_p (XEXP (op0, 0), op2)
4548                   && rtx_equal_p (XEXP (op0, 1), op1))))
4549         return op2;
4550
4551       if (COMPARISON_P (op0) && ! side_effects_p (op0))
4552         {
4553           enum machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
4554                                         ? GET_MODE (XEXP (op0, 1))
4555                                         : GET_MODE (XEXP (op0, 0)));
4556           rtx temp;
4557
4558           /* Look for happy constants in op1 and op2.  */
4559           if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
4560             {
4561               HOST_WIDE_INT t = INTVAL (op1);
4562               HOST_WIDE_INT f = INTVAL (op2);
4563
4564               if (t == STORE_FLAG_VALUE && f == 0)
4565                 code = GET_CODE (op0);
4566               else if (t == 0 && f == STORE_FLAG_VALUE)
4567                 {
4568                   enum rtx_code tmp;
4569                   tmp = reversed_comparison_code (op0, NULL_RTX);
4570                   if (tmp == UNKNOWN)
4571                     break;
4572                   code = tmp;
4573                 }
4574               else
4575                 break;
4576
4577               return simplify_gen_relational (code, mode, cmp_mode,
4578                                               XEXP (op0, 0), XEXP (op0, 1));
4579             }
4580
4581           if (cmp_mode == VOIDmode)
4582             cmp_mode = op0_mode;
4583           temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
4584                                                 cmp_mode, XEXP (op0, 0),
4585                                                 XEXP (op0, 1));
4586
4587           /* See if any simplifications were possible.  */
4588           if (temp)
4589             {
4590               if (GET_CODE (temp) == CONST_INT)
4591                 return temp == const0_rtx ? op2 : op1;
4592               else if (temp)
4593                 return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
4594             }
4595         }
4596       break;
4597
4598     case VEC_MERGE:
4599       gcc_assert (GET_MODE (op0) == mode);
4600       gcc_assert (GET_MODE (op1) == mode);
4601       gcc_assert (VECTOR_MODE_P (mode));
4602       op2 = avoid_constant_pool_reference (op2);
4603       if (GET_CODE (op2) == CONST_INT)
4604         {
4605           int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
4606           unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
4607           int mask = (1 << n_elts) - 1;
4608
4609           if (!(INTVAL (op2) & mask))
4610             return op1;
4611           if ((INTVAL (op2) & mask) == mask)
4612             return op0;
4613
4614           op0 = avoid_constant_pool_reference (op0);
4615           op1 = avoid_constant_pool_reference (op1);
4616           if (GET_CODE (op0) == CONST_VECTOR
4617               && GET_CODE (op1) == CONST_VECTOR)
4618             {
4619               rtvec v = rtvec_alloc (n_elts);
4620               unsigned int i;
4621
4622               for (i = 0; i < n_elts; i++)
4623                 RTVEC_ELT (v, i) = (INTVAL (op2) & (1 << i)
4624                                     ? CONST_VECTOR_ELT (op0, i)
4625                                     : CONST_VECTOR_ELT (op1, i));
4626               return gen_rtx_CONST_VECTOR (mode, v);
4627             }
4628         }
4629       break;
4630
4631     default:
4632       gcc_unreachable ();
4633     }
4634
4635   return 0;
4636 }
4637
4638 /* Evaluate a SUBREG of a CONST_INT or CONST_DOUBLE or CONST_FIXED
4639    or CONST_VECTOR,
4640    returning another CONST_INT or CONST_DOUBLE or CONST_FIXED or CONST_VECTOR.
4641
4642    Works by unpacking OP into a collection of 8-bit values
4643    represented as a little-endian array of 'unsigned char', selecting by BYTE,
4644    and then repacking them again for OUTERMODE.  */
4645
4646 static rtx
4647 simplify_immed_subreg (enum machine_mode outermode, rtx op, 
4648                        enum machine_mode innermode, unsigned int byte)
4649 {
4650   /* We support up to 512-bit values (for V8DFmode).  */
4651   enum {
4652     max_bitsize = 512,
4653     value_bit = 8,
4654     value_mask = (1 << value_bit) - 1
4655   };
4656   unsigned char value[max_bitsize / value_bit];
4657   int value_start;
4658   int i;
4659   int elem;
4660
4661   int num_elem;
4662   rtx * elems;
4663   int elem_bitsize;
4664   rtx result_s;
4665   rtvec result_v = NULL;
4666   enum mode_class outer_class;
4667   enum machine_mode outer_submode;
4668
4669   /* Some ports misuse CCmode.  */
4670   if (GET_MODE_CLASS (outermode) == MODE_CC && GET_CODE (op) == CONST_INT)
4671     return op;
4672
4673   /* We have no way to represent a complex constant at the rtl level.  */
4674   if (COMPLEX_MODE_P (outermode))
4675     return NULL_RTX;
4676
4677   /* Unpack the value.  */
4678
4679   if (GET_CODE (op) == CONST_VECTOR)
4680     {
4681       num_elem = CONST_VECTOR_NUNITS (op);
4682       elems = &CONST_VECTOR_ELT (op, 0);
4683       elem_bitsize = GET_MODE_BITSIZE (GET_MODE_INNER (innermode));
4684     }
4685   else
4686     {
4687       num_elem = 1;
4688       elems = &op;
4689       elem_bitsize = max_bitsize;
4690     }
4691   /* If this asserts, it is too complicated; reducing value_bit may help.  */
4692   gcc_assert (BITS_PER_UNIT % value_bit == 0);
4693   /* I don't know how to handle endianness of sub-units.  */
4694   gcc_assert (elem_bitsize % BITS_PER_UNIT == 0);
4695   
4696   for (elem = 0; elem < num_elem; elem++)
4697     {
4698       unsigned char * vp;
4699       rtx el = elems[elem];
4700       
4701       /* Vectors are kept in target memory order.  (This is probably
4702          a mistake.)  */
4703       {
4704         unsigned byte = (elem * elem_bitsize) / BITS_PER_UNIT;
4705         unsigned ibyte = (((num_elem - 1 - elem) * elem_bitsize) 
4706                           / BITS_PER_UNIT);
4707         unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
4708         unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
4709         unsigned bytele = (subword_byte % UNITS_PER_WORD
4710                          + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
4711         vp = value + (bytele * BITS_PER_UNIT) / value_bit;
4712       }
4713         
4714       switch (GET_CODE (el))
4715         {
4716         case CONST_INT:
4717           for (i = 0;
4718                i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize; 
4719                i += value_bit)
4720             *vp++ = INTVAL (el) >> i;
4721           /* CONST_INTs are always logically sign-extended.  */
4722           for (; i < elem_bitsize; i += value_bit)
4723             *vp++ = INTVAL (el) < 0 ? -1 : 0;
4724           break;
4725       
4726         case CONST_DOUBLE:
4727           if (GET_MODE (el) == VOIDmode)
4728             {
4729               /* If this triggers, someone should have generated a
4730                  CONST_INT instead.  */
4731               gcc_assert (elem_bitsize > HOST_BITS_PER_WIDE_INT);
4732
4733               for (i = 0; i < HOST_BITS_PER_WIDE_INT; i += value_bit)
4734                 *vp++ = CONST_DOUBLE_LOW (el) >> i;
4735               while (i < HOST_BITS_PER_WIDE_INT * 2 && i < elem_bitsize)
4736                 {
4737                   *vp++
4738                     = CONST_DOUBLE_HIGH (el) >> (i - HOST_BITS_PER_WIDE_INT);
4739                   i += value_bit;
4740                 }
4741               /* It shouldn't matter what's done here, so fill it with
4742                  zero.  */
4743               for (; i < elem_bitsize; i += value_bit)
4744                 *vp++ = 0;
4745             }
4746           else
4747             {
4748               long tmp[max_bitsize / 32];
4749               int bitsize = GET_MODE_BITSIZE (GET_MODE (el));
4750
4751               gcc_assert (SCALAR_FLOAT_MODE_P (GET_MODE (el)));
4752               gcc_assert (bitsize <= elem_bitsize);
4753               gcc_assert (bitsize % value_bit == 0);
4754
4755               real_to_target (tmp, CONST_DOUBLE_REAL_VALUE (el),
4756                               GET_MODE (el));
4757
4758               /* real_to_target produces its result in words affected by
4759                  FLOAT_WORDS_BIG_ENDIAN.  However, we ignore this,
4760                  and use WORDS_BIG_ENDIAN instead; see the documentation
4761                  of SUBREG in rtl.texi.  */
4762               for (i = 0; i < bitsize; i += value_bit)
4763                 {
4764                   int ibase;
4765                   if (WORDS_BIG_ENDIAN)
4766                     ibase = bitsize - 1 - i;
4767                   else
4768                     ibase = i;
4769                   *vp++ = tmp[ibase / 32] >> i % 32;
4770                 }
4771               
4772               /* It shouldn't matter what's done here, so fill it with
4773                  zero.  */
4774               for (; i < elem_bitsize; i += value_bit)
4775                 *vp++ = 0;
4776             }
4777           break;
4778
4779         case CONST_FIXED:
4780           if (elem_bitsize <= HOST_BITS_PER_WIDE_INT)
4781             {
4782               for (i = 0; i < elem_bitsize; i += value_bit)
4783                 *vp++ = CONST_FIXED_VALUE_LOW (el) >> i;
4784             }
4785           else
4786             {
4787               for (i = 0; i < HOST_BITS_PER_WIDE_INT; i += value_bit)
4788                 *vp++ = CONST_FIXED_VALUE_LOW (el) >> i;
4789               for (; i < 2 * HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
4790                    i += value_bit)
4791                 *vp++ = CONST_FIXED_VALUE_HIGH (el)
4792                         >> (i - HOST_BITS_PER_WIDE_INT);
4793               for (; i < elem_bitsize; i += value_bit)
4794                 *vp++ = 0;
4795             }
4796           break;
4797           
4798         default:
4799           gcc_unreachable ();
4800         }
4801     }
4802
4803   /* Now, pick the right byte to start with.  */
4804   /* Renumber BYTE so that the least-significant byte is byte 0.  A special
4805      case is paradoxical SUBREGs, which shouldn't be adjusted since they
4806      will already have offset 0.  */
4807   if (GET_MODE_SIZE (innermode) >= GET_MODE_SIZE (outermode))
4808     {
4809       unsigned ibyte = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode) 
4810                         - byte);
4811       unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
4812       unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
4813       byte = (subword_byte % UNITS_PER_WORD
4814               + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
4815     }
4816
4817   /* BYTE should still be inside OP.  (Note that BYTE is unsigned,
4818      so if it's become negative it will instead be very large.)  */
4819   gcc_assert (byte < GET_MODE_SIZE (innermode));
4820
4821   /* Convert from bytes to chunks of size value_bit.  */
4822   value_start = byte * (BITS_PER_UNIT / value_bit);
4823
4824   /* Re-pack the value.  */
4825     
4826   if (VECTOR_MODE_P (outermode))
4827     {
4828       num_elem = GET_MODE_NUNITS (outermode);
4829       result_v = rtvec_alloc (num_elem);
4830       elems = &RTVEC_ELT (result_v, 0);
4831       outer_submode = GET_MODE_INNER (outermode);
4832     }
4833   else
4834     {
4835       num_elem = 1;
4836       elems = &result_s;
4837       outer_submode = outermode;
4838     }
4839
4840   outer_class = GET_MODE_CLASS (outer_submode);
4841   elem_bitsize = GET_MODE_BITSIZE (outer_submode);
4842
4843   gcc_assert (elem_bitsize % value_bit == 0);
4844   gcc_assert (elem_bitsize + value_start * value_bit <= max_bitsize);
4845
4846   for (elem = 0; elem < num_elem; elem++)
4847     {
4848       unsigned char *vp;
4849       
4850       /* Vectors are stored in target memory order.  (This is probably
4851          a mistake.)  */
4852       {
4853         unsigned byte = (elem * elem_bitsize) / BITS_PER_UNIT;
4854         unsigned ibyte = (((num_elem - 1 - elem) * elem_bitsize) 
4855                           / BITS_PER_UNIT);
4856         unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
4857         unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
4858         unsigned bytele = (subword_byte % UNITS_PER_WORD
4859                          + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
4860         vp = value + value_start + (bytele * BITS_PER_UNIT) / value_bit;
4861       }
4862
4863       switch (outer_class)
4864         {
4865         case MODE_INT:
4866         case MODE_PARTIAL_INT:
4867           {
4868             unsigned HOST_WIDE_INT hi = 0, lo = 0;
4869
4870             for (i = 0;
4871                  i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
4872                  i += value_bit)
4873               lo |= (HOST_WIDE_INT)(*vp++ & value_mask) << i;
4874             for (; i < elem_bitsize; i += value_bit)
4875               hi |= ((HOST_WIDE_INT)(*vp++ & value_mask)
4876                      << (i - HOST_BITS_PER_WIDE_INT));
4877             
4878             /* immed_double_const doesn't call trunc_int_for_mode.  I don't
4879                know why.  */
4880             if (elem_bitsize <= HOST_BITS_PER_WIDE_INT)
4881               elems[elem] = gen_int_mode (lo, outer_submode);
4882             else if (elem_bitsize <= 2 * HOST_BITS_PER_WIDE_INT)
4883               elems[elem] = immed_double_const (lo, hi, outer_submode);
4884             else
4885               return NULL_RTX;
4886           }
4887           break;
4888       
4889         case MODE_FLOAT:
4890         case MODE_DECIMAL_FLOAT:
4891           {
4892             REAL_VALUE_TYPE r;
4893             long tmp[max_bitsize / 32];
4894             
4895             /* real_from_target wants its input in words affected by
4896                FLOAT_WORDS_BIG_ENDIAN.  However, we ignore this,
4897                and use WORDS_BIG_ENDIAN instead; see the documentation
4898                of SUBREG in rtl.texi.  */
4899             for (i = 0; i < max_bitsize / 32; i++)
4900               tmp[i] = 0;
4901             for (i = 0; i < elem_bitsize; i += value_bit)
4902               {
4903                 int ibase;
4904                 if (WORDS_BIG_ENDIAN)
4905                   ibase = elem_bitsize - 1 - i;
4906                 else
4907                   ibase = i;
4908                 tmp[ibase / 32] |= (*vp++ & value_mask) << i % 32;
4909               }
4910
4911             real_from_target (&r, tmp, outer_submode);
4912             elems[elem] = CONST_DOUBLE_FROM_REAL_VALUE (r, outer_submode);
4913           }
4914           break;
4915
4916         case MODE_FRACT:
4917         case MODE_UFRACT:
4918         case MODE_ACCUM:
4919         case MODE_UACCUM:
4920           {
4921             FIXED_VALUE_TYPE f;
4922             f.data.low = 0;
4923             f.data.high = 0;
4924             f.mode = outer_submode;
4925
4926             for (i = 0;
4927                  i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
4928                  i += value_bit)
4929               f.data.low |= (HOST_WIDE_INT)(*vp++ & value_mask) << i;
4930             for (; i < elem_bitsize; i += value_bit)
4931               f.data.high |= ((HOST_WIDE_INT)(*vp++ & value_mask)
4932                              << (i - HOST_BITS_PER_WIDE_INT));
4933
4934             elems[elem] = CONST_FIXED_FROM_FIXED_VALUE (f, outer_submode);
4935           }
4936           break;
4937             
4938         default:
4939           gcc_unreachable ();
4940         }
4941     }
4942   if (VECTOR_MODE_P (outermode))
4943     return gen_rtx_CONST_VECTOR (outermode, result_v);
4944   else
4945     return result_s;
4946 }
4947
4948 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
4949    Return 0 if no simplifications are possible.  */
4950 rtx
4951 simplify_subreg (enum machine_mode outermode, rtx op,
4952                  enum machine_mode innermode, unsigned int byte)
4953 {
4954   /* Little bit of sanity checking.  */
4955   gcc_assert (innermode != VOIDmode);
4956   gcc_assert (outermode != VOIDmode);
4957   gcc_assert (innermode != BLKmode);
4958   gcc_assert (outermode != BLKmode);
4959
4960   gcc_assert (GET_MODE (op) == innermode
4961               || GET_MODE (op) == VOIDmode);
4962
4963   gcc_assert ((byte % GET_MODE_SIZE (outermode)) == 0);
4964   gcc_assert (byte < GET_MODE_SIZE (innermode));
4965
4966   if (outermode == innermode && !byte)
4967     return op;
4968
4969   if (GET_CODE (op) == CONST_INT
4970       || GET_CODE (op) == CONST_DOUBLE
4971       || GET_CODE (op) == CONST_FIXED
4972       || GET_CODE (op) == CONST_VECTOR)
4973     return simplify_immed_subreg (outermode, op, innermode, byte);
4974
4975   /* Changing mode twice with SUBREG => just change it once,
4976      or not at all if changing back op starting mode.  */
4977   if (GET_CODE (op) == SUBREG)
4978     {
4979       enum machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
4980       int final_offset = byte + SUBREG_BYTE (op);
4981       rtx newx;
4982
4983       if (outermode == innermostmode
4984           && byte == 0 && SUBREG_BYTE (op) == 0)
4985         return SUBREG_REG (op);
4986
4987       /* The SUBREG_BYTE represents offset, as if the value were stored
4988          in memory.  Irritating exception is paradoxical subreg, where
4989          we define SUBREG_BYTE to be 0.  On big endian machines, this
4990          value should be negative.  For a moment, undo this exception.  */
4991       if (byte == 0 && GET_MODE_SIZE (innermode) < GET_MODE_SIZE (outermode))
4992         {
4993           int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
4994           if (WORDS_BIG_ENDIAN)
4995             final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
4996           if (BYTES_BIG_ENDIAN)
4997             final_offset += difference % UNITS_PER_WORD;
4998         }
4999       if (SUBREG_BYTE (op) == 0
5000           && GET_MODE_SIZE (innermostmode) < GET_MODE_SIZE (innermode))
5001         {
5002           int difference = (GET_MODE_SIZE (innermostmode) - GET_MODE_SIZE (innermode));
5003           if (WORDS_BIG_ENDIAN)
5004             final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
5005           if (BYTES_BIG_ENDIAN)
5006             final_offset += difference % UNITS_PER_WORD;
5007         }
5008
5009       /* See whether resulting subreg will be paradoxical.  */
5010       if (GET_MODE_SIZE (innermostmode) > GET_MODE_SIZE (outermode))
5011         {
5012           /* In nonparadoxical subregs we can't handle negative offsets.  */
5013           if (final_offset < 0)
5014             return NULL_RTX;
5015           /* Bail out in case resulting subreg would be incorrect.  */
5016           if (final_offset % GET_MODE_SIZE (outermode)
5017               || (unsigned) final_offset >= GET_MODE_SIZE (innermostmode))
5018             return NULL_RTX;
5019         }
5020       else
5021         {
5022           int offset = 0;
5023           int difference = (GET_MODE_SIZE (innermostmode) - GET_MODE_SIZE (outermode));
5024
5025           /* In paradoxical subreg, see if we are still looking on lower part.
5026              If so, our SUBREG_BYTE will be 0.  */
5027           if (WORDS_BIG_ENDIAN)
5028             offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
5029           if (BYTES_BIG_ENDIAN)
5030             offset += difference % UNITS_PER_WORD;
5031           if (offset == final_offset)
5032             final_offset = 0;
5033           else
5034             return NULL_RTX;
5035         }
5036
5037       /* Recurse for further possible simplifications.  */
5038       newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
5039                               final_offset);
5040       if (newx)
5041         return newx;
5042       if (validate_subreg (outermode, innermostmode,
5043                            SUBREG_REG (op), final_offset))
5044         {
5045           newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
5046           if (SUBREG_PROMOTED_VAR_P (op)
5047               && SUBREG_PROMOTED_UNSIGNED_P (op) >= 0
5048               && GET_MODE_CLASS (outermode) == MODE_INT
5049               && IN_RANGE (GET_MODE_SIZE (outermode),
5050                            GET_MODE_SIZE (innermode),
5051                            GET_MODE_SIZE (innermostmode))
5052               && subreg_lowpart_p (newx))
5053             {
5054               SUBREG_PROMOTED_VAR_P (newx) = 1;
5055               SUBREG_PROMOTED_UNSIGNED_SET
5056                 (newx, SUBREG_PROMOTED_UNSIGNED_P (op));
5057             }
5058           return newx;
5059         }
5060       return NULL_RTX;
5061     }
5062
5063   /* Merge implicit and explicit truncations.  */
5064
5065   if (GET_CODE (op) == TRUNCATE
5066       && GET_MODE_SIZE (outermode) < GET_MODE_SIZE (innermode)
5067       && subreg_lowpart_offset (outermode, innermode) == byte)
5068     return simplify_gen_unary (TRUNCATE, outermode, XEXP (op, 0),
5069                                GET_MODE (XEXP (op, 0)));
5070
5071   /* SUBREG of a hard register => just change the register number
5072      and/or mode.  If the hard register is not valid in that mode,
5073      suppress this simplification.  If the hard register is the stack,
5074      frame, or argument pointer, leave this as a SUBREG.  */
5075
5076   if (REG_P (op) && HARD_REGISTER_P (op))
5077     {
5078       unsigned int regno, final_regno;
5079
5080       regno = REGNO (op);
5081       final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
5082       if (HARD_REGISTER_NUM_P (final_regno))
5083         {
5084           rtx x;
5085           int final_offset = byte;
5086
5087           /* Adjust offset for paradoxical subregs.  */
5088           if (byte == 0
5089               && GET_MODE_SIZE (innermode) < GET_MODE_SIZE (outermode))
5090             {
5091               int difference = (GET_MODE_SIZE (innermode)
5092                                 - GET_MODE_SIZE (outermode));
5093               if (WORDS_BIG_ENDIAN)
5094                 final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
5095               if (BYTES_BIG_ENDIAN)
5096                 final_offset += difference % UNITS_PER_WORD;
5097             }
5098
5099           x = gen_rtx_REG_offset (op, outermode, final_regno, final_offset);
5100
5101           /* Propagate original regno.  We don't have any way to specify
5102              the offset inside original regno, so do so only for lowpart.
5103              The information is used only by alias analysis that can not
5104              grog partial register anyway.  */
5105
5106           if (subreg_lowpart_offset (outermode, innermode) == byte)
5107             ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
5108           return x;
5109         }
5110     }
5111
5112   /* If we have a SUBREG of a register that we are replacing and we are
5113      replacing it with a MEM, make a new MEM and try replacing the
5114      SUBREG with it.  Don't do this if the MEM has a mode-dependent address
5115      or if we would be widening it.  */
5116
5117   if (MEM_P (op)
5118       && ! mode_dependent_address_p (XEXP (op, 0))
5119       /* Allow splitting of volatile memory references in case we don't
5120          have instruction to move the whole thing.  */
5121       && (! MEM_VOLATILE_P (op)
5122           || ! have_insn_for (SET, innermode))
5123       && GET_MODE_SIZE (outermode) <= GET_MODE_SIZE (GET_MODE (op)))
5124     return adjust_address_nv (op, outermode, byte);
5125
5126   /* Handle complex values represented as CONCAT
5127      of real and imaginary part.  */
5128   if (GET_CODE (op) == CONCAT)
5129     {
5130       unsigned int part_size, final_offset;
5131       rtx part, res;
5132
5133       part_size = GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)));
5134       if (byte < part_size)
5135         {
5136           part = XEXP (op, 0);
5137           final_offset = byte;
5138         }
5139       else
5140         {
5141           part = XEXP (op, 1);
5142           final_offset = byte - part_size;
5143         }
5144
5145       if (final_offset + GET_MODE_SIZE (outermode) > part_size)
5146         return NULL_RTX;
5147
5148       res = simplify_subreg (outermode, part, GET_MODE (part), final_offset);
5149       if (res)
5150         return res;
5151       if (validate_subreg (outermode, GET_MODE (part), part, final_offset))
5152         return gen_rtx_SUBREG (outermode, part, final_offset);
5153       return NULL_RTX;
5154     }
5155
5156   /* Optimize SUBREG truncations of zero and sign extended values.  */
5157   if ((GET_CODE (op) == ZERO_EXTEND
5158        || GET_CODE (op) == SIGN_EXTEND)
5159       && GET_MODE_BITSIZE (outermode) < GET_MODE_BITSIZE (innermode))
5160     {
5161       unsigned int bitpos = subreg_lsb_1 (outermode, innermode, byte);
5162
5163       /* If we're requesting the lowpart of a zero or sign extension,
5164          there are three possibilities.  If the outermode is the same
5165          as the origmode, we can omit both the extension and the subreg.
5166          If the outermode is not larger than the origmode, we can apply
5167          the truncation without the extension.  Finally, if the outermode
5168          is larger than the origmode, but both are integer modes, we
5169          can just extend to the appropriate mode.  */
5170       if (bitpos == 0)
5171         {
5172           enum machine_mode origmode = GET_MODE (XEXP (op, 0));
5173           if (outermode == origmode)
5174             return XEXP (op, 0);
5175           if (GET_MODE_BITSIZE (outermode) <= GET_MODE_BITSIZE (origmode))
5176             return simplify_gen_subreg (outermode, XEXP (op, 0), origmode,
5177                                         subreg_lowpart_offset (outermode,
5178                                                                origmode));
5179           if (SCALAR_INT_MODE_P (outermode))
5180             return simplify_gen_unary (GET_CODE (op), outermode,
5181                                        XEXP (op, 0), origmode);
5182         }
5183
5184       /* A SUBREG resulting from a zero extension may fold to zero if
5185          it extracts higher bits that the ZERO_EXTEND's source bits.  */
5186       if (GET_CODE (op) == ZERO_EXTEND
5187           && bitpos >= GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))))
5188         return CONST0_RTX (outermode);
5189     }
5190
5191   /* Simplify (subreg:QI (lshiftrt:SI (sign_extend:SI (x:QI)) C), 0) into
5192      to (ashiftrt:QI (x:QI) C), where C is a suitable small constant and
5193      the outer subreg is effectively a truncation to the original mode.  */
5194   if ((GET_CODE (op) == LSHIFTRT
5195        || GET_CODE (op) == ASHIFTRT)
5196       && SCALAR_INT_MODE_P (outermode)
5197       /* Ensure that OUTERMODE is at least twice as wide as the INNERMODE
5198          to avoid the possibility that an outer LSHIFTRT shifts by more
5199          than the sign extension's sign_bit_copies and introduces zeros
5200          into the high bits of the result.  */
5201       && (2 * GET_MODE_BITSIZE (outermode)) <= GET_MODE_BITSIZE (innermode)
5202       && GET_CODE (XEXP (op, 1)) == CONST_INT
5203       && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
5204       && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
5205       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (outermode)
5206       && subreg_lsb_1 (outermode, innermode, byte) == 0)
5207     return simplify_gen_binary (ASHIFTRT, outermode,
5208                                 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
5209
5210   /* Likewise (subreg:QI (lshiftrt:SI (zero_extend:SI (x:QI)) C), 0) into
5211      to (lshiftrt:QI (x:QI) C), where C is a suitable small constant and
5212      the outer subreg is effectively a truncation to the original mode.  */
5213   if ((GET_CODE (op) == LSHIFTRT
5214        || GET_CODE (op) == ASHIFTRT)
5215       && SCALAR_INT_MODE_P (outermode)
5216       && GET_MODE_BITSIZE (outermode) < GET_MODE_BITSIZE (innermode)
5217       && GET_CODE (XEXP (op, 1)) == CONST_INT
5218       && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
5219       && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
5220       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (outermode)
5221       && subreg_lsb_1 (outermode, innermode, byte) == 0)
5222     return simplify_gen_binary (LSHIFTRT, outermode,
5223                                 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
5224
5225   /* Likewise (subreg:QI (ashift:SI (zero_extend:SI (x:QI)) C), 0) into
5226      to (ashift:QI (x:QI) C), where C is a suitable small constant and
5227      the outer subreg is effectively a truncation to the original mode.  */
5228   if (GET_CODE (op) == ASHIFT
5229       && SCALAR_INT_MODE_P (outermode)
5230       && GET_MODE_BITSIZE (outermode) < GET_MODE_BITSIZE (innermode)
5231       && GET_CODE (XEXP (op, 1)) == CONST_INT
5232       && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
5233           || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
5234       && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
5235       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (outermode)
5236       && subreg_lsb_1 (outermode, innermode, byte) == 0)
5237     return simplify_gen_binary (ASHIFT, outermode,
5238                                 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
5239
5240   /* Recognize a word extraction from a multi-word subreg.  */
5241   if ((GET_CODE (op) == LSHIFTRT
5242        || GET_CODE (op) == ASHIFTRT)
5243       && SCALAR_INT_MODE_P (outermode)
5244       && GET_MODE_BITSIZE (outermode) >= BITS_PER_WORD
5245       && GET_MODE_BITSIZE (innermode) >= (2 * GET_MODE_BITSIZE (outermode))
5246       && GET_CODE (XEXP (op, 1)) == CONST_INT
5247       && (INTVAL (XEXP (op, 1)) & (GET_MODE_BITSIZE (outermode) - 1)) == 0
5248       && INTVAL (XEXP (op, 1)) >= 0
5249       && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (innermode)      
5250       && byte == subreg_lowpart_offset (outermode, innermode))
5251     {
5252       int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
5253       return simplify_gen_subreg (outermode, XEXP (op, 0), innermode,
5254                                   (WORDS_BIG_ENDIAN
5255                                    ? byte - shifted_bytes : byte + shifted_bytes));
5256     }
5257
5258   return NULL_RTX;
5259 }
5260
5261 /* Make a SUBREG operation or equivalent if it folds.  */
5262
5263 rtx
5264 simplify_gen_subreg (enum machine_mode outermode, rtx op,
5265                      enum machine_mode innermode, unsigned int byte)
5266 {
5267   rtx newx;
5268
5269   newx = simplify_subreg (outermode, op, innermode, byte);
5270   if (newx)
5271     return newx;
5272
5273   if (GET_CODE (op) == SUBREG
5274       || GET_CODE (op) == CONCAT
5275       || GET_MODE (op) == VOIDmode)
5276     return NULL_RTX;
5277
5278   if (validate_subreg (outermode, innermode, op, byte))
5279     return gen_rtx_SUBREG (outermode, op, byte);
5280
5281   return NULL_RTX;
5282 }
5283
5284 /* Simplify X, an rtx expression.
5285
5286    Return the simplified expression or NULL if no simplifications
5287    were possible.
5288
5289    This is the preferred entry point into the simplification routines;
5290    however, we still allow passes to call the more specific routines.
5291
5292    Right now GCC has three (yes, three) major bodies of RTL simplification
5293    code that need to be unified.
5294
5295         1. fold_rtx in cse.c.  This code uses various CSE specific
5296            information to aid in RTL simplification.
5297
5298         2. simplify_rtx in combine.c.  Similar to fold_rtx, except that
5299            it uses combine specific information to aid in RTL
5300            simplification.
5301
5302         3. The routines in this file.
5303
5304
5305    Long term we want to only have one body of simplification code; to
5306    get to that state I recommend the following steps:
5307
5308         1. Pour over fold_rtx & simplify_rtx and move any simplifications
5309            which are not pass dependent state into these routines.
5310
5311         2. As code is moved by #1, change fold_rtx & simplify_rtx to
5312            use this routine whenever possible.
5313
5314         3. Allow for pass dependent state to be provided to these
5315            routines and add simplifications based on the pass dependent
5316            state.  Remove code from cse.c & combine.c that becomes
5317            redundant/dead.
5318
5319     It will take time, but ultimately the compiler will be easier to
5320     maintain and improve.  It's totally silly that when we add a
5321     simplification that it needs to be added to 4 places (3 for RTL
5322     simplification and 1 for tree simplification.  */
5323
5324 rtx
5325 simplify_rtx (const_rtx x)
5326 {
5327   const enum rtx_code code = GET_CODE (x);
5328   const enum machine_mode mode = GET_MODE (x);
5329
5330   switch (GET_RTX_CLASS (code))
5331     {
5332     case RTX_UNARY:
5333       return simplify_unary_operation (code, mode,
5334                                        XEXP (x, 0), GET_MODE (XEXP (x, 0)));
5335     case RTX_COMM_ARITH:
5336       if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
5337         return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
5338
5339       /* Fall through....  */
5340
5341     case RTX_BIN_ARITH:
5342       return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
5343
5344     case RTX_TERNARY:
5345     case RTX_BITFIELD_OPS:
5346       return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
5347                                          XEXP (x, 0), XEXP (x, 1),
5348                                          XEXP (x, 2));
5349
5350     case RTX_COMPARE:
5351     case RTX_COMM_COMPARE:
5352       return simplify_relational_operation (code, mode,
5353                                             ((GET_MODE (XEXP (x, 0))
5354                                              != VOIDmode)
5355                                             ? GET_MODE (XEXP (x, 0))
5356                                             : GET_MODE (XEXP (x, 1))),
5357                                             XEXP (x, 0),
5358                                             XEXP (x, 1));
5359
5360     case RTX_EXTRA:
5361       if (code == SUBREG)
5362         return simplify_subreg (mode, SUBREG_REG (x),
5363                                 GET_MODE (SUBREG_REG (x)),
5364                                 SUBREG_BYTE (x));
5365       break;
5366
5367     case RTX_OBJ:
5368       if (code == LO_SUM)
5369         {
5370           /* Convert (lo_sum (high FOO) FOO) to FOO.  */
5371           if (GET_CODE (XEXP (x, 0)) == HIGH
5372               && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
5373           return XEXP (x, 1);
5374         }
5375       break;
5376
5377     default:
5378       break;
5379     }
5380   return NULL;
5381 }