OSDN Git Service

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