OSDN Git Service

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