OSDN Git Service

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