OSDN Git Service

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