OSDN Git Service

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