OSDN Git Service

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