OSDN Git Service

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