mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-12 02:44:34 +08:00
combine.c (gen_binary): Remove.
2004-05-25 Paolo Bonzini <bonzini@gnu.org> * combine.c (gen_binary): Remove. (known_cond, simplify_shift_const find_split_point, combine_simplify_rtx, simplify_if_then_else, simplify_set, simplify_logical, expand_field_assignment, extract_left_shift, force_to_mode, if_then_else_cond, apply_distributive_law, simplify_and_const_int, simplify_shift_const, gen_lowpart_for_combine, simplify_comparison, reversed_comparison): Replace with simplify_gen_binary, simplify_gen_relational or distribute_and_simplify_rtx. (distribute_and_simplify_rtx): New function. * simplify-rtx.c (simplify_binary_operation): Use nonzero_bits to simplify ANDs where we are turning off bits already known to be off in OP0. From-SVN: r82317
This commit is contained in:
parent
42f806e5a0
commit
dce1438a65
@ -1,3 +1,22 @@
|
||||
2004-05-25 Paolo Bonzini <bonzini@gnu.org>
|
||||
|
||||
* combine.c (gen_binary): Remove.
|
||||
(known_cond, simplify_shift_const
|
||||
find_split_point, combine_simplify_rtx,
|
||||
simplify_if_then_else, simplify_set,
|
||||
simplify_logical, expand_field_assignment,
|
||||
extract_left_shift, force_to_mode,
|
||||
if_then_else_cond, apply_distributive_law,
|
||||
simplify_and_const_int, simplify_shift_const,
|
||||
gen_lowpart_for_combine, simplify_comparison,
|
||||
reversed_comparison): Replace with
|
||||
simplify_gen_binary, simplify_gen_relational or
|
||||
distribute_and_simplify_rtx.
|
||||
(distribute_and_simplify_rtx): New function.
|
||||
* simplify-rtx.c (simplify_binary_operation):
|
||||
Use nonzero_bits to simplify ANDs where we are
|
||||
turning off bits already known to be off in OP0.
|
||||
|
||||
2004-05-27 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
PR target/14478
|
||||
|
518
gcc/combine.c
518
gcc/combine.c
@ -372,6 +372,7 @@ static rtx known_cond (rtx, enum rtx_code, rtx, rtx);
|
||||
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,7 +381,6 @@ static rtx simplify_shift_const (rtx, enum rtx_code, enum machine_mode, rtx,
|
||||
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);
|
||||
@ -3017,14 +3017,16 @@ find_split_point (rtx *loc, rtx insn)
|
||||
|
||||
if (src == mask)
|
||||
SUBST (SET_SRC (x),
|
||||
gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
|
||||
simplify_gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
|
||||
else
|
||||
{
|
||||
rtx negmask = gen_int_mode (~(mask << pos), mode);
|
||||
SUBST (SET_SRC (x),
|
||||
gen_binary (IOR, mode,
|
||||
gen_binary (AND, mode, dest,
|
||||
gen_int_mode (~(mask << pos),
|
||||
mode)),
|
||||
simplify_gen_binary (IOR, mode,
|
||||
simplify_gen_binary (AND, mode,
|
||||
dest, negmask),
|
||||
GEN_INT (src << pos)));
|
||||
}
|
||||
|
||||
SUBST (SET_DEST (x), dest);
|
||||
|
||||
@ -3599,7 +3601,7 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
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));
|
||||
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,12 +3658,14 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
/* 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);
|
||||
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 = gen_binary (reversed, mode, cond, cop1);
|
||||
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,8 +3673,9 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
&& INTVAL (true_rtx) == - STORE_FLAG_VALUE
|
||||
&& false_rtx == const0_rtx)
|
||||
x = simplify_gen_unary (NEG, mode,
|
||||
gen_binary (cond_code, mode, cond,
|
||||
cop1),
|
||||
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,13 +3684,17 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
(cond_code, cond, cop1, NULL))
|
||||
!= UNKNOWN))
|
||||
x = simplify_gen_unary (NEG, mode,
|
||||
gen_binary (reversed, mode,
|
||||
simplify_gen_relational (reversed,
|
||||
mode, VOIDmode,
|
||||
cond, cop1),
|
||||
mode);
|
||||
else
|
||||
return gen_rtx_IF_THEN_ELSE (mode,
|
||||
gen_binary (cond_code, VOIDmode,
|
||||
cond, cop1),
|
||||
simplify_gen_relational (cond_code,
|
||||
mode,
|
||||
VOIDmode,
|
||||
cond,
|
||||
cop1),
|
||||
true_rtx, false_rtx);
|
||||
|
||||
code = GET_CODE (x);
|
||||
@ -3788,7 +3797,7 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
}
|
||||
|
||||
if (inner)
|
||||
return gen_binary (code, mode, other, inner);
|
||||
return simplify_gen_binary (code, mode, other, inner);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3890,7 +3899,8 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
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);
|
||||
return simplify_gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
|
||||
constm1_rtx);
|
||||
|
||||
temp = expand_compound_operation (XEXP (x, 0));
|
||||
|
||||
@ -4118,8 +4128,9 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
|
||||
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));
|
||||
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,8 +4139,9 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
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),
|
||||
return simplify_gen_binary (PLUS, mode,
|
||||
simplify_gen_binary (PLUS, mode,
|
||||
XEXP (XEXP (x, 0), 0),
|
||||
XEXP (x, 1)),
|
||||
XEXP (XEXP (x, 0), 1));
|
||||
|
||||
@ -4197,7 +4209,7 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
& 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));
|
||||
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,7 +4249,9 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
|
||||
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),
|
||||
return simplify_gen_binary (PLUS, mode,
|
||||
simplify_gen_binary (MULT, mode,
|
||||
in1, in2),
|
||||
XEXP (x, 0));
|
||||
}
|
||||
|
||||
@ -4250,15 +4264,18 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
|
||||
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),
|
||||
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 gen_binary (MINUS, mode,
|
||||
gen_binary (MINUS, mode, XEXP (x, 0),
|
||||
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;
|
||||
@ -4270,17 +4287,11 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
|
||||
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;
|
||||
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,7 +4300,7 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
XEXP (XEXP (x, 0), 0),
|
||||
XEXP (x, 1));
|
||||
if (tem)
|
||||
return gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
|
||||
return simplify_gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -4369,7 +4380,7 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
&& nonzero_bits (op0, mode) == 1)
|
||||
{
|
||||
op0 = expand_compound_operation (op0);
|
||||
return gen_binary (XOR, mode,
|
||||
return simplify_gen_binary (XOR, mode,
|
||||
gen_lowpart (mode, op0),
|
||||
const1_rtx);
|
||||
}
|
||||
@ -4614,7 +4625,8 @@ simplify_if_then_else (rtx x)
|
||||
|
||||
/* 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));
|
||||
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,16 +4776,16 @@ simplify_if_then_else (rtx x)
|
||||
{
|
||||
case GE:
|
||||
case GT:
|
||||
return gen_binary (SMAX, mode, true_rtx, false_rtx);
|
||||
return simplify_gen_binary (SMAX, mode, true_rtx, false_rtx);
|
||||
case LE:
|
||||
case LT:
|
||||
return gen_binary (SMIN, mode, true_rtx, false_rtx);
|
||||
return simplify_gen_binary (SMIN, mode, true_rtx, false_rtx);
|
||||
case GEU:
|
||||
case GTU:
|
||||
return gen_binary (UMAX, mode, true_rtx, false_rtx);
|
||||
return simplify_gen_binary (UMAX, mode, true_rtx, false_rtx);
|
||||
case LEU:
|
||||
case LTU:
|
||||
return gen_binary (UMIN, mode, true_rtx, false_rtx);
|
||||
return simplify_gen_binary (UMIN, mode, true_rtx, false_rtx);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -4886,12 +4898,14 @@ simplify_if_then_else (rtx x)
|
||||
|
||||
if (z)
|
||||
{
|
||||
temp = subst (gen_binary (true_code, m, cond_op0, cond_op1),
|
||||
temp = subst (simplify_gen_relational (true_code, m, VOIDmode,
|
||||
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 = 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 = gen_binary (op, m, gen_lowpart (m, z), temp);
|
||||
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,7 +5090,8 @@ simplify_set (rtx x)
|
||||
PUT_CODE (*cc_use, old_code);
|
||||
other_changed = 0;
|
||||
|
||||
op0 = gen_binary (XOR, GET_MODE (op0), op0, GEN_INT (mask));
|
||||
op0 = simplify_gen_binary (XOR, GET_MODE (op0),
|
||||
op0, GEN_INT (mask));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5240,17 +5255,18 @@ simplify_set (rtx x)
|
||||
&& 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),
|
||||
term2 = simplify_gen_binary (AND, GET_MODE (src),
|
||||
XEXP (XEXP (src, 0), 0), true_rtx);
|
||||
term3 = gen_binary (AND, GET_MODE (src),
|
||||
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),
|
||||
gen_binary (IOR, GET_MODE (src),
|
||||
gen_binary (IOR, GET_MODE (src), term1, term2),
|
||||
simplify_gen_binary (IOR, GET_MODE (src),
|
||||
simplify_gen_binary (IOR, GET_MODE (src),
|
||||
term1, term2),
|
||||
term3));
|
||||
|
||||
src = SET_SRC (x);
|
||||
@ -5286,15 +5302,17 @@ simplify_logical (rtx x)
|
||||
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),
|
||||
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 = gen_binary (AND, mode,
|
||||
simplify_gen_unary (NOT, mode, XEXP (op0, 0), mode),
|
||||
x = simplify_gen_binary (AND, mode,
|
||||
simplify_gen_unary (NOT, mode,
|
||||
XEXP (op0, 0), mode),
|
||||
op1);
|
||||
|
||||
/* Similarly for (~(A ^ B)) & A. */
|
||||
@ -5302,13 +5320,13 @@ simplify_logical (rtx x)
|
||||
&& 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);
|
||||
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 = gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), 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,8 +5346,9 @@ simplify_logical (rtx x)
|
||||
&& 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),
|
||||
return simplify_gen_binary (IOR, mode,
|
||||
simplify_gen_binary
|
||||
(AND, mode, XEXP (op0, 0),
|
||||
GEN_INT (INTVAL (XEXP (op0, 1))
|
||||
& ~INTVAL (op1))), op1);
|
||||
|
||||
@ -5348,54 +5367,16 @@ simplify_logical (rtx x)
|
||||
&& ! 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)
|
||||
/* 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)
|
||||
{
|
||||
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;
|
||||
rtx result = distribute_and_simplify_rtx (x);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
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:
|
||||
@ -5416,28 +5397,11 @@ simplify_logical (rtx x)
|
||||
/* 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)
|
||||
if (GET_CODE (op0) == AND || GET_CODE (op1) == 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;
|
||||
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,7 +5450,7 @@ simplify_logical (rtx x)
|
||||
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));
|
||||
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,7 +5470,8 @@ simplify_logical (rtx x)
|
||||
}
|
||||
else if (num_negated == 1)
|
||||
return
|
||||
simplify_gen_unary (NOT, mode, gen_binary (XOR, mode, op0, op1),
|
||||
simplify_gen_unary (NOT, mode,
|
||||
simplify_gen_binary (XOR, mode, op0, op1),
|
||||
mode);
|
||||
}
|
||||
|
||||
@ -5517,15 +5482,17 @@ simplify_logical (rtx x)
|
||||
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),
|
||||
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 gen_binary (AND, mode,
|
||||
simplify_gen_unary (NOT, mode, XEXP (op0, 1), mode),
|
||||
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
|
||||
@ -5795,7 +5762,7 @@ expand_field_assignment (rtx x)
|
||||
rtx inner;
|
||||
rtx pos; /* Always counts from low bit. */
|
||||
int len;
|
||||
rtx mask;
|
||||
rtx mask, cleared, masked;
|
||||
enum machine_mode compute_mode;
|
||||
|
||||
/* Loop until we find something we can't simplify. */
|
||||
@ -5833,8 +5800,9 @@ expand_field_assignment (rtx x)
|
||||
/* 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))
|
||||
pos = simplify_gen_binary (MINUS, GET_MODE (pos),
|
||||
GEN_INT (GET_MODE_BITSIZE (
|
||||
GET_MODE (inner))
|
||||
- len),
|
||||
pos);
|
||||
}
|
||||
@ -5883,30 +5851,30 @@ expand_field_assignment (rtx x)
|
||||
}
|
||||
|
||||
/* 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
|
||||
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. */
|
||||
x = gen_rtx_SET
|
||||
(VOIDmode, copy_rtx (inner),
|
||||
gen_binary (IOR, compute_mode,
|
||||
gen_binary (AND, compute_mode,
|
||||
mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1);
|
||||
cleared = simplify_gen_binary (AND, compute_mode,
|
||||
simplify_gen_unary (NOT, compute_mode,
|
||||
gen_binary (ASHIFT,
|
||||
simplify_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)),
|
||||
inner);
|
||||
masked = simplify_gen_binary (ASHIFT, compute_mode,
|
||||
simplify_gen_binary (
|
||||
AND, compute_mode,
|
||||
gen_lowpart (compute_mode, SET_SRC (x)),
|
||||
mask),
|
||||
pos)));
|
||||
pos);
|
||||
|
||||
x = gen_rtx_SET (VOIDmode, copy_rtx (inner),
|
||||
simplify_gen_binary (IOR, compute_mode,
|
||||
cleared, masked));
|
||||
}
|
||||
|
||||
return x;
|
||||
@ -6362,7 +6330,7 @@ extract_left_shift (rtx x, int count)
|
||||
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,
|
||||
return simplify_gen_binary (code, mode, tem,
|
||||
GEN_INT (INTVAL (XEXP (x, 1)) >> count));
|
||||
|
||||
break;
|
||||
@ -6854,7 +6822,8 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
|
||||
&& (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));
|
||||
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,9 +6915,9 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
|
||||
{
|
||||
temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask)
|
||||
<< INTVAL (XEXP (XEXP (x, 0), 1)));
|
||||
temp = gen_binary (GET_CODE (x), GET_MODE (x),
|
||||
temp = simplify_gen_binary (GET_CODE (x), GET_MODE (x),
|
||||
XEXP (XEXP (x, 0), 0), temp);
|
||||
x = gen_binary (LSHIFTRT, GET_MODE (x), 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,7 +6934,7 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
|
||||
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);
|
||||
x = simplify_gen_binary (code, op_mode, op0, op1);
|
||||
break;
|
||||
|
||||
case ASHIFT:
|
||||
@ -6999,7 +6968,7 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
|
||||
mask, reg, next_select));
|
||||
|
||||
if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
|
||||
x = gen_binary (code, op_mode, op0, XEXP (x, 1));
|
||||
x = simplify_gen_binary (code, op_mode, op0, XEXP (x, 1));
|
||||
break;
|
||||
|
||||
case LSHIFTRT:
|
||||
@ -7027,7 +6996,7 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
|
||||
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));
|
||||
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,7 +7018,7 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
|
||||
/* 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),
|
||||
x = simplify_gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0),
|
||||
GEN_INT (GET_MODE_BITSIZE (GET_MODE (x))
|
||||
- exact_log2 (mask + 1)));
|
||||
|
||||
@ -7116,7 +7085,8 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
|
||||
/* 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));
|
||||
x = simplify_gen_binary (LSHIFTRT, GET_MODE (x),
|
||||
XEXP (x, 0), XEXP (x, 1));
|
||||
|
||||
shiftrt:
|
||||
|
||||
@ -7181,8 +7151,10 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
|
||||
{
|
||||
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));
|
||||
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,8 +7264,19 @@ if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse)
|
||||
else if (cond1 == 0)
|
||||
true1 = copy_rtx (true1);
|
||||
|
||||
*ptrue = gen_binary (code, mode, true0, true1);
|
||||
*pfalse = gen_binary (code, mode, false0, false1);
|
||||
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,11 +7306,11 @@ if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse)
|
||||
&& 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,
|
||||
*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)
|
||||
? simplify_gen_unary (NEG, mode,
|
||||
op1, mode)
|
||||
: op1),
|
||||
const_true_rtx);
|
||||
return cond0;
|
||||
@ -7833,7 +7816,7 @@ apply_distributive_law (rtx x)
|
||||
|| GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD)
|
||||
return x;
|
||||
|
||||
tem = gen_binary (code, GET_MODE (SUBREG_REG (lhs)),
|
||||
tem = simplify_gen_binary (code, GET_MODE (SUBREG_REG (lhs)),
|
||||
SUBREG_REG (lhs), SUBREG_REG (rhs));
|
||||
return gen_lowpart (GET_MODE (x), tem);
|
||||
|
||||
@ -7860,7 +7843,7 @@ apply_distributive_law (rtx x)
|
||||
return x;
|
||||
|
||||
/* Form the new inner operation, seeing if it simplifies first. */
|
||||
tem = gen_binary (code, GET_MODE (x), lhs, rhs);
|
||||
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,9 +7856,96 @@ apply_distributive_law (rtx x)
|
||||
/* 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),
|
||||
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, op1);
|
||||
new_op1 = simplify_gen_binary (IOR, mode, inner_op1, op1);
|
||||
x = apply_distributive_law (simplify_gen_binary (XOR, mode,
|
||||
new_op0, new_op1));
|
||||
|
||||
if (GET_CODE (x) != AND)
|
||||
return x;
|
||||
}
|
||||
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, op0);
|
||||
new_op1 = simplify_gen_binary (IOR, mode, inner_op1, op0);
|
||||
x = apply_distributive_law (simplify_gen_binary (XOR, mode,
|
||||
new_op0, new_op1));
|
||||
|
||||
if (GET_CODE (x) != AND)
|
||||
return x;
|
||||
}
|
||||
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
|
||||
in MODE.
|
||||
@ -7941,11 +8011,15 @@ simplify_and_const_int (rtx x, enum machine_mode mode, rtx varop,
|
||||
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))));
|
||||
(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,7 +8060,7 @@ simplify_and_const_int (rtx x, enum machine_mode mode, rtx varop,
|
||||
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));
|
||||
x = simplify_gen_binary (AND, mode, varop, GEN_INT (constop));
|
||||
|
||||
else
|
||||
{
|
||||
@ -8505,8 +8579,10 @@ simplify_shift_const (rtx x, enum rtx_code code,
|
||||
&& 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)))));
|
||||
= simplify_gen_binary (ASHIFT, GET_MODE (varop),
|
||||
XEXP (varop, 0),
|
||||
GEN_INT (exact_log2 (
|
||||
INTVAL (XEXP (varop, 1)))));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@ -8517,8 +8593,10 @@ simplify_shift_const (rtx x, enum rtx_code code,
|
||||
&& 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)))));
|
||||
= simplify_gen_binary (LSHIFTRT, GET_MODE (varop),
|
||||
XEXP (varop, 0),
|
||||
GEN_INT (exact_log2 (
|
||||
INTVAL (XEXP (varop, 1)))));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@ -8763,7 +8841,7 @@ simplify_shift_const (rtx x, enum rtx_code code,
|
||||
logical expression, make a new logical expression, and apply
|
||||
the inverse distributive law. This also can't be done
|
||||
for some (ashiftrt (xor)). */
|
||||
if (code != ASHIFTRT || GET_CODE (varop)!= XOR
|
||||
if (code != ASHIFTRT || GET_CODE (varop) != XOR
|
||||
|| 0 <= trunc_int_for_mode (INTVAL (XEXP (varop, 1)),
|
||||
shift_mode))
|
||||
{
|
||||
@ -8772,7 +8850,8 @@ simplify_shift_const (rtx x, enum rtx_code code,
|
||||
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 = simplify_gen_binary (GET_CODE (varop), shift_mode,
|
||||
lhs, rhs);
|
||||
varop = apply_distributive_law (varop);
|
||||
|
||||
count = 0;
|
||||
@ -9026,7 +9105,8 @@ simplify_shift_const (rtx x, enum rtx_code code,
|
||||
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));
|
||||
x = simplify_gen_binary (outer_op, result_mode, x,
|
||||
GEN_INT (outer_const));
|
||||
}
|
||||
|
||||
return x;
|
||||
@ -9259,63 +9339,6 @@ gen_lowpart_for_combine (enum machine_mode mode, rtx x)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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.
|
||||
|
||||
@ -10150,7 +10173,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
|
||||
&& c1 != mask
|
||||
&& c1 != GET_MODE_MASK (tmode))
|
||||
{
|
||||
op0 = gen_binary (AND, tmode,
|
||||
op0 = simplify_gen_binary (AND, tmode,
|
||||
SUBREG_REG (XEXP (op0, 0)),
|
||||
gen_int_mode (c1, tmode));
|
||||
op0 = gen_lowpart (mode, op0);
|
||||
@ -10296,10 +10319,10 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
|
||||
{
|
||||
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));
|
||||
rtx new_const = simplify_gen_binary (ASHIFTRT, GET_MODE (op0),
|
||||
add_const, XEXP (op0, 1));
|
||||
|
||||
op0 = gen_binary (PLUS, tmode,
|
||||
op0 = simplify_gen_binary (PLUS, tmode,
|
||||
gen_lowpart (tmode, inner),
|
||||
new_const);
|
||||
continue;
|
||||
@ -10454,7 +10477,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
|
||||
make a new AND in the proper mode. */
|
||||
if (GET_CODE (op0) == AND
|
||||
&& !have_insn_for (AND, mode))
|
||||
op0 = gen_binary (AND, tmode,
|
||||
op0 = simplify_gen_binary (AND, tmode,
|
||||
gen_lowpart (tmode,
|
||||
XEXP (op0, 0)),
|
||||
gen_lowpart (tmode,
|
||||
@ -10473,10 +10496,11 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
|
||||
if (op1 == const0_rtx && (code == LT || code == GE)
|
||||
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
op0 = gen_binary (AND, tmode,
|
||||
op0 = simplify_gen_binary (AND, tmode,
|
||||
gen_lowpart (tmode, op0),
|
||||
GEN_INT ((HOST_WIDE_INT) 1
|
||||
<< (GET_MODE_BITSIZE (mode) - 1)));
|
||||
<< (GET_MODE_BITSIZE (mode)
|
||||
- 1)));
|
||||
code = (code == LT) ? NE : EQ;
|
||||
break;
|
||||
}
|
||||
@ -10523,7 +10547,7 @@ reversed_comparison (rtx exp, enum machine_mode mode, rtx op0, rtx op1)
|
||||
if (reversed_code == UNKNOWN)
|
||||
return NULL_RTX;
|
||||
else
|
||||
return gen_binary (reversed_code, mode, op0, op1);
|
||||
return simplify_gen_relational (reversed_code, mode, VOIDmode, op0, op1);
|
||||
}
|
||||
|
||||
/* Utility function for following routine. Called when X is part of a value
|
||||
|
@ -1844,9 +1844,11 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
|
||||
case AND:
|
||||
if (trueop1 == const0_rtx && ! side_effects_p (op0))
|
||||
return const0_rtx;
|
||||
/* If we are turning off bits already known off in OP0, we need
|
||||
not do an AND. */
|
||||
if (GET_CODE (trueop1) == CONST_INT
|
||||
&& ((INTVAL (trueop1) & GET_MODE_MASK (mode))
|
||||
== GET_MODE_MASK (mode)))
|
||||
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
|
||||
&& (nonzero_bits (trueop0, mode) & ~INTVAL (trueop1)) == 0)
|
||||
return op0;
|
||||
if (trueop0 == trueop1 && ! side_effects_p (op0)
|
||||
&& GET_MODE_CLASS (mode) != MODE_CC)
|
||||
|
Loading…
Reference in New Issue
Block a user