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