OSDN Git Service

2005-12-16 Paolo Bonzini <bonzini@gnu.org>
[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, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, 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, rtx);
56 static rtx simplify_immed_subreg (enum machine_mode, rtx, enum machine_mode,
57                                   unsigned int);
58 static rtx simplify_associative_operation (enum rtx_code, enum machine_mode,
59                                            rtx, rtx);
60 static rtx simplify_relational_operation_1 (enum rtx_code, enum machine_mode,
61                                             enum machine_mode, rtx, rtx);
62 static rtx simplify_unary_operation_1 (enum rtx_code, enum machine_mode, rtx);
63 static rtx simplify_binary_operation_1 (enum rtx_code, enum machine_mode,
64                                         rtx, rtx, rtx, rtx);
65 \f
66 /* Negate a CONST_INT rtx, truncating (because a conversion from a
67    maximally negative number can overflow).  */
68 static rtx
69 neg_const_int (enum machine_mode mode, rtx i)
70 {
71   return gen_int_mode (- INTVAL (i), mode);
72 }
73
74 /* Test whether expression, X, is an immediate constant that represents
75    the most significant bit of machine mode MODE.  */
76
77 bool
78 mode_signbit_p (enum machine_mode mode, rtx x)
79 {
80   unsigned HOST_WIDE_INT val;
81   unsigned int width;
82
83   if (GET_MODE_CLASS (mode) != MODE_INT)
84     return false;
85
86   width = GET_MODE_BITSIZE (mode);
87   if (width == 0)
88     return false;
89   
90   if (width <= HOST_BITS_PER_WIDE_INT
91       && GET_CODE (x) == CONST_INT)
92     val = INTVAL (x);
93   else if (width <= 2 * HOST_BITS_PER_WIDE_INT
94            && GET_CODE (x) == CONST_DOUBLE
95            && CONST_DOUBLE_LOW (x) == 0)
96     {
97       val = CONST_DOUBLE_HIGH (x);
98       width -= HOST_BITS_PER_WIDE_INT;
99     }
100   else
101     return false;
102
103   if (width < HOST_BITS_PER_WIDE_INT)
104     val &= ((unsigned HOST_WIDE_INT) 1 << width) - 1;
105   return val == ((unsigned HOST_WIDE_INT) 1 << (width - 1));
106 }
107 \f
108 /* Make a binary operation by properly ordering the operands and
109    seeing if the expression folds.  */
110
111 rtx
112 simplify_gen_binary (enum rtx_code code, enum machine_mode mode, rtx op0,
113                      rtx op1)
114 {
115   rtx tem;
116
117   /* Put complex operands first and constants second if commutative.  */
118   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
119       && swap_commutative_operands_p (op0, op1))
120     tem = op0, op0 = op1, op1 = tem;
121
122   /* If this simplifies, do it.  */
123   tem = simplify_binary_operation (code, mode, op0, op1);
124   if (tem)
125     return tem;
126
127   return gen_rtx_fmt_ee (code, mode, op0, op1);
128 }
129 \f
130 /* If X is a MEM referencing the constant pool, return the real value.
131    Otherwise return X.  */
132 rtx
133 avoid_constant_pool_reference (rtx x)
134 {
135   rtx c, tmp, addr;
136   enum machine_mode cmode;
137   HOST_WIDE_INT offset = 0;
138
139   switch (GET_CODE (x))
140     {
141     case MEM:
142       break;
143
144     case FLOAT_EXTEND:
145       /* Handle float extensions of constant pool references.  */
146       tmp = XEXP (x, 0);
147       c = avoid_constant_pool_reference (tmp);
148       if (c != tmp && GET_CODE (c) == CONST_DOUBLE)
149         {
150           REAL_VALUE_TYPE d;
151
152           REAL_VALUE_FROM_CONST_DOUBLE (d, c);
153           return CONST_DOUBLE_FROM_REAL_VALUE (d, GET_MODE (x));
154         }
155       return x;
156
157     default:
158       return x;
159     }
160
161   addr = XEXP (x, 0);
162
163   /* Call target hook to avoid the effects of -fpic etc....  */
164   addr = targetm.delegitimize_address (addr);
165
166   /* Split the address into a base and integer offset.  */
167   if (GET_CODE (addr) == CONST
168       && GET_CODE (XEXP (addr, 0)) == PLUS
169       && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
170     {
171       offset = INTVAL (XEXP (XEXP (addr, 0), 1));
172       addr = XEXP (XEXP (addr, 0), 0);
173     }
174
175   if (GET_CODE (addr) == LO_SUM)
176     addr = XEXP (addr, 1);
177
178   /* If this is a constant pool reference, we can turn it into its
179      constant and hope that simplifications happen.  */
180   if (GET_CODE (addr) == SYMBOL_REF
181       && CONSTANT_POOL_ADDRESS_P (addr))
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 (offset != 0 || cmode != GET_MODE (x))
190         {
191           rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
192           if (tem && CONSTANT_P (tem))
193             return tem;
194         }
195       else
196         return c;
197     }
198
199   return x;
200 }
201
202 /* Return true if X is a MEM referencing the constant pool.  */
203
204 bool
205 constant_pool_reference_p (rtx x)
206 {
207   return avoid_constant_pool_reference (x) != x;
208 }
209 \f
210 /* Make a unary operation by first seeing if it folds and otherwise making
211    the specified operation.  */
212
213 rtx
214 simplify_gen_unary (enum rtx_code code, enum machine_mode mode, rtx op,
215                     enum machine_mode op_mode)
216 {
217   rtx tem;
218
219   /* If this simplifies, use it.  */
220   if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
221     return tem;
222
223   return gen_rtx_fmt_e (code, mode, op);
224 }
225
226 /* Likewise for ternary operations.  */
227
228 rtx
229 simplify_gen_ternary (enum rtx_code code, enum machine_mode mode,
230                       enum machine_mode op0_mode, rtx op0, rtx op1, rtx op2)
231 {
232   rtx tem;
233
234   /* If this simplifies, use it.  */
235   if (0 != (tem = simplify_ternary_operation (code, mode, op0_mode,
236                                               op0, op1, op2)))
237     return tem;
238
239   return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
240 }
241
242 /* Likewise, for relational operations.
243    CMP_MODE specifies mode comparison is done in.  */
244
245 rtx
246 simplify_gen_relational (enum rtx_code code, enum machine_mode mode,
247                          enum machine_mode cmp_mode, rtx op0, rtx op1)
248 {
249   rtx tem;
250
251   if (0 != (tem = simplify_relational_operation (code, mode, cmp_mode,
252                                                  op0, op1)))
253     return tem;
254
255   return gen_rtx_fmt_ee (code, mode, op0, op1);
256 }
257 \f
258 /* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the
259    resulting RTX.  Return a new RTX which is as simplified as possible.  */
260
261 rtx
262 simplify_replace_rtx (rtx x, rtx old_rtx, rtx new_rtx)
263 {
264   enum rtx_code code = GET_CODE (x);
265   enum machine_mode mode = GET_MODE (x);
266   enum machine_mode op_mode;
267   rtx op0, op1, op2;
268
269   /* If X is OLD_RTX, return NEW_RTX.  Otherwise, if this is an expression, try
270      to build a new expression substituting recursively.  If we can't do
271      anything, return our input.  */
272
273   if (x == old_rtx)
274     return new_rtx;
275
276   switch (GET_RTX_CLASS (code))
277     {
278     case RTX_UNARY:
279       op0 = XEXP (x, 0);
280       op_mode = GET_MODE (op0);
281       op0 = simplify_replace_rtx (op0, old_rtx, new_rtx);
282       if (op0 == XEXP (x, 0))
283         return x;
284       return simplify_gen_unary (code, mode, op0, op_mode);
285
286     case RTX_BIN_ARITH:
287     case RTX_COMM_ARITH:
288       op0 = simplify_replace_rtx (XEXP (x, 0), old_rtx, new_rtx);
289       op1 = simplify_replace_rtx (XEXP (x, 1), old_rtx, new_rtx);
290       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
291         return x;
292       return simplify_gen_binary (code, mode, op0, op1);
293
294     case RTX_COMPARE:
295     case RTX_COMM_COMPARE:
296       op0 = XEXP (x, 0);
297       op1 = XEXP (x, 1);
298       op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
299       op0 = simplify_replace_rtx (op0, old_rtx, new_rtx);
300       op1 = simplify_replace_rtx (op1, old_rtx, new_rtx);
301       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
302         return x;
303       return simplify_gen_relational (code, mode, op_mode, op0, op1);
304
305     case RTX_TERNARY:
306     case RTX_BITFIELD_OPS:
307       op0 = XEXP (x, 0);
308       op_mode = GET_MODE (op0);
309       op0 = simplify_replace_rtx (op0, old_rtx, new_rtx);
310       op1 = simplify_replace_rtx (XEXP (x, 1), old_rtx, new_rtx);
311       op2 = simplify_replace_rtx (XEXP (x, 2), old_rtx, new_rtx);
312       if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
313         return x;
314       if (op_mode == VOIDmode)
315         op_mode = GET_MODE (op0);
316       return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
317
318     case RTX_EXTRA:
319       /* The only case we try to handle is a SUBREG.  */
320       if (code == SUBREG)
321         {
322           op0 = simplify_replace_rtx (SUBREG_REG (x), old_rtx, new_rtx);
323           if (op0 == SUBREG_REG (x))
324             return x;
325           op0 = simplify_gen_subreg (GET_MODE (x), op0,
326                                      GET_MODE (SUBREG_REG (x)),
327                                      SUBREG_BYTE (x));
328           return op0 ? op0 : x;
329         }
330       break;
331
332     case RTX_OBJ:
333       if (code == MEM)
334         {
335           op0 = simplify_replace_rtx (XEXP (x, 0), old_rtx, new_rtx);
336           if (op0 == XEXP (x, 0))
337             return x;
338           return replace_equiv_address_nv (x, op0);
339         }
340       else if (code == LO_SUM)
341         {
342           op0 = simplify_replace_rtx (XEXP (x, 0), old_rtx, new_rtx);
343           op1 = simplify_replace_rtx (XEXP (x, 1), old_rtx, new_rtx);
344
345           /* (lo_sum (high x) x) -> x  */
346           if (GET_CODE (op0) == HIGH && rtx_equal_p (XEXP (op0, 0), op1))
347             return op1;
348
349           if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
350             return x;
351           return gen_rtx_LO_SUM (mode, op0, op1);
352         }
353       else if (code == REG)
354         {
355           if (rtx_equal_p (x, old_rtx))
356             return new_rtx;
357         }
358       break;
359
360     default:
361       break;
362     }
363   return x;
364 }
365 \f
366 /* Try to simplify a unary operation CODE whose output mode is to be
367    MODE with input operand OP whose mode was originally OP_MODE.
368    Return zero if no simplification can be made.  */
369 rtx
370 simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
371                           rtx op, enum machine_mode op_mode)
372 {
373   rtx trueop, tem;
374
375   if (GET_CODE (op) == CONST)
376     op = XEXP (op, 0);
377
378   trueop = avoid_constant_pool_reference (op);
379
380   tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
381   if (tem)
382     return tem;
383
384   return simplify_unary_operation_1 (code, mode, op);
385 }
386
387 /* Perform some simplifications we can do even if the operands
388    aren't constant.  */
389 static rtx
390 simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
391 {
392   enum rtx_code reversed;
393   rtx temp;
394
395   switch (code)
396     {
397     case NOT:
398       /* (not (not X)) == X.  */
399       if (GET_CODE (op) == NOT)
400         return XEXP (op, 0);
401
402       /* (not (eq X Y)) == (ne X Y), etc. if BImode or the result of the
403          comparison is all ones.   */
404       if (COMPARISON_P (op)
405           && (mode == BImode || STORE_FLAG_VALUE == -1)
406           && ((reversed = reversed_comparison_code (op, NULL_RTX)) != UNKNOWN))
407         return simplify_gen_relational (reversed, mode, VOIDmode,
408                                         XEXP (op, 0), XEXP (op, 1));
409
410       /* (not (plus X -1)) can become (neg X).  */
411       if (GET_CODE (op) == PLUS
412           && XEXP (op, 1) == constm1_rtx)
413         return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
414
415       /* Similarly, (not (neg X)) is (plus X -1).  */
416       if (GET_CODE (op) == NEG)
417         return plus_constant (XEXP (op, 0), -1);
418
419       /* (not (xor X C)) for C constant is (xor X D) with D = ~C.  */
420       if (GET_CODE (op) == XOR
421           && GET_CODE (XEXP (op, 1)) == CONST_INT
422           && (temp = simplify_unary_operation (NOT, mode,
423                                                XEXP (op, 1), mode)) != 0)
424         return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
425
426       /* (not (plus X C)) for signbit C is (xor X D) with D = ~C.  */
427       if (GET_CODE (op) == PLUS
428           && GET_CODE (XEXP (op, 1)) == CONST_INT
429           && mode_signbit_p (mode, XEXP (op, 1))
430           && (temp = simplify_unary_operation (NOT, mode,
431                                                XEXP (op, 1), mode)) != 0)
432         return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
433
434
435       /* (not (ashift 1 X)) is (rotate ~1 X).  We used to do this for
436          operands other than 1, but that is not valid.  We could do a
437          similar simplification for (not (lshiftrt C X)) where C is
438          just the sign bit, but this doesn't seem common enough to
439          bother with.  */
440       if (GET_CODE (op) == ASHIFT
441           && XEXP (op, 0) == const1_rtx)
442         {
443           temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
444           return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
445         }
446
447       /* (not (ashiftrt foo C)) where C is the number of bits in FOO
448          minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
449          so we can perform the above simplification.  */
450  
451       if (STORE_FLAG_VALUE == -1
452           && GET_CODE (op) == ASHIFTRT
453           && GET_CODE (XEXP (op, 1)) == CONST_INT
454           && INTVAL (XEXP (op, 1)) == GET_MODE_BITSIZE (mode) - 1)
455         return simplify_gen_relational (GE, mode, VOIDmode,
456                                         XEXP (op, 0), const0_rtx);
457
458
459       if (GET_CODE (op) == SUBREG
460           && subreg_lowpart_p (op)
461           && (GET_MODE_SIZE (GET_MODE (op))
462               < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))))
463           && GET_CODE (SUBREG_REG (op)) == ASHIFT
464           && XEXP (SUBREG_REG (op), 0) == const1_rtx)
465         {
466           enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
467           rtx x;
468
469           x = gen_rtx_ROTATE (inner_mode,
470                               simplify_gen_unary (NOT, inner_mode, const1_rtx,
471                                                   inner_mode),
472                               XEXP (SUBREG_REG (op), 1));
473           return rtl_hooks.gen_lowpart_no_emit (mode, x);
474         }
475
476       /* Apply De Morgan's laws to reduce number of patterns for machines
477          with negating logical insns (and-not, nand, etc.).  If result has
478          only one NOT, put it first, since that is how the patterns are
479          coded.  */
480
481       if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
482         {
483           rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
484           enum machine_mode op_mode;
485
486           op_mode = GET_MODE (in1);
487           in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
488
489           op_mode = GET_MODE (in2);
490           if (op_mode == VOIDmode)
491             op_mode = mode;
492           in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
493
494           if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
495             {
496               rtx tem = in2;
497               in2 = in1; in1 = tem;
498             }
499
500           return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
501                                  mode, in1, in2);
502         }
503       break;
504
505     case NEG:
506       /* (neg (neg X)) == X.  */
507       if (GET_CODE (op) == NEG)
508         return XEXP (op, 0);
509
510       /* (neg (plus X 1)) can become (not X).  */
511       if (GET_CODE (op) == PLUS
512           && XEXP (op, 1) == const1_rtx)
513         return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
514       
515       /* Similarly, (neg (not X)) is (plus X 1).  */
516       if (GET_CODE (op) == NOT)
517         return plus_constant (XEXP (op, 0), 1);
518       
519       /* (neg (minus X Y)) can become (minus Y X).  This transformation
520          isn't safe for modes with signed zeros, since if X and Y are
521          both +0, (minus Y X) is the same as (minus X Y).  If the
522          rounding mode is towards +infinity (or -infinity) then the two
523          expressions will be rounded differently.  */
524       if (GET_CODE (op) == MINUS
525           && !HONOR_SIGNED_ZEROS (mode)
526           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
527         return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
528       
529       if (GET_CODE (op) == PLUS
530           && !HONOR_SIGNED_ZEROS (mode)
531           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
532         {
533           /* (neg (plus A C)) is simplified to (minus -C A).  */
534           if (GET_CODE (XEXP (op, 1)) == CONST_INT
535               || GET_CODE (XEXP (op, 1)) == CONST_DOUBLE)
536             {
537               temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
538               if (temp)
539                 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
540             }
541
542           /* (neg (plus A B)) is canonicalized to (minus (neg A) B).  */
543           temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
544           return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
545         }
546
547       /* (neg (mult A B)) becomes (mult (neg A) B).
548          This works even for floating-point values.  */
549       if (GET_CODE (op) == MULT
550           && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
551         {
552           temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
553           return simplify_gen_binary (MULT, mode, temp, XEXP (op, 1));
554         }
555
556       /* NEG commutes with ASHIFT since it is multiplication.  Only do
557          this if we can then eliminate the NEG (e.g., if the operand
558          is a constant).  */
559       if (GET_CODE (op) == ASHIFT)
560         {
561           temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
562           if (temp)
563             return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
564         }
565
566       /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
567          C is equal to the width of MODE minus 1.  */
568       if (GET_CODE (op) == ASHIFTRT
569           && GET_CODE (XEXP (op, 1)) == CONST_INT
570           && INTVAL (XEXP (op, 1)) == GET_MODE_BITSIZE (mode) - 1)
571         return simplify_gen_binary (LSHIFTRT, mode,
572                                     XEXP (op, 0), XEXP (op, 1));
573
574       /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
575          C is equal to the width of MODE minus 1.  */
576       if (GET_CODE (op) == LSHIFTRT
577           && GET_CODE (XEXP (op, 1)) == CONST_INT
578           && INTVAL (XEXP (op, 1)) == GET_MODE_BITSIZE (mode) - 1)
579         return simplify_gen_binary (ASHIFTRT, mode,
580                                     XEXP (op, 0), XEXP (op, 1));
581       
582       /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1.  */
583       if (GET_CODE (op) == XOR
584           && XEXP (op, 1) == const1_rtx
585           && nonzero_bits (XEXP (op, 0), mode) == 1)
586         return plus_constant (XEXP (op, 0), -1);
587       break;
588
589     case TRUNCATE:
590       /* We can't handle truncation to a partial integer mode here
591          because we don't know the real bitsize of the partial
592          integer mode.  */
593       if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
594         break;
595
596       /* (truncate:SI ({sign,zero}_extend:DI foo:SI)) == foo:SI.  */
597       if ((GET_CODE (op) == SIGN_EXTEND
598            || GET_CODE (op) == ZERO_EXTEND)
599           && GET_MODE (XEXP (op, 0)) == mode)
600         return XEXP (op, 0);
601
602       /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
603          (OP:SI foo:SI) if OP is NEG or ABS.  */
604       if ((GET_CODE (op) == ABS
605            || GET_CODE (op) == NEG)
606           && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
607               || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
608           && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
609         return simplify_gen_unary (GET_CODE (op), mode,
610                                    XEXP (XEXP (op, 0), 0), mode);
611
612       /* (truncate:SI (subreg:DI (truncate:SI X) 0)) is
613          (truncate:SI x).  */
614       if (GET_CODE (op) == SUBREG
615           && GET_CODE (SUBREG_REG (op)) == TRUNCATE
616           && subreg_lowpart_p (op))
617         return SUBREG_REG (op);
618
619       /* If we know that the value is already truncated, we can
620          replace the TRUNCATE with a SUBREG if TRULY_NOOP_TRUNCATION
621          is nonzero for the corresponding modes.  But don't do this
622          for an (LSHIFTRT (MULT ...)) since this will cause problems
623          with the umulXi3_highpart patterns.  */
624       if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
625                                  GET_MODE_BITSIZE (GET_MODE (op)))
626           && num_sign_bit_copies (op, GET_MODE (op))
627              >= (unsigned int) (GET_MODE_BITSIZE (mode) + 1)
628           && ! (GET_CODE (op) == LSHIFTRT
629                 && GET_CODE (XEXP (op, 0)) == MULT))
630         return rtl_hooks.gen_lowpart_no_emit (mode, op);
631
632       /* A truncate of a comparison can be replaced with a subreg if
633          STORE_FLAG_VALUE permits.  This is like the previous test,
634          but it works even if the comparison is done in a mode larger
635          than HOST_BITS_PER_WIDE_INT.  */
636       if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
637           && COMPARISON_P (op)
638           && ((HOST_WIDE_INT) STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0)
639         return rtl_hooks.gen_lowpart_no_emit (mode, op);
640       break;
641
642     case FLOAT_TRUNCATE:
643       /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF.  */
644       if (GET_CODE (op) == FLOAT_EXTEND
645           && GET_MODE (XEXP (op, 0)) == mode)
646         return XEXP (op, 0);
647
648       /* (float_truncate:SF (float_truncate:DF foo:XF))
649          = (float_truncate:SF foo:XF).
650          This may eliminate double rounding, so it is unsafe.
651
652          (float_truncate:SF (float_extend:XF foo:DF))
653          = (float_truncate:SF foo:DF).
654
655          (float_truncate:DF (float_extend:XF foo:SF))
656          = (float_extend:SF foo:DF).  */
657       if ((GET_CODE (op) == FLOAT_TRUNCATE
658            && flag_unsafe_math_optimizations)
659           || GET_CODE (op) == FLOAT_EXTEND)
660         return simplify_gen_unary (GET_MODE_SIZE (GET_MODE (XEXP (op,
661                                                             0)))
662                                    > GET_MODE_SIZE (mode)
663                                    ? FLOAT_TRUNCATE : FLOAT_EXTEND,
664                                    mode,
665                                    XEXP (op, 0), mode);
666
667       /*  (float_truncate (float x)) is (float x)  */
668       if (GET_CODE (op) == FLOAT
669           && (flag_unsafe_math_optimizations
670               || ((unsigned)significand_size (GET_MODE (op))
671                   >= (GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0)))
672                       - num_sign_bit_copies (XEXP (op, 0),
673                                              GET_MODE (XEXP (op, 0)))))))
674         return simplify_gen_unary (FLOAT, mode,
675                                    XEXP (op, 0),
676                                    GET_MODE (XEXP (op, 0)));
677
678       /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
679          (OP:SF foo:SF) if OP is NEG or ABS.  */
680       if ((GET_CODE (op) == ABS
681            || GET_CODE (op) == NEG)
682           && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
683           && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
684         return simplify_gen_unary (GET_CODE (op), mode,
685                                    XEXP (XEXP (op, 0), 0), mode);
686
687       /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
688          is (float_truncate:SF x).  */
689       if (GET_CODE (op) == SUBREG
690           && subreg_lowpart_p (op)
691           && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
692         return SUBREG_REG (op);
693       break;
694
695     case FLOAT_EXTEND:
696       /*  (float_extend (float_extend x)) is (float_extend x)
697
698           (float_extend (float x)) is (float x) assuming that double
699           rounding can't happen.
700           */
701       if (GET_CODE (op) == FLOAT_EXTEND
702           || (GET_CODE (op) == FLOAT
703               && ((unsigned)significand_size (GET_MODE (op))
704                   >= (GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0)))
705                       - num_sign_bit_copies (XEXP (op, 0),
706                                              GET_MODE (XEXP (op, 0)))))))
707         return simplify_gen_unary (GET_CODE (op), mode,
708                                    XEXP (op, 0),
709                                    GET_MODE (XEXP (op, 0)));
710
711       break;
712
713     case ABS:
714       /* (abs (neg <foo>)) -> (abs <foo>) */
715       if (GET_CODE (op) == NEG)
716         return simplify_gen_unary (ABS, mode, XEXP (op, 0),
717                                    GET_MODE (XEXP (op, 0)));
718
719       /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
720          do nothing.  */
721       if (GET_MODE (op) == VOIDmode)
722         break;
723
724       /* If operand is something known to be positive, ignore the ABS.  */
725       if (GET_CODE (op) == FFS || GET_CODE (op) == ABS
726           || ((GET_MODE_BITSIZE (GET_MODE (op))
727                <= HOST_BITS_PER_WIDE_INT)
728               && ((nonzero_bits (op, GET_MODE (op))
729                    & ((HOST_WIDE_INT) 1
730                       << (GET_MODE_BITSIZE (GET_MODE (op)) - 1)))
731                   == 0)))
732         return op;
733
734       /* If operand is known to be only -1 or 0, convert ABS to NEG.  */
735       if (num_sign_bit_copies (op, mode) == GET_MODE_BITSIZE (mode))
736         return gen_rtx_NEG (mode, op);
737
738       break;
739
740     case FFS:
741       /* (ffs (*_extend <X>)) = (ffs <X>) */
742       if (GET_CODE (op) == SIGN_EXTEND
743           || GET_CODE (op) == ZERO_EXTEND)
744         return simplify_gen_unary (FFS, mode, XEXP (op, 0),
745                                    GET_MODE (XEXP (op, 0)));
746       break;
747
748     case POPCOUNT:
749     case PARITY:
750       /* (pop* (zero_extend <X>)) = (pop* <X>) */
751       if (GET_CODE (op) == ZERO_EXTEND)
752         return simplify_gen_unary (code, mode, XEXP (op, 0),
753                                    GET_MODE (XEXP (op, 0)));
754       break;
755
756     case FLOAT:
757       /* (float (sign_extend <X>)) = (float <X>).  */
758       if (GET_CODE (op) == SIGN_EXTEND)
759         return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
760                                    GET_MODE (XEXP (op, 0)));
761       break;
762
763     case SIGN_EXTEND:
764       /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
765          becomes just the MINUS if its mode is MODE.  This allows
766          folding switch statements on machines using casesi (such as
767          the VAX).  */
768       if (GET_CODE (op) == TRUNCATE
769           && GET_MODE (XEXP (op, 0)) == mode
770           && GET_CODE (XEXP (op, 0)) == MINUS
771           && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
772           && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
773         return XEXP (op, 0);
774
775       /* Check for a sign extension of a subreg of a promoted
776          variable, where the promotion is sign-extended, and the
777          target mode is the same as the variable's promotion.  */
778       if (GET_CODE (op) == SUBREG
779           && SUBREG_PROMOTED_VAR_P (op)
780           && ! SUBREG_PROMOTED_UNSIGNED_P (op)
781           && GET_MODE (XEXP (op, 0)) == mode)
782         return XEXP (op, 0);
783
784 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
785       if (! POINTERS_EXTEND_UNSIGNED
786           && mode == Pmode && GET_MODE (op) == ptr_mode
787           && (CONSTANT_P (op)
788               || (GET_CODE (op) == SUBREG
789                   && REG_P (SUBREG_REG (op))
790                   && REG_POINTER (SUBREG_REG (op))
791                   && GET_MODE (SUBREG_REG (op)) == Pmode)))
792         return convert_memory_address (Pmode, op);
793 #endif
794       break;
795
796     case ZERO_EXTEND:
797       /* Check for a zero extension of a subreg of a promoted
798          variable, where the promotion is zero-extended, and the
799          target mode is the same as the variable's promotion.  */
800       if (GET_CODE (op) == SUBREG
801           && SUBREG_PROMOTED_VAR_P (op)
802           && SUBREG_PROMOTED_UNSIGNED_P (op) > 0
803           && GET_MODE (XEXP (op, 0)) == mode)
804         return XEXP (op, 0);
805
806 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
807       if (POINTERS_EXTEND_UNSIGNED > 0
808           && mode == Pmode && GET_MODE (op) == ptr_mode
809           && (CONSTANT_P (op)
810               || (GET_CODE (op) == SUBREG
811                   && REG_P (SUBREG_REG (op))
812                   && REG_POINTER (SUBREG_REG (op))
813                   && GET_MODE (SUBREG_REG (op)) == Pmode)))
814         return convert_memory_address (Pmode, op);
815 #endif
816       break;
817
818     default:
819       break;
820     }
821   
822   return 0;
823 }
824
825 /* Try to compute the value of a unary operation CODE whose output mode is to
826    be MODE with input operand OP whose mode was originally OP_MODE.
827    Return zero if the value cannot be computed.  */
828 rtx
829 simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
830                                 rtx op, enum machine_mode op_mode)
831 {
832   unsigned int width = GET_MODE_BITSIZE (mode);
833
834   if (code == VEC_DUPLICATE)
835     {
836       gcc_assert (VECTOR_MODE_P (mode));
837       if (GET_MODE (op) != VOIDmode)
838       {
839         if (!VECTOR_MODE_P (GET_MODE (op)))
840           gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
841         else
842           gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
843                                                 (GET_MODE (op)));
844       }
845       if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
846           || GET_CODE (op) == CONST_VECTOR)
847         {
848           int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
849           unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
850           rtvec v = rtvec_alloc (n_elts);
851           unsigned int i;
852
853           if (GET_CODE (op) != CONST_VECTOR)
854             for (i = 0; i < n_elts; i++)
855               RTVEC_ELT (v, i) = op;
856           else
857             {
858               enum machine_mode inmode = GET_MODE (op);
859               int in_elt_size = GET_MODE_SIZE (GET_MODE_INNER (inmode));
860               unsigned in_n_elts = (GET_MODE_SIZE (inmode) / in_elt_size);
861
862               gcc_assert (in_n_elts < n_elts);
863               gcc_assert ((n_elts % in_n_elts) == 0);
864               for (i = 0; i < n_elts; i++)
865                 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op, i % in_n_elts);
866             }
867           return gen_rtx_CONST_VECTOR (mode, v);
868         }
869     }
870
871   if (VECTOR_MODE_P (mode) && GET_CODE (op) == CONST_VECTOR)
872     {
873       int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
874       unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
875       enum machine_mode opmode = GET_MODE (op);
876       int op_elt_size = GET_MODE_SIZE (GET_MODE_INNER (opmode));
877       unsigned op_n_elts = (GET_MODE_SIZE (opmode) / op_elt_size);
878       rtvec v = rtvec_alloc (n_elts);
879       unsigned int i;
880
881       gcc_assert (op_n_elts == n_elts);
882       for (i = 0; i < n_elts; i++)
883         {
884           rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
885                                             CONST_VECTOR_ELT (op, i),
886                                             GET_MODE_INNER (opmode));
887           if (!x)
888             return 0;
889           RTVEC_ELT (v, i) = x;
890         }
891       return gen_rtx_CONST_VECTOR (mode, v);
892     }
893
894   /* The order of these tests is critical so that, for example, we don't
895      check the wrong mode (input vs. output) for a conversion operation,
896      such as FIX.  At some point, this should be simplified.  */
897
898   if (code == FLOAT && GET_MODE (op) == VOIDmode
899       && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
900     {
901       HOST_WIDE_INT hv, lv;
902       REAL_VALUE_TYPE d;
903
904       if (GET_CODE (op) == CONST_INT)
905         lv = INTVAL (op), hv = HWI_SIGN_EXTEND (lv);
906       else
907         lv = CONST_DOUBLE_LOW (op),  hv = CONST_DOUBLE_HIGH (op);
908
909       REAL_VALUE_FROM_INT (d, lv, hv, mode);
910       d = real_value_truncate (mode, d);
911       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
912     }
913   else if (code == UNSIGNED_FLOAT && GET_MODE (op) == VOIDmode
914            && (GET_CODE (op) == CONST_DOUBLE
915                || GET_CODE (op) == CONST_INT))
916     {
917       HOST_WIDE_INT hv, lv;
918       REAL_VALUE_TYPE d;
919
920       if (GET_CODE (op) == CONST_INT)
921         lv = INTVAL (op), hv = HWI_SIGN_EXTEND (lv);
922       else
923         lv = CONST_DOUBLE_LOW (op),  hv = CONST_DOUBLE_HIGH (op);
924
925       if (op_mode == VOIDmode)
926         {
927           /* We don't know how to interpret negative-looking numbers in
928              this case, so don't try to fold those.  */
929           if (hv < 0)
930             return 0;
931         }
932       else if (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT * 2)
933         ;
934       else
935         hv = 0, lv &= GET_MODE_MASK (op_mode);
936
937       REAL_VALUE_FROM_UNSIGNED_INT (d, lv, hv, mode);
938       d = real_value_truncate (mode, d);
939       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
940     }
941
942   if (GET_CODE (op) == CONST_INT
943       && width <= HOST_BITS_PER_WIDE_INT && width > 0)
944     {
945       HOST_WIDE_INT arg0 = INTVAL (op);
946       HOST_WIDE_INT val;
947
948       switch (code)
949         {
950         case NOT:
951           val = ~ arg0;
952           break;
953
954         case NEG:
955           val = - arg0;
956           break;
957
958         case ABS:
959           val = (arg0 >= 0 ? arg0 : - arg0);
960           break;
961
962         case FFS:
963           /* Don't use ffs here.  Instead, get low order bit and then its
964              number.  If arg0 is zero, this will return 0, as desired.  */
965           arg0 &= GET_MODE_MASK (mode);
966           val = exact_log2 (arg0 & (- arg0)) + 1;
967           break;
968
969         case CLZ:
970           arg0 &= GET_MODE_MASK (mode);
971           if (arg0 == 0 && CLZ_DEFINED_VALUE_AT_ZERO (mode, val))
972             ;
973           else
974             val = GET_MODE_BITSIZE (mode) - floor_log2 (arg0) - 1;
975           break;
976
977         case CTZ:
978           arg0 &= GET_MODE_MASK (mode);
979           if (arg0 == 0)
980             {
981               /* Even if the value at zero is undefined, we have to come
982                  up with some replacement.  Seems good enough.  */
983               if (! CTZ_DEFINED_VALUE_AT_ZERO (mode, val))
984                 val = GET_MODE_BITSIZE (mode);
985             }
986           else
987             val = exact_log2 (arg0 & -arg0);
988           break;
989
990         case POPCOUNT:
991           arg0 &= GET_MODE_MASK (mode);
992           val = 0;
993           while (arg0)
994             val++, arg0 &= arg0 - 1;
995           break;
996
997         case PARITY:
998           arg0 &= GET_MODE_MASK (mode);
999           val = 0;
1000           while (arg0)
1001             val++, arg0 &= arg0 - 1;
1002           val &= 1;
1003           break;
1004
1005         case TRUNCATE:
1006           val = arg0;
1007           break;
1008
1009         case ZERO_EXTEND:
1010           /* When zero-extending a CONST_INT, we need to know its
1011              original mode.  */
1012           gcc_assert (op_mode != VOIDmode);
1013           if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
1014             {
1015               /* If we were really extending the mode,
1016                  we would have to distinguish between zero-extension
1017                  and sign-extension.  */
1018               gcc_assert (width == GET_MODE_BITSIZE (op_mode));
1019               val = arg0;
1020             }
1021           else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
1022             val = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode));
1023           else
1024             return 0;
1025           break;
1026
1027         case SIGN_EXTEND:
1028           if (op_mode == VOIDmode)
1029             op_mode = mode;
1030           if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
1031             {
1032               /* If we were really extending the mode,
1033                  we would have to distinguish between zero-extension
1034                  and sign-extension.  */
1035               gcc_assert (width == GET_MODE_BITSIZE (op_mode));
1036               val = arg0;
1037             }
1038           else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
1039             {
1040               val
1041                 = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode));
1042               if (val
1043                   & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (op_mode) - 1)))
1044                 val -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
1045             }
1046           else
1047             return 0;
1048           break;
1049
1050         case SQRT:
1051         case FLOAT_EXTEND:
1052         case FLOAT_TRUNCATE:
1053         case SS_TRUNCATE:
1054         case US_TRUNCATE:
1055           return 0;
1056
1057         default:
1058           gcc_unreachable ();
1059         }
1060
1061       return gen_int_mode (val, mode);
1062     }
1063
1064   /* We can do some operations on integer CONST_DOUBLEs.  Also allow
1065      for a DImode operation on a CONST_INT.  */
1066   else if (GET_MODE (op) == VOIDmode
1067            && width <= HOST_BITS_PER_WIDE_INT * 2
1068            && (GET_CODE (op) == CONST_DOUBLE
1069                || GET_CODE (op) == CONST_INT))
1070     {
1071       unsigned HOST_WIDE_INT l1, lv;
1072       HOST_WIDE_INT h1, hv;
1073
1074       if (GET_CODE (op) == CONST_DOUBLE)
1075         l1 = CONST_DOUBLE_LOW (op), h1 = CONST_DOUBLE_HIGH (op);
1076       else
1077         l1 = INTVAL (op), h1 = HWI_SIGN_EXTEND (l1);
1078
1079       switch (code)
1080         {
1081         case NOT:
1082           lv = ~ l1;
1083           hv = ~ h1;
1084           break;
1085
1086         case NEG:
1087           neg_double (l1, h1, &lv, &hv);
1088           break;
1089
1090         case ABS:
1091           if (h1 < 0)
1092             neg_double (l1, h1, &lv, &hv);
1093           else
1094             lv = l1, hv = h1;
1095           break;
1096
1097         case FFS:
1098           hv = 0;
1099           if (l1 == 0)
1100             {
1101               if (h1 == 0)
1102                 lv = 0;
1103               else
1104                 lv = HOST_BITS_PER_WIDE_INT + exact_log2 (h1 & -h1) + 1;
1105             }
1106           else
1107             lv = exact_log2 (l1 & -l1) + 1;
1108           break;
1109
1110         case CLZ:
1111           hv = 0;
1112           if (h1 != 0)
1113             lv = GET_MODE_BITSIZE (mode) - floor_log2 (h1) - 1
1114               - HOST_BITS_PER_WIDE_INT;
1115           else if (l1 != 0)
1116             lv = GET_MODE_BITSIZE (mode) - floor_log2 (l1) - 1;
1117           else if (! CLZ_DEFINED_VALUE_AT_ZERO (mode, lv))
1118             lv = GET_MODE_BITSIZE (mode);
1119           break;
1120
1121         case CTZ:
1122           hv = 0;
1123           if (l1 != 0)
1124             lv = exact_log2 (l1 & -l1);
1125           else if (h1 != 0)
1126             lv = HOST_BITS_PER_WIDE_INT + exact_log2 (h1 & -h1);
1127           else if (! CTZ_DEFINED_VALUE_AT_ZERO (mode, lv))
1128             lv = GET_MODE_BITSIZE (mode);
1129           break;
1130
1131         case POPCOUNT:
1132           hv = 0;
1133           lv = 0;
1134           while (l1)
1135             lv++, l1 &= l1 - 1;
1136           while (h1)
1137             lv++, h1 &= h1 - 1;
1138           break;
1139
1140         case PARITY:
1141           hv = 0;
1142           lv = 0;
1143           while (l1)
1144             lv++, l1 &= l1 - 1;
1145           while (h1)
1146             lv++, h1 &= h1 - 1;
1147           lv &= 1;
1148           break;
1149
1150         case TRUNCATE:
1151           /* This is just a change-of-mode, so do nothing.  */
1152           lv = l1, hv = h1;
1153           break;
1154
1155         case ZERO_EXTEND:
1156           gcc_assert (op_mode != VOIDmode);
1157
1158           if (GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
1159             return 0;
1160
1161           hv = 0;
1162           lv = l1 & GET_MODE_MASK (op_mode);
1163           break;
1164
1165         case SIGN_EXTEND:
1166           if (op_mode == VOIDmode
1167               || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
1168             return 0;
1169           else
1170             {
1171               lv = l1 & GET_MODE_MASK (op_mode);
1172               if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT
1173                   && (lv & ((HOST_WIDE_INT) 1
1174                             << (GET_MODE_BITSIZE (op_mode) - 1))) != 0)
1175                 lv -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
1176
1177               hv = HWI_SIGN_EXTEND (lv);
1178             }
1179           break;
1180
1181         case SQRT:
1182           return 0;
1183
1184         default:
1185           return 0;
1186         }
1187
1188       return immed_double_const (lv, hv, mode);
1189     }
1190
1191   else if (GET_CODE (op) == CONST_DOUBLE
1192            && SCALAR_FLOAT_MODE_P (mode))
1193     {
1194       REAL_VALUE_TYPE d, t;
1195       REAL_VALUE_FROM_CONST_DOUBLE (d, op);
1196
1197       switch (code)
1198         {
1199         case SQRT:
1200           if (HONOR_SNANS (mode) && real_isnan (&d))
1201             return 0;
1202           real_sqrt (&t, mode, &d);
1203           d = t;
1204           break;
1205         case ABS:
1206           d = REAL_VALUE_ABS (d);
1207           break;
1208         case NEG:
1209           d = REAL_VALUE_NEGATE (d);
1210           break;
1211         case FLOAT_TRUNCATE:
1212           d = real_value_truncate (mode, d);
1213           break;
1214         case FLOAT_EXTEND:
1215           /* All this does is change the mode.  */
1216           break;
1217         case FIX:
1218           real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
1219           break;
1220         case NOT:
1221           {
1222             long tmp[4];
1223             int i;
1224
1225             real_to_target (tmp, &d, GET_MODE (op));
1226             for (i = 0; i < 4; i++)
1227               tmp[i] = ~tmp[i];
1228             real_from_target (&d, tmp, mode);
1229             break;
1230           }
1231         default:
1232           gcc_unreachable ();
1233         }
1234       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
1235     }
1236
1237   else if (GET_CODE (op) == CONST_DOUBLE
1238            && SCALAR_FLOAT_MODE_P (GET_MODE (op))
1239            && GET_MODE_CLASS (mode) == MODE_INT
1240            && width <= 2*HOST_BITS_PER_WIDE_INT && width > 0)
1241     {
1242       /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
1243          operators are intentionally left unspecified (to ease implementation
1244          by target backends), for consistency, this routine implements the
1245          same semantics for constant folding as used by the middle-end.  */
1246
1247       /* This was formerly used only for non-IEEE float.
1248          eggert@twinsun.com says it is safe for IEEE also.  */
1249       HOST_WIDE_INT xh, xl, th, tl;
1250       REAL_VALUE_TYPE x, t;
1251       REAL_VALUE_FROM_CONST_DOUBLE (x, op);
1252       switch (code)
1253         {
1254         case FIX:
1255           if (REAL_VALUE_ISNAN (x))
1256             return const0_rtx;
1257
1258           /* Test against the signed upper bound.  */
1259           if (width > HOST_BITS_PER_WIDE_INT)
1260             {
1261               th = ((unsigned HOST_WIDE_INT) 1
1262                     << (width - HOST_BITS_PER_WIDE_INT - 1)) - 1;
1263               tl = -1;
1264             }
1265           else
1266             {
1267               th = 0;
1268               tl = ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1;
1269             }
1270           real_from_integer (&t, VOIDmode, tl, th, 0);
1271           if (REAL_VALUES_LESS (t, x))
1272             {
1273               xh = th;
1274               xl = tl;
1275               break;
1276             }
1277
1278           /* Test against the signed lower bound.  */
1279           if (width > HOST_BITS_PER_WIDE_INT)
1280             {
1281               th = (HOST_WIDE_INT) -1 << (width - HOST_BITS_PER_WIDE_INT - 1);
1282               tl = 0;
1283             }
1284           else
1285             {
1286               th = -1;
1287               tl = (HOST_WIDE_INT) -1 << (width - 1);
1288             }
1289           real_from_integer (&t, VOIDmode, tl, th, 0);
1290           if (REAL_VALUES_LESS (x, t))
1291             {
1292               xh = th;
1293               xl = tl;
1294               break;
1295             }
1296           REAL_VALUE_TO_INT (&xl, &xh, x);
1297           break;
1298
1299         case UNSIGNED_FIX:
1300           if (REAL_VALUE_ISNAN (x) || REAL_VALUE_NEGATIVE (x))
1301             return const0_rtx;
1302
1303           /* Test against the unsigned upper bound.  */
1304           if (width == 2*HOST_BITS_PER_WIDE_INT)
1305             {
1306               th = -1;
1307               tl = -1;
1308             }
1309           else if (width >= HOST_BITS_PER_WIDE_INT)
1310             {
1311               th = ((unsigned HOST_WIDE_INT) 1
1312                     << (width - HOST_BITS_PER_WIDE_INT)) - 1;
1313               tl = -1;
1314             }
1315           else
1316             {
1317               th = 0;
1318               tl = ((unsigned HOST_WIDE_INT) 1 << width) - 1;
1319             }
1320           real_from_integer (&t, VOIDmode, tl, th, 1);
1321           if (REAL_VALUES_LESS (t, x))
1322             {
1323               xh = th;
1324               xl = tl;
1325               break;
1326             }
1327
1328           REAL_VALUE_TO_INT (&xl, &xh, x);
1329           break;
1330
1331         default:
1332           gcc_unreachable ();
1333         }
1334       return immed_double_const (xl, xh, mode);
1335     }
1336
1337   return NULL_RTX;
1338 }
1339 \f
1340 /* Subroutine of simplify_binary_operation to simplify a commutative,
1341    associative binary operation CODE with result mode MODE, operating
1342    on OP0 and OP1.  CODE is currently one of PLUS, MULT, AND, IOR, XOR,
1343    SMIN, SMAX, UMIN or UMAX.  Return zero if no simplification or
1344    canonicalization is possible.  */
1345
1346 static rtx
1347 simplify_associative_operation (enum rtx_code code, enum machine_mode mode,
1348                                 rtx op0, rtx op1)
1349 {
1350   rtx tem;
1351
1352   /* Linearize the operator to the left.  */
1353   if (GET_CODE (op1) == code)
1354     {
1355       /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)".  */
1356       if (GET_CODE (op0) == code)
1357         {
1358           tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
1359           return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
1360         }
1361
1362       /* "a op (b op c)" becomes "(b op c) op a".  */
1363       if (! swap_commutative_operands_p (op1, op0))
1364         return simplify_gen_binary (code, mode, op1, op0);
1365
1366       tem = op0;
1367       op0 = op1;
1368       op1 = tem;
1369     }
1370
1371   if (GET_CODE (op0) == code)
1372     {
1373       /* Canonicalize "(x op c) op y" as "(x op y) op c".  */
1374       if (swap_commutative_operands_p (XEXP (op0, 1), op1))
1375         {
1376           tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
1377           return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
1378         }
1379
1380       /* Attempt to simplify "(a op b) op c" as "a op (b op c)".  */
1381       tem = swap_commutative_operands_p (XEXP (op0, 1), op1)
1382             ? simplify_binary_operation (code, mode, op1, XEXP (op0, 1))
1383             : simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
1384       if (tem != 0)
1385         return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
1386
1387       /* Attempt to simplify "(a op b) op c" as "(a op c) op b".  */
1388       tem = swap_commutative_operands_p (XEXP (op0, 0), op1)
1389             ? simplify_binary_operation (code, mode, op1, XEXP (op0, 0))
1390             : simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
1391       if (tem != 0)
1392         return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
1393     }
1394
1395   return 0;
1396 }
1397
1398
1399 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
1400    and OP1.  Return 0 if no simplification is possible.
1401
1402    Don't use this for relational operations such as EQ or LT.
1403    Use simplify_relational_operation instead.  */
1404 rtx
1405 simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
1406                            rtx op0, rtx op1)
1407 {
1408   rtx trueop0, trueop1;
1409   rtx tem;
1410
1411   /* Relational operations don't work here.  We must know the mode
1412      of the operands in order to do the comparison correctly.
1413      Assuming a full word can give incorrect results.
1414      Consider comparing 128 with -128 in QImode.  */
1415   gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
1416   gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
1417
1418   /* Make sure the constant is second.  */
1419   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
1420       && swap_commutative_operands_p (op0, op1))
1421     {
1422       tem = op0, op0 = op1, op1 = tem;
1423     }
1424
1425   trueop0 = avoid_constant_pool_reference (op0);
1426   trueop1 = avoid_constant_pool_reference (op1);
1427
1428   tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
1429   if (tem)
1430     return tem;
1431   return simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
1432 }
1433
1434 static rtx
1435 simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
1436                              rtx op0, rtx op1, rtx trueop0, rtx trueop1)
1437 {
1438   rtx tem, reversed, opleft, opright;
1439   HOST_WIDE_INT val;
1440   unsigned int width = GET_MODE_BITSIZE (mode);
1441
1442   /* Even if we can't compute a constant result,
1443      there are some cases worth simplifying.  */
1444
1445   switch (code)
1446     {
1447     case PLUS:
1448       /* Maybe simplify x + 0 to x.  The two expressions are equivalent
1449          when x is NaN, infinite, or finite and nonzero.  They aren't
1450          when x is -0 and the rounding mode is not towards -infinity,
1451          since (-0) + 0 is then 0.  */
1452       if (!HONOR_SIGNED_ZEROS (mode) && trueop1 == CONST0_RTX (mode))
1453         return op0;
1454
1455       /* ((-a) + b) -> (b - a) and similarly for (a + (-b)).  These
1456          transformations are safe even for IEEE.  */
1457       if (GET_CODE (op0) == NEG)
1458         return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
1459       else if (GET_CODE (op1) == NEG)
1460         return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
1461
1462       /* (~a) + 1 -> -a */
1463       if (INTEGRAL_MODE_P (mode)
1464           && GET_CODE (op0) == NOT
1465           && trueop1 == const1_rtx)
1466         return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
1467
1468       /* Handle both-operands-constant cases.  We can only add
1469          CONST_INTs to constants since the sum of relocatable symbols
1470          can't be handled by most assemblers.  Don't add CONST_INT
1471          to CONST_INT since overflow won't be computed properly if wider
1472          than HOST_BITS_PER_WIDE_INT.  */
1473
1474       if (CONSTANT_P (op0) && GET_MODE (op0) != VOIDmode
1475           && GET_CODE (op1) == CONST_INT)
1476         return plus_constant (op0, INTVAL (op1));
1477       else if (CONSTANT_P (op1) && GET_MODE (op1) != VOIDmode
1478                && GET_CODE (op0) == CONST_INT)
1479         return plus_constant (op1, INTVAL (op0));
1480
1481       /* See if this is something like X * C - X or vice versa or
1482          if the multiplication is written as a shift.  If so, we can
1483          distribute and make a new multiply, shift, or maybe just
1484          have X (if C is 2 in the example above).  But don't make
1485          something more expensive than we had before.  */
1486
1487       if (SCALAR_INT_MODE_P (mode))
1488         {
1489           HOST_WIDE_INT coeff0h = 0, coeff1h = 0;
1490           unsigned HOST_WIDE_INT coeff0l = 1, coeff1l = 1;
1491           rtx lhs = op0, rhs = op1;
1492
1493           if (GET_CODE (lhs) == NEG)
1494             {
1495               coeff0l = -1;
1496               coeff0h = -1;
1497               lhs = XEXP (lhs, 0);
1498             }
1499           else if (GET_CODE (lhs) == MULT
1500                    && GET_CODE (XEXP (lhs, 1)) == CONST_INT)
1501             {
1502               coeff0l = INTVAL (XEXP (lhs, 1));
1503               coeff0h = INTVAL (XEXP (lhs, 1)) < 0 ? -1 : 0;
1504               lhs = XEXP (lhs, 0);
1505             }
1506           else if (GET_CODE (lhs) == ASHIFT
1507                    && GET_CODE (XEXP (lhs, 1)) == CONST_INT
1508                    && INTVAL (XEXP (lhs, 1)) >= 0
1509                    && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
1510             {
1511               coeff0l = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
1512               coeff0h = 0;
1513               lhs = XEXP (lhs, 0);
1514             }
1515
1516           if (GET_CODE (rhs) == NEG)
1517             {
1518               coeff1l = -1;
1519               coeff1h = -1;
1520               rhs = XEXP (rhs, 0);
1521             }
1522           else if (GET_CODE (rhs) == MULT
1523                    && GET_CODE (XEXP (rhs, 1)) == CONST_INT)
1524             {
1525               coeff1l = INTVAL (XEXP (rhs, 1));
1526               coeff1h = INTVAL (XEXP (rhs, 1)) < 0 ? -1 : 0;
1527               rhs = XEXP (rhs, 0);
1528             }
1529           else if (GET_CODE (rhs) == ASHIFT
1530                    && GET_CODE (XEXP (rhs, 1)) == CONST_INT
1531                    && INTVAL (XEXP (rhs, 1)) >= 0
1532                    && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
1533             {
1534               coeff1l = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
1535               coeff1h = 0;
1536               rhs = XEXP (rhs, 0);
1537             }
1538
1539           if (rtx_equal_p (lhs, rhs))
1540             {
1541               rtx orig = gen_rtx_PLUS (mode, op0, op1);
1542               rtx coeff;
1543               unsigned HOST_WIDE_INT l;
1544               HOST_WIDE_INT h;
1545
1546               add_double (coeff0l, coeff0h, coeff1l, coeff1h, &l, &h);
1547               coeff = immed_double_const (l, h, mode);
1548
1549               tem = simplify_gen_binary (MULT, mode, lhs, coeff);
1550               return rtx_cost (tem, SET) <= rtx_cost (orig, SET)
1551                 ? tem : 0;
1552             }
1553         }
1554
1555       /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit.  */
1556       if ((GET_CODE (op1) == CONST_INT
1557            || GET_CODE (op1) == CONST_DOUBLE)
1558           && GET_CODE (op0) == XOR
1559           && (GET_CODE (XEXP (op0, 1)) == CONST_INT
1560               || GET_CODE (XEXP (op0, 1)) == CONST_DOUBLE)
1561           && mode_signbit_p (mode, op1))
1562         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
1563                                     simplify_gen_binary (XOR, mode, op1,
1564                                                          XEXP (op0, 1)));
1565
1566       /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)).  */
1567       if (GET_CODE (op0) == MULT
1568           && GET_CODE (XEXP (op0, 0)) == NEG)
1569         {
1570           rtx in1, in2;
1571
1572           in1 = XEXP (XEXP (op0, 0), 0);
1573           in2 = XEXP (op0, 1);
1574           return simplify_gen_binary (MINUS, mode, op1,
1575                                       simplify_gen_binary (MULT, mode,
1576                                                            in1, in2));
1577         }
1578
1579       /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
1580          C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
1581          is 1.  */
1582       if (COMPARISON_P (op0)
1583           && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
1584               || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
1585           && (reversed = reversed_comparison (op0, mode)))
1586         return
1587           simplify_gen_unary (NEG, mode, reversed, mode);
1588
1589       /* If one of the operands is a PLUS or a MINUS, see if we can
1590          simplify this by the associative law.
1591          Don't use the associative law for floating point.
1592          The inaccuracy makes it nonassociative,
1593          and subtle programs can break if operations are associated.  */
1594
1595       if (INTEGRAL_MODE_P (mode)
1596           && (plus_minus_operand_p (op0)
1597               || plus_minus_operand_p (op1))
1598           && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
1599         return tem;
1600
1601       /* Reassociate floating point addition only when the user
1602          specifies unsafe math optimizations.  */
1603       if (FLOAT_MODE_P (mode)
1604           && flag_unsafe_math_optimizations)
1605         {
1606           tem = simplify_associative_operation (code, mode, op0, op1);
1607           if (tem)
1608             return tem;
1609         }
1610       break;
1611
1612     case COMPARE:
1613 #ifdef HAVE_cc0
1614       /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
1615          using cc0, in which case we want to leave it as a COMPARE
1616          so we can distinguish it from a register-register-copy.
1617
1618          In IEEE floating point, x-0 is not the same as x.  */
1619
1620       if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
1621            || ! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
1622           && trueop1 == CONST0_RTX (mode))
1623         return op0;
1624 #endif
1625
1626       /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags).  */
1627       if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
1628            || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
1629           && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx)
1630         {
1631           rtx xop00 = XEXP (op0, 0);
1632           rtx xop10 = XEXP (op1, 0);
1633
1634 #ifdef HAVE_cc0
1635           if (GET_CODE (xop00) == CC0 && GET_CODE (xop10) == CC0)
1636 #else
1637             if (REG_P (xop00) && REG_P (xop10)
1638                 && GET_MODE (xop00) == GET_MODE (xop10)
1639                 && REGNO (xop00) == REGNO (xop10)
1640                 && GET_MODE_CLASS (GET_MODE (xop00)) == MODE_CC
1641                 && GET_MODE_CLASS (GET_MODE (xop10)) == MODE_CC)
1642 #endif
1643               return xop00;
1644         }
1645       break;
1646
1647     case MINUS:
1648       /* We can't assume x-x is 0 even with non-IEEE floating point,
1649          but since it is zero except in very strange circumstances, we
1650          will treat it as zero with -funsafe-math-optimizations.  */
1651       if (rtx_equal_p (trueop0, trueop1)
1652           && ! side_effects_p (op0)
1653           && (! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations))
1654         return CONST0_RTX (mode);
1655
1656       /* Change subtraction from zero into negation.  (0 - x) is the
1657          same as -x when x is NaN, infinite, or finite and nonzero.
1658          But if the mode has signed zeros, and does not round towards
1659          -infinity, then 0 - 0 is 0, not -0.  */
1660       if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
1661         return simplify_gen_unary (NEG, mode, op1, mode);
1662
1663       /* (-1 - a) is ~a.  */
1664       if (trueop0 == constm1_rtx)
1665         return simplify_gen_unary (NOT, mode, op1, mode);
1666
1667       /* Subtracting 0 has no effect unless the mode has signed zeros
1668          and supports rounding towards -infinity.  In such a case,
1669          0 - 0 is -0.  */
1670       if (!(HONOR_SIGNED_ZEROS (mode)
1671             && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1672           && trueop1 == CONST0_RTX (mode))
1673         return op0;
1674
1675       /* See if this is something like X * C - X or vice versa or
1676          if the multiplication is written as a shift.  If so, we can
1677          distribute and make a new multiply, shift, or maybe just
1678          have X (if C is 2 in the example above).  But don't make
1679          something more expensive than we had before.  */
1680
1681       if (SCALAR_INT_MODE_P (mode))
1682         {
1683           HOST_WIDE_INT coeff0h = 0, negcoeff1h = -1;
1684           unsigned HOST_WIDE_INT coeff0l = 1, negcoeff1l = -1;
1685           rtx lhs = op0, rhs = op1;
1686
1687           if (GET_CODE (lhs) == NEG)
1688             {
1689               coeff0l = -1;
1690               coeff0h = -1;
1691               lhs = XEXP (lhs, 0);
1692             }
1693           else if (GET_CODE (lhs) == MULT
1694                    && GET_CODE (XEXP (lhs, 1)) == CONST_INT)
1695             {
1696               coeff0l = INTVAL (XEXP (lhs, 1));
1697               coeff0h = INTVAL (XEXP (lhs, 1)) < 0 ? -1 : 0;
1698               lhs = XEXP (lhs, 0);
1699             }
1700           else if (GET_CODE (lhs) == ASHIFT
1701                    && GET_CODE (XEXP (lhs, 1)) == CONST_INT
1702                    && INTVAL (XEXP (lhs, 1)) >= 0
1703                    && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
1704             {
1705               coeff0l = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
1706               coeff0h = 0;
1707               lhs = XEXP (lhs, 0);
1708             }
1709
1710           if (GET_CODE (rhs) == NEG)
1711             {
1712               negcoeff1l = 1;
1713               negcoeff1h = 0;
1714               rhs = XEXP (rhs, 0);
1715             }
1716           else if (GET_CODE (rhs) == MULT
1717                    && GET_CODE (XEXP (rhs, 1)) == CONST_INT)
1718             {
1719               negcoeff1l = -INTVAL (XEXP (rhs, 1));
1720               negcoeff1h = INTVAL (XEXP (rhs, 1)) <= 0 ? 0 : -1;
1721               rhs = XEXP (rhs, 0);
1722             }
1723           else if (GET_CODE (rhs) == ASHIFT
1724                    && GET_CODE (XEXP (rhs, 1)) == CONST_INT
1725                    && INTVAL (XEXP (rhs, 1)) >= 0
1726                    && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
1727             {
1728               negcoeff1l = -(((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1)));
1729               negcoeff1h = -1;
1730               rhs = XEXP (rhs, 0);
1731             }
1732
1733           if (rtx_equal_p (lhs, rhs))
1734             {
1735               rtx orig = gen_rtx_MINUS (mode, op0, op1);
1736               rtx coeff;
1737               unsigned HOST_WIDE_INT l;
1738               HOST_WIDE_INT h;
1739
1740               add_double (coeff0l, coeff0h, negcoeff1l, negcoeff1h, &l, &h);
1741               coeff = immed_double_const (l, h, mode);
1742
1743               tem = simplify_gen_binary (MULT, mode, lhs, coeff);
1744               return rtx_cost (tem, SET) <= rtx_cost (orig, SET)
1745                 ? tem : 0;
1746             }
1747         }
1748
1749       /* (a - (-b)) -> (a + b).  True even for IEEE.  */
1750       if (GET_CODE (op1) == NEG)
1751         return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
1752
1753       /* (-x - c) may be simplified as (-c - x).  */
1754       if (GET_CODE (op0) == NEG
1755           && (GET_CODE (op1) == CONST_INT
1756               || GET_CODE (op1) == CONST_DOUBLE))
1757         {
1758           tem = simplify_unary_operation (NEG, mode, op1, mode);
1759           if (tem)
1760             return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
1761         }
1762
1763       /* Don't let a relocatable value get a negative coeff.  */
1764       if (GET_CODE (op1) == CONST_INT && GET_MODE (op0) != VOIDmode)
1765         return simplify_gen_binary (PLUS, mode,
1766                                     op0,
1767                                     neg_const_int (mode, op1));
1768
1769       /* (x - (x & y)) -> (x & ~y) */
1770       if (GET_CODE (op1) == AND)
1771         {
1772           if (rtx_equal_p (op0, XEXP (op1, 0)))
1773             {
1774               tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
1775                                         GET_MODE (XEXP (op1, 1)));
1776               return simplify_gen_binary (AND, mode, op0, tem);
1777             }
1778           if (rtx_equal_p (op0, XEXP (op1, 1)))
1779             {
1780               tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
1781                                         GET_MODE (XEXP (op1, 0)));
1782               return simplify_gen_binary (AND, mode, op0, tem);
1783             }
1784         }
1785
1786       /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
1787          by reversing the comparison code if valid.  */
1788       if (STORE_FLAG_VALUE == 1
1789           && trueop0 == const1_rtx
1790           && COMPARISON_P (op1)
1791           && (reversed = reversed_comparison (op1, mode)))
1792         return reversed;
1793
1794       /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A).  */
1795       if (GET_CODE (op1) == MULT
1796           && GET_CODE (XEXP (op1, 0)) == NEG)
1797         {
1798           rtx in1, in2;
1799
1800           in1 = XEXP (XEXP (op1, 0), 0);
1801           in2 = XEXP (op1, 1);
1802           return simplify_gen_binary (PLUS, mode,
1803                                       simplify_gen_binary (MULT, mode,
1804                                                            in1, in2),
1805                                       op0);
1806         }
1807
1808       /* Canonicalize (minus (neg A) (mult B C)) to
1809          (minus (mult (neg B) C) A).  */
1810       if (GET_CODE (op1) == MULT
1811           && GET_CODE (op0) == NEG)
1812         {
1813           rtx in1, in2;
1814
1815           in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
1816           in2 = XEXP (op1, 1);
1817           return simplify_gen_binary (MINUS, mode,
1818                                       simplify_gen_binary (MULT, mode,
1819                                                            in1, in2),
1820                                       XEXP (op0, 0));
1821         }
1822
1823       /* If one of the operands is a PLUS or a MINUS, see if we can
1824          simplify this by the associative law.  This will, for example,
1825          canonicalize (minus A (plus B C)) to (minus (minus A B) C).
1826          Don't use the associative law for floating point.
1827          The inaccuracy makes it nonassociative,
1828          and subtle programs can break if operations are associated.  */
1829
1830       if (INTEGRAL_MODE_P (mode)
1831           && (plus_minus_operand_p (op0)
1832               || plus_minus_operand_p (op1))
1833           && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
1834         return tem;
1835       break;
1836
1837     case MULT:
1838       if (trueop1 == constm1_rtx)
1839         return simplify_gen_unary (NEG, mode, op0, mode);
1840
1841       /* Maybe simplify x * 0 to 0.  The reduction is not valid if
1842          x is NaN, since x * 0 is then also NaN.  Nor is it valid
1843          when the mode has signed zeros, since multiplying a negative
1844          number by 0 will give -0, not 0.  */
1845       if (!HONOR_NANS (mode)
1846           && !HONOR_SIGNED_ZEROS (mode)
1847           && trueop1 == CONST0_RTX (mode)
1848           && ! side_effects_p (op0))
1849         return op1;
1850
1851       /* In IEEE floating point, x*1 is not equivalent to x for
1852          signalling NaNs.  */
1853       if (!HONOR_SNANS (mode)
1854           && trueop1 == CONST1_RTX (mode))
1855         return op0;
1856
1857       /* Convert multiply by constant power of two into shift unless
1858          we are still generating RTL.  This test is a kludge.  */
1859       if (GET_CODE (trueop1) == CONST_INT
1860           && (val = exact_log2 (INTVAL (trueop1))) >= 0
1861           /* If the mode is larger than the host word size, and the
1862              uppermost bit is set, then this isn't a power of two due
1863              to implicit sign extension.  */
1864           && (width <= HOST_BITS_PER_WIDE_INT
1865               || val != HOST_BITS_PER_WIDE_INT - 1))
1866         return simplify_gen_binary (ASHIFT, mode, op0, GEN_INT (val));
1867
1868       /* Likewise for multipliers wider than a word.  */
1869       else if (GET_CODE (trueop1) == CONST_DOUBLE
1870                && (GET_MODE (trueop1) == VOIDmode
1871                    || GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_INT)
1872                && GET_MODE (op0) == mode
1873                && CONST_DOUBLE_LOW (trueop1) == 0
1874                && (val = exact_log2 (CONST_DOUBLE_HIGH (trueop1))) >= 0)
1875         return simplify_gen_binary (ASHIFT, mode, op0,
1876                                     GEN_INT (val + HOST_BITS_PER_WIDE_INT));
1877
1878       /* x*2 is x+x and x*(-1) is -x */
1879       if (GET_CODE (trueop1) == CONST_DOUBLE
1880           && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
1881           && GET_MODE (op0) == mode)
1882         {
1883           REAL_VALUE_TYPE d;
1884           REAL_VALUE_FROM_CONST_DOUBLE (d, trueop1);
1885
1886           if (REAL_VALUES_EQUAL (d, dconst2))
1887             return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
1888
1889           if (REAL_VALUES_EQUAL (d, dconstm1))
1890             return simplify_gen_unary (NEG, mode, op0, mode);
1891         }
1892
1893       /* Reassociate multiplication, but for floating point MULTs
1894          only when the user specifies unsafe math optimizations.  */
1895       if (! FLOAT_MODE_P (mode)
1896           || flag_unsafe_math_optimizations)
1897         {
1898           tem = simplify_associative_operation (code, mode, op0, op1);
1899           if (tem)
1900             return tem;
1901         }
1902       break;
1903
1904     case IOR:
1905       if (trueop1 == const0_rtx)
1906         return op0;
1907       if (GET_CODE (trueop1) == CONST_INT
1908           && ((INTVAL (trueop1) & GET_MODE_MASK (mode))
1909               == GET_MODE_MASK (mode)))
1910         return op1;
1911       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
1912         return op0;
1913       /* A | (~A) -> -1 */
1914       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
1915            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
1916           && ! side_effects_p (op0)
1917           && SCALAR_INT_MODE_P (mode))
1918         return constm1_rtx;
1919
1920       /* (ior A C) is C if all bits of A that might be nonzero are on in C.  */
1921       if (GET_CODE (op1) == CONST_INT
1922           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
1923           && (nonzero_bits (op0, mode) & ~INTVAL (op1)) == 0)
1924         return op1;
1925  
1926       /* Convert (A & B) | A to A.  */
1927       if (GET_CODE (op0) == AND
1928           && (rtx_equal_p (XEXP (op0, 0), op1)
1929               || rtx_equal_p (XEXP (op0, 1), op1))
1930           && ! side_effects_p (XEXP (op0, 0))
1931           && ! side_effects_p (XEXP (op0, 1)))
1932         return op1;
1933
1934       /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
1935          mode size to (rotate A CX).  */
1936
1937       if (GET_CODE (op1) == ASHIFT
1938           || GET_CODE (op1) == SUBREG)
1939         {
1940           opleft = op1;
1941           opright = op0;
1942         }
1943       else
1944         {
1945           opright = op1;
1946           opleft = op0;
1947         }
1948
1949       if (GET_CODE (opleft) == ASHIFT && GET_CODE (opright) == LSHIFTRT
1950           && rtx_equal_p (XEXP (opleft, 0), XEXP (opright, 0))
1951           && GET_CODE (XEXP (opleft, 1)) == CONST_INT
1952           && GET_CODE (XEXP (opright, 1)) == CONST_INT
1953           && (INTVAL (XEXP (opleft, 1)) + INTVAL (XEXP (opright, 1))
1954               == GET_MODE_BITSIZE (mode)))
1955         return gen_rtx_ROTATE (mode, XEXP (opright, 0), XEXP (opleft, 1));
1956
1957       /* Same, but for ashift that has been "simplified" to a wider mode
1958         by simplify_shift_const.  */
1959
1960       if (GET_CODE (opleft) == SUBREG
1961           && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
1962           && GET_CODE (opright) == LSHIFTRT
1963           && GET_CODE (XEXP (opright, 0)) == SUBREG
1964           && GET_MODE (opleft) == GET_MODE (XEXP (opright, 0))
1965           && SUBREG_BYTE (opleft) == SUBREG_BYTE (XEXP (opright, 0))
1966           && (GET_MODE_SIZE (GET_MODE (opleft))
1967               < GET_MODE_SIZE (GET_MODE (SUBREG_REG (opleft))))
1968           && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
1969                           SUBREG_REG (XEXP (opright, 0)))
1970           && GET_CODE (XEXP (SUBREG_REG (opleft), 1)) == CONST_INT
1971           && GET_CODE (XEXP (opright, 1)) == CONST_INT
1972           && (INTVAL (XEXP (SUBREG_REG (opleft), 1)) + INTVAL (XEXP (opright, 1))
1973               == GET_MODE_BITSIZE (mode)))
1974         return gen_rtx_ROTATE (mode, XEXP (opright, 0),
1975                                XEXP (SUBREG_REG (opright), 1));
1976
1977       /* If we have (ior (and (X C1) C2)), simplify this by making
1978          C1 as small as possible if C1 actually changes.  */
1979       if (GET_CODE (op1) == CONST_INT
1980           && (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
1981               || INTVAL (op1) > 0)
1982           && GET_CODE (op0) == AND
1983           && GET_CODE (XEXP (op0, 1)) == CONST_INT
1984           && GET_CODE (op1) == CONST_INT
1985           && (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) != 0)
1986         return simplify_gen_binary (IOR, mode,
1987                                     simplify_gen_binary
1988                                           (AND, mode, XEXP (op0, 0),
1989                                            GEN_INT (INTVAL (XEXP (op0, 1))
1990                                                     & ~INTVAL (op1))),
1991                                     op1);
1992
1993       /* If OP0 is (ashiftrt (plus ...) C), it might actually be
1994          a (sign_extend (plus ...)).  Then check if OP1 is a CONST_INT and
1995          the PLUS does not affect any of the bits in OP1: then we can do
1996          the IOR as a PLUS and we can associate.  This is valid if OP1
1997          can be safely shifted left C bits.  */
1998       if (GET_CODE (trueop1) == CONST_INT && GET_CODE (op0) == ASHIFTRT
1999           && GET_CODE (XEXP (op0, 0)) == PLUS
2000           && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
2001           && GET_CODE (XEXP (op0, 1)) == CONST_INT
2002           && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
2003         {
2004           int count = INTVAL (XEXP (op0, 1));
2005           HOST_WIDE_INT mask = INTVAL (trueop1) << count;
2006
2007           if (mask >> count == INTVAL (trueop1)
2008               && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
2009             return simplify_gen_binary (ASHIFTRT, mode,
2010                                         plus_constant (XEXP (op0, 0), mask),
2011                                         XEXP (op0, 1));
2012         }
2013
2014       tem = simplify_associative_operation (code, mode, op0, op1);
2015       if (tem)
2016         return tem;
2017       break;
2018
2019     case XOR:
2020       if (trueop1 == const0_rtx)
2021         return op0;
2022       if (GET_CODE (trueop1) == CONST_INT
2023           && ((INTVAL (trueop1) & GET_MODE_MASK (mode))
2024               == GET_MODE_MASK (mode)))
2025         return simplify_gen_unary (NOT, mode, op0, mode);
2026       if (rtx_equal_p (trueop0, trueop1)
2027           && ! side_effects_p (op0)
2028           && GET_MODE_CLASS (mode) != MODE_CC)
2029          return CONST0_RTX (mode);
2030
2031       /* Canonicalize XOR of the most significant bit to PLUS.  */
2032       if ((GET_CODE (op1) == CONST_INT
2033            || GET_CODE (op1) == CONST_DOUBLE)
2034           && mode_signbit_p (mode, op1))
2035         return simplify_gen_binary (PLUS, mode, op0, op1);
2036       /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit.  */
2037       if ((GET_CODE (op1) == CONST_INT
2038            || GET_CODE (op1) == CONST_DOUBLE)
2039           && GET_CODE (op0) == PLUS
2040           && (GET_CODE (XEXP (op0, 1)) == CONST_INT
2041               || GET_CODE (XEXP (op0, 1)) == CONST_DOUBLE)
2042           && mode_signbit_p (mode, XEXP (op0, 1)))
2043         return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
2044                                     simplify_gen_binary (XOR, mode, op1,
2045                                                          XEXP (op0, 1)));
2046
2047       /* If we are XORing two things that have no bits in common,
2048          convert them into an IOR.  This helps to detect rotation encoded
2049          using those methods and possibly other simplifications.  */
2050
2051       if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2052           && (nonzero_bits (op0, mode)
2053               & nonzero_bits (op1, mode)) == 0)
2054         return (simplify_gen_binary (IOR, mode, op0, op1));
2055
2056       /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
2057          Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
2058          (NOT y).  */
2059       {
2060         int num_negated = 0;
2061
2062         if (GET_CODE (op0) == NOT)
2063           num_negated++, op0 = XEXP (op0, 0);
2064         if (GET_CODE (op1) == NOT)
2065           num_negated++, op1 = XEXP (op1, 0);
2066
2067         if (num_negated == 2)
2068           return simplify_gen_binary (XOR, mode, op0, op1);
2069         else if (num_negated == 1)
2070           return simplify_gen_unary (NOT, mode,
2071                                      simplify_gen_binary (XOR, mode, op0, op1),
2072                                      mode);
2073       }
2074
2075       /* Convert (xor (and A B) B) to (and (not A) B).  The latter may
2076          correspond to a machine insn or result in further simplifications
2077          if B is a constant.  */
2078
2079       if (GET_CODE (op0) == AND
2080           && rtx_equal_p (XEXP (op0, 1), op1)
2081           && ! side_effects_p (op1))
2082         return simplify_gen_binary (AND, mode,
2083                                     simplify_gen_unary (NOT, mode,
2084                                                         XEXP (op0, 0), mode),
2085                                     op1);
2086
2087       else if (GET_CODE (op0) == AND
2088                && rtx_equal_p (XEXP (op0, 0), op1)
2089                && ! side_effects_p (op1))
2090         return simplify_gen_binary (AND, mode,
2091                                     simplify_gen_unary (NOT, mode,
2092                                                         XEXP (op0, 1), mode),
2093                                     op1);
2094
2095       /* (xor (comparison foo bar) (const_int 1)) can become the reversed
2096          comparison if STORE_FLAG_VALUE is 1.  */
2097       if (STORE_FLAG_VALUE == 1
2098           && trueop1 == const1_rtx
2099           && COMPARISON_P (op0)
2100           && (reversed = reversed_comparison (op0, mode)))
2101         return reversed;
2102
2103       /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
2104          is (lt foo (const_int 0)), so we can perform the above
2105          simplification if STORE_FLAG_VALUE is 1.  */
2106
2107       if (STORE_FLAG_VALUE == 1
2108           && trueop1 == const1_rtx
2109           && GET_CODE (op0) == LSHIFTRT
2110           && GET_CODE (XEXP (op0, 1)) == CONST_INT
2111           && INTVAL (XEXP (op0, 1)) == GET_MODE_BITSIZE (mode) - 1)
2112         return gen_rtx_GE (mode, XEXP (op0, 0), const0_rtx);
2113
2114       /* (xor (comparison foo bar) (const_int sign-bit))
2115          when STORE_FLAG_VALUE is the sign bit.  */
2116       if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2117           && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
2118               == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
2119           && trueop1 == const_true_rtx
2120           && COMPARISON_P (op0)
2121           && (reversed = reversed_comparison (op0, mode)))
2122         return reversed;
2123
2124       break;
2125       
2126       tem = simplify_associative_operation (code, mode, op0, op1);
2127       if (tem)
2128         return tem;
2129       break;
2130
2131     case AND:
2132       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
2133         return trueop1;
2134       /* If we are turning off bits already known off in OP0, we need
2135          not do an AND.  */
2136       if (GET_CODE (trueop1) == CONST_INT
2137           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2138           && (nonzero_bits (trueop0, mode) & ~INTVAL (trueop1)) == 0)
2139         return op0;
2140       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
2141           && GET_MODE_CLASS (mode) != MODE_CC)
2142         return op0;
2143       /* A & (~A) -> 0 */
2144       if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
2145            || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
2146           && ! side_effects_p (op0)
2147           && GET_MODE_CLASS (mode) != MODE_CC)
2148         return CONST0_RTX (mode);
2149
2150       /* Transform (and (extend X) C) into (zero_extend (and X C)) if
2151          there are no nonzero bits of C outside of X's mode.  */
2152       if ((GET_CODE (op0) == SIGN_EXTEND
2153            || GET_CODE (op0) == ZERO_EXTEND)
2154           && GET_CODE (trueop1) == CONST_INT
2155           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2156           && (~GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))
2157               & INTVAL (trueop1)) == 0)
2158         {
2159           enum machine_mode imode = GET_MODE (XEXP (op0, 0));
2160           tem = simplify_gen_binary (AND, imode, XEXP (op0, 0),
2161                                      gen_int_mode (INTVAL (trueop1),
2162                                                    imode));
2163           return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
2164         }
2165
2166       /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
2167          insn (and may simplify more).  */
2168       if (GET_CODE (op0) == XOR
2169           && rtx_equal_p (XEXP (op0, 0), op1)
2170           && ! side_effects_p (op1))
2171         return simplify_gen_binary (AND, mode,
2172                                     simplify_gen_unary (NOT, mode,
2173                                                         XEXP (op0, 1), mode),
2174                                     op1);
2175
2176       if (GET_CODE (op0) == XOR
2177           && rtx_equal_p (XEXP (op0, 1), op1)
2178           && ! side_effects_p (op1))
2179         return simplify_gen_binary (AND, mode,
2180                                     simplify_gen_unary (NOT, mode,
2181                                                         XEXP (op0, 0), mode),
2182                                     op1);
2183
2184       /* Similarly for (~(A ^ B)) & A.  */
2185       if (GET_CODE (op0) == NOT
2186           && GET_CODE (XEXP (op0, 0)) == XOR
2187           && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
2188           && ! side_effects_p (op1))
2189         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
2190
2191       if (GET_CODE (op0) == NOT
2192           && GET_CODE (XEXP (op0, 0)) == XOR
2193           && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
2194           && ! side_effects_p (op1))
2195         return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
2196
2197       /* Convert (A | B) & A to A.  */
2198       if (GET_CODE (op0) == IOR
2199           && (rtx_equal_p (XEXP (op0, 0), op1)
2200               || rtx_equal_p (XEXP (op0, 1), op1))
2201           && ! side_effects_p (XEXP (op0, 0))
2202           && ! side_effects_p (XEXP (op0, 1)))
2203         return op1;
2204
2205       /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
2206          ((A & N) + B) & M -> (A + B) & M
2207          Similarly if (N & M) == 0,
2208          ((A | N) + B) & M -> (A + B) & M
2209          and for - instead of + and/or ^ instead of |.  */
2210       if (GET_CODE (trueop1) == CONST_INT
2211           && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2212           && ~INTVAL (trueop1)
2213           && (INTVAL (trueop1) & (INTVAL (trueop1) + 1)) == 0
2214           && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
2215         {
2216           rtx pmop[2];
2217           int which;
2218
2219           pmop[0] = XEXP (op0, 0);
2220           pmop[1] = XEXP (op0, 1);
2221
2222           for (which = 0; which < 2; which++)
2223             {
2224               tem = pmop[which];
2225               switch (GET_CODE (tem))
2226                 {
2227                 case AND:
2228                   if (GET_CODE (XEXP (tem, 1)) == CONST_INT
2229                       && (INTVAL (XEXP (tem, 1)) & INTVAL (trueop1))
2230                       == INTVAL (trueop1))
2231                     pmop[which] = XEXP (tem, 0);
2232                   break;
2233                 case IOR:
2234                 case XOR:
2235                   if (GET_CODE (XEXP (tem, 1)) == CONST_INT
2236                       && (INTVAL (XEXP (tem, 1)) & INTVAL (trueop1)) == 0)
2237                     pmop[which] = XEXP (tem, 0);
2238                   break;
2239                 default:
2240                   break;
2241                 }
2242             }
2243
2244           if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
2245             {
2246               tem = simplify_gen_binary (GET_CODE (op0), mode,
2247                                          pmop[0], pmop[1]);
2248               return simplify_gen_binary (code, mode, tem, op1);
2249             }
2250         }
2251       tem = simplify_associative_operation (code, mode, op0, op1);
2252       if (tem)
2253         return tem;
2254       break;
2255
2256     case UDIV:
2257       /* 0/x is 0 (or x&0 if x has side-effects).  */
2258       if (trueop0 == CONST0_RTX (mode))
2259         {
2260           if (side_effects_p (op1))
2261             return simplify_gen_binary (AND, mode, op1, trueop0);
2262           return trueop0;
2263         }
2264       /* x/1 is x.  */
2265       if (trueop1 == CONST1_RTX (mode))
2266         return rtl_hooks.gen_lowpart_no_emit (mode, op0);
2267       /* Convert divide by power of two into shift.  */
2268       if (GET_CODE (trueop1) == CONST_INT
2269           && (val = exact_log2 (INTVAL (trueop1))) > 0)
2270         return simplify_gen_binary (LSHIFTRT, mode, op0, GEN_INT (val));
2271       break;
2272
2273     case DIV:
2274       /* Handle floating point and integers separately.  */
2275       if (SCALAR_FLOAT_MODE_P (mode))
2276         {
2277           /* Maybe change 0.0 / x to 0.0.  This transformation isn't
2278              safe for modes with NaNs, since 0.0 / 0.0 will then be
2279              NaN rather than 0.0.  Nor is it safe for modes with signed
2280              zeros, since dividing 0 by a negative number gives -0.0  */
2281           if (trueop0 == CONST0_RTX (mode)
2282               && !HONOR_NANS (mode)
2283               && !HONOR_SIGNED_ZEROS (mode)
2284               && ! side_effects_p (op1))
2285             return op0;
2286           /* x/1.0 is x.  */
2287           if (trueop1 == CONST1_RTX (mode)
2288               && !HONOR_SNANS (mode))
2289             return op0;
2290
2291           if (GET_CODE (trueop1) == CONST_DOUBLE
2292               && trueop1 != CONST0_RTX (mode))
2293             {
2294               REAL_VALUE_TYPE d;
2295               REAL_VALUE_FROM_CONST_DOUBLE (d, trueop1);
2296
2297               /* x/-1.0 is -x.  */
2298               if (REAL_VALUES_EQUAL (d, dconstm1)
2299                   && !HONOR_SNANS (mode))
2300                 return simplify_gen_unary (NEG, mode, op0, mode);
2301
2302               /* Change FP division by a constant into multiplication.
2303                  Only do this with -funsafe-math-optimizations.  */
2304               if (flag_unsafe_math_optimizations
2305                   && !REAL_VALUES_EQUAL (d, dconst0))
2306                 {
2307                   REAL_ARITHMETIC (d, RDIV_EXPR, dconst1, d);
2308                   tem = CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
2309                   return simplify_gen_binary (MULT, mode, op0, tem);
2310                 }
2311             }
2312         }
2313       else
2314         {
2315           /* 0/x is 0 (or x&0 if x has side-effects).  */
2316           if (trueop0 == CONST0_RTX (mode))
2317             {
2318               if (side_effects_p (op1))
2319                 return simplify_gen_binary (AND, mode, op1, trueop0);
2320               return trueop0;
2321             }
2322           /* x/1 is x.  */
2323           if (trueop1 == CONST1_RTX (mode))
2324             return rtl_hooks.gen_lowpart_no_emit (mode, op0);
2325           /* x/-1 is -x.  */
2326           if (trueop1 == constm1_rtx)
2327             {
2328               rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
2329               return simplify_gen_unary (NEG, mode, x, mode);
2330             }
2331         }
2332       break;
2333
2334     case UMOD:
2335       /* 0%x is 0 (or x&0 if x has side-effects).  */
2336       if (trueop0 == CONST0_RTX (mode))
2337         {
2338           if (side_effects_p (op1))
2339             return simplify_gen_binary (AND, mode, op1, trueop0);
2340           return trueop0;
2341         }
2342       /* x%1 is 0 (of x&0 if x has side-effects).  */
2343       if (trueop1 == CONST1_RTX (mode))
2344         {
2345           if (side_effects_p (op0))
2346             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
2347           return CONST0_RTX (mode);
2348         }
2349       /* Implement modulus by power of two as AND.  */
2350       if (GET_CODE (trueop1) == CONST_INT
2351           && exact_log2 (INTVAL (trueop1)) > 0)
2352         return simplify_gen_binary (AND, mode, op0,
2353                                     GEN_INT (INTVAL (op1) - 1));
2354       break;
2355
2356     case MOD:
2357       /* 0%x is 0 (or x&0 if x has side-effects).  */
2358       if (trueop0 == CONST0_RTX (mode))
2359         {
2360           if (side_effects_p (op1))
2361             return simplify_gen_binary (AND, mode, op1, trueop0);
2362           return trueop0;
2363         }
2364       /* x%1 and x%-1 is 0 (or x&0 if x has side-effects).  */
2365       if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
2366         {
2367           if (side_effects_p (op0))
2368             return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
2369           return CONST0_RTX (mode);
2370         }
2371       break;
2372
2373     case ROTATERT:
2374     case ROTATE:
2375     case ASHIFTRT:
2376       /* Rotating ~0 always results in ~0.  */
2377       if (GET_CODE (trueop0) == CONST_INT && width <= HOST_BITS_PER_WIDE_INT
2378           && (unsigned HOST_WIDE_INT) INTVAL (trueop0) == GET_MODE_MASK (mode)
2379           && ! side_effects_p (op1))
2380         return op0;
2381
2382       /* Fall through....  */
2383
2384     case ASHIFT:
2385     case LSHIFTRT:
2386       if (trueop1 == CONST0_RTX (mode))
2387         return op0;
2388       if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
2389         return op0;
2390       break;
2391
2392     case SMIN:
2393       if (width <= HOST_BITS_PER_WIDE_INT
2394           && GET_CODE (trueop1) == CONST_INT
2395           && INTVAL (trueop1) == (HOST_WIDE_INT) 1 << (width -1)
2396           && ! side_effects_p (op0))
2397         return op1;
2398       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2399         return op0;
2400       tem = simplify_associative_operation (code, mode, op0, op1);
2401       if (tem)
2402         return tem;
2403       break;
2404
2405     case SMAX:
2406       if (width <= HOST_BITS_PER_WIDE_INT
2407           && GET_CODE (trueop1) == CONST_INT
2408           && ((unsigned HOST_WIDE_INT) INTVAL (trueop1)
2409               == (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode) >> 1)
2410           && ! side_effects_p (op0))
2411         return op1;
2412       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2413         return op0;
2414       tem = simplify_associative_operation (code, mode, op0, op1);
2415       if (tem)
2416         return tem;
2417       break;
2418
2419     case UMIN:
2420       if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
2421         return op1;
2422       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2423         return op0;
2424       tem = simplify_associative_operation (code, mode, op0, op1);
2425       if (tem)
2426         return tem;
2427       break;
2428
2429     case UMAX:
2430       if (trueop1 == constm1_rtx && ! side_effects_p (op0))
2431         return op1;
2432       if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2433         return op0;
2434       tem = simplify_associative_operation (code, mode, op0, op1);
2435       if (tem)
2436         return tem;
2437       break;
2438
2439     case SS_PLUS:
2440     case US_PLUS:
2441     case SS_MINUS:
2442     case US_MINUS:
2443       /* ??? There are simplifications that can be done.  */
2444       return 0;
2445
2446     case VEC_SELECT:
2447       if (!VECTOR_MODE_P (mode))
2448         {
2449           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
2450           gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
2451           gcc_assert (GET_CODE (trueop1) == PARALLEL);
2452           gcc_assert (XVECLEN (trueop1, 0) == 1);
2453           gcc_assert (GET_CODE (XVECEXP (trueop1, 0, 0)) == CONST_INT);
2454
2455           if (GET_CODE (trueop0) == CONST_VECTOR)
2456             return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
2457                                                       (trueop1, 0, 0)));
2458         }
2459       else
2460         {
2461           gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
2462           gcc_assert (GET_MODE_INNER (mode)
2463                       == GET_MODE_INNER (GET_MODE (trueop0)));
2464           gcc_assert (GET_CODE (trueop1) == PARALLEL);
2465
2466           if (GET_CODE (trueop0) == CONST_VECTOR)
2467             {
2468               int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
2469               unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
2470               rtvec v = rtvec_alloc (n_elts);
2471               unsigned int i;
2472
2473               gcc_assert (XVECLEN (trueop1, 0) == (int) n_elts);
2474               for (i = 0; i < n_elts; i++)
2475                 {
2476                   rtx x = XVECEXP (trueop1, 0, i);
2477
2478                   gcc_assert (GET_CODE (x) == CONST_INT);
2479                   RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
2480                                                        INTVAL (x));
2481                 }
2482
2483               return gen_rtx_CONST_VECTOR (mode, v);
2484             }
2485         }
2486
2487       if (XVECLEN (trueop1, 0) == 1
2488           && GET_CODE (XVECEXP (trueop1, 0, 0)) == CONST_INT
2489           && GET_CODE (trueop0) == VEC_CONCAT)
2490         {
2491           rtx vec = trueop0;
2492           int offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
2493
2494           /* Try to find the element in the VEC_CONCAT.  */
2495           while (GET_MODE (vec) != mode
2496                  && GET_CODE (vec) == VEC_CONCAT)
2497             {
2498               HOST_WIDE_INT vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
2499               if (offset < vec_size)
2500                 vec = XEXP (vec, 0);
2501               else
2502                 {
2503                   offset -= vec_size;
2504                   vec = XEXP (vec, 1);
2505                 }
2506               vec = avoid_constant_pool_reference (vec);
2507             }
2508
2509           if (GET_MODE (vec) == mode)
2510             return vec;
2511         }
2512
2513       return 0;
2514     case VEC_CONCAT:
2515       {
2516         enum machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
2517                                       ? GET_MODE (trueop0)
2518                                       : GET_MODE_INNER (mode));
2519         enum machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
2520                                       ? GET_MODE (trueop1)
2521                                       : GET_MODE_INNER (mode));
2522
2523         gcc_assert (VECTOR_MODE_P (mode));
2524         gcc_assert (GET_MODE_SIZE (op0_mode) + GET_MODE_SIZE (op1_mode)
2525                     == GET_MODE_SIZE (mode));
2526
2527         if (VECTOR_MODE_P (op0_mode))
2528           gcc_assert (GET_MODE_INNER (mode)
2529                       == GET_MODE_INNER (op0_mode));
2530         else
2531           gcc_assert (GET_MODE_INNER (mode) == op0_mode);
2532
2533         if (VECTOR_MODE_P (op1_mode))
2534           gcc_assert (GET_MODE_INNER (mode)
2535                       == GET_MODE_INNER (op1_mode));
2536         else
2537           gcc_assert (GET_MODE_INNER (mode) == op1_mode);
2538
2539         if ((GET_CODE (trueop0) == CONST_VECTOR
2540              || GET_CODE (trueop0) == CONST_INT
2541              || GET_CODE (trueop0) == CONST_DOUBLE)
2542             && (GET_CODE (trueop1) == CONST_VECTOR
2543                 || GET_CODE (trueop1) == CONST_INT
2544                 || GET_CODE (trueop1) == CONST_DOUBLE))
2545           {
2546             int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
2547             unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
2548             rtvec v = rtvec_alloc (n_elts);
2549             unsigned int i;
2550             unsigned in_n_elts = 1;
2551
2552             if (VECTOR_MODE_P (op0_mode))
2553               in_n_elts = (GET_MODE_SIZE (op0_mode) / elt_size);
2554             for (i = 0; i < n_elts; i++)
2555               {
2556                 if (i < in_n_elts)
2557                   {
2558                     if (!VECTOR_MODE_P (op0_mode))
2559                       RTVEC_ELT (v, i) = trueop0;
2560                     else
2561                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
2562                   }
2563                 else
2564                   {
2565                     if (!VECTOR_MODE_P (op1_mode))
2566                       RTVEC_ELT (v, i) = trueop1;
2567                     else
2568                       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
2569                                                            i - in_n_elts);
2570                   }
2571               }
2572
2573             return gen_rtx_CONST_VECTOR (mode, v);
2574           }
2575       }
2576       return 0;
2577
2578     default:
2579       gcc_unreachable ();
2580     }
2581
2582   return 0;
2583 }
2584
2585 rtx
2586 simplify_const_binary_operation (enum rtx_code code, enum machine_mode mode,
2587                                  rtx op0, rtx op1)
2588 {
2589   HOST_WIDE_INT arg0, arg1, arg0s, arg1s;
2590   HOST_WIDE_INT val;
2591   unsigned int width = GET_MODE_BITSIZE (mode);
2592
2593   if (VECTOR_MODE_P (mode)
2594       && code != VEC_CONCAT
2595       && GET_CODE (op0) == CONST_VECTOR
2596       && GET_CODE (op1) == CONST_VECTOR)
2597     {
2598       unsigned n_elts = GET_MODE_NUNITS (mode);
2599       enum machine_mode op0mode = GET_MODE (op0);
2600       unsigned op0_n_elts = GET_MODE_NUNITS (op0mode);
2601       enum machine_mode op1mode = GET_MODE (op1);
2602       unsigned op1_n_elts = GET_MODE_NUNITS (op1mode);
2603       rtvec v = rtvec_alloc (n_elts);
2604       unsigned int i;
2605
2606       gcc_assert (op0_n_elts == n_elts);
2607       gcc_assert (op1_n_elts == n_elts);
2608       for (i = 0; i < n_elts; i++)
2609         {
2610           rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
2611                                              CONST_VECTOR_ELT (op0, i),
2612                                              CONST_VECTOR_ELT (op1, i));
2613           if (!x)
2614             return 0;
2615           RTVEC_ELT (v, i) = x;
2616         }
2617
2618       return gen_rtx_CONST_VECTOR (mode, v);
2619     }
2620
2621   if (VECTOR_MODE_P (mode)
2622       && code == VEC_CONCAT
2623       && CONSTANT_P (op0) && CONSTANT_P (op1))
2624     {
2625       unsigned n_elts = GET_MODE_NUNITS (mode);
2626       rtvec v = rtvec_alloc (n_elts);
2627
2628       gcc_assert (n_elts >= 2);
2629       if (n_elts == 2)
2630         {
2631           gcc_assert (GET_CODE (op0) != CONST_VECTOR);
2632           gcc_assert (GET_CODE (op1) != CONST_VECTOR);
2633
2634           RTVEC_ELT (v, 0) = op0;
2635           RTVEC_ELT (v, 1) = op1;
2636         }
2637       else
2638         {
2639           unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0));
2640           unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1));
2641           unsigned i;
2642
2643           gcc_assert (GET_CODE (op0) == CONST_VECTOR);
2644           gcc_assert (GET_CODE (op1) == CONST_VECTOR);
2645           gcc_assert (op0_n_elts + op1_n_elts == n_elts);
2646
2647           for (i = 0; i < op0_n_elts; ++i)
2648             RTVEC_ELT (v, i) = XVECEXP (op0, 0, i);
2649           for (i = 0; i < op1_n_elts; ++i)
2650             RTVEC_ELT (v, op0_n_elts+i) = XVECEXP (op1, 0, i);
2651         }
2652
2653       return gen_rtx_CONST_VECTOR (mode, v);
2654     }
2655
2656   if (SCALAR_FLOAT_MODE_P (mode)
2657       && GET_CODE (op0) == CONST_DOUBLE
2658       && GET_CODE (op1) == CONST_DOUBLE
2659       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
2660     {
2661       if (code == AND
2662           || code == IOR
2663           || code == XOR)
2664         {
2665           long tmp0[4];
2666           long tmp1[4];
2667           REAL_VALUE_TYPE r;
2668           int i;
2669
2670           real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
2671                           GET_MODE (op0));
2672           real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
2673                           GET_MODE (op1));
2674           for (i = 0; i < 4; i++)
2675             {
2676               switch (code)
2677               {
2678               case AND:
2679                 tmp0[i] &= tmp1[i];
2680                 break;
2681               case IOR:
2682                 tmp0[i] |= tmp1[i];
2683                 break;
2684               case XOR:
2685                 tmp0[i] ^= tmp1[i];
2686                 break;
2687               default:
2688                 gcc_unreachable ();
2689               }
2690             }
2691            real_from_target (&r, tmp0, mode);
2692            return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
2693         }
2694       else
2695         {
2696           REAL_VALUE_TYPE f0, f1, value, result;
2697           bool inexact;
2698
2699           REAL_VALUE_FROM_CONST_DOUBLE (f0, op0);
2700           REAL_VALUE_FROM_CONST_DOUBLE (f1, op1);
2701           real_convert (&f0, mode, &f0);
2702           real_convert (&f1, mode, &f1);
2703
2704           if (HONOR_SNANS (mode)
2705               && (REAL_VALUE_ISNAN (f0) || REAL_VALUE_ISNAN (f1)))
2706             return 0;
2707
2708           if (code == DIV
2709               && REAL_VALUES_EQUAL (f1, dconst0)
2710               && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
2711             return 0;
2712
2713           if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
2714               && flag_trapping_math
2715               && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
2716             {
2717               int s0 = REAL_VALUE_NEGATIVE (f0);
2718               int s1 = REAL_VALUE_NEGATIVE (f1);
2719
2720               switch (code)
2721                 {
2722                 case PLUS:
2723                   /* Inf + -Inf = NaN plus exception.  */
2724                   if (s0 != s1)
2725                     return 0;
2726                   break;
2727                 case MINUS:
2728                   /* Inf - Inf = NaN plus exception.  */
2729                   if (s0 == s1)
2730                     return 0;
2731                   break;
2732                 case DIV:
2733                   /* Inf / Inf = NaN plus exception.  */
2734                   return 0;
2735                 default:
2736                   break;
2737                 }
2738             }
2739
2740           if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
2741               && flag_trapping_math
2742               && ((REAL_VALUE_ISINF (f0) && REAL_VALUES_EQUAL (f1, dconst0))
2743                   || (REAL_VALUE_ISINF (f1)
2744                       && REAL_VALUES_EQUAL (f0, dconst0))))
2745             /* Inf * 0 = NaN plus exception.  */
2746             return 0;
2747
2748           inexact = real_arithmetic (&value, rtx_to_tree_code (code),
2749                                      &f0, &f1);
2750           real_convert (&result, mode, &value);
2751
2752           /* Don't constant fold this floating point operation if
2753              the result has overflowed and flag_trapping_math.  */
2754
2755           if (flag_trapping_math
2756               && MODE_HAS_INFINITIES (mode)
2757               && REAL_VALUE_ISINF (result)
2758               && !REAL_VALUE_ISINF (f0)
2759               && !REAL_VALUE_ISINF (f1))
2760             /* Overflow plus exception.  */
2761             return 0;
2762
2763           /* Don't constant fold this floating point operation if the
2764              result may dependent upon the run-time rounding mode and
2765              flag_rounding_math is set, or if GCC's software emulation
2766              is unable to accurately represent the result.  */
2767
2768           if ((flag_rounding_math
2769                || (REAL_MODE_FORMAT_COMPOSITE_P (mode)
2770                    && !flag_unsafe_math_optimizations))
2771               && (inexact || !real_identical (&result, &value)))
2772             return NULL_RTX;
2773
2774           return CONST_DOUBLE_FROM_REAL_VALUE (result, mode);
2775         }
2776     }
2777
2778   /* We can fold some multi-word operations.  */
2779   if (GET_MODE_CLASS (mode) == MODE_INT
2780       && width == HOST_BITS_PER_WIDE_INT * 2
2781       && (GET_CODE (op0) == CONST_DOUBLE || GET_CODE (op0) == CONST_INT)
2782       && (GET_CODE (op1) == CONST_DOUBLE || GET_CODE (op1) == CONST_INT))
2783     {
2784       unsigned HOST_WIDE_INT l1, l2, lv, lt;
2785       HOST_WIDE_INT h1, h2, hv, ht;
2786
2787       if (GET_CODE (op0) == CONST_DOUBLE)
2788         l1 = CONST_DOUBLE_LOW (op0), h1 = CONST_DOUBLE_HIGH (op0);
2789       else
2790         l1 = INTVAL (op0), h1 = HWI_SIGN_EXTEND (l1);
2791
2792       if (GET_CODE (op1) == CONST_DOUBLE)
2793         l2 = CONST_DOUBLE_LOW (op1), h2 = CONST_DOUBLE_HIGH (op1);
2794       else
2795         l2 = INTVAL (op1), h2 = HWI_SIGN_EXTEND (l2);
2796
2797       switch (code)
2798         {
2799         case MINUS:
2800           /* A - B == A + (-B).  */
2801           neg_double (l2, h2, &lv, &hv);
2802           l2 = lv, h2 = hv;
2803
2804           /* Fall through....  */
2805
2806         case PLUS:
2807           add_double (l1, h1, l2, h2, &lv, &hv);
2808           break;
2809
2810         case MULT:
2811           mul_double (l1, h1, l2, h2, &lv, &hv);
2812           break;
2813
2814         case DIV:
2815           if (div_and_round_double (TRUNC_DIV_EXPR, 0, l1, h1, l2, h2,
2816                                     &lv, &hv, &lt, &ht))
2817             return 0;
2818           break;
2819
2820         case MOD:
2821           if (div_and_round_double (TRUNC_DIV_EXPR, 0, l1, h1, l2, h2,
2822                                     &lt, &ht, &lv, &hv))
2823             return 0;
2824           break;
2825
2826         case UDIV:
2827           if (div_and_round_double (TRUNC_DIV_EXPR, 1, l1, h1, l2, h2,
2828                                     &lv, &hv, &lt, &ht))
2829             return 0;
2830           break;
2831
2832         case UMOD:
2833           if (div_and_round_double (TRUNC_DIV_EXPR, 1, l1, h1, l2, h2,
2834                                     &lt, &ht, &lv, &hv))
2835             return 0;
2836           break;
2837
2838         case AND:
2839           lv = l1 & l2, hv = h1 & h2;
2840           break;
2841
2842         case IOR:
2843           lv = l1 | l2, hv = h1 | h2;
2844           break;
2845
2846         case XOR:
2847           lv = l1 ^ l2, hv = h1 ^ h2;
2848           break;
2849
2850         case SMIN:
2851           if (h1 < h2
2852               || (h1 == h2
2853                   && ((unsigned HOST_WIDE_INT) l1
2854                       < (unsigned HOST_WIDE_INT) l2)))
2855             lv = l1, hv = h1;
2856           else
2857             lv = l2, hv = h2;
2858           break;
2859
2860         case SMAX:
2861           if (h1 > h2
2862               || (h1 == h2
2863                   && ((unsigned HOST_WIDE_INT) l1
2864                       > (unsigned HOST_WIDE_INT) l2)))
2865             lv = l1, hv = h1;
2866           else
2867             lv = l2, hv = h2;
2868           break;
2869
2870         case UMIN:
2871           if ((unsigned HOST_WIDE_INT) h1 < (unsigned HOST_WIDE_INT) h2
2872               || (h1 == h2
2873                   && ((unsigned HOST_WIDE_INT) l1
2874                       < (unsigned HOST_WIDE_INT) l2)))
2875             lv = l1, hv = h1;
2876           else
2877             lv = l2, hv = h2;
2878           break;
2879
2880         case UMAX:
2881           if ((unsigned HOST_WIDE_INT) h1 > (unsigned HOST_WIDE_INT) h2
2882               || (h1 == h2
2883                   && ((unsigned HOST_WIDE_INT) l1
2884                       > (unsigned HOST_WIDE_INT) l2)))
2885             lv = l1, hv = h1;
2886           else
2887             lv = l2, hv = h2;
2888           break;
2889
2890         case LSHIFTRT:   case ASHIFTRT:
2891         case ASHIFT:
2892         case ROTATE:     case ROTATERT:
2893           if (SHIFT_COUNT_TRUNCATED)
2894             l2 &= (GET_MODE_BITSIZE (mode) - 1), h2 = 0;
2895
2896           if (h2 != 0 || l2 >= GET_MODE_BITSIZE (mode))
2897             return 0;
2898
2899           if (code == LSHIFTRT || code == ASHIFTRT)
2900             rshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv,
2901                            code == ASHIFTRT);
2902           else if (code == ASHIFT)
2903             lshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv, 1);
2904           else if (code == ROTATE)
2905             lrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
2906           else /* code == ROTATERT */
2907             rrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
2908           break;
2909
2910         default:
2911           return 0;
2912         }
2913
2914       return immed_double_const (lv, hv, mode);
2915     }
2916
2917   if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == CONST_INT
2918       && width <= HOST_BITS_PER_WIDE_INT && width != 0)
2919     {
2920       /* Get the integer argument values in two forms:
2921          zero-extended in ARG0, ARG1 and sign-extended in ARG0S, ARG1S.  */
2922
2923       arg0 = INTVAL (op0);
2924       arg1 = INTVAL (op1);
2925
2926       if (width < HOST_BITS_PER_WIDE_INT)
2927         {
2928           arg0 &= ((HOST_WIDE_INT) 1 << width) - 1;
2929           arg1 &= ((HOST_WIDE_INT) 1 << width) - 1;
2930
2931           arg0s = arg0;
2932           if (arg0s & ((HOST_WIDE_INT) 1 << (width - 1)))
2933             arg0s |= ((HOST_WIDE_INT) (-1) << width);
2934
2935           arg1s = arg1;
2936           if (arg1s & ((HOST_WIDE_INT) 1 << (width - 1)))
2937             arg1s |= ((HOST_WIDE_INT) (-1) << width);
2938         }
2939       else
2940         {
2941           arg0s = arg0;
2942           arg1s = arg1;
2943         }
2944       
2945       /* Compute the value of the arithmetic.  */
2946       
2947       switch (code)
2948         {
2949         case PLUS:
2950           val = arg0s + arg1s;
2951           break;
2952           
2953         case MINUS:
2954           val = arg0s - arg1s;
2955           break;
2956           
2957         case MULT:
2958           val = arg0s * arg1s;
2959           break;
2960           
2961         case DIV:
2962           if (arg1s == 0
2963               || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
2964                   && arg1s == -1))
2965             return 0;
2966           val = arg0s / arg1s;
2967           break;
2968           
2969         case MOD:
2970           if (arg1s == 0
2971               || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
2972                   && arg1s == -1))
2973             return 0;
2974           val = arg0s % arg1s;
2975           break;
2976           
2977         case UDIV:
2978           if (arg1 == 0
2979               || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
2980                   && arg1s == -1))
2981             return 0;
2982           val = (unsigned HOST_WIDE_INT) arg0 / arg1;
2983           break;
2984           
2985         case UMOD:
2986           if (arg1 == 0
2987               || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
2988                   && arg1s == -1))
2989             return 0;
2990           val = (unsigned HOST_WIDE_INT) arg0 % arg1;
2991           break;
2992           
2993         case AND:
2994           val = arg0 & arg1;
2995           break;
2996           
2997         case IOR:
2998           val = arg0 | arg1;
2999           break;
3000           
3001         case XOR:
3002           val = arg0 ^ arg1;
3003           break;
3004           
3005         case LSHIFTRT:
3006         case ASHIFT:
3007         case ASHIFTRT:
3008           /* Truncate the shift if SHIFT_COUNT_TRUNCATED, otherwise make sure
3009              the value is in range.  We can't return any old value for
3010              out-of-range arguments because either the middle-end (via
3011              shift_truncation_mask) or the back-end might be relying on
3012              target-specific knowledge.  Nor can we rely on
3013              shift_truncation_mask, since the shift might not be part of an
3014              ashlM3, lshrM3 or ashrM3 instruction.  */
3015           if (SHIFT_COUNT_TRUNCATED)
3016             arg1 = (unsigned HOST_WIDE_INT) arg1 % width;
3017           else if (arg1 < 0 || arg1 >= GET_MODE_BITSIZE (mode))
3018             return 0;
3019           
3020           val = (code == ASHIFT
3021                  ? ((unsigned HOST_WIDE_INT) arg0) << arg1
3022                  : ((unsigned HOST_WIDE_INT) arg0) >> arg1);
3023           
3024           /* Sign-extend the result for arithmetic right shifts.  */
3025           if (code == ASHIFTRT && arg0s < 0 && arg1 > 0)
3026             val |= ((HOST_WIDE_INT) -1) << (width - arg1);
3027           break;
3028           
3029         case ROTATERT:
3030           if (arg1 < 0)
3031             return 0;
3032           
3033           arg1 %= width;
3034           val = ((((unsigned HOST_WIDE_INT) arg0) << (width - arg1))
3035                  | (((unsigned HOST_WIDE_INT) arg0) >> arg1));
3036           break;
3037           
3038         case ROTATE:
3039           if (arg1 < 0)
3040             return 0;
3041           
3042           arg1 %= width;
3043           val = ((((unsigned HOST_WIDE_INT) arg0) << arg1)
3044                  | (((unsigned HOST_WIDE_INT) arg0) >> (width - arg1)));
3045           break;
3046           
3047         case COMPARE:
3048           /* Do nothing here.  */
3049           return 0;
3050           
3051         case SMIN:
3052           val = arg0s <= arg1s ? arg0s : arg1s;
3053           break;
3054           
3055         case UMIN:
3056           val = ((unsigned HOST_WIDE_INT) arg0
3057                  <= (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
3058           break;
3059           
3060         case SMAX:
3061           val = arg0s > arg1s ? arg0s : arg1s;
3062           break;
3063           
3064         case UMAX:
3065           val = ((unsigned HOST_WIDE_INT) arg0
3066                  > (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
3067           break;
3068           
3069         case SS_PLUS:
3070         case US_PLUS:
3071         case SS_MINUS:
3072         case US_MINUS:
3073           /* ??? There are simplifications that can be done.  */
3074           return 0;
3075           
3076         default:
3077           gcc_unreachable ();
3078         }
3079
3080       return gen_int_mode (val, mode);
3081     }
3082
3083   return NULL_RTX;
3084 }
3085
3086
3087 \f
3088 /* Simplify a PLUS or MINUS, at least one of whose operands may be another
3089    PLUS or MINUS.
3090
3091    Rather than test for specific case, we do this by a brute-force method
3092    and do all possible simplifications until no more changes occur.  Then
3093    we rebuild the operation.  */
3094
3095 struct simplify_plus_minus_op_data
3096 {
3097   rtx op;
3098   short neg;
3099   short ix;
3100 };
3101
3102 static int
3103 simplify_plus_minus_op_data_cmp (const void *p1, const void *p2)
3104 {
3105   const struct simplify_plus_minus_op_data *d1 = p1;
3106   const struct simplify_plus_minus_op_data *d2 = p2;
3107   int result;
3108
3109   result = (commutative_operand_precedence (d2->op)
3110             - commutative_operand_precedence (d1->op));
3111   if (result)
3112     return result;
3113   return d1->ix - d2->ix;
3114 }
3115
3116 static rtx
3117 simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
3118                      rtx op1)
3119 {
3120   struct simplify_plus_minus_op_data ops[8];
3121   rtx result, tem;
3122   int n_ops = 2, input_ops = 2;
3123   int first, changed, canonicalized = 0;
3124   int i, j;
3125
3126   memset (ops, 0, sizeof ops);
3127
3128   /* Set up the two operands and then expand them until nothing has been
3129      changed.  If we run out of room in our array, give up; this should
3130      almost never happen.  */
3131
3132   ops[0].op = op0;
3133   ops[0].neg = 0;
3134   ops[1].op = op1;
3135   ops[1].neg = (code == MINUS);
3136
3137   do
3138     {
3139       changed = 0;
3140
3141       for (i = 0; i < n_ops; i++)
3142         {
3143           rtx this_op = ops[i].op;
3144           int this_neg = ops[i].neg;
3145           enum rtx_code this_code = GET_CODE (this_op);
3146
3147           switch (this_code)
3148             {
3149             case PLUS:
3150             case MINUS:
3151               if (n_ops == 7)
3152                 return NULL_RTX;
3153
3154               ops[n_ops].op = XEXP (this_op, 1);
3155               ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
3156               n_ops++;
3157
3158               ops[i].op = XEXP (this_op, 0);
3159               input_ops++;
3160               changed = 1;
3161               canonicalized |= this_neg;
3162               break;
3163
3164             case NEG:
3165               ops[i].op = XEXP (this_op, 0);
3166               ops[i].neg = ! this_neg;
3167               changed = 1;
3168               canonicalized = 1;
3169               break;
3170
3171             case CONST:
3172               if (n_ops < 7
3173                   && GET_CODE (XEXP (this_op, 0)) == PLUS
3174                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
3175                   && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
3176                 {
3177                   ops[i].op = XEXP (XEXP (this_op, 0), 0);
3178                   ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
3179                   ops[n_ops].neg = this_neg;
3180                   n_ops++;
3181                   changed = 1;
3182                   canonicalized = 1;
3183                 }
3184               break;
3185
3186             case NOT:
3187               /* ~a -> (-a - 1) */
3188               if (n_ops != 7)
3189                 {
3190                   ops[n_ops].op = constm1_rtx;
3191                   ops[n_ops++].neg = this_neg;
3192                   ops[i].op = XEXP (this_op, 0);
3193                   ops[i].neg = !this_neg;
3194                   changed = 1;
3195                   canonicalized = 1;
3196                 }
3197               break;
3198
3199             case CONST_INT:
3200               if (this_neg)
3201                 {
3202                   ops[i].op = neg_const_int (mode, this_op);
3203                   ops[i].neg = 0;
3204                   changed = 1;
3205                   canonicalized = 1;
3206                 }
3207               break;
3208
3209             default:
3210               break;
3211             }
3212         }
3213     }
3214   while (changed);
3215
3216   gcc_assert (n_ops >= 2);
3217   if (!canonicalized)
3218     {
3219       int n_constants = 0;
3220
3221       for (i = 0; i < n_ops; i++)
3222         if (GET_CODE (ops[i].op) == CONST_INT)
3223           n_constants++;
3224
3225       if (n_constants <= 1)
3226         return NULL_RTX;
3227     }
3228
3229   /* If we only have two operands, we can avoid the loops.  */
3230   if (n_ops == 2)
3231     {
3232       enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
3233       rtx lhs, rhs;
3234
3235       /* Get the two operands.  Be careful with the order, especially for
3236          the cases where code == MINUS.  */
3237       if (ops[0].neg && ops[1].neg)
3238         {
3239           lhs = gen_rtx_NEG (mode, ops[0].op);
3240           rhs = ops[1].op;
3241         }
3242       else if (ops[0].neg)
3243         {
3244           lhs = ops[1].op;
3245           rhs = ops[0].op;
3246         }
3247       else
3248         {
3249           lhs = ops[0].op;
3250           rhs = ops[1].op;
3251         }
3252
3253       return simplify_const_binary_operation (code, mode, lhs, rhs);
3254     }
3255
3256   /* Now simplify each pair of operands until nothing changes.  The first
3257      time through just simplify constants against each other.  */
3258
3259   first = 1;
3260   do
3261     {
3262       changed = first;
3263
3264       for (i = 0; i < n_ops - 1; i++)
3265         for (j = i + 1; j < n_ops; j++)
3266           {
3267             rtx lhs = ops[i].op, rhs = ops[j].op;
3268             int lneg = ops[i].neg, rneg = ops[j].neg;
3269
3270             if (lhs != 0 && rhs != 0
3271                 && (! first || (CONSTANT_P (lhs) && CONSTANT_P (rhs))))
3272               {
3273                 enum rtx_code ncode = PLUS;
3274
3275                 if (lneg != rneg)
3276                   {
3277                     ncode = MINUS;
3278                     if (lneg)
3279                       tem = lhs, lhs = rhs, rhs = tem;
3280                   }