OSDN Git Service

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