public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* RFT/RFA: Eliminate gen_binary, take 2
@ 2004-06-08 16:42 Paolo Bonzini
  2004-06-08 21:13 ` Roger Sayle
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Paolo Bonzini @ 2004-06-08 16:42 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 935 bytes --]

This patch, which is relative to the "Eliminate gen_binary patch", fixes 
the bootstrapping failures that it had caused.  As I had guessed, it is 
a pasto where handling of AND-with-complement-of expressions, which went
undetected under i686-pc-linux-gnu because of the absence of these 
instructions.  I'm sorry to people using other archs.

This version was bootstrapped/regtested i686-pc-linux-gnu, a very 
similar one was tested on sparc-sun-solaris2.8, and this one passes the 
testcase that Eric Botcazou had distilled; but experience with the 
previous patch clearly showed that "very similar" is not enough, so even 
if approved I'll let a week pass so that people can test it and mail 
results.

The actual changelog if approved would be the same as in the gen_binary
elimination patch, since distribute_and_simplify_rtx was described
simply as "New function" there.

Ok for mainline together with the original patch?

Paolo


[-- Attachment #2: combine-tweak.patch --]
[-- Type: text/plain, Size: 2319 bytes --]

2004-06-06  Paolo Bonzini  <bonzini@gnu.org>

	* combine.c (distribute_and_simplify_rtx): Fix handling of
	(and (xor (B C) (not A))).

Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.430
diff -u -r1.430 combine.c
--- combine.c	27 May 2004 08:28:28 -0000	1.430
+++ combine.c	3 Jun 2004 09:00:27 -0000
@@ -7895,13 +7895,10 @@
       /* (and (xor B C) (not A)) == (xor (ior A B) (ior A C))  */
       if (outer == AND && inner == XOR && GET_CODE (op1) == NOT)
         {
-	  new_op0 = simplify_gen_binary (IOR, mode, inner_op0, op1);
-          new_op1 = simplify_gen_binary (IOR, mode, inner_op1, op1);
+	  new_op0 = simplify_gen_binary (IOR, mode, inner_op0, XEXP (op1, 0));
+          new_op1 = simplify_gen_binary (IOR, mode, inner_op1, XEXP (op1, 0));
           x = apply_distributive_law (simplify_gen_binary (XOR, mode,
 							   new_op0, new_op1));
-
-	  if (GET_CODE (x) != AND)
-	    return x;
 	}
       else
 	{
@@ -7909,10 +7906,9 @@
           new_op1 = simplify_gen_binary (outer, mode, inner_op1, op1);
           x = apply_distributive_law (simplify_gen_binary (inner, mode,
 							   new_op0, new_op1));
-
-	  if (GET_CODE (x) != outer)
-	    return x;
 	}
+      if (GET_CODE (x) != outer)
+        return x;
     }
 
   if (ARITHMETIC_P (op1))
@@ -7924,13 +7920,10 @@
       /* (and (not A) (xor B C)) == (xor (ior A B) (ior A C))  */
       if (outer == AND && inner == XOR && GET_CODE (op0) == NOT)
         {
-	  new_op0 = simplify_gen_binary (IOR, mode, inner_op0, op0);
-          new_op1 = simplify_gen_binary (IOR, mode, inner_op1, op0);
+	  new_op0 = simplify_gen_binary (IOR, mode, inner_op0, XEXP (op0, 0));
+          new_op1 = simplify_gen_binary (IOR, mode, inner_op1, XEXP (op0, 0));
           x = apply_distributive_law (simplify_gen_binary (XOR, mode,
 							   new_op0, new_op1));
-
-	  if (GET_CODE (x) != AND)
-	    return x;
 	}
       else
 	{
@@ -7938,10 +7931,9 @@
           new_op1 = simplify_gen_binary (outer, mode, op0, inner_op1);
           x = apply_distributive_law (simplify_gen_binary (inner, mode,
 							   new_op0, new_op1));
-
-	  if (GET_CODE (x) != outer)
-	    return x;
 	}
+      if (GET_CODE (x) != outer)
+        return x;
     }
 
   return NULL_RTX;

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFT/RFA: Eliminate gen_binary, take 2
  2004-06-08 16:42 RFT/RFA: Eliminate gen_binary, take 2 Paolo Bonzini
@ 2004-06-08 21:13 ` Roger Sayle
  2004-06-08 21:51 ` Eric Botcazou
  2004-06-10 12:34 ` Eric Botcazou
  2 siblings, 0 replies; 11+ messages in thread
From: Roger Sayle @ 2004-06-08 21:13 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: gcc-patches


On Tue, 8 Jun 2004, Paolo Bonzini wrote:
> 2004-06-06  Paolo Bonzini  <bonzini@gnu.org>
>
>	* combine.c (distribute_and_simplify_rtx): Fix handling of
>	(and (xor (B C) (not A))).

This is Ok for mainline together with the original.

Thanks for addressing this issue, and for quickly reverting the
broken patch whilst investigating the cause of the failures.

Roger
--

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFT/RFA: Eliminate gen_binary, take 2
  2004-06-08 16:42 RFT/RFA: Eliminate gen_binary, take 2 Paolo Bonzini
  2004-06-08 21:13 ` Roger Sayle
@ 2004-06-08 21:51 ` Eric Botcazou
  2004-06-09  9:21   ` Paolo Bonzini
  2004-06-10 12:34 ` Eric Botcazou
  2 siblings, 1 reply; 11+ messages in thread
From: Eric Botcazou @ 2004-06-08 21:51 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: GCC Patches

> This version was bootstrapped/regtested i686-pc-linux-gnu, a very
> similar one was tested on sparc-sun-solaris2.8, and this one passes the
> testcase that Eric Botcazou had distilled; but experience with the
> previous patch clearly showed that "very similar" is not enough, so even
> if approved I'll let a week pass so that people can test it and mail
> results.

Please provide a complete patch.  And I'll try to find a version of GNU patch 
that can apply it this time. :-)

Thanks.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFT/RFA: Eliminate gen_binary, take 2
  2004-06-08 21:51 ` Eric Botcazou
@ 2004-06-09  9:21   ` Paolo Bonzini
  2004-06-09  9:36     ` Paolo Bonzini
  2004-06-10  7:17     ` Eric Botcazou
  0 siblings, 2 replies; 11+ messages in thread
From: Paolo Bonzini @ 2004-06-09  9:21 UTC (permalink / raw)
  To: gcc-patches; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 195 bytes --]

> Please provide a complete patch.  And I'll try to find a version of GNU patch 
> that can apply it this time. :-)

Here it is.

I can mail you privately a gzipped combine.c if you want.

Paolo

[-- Attachment #2: combine-kill-gen-binary-take-4.patch --]
[-- Type: text/plain, Size: 49569 bytes --]

Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.432
diff -c -r1.432 combine.c
*** combine.c	5 Jun 2004 07:59:39 -0000	1.432
--- combine.c	9 Jun 2004 07:20:09 -0000
***************
*** 372,377 ****
--- 372,378 ----
  static int rtx_equal_for_field_assignment_p (rtx, rtx);
  static rtx make_field_assignment (rtx);
  static rtx apply_distributive_law (rtx);
+ static rtx distribute_and_simplify_rtx (rtx);
  static rtx simplify_and_const_int (rtx, enum machine_mode, rtx,
  				   unsigned HOST_WIDE_INT);
  static int merge_outer_ops (enum rtx_code *, HOST_WIDE_INT *, enum rtx_code,
***************
*** 380,386 ****
  				 int);
  static int recog_for_combine (rtx *, rtx, rtx *);
  static rtx gen_lowpart_for_combine (enum machine_mode, rtx);
- static rtx gen_binary (enum rtx_code, enum machine_mode, rtx, rtx);
  static enum rtx_code simplify_comparison (enum rtx_code, rtx *, rtx *);
  static void update_table_tick (rtx);
  static void record_value_for_reg (rtx, rtx, rtx);
--- 381,386 ----
***************
*** 3017,3030 ****
  
  	  if (src == mask)
  	    SUBST (SET_SRC (x),
! 		   gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
  	  else
! 	    SUBST (SET_SRC (x),
! 		   gen_binary (IOR, mode,
! 			       gen_binary (AND, mode, dest,
! 					   gen_int_mode (~(mask << pos),
! 							 mode)),
! 			       GEN_INT (src << pos)));
  
  	  SUBST (SET_DEST (x), dest);
  
--- 3017,3032 ----
  
  	  if (src == mask)
  	    SUBST (SET_SRC (x),
! 		   simplify_gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
  	  else
! 	    {
! 	      rtx negmask = gen_int_mode (~(mask << pos), mode);
! 	      SUBST (SET_SRC (x),
! 		     simplify_gen_binary (IOR, mode,
! 				          simplify_gen_binary (AND, mode,
! 							       dest, negmask),
! 					  GEN_INT (src << pos)));
! 	    }
  
  	  SUBST (SET_DEST (x), dest);
  
***************
*** 3599,3605 ****
        new = simplify_shift_const (NULL_RTX, ASHIFTRT, mode, new,
  				  INTVAL (XEXP (XEXP (x, 0), 1)));
  
!       SUBST (XEXP (x, 0), gen_binary (PLUS, mode, new, temp));
      }
  
    /* If this is a simple operation applied to an IF_THEN_ELSE, try
--- 3601,3607 ----
        new = simplify_shift_const (NULL_RTX, ASHIFTRT, mode, new,
  				  INTVAL (XEXP (XEXP (x, 0), 1)));
  
!       SUBST (XEXP (x, 0), simplify_gen_binary (PLUS, mode, new, temp));
      }
  
    /* If this is a simple operation applied to an IF_THEN_ELSE, try
***************
*** 3656,3667 ****
  	      /* If the result values are STORE_FLAG_VALUE and zero, we can
  		 just make the comparison operation.  */
  	      if (true_rtx == const_true_rtx && false_rtx == const0_rtx)
! 		x = gen_binary (cond_code, mode, cond, cop1);
  	      else if (true_rtx == const0_rtx && false_rtx == const_true_rtx
  		       && ((reversed = reversed_comparison_code_parts
  					(cond_code, cond, cop1, NULL))
  		           != UNKNOWN))
! 		x = gen_binary (reversed, mode, cond, cop1);
  
  	      /* Likewise, we can make the negate of a comparison operation
  		 if the result values are - STORE_FLAG_VALUE and zero.  */
--- 3658,3671 ----
  	      /* If the result values are STORE_FLAG_VALUE and zero, we can
  		 just make the comparison operation.  */
  	      if (true_rtx == const_true_rtx && false_rtx == const0_rtx)
! 		x = simplify_gen_relational (cond_code, mode, VOIDmode,
! 					     cond, cop1);
  	      else if (true_rtx == const0_rtx && false_rtx == const_true_rtx
  		       && ((reversed = reversed_comparison_code_parts
  					(cond_code, cond, cop1, NULL))
  		           != UNKNOWN))
! 		x = simplify_gen_relational (reversed, mode, VOIDmode,
! 					     cond, cop1);
  
  	      /* Likewise, we can make the negate of a comparison operation
  		 if the result values are - STORE_FLAG_VALUE and zero.  */
***************
*** 3669,3676 ****
  		       && INTVAL (true_rtx) == - STORE_FLAG_VALUE
  		       && false_rtx == const0_rtx)
  		x = simplify_gen_unary (NEG, mode,
! 					gen_binary (cond_code, mode, cond,
! 						    cop1),
  					mode);
  	      else if (GET_CODE (false_rtx) == CONST_INT
  		       && INTVAL (false_rtx) == - STORE_FLAG_VALUE
--- 3673,3681 ----
  		       && INTVAL (true_rtx) == - STORE_FLAG_VALUE
  		       && false_rtx == const0_rtx)
  		x = simplify_gen_unary (NEG, mode,
! 					simplify_gen_relational (cond_code,
! 								 mode, VOIDmode,
! 								 cond, cop1),
  					mode);
  	      else if (GET_CODE (false_rtx) == CONST_INT
  		       && INTVAL (false_rtx) == - STORE_FLAG_VALUE
***************
*** 3679,3691 ****
  					(cond_code, cond, cop1, NULL))
  		           != UNKNOWN))
  		x = simplify_gen_unary (NEG, mode,
! 					gen_binary (reversed, mode,
! 						    cond, cop1),
  					mode);
  	      else
  		return gen_rtx_IF_THEN_ELSE (mode,
! 					     gen_binary (cond_code, VOIDmode,
! 							 cond, cop1),
  					     true_rtx, false_rtx);
  
  	      code = GET_CODE (x);
--- 3684,3700 ----
  					(cond_code, cond, cop1, NULL))
  		           != UNKNOWN))
  		x = simplify_gen_unary (NEG, mode,
! 					simplify_gen_relational (reversed,
! 								 mode, VOIDmode,
! 								 cond, cop1),
  					mode);
  	      else
  		return gen_rtx_IF_THEN_ELSE (mode,
! 					     simplify_gen_relational (cond_code,
! 								      mode,
! 								      VOIDmode,
! 								      cond,
! 								      cop1),
  					     true_rtx, false_rtx);
  
  	      code = GET_CODE (x);
***************
*** 3788,3794 ****
  	    }
  
  	  if (inner)
! 	    return gen_binary (code, mode, other, inner);
  	}
      }
  
--- 3797,3803 ----
  	    }
  
  	  if (inner)
! 	    return simplify_gen_binary (code, mode, other, inner);
  	}
      }
  
***************
*** 3890,3896 ****
        if (GET_CODE (XEXP (x, 0)) == XOR
  	  && XEXP (XEXP (x, 0), 1) == const1_rtx
  	  && nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1)
! 	return gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0), constm1_rtx);
  
        temp = expand_compound_operation (XEXP (x, 0));
  
--- 3899,3906 ----
        if (GET_CODE (XEXP (x, 0)) == XOR
  	  && XEXP (XEXP (x, 0), 1) == const1_rtx
  	  && nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1)
! 	return simplify_gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
! 				    constm1_rtx);
  
        temp = expand_compound_operation (XEXP (x, 0));
  
***************
*** 4118,4125 ****
  
  	  in1 = XEXP (XEXP (XEXP (x, 0), 0), 0);
  	  in2 = XEXP (XEXP (x, 0), 1);
! 	  return gen_binary (MINUS, mode, XEXP (x, 1),
! 			     gen_binary (MULT, mode, in1, in2));
  	}
  
        /* If we have (plus (plus (A const) B)), associate it so that CONST is
--- 4128,4136 ----
  
  	  in1 = XEXP (XEXP (XEXP (x, 0), 0), 0);
  	  in2 = XEXP (XEXP (x, 0), 1);
! 	  return simplify_gen_binary (MINUS, mode, XEXP (x, 1),
! 				      simplify_gen_binary (MULT, mode,
! 							   in1, in2));
  	}
  
        /* If we have (plus (plus (A const) B)), associate it so that CONST is
***************
*** 4128,4137 ****
  	 they are now checked elsewhere.  */
        if (GET_CODE (XEXP (x, 0)) == PLUS
  	  && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
! 	return gen_binary (PLUS, mode,
! 			   gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
! 				       XEXP (x, 1)),
! 			   XEXP (XEXP (x, 0), 1));
  
        /* (plus (xor (and <foo> (const_int pow2 - 1)) <c>) <-c>)
  	 when c is (const_int (pow2 + 1) / 2) is a sign extension of a
--- 4139,4149 ----
  	 they are now checked elsewhere.  */
        if (GET_CODE (XEXP (x, 0)) == PLUS
  	  && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
! 	return simplify_gen_binary (PLUS, mode,
! 			   	    simplify_gen_binary (PLUS, mode,
! 							 XEXP (XEXP (x, 0), 0),
! 							 XEXP (x, 1)),
! 				    XEXP (XEXP (x, 0), 1));
  
        /* (plus (xor (and <foo> (const_int pow2 - 1)) <c>) <-c>)
  	 when c is (const_int (pow2 + 1) / 2) is a sign extension of a
***************
*** 4197,4203 ****
  	      & nonzero_bits (XEXP (x, 1), mode)) == 0)
  	{
  	  /* Try to simplify the expression further.  */
! 	  rtx tor = gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
  	  temp = combine_simplify_rtx (tor, mode, in_dest);
  
  	  /* If we could, great.  If not, do not go ahead with the IOR
--- 4209,4215 ----
  	      & nonzero_bits (XEXP (x, 1), mode)) == 0)
  	{
  	  /* Try to simplify the expression further.  */
! 	  rtx tor = simplify_gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
  	  temp = combine_simplify_rtx (tor, mode, in_dest);
  
  	  /* If we could, great.  If not, do not go ahead with the IOR
***************
*** 4237,4244 ****
  
  	  in1 = XEXP (XEXP (XEXP (x, 1), 0), 0);
  	  in2 = XEXP (XEXP (x, 1), 1);
! 	  return gen_binary (PLUS, mode, gen_binary (MULT, mode, in1, in2),
! 			     XEXP (x, 0));
  	}
  
        /* Canonicalize (minus (neg A) (mult B C)) to
--- 4249,4258 ----
  
  	  in1 = XEXP (XEXP (XEXP (x, 1), 0), 0);
  	  in2 = XEXP (XEXP (x, 1), 1);
! 	  return simplify_gen_binary (PLUS, mode,
! 				      simplify_gen_binary (MULT, mode,
! 							   in1, in2),
! 				      XEXP (x, 0));
  	}
  
        /* Canonicalize (minus (neg A) (mult B C)) to
***************
*** 4250,4266 ****
  
  	  in1 = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 1), 0), mode);
  	  in2 = XEXP (XEXP (x, 1), 1);
! 	  return gen_binary (MINUS, mode, gen_binary (MULT, mode, in1, in2),
! 			     XEXP (XEXP (x, 0), 0));
  	}
  
        /* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for
  	 integers.  */
        if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode))
! 	return gen_binary (MINUS, mode,
! 			   gen_binary (MINUS, mode, XEXP (x, 0),
! 				       XEXP (XEXP (x, 1), 0)),
! 			   XEXP (XEXP (x, 1), 1));
        break;
  
      case MULT:
--- 4264,4283 ----
  
  	  in1 = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 1), 0), mode);
  	  in2 = XEXP (XEXP (x, 1), 1);
! 	  return simplify_gen_binary (MINUS, mode,
! 				      simplify_gen_binary (MULT, mode,
! 							   in1, in2),
! 				      XEXP (XEXP (x, 0), 0));
  	}
  
        /* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for
  	 integers.  */
        if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode))
! 	return simplify_gen_binary (MINUS, mode,
! 				    simplify_gen_binary (MINUS, mode,
! 							 XEXP (x, 0),
! 						         XEXP (XEXP (x, 1), 0)),
! 				    XEXP (XEXP (x, 1), 1));
        break;
  
      case MULT:
***************
*** 4270,4286 ****
  
        if (GET_CODE (XEXP (x, 0)) == PLUS)
  	{
! 	  x = apply_distributive_law
! 	    (gen_binary (PLUS, mode,
! 			 gen_binary (MULT, mode,
! 				     XEXP (XEXP (x, 0), 0), XEXP (x, 1)),
! 			 gen_binary (MULT, mode,
! 				     XEXP (XEXP (x, 0), 1),
! 				     copy_rtx (XEXP (x, 1)))));
! 
! 	  if (GET_CODE (x) != MULT)
! 	    return x;
  	}
        /* Try simplify a*(b/c) as (a*b)/c.  */
        if (FLOAT_MODE_P (mode) && flag_unsafe_math_optimizations
  	  && GET_CODE (XEXP (x, 0)) == DIV)
--- 4287,4297 ----
  
        if (GET_CODE (XEXP (x, 0)) == PLUS)
  	{
! 	  rtx result = distribute_and_simplify_rtx (x);
! 	  if (result)
! 	    return result;
  	}
+ 
        /* Try simplify a*(b/c) as (a*b)/c.  */
        if (FLOAT_MODE_P (mode) && flag_unsafe_math_optimizations
  	  && GET_CODE (XEXP (x, 0)) == DIV)
***************
*** 4289,4295 ****
  					       XEXP (XEXP (x, 0), 0),
  					       XEXP (x, 1));
  	  if (tem)
! 	    return gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
  	}
        break;
  
--- 4300,4306 ----
  					       XEXP (XEXP (x, 0), 0),
  					       XEXP (x, 1));
  	  if (tem)
! 	    return simplify_gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
  	}
        break;
  
***************
*** 4369,4377 ****
  		   && nonzero_bits (op0, mode) == 1)
  	    {
  	      op0 = expand_compound_operation (op0);
! 	      return gen_binary (XOR, mode,
! 				 gen_lowpart (mode, op0),
! 				 const1_rtx);
  	    }
  
  	  else if (STORE_FLAG_VALUE == 1
--- 4380,4388 ----
  		   && nonzero_bits (op0, mode) == 1)
  	    {
  	      op0 = expand_compound_operation (op0);
! 	      return simplify_gen_binary (XOR, mode,
! 					  gen_lowpart (mode, op0),
! 					  const1_rtx);
  	    }
  
  	  else if (STORE_FLAG_VALUE == 1
***************
*** 4614,4620 ****
  
    /* Simplify storing of the truth value.  */
    if (comparison_p && true_rtx == const_true_rtx && false_rtx == const0_rtx)
!     return gen_binary (true_code, mode, XEXP (cond, 0), XEXP (cond, 1));
  
    /* Also when the truth value has to be reversed.  */
    if (comparison_p
--- 4625,4632 ----
  
    /* Simplify storing of the truth value.  */
    if (comparison_p && true_rtx == const_true_rtx && false_rtx == const0_rtx)
!     return simplify_gen_relational (true_code, mode, VOIDmode,
! 				    XEXP (cond, 0), XEXP (cond, 1));
  
    /* Also when the truth value has to be reversed.  */
    if (comparison_p
***************
*** 4764,4779 ****
        {
        case GE:
        case GT:
! 	return gen_binary (SMAX, mode, true_rtx, false_rtx);
        case LE:
        case LT:
! 	return gen_binary (SMIN, mode, true_rtx, false_rtx);
        case GEU:
        case GTU:
! 	return gen_binary (UMAX, mode, true_rtx, false_rtx);
        case LEU:
        case LTU:
! 	return gen_binary (UMIN, mode, true_rtx, false_rtx);
        default:
  	break;
        }
--- 4776,4791 ----
        {
        case GE:
        case GT:
! 	return simplify_gen_binary (SMAX, mode, true_rtx, false_rtx);
        case LE:
        case LT:
! 	return simplify_gen_binary (SMIN, mode, true_rtx, false_rtx);
        case GEU:
        case GTU:
! 	return simplify_gen_binary (UMAX, mode, true_rtx, false_rtx);
        case LEU:
        case LTU:
! 	return simplify_gen_binary (UMIN, mode, true_rtx, false_rtx);
        default:
  	break;
        }
***************
*** 4886,4897 ****
  
        if (z)
  	{
! 	  temp = subst (gen_binary (true_code, m, cond_op0, cond_op1),
  			pc_rtx, pc_rtx, 0, 0);
! 	  temp = gen_binary (MULT, m, temp,
! 			     gen_binary (MULT, m, c1, const_true_rtx));
  	  temp = subst (temp, pc_rtx, pc_rtx, 0, 0);
! 	  temp = gen_binary (op, m, gen_lowpart (m, z), temp);
  
  	  if (extend_op != NIL)
  	    temp = simplify_gen_unary (extend_op, mode, temp, m);
--- 4898,4911 ----
  
        if (z)
  	{
! 	  temp = subst (simplify_gen_relational (true_code, m, VOIDmode,
! 						 cond_op0, cond_op1),
  			pc_rtx, pc_rtx, 0, 0);
! 	  temp = simplify_gen_binary (MULT, m, temp,
! 				      simplify_gen_binary (MULT, m, c1,
! 							   const_true_rtx));
  	  temp = subst (temp, pc_rtx, pc_rtx, 0, 0);
! 	  temp = simplify_gen_binary (op, m, gen_lowpart (m, z), temp);
  
  	  if (extend_op != NIL)
  	    temp = simplify_gen_unary (extend_op, mode, temp, m);
***************
*** 5076,5082 ****
  		  PUT_CODE (*cc_use, old_code);
  		  other_changed = 0;
  
! 		  op0 = gen_binary (XOR, GET_MODE (op0), op0, GEN_INT (mask));
  		}
  	    }
  	}
--- 5090,5097 ----
  		  PUT_CODE (*cc_use, old_code);
  		  other_changed = 0;
  
! 		  op0 = simplify_gen_binary (XOR, GET_MODE (op0),
! 					     op0, GEN_INT (mask));
  		}
  	    }
  	}
***************
*** 5240,5257 ****
  	       && rtx_equal_p (XEXP (false_rtx, 1), true_rtx))
  	term1 = true_rtx, false_rtx = XEXP (false_rtx, 0), true_rtx = const0_rtx;
  
!       term2 = gen_binary (AND, GET_MODE (src),
! 			  XEXP (XEXP (src, 0), 0), true_rtx);
!       term3 = gen_binary (AND, GET_MODE (src),
! 			  simplify_gen_unary (NOT, GET_MODE (src),
! 					      XEXP (XEXP (src, 0), 0),
! 					      GET_MODE (src)),
! 			  false_rtx);
  
        SUBST (SET_SRC (x),
! 	     gen_binary (IOR, GET_MODE (src),
! 			 gen_binary (IOR, GET_MODE (src), term1, term2),
! 			 term3));
  
        src = SET_SRC (x);
      }
--- 5255,5273 ----
  	       && rtx_equal_p (XEXP (false_rtx, 1), true_rtx))
  	term1 = true_rtx, false_rtx = XEXP (false_rtx, 0), true_rtx = const0_rtx;
  
!       term2 = simplify_gen_binary (AND, GET_MODE (src),
! 				   XEXP (XEXP (src, 0), 0), true_rtx);
!       term3 = simplify_gen_binary (AND, GET_MODE (src),
! 				   simplify_gen_unary (NOT, GET_MODE (src),
! 						       XEXP (XEXP (src, 0), 0),
! 						       GET_MODE (src)),
! 				   false_rtx);
  
        SUBST (SET_SRC (x),
! 	     simplify_gen_binary (IOR, GET_MODE (src),
! 				  simplify_gen_binary (IOR, GET_MODE (src),
! 						       term1, term2),
! 				  term3));
  
        src = SET_SRC (x);
      }
***************
*** 5286,5314 ****
        if (GET_CODE (op0) == XOR
  	  && rtx_equal_p (XEXP (op0, 0), op1)
  	  && ! side_effects_p (op1))
! 	x = gen_binary (AND, mode,
! 			simplify_gen_unary (NOT, mode, XEXP (op0, 1), mode),
! 			op1);
  
        if (GET_CODE (op0) == XOR
  	  && rtx_equal_p (XEXP (op0, 1), op1)
  	  && ! side_effects_p (op1))
! 	x = gen_binary (AND, mode,
! 			simplify_gen_unary (NOT, mode, XEXP (op0, 0), mode),
! 			op1);
  
        /* Similarly for (~(A ^ B)) & A.  */
        if (GET_CODE (op0) == NOT
  	  && GET_CODE (XEXP (op0, 0)) == XOR
  	  && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
  	  && ! side_effects_p (op1))
! 	x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
  
        if (GET_CODE (op0) == NOT
  	  && GET_CODE (XEXP (op0, 0)) == XOR
  	  && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
  	  && ! side_effects_p (op1))
! 	x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
  
        /* We can call simplify_and_const_int only if we don't lose
  	 any (sign) bits when converting INTVAL (op1) to
--- 5302,5332 ----
        if (GET_CODE (op0) == XOR
  	  && rtx_equal_p (XEXP (op0, 0), op1)
  	  && ! side_effects_p (op1))
! 	x = simplify_gen_binary (AND, mode,
! 				 simplify_gen_unary (NOT, mode,
! 						     XEXP (op0, 1), mode),
! 				 op1);
  
        if (GET_CODE (op0) == XOR
  	  && rtx_equal_p (XEXP (op0, 1), op1)
  	  && ! side_effects_p (op1))
! 	x = simplify_gen_binary (AND, mode,
! 				 simplify_gen_unary (NOT, mode,
! 						     XEXP (op0, 0), mode),
! 				 op1);
  
        /* Similarly for (~(A ^ B)) & A.  */
        if (GET_CODE (op0) == NOT
  	  && GET_CODE (XEXP (op0, 0)) == XOR
  	  && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
  	  && ! side_effects_p (op1))
! 	x = simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
  
        if (GET_CODE (op0) == NOT
  	  && GET_CODE (XEXP (op0, 0)) == XOR
  	  && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
  	  && ! side_effects_p (op1))
! 	x = simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
  
        /* We can call simplify_and_const_int only if we don't lose
  	 any (sign) bits when converting INTVAL (op1) to
***************
*** 5328,5335 ****
  	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
  	      && GET_CODE (op1) == CONST_INT
  	      && (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) != 0)
! 	    return gen_binary (IOR, mode,
! 			       gen_binary (AND, mode, XEXP (op0, 0),
  					   GEN_INT (INTVAL (XEXP (op0, 1))
  						    & ~INTVAL (op1))), op1);
  
--- 5346,5354 ----
  	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
  	      && GET_CODE (op1) == CONST_INT
  	      && (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) != 0)
! 	    return simplify_gen_binary (IOR, mode,
! 				        simplify_gen_binary
! 					  (AND, mode, XEXP (op0, 0),
  					   GEN_INT (INTVAL (XEXP (op0, 1))
  						    & ~INTVAL (op1))), op1);
  
***************
*** 5348,5401 ****
  	  && ! side_effects_p (XEXP (op0, 1)))
  	return op1;
  
!       /* In the following group of tests (and those in case IOR below),
! 	 we start with some combination of logical operations and apply
! 	 the distributive law followed by the inverse distributive law.
! 	 Most of the time, this results in no change.  However, if some of
! 	 the operands are the same or inverses of each other, simplifications
! 	 will result.
! 
! 	 For example, (and (ior A B) (not B)) can occur as the result of
! 	 expanding a bit field assignment.  When we apply the distributive
! 	 law to this, we get (ior (and (A (not B))) (and (B (not B)))),
! 	 which then simplifies to (and (A (not B))).
! 
! 	 If we have (and (ior A B) C), apply the distributive law and then
! 	 the inverse distributive law to see if things simplify.  */
! 
!       if (GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
! 	{
! 	  x = apply_distributive_law
! 	    (gen_binary (GET_CODE (op0), mode,
! 			 gen_binary (AND, mode, XEXP (op0, 0), op1),
! 			 gen_binary (AND, mode, XEXP (op0, 1),
! 				     copy_rtx (op1))));
! 	  if (GET_CODE (x) != AND)
! 	    return x;
  	}
- 
-       if (GET_CODE (op1) == IOR || GET_CODE (op1) == XOR)
- 	return apply_distributive_law
- 	  (gen_binary (GET_CODE (op1), mode,
- 		       gen_binary (AND, mode, XEXP (op1, 0), op0),
- 		       gen_binary (AND, mode, XEXP (op1, 1),
- 				   copy_rtx (op0))));
- 
-       /* Similarly, taking advantage of the fact that
- 	 (and (not A) (xor B C)) == (xor (ior A B) (ior A C))  */
- 
-       if (GET_CODE (op0) == NOT && GET_CODE (op1) == XOR)
- 	return apply_distributive_law
- 	  (gen_binary (XOR, mode,
- 		       gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 0)),
- 		       gen_binary (IOR, mode, copy_rtx (XEXP (op0, 0)),
- 				   XEXP (op1, 1))));
- 
-       else if (GET_CODE (op1) == NOT && GET_CODE (op0) == XOR)
- 	return apply_distributive_law
- 	  (gen_binary (XOR, mode,
- 		       gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 0)),
- 		       gen_binary (IOR, mode, copy_rtx (XEXP (op1, 0)), XEXP (op0, 1))));
        break;
  
      case IOR:
--- 5367,5382 ----
  	  && ! side_effects_p (XEXP (op0, 1)))
  	return op1;
  
!       /* If we have any of (and (ior A B) C) or (and (xor A B) C),
! 	 apply the distributive law and then the inverse distributive
! 	 law to see if things simplify.  */
!       if (GET_CODE (op0) == IOR || GET_CODE (op0) == XOR
!           || GET_CODE (op1) == IOR || GET_CODE (op1) == XOR)
! 	{
! 	  rtx result = distribute_and_simplify_rtx (x);
! 	  if (result)
! 	    return result;
  	}
        break;
  
      case IOR:
***************
*** 5416,5443 ****
        /* If we have (ior (and A B) C), apply the distributive law and then
  	 the inverse distributive law to see if things simplify.  */
  
!       if (GET_CODE (op0) == AND)
! 	{
! 	  x = apply_distributive_law
! 	    (gen_binary (AND, mode,
! 			 gen_binary (IOR, mode, XEXP (op0, 0), op1),
! 			 gen_binary (IOR, mode, XEXP (op0, 1),
! 				     copy_rtx (op1))));
! 
! 	  if (GET_CODE (x) != IOR)
! 	    return x;
! 	}
! 
!       if (GET_CODE (op1) == AND)
  	{
! 	  x = apply_distributive_law
! 	    (gen_binary (AND, mode,
! 			 gen_binary (IOR, mode, XEXP (op1, 0), op0),
! 			 gen_binary (IOR, mode, XEXP (op1, 1),
! 				     copy_rtx (op0))));
! 
! 	  if (GET_CODE (x) != IOR)
! 	    return x;
  	}
  
        /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
--- 5397,5407 ----
        /* If we have (ior (and A B) C), apply the distributive law and then
  	 the inverse distributive law to see if things simplify.  */
  
!       if (GET_CODE (op0) == AND || GET_CODE (op1) == AND)
  	{
! 	  rtx result = distribute_and_simplify_rtx (x);
! 	  if (result)
! 	    return result;
  	}
  
        /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
***************
*** 5486,5492 ****
        if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
  	  && (nonzero_bits (op0, mode)
  	      & nonzero_bits (op1, mode)) == 0)
! 	return (gen_binary (IOR, mode, op0, op1));
  
        /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
  	 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
--- 5450,5456 ----
        if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
  	  && (nonzero_bits (op0, mode)
  	      & nonzero_bits (op1, mode)) == 0)
! 	return (simplify_gen_binary (IOR, mode, op0, op1));
  
        /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
  	 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
***************
*** 5506,5512 ****
  	  }
  	else if (num_negated == 1)
  	  return
! 	    simplify_gen_unary (NOT, mode, gen_binary (XOR, mode, op0, op1),
  				mode);
        }
  
--- 5470,5477 ----
  	  }
  	else if (num_negated == 1)
  	  return
! 	    simplify_gen_unary (NOT, mode,
! 				simplify_gen_binary (XOR, mode, op0, op1),
  				mode);
        }
  
***************
*** 5517,5532 ****
        if (GET_CODE (op0) == AND
  	  && rtx_equal_p (XEXP (op0, 1), op1)
  	  && ! side_effects_p (op1))
! 	return gen_binary (AND, mode,
! 			   simplify_gen_unary (NOT, mode, XEXP (op0, 0), mode),
! 			   op1);
  
        else if (GET_CODE (op0) == AND
  	       && rtx_equal_p (XEXP (op0, 0), op1)
  	       && ! side_effects_p (op1))
! 	return gen_binary (AND, mode,
! 			   simplify_gen_unary (NOT, mode, XEXP (op0, 1), mode),
! 			   op1);
  
        /* (xor (comparison foo bar) (const_int 1)) can become the reversed
  	 comparison if STORE_FLAG_VALUE is 1.  */
--- 5482,5499 ----
        if (GET_CODE (op0) == AND
  	  && rtx_equal_p (XEXP (op0, 1), op1)
  	  && ! side_effects_p (op1))
! 	return simplify_gen_binary (AND, mode,
! 				    simplify_gen_unary (NOT, mode,
! 							XEXP (op0, 0), mode),
! 				    op1);
  
        else if (GET_CODE (op0) == AND
  	       && rtx_equal_p (XEXP (op0, 0), op1)
  	       && ! side_effects_p (op1))
! 	return simplify_gen_binary (AND, mode,
! 				    simplify_gen_unary (NOT, mode,
! 							XEXP (op0, 1), mode),
! 				    op1);
  
        /* (xor (comparison foo bar) (const_int 1)) can become the reversed
  	 comparison if STORE_FLAG_VALUE is 1.  */
***************
*** 5795,5801 ****
    rtx inner;
    rtx pos;			/* Always counts from low bit.  */
    int len;
!   rtx mask;
    enum machine_mode compute_mode;
  
    /* Loop until we find something we can't simplify.  */
--- 5762,5768 ----
    rtx inner;
    rtx pos;			/* Always counts from low bit.  */
    int len;
!   rtx mask, cleared, masked;
    enum machine_mode compute_mode;
  
    /* Loop until we find something we can't simplify.  */
***************
*** 5833,5842 ****
  		/* If position is ADJUST - X, new position is X.  */
  		pos = XEXP (pos, 0);
  	      else
! 		pos = gen_binary (MINUS, GET_MODE (pos),
! 				  GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner))
! 					   - len),
! 				  pos);
  	    }
  	}
  
--- 5800,5810 ----
  		/* If position is ADJUST - X, new position is X.  */
  		pos = XEXP (pos, 0);
  	      else
! 		pos = simplify_gen_binary (MINUS, GET_MODE (pos),
! 					   GEN_INT (GET_MODE_BITSIZE (
! 						    GET_MODE (inner))
! 						    - len),
! 					   pos);
  	    }
  	}
  
***************
*** 5883,5912 ****
  	}
  
        /* Compute a mask of LEN bits, if we can do this on the host machine.  */
!       if (len < HOST_BITS_PER_WIDE_INT)
! 	mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1);
!       else
  	break;
  
        /* Now compute the equivalent expression.  Make a copy of INNER
  	 for the SET_DEST in case it is a MEM into which we will substitute;
  	 we don't want shared RTL in that case.  */
!       x = gen_rtx_SET
! 	(VOIDmode, copy_rtx (inner),
! 	 gen_binary (IOR, compute_mode,
! 		     gen_binary (AND, compute_mode,
! 				 simplify_gen_unary (NOT, compute_mode,
! 						     gen_binary (ASHIFT,
! 								 compute_mode,
! 								 mask, pos),
! 						     compute_mode),
! 				 inner),
! 		     gen_binary (ASHIFT, compute_mode,
! 				 gen_binary (AND, compute_mode,
! 					     gen_lowpart
! 					     (compute_mode, SET_SRC (x)),
! 					     mask),
! 				 pos)));
      }
  
    return x;
--- 5851,5880 ----
  	}
  
        /* Compute a mask of LEN bits, if we can do this on the host machine.  */
!       if (len >= HOST_BITS_PER_WIDE_INT)
  	break;
  
        /* Now compute the equivalent expression.  Make a copy of INNER
  	 for the SET_DEST in case it is a MEM into which we will substitute;
  	 we don't want shared RTL in that case.  */
!       mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1);
!       cleared = simplify_gen_binary (AND, compute_mode,
! 				     simplify_gen_unary (NOT, compute_mode,
! 				       simplify_gen_binary (ASHIFT,
! 							    compute_mode,
! 							    mask, pos),
! 				       compute_mode),
! 				     inner);
!       masked = simplify_gen_binary (ASHIFT, compute_mode,
! 				    simplify_gen_binary (
! 				      AND, compute_mode,
! 				      gen_lowpart (compute_mode, SET_SRC (x)),
! 				      mask),
! 				    pos);
! 
!       x = gen_rtx_SET (VOIDmode, copy_rtx (inner),
! 		       simplify_gen_binary (IOR, compute_mode,
! 					    cleared, masked));
      }
  
    return x;
***************
*** 6362,6369 ****
        if (GET_CODE (XEXP (x, 1)) == CONST_INT
  	  && (INTVAL (XEXP (x, 1)) & ((((HOST_WIDE_INT) 1 << count)) - 1)) == 0
  	  && (tem = extract_left_shift (XEXP (x, 0), count)) != 0)
! 	return gen_binary (code, mode, tem,
! 			   GEN_INT (INTVAL (XEXP (x, 1)) >> count));
  
        break;
  
--- 6330,6337 ----
        if (GET_CODE (XEXP (x, 1)) == CONST_INT
  	  && (INTVAL (XEXP (x, 1)) & ((((HOST_WIDE_INT) 1 << count)) - 1)) == 0
  	  && (tem = extract_left_shift (XEXP (x, 0), count)) != 0)
! 	return simplify_gen_binary (code, mode, tem,
! 				    GEN_INT (INTVAL (XEXP (x, 1)) >> count));
  
        break;
  
***************
*** 6854,6860 ****
  		  && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
  		cval |= (HOST_WIDE_INT) -1 << width;
  
! 	      y = gen_binary (AND, GET_MODE (x), XEXP (x, 0), GEN_INT (cval));
  	      if (rtx_cost (y, SET) < rtx_cost (x, SET))
  		x = y;
  	    }
--- 6822,6829 ----
  		  && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
  		cval |= (HOST_WIDE_INT) -1 << width;
  
! 	      y = simplify_gen_binary (AND, GET_MODE (x),
! 				       XEXP (x, 0), GEN_INT (cval));
  	      if (rtx_cost (y, SET) < rtx_cost (x, SET))
  		x = y;
  	    }
***************
*** 6946,6955 ****
  	{
  	  temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask)
  			  << INTVAL (XEXP (XEXP (x, 0), 1)));
! 	  temp = gen_binary (GET_CODE (x), GET_MODE (x),
! 			     XEXP (XEXP (x, 0), 0), temp);
! 	  x = gen_binary (LSHIFTRT, GET_MODE (x), temp,
! 			  XEXP (XEXP (x, 0), 1));
  	  return force_to_mode (x, mode, mask, reg, next_select);
  	}
  
--- 6915,6924 ----
  	{
  	  temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask)
  			  << INTVAL (XEXP (XEXP (x, 0), 1)));
! 	  temp = simplify_gen_binary (GET_CODE (x), GET_MODE (x),
! 				      XEXP (XEXP (x, 0), 0), temp);
! 	  x = simplify_gen_binary (LSHIFTRT, GET_MODE (x), temp,
! 				   XEXP (XEXP (x, 0), 1));
  	  return force_to_mode (x, mode, mask, reg, next_select);
  	}
  
***************
*** 6965,6971 ****
  					reg, next_select));
  
        if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
! 	x = gen_binary (code, op_mode, op0, op1);
        break;
  
      case ASHIFT:
--- 6934,6940 ----
  					reg, next_select));
  
        if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
! 	x = simplify_gen_binary (code, op_mode, op0, op1);
        break;
  
      case ASHIFT:
***************
*** 6999,7005 ****
  					mask, reg, next_select));
  
        if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
! 	x = gen_binary (code, op_mode, op0, XEXP (x, 1));
        break;
  
      case LSHIFTRT:
--- 6968,6974 ----
  					mask, reg, next_select));
  
        if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
! 	x = simplify_gen_binary (code, op_mode, op0, XEXP (x, 1));
        break;
  
      case LSHIFTRT:
***************
*** 7027,7033 ****
  	  inner = force_to_mode (inner, op_mode, inner_mask, reg, next_select);
  
  	  if (GET_MODE (x) != op_mode || inner != XEXP (x, 0))
! 	    x = gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1));
  	}
  
        /* If we have (and (lshiftrt FOO C1) C2) where the combination of the
--- 6996,7002 ----
  	  inner = force_to_mode (inner, op_mode, inner_mask, reg, next_select);
  
  	  if (GET_MODE (x) != op_mode || inner != XEXP (x, 0))
! 	    x = simplify_gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1));
  	}
  
        /* If we have (and (lshiftrt FOO C1) C2) where the combination of the
***************
*** 7049,7057 ****
  	  /* Must be more sign bit copies than the mask needs.  */
  	  && ((int) num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
  	      >= exact_log2 (mask + 1)))
! 	x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0),
! 			GEN_INT (GET_MODE_BITSIZE (GET_MODE (x))
! 				 - exact_log2 (mask + 1)));
  
        goto shiftrt;
  
--- 7018,7026 ----
  	  /* Must be more sign bit copies than the mask needs.  */
  	  && ((int) num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
  	      >= exact_log2 (mask + 1)))
! 	x = simplify_gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0),
! 				 GEN_INT (GET_MODE_BITSIZE (GET_MODE (x))
! 					  - exact_log2 (mask + 1)));
  
        goto shiftrt;
  
***************
*** 7116,7122 ****
        /* If MASK is 1, convert this to an LSHIFTRT.  This can be done
  	 even if the shift count isn't a constant.  */
        if (mask == 1)
! 	x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0), XEXP (x, 1));
  
      shiftrt:
  
--- 7085,7092 ----
        /* If MASK is 1, convert this to an LSHIFTRT.  This can be done
  	 even if the shift count isn't a constant.  */
        if (mask == 1)
! 	x = simplify_gen_binary (LSHIFTRT, GET_MODE (x),
! 				 XEXP (x, 0), XEXP (x, 1));
  
      shiftrt:
  
***************
*** 7181,7188 ****
  	{
  	  temp = gen_int_mode (mask << INTVAL (XEXP (XEXP (x, 0), 1)),
  			       GET_MODE (x));
! 	  temp = gen_binary (XOR, GET_MODE (x), XEXP (XEXP (x, 0), 0), temp);
! 	  x = gen_binary (LSHIFTRT, GET_MODE (x), temp, XEXP (XEXP (x, 0), 1));
  
  	  return force_to_mode (x, mode, mask, reg, next_select);
  	}
--- 7151,7160 ----
  	{
  	  temp = gen_int_mode (mask << INTVAL (XEXP (XEXP (x, 0), 1)),
  			       GET_MODE (x));
! 	  temp = simplify_gen_binary (XOR, GET_MODE (x),
! 				      XEXP (XEXP (x, 0), 0), temp);
! 	  x = simplify_gen_binary (LSHIFTRT, GET_MODE (x),
! 				   temp, XEXP (XEXP (x, 0), 1));
  
  	  return force_to_mode (x, mode, mask, reg, next_select);
  	}
***************
*** 7292,7299 ****
  	  else if (cond1 == 0)
  	    true1 = copy_rtx (true1);
  
! 	  *ptrue = gen_binary (code, mode, true0, true1);
! 	  *pfalse = gen_binary (code, mode, false0, false1);
  	  return cond0 ? cond0 : cond1;
  	}
  
--- 7264,7282 ----
  	  else if (cond1 == 0)
  	    true1 = copy_rtx (true1);
  
! 	  if (COMPARISON_P (x))
! 	    {
! 	      *ptrue = simplify_gen_relational (code, mode, VOIDmode,
! 						true0, true1);
! 	      *pfalse = simplify_gen_relational (code, mode, VOIDmode,
! 					         false0, false1);
! 	     }
! 	  else
! 	    {
! 	      *ptrue = simplify_gen_binary (code, mode, true0, true1);
! 	      *pfalse = simplify_gen_binary (code, mode, false0, false1);
! 	    }
! 
  	  return cond0 ? cond0 : cond1;
  	}
  
***************
*** 7323,7335 ****
  		      && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
  	      && ! side_effects_p (x))
  	    {
! 	      *ptrue = gen_binary (MULT, mode, op0, const_true_rtx);
! 	      *pfalse = gen_binary (MULT, mode,
! 				    (code == MINUS
! 				     ? simplify_gen_unary (NEG, mode, op1,
! 							   mode)
! 				     : op1),
! 				    const_true_rtx);
  	      return cond0;
  	    }
  	}
--- 7306,7318 ----
  		      && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
  	      && ! side_effects_p (x))
  	    {
! 	      *ptrue = simplify_gen_binary (MULT, mode, op0, const_true_rtx);
! 	      *pfalse = simplify_gen_binary (MULT, mode,
! 					     (code == MINUS
! 					      ? simplify_gen_unary (NEG, mode,
! 								    op1, mode)
! 					      : op1),
! 					      const_true_rtx);
  	      return cond0;
  	    }
  	}
***************
*** 7833,7840 ****
  	  || GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD)
  	return x;
  
!       tem = gen_binary (code, GET_MODE (SUBREG_REG (lhs)),
! 			SUBREG_REG (lhs), SUBREG_REG (rhs));
        return gen_lowpart (GET_MODE (x), tem);
  
      default:
--- 7816,7823 ----
  	  || GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD)
  	return x;
  
!       tem = simplify_gen_binary (code, GET_MODE (SUBREG_REG (lhs)),
! 				 SUBREG_REG (lhs), SUBREG_REG (rhs));
        return gen_lowpart (GET_MODE (x), tem);
  
      default:
***************
*** 7860,7866 ****
      return x;
  
    /* Form the new inner operation, seeing if it simplifies first.  */
!   tem = gen_binary (code, GET_MODE (x), lhs, rhs);
  
    /* There is one exception to the general way of distributing:
       (a | c) ^ (b | c) -> (a ^ b) & ~c  */
--- 7843,7849 ----
      return x;
  
    /* Form the new inner operation, seeing if it simplifies first.  */
!   tem = simplify_gen_binary (code, GET_MODE (x), lhs, rhs);
  
    /* There is one exception to the general way of distributing:
       (a | c) ^ (b | c) -> (a ^ b) & ~c  */
***************
*** 7873,7880 ****
    /* We may be able to continuing distributing the result, so call
       ourselves recursively on the inner operation before forming the
       outer operation, which we return.  */
!   return gen_binary (inner_code, GET_MODE (x),
! 		     apply_distributive_law (tem), other);
  }
  \f
  /* We have X, a logical `and' of VAROP with the constant CONSTOP, to be done
--- 7856,7942 ----
    /* We may be able to continuing distributing the result, so call
       ourselves recursively on the inner operation before forming the
       outer operation, which we return.  */
!   return simplify_gen_binary (inner_code, GET_MODE (x),
! 			      apply_distributive_law (tem), other);
! }
! 
! /* See if X is of the form (* (+ a b) c), and if so convert to
!    (+ (* a c) (* b c)) and try to simplify.
! 
!    Most of the time, this results in no change.  However, if some of
!    the operands are the same or inverses of each other, simplifications
!    will result.
! 
!    For example, (and (ior A B) (not B)) can occur as the result of
!    expanding a bit field assignment.  When we apply the distributive
!    law to this, we get (ior (and (A (not B))) (and (B (not B)))),
!    which then simplifies to (and (A (not B))).
!  
!    Note that no checks happen on the validity of applying the inverse
!    distributive law.  This is pointless since we can do it in the
!    few places where this routine is called.  */
! static rtx
! distribute_and_simplify_rtx (rtx x)
! {
!   enum machine_mode mode;
!   enum rtx_code outer, inner;
!   rtx op0, op1, inner_op0, inner_op1, new_op0, new_op1;
! 
!   mode = GET_MODE (x);
!   outer = GET_CODE (x);
!   op0 = XEXP (x, 0);
!   op1 = XEXP (x, 1);
!   if (ARITHMETIC_P (op0))
!     {
!       inner = GET_CODE (op0);
!       inner_op0 = XEXP (op0, 0);
!       inner_op1 = XEXP (op0, 1);
! 
!       /* (and (xor B C) (not A)) == (xor (ior A B) (ior A C))  */
!       if (outer == AND && inner == XOR && GET_CODE (op1) == NOT)
!         {
! 	  new_op0 = simplify_gen_binary (IOR, mode, inner_op0, XEXP (op1, 0));
!           new_op1 = simplify_gen_binary (IOR, mode, inner_op1, XEXP (op1, 0));
!           x = apply_distributive_law (simplify_gen_binary (XOR, mode,
! 							   new_op0, new_op1));
! 	}
!       else
! 	{
!           new_op0 = simplify_gen_binary (outer, mode, inner_op0, op1);
!           new_op1 = simplify_gen_binary (outer, mode, inner_op1, op1);
!           x = apply_distributive_law (simplify_gen_binary (inner, mode,
! 							   new_op0, new_op1));
! 	}
!       if (GET_CODE (x) != outer)
!         return x;
!     }
! 
!   if (ARITHMETIC_P (op1))
!     {
!       inner = GET_CODE (op1);
!       inner_op0 = XEXP (op1, 0);
!       inner_op1 = XEXP (op1, 1);
! 
!       /* (and (not A) (xor B C)) == (xor (ior A B) (ior A C))  */
!       if (outer == AND && inner == XOR && GET_CODE (op0) == NOT)
!         {
! 	  new_op0 = simplify_gen_binary (IOR, mode, inner_op0, XEXP (op0, 0));
!           new_op1 = simplify_gen_binary (IOR, mode, inner_op1, XEXP (op0, 0));
!           x = apply_distributive_law (simplify_gen_binary (XOR, mode,
! 							   new_op0, new_op1));
! 	}
!       else
! 	{
!           new_op0 = simplify_gen_binary (outer, mode, op0, inner_op0);
!           new_op1 = simplify_gen_binary (outer, mode, op0, inner_op1);
!           x = apply_distributive_law (simplify_gen_binary (inner, mode,
! 							   new_op0, new_op1));
! 	}
!       if (GET_CODE (x) != outer)
!         return x;
!     }
! 
!   return NULL_RTX;
  }
  \f
  /* We have X, a logical `and' of VAROP with the constant CONSTOP, to be done
***************
*** 7941,7951 ****
        gen_lowpart
  	(mode,
  	 apply_distributive_law
! 	 (gen_binary (GET_CODE (varop), GET_MODE (varop),
! 		      simplify_and_const_int (NULL_RTX, GET_MODE (varop),
! 					      XEXP (varop, 0), constop),
! 		      simplify_and_const_int (NULL_RTX, GET_MODE (varop),
! 					      XEXP (varop, 1), constop))));
  
    /* If VAROP is PLUS, and the constant is a mask of low bite, distribute
       the AND and see if one of the operands simplifies to zero.  If so, we
--- 8003,8017 ----
        gen_lowpart
  	(mode,
  	 apply_distributive_law
! 	 (simplify_gen_binary (GET_CODE (varop), GET_MODE (varop),
! 			       simplify_and_const_int (NULL_RTX,
! 						       GET_MODE (varop),
! 						       XEXP (varop, 0),
! 						       constop),
! 			       simplify_and_const_int (NULL_RTX,
! 						       GET_MODE (varop),
! 						       XEXP (varop, 1),
! 						       constop))));
  
    /* If VAROP is PLUS, and the constant is a mask of low bite, distribute
       the AND and see if one of the operands simplifies to zero.  If so, we
***************
*** 7986,7992 ****
        constop = trunc_int_for_mode (constop, mode);
        /* See how much, if any, of X we can use.  */
        if (x == 0 || GET_CODE (x) != AND || GET_MODE (x) != mode)
! 	x = gen_binary (AND, mode, varop, GEN_INT (constop));
  
        else
  	{
--- 8052,8058 ----
        constop = trunc_int_for_mode (constop, mode);
        /* See how much, if any, of X we can use.  */
        if (x == 0 || GET_CODE (x) != AND || GET_MODE (x) != mode)
! 	x = simplify_gen_binary (AND, mode, varop, GEN_INT (constop));
  
        else
  	{
***************
*** 8505,8512 ****
  	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
  	    {
  	      varop
! 		= gen_binary (ASHIFT, GET_MODE (varop), XEXP (varop, 0),
! 			      GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
  	      continue;
  	    }
  	  break;
--- 8571,8580 ----
  	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
  	    {
  	      varop
! 		= simplify_gen_binary (ASHIFT, GET_MODE (varop),
! 				       XEXP (varop, 0),
! 				       GEN_INT (exact_log2 (
! 						INTVAL (XEXP (varop, 1)))));
  	      continue;
  	    }
  	  break;
***************
*** 8517,8524 ****
  	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
  	    {
  	      varop
! 		= gen_binary (LSHIFTRT, GET_MODE (varop), XEXP (varop, 0),
! 			      GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
  	      continue;
  	    }
  	  break;
--- 8585,8594 ----
  	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
  	    {
  	      varop
! 		= simplify_gen_binary (LSHIFTRT, GET_MODE (varop),
! 				       XEXP (varop, 0),
! 				       GEN_INT (exact_log2 (
! 						INTVAL (XEXP (varop, 1)))));
  	      continue;
  	    }
  	  break;
***************
*** 8773,8779 ****
  	      rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
  					      XEXP (varop, 1), count);
  
! 	      varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs);
  	      varop = apply_distributive_law (varop);
  
  	      count = 0;
--- 8843,8850 ----
  	      rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
  					      XEXP (varop, 1), count);
  
! 	      varop = simplify_gen_binary (GET_CODE (varop), shift_mode,
! 					   lhs, rhs);
  	      varop = apply_distributive_law (varop);
  
  	      count = 0;
***************
*** 9028,9034 ****
        else if (GET_RTX_CLASS (outer_op) == RTX_UNARY)
  	x = simplify_gen_unary (outer_op, result_mode, x, result_mode);
        else
! 	x = gen_binary (outer_op, result_mode, x, GEN_INT (outer_const));
      }
  
    return x;
--- 9099,9106 ----
        else if (GET_RTX_CLASS (outer_op) == RTX_UNARY)
  	x = simplify_gen_unary (outer_op, result_mode, x, result_mode);
        else
! 	x = simplify_gen_binary (outer_op, result_mode, x,
! 				 GEN_INT (outer_const));
      }
  
    return x;
***************
*** 9261,9323 ****
      }
  }
  \f
- /* These routines make binary and unary operations by first seeing if they
-    fold; if not, a new expression is allocated.  */
- 
- static rtx
- gen_binary (enum rtx_code code, enum machine_mode mode, rtx op0, rtx op1)
- {
-   rtx result;
-   rtx tem;
- 
-   if (GET_CODE (op0) == CLOBBER)
-     return op0;
-   else if (GET_CODE (op1) == CLOBBER)
-     return op1;
-   
-   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
-       && swap_commutative_operands_p (op0, op1))
-     tem = op0, op0 = op1, op1 = tem;
- 
-   if (GET_RTX_CLASS (code) == RTX_COMPARE
-       || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
-     {
-       enum machine_mode op_mode = GET_MODE (op0);
- 
-       /* Strip the COMPARE from (REL_OP (compare X Y) 0) to get
- 	 just (REL_OP X Y).  */
-       if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
- 	{
- 	  op1 = XEXP (op0, 1);
- 	  op0 = XEXP (op0, 0);
- 	  op_mode = GET_MODE (op0);
- 	}
- 
-       if (op_mode == VOIDmode)
- 	op_mode = GET_MODE (op1);
-       result = simplify_relational_operation (code, mode, op_mode, op0, op1);
-     }
-   else
-     result = simplify_binary_operation (code, mode, op0, op1);
- 
-   if (result)
-     return result;
- 
-   /* Put complex operands first and constants second.  */
-   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
-       && swap_commutative_operands_p (op0, op1))
-     return gen_rtx_fmt_ee (code, mode, op1, op0);
- 
-   /* If we are turning off bits already known off in OP0, we need not do
-      an AND.  */
-   else if (code == AND && GET_CODE (op1) == CONST_INT
- 	   && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
- 	   && (nonzero_bits (op0, mode) & ~INTVAL (op1)) == 0)
-     return op0;
- 
-   return gen_rtx_fmt_ee (code, mode, op0, op1);
- }
- \f
  /* Simplify a comparison between *POP0 and *POP1 where CODE is the
     comparison code that will be tested.
  
--- 9333,9338 ----
***************
*** 10152,10160 ****
  		  && c1 != mask
  		  && c1 != GET_MODE_MASK (tmode))
  		{
! 		  op0 = gen_binary (AND, tmode,
! 				    SUBREG_REG (XEXP (op0, 0)),
! 				    gen_int_mode (c1, tmode));
  		  op0 = gen_lowpart (mode, op0);
  		  continue;
  		}
--- 10167,10175 ----
  		  && c1 != mask
  		  && c1 != GET_MODE_MASK (tmode))
  		{
! 		  op0 = simplify_gen_binary (AND, tmode,
! 					     SUBREG_REG (XEXP (op0, 0)),
! 					     gen_int_mode (c1, tmode));
  		  op0 = gen_lowpart (mode, op0);
  		  continue;
  		}
***************
*** 10298,10309 ****
  	    {
  	      rtx inner = XEXP (XEXP (XEXP (op0, 0), 0), 0);
  	      rtx add_const = XEXP (XEXP (op0, 0), 1);
! 	      rtx new_const = gen_binary (ASHIFTRT, GET_MODE (op0), add_const,
! 					  XEXP (op0, 1));
  
! 	      op0 = gen_binary (PLUS, tmode,
! 				gen_lowpart (tmode, inner),
! 				new_const);
  	      continue;
  	    }
  
--- 10313,10324 ----
  	    {
  	      rtx inner = XEXP (XEXP (XEXP (op0, 0), 0), 0);
  	      rtx add_const = XEXP (XEXP (op0, 0), 1);
! 	      rtx new_const = simplify_gen_binary (ASHIFTRT, GET_MODE (op0),
! 						   add_const, XEXP (op0, 1));
  
! 	      op0 = simplify_gen_binary (PLUS, tmode,
! 					 gen_lowpart (tmode, inner),
! 					 new_const);
  	      continue;
  	    }
  
***************
*** 10456,10466 ****
  		 make a new AND in the proper mode.  */
  	      if (GET_CODE (op0) == AND
  		  && !have_insn_for (AND, mode))
! 		op0 = gen_binary (AND, tmode,
! 				  gen_lowpart (tmode,
! 					       XEXP (op0, 0)),
! 				  gen_lowpart (tmode,
! 					       XEXP (op0, 1)));
  
  	      op0 = gen_lowpart (tmode, op0);
  	      if (zero_extended && GET_CODE (op1) == CONST_INT)
--- 10471,10481 ----
  		 make a new AND in the proper mode.  */
  	      if (GET_CODE (op0) == AND
  		  && !have_insn_for (AND, mode))
! 		op0 = simplify_gen_binary (AND, tmode,
! 					   gen_lowpart (tmode,
! 							XEXP (op0, 0)),
! 					   gen_lowpart (tmode,
! 							XEXP (op0, 1)));
  
  	      op0 = gen_lowpart (tmode, op0);
  	      if (zero_extended && GET_CODE (op1) == CONST_INT)
***************
*** 10475,10484 ****
  	  if (op1 == const0_rtx && (code == LT || code == GE)
  	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
  	    {
! 	      op0 = gen_binary (AND, tmode,
! 				gen_lowpart (tmode, op0),
! 				GEN_INT ((HOST_WIDE_INT) 1
! 					 << (GET_MODE_BITSIZE (mode) - 1)));
  	      code = (code == LT) ? NE : EQ;
  	      break;
  	    }
--- 10490,10500 ----
  	  if (op1 == const0_rtx && (code == LT || code == GE)
  	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
  	    {
! 	      op0 = simplify_gen_binary (AND, tmode,
! 					 gen_lowpart (tmode, op0),
! 					 GEN_INT ((HOST_WIDE_INT) 1
! 						  << (GET_MODE_BITSIZE (mode)
! 						      - 1)));
  	      code = (code == LT) ? NE : EQ;
  	      break;
  	    }
***************
*** 10525,10531 ****
    if (reversed_code == UNKNOWN)
      return NULL_RTX;
    else
!     return gen_binary (reversed_code, mode, op0, op1);
  }
  \f
  /* Utility function for following routine.  Called when X is part of a value
--- 10541,10547 ----
    if (reversed_code == UNKNOWN)
      return NULL_RTX;
    else
!     return simplify_gen_relational (reversed_code, mode, VOIDmode, op0, op1);
  }
  \f
  /* Utility function for following routine.  Called when X is part of a value

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFT/RFA: Eliminate gen_binary, take 2
  2004-06-09  9:21   ` Paolo Bonzini
@ 2004-06-09  9:36     ` Paolo Bonzini
  2004-06-10  7:17     ` Eric Botcazou
  1 sibling, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2004-06-09  9:36 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 195 bytes --]

> Please provide a complete patch.  And I'll try to find a version of GNU patch 
> that can apply it this time. :-)

Here it is.

I can mail you privately a gzipped combine.c if you want.

Paolo

[-- Attachment #2: combine-kill-gen-binary-take-4.patch --]
[-- Type: text/plain, Size: 49569 bytes --]

Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.432
diff -c -r1.432 combine.c
*** combine.c	5 Jun 2004 07:59:39 -0000	1.432
--- combine.c	9 Jun 2004 07:20:09 -0000
***************
*** 372,377 ****
--- 372,378 ----
  static int rtx_equal_for_field_assignment_p (rtx, rtx);
  static rtx make_field_assignment (rtx);
  static rtx apply_distributive_law (rtx);
+ static rtx distribute_and_simplify_rtx (rtx);
  static rtx simplify_and_const_int (rtx, enum machine_mode, rtx,
  				   unsigned HOST_WIDE_INT);
  static int merge_outer_ops (enum rtx_code *, HOST_WIDE_INT *, enum rtx_code,
***************
*** 380,386 ****
  				 int);
  static int recog_for_combine (rtx *, rtx, rtx *);
  static rtx gen_lowpart_for_combine (enum machine_mode, rtx);
- static rtx gen_binary (enum rtx_code, enum machine_mode, rtx, rtx);
  static enum rtx_code simplify_comparison (enum rtx_code, rtx *, rtx *);
  static void update_table_tick (rtx);
  static void record_value_for_reg (rtx, rtx, rtx);
--- 381,386 ----
***************
*** 3017,3030 ****
  
  	  if (src == mask)
  	    SUBST (SET_SRC (x),
! 		   gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
  	  else
! 	    SUBST (SET_SRC (x),
! 		   gen_binary (IOR, mode,
! 			       gen_binary (AND, mode, dest,
! 					   gen_int_mode (~(mask << pos),
! 							 mode)),
! 			       GEN_INT (src << pos)));
  
  	  SUBST (SET_DEST (x), dest);
  
--- 3017,3032 ----
  
  	  if (src == mask)
  	    SUBST (SET_SRC (x),
! 		   simplify_gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
  	  else
! 	    {
! 	      rtx negmask = gen_int_mode (~(mask << pos), mode);
! 	      SUBST (SET_SRC (x),
! 		     simplify_gen_binary (IOR, mode,
! 				          simplify_gen_binary (AND, mode,
! 							       dest, negmask),
! 					  GEN_INT (src << pos)));
! 	    }
  
  	  SUBST (SET_DEST (x), dest);
  
***************
*** 3599,3605 ****
        new = simplify_shift_const (NULL_RTX, ASHIFTRT, mode, new,
  				  INTVAL (XEXP (XEXP (x, 0), 1)));
  
!       SUBST (XEXP (x, 0), gen_binary (PLUS, mode, new, temp));
      }
  
    /* If this is a simple operation applied to an IF_THEN_ELSE, try
--- 3601,3607 ----
        new = simplify_shift_const (NULL_RTX, ASHIFTRT, mode, new,
  				  INTVAL (XEXP (XEXP (x, 0), 1)));
  
!       SUBST (XEXP (x, 0), simplify_gen_binary (PLUS, mode, new, temp));
      }
  
    /* If this is a simple operation applied to an IF_THEN_ELSE, try
***************
*** 3656,3667 ****
  	      /* If the result values are STORE_FLAG_VALUE and zero, we can
  		 just make the comparison operation.  */
  	      if (true_rtx == const_true_rtx && false_rtx == const0_rtx)
! 		x = gen_binary (cond_code, mode, cond, cop1);
  	      else if (true_rtx == const0_rtx && false_rtx == const_true_rtx
  		       && ((reversed = reversed_comparison_code_parts
  					(cond_code, cond, cop1, NULL))
  		           != UNKNOWN))
! 		x = gen_binary (reversed, mode, cond, cop1);
  
  	      /* Likewise, we can make the negate of a comparison operation
  		 if the result values are - STORE_FLAG_VALUE and zero.  */
--- 3658,3671 ----
  	      /* If the result values are STORE_FLAG_VALUE and zero, we can
  		 just make the comparison operation.  */
  	      if (true_rtx == const_true_rtx && false_rtx == const0_rtx)
! 		x = simplify_gen_relational (cond_code, mode, VOIDmode,
! 					     cond, cop1);
  	      else if (true_rtx == const0_rtx && false_rtx == const_true_rtx
  		       && ((reversed = reversed_comparison_code_parts
  					(cond_code, cond, cop1, NULL))
  		           != UNKNOWN))
! 		x = simplify_gen_relational (reversed, mode, VOIDmode,
! 					     cond, cop1);
  
  	      /* Likewise, we can make the negate of a comparison operation
  		 if the result values are - STORE_FLAG_VALUE and zero.  */
***************
*** 3669,3676 ****
  		       && INTVAL (true_rtx) == - STORE_FLAG_VALUE
  		       && false_rtx == const0_rtx)
  		x = simplify_gen_unary (NEG, mode,
! 					gen_binary (cond_code, mode, cond,
! 						    cop1),
  					mode);
  	      else if (GET_CODE (false_rtx) == CONST_INT
  		       && INTVAL (false_rtx) == - STORE_FLAG_VALUE
--- 3673,3681 ----
  		       && INTVAL (true_rtx) == - STORE_FLAG_VALUE
  		       && false_rtx == const0_rtx)
  		x = simplify_gen_unary (NEG, mode,
! 					simplify_gen_relational (cond_code,
! 								 mode, VOIDmode,
! 								 cond, cop1),
  					mode);
  	      else if (GET_CODE (false_rtx) == CONST_INT
  		       && INTVAL (false_rtx) == - STORE_FLAG_VALUE
***************
*** 3679,3691 ****
  					(cond_code, cond, cop1, NULL))
  		           != UNKNOWN))
  		x = simplify_gen_unary (NEG, mode,
! 					gen_binary (reversed, mode,
! 						    cond, cop1),
  					mode);
  	      else
  		return gen_rtx_IF_THEN_ELSE (mode,
! 					     gen_binary (cond_code, VOIDmode,
! 							 cond, cop1),
  					     true_rtx, false_rtx);
  
  	      code = GET_CODE (x);
--- 3684,3700 ----
  					(cond_code, cond, cop1, NULL))
  		           != UNKNOWN))
  		x = simplify_gen_unary (NEG, mode,
! 					simplify_gen_relational (reversed,
! 								 mode, VOIDmode,
! 								 cond, cop1),
  					mode);
  	      else
  		return gen_rtx_IF_THEN_ELSE (mode,
! 					     simplify_gen_relational (cond_code,
! 								      mode,
! 								      VOIDmode,
! 								      cond,
! 								      cop1),
  					     true_rtx, false_rtx);
  
  	      code = GET_CODE (x);
***************
*** 3788,3794 ****
  	    }
  
  	  if (inner)
! 	    return gen_binary (code, mode, other, inner);
  	}
      }
  
--- 3797,3803 ----
  	    }
  
  	  if (inner)
! 	    return simplify_gen_binary (code, mode, other, inner);
  	}
      }
  
***************
*** 3890,3896 ****
        if (GET_CODE (XEXP (x, 0)) == XOR
  	  && XEXP (XEXP (x, 0), 1) == const1_rtx
  	  && nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1)
! 	return gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0), constm1_rtx);
  
        temp = expand_compound_operation (XEXP (x, 0));
  
--- 3899,3906 ----
        if (GET_CODE (XEXP (x, 0)) == XOR
  	  && XEXP (XEXP (x, 0), 1) == const1_rtx
  	  && nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1)
! 	return simplify_gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
! 				    constm1_rtx);
  
        temp = expand_compound_operation (XEXP (x, 0));
  
***************
*** 4118,4125 ****
  
  	  in1 = XEXP (XEXP (XEXP (x, 0), 0), 0);
  	  in2 = XEXP (XEXP (x, 0), 1);
! 	  return gen_binary (MINUS, mode, XEXP (x, 1),
! 			     gen_binary (MULT, mode, in1, in2));
  	}
  
        /* If we have (plus (plus (A const) B)), associate it so that CONST is
--- 4128,4136 ----
  
  	  in1 = XEXP (XEXP (XEXP (x, 0), 0), 0);
  	  in2 = XEXP (XEXP (x, 0), 1);
! 	  return simplify_gen_binary (MINUS, mode, XEXP (x, 1),
! 				      simplify_gen_binary (MULT, mode,
! 							   in1, in2));
  	}
  
        /* If we have (plus (plus (A const) B)), associate it so that CONST is
***************
*** 4128,4137 ****
  	 they are now checked elsewhere.  */
        if (GET_CODE (XEXP (x, 0)) == PLUS
  	  && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
! 	return gen_binary (PLUS, mode,
! 			   gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
! 				       XEXP (x, 1)),
! 			   XEXP (XEXP (x, 0), 1));
  
        /* (plus (xor (and <foo> (const_int pow2 - 1)) <c>) <-c>)
  	 when c is (const_int (pow2 + 1) / 2) is a sign extension of a
--- 4139,4149 ----
  	 they are now checked elsewhere.  */
        if (GET_CODE (XEXP (x, 0)) == PLUS
  	  && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
! 	return simplify_gen_binary (PLUS, mode,
! 			   	    simplify_gen_binary (PLUS, mode,
! 							 XEXP (XEXP (x, 0), 0),
! 							 XEXP (x, 1)),
! 				    XEXP (XEXP (x, 0), 1));
  
        /* (plus (xor (and <foo> (const_int pow2 - 1)) <c>) <-c>)
  	 when c is (const_int (pow2 + 1) / 2) is a sign extension of a
***************
*** 4197,4203 ****
  	      & nonzero_bits (XEXP (x, 1), mode)) == 0)
  	{
  	  /* Try to simplify the expression further.  */
! 	  rtx tor = gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
  	  temp = combine_simplify_rtx (tor, mode, in_dest);
  
  	  /* If we could, great.  If not, do not go ahead with the IOR
--- 4209,4215 ----
  	      & nonzero_bits (XEXP (x, 1), mode)) == 0)
  	{
  	  /* Try to simplify the expression further.  */
! 	  rtx tor = simplify_gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
  	  temp = combine_simplify_rtx (tor, mode, in_dest);
  
  	  /* If we could, great.  If not, do not go ahead with the IOR
***************
*** 4237,4244 ****
  
  	  in1 = XEXP (XEXP (XEXP (x, 1), 0), 0);
  	  in2 = XEXP (XEXP (x, 1), 1);
! 	  return gen_binary (PLUS, mode, gen_binary (MULT, mode, in1, in2),
! 			     XEXP (x, 0));
  	}
  
        /* Canonicalize (minus (neg A) (mult B C)) to
--- 4249,4258 ----
  
  	  in1 = XEXP (XEXP (XEXP (x, 1), 0), 0);
  	  in2 = XEXP (XEXP (x, 1), 1);
! 	  return simplify_gen_binary (PLUS, mode,
! 				      simplify_gen_binary (MULT, mode,
! 							   in1, in2),
! 				      XEXP (x, 0));
  	}
  
        /* Canonicalize (minus (neg A) (mult B C)) to
***************
*** 4250,4266 ****
  
  	  in1 = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 1), 0), mode);
  	  in2 = XEXP (XEXP (x, 1), 1);
! 	  return gen_binary (MINUS, mode, gen_binary (MULT, mode, in1, in2),
! 			     XEXP (XEXP (x, 0), 0));
  	}
  
        /* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for
  	 integers.  */
        if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode))
! 	return gen_binary (MINUS, mode,
! 			   gen_binary (MINUS, mode, XEXP (x, 0),
! 				       XEXP (XEXP (x, 1), 0)),
! 			   XEXP (XEXP (x, 1), 1));
        break;
  
      case MULT:
--- 4264,4283 ----
  
  	  in1 = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 1), 0), mode);
  	  in2 = XEXP (XEXP (x, 1), 1);
! 	  return simplify_gen_binary (MINUS, mode,
! 				      simplify_gen_binary (MULT, mode,
! 							   in1, in2),
! 				      XEXP (XEXP (x, 0), 0));
  	}
  
        /* Canonicalize (minus A (plus B C)) to (minus (minus A B) C) for
  	 integers.  */
        if (GET_CODE (XEXP (x, 1)) == PLUS && INTEGRAL_MODE_P (mode))
! 	return simplify_gen_binary (MINUS, mode,
! 				    simplify_gen_binary (MINUS, mode,
! 							 XEXP (x, 0),
! 						         XEXP (XEXP (x, 1), 0)),
! 				    XEXP (XEXP (x, 1), 1));
        break;
  
      case MULT:
***************
*** 4270,4286 ****
  
        if (GET_CODE (XEXP (x, 0)) == PLUS)
  	{
! 	  x = apply_distributive_law
! 	    (gen_binary (PLUS, mode,
! 			 gen_binary (MULT, mode,
! 				     XEXP (XEXP (x, 0), 0), XEXP (x, 1)),
! 			 gen_binary (MULT, mode,
! 				     XEXP (XEXP (x, 0), 1),
! 				     copy_rtx (XEXP (x, 1)))));
! 
! 	  if (GET_CODE (x) != MULT)
! 	    return x;
  	}
        /* Try simplify a*(b/c) as (a*b)/c.  */
        if (FLOAT_MODE_P (mode) && flag_unsafe_math_optimizations
  	  && GET_CODE (XEXP (x, 0)) == DIV)
--- 4287,4297 ----
  
        if (GET_CODE (XEXP (x, 0)) == PLUS)
  	{
! 	  rtx result = distribute_and_simplify_rtx (x);
! 	  if (result)
! 	    return result;
  	}
+ 
        /* Try simplify a*(b/c) as (a*b)/c.  */
        if (FLOAT_MODE_P (mode) && flag_unsafe_math_optimizations
  	  && GET_CODE (XEXP (x, 0)) == DIV)
***************
*** 4289,4295 ****
  					       XEXP (XEXP (x, 0), 0),
  					       XEXP (x, 1));
  	  if (tem)
! 	    return gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
  	}
        break;
  
--- 4300,4306 ----
  					       XEXP (XEXP (x, 0), 0),
  					       XEXP (x, 1));
  	  if (tem)
! 	    return simplify_gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
  	}
        break;
  
***************
*** 4369,4377 ****
  		   && nonzero_bits (op0, mode) == 1)
  	    {
  	      op0 = expand_compound_operation (op0);
! 	      return gen_binary (XOR, mode,
! 				 gen_lowpart (mode, op0),
! 				 const1_rtx);
  	    }
  
  	  else if (STORE_FLAG_VALUE == 1
--- 4380,4388 ----
  		   && nonzero_bits (op0, mode) == 1)
  	    {
  	      op0 = expand_compound_operation (op0);
! 	      return simplify_gen_binary (XOR, mode,
! 					  gen_lowpart (mode, op0),
! 					  const1_rtx);
  	    }
  
  	  else if (STORE_FLAG_VALUE == 1
***************
*** 4614,4620 ****
  
    /* Simplify storing of the truth value.  */
    if (comparison_p && true_rtx == const_true_rtx && false_rtx == const0_rtx)
!     return gen_binary (true_code, mode, XEXP (cond, 0), XEXP (cond, 1));
  
    /* Also when the truth value has to be reversed.  */
    if (comparison_p
--- 4625,4632 ----
  
    /* Simplify storing of the truth value.  */
    if (comparison_p && true_rtx == const_true_rtx && false_rtx == const0_rtx)
!     return simplify_gen_relational (true_code, mode, VOIDmode,
! 				    XEXP (cond, 0), XEXP (cond, 1));
  
    /* Also when the truth value has to be reversed.  */
    if (comparison_p
***************
*** 4764,4779 ****
        {
        case GE:
        case GT:
! 	return gen_binary (SMAX, mode, true_rtx, false_rtx);
        case LE:
        case LT:
! 	return gen_binary (SMIN, mode, true_rtx, false_rtx);
        case GEU:
        case GTU:
! 	return gen_binary (UMAX, mode, true_rtx, false_rtx);
        case LEU:
        case LTU:
! 	return gen_binary (UMIN, mode, true_rtx, false_rtx);
        default:
  	break;
        }
--- 4776,4791 ----
        {
        case GE:
        case GT:
! 	return simplify_gen_binary (SMAX, mode, true_rtx, false_rtx);
        case LE:
        case LT:
! 	return simplify_gen_binary (SMIN, mode, true_rtx, false_rtx);
        case GEU:
        case GTU:
! 	return simplify_gen_binary (UMAX, mode, true_rtx, false_rtx);
        case LEU:
        case LTU:
! 	return simplify_gen_binary (UMIN, mode, true_rtx, false_rtx);
        default:
  	break;
        }
***************
*** 4886,4897 ****
  
        if (z)
  	{
! 	  temp = subst (gen_binary (true_code, m, cond_op0, cond_op1),
  			pc_rtx, pc_rtx, 0, 0);
! 	  temp = gen_binary (MULT, m, temp,
! 			     gen_binary (MULT, m, c1, const_true_rtx));
  	  temp = subst (temp, pc_rtx, pc_rtx, 0, 0);
! 	  temp = gen_binary (op, m, gen_lowpart (m, z), temp);
  
  	  if (extend_op != NIL)
  	    temp = simplify_gen_unary (extend_op, mode, temp, m);
--- 4898,4911 ----
  
        if (z)
  	{
! 	  temp = subst (simplify_gen_relational (true_code, m, VOIDmode,
! 						 cond_op0, cond_op1),
  			pc_rtx, pc_rtx, 0, 0);
! 	  temp = simplify_gen_binary (MULT, m, temp,
! 				      simplify_gen_binary (MULT, m, c1,
! 							   const_true_rtx));
  	  temp = subst (temp, pc_rtx, pc_rtx, 0, 0);
! 	  temp = simplify_gen_binary (op, m, gen_lowpart (m, z), temp);
  
  	  if (extend_op != NIL)
  	    temp = simplify_gen_unary (extend_op, mode, temp, m);
***************
*** 5076,5082 ****
  		  PUT_CODE (*cc_use, old_code);
  		  other_changed = 0;
  
! 		  op0 = gen_binary (XOR, GET_MODE (op0), op0, GEN_INT (mask));
  		}
  	    }
  	}
--- 5090,5097 ----
  		  PUT_CODE (*cc_use, old_code);
  		  other_changed = 0;
  
! 		  op0 = simplify_gen_binary (XOR, GET_MODE (op0),
! 					     op0, GEN_INT (mask));
  		}
  	    }
  	}
***************
*** 5240,5257 ****
  	       && rtx_equal_p (XEXP (false_rtx, 1), true_rtx))
  	term1 = true_rtx, false_rtx = XEXP (false_rtx, 0), true_rtx = const0_rtx;
  
!       term2 = gen_binary (AND, GET_MODE (src),
! 			  XEXP (XEXP (src, 0), 0), true_rtx);
!       term3 = gen_binary (AND, GET_MODE (src),
! 			  simplify_gen_unary (NOT, GET_MODE (src),
! 					      XEXP (XEXP (src, 0), 0),
! 					      GET_MODE (src)),
! 			  false_rtx);
  
        SUBST (SET_SRC (x),
! 	     gen_binary (IOR, GET_MODE (src),
! 			 gen_binary (IOR, GET_MODE (src), term1, term2),
! 			 term3));
  
        src = SET_SRC (x);
      }
--- 5255,5273 ----
  	       && rtx_equal_p (XEXP (false_rtx, 1), true_rtx))
  	term1 = true_rtx, false_rtx = XEXP (false_rtx, 0), true_rtx = const0_rtx;
  
!       term2 = simplify_gen_binary (AND, GET_MODE (src),
! 				   XEXP (XEXP (src, 0), 0), true_rtx);
!       term3 = simplify_gen_binary (AND, GET_MODE (src),
! 				   simplify_gen_unary (NOT, GET_MODE (src),
! 						       XEXP (XEXP (src, 0), 0),
! 						       GET_MODE (src)),
! 				   false_rtx);
  
        SUBST (SET_SRC (x),
! 	     simplify_gen_binary (IOR, GET_MODE (src),
! 				  simplify_gen_binary (IOR, GET_MODE (src),
! 						       term1, term2),
! 				  term3));
  
        src = SET_SRC (x);
      }
***************
*** 5286,5314 ****
        if (GET_CODE (op0) == XOR
  	  && rtx_equal_p (XEXP (op0, 0), op1)
  	  && ! side_effects_p (op1))
! 	x = gen_binary (AND, mode,
! 			simplify_gen_unary (NOT, mode, XEXP (op0, 1), mode),
! 			op1);
  
        if (GET_CODE (op0) == XOR
  	  && rtx_equal_p (XEXP (op0, 1), op1)
  	  && ! side_effects_p (op1))
! 	x = gen_binary (AND, mode,
! 			simplify_gen_unary (NOT, mode, XEXP (op0, 0), mode),
! 			op1);
  
        /* Similarly for (~(A ^ B)) & A.  */
        if (GET_CODE (op0) == NOT
  	  && GET_CODE (XEXP (op0, 0)) == XOR
  	  && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
  	  && ! side_effects_p (op1))
! 	x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
  
        if (GET_CODE (op0) == NOT
  	  && GET_CODE (XEXP (op0, 0)) == XOR
  	  && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
  	  && ! side_effects_p (op1))
! 	x = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
  
        /* We can call simplify_and_const_int only if we don't lose
  	 any (sign) bits when converting INTVAL (op1) to
--- 5302,5332 ----
        if (GET_CODE (op0) == XOR
  	  && rtx_equal_p (XEXP (op0, 0), op1)
  	  && ! side_effects_p (op1))
! 	x = simplify_gen_binary (AND, mode,
! 				 simplify_gen_unary (NOT, mode,
! 						     XEXP (op0, 1), mode),
! 				 op1);
  
        if (GET_CODE (op0) == XOR
  	  && rtx_equal_p (XEXP (op0, 1), op1)
  	  && ! side_effects_p (op1))
! 	x = simplify_gen_binary (AND, mode,
! 				 simplify_gen_unary (NOT, mode,
! 						     XEXP (op0, 0), mode),
! 				 op1);
  
        /* Similarly for (~(A ^ B)) & A.  */
        if (GET_CODE (op0) == NOT
  	  && GET_CODE (XEXP (op0, 0)) == XOR
  	  && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
  	  && ! side_effects_p (op1))
! 	x = simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
  
        if (GET_CODE (op0) == NOT
  	  && GET_CODE (XEXP (op0, 0)) == XOR
  	  && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
  	  && ! side_effects_p (op1))
! 	x = simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
  
        /* We can call simplify_and_const_int only if we don't lose
  	 any (sign) bits when converting INTVAL (op1) to
***************
*** 5328,5335 ****
  	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
  	      && GET_CODE (op1) == CONST_INT
  	      && (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) != 0)
! 	    return gen_binary (IOR, mode,
! 			       gen_binary (AND, mode, XEXP (op0, 0),
  					   GEN_INT (INTVAL (XEXP (op0, 1))
  						    & ~INTVAL (op1))), op1);
  
--- 5346,5354 ----
  	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
  	      && GET_CODE (op1) == CONST_INT
  	      && (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) != 0)
! 	    return simplify_gen_binary (IOR, mode,
! 				        simplify_gen_binary
! 					  (AND, mode, XEXP (op0, 0),
  					   GEN_INT (INTVAL (XEXP (op0, 1))
  						    & ~INTVAL (op1))), op1);
  
***************
*** 5348,5401 ****
  	  && ! side_effects_p (XEXP (op0, 1)))
  	return op1;
  
!       /* In the following group of tests (and those in case IOR below),
! 	 we start with some combination of logical operations and apply
! 	 the distributive law followed by the inverse distributive law.
! 	 Most of the time, this results in no change.  However, if some of
! 	 the operands are the same or inverses of each other, simplifications
! 	 will result.
! 
! 	 For example, (and (ior A B) (not B)) can occur as the result of
! 	 expanding a bit field assignment.  When we apply the distributive
! 	 law to this, we get (ior (and (A (not B))) (and (B (not B)))),
! 	 which then simplifies to (and (A (not B))).
! 
! 	 If we have (and (ior A B) C), apply the distributive law and then
! 	 the inverse distributive law to see if things simplify.  */
! 
!       if (GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
! 	{
! 	  x = apply_distributive_law
! 	    (gen_binary (GET_CODE (op0), mode,
! 			 gen_binary (AND, mode, XEXP (op0, 0), op1),
! 			 gen_binary (AND, mode, XEXP (op0, 1),
! 				     copy_rtx (op1))));
! 	  if (GET_CODE (x) != AND)
! 	    return x;
  	}
- 
-       if (GET_CODE (op1) == IOR || GET_CODE (op1) == XOR)
- 	return apply_distributive_law
- 	  (gen_binary (GET_CODE (op1), mode,
- 		       gen_binary (AND, mode, XEXP (op1, 0), op0),
- 		       gen_binary (AND, mode, XEXP (op1, 1),
- 				   copy_rtx (op0))));
- 
-       /* Similarly, taking advantage of the fact that
- 	 (and (not A) (xor B C)) == (xor (ior A B) (ior A C))  */
- 
-       if (GET_CODE (op0) == NOT && GET_CODE (op1) == XOR)
- 	return apply_distributive_law
- 	  (gen_binary (XOR, mode,
- 		       gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 0)),
- 		       gen_binary (IOR, mode, copy_rtx (XEXP (op0, 0)),
- 				   XEXP (op1, 1))));
- 
-       else if (GET_CODE (op1) == NOT && GET_CODE (op0) == XOR)
- 	return apply_distributive_law
- 	  (gen_binary (XOR, mode,
- 		       gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 0)),
- 		       gen_binary (IOR, mode, copy_rtx (XEXP (op1, 0)), XEXP (op0, 1))));
        break;
  
      case IOR:
--- 5367,5382 ----
  	  && ! side_effects_p (XEXP (op0, 1)))
  	return op1;
  
!       /* If we have any of (and (ior A B) C) or (and (xor A B) C),
! 	 apply the distributive law and then the inverse distributive
! 	 law to see if things simplify.  */
!       if (GET_CODE (op0) == IOR || GET_CODE (op0) == XOR
!           || GET_CODE (op1) == IOR || GET_CODE (op1) == XOR)
! 	{
! 	  rtx result = distribute_and_simplify_rtx (x);
! 	  if (result)
! 	    return result;
  	}
        break;
  
      case IOR:
***************
*** 5416,5443 ****
        /* If we have (ior (and A B) C), apply the distributive law and then
  	 the inverse distributive law to see if things simplify.  */
  
!       if (GET_CODE (op0) == AND)
! 	{
! 	  x = apply_distributive_law
! 	    (gen_binary (AND, mode,
! 			 gen_binary (IOR, mode, XEXP (op0, 0), op1),
! 			 gen_binary (IOR, mode, XEXP (op0, 1),
! 				     copy_rtx (op1))));
! 
! 	  if (GET_CODE (x) != IOR)
! 	    return x;
! 	}
! 
!       if (GET_CODE (op1) == AND)
  	{
! 	  x = apply_distributive_law
! 	    (gen_binary (AND, mode,
! 			 gen_binary (IOR, mode, XEXP (op1, 0), op0),
! 			 gen_binary (IOR, mode, XEXP (op1, 1),
! 				     copy_rtx (op0))));
! 
! 	  if (GET_CODE (x) != IOR)
! 	    return x;
  	}
  
        /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
--- 5397,5407 ----
        /* If we have (ior (and A B) C), apply the distributive law and then
  	 the inverse distributive law to see if things simplify.  */
  
!       if (GET_CODE (op0) == AND || GET_CODE (op1) == AND)
  	{
! 	  rtx result = distribute_and_simplify_rtx (x);
! 	  if (result)
! 	    return result;
  	}
  
        /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
***************
*** 5486,5492 ****
        if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
  	  && (nonzero_bits (op0, mode)
  	      & nonzero_bits (op1, mode)) == 0)
! 	return (gen_binary (IOR, mode, op0, op1));
  
        /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
  	 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
--- 5450,5456 ----
        if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
  	  && (nonzero_bits (op0, mode)
  	      & nonzero_bits (op1, mode)) == 0)
! 	return (simplify_gen_binary (IOR, mode, op0, op1));
  
        /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
  	 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
***************
*** 5506,5512 ****
  	  }
  	else if (num_negated == 1)
  	  return
! 	    simplify_gen_unary (NOT, mode, gen_binary (XOR, mode, op0, op1),
  				mode);
        }
  
--- 5470,5477 ----
  	  }
  	else if (num_negated == 1)
  	  return
! 	    simplify_gen_unary (NOT, mode,
! 				simplify_gen_binary (XOR, mode, op0, op1),
  				mode);
        }
  
***************
*** 5517,5532 ****
        if (GET_CODE (op0) == AND
  	  && rtx_equal_p (XEXP (op0, 1), op1)
  	  && ! side_effects_p (op1))
! 	return gen_binary (AND, mode,
! 			   simplify_gen_unary (NOT, mode, XEXP (op0, 0), mode),
! 			   op1);
  
        else if (GET_CODE (op0) == AND
  	       && rtx_equal_p (XEXP (op0, 0), op1)
  	       && ! side_effects_p (op1))
! 	return gen_binary (AND, mode,
! 			   simplify_gen_unary (NOT, mode, XEXP (op0, 1), mode),
! 			   op1);
  
        /* (xor (comparison foo bar) (const_int 1)) can become the reversed
  	 comparison if STORE_FLAG_VALUE is 1.  */
--- 5482,5499 ----
        if (GET_CODE (op0) == AND
  	  && rtx_equal_p (XEXP (op0, 1), op1)
  	  && ! side_effects_p (op1))
! 	return simplify_gen_binary (AND, mode,
! 				    simplify_gen_unary (NOT, mode,
! 							XEXP (op0, 0), mode),
! 				    op1);
  
        else if (GET_CODE (op0) == AND
  	       && rtx_equal_p (XEXP (op0, 0), op1)
  	       && ! side_effects_p (op1))
! 	return simplify_gen_binary (AND, mode,
! 				    simplify_gen_unary (NOT, mode,
! 							XEXP (op0, 1), mode),
! 				    op1);
  
        /* (xor (comparison foo bar) (const_int 1)) can become the reversed
  	 comparison if STORE_FLAG_VALUE is 1.  */
***************
*** 5795,5801 ****
    rtx inner;
    rtx pos;			/* Always counts from low bit.  */
    int len;
!   rtx mask;
    enum machine_mode compute_mode;
  
    /* Loop until we find something we can't simplify.  */
--- 5762,5768 ----
    rtx inner;
    rtx pos;			/* Always counts from low bit.  */
    int len;
!   rtx mask, cleared, masked;
    enum machine_mode compute_mode;
  
    /* Loop until we find something we can't simplify.  */
***************
*** 5833,5842 ****
  		/* If position is ADJUST - X, new position is X.  */
  		pos = XEXP (pos, 0);
  	      else
! 		pos = gen_binary (MINUS, GET_MODE (pos),
! 				  GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner))
! 					   - len),
! 				  pos);
  	    }
  	}
  
--- 5800,5810 ----
  		/* If position is ADJUST - X, new position is X.  */
  		pos = XEXP (pos, 0);
  	      else
! 		pos = simplify_gen_binary (MINUS, GET_MODE (pos),
! 					   GEN_INT (GET_MODE_BITSIZE (
! 						    GET_MODE (inner))
! 						    - len),
! 					   pos);
  	    }
  	}
  
***************
*** 5883,5912 ****
  	}
  
        /* Compute a mask of LEN bits, if we can do this on the host machine.  */
!       if (len < HOST_BITS_PER_WIDE_INT)
! 	mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1);
!       else
  	break;
  
        /* Now compute the equivalent expression.  Make a copy of INNER
  	 for the SET_DEST in case it is a MEM into which we will substitute;
  	 we don't want shared RTL in that case.  */
!       x = gen_rtx_SET
! 	(VOIDmode, copy_rtx (inner),
! 	 gen_binary (IOR, compute_mode,
! 		     gen_binary (AND, compute_mode,
! 				 simplify_gen_unary (NOT, compute_mode,
! 						     gen_binary (ASHIFT,
! 								 compute_mode,
! 								 mask, pos),
! 						     compute_mode),
! 				 inner),
! 		     gen_binary (ASHIFT, compute_mode,
! 				 gen_binary (AND, compute_mode,
! 					     gen_lowpart
! 					     (compute_mode, SET_SRC (x)),
! 					     mask),
! 				 pos)));
      }
  
    return x;
--- 5851,5880 ----
  	}
  
        /* Compute a mask of LEN bits, if we can do this on the host machine.  */
!       if (len >= HOST_BITS_PER_WIDE_INT)
  	break;
  
        /* Now compute the equivalent expression.  Make a copy of INNER
  	 for the SET_DEST in case it is a MEM into which we will substitute;
  	 we don't want shared RTL in that case.  */
!       mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1);
!       cleared = simplify_gen_binary (AND, compute_mode,
! 				     simplify_gen_unary (NOT, compute_mode,
! 				       simplify_gen_binary (ASHIFT,
! 							    compute_mode,
! 							    mask, pos),
! 				       compute_mode),
! 				     inner);
!       masked = simplify_gen_binary (ASHIFT, compute_mode,
! 				    simplify_gen_binary (
! 				      AND, compute_mode,
! 				      gen_lowpart (compute_mode, SET_SRC (x)),
! 				      mask),
! 				    pos);
! 
!       x = gen_rtx_SET (VOIDmode, copy_rtx (inner),
! 		       simplify_gen_binary (IOR, compute_mode,
! 					    cleared, masked));
      }
  
    return x;
***************
*** 6362,6369 ****
        if (GET_CODE (XEXP (x, 1)) == CONST_INT
  	  && (INTVAL (XEXP (x, 1)) & ((((HOST_WIDE_INT) 1 << count)) - 1)) == 0
  	  && (tem = extract_left_shift (XEXP (x, 0), count)) != 0)
! 	return gen_binary (code, mode, tem,
! 			   GEN_INT (INTVAL (XEXP (x, 1)) >> count));
  
        break;
  
--- 6330,6337 ----
        if (GET_CODE (XEXP (x, 1)) == CONST_INT
  	  && (INTVAL (XEXP (x, 1)) & ((((HOST_WIDE_INT) 1 << count)) - 1)) == 0
  	  && (tem = extract_left_shift (XEXP (x, 0), count)) != 0)
! 	return simplify_gen_binary (code, mode, tem,
! 				    GEN_INT (INTVAL (XEXP (x, 1)) >> count));
  
        break;
  
***************
*** 6854,6860 ****
  		  && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
  		cval |= (HOST_WIDE_INT) -1 << width;
  
! 	      y = gen_binary (AND, GET_MODE (x), XEXP (x, 0), GEN_INT (cval));
  	      if (rtx_cost (y, SET) < rtx_cost (x, SET))
  		x = y;
  	    }
--- 6822,6829 ----
  		  && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
  		cval |= (HOST_WIDE_INT) -1 << width;
  
! 	      y = simplify_gen_binary (AND, GET_MODE (x),
! 				       XEXP (x, 0), GEN_INT (cval));
  	      if (rtx_cost (y, SET) < rtx_cost (x, SET))
  		x = y;
  	    }
***************
*** 6946,6955 ****
  	{
  	  temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask)
  			  << INTVAL (XEXP (XEXP (x, 0), 1)));
! 	  temp = gen_binary (GET_CODE (x), GET_MODE (x),
! 			     XEXP (XEXP (x, 0), 0), temp);
! 	  x = gen_binary (LSHIFTRT, GET_MODE (x), temp,
! 			  XEXP (XEXP (x, 0), 1));
  	  return force_to_mode (x, mode, mask, reg, next_select);
  	}
  
--- 6915,6924 ----
  	{
  	  temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask)
  			  << INTVAL (XEXP (XEXP (x, 0), 1)));
! 	  temp = simplify_gen_binary (GET_CODE (x), GET_MODE (x),
! 				      XEXP (XEXP (x, 0), 0), temp);
! 	  x = simplify_gen_binary (LSHIFTRT, GET_MODE (x), temp,
! 				   XEXP (XEXP (x, 0), 1));
  	  return force_to_mode (x, mode, mask, reg, next_select);
  	}
  
***************
*** 6965,6971 ****
  					reg, next_select));
  
        if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
! 	x = gen_binary (code, op_mode, op0, op1);
        break;
  
      case ASHIFT:
--- 6934,6940 ----
  					reg, next_select));
  
        if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
! 	x = simplify_gen_binary (code, op_mode, op0, op1);
        break;
  
      case ASHIFT:
***************
*** 6999,7005 ****
  					mask, reg, next_select));
  
        if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
! 	x = gen_binary (code, op_mode, op0, XEXP (x, 1));
        break;
  
      case LSHIFTRT:
--- 6968,6974 ----
  					mask, reg, next_select));
  
        if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
! 	x = simplify_gen_binary (code, op_mode, op0, XEXP (x, 1));
        break;
  
      case LSHIFTRT:
***************
*** 7027,7033 ****
  	  inner = force_to_mode (inner, op_mode, inner_mask, reg, next_select);
  
  	  if (GET_MODE (x) != op_mode || inner != XEXP (x, 0))
! 	    x = gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1));
  	}
  
        /* If we have (and (lshiftrt FOO C1) C2) where the combination of the
--- 6996,7002 ----
  	  inner = force_to_mode (inner, op_mode, inner_mask, reg, next_select);
  
  	  if (GET_MODE (x) != op_mode || inner != XEXP (x, 0))
! 	    x = simplify_gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1));
  	}
  
        /* If we have (and (lshiftrt FOO C1) C2) where the combination of the
***************
*** 7049,7057 ****
  	  /* Must be more sign bit copies than the mask needs.  */
  	  && ((int) num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
  	      >= exact_log2 (mask + 1)))
! 	x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0),
! 			GEN_INT (GET_MODE_BITSIZE (GET_MODE (x))
! 				 - exact_log2 (mask + 1)));
  
        goto shiftrt;
  
--- 7018,7026 ----
  	  /* Must be more sign bit copies than the mask needs.  */
  	  && ((int) num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
  	      >= exact_log2 (mask + 1)))
! 	x = simplify_gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0),
! 				 GEN_INT (GET_MODE_BITSIZE (GET_MODE (x))
! 					  - exact_log2 (mask + 1)));
  
        goto shiftrt;
  
***************
*** 7116,7122 ****
        /* If MASK is 1, convert this to an LSHIFTRT.  This can be done
  	 even if the shift count isn't a constant.  */
        if (mask == 1)
! 	x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0), XEXP (x, 1));
  
      shiftrt:
  
--- 7085,7092 ----
        /* If MASK is 1, convert this to an LSHIFTRT.  This can be done
  	 even if the shift count isn't a constant.  */
        if (mask == 1)
! 	x = simplify_gen_binary (LSHIFTRT, GET_MODE (x),
! 				 XEXP (x, 0), XEXP (x, 1));
  
      shiftrt:
  
***************
*** 7181,7188 ****
  	{
  	  temp = gen_int_mode (mask << INTVAL (XEXP (XEXP (x, 0), 1)),
  			       GET_MODE (x));
! 	  temp = gen_binary (XOR, GET_MODE (x), XEXP (XEXP (x, 0), 0), temp);
! 	  x = gen_binary (LSHIFTRT, GET_MODE (x), temp, XEXP (XEXP (x, 0), 1));
  
  	  return force_to_mode (x, mode, mask, reg, next_select);
  	}
--- 7151,7160 ----
  	{
  	  temp = gen_int_mode (mask << INTVAL (XEXP (XEXP (x, 0), 1)),
  			       GET_MODE (x));
! 	  temp = simplify_gen_binary (XOR, GET_MODE (x),
! 				      XEXP (XEXP (x, 0), 0), temp);
! 	  x = simplify_gen_binary (LSHIFTRT, GET_MODE (x),
! 				   temp, XEXP (XEXP (x, 0), 1));
  
  	  return force_to_mode (x, mode, mask, reg, next_select);
  	}
***************
*** 7292,7299 ****
  	  else if (cond1 == 0)
  	    true1 = copy_rtx (true1);
  
! 	  *ptrue = gen_binary (code, mode, true0, true1);
! 	  *pfalse = gen_binary (code, mode, false0, false1);
  	  return cond0 ? cond0 : cond1;
  	}
  
--- 7264,7282 ----
  	  else if (cond1 == 0)
  	    true1 = copy_rtx (true1);
  
! 	  if (COMPARISON_P (x))
! 	    {
! 	      *ptrue = simplify_gen_relational (code, mode, VOIDmode,
! 						true0, true1);
! 	      *pfalse = simplify_gen_relational (code, mode, VOIDmode,
! 					         false0, false1);
! 	     }
! 	  else
! 	    {
! 	      *ptrue = simplify_gen_binary (code, mode, true0, true1);
! 	      *pfalse = simplify_gen_binary (code, mode, false0, false1);
! 	    }
! 
  	  return cond0 ? cond0 : cond1;
  	}
  
***************
*** 7323,7335 ****
  		      && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
  	      && ! side_effects_p (x))
  	    {
! 	      *ptrue = gen_binary (MULT, mode, op0, const_true_rtx);
! 	      *pfalse = gen_binary (MULT, mode,
! 				    (code == MINUS
! 				     ? simplify_gen_unary (NEG, mode, op1,
! 							   mode)
! 				     : op1),
! 				    const_true_rtx);
  	      return cond0;
  	    }
  	}
--- 7306,7318 ----
  		      && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
  	      && ! side_effects_p (x))
  	    {
! 	      *ptrue = simplify_gen_binary (MULT, mode, op0, const_true_rtx);
! 	      *pfalse = simplify_gen_binary (MULT, mode,
! 					     (code == MINUS
! 					      ? simplify_gen_unary (NEG, mode,
! 								    op1, mode)
! 					      : op1),
! 					      const_true_rtx);
  	      return cond0;
  	    }
  	}
***************
*** 7833,7840 ****
  	  || GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD)
  	return x;
  
!       tem = gen_binary (code, GET_MODE (SUBREG_REG (lhs)),
! 			SUBREG_REG (lhs), SUBREG_REG (rhs));
        return gen_lowpart (GET_MODE (x), tem);
  
      default:
--- 7816,7823 ----
  	  || GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD)
  	return x;
  
!       tem = simplify_gen_binary (code, GET_MODE (SUBREG_REG (lhs)),
! 				 SUBREG_REG (lhs), SUBREG_REG (rhs));
        return gen_lowpart (GET_MODE (x), tem);
  
      default:
***************
*** 7860,7866 ****
      return x;
  
    /* Form the new inner operation, seeing if it simplifies first.  */
!   tem = gen_binary (code, GET_MODE (x), lhs, rhs);
  
    /* There is one exception to the general way of distributing:
       (a | c) ^ (b | c) -> (a ^ b) & ~c  */
--- 7843,7849 ----
      return x;
  
    /* Form the new inner operation, seeing if it simplifies first.  */
!   tem = simplify_gen_binary (code, GET_MODE (x), lhs, rhs);
  
    /* There is one exception to the general way of distributing:
       (a | c) ^ (b | c) -> (a ^ b) & ~c  */
***************
*** 7873,7880 ****
    /* We may be able to continuing distributing the result, so call
       ourselves recursively on the inner operation before forming the
       outer operation, which we return.  */
!   return gen_binary (inner_code, GET_MODE (x),
! 		     apply_distributive_law (tem), other);
  }
  \f
  /* We have X, a logical `and' of VAROP with the constant CONSTOP, to be done
--- 7856,7942 ----
    /* We may be able to continuing distributing the result, so call
       ourselves recursively on the inner operation before forming the
       outer operation, which we return.  */
!   return simplify_gen_binary (inner_code, GET_MODE (x),
! 			      apply_distributive_law (tem), other);
! }
! 
! /* See if X is of the form (* (+ a b) c), and if so convert to
!    (+ (* a c) (* b c)) and try to simplify.
! 
!    Most of the time, this results in no change.  However, if some of
!    the operands are the same or inverses of each other, simplifications
!    will result.
! 
!    For example, (and (ior A B) (not B)) can occur as the result of
!    expanding a bit field assignment.  When we apply the distributive
!    law to this, we get (ior (and (A (not B))) (and (B (not B)))),
!    which then simplifies to (and (A (not B))).
!  
!    Note that no checks happen on the validity of applying the inverse
!    distributive law.  This is pointless since we can do it in the
!    few places where this routine is called.  */
! static rtx
! distribute_and_simplify_rtx (rtx x)
! {
!   enum machine_mode mode;
!   enum rtx_code outer, inner;
!   rtx op0, op1, inner_op0, inner_op1, new_op0, new_op1;
! 
!   mode = GET_MODE (x);
!   outer = GET_CODE (x);
!   op0 = XEXP (x, 0);
!   op1 = XEXP (x, 1);
!   if (ARITHMETIC_P (op0))
!     {
!       inner = GET_CODE (op0);
!       inner_op0 = XEXP (op0, 0);
!       inner_op1 = XEXP (op0, 1);
! 
!       /* (and (xor B C) (not A)) == (xor (ior A B) (ior A C))  */
!       if (outer == AND && inner == XOR && GET_CODE (op1) == NOT)
!         {
! 	  new_op0 = simplify_gen_binary (IOR, mode, inner_op0, XEXP (op1, 0));
!           new_op1 = simplify_gen_binary (IOR, mode, inner_op1, XEXP (op1, 0));
!           x = apply_distributive_law (simplify_gen_binary (XOR, mode,
! 							   new_op0, new_op1));
! 	}
!       else
! 	{
!           new_op0 = simplify_gen_binary (outer, mode, inner_op0, op1);
!           new_op1 = simplify_gen_binary (outer, mode, inner_op1, op1);
!           x = apply_distributive_law (simplify_gen_binary (inner, mode,
! 							   new_op0, new_op1));
! 	}
!       if (GET_CODE (x) != outer)
!         return x;
!     }
! 
!   if (ARITHMETIC_P (op1))
!     {
!       inner = GET_CODE (op1);
!       inner_op0 = XEXP (op1, 0);
!       inner_op1 = XEXP (op1, 1);
! 
!       /* (and (not A) (xor B C)) == (xor (ior A B) (ior A C))  */
!       if (outer == AND && inner == XOR && GET_CODE (op0) == NOT)
!         {
! 	  new_op0 = simplify_gen_binary (IOR, mode, inner_op0, XEXP (op0, 0));
!           new_op1 = simplify_gen_binary (IOR, mode, inner_op1, XEXP (op0, 0));
!           x = apply_distributive_law (simplify_gen_binary (XOR, mode,
! 							   new_op0, new_op1));
! 	}
!       else
! 	{
!           new_op0 = simplify_gen_binary (outer, mode, op0, inner_op0);
!           new_op1 = simplify_gen_binary (outer, mode, op0, inner_op1);
!           x = apply_distributive_law (simplify_gen_binary (inner, mode,
! 							   new_op0, new_op1));
! 	}
!       if (GET_CODE (x) != outer)
!         return x;
!     }
! 
!   return NULL_RTX;
  }
  \f
  /* We have X, a logical `and' of VAROP with the constant CONSTOP, to be done
***************
*** 7941,7951 ****
        gen_lowpart
  	(mode,
  	 apply_distributive_law
! 	 (gen_binary (GET_CODE (varop), GET_MODE (varop),
! 		      simplify_and_const_int (NULL_RTX, GET_MODE (varop),
! 					      XEXP (varop, 0), constop),
! 		      simplify_and_const_int (NULL_RTX, GET_MODE (varop),
! 					      XEXP (varop, 1), constop))));
  
    /* If VAROP is PLUS, and the constant is a mask of low bite, distribute
       the AND and see if one of the operands simplifies to zero.  If so, we
--- 8003,8017 ----
        gen_lowpart
  	(mode,
  	 apply_distributive_law
! 	 (simplify_gen_binary (GET_CODE (varop), GET_MODE (varop),
! 			       simplify_and_const_int (NULL_RTX,
! 						       GET_MODE (varop),
! 						       XEXP (varop, 0),
! 						       constop),
! 			       simplify_and_const_int (NULL_RTX,
! 						       GET_MODE (varop),
! 						       XEXP (varop, 1),
! 						       constop))));
  
    /* If VAROP is PLUS, and the constant is a mask of low bite, distribute
       the AND and see if one of the operands simplifies to zero.  If so, we
***************
*** 7986,7992 ****
        constop = trunc_int_for_mode (constop, mode);
        /* See how much, if any, of X we can use.  */
        if (x == 0 || GET_CODE (x) != AND || GET_MODE (x) != mode)
! 	x = gen_binary (AND, mode, varop, GEN_INT (constop));
  
        else
  	{
--- 8052,8058 ----
        constop = trunc_int_for_mode (constop, mode);
        /* See how much, if any, of X we can use.  */
        if (x == 0 || GET_CODE (x) != AND || GET_MODE (x) != mode)
! 	x = simplify_gen_binary (AND, mode, varop, GEN_INT (constop));
  
        else
  	{
***************
*** 8505,8512 ****
  	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
  	    {
  	      varop
! 		= gen_binary (ASHIFT, GET_MODE (varop), XEXP (varop, 0),
! 			      GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
  	      continue;
  	    }
  	  break;
--- 8571,8580 ----
  	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
  	    {
  	      varop
! 		= simplify_gen_binary (ASHIFT, GET_MODE (varop),
! 				       XEXP (varop, 0),
! 				       GEN_INT (exact_log2 (
! 						INTVAL (XEXP (varop, 1)))));
  	      continue;
  	    }
  	  break;
***************
*** 8517,8524 ****
  	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
  	    {
  	      varop
! 		= gen_binary (LSHIFTRT, GET_MODE (varop), XEXP (varop, 0),
! 			      GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
  	      continue;
  	    }
  	  break;
--- 8585,8594 ----
  	      && exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
  	    {
  	      varop
! 		= simplify_gen_binary (LSHIFTRT, GET_MODE (varop),
! 				       XEXP (varop, 0),
! 				       GEN_INT (exact_log2 (
! 						INTVAL (XEXP (varop, 1)))));
  	      continue;
  	    }
  	  break;
***************
*** 8773,8779 ****
  	      rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
  					      XEXP (varop, 1), count);
  
! 	      varop = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs);
  	      varop = apply_distributive_law (varop);
  
  	      count = 0;
--- 8843,8850 ----
  	      rtx rhs = simplify_shift_const (NULL_RTX, code, shift_mode,
  					      XEXP (varop, 1), count);
  
! 	      varop = simplify_gen_binary (GET_CODE (varop), shift_mode,
! 					   lhs, rhs);
  	      varop = apply_distributive_law (varop);
  
  	      count = 0;
***************
*** 9028,9034 ****
        else if (GET_RTX_CLASS (outer_op) == RTX_UNARY)
  	x = simplify_gen_unary (outer_op, result_mode, x, result_mode);
        else
! 	x = gen_binary (outer_op, result_mode, x, GEN_INT (outer_const));
      }
  
    return x;
--- 9099,9106 ----
        else if (GET_RTX_CLASS (outer_op) == RTX_UNARY)
  	x = simplify_gen_unary (outer_op, result_mode, x, result_mode);
        else
! 	x = simplify_gen_binary (outer_op, result_mode, x,
! 				 GEN_INT (outer_const));
      }
  
    return x;
***************
*** 9261,9323 ****
      }
  }
  \f
- /* These routines make binary and unary operations by first seeing if they
-    fold; if not, a new expression is allocated.  */
- 
- static rtx
- gen_binary (enum rtx_code code, enum machine_mode mode, rtx op0, rtx op1)
- {
-   rtx result;
-   rtx tem;
- 
-   if (GET_CODE (op0) == CLOBBER)
-     return op0;
-   else if (GET_CODE (op1) == CLOBBER)
-     return op1;
-   
-   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
-       && swap_commutative_operands_p (op0, op1))
-     tem = op0, op0 = op1, op1 = tem;
- 
-   if (GET_RTX_CLASS (code) == RTX_COMPARE
-       || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
-     {
-       enum machine_mode op_mode = GET_MODE (op0);
- 
-       /* Strip the COMPARE from (REL_OP (compare X Y) 0) to get
- 	 just (REL_OP X Y).  */
-       if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
- 	{
- 	  op1 = XEXP (op0, 1);
- 	  op0 = XEXP (op0, 0);
- 	  op_mode = GET_MODE (op0);
- 	}
- 
-       if (op_mode == VOIDmode)
- 	op_mode = GET_MODE (op1);
-       result = simplify_relational_operation (code, mode, op_mode, op0, op1);
-     }
-   else
-     result = simplify_binary_operation (code, mode, op0, op1);
- 
-   if (result)
-     return result;
- 
-   /* Put complex operands first and constants second.  */
-   if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
-       && swap_commutative_operands_p (op0, op1))
-     return gen_rtx_fmt_ee (code, mode, op1, op0);
- 
-   /* If we are turning off bits already known off in OP0, we need not do
-      an AND.  */
-   else if (code == AND && GET_CODE (op1) == CONST_INT
- 	   && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
- 	   && (nonzero_bits (op0, mode) & ~INTVAL (op1)) == 0)
-     return op0;
- 
-   return gen_rtx_fmt_ee (code, mode, op0, op1);
- }
- \f
  /* Simplify a comparison between *POP0 and *POP1 where CODE is the
     comparison code that will be tested.
  
--- 9333,9338 ----
***************
*** 10152,10160 ****
  		  && c1 != mask
  		  && c1 != GET_MODE_MASK (tmode))
  		{
! 		  op0 = gen_binary (AND, tmode,
! 				    SUBREG_REG (XEXP (op0, 0)),
! 				    gen_int_mode (c1, tmode));
  		  op0 = gen_lowpart (mode, op0);
  		  continue;
  		}
--- 10167,10175 ----
  		  && c1 != mask
  		  && c1 != GET_MODE_MASK (tmode))
  		{
! 		  op0 = simplify_gen_binary (AND, tmode,
! 					     SUBREG_REG (XEXP (op0, 0)),
! 					     gen_int_mode (c1, tmode));
  		  op0 = gen_lowpart (mode, op0);
  		  continue;
  		}
***************
*** 10298,10309 ****
  	    {
  	      rtx inner = XEXP (XEXP (XEXP (op0, 0), 0), 0);
  	      rtx add_const = XEXP (XEXP (op0, 0), 1);
! 	      rtx new_const = gen_binary (ASHIFTRT, GET_MODE (op0), add_const,
! 					  XEXP (op0, 1));
  
! 	      op0 = gen_binary (PLUS, tmode,
! 				gen_lowpart (tmode, inner),
! 				new_const);
  	      continue;
  	    }
  
--- 10313,10324 ----
  	    {
  	      rtx inner = XEXP (XEXP (XEXP (op0, 0), 0), 0);
  	      rtx add_const = XEXP (XEXP (op0, 0), 1);
! 	      rtx new_const = simplify_gen_binary (ASHIFTRT, GET_MODE (op0),
! 						   add_const, XEXP (op0, 1));
  
! 	      op0 = simplify_gen_binary (PLUS, tmode,
! 					 gen_lowpart (tmode, inner),
! 					 new_const);
  	      continue;
  	    }
  
***************
*** 10456,10466 ****
  		 make a new AND in the proper mode.  */
  	      if (GET_CODE (op0) == AND
  		  && !have_insn_for (AND, mode))
! 		op0 = gen_binary (AND, tmode,
! 				  gen_lowpart (tmode,
! 					       XEXP (op0, 0)),
! 				  gen_lowpart (tmode,
! 					       XEXP (op0, 1)));
  
  	      op0 = gen_lowpart (tmode, op0);
  	      if (zero_extended && GET_CODE (op1) == CONST_INT)
--- 10471,10481 ----
  		 make a new AND in the proper mode.  */
  	      if (GET_CODE (op0) == AND
  		  && !have_insn_for (AND, mode))
! 		op0 = simplify_gen_binary (AND, tmode,
! 					   gen_lowpart (tmode,
! 							XEXP (op0, 0)),
! 					   gen_lowpart (tmode,
! 							XEXP (op0, 1)));
  
  	      op0 = gen_lowpart (tmode, op0);
  	      if (zero_extended && GET_CODE (op1) == CONST_INT)
***************
*** 10475,10484 ****
  	  if (op1 == const0_rtx && (code == LT || code == GE)
  	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
  	    {
! 	      op0 = gen_binary (AND, tmode,
! 				gen_lowpart (tmode, op0),
! 				GEN_INT ((HOST_WIDE_INT) 1
! 					 << (GET_MODE_BITSIZE (mode) - 1)));
  	      code = (code == LT) ? NE : EQ;
  	      break;
  	    }
--- 10490,10500 ----
  	  if (op1 == const0_rtx && (code == LT || code == GE)
  	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
  	    {
! 	      op0 = simplify_gen_binary (AND, tmode,
! 					 gen_lowpart (tmode, op0),
! 					 GEN_INT ((HOST_WIDE_INT) 1
! 						  << (GET_MODE_BITSIZE (mode)
! 						      - 1)));
  	      code = (code == LT) ? NE : EQ;
  	      break;
  	    }
***************
*** 10525,10531 ****
    if (reversed_code == UNKNOWN)
      return NULL_RTX;
    else
!     return gen_binary (reversed_code, mode, op0, op1);
  }
  \f
  /* Utility function for following routine.  Called when X is part of a value
--- 10541,10547 ----
    if (reversed_code == UNKNOWN)
      return NULL_RTX;
    else
!     return simplify_gen_relational (reversed_code, mode, VOIDmode, op0, op1);
  }
  \f
  /* Utility function for following routine.  Called when X is part of a value

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFT/RFA: Eliminate gen_binary, take 2
  2004-06-09  9:21   ` Paolo Bonzini
  2004-06-09  9:36     ` Paolo Bonzini
@ 2004-06-10  7:17     ` Eric Botcazou
  2004-06-10  8:16       ` Paolo Bonzini
  1 sibling, 1 reply; 11+ messages in thread
From: Eric Botcazou @ 2004-06-10  7:17 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: GCC Patches

> Here it is.

I've found the problem: for some reason, the diff doesn't contain the page 
delimiter (see line 9335 for example) so patch rejects it.

Would you mind checking that it is present in the original diff and, if so, 
repost the patch gzipped?

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFT/RFA: Eliminate gen_binary, take 2
  2004-06-10  7:17     ` Eric Botcazou
@ 2004-06-10  8:16       ` Paolo Bonzini
  2004-06-10 11:16         ` Eric Botcazou
  0 siblings, 1 reply; 11+ messages in thread
From: Paolo Bonzini @ 2004-06-10  8:16 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: Paolo Bonzini, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 127 bytes --]

> Would you mind checking that it is present in the original diff and, if so, 
> repost the patch gzipped?

Here it is.

Paolo

[-- Attachment #2: combine-kill-gen-binary-take-4.patch.gz --]
[-- Type: application/gzip, Size: 9073 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFT/RFA: Eliminate gen_binary, take 2
  2004-06-10  8:16       ` Paolo Bonzini
@ 2004-06-10 11:16         ` Eric Botcazou
  0 siblings, 0 replies; 11+ messages in thread
From: Eric Botcazou @ 2004-06-10 11:16 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: GCC Patches

> Here it is.

Victory :-)

Now asking the SPARC boxes what they think about it...

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFT/RFA: Eliminate gen_binary, take 2
  2004-06-08 16:42 RFT/RFA: Eliminate gen_binary, take 2 Paolo Bonzini
  2004-06-08 21:13 ` Roger Sayle
  2004-06-08 21:51 ` Eric Botcazou
@ 2004-06-10 12:34 ` Eric Botcazou
  2004-06-10 12:48   ` Paolo Bonzini
  2 siblings, 1 reply; 11+ messages in thread
From: Eric Botcazou @ 2004-06-10 12:34 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: GCC Patches

> This version was bootstrapped/regtested i686-pc-linux-gnu, a very
> similar one was tested on sparc-sun-solaris2.8, and this one passes the
> testcase that Eric Botcazou had distilled; but experience with the
> previous patch clearly showed that "very similar" is not enough, so even
> if approved I'll let a week pass so that people can test it and mail
> results.

Appears to miscompile the C++ compiler on sparc-sun-solaris2.8:

In file included from /home/eric/cvs/gcc/libstdc++-v3/libsupc++/new:42,
                 from /home/eric/cvs/gcc/libstdc++-v3/libsupc++/del_op.cc:31:
/home/eric/cvs/gcc/libstdc++-v3/libsupc++/exception:56: error: expected 
unqualified-id before "virtual"
/home/eric/cvs/gcc/libstdc++-v3/libsupc++/exception:59: error: expected 
unqualified-id before "virtual"
/home/eric/cvs/gcc/libstdc++-v3/libsupc++/exception:70: error: expected 
unqualified-id before "virtual"
In file included from /home/eric/cvs/gcc/libstdc++-v3/libsupc++/del_op.cc:31:
/home/eric/cvs/gcc/libstdc++-v3/libsupc++/new:59: error: expected 
unqualified-id before "virtual"
/home/eric/cvs/gcc/libstdc++-v3/libsupc++/new:63: internal compiler error: in 
cp_parser_type_specifier, at cp/parser.c:8917
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
gmake[4]: *** [del_op.lo] Error 1
gmake[4]: Leaving directory 
`/opt/build/eric/gcc/sparc-sun-solaris2.8/libstdc++-v3/libsupc++'
gmake[3]: *** [all-recursive] Error 1
gmake[3]: Leaving directory 
`/opt/build/eric/gcc/sparc-sun-solaris2.8/libstdc++-v3'
gmake[2]: *** [all] Error 2
gmake[2]: Leaving directory 
`/opt/build/eric/gcc/sparc-sun-solaris2.8/libstdc++-v3'
gmake[1]: *** [all-target-libstdc++-v3] Error 2
gmake[1]: Leaving directory `/opt/build/eric/gcc'
gmake: *** [bootstrap] Error 2


sparc64-sun-solaris2.9 with the same sources (20040606, I heard rumours 
that SPARC has again been broken in the meantime) is not affected.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFT/RFA: Eliminate gen_binary, take 2
  2004-06-10 12:34 ` Eric Botcazou
@ 2004-06-10 12:48   ` Paolo Bonzini
  2004-06-10 23:30     ` Eric Botcazou
  0 siblings, 1 reply; 11+ messages in thread
From: Paolo Bonzini @ 2004-06-10 12:48 UTC (permalink / raw)
  To: Eric Botcazou, gcc-patches

> Appears to miscompile the C++ compiler on sparc-sun-solaris2.8:

grm.  Ok, I'll try to synthesize a test case myself (not so hard because 
ideally the patch should not at all change the RTL/assembly output).  Do 
not hurry, it is nothing extremely high priority. :-)

Paolo

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: RFT/RFA: Eliminate gen_binary, take 2
  2004-06-10 12:48   ` Paolo Bonzini
@ 2004-06-10 23:30     ` Eric Botcazou
  0 siblings, 0 replies; 11+ messages in thread
From: Eric Botcazou @ 2004-06-10 23:30 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 344 bytes --]

> grm.  Ok, I'll try to synthesize a test case myself (not so hard because
> ideally the patch should not at all change the RTL/assembly output).  Do
> not hurry, it is nothing extremely high priority. :-)

Well, I'm starting to get used to doing it :-)

Same story, the combiner completely butchers the RTL at -O1 and above.

-- 
Eric Botcazou

[-- Attachment #2: parser.c.gz --]
[-- Type: application/x-gzip, Size: 17548 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2004-06-10 21:42 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-06-08 16:42 RFT/RFA: Eliminate gen_binary, take 2 Paolo Bonzini
2004-06-08 21:13 ` Roger Sayle
2004-06-08 21:51 ` Eric Botcazou
2004-06-09  9:21   ` Paolo Bonzini
2004-06-09  9:36     ` Paolo Bonzini
2004-06-10  7:17     ` Eric Botcazou
2004-06-10  8:16       ` Paolo Bonzini
2004-06-10 11:16         ` Eric Botcazou
2004-06-10 12:34 ` Eric Botcazou
2004-06-10 12:48   ` Paolo Bonzini
2004-06-10 23:30     ` Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).