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