From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12813 invoked by alias); 9 Jun 2004 07:21:04 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 12690 invoked from network); 9 Jun 2004 07:20:56 -0000 Received: from unknown (HELO main.gmane.org) (80.91.224.249) by sourceware.org with SMTP; 9 Jun 2004 07:20:56 -0000 Received: from list by main.gmane.org with local (Exim 3.35 #1 (Debian)) id 1BXxOJ-0005ez-00 for ; Wed, 09 Jun 2004 09:20:55 +0200 Received: from paride.rett.polimi.it ([131.175.65.135]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 09 Jun 2004 09:20:55 +0200 Received: from bonzini by paride.rett.polimi.it with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 09 Jun 2004 09:20:55 +0200 To: gcc-patches@gcc.gnu.org From: Paolo Bonzini Subject: Re: RFT/RFA: Eliminate gen_binary, take 2 Date: Wed, 09 Jun 2004 09:21:00 -0000 Message-ID: <40C6BAF5.6020201@gnu.org> References: <40C5CF10.8040404@polimi.it> <200406082314.40908.ebotcazou@libertysurf.fr> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------030208060307020309040203" X-Complaints-To: usenet@sea.gmane.org Cc: GCC Patches X-Gmane-NNTP-Posting-Host: paride.rett.polimi.it User-Agent: Mozilla Thunderbird 0.5 (Windows/20040207) In-Reply-To: <200406082314.40908.ebotcazou@libertysurf.fr> X-SW-Source: 2004-06/txt/msg00498.txt.bz2 This is a multi-part message in MIME format. --------------030208060307020309040203 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 195 > 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 --------------030208060307020309040203 Content-Type: text/plain; name="combine-kill-gen-binary-take-4.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="combine-kill-gen-binary-take-4.patch" Content-length: 49569 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 (const_int pow2 - 1)) ) <-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 (const_int pow2 - 1)) ) <-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); } /* 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; } /* 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 **** } } - /* 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); - } - /* 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); } /* 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); } /* Utility function for following routine. Called when X is part of a value --------------030208060307020309040203-- From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12829 invoked by alias); 9 Jun 2004 07:21:06 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 12724 invoked from network); 9 Jun 2004 07:20:58 -0000 Received: from unknown (HELO mail.polimi.it) (131.175.12.67) by sourceware.org with SMTP; 9 Jun 2004 07:20:58 -0000 Received: from gnu.org (paride.rett.polimi.it [131.175.65.135]) (authenticated bits=0) by mail.polimi.it (Switch-3.0.5/Switch-3.0.0) with ESMTP id i597KpAV029817; Wed, 9 Jun 2004 09:20:52 +0200 (MEST) Message-ID: <40C6BAF5.6020201@gnu.org> Date: Wed, 09 Jun 2004 09:36:00 -0000 From: Paolo Bonzini User-Agent: Mozilla Thunderbird 0.5 (Windows/20040207) MIME-Version: 1.0 Newsgroups: gmane.comp.gcc.patches To: Eric Botcazou CC: GCC Patches Subject: Re: RFT/RFA: Eliminate gen_binary, take 2 References: <40C5CF10.8040404@polimi.it> <200406082314.40908.ebotcazou@libertysurf.fr> In-Reply-To: <200406082314.40908.ebotcazou@libertysurf.fr> Content-Type: multipart/mixed; boundary="------------030208060307020309040203" X-PMX-Version: 4.6.0.99824, Antispam-Core: 4.6.0.99824, Antispam-Data: 2004.6.8.102929 X-PerlMx-Spam: Gauge=IIIIIIII, Probability=8%, Report='LINES_OF_YELLING 0.001, __HAS_MSGID 0, __SANE_MSGID 0, __USER_AGENT 0, X_ACCEPT_LANG 0, __MIME_VERSION 0, __TO_MALFORMED_2 0, __REFERENCES 0, __IN_REP_TO 0, __CT 0, __CTYPE_HAS_BOUNDARY 0, __CTYPE_MULTIPART 0, __BAT_BOUNDARY 0, __UNUSABLE_MSGID 0, __MOZILLA_MSGID 0, __MIME_TEXT_ONLY 0, REFERENCES 0.000, IN_REP_TO 0, USER_AGENT 0.000' X-SW-Source: 2004-06/txt/msg00499.txt.bz2 Message-ID: <20040609093600.GjGLHVSFcp5ErqV-bCCbH8Ka4EaA89MUKMBvrM5VQBU@z> This is a multi-part message in MIME format. --------------030208060307020309040203 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 195 > 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 --------------030208060307020309040203 Content-Type: text/plain; name="combine-kill-gen-binary-take-4.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="combine-kill-gen-binary-take-4.patch" Content-length: 49569 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 (const_int pow2 - 1)) ) <-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 (const_int pow2 - 1)) ) <-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); } /* 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; } /* 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 **** } } - /* 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); - } - /* 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); } /* 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); } /* Utility function for following routine. Called when X is part of a value --------------030208060307020309040203--