OSDN Git Service

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