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