OSDN Git Service

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