revert: combine.c (gen_binary): Remove.

2004-05-31  Paolo Bonzini  <bonzini@gnu.org>

	Revert this patch:
	2004-05-27  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.

From-SVN: r82475
This commit is contained in:
Paolo Bonzini 2004-05-31 06:59:47 +00:00 committed by Paolo Bonzini
parent 97509a89b1
commit 1999435c8a
2 changed files with 315 additions and 320 deletions

View File

@ -1,3 +1,22 @@
2004-05-31 Paolo Bonzini <bonzini@gnu.org>
Revert this patch:
2004-05-27 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.
2004-05-30 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* pa.c (emit_move_sequence): Fix loading of non 14-bit CONST operands
@ -269,7 +288,7 @@
* cfgbuild.c (control_flow_insn_p): Notice noreturn call
2004-05-25 Paolo Bonzini <bonzini@gnu.org>
2004-05-27 Paolo Bonzini <bonzini@gnu.org>
* combine.c (gen_binary): Remove.
(known_cond, simplify_shift_const

View File

@ -372,7 +372,6 @@ 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,
@ -381,6 +380,7 @@ 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,16 +3017,14 @@ find_split_point (rtx *loc, rtx insn)
if (src == mask)
SUBST (SET_SRC (x),
simplify_gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
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_binary (IOR, mode,
gen_binary (AND, mode, dest,
gen_int_mode (~(mask << pos),
mode)),
GEN_INT (src << pos)));
}
SUBST (SET_DEST (x), dest);
@ -3601,7 +3599,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), simplify_gen_binary (PLUS, mode, new, temp));
SUBST (XEXP (x, 0), gen_binary (PLUS, mode, new, temp));
}
/* If this is a simple operation applied to an IF_THEN_ELSE, try
@ -3658,14 +3656,12 @@ 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 = simplify_gen_relational (cond_code, mode, VOIDmode,
cond, cop1);
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 = simplify_gen_relational (reversed, mode, VOIDmode,
cond, cop1);
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. */
@ -3673,9 +3669,8 @@ 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,
simplify_gen_relational (cond_code,
mode, VOIDmode,
cond, cop1),
gen_binary (cond_code, mode, cond,
cop1),
mode);
else if (GET_CODE (false_rtx) == CONST_INT
&& INTVAL (false_rtx) == - STORE_FLAG_VALUE
@ -3684,17 +3679,13 @@ 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,
simplify_gen_relational (reversed,
mode, VOIDmode,
gen_binary (reversed, mode,
cond, cop1),
mode);
else
return gen_rtx_IF_THEN_ELSE (mode,
simplify_gen_relational (cond_code,
mode,
VOIDmode,
cond,
cop1),
gen_binary (cond_code, VOIDmode,
cond, cop1),
true_rtx, false_rtx);
code = GET_CODE (x);
@ -3797,7 +3788,7 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
}
if (inner)
return simplify_gen_binary (code, mode, other, inner);
return gen_binary (code, mode, other, inner);
}
}
@ -3899,8 +3890,7 @@ 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 simplify_gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
constm1_rtx);
return gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0), constm1_rtx);
temp = expand_compound_operation (XEXP (x, 0));
@ -4128,9 +4118,8 @@ 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 simplify_gen_binary (MINUS, mode, XEXP (x, 1),
simplify_gen_binary (MULT, mode,
in1, in2));
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
@ -4139,9 +4128,8 @@ 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 simplify_gen_binary (PLUS, mode,
simplify_gen_binary (PLUS, mode,
XEXP (XEXP (x, 0), 0),
return gen_binary (PLUS, mode,
gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0),
XEXP (x, 1)),
XEXP (XEXP (x, 0), 1));
@ -4209,7 +4197,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 = simplify_gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
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
@ -4249,9 +4237,7 @@ 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 simplify_gen_binary (PLUS, mode,
simplify_gen_binary (MULT, mode,
in1, in2),
return gen_binary (PLUS, mode, gen_binary (MULT, mode, in1, in2),
XEXP (x, 0));
}
@ -4264,18 +4250,15 @@ 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 simplify_gen_binary (MINUS, mode,
simplify_gen_binary (MULT, mode,
in1, in2),
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 simplify_gen_binary (MINUS, mode,
simplify_gen_binary (MINUS, mode,
XEXP (x, 0),
return gen_binary (MINUS, mode,
gen_binary (MINUS, mode, XEXP (x, 0),
XEXP (XEXP (x, 1), 0)),
XEXP (XEXP (x, 1), 1));
break;
@ -4287,11 +4270,17 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
if (GET_CODE (XEXP (x, 0)) == PLUS)
{
rtx result = distribute_and_simplify_rtx (x);
if (result)
return result;
}
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)
@ -4300,7 +4289,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 simplify_gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
return gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
}
break;
@ -4380,7 +4369,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 simplify_gen_binary (XOR, mode,
return gen_binary (XOR, mode,
gen_lowpart (mode, op0),
const1_rtx);
}
@ -4625,8 +4614,7 @@ 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 simplify_gen_relational (true_code, mode, VOIDmode,
XEXP (cond, 0), XEXP (cond, 1));
return gen_binary (true_code, mode, XEXP (cond, 0), XEXP (cond, 1));
/* Also when the truth value has to be reversed. */
if (comparison_p
@ -4776,16 +4764,16 @@ simplify_if_then_else (rtx x)
{
case GE:
case GT:
return simplify_gen_binary (SMAX, mode, true_rtx, false_rtx);
return gen_binary (SMAX, mode, true_rtx, false_rtx);
case LE:
case LT:
return simplify_gen_binary (SMIN, mode, true_rtx, false_rtx);
return gen_binary (SMIN, mode, true_rtx, false_rtx);
case GEU:
case GTU:
return simplify_gen_binary (UMAX, mode, true_rtx, false_rtx);
return gen_binary (UMAX, mode, true_rtx, false_rtx);
case LEU:
case LTU:
return simplify_gen_binary (UMIN, mode, true_rtx, false_rtx);
return gen_binary (UMIN, mode, true_rtx, false_rtx);
default:
break;
}
@ -4898,14 +4886,12 @@ simplify_if_then_else (rtx x)
if (z)
{
temp = subst (simplify_gen_relational (true_code, m, VOIDmode,
cond_op0, cond_op1),
temp = subst (gen_binary (true_code, m, 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 = gen_binary (MULT, m, temp,
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);
temp = gen_binary (op, m, gen_lowpart (m, z), temp);
if (extend_op != NIL)
temp = simplify_gen_unary (extend_op, mode, temp, m);
@ -5090,8 +5076,7 @@ simplify_set (rtx x)
PUT_CODE (*cc_use, old_code);
other_changed = 0;
op0 = simplify_gen_binary (XOR, GET_MODE (op0),
op0, GEN_INT (mask));
op0 = gen_binary (XOR, GET_MODE (op0), op0, GEN_INT (mask));
}
}
}
@ -5255,18 +5240,17 @@ 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 = simplify_gen_binary (AND, GET_MODE (src),
term2 = gen_binary (AND, GET_MODE (src),
XEXP (XEXP (src, 0), 0), true_rtx);
term3 = simplify_gen_binary (AND, GET_MODE (src),
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),
simplify_gen_binary (IOR, GET_MODE (src),
simplify_gen_binary (IOR, GET_MODE (src),
term1, term2),
gen_binary (IOR, GET_MODE (src),
gen_binary (IOR, GET_MODE (src), term1, term2),
term3));
src = SET_SRC (x);
@ -5302,17 +5286,15 @@ simplify_logical (rtx x)
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),
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 = simplify_gen_binary (AND, mode,
simplify_gen_unary (NOT, mode,
XEXP (op0, 0), mode),
x = gen_binary (AND, mode,
simplify_gen_unary (NOT, mode, XEXP (op0, 0), mode),
op1);
/* Similarly for (~(A ^ B)) & A. */
@ -5320,13 +5302,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 = simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), 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 = simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), 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
@ -5346,9 +5328,8 @@ simplify_logical (rtx x)
&& 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),
return gen_binary (IOR, mode,
gen_binary (AND, mode, XEXP (op0, 0),
GEN_INT (INTVAL (XEXP (op0, 1))
& ~INTVAL (op1))), op1);
@ -5367,16 +5348,54 @@ simplify_logical (rtx x)
&& ! 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)
/* 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)
{
rtx result = distribute_and_simplify_rtx (x);
if (result)
return result;
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:
@ -5397,11 +5416,28 @@ 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 || GET_CODE (op1) == AND)
if (GET_CODE (op0) == AND)
{
rtx result = distribute_and_simplify_rtx (x);
if (result)
return result;
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
@ -5450,7 +5486,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 (simplify_gen_binary (IOR, mode, op0, op1));
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
@ -5470,8 +5506,7 @@ simplify_logical (rtx x)
}
else if (num_negated == 1)
return
simplify_gen_unary (NOT, mode,
simplify_gen_binary (XOR, mode, op0, op1),
simplify_gen_unary (NOT, mode, gen_binary (XOR, mode, op0, op1),
mode);
}
@ -5482,17 +5517,15 @@ simplify_logical (rtx x)
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),
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 simplify_gen_binary (AND, mode,
simplify_gen_unary (NOT, mode,
XEXP (op0, 1), mode),
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
@ -5762,7 +5795,7 @@ expand_field_assignment (rtx x)
rtx inner;
rtx pos; /* Always counts from low bit. */
int len;
rtx mask, cleared, masked;
rtx mask;
enum machine_mode compute_mode;
/* Loop until we find something we can't simplify. */
@ -5800,9 +5833,8 @@ expand_field_assignment (rtx x)
/* 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))
pos = gen_binary (MINUS, GET_MODE (pos),
GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner))
- len),
pos);
}
@ -5851,30 +5883,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)
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. */
mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1);
cleared = simplify_gen_binary (AND, compute_mode,
x = gen_rtx_SET
(VOIDmode, copy_rtx (inner),
gen_binary (IOR, compute_mode,
gen_binary (AND, compute_mode,
simplify_gen_unary (NOT, compute_mode,
simplify_gen_binary (ASHIFT,
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)),
inner),
gen_binary (ASHIFT, compute_mode,
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));
pos)));
}
return x;
@ -6330,7 +6362,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 simplify_gen_binary (code, mode, tem,
return gen_binary (code, mode, tem,
GEN_INT (INTVAL (XEXP (x, 1)) >> count));
break;
@ -6822,8 +6854,7 @@ 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 = simplify_gen_binary (AND, GET_MODE (x),
XEXP (x, 0), GEN_INT (cval));
y = gen_binary (AND, GET_MODE (x), XEXP (x, 0), GEN_INT (cval));
if (rtx_cost (y, SET) < rtx_cost (x, SET))
x = y;
}
@ -6915,9 +6946,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 = simplify_gen_binary (GET_CODE (x), GET_MODE (x),
temp = gen_binary (GET_CODE (x), GET_MODE (x),
XEXP (XEXP (x, 0), 0), temp);
x = simplify_gen_binary (LSHIFTRT, GET_MODE (x), temp,
x = gen_binary (LSHIFTRT, GET_MODE (x), temp,
XEXP (XEXP (x, 0), 1));
return force_to_mode (x, mode, mask, reg, next_select);
}
@ -6934,7 +6965,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 = simplify_gen_binary (code, op_mode, op0, op1);
x = gen_binary (code, op_mode, op0, op1);
break;
case ASHIFT:
@ -6968,7 +6999,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 = simplify_gen_binary (code, op_mode, op0, XEXP (x, 1));
x = gen_binary (code, op_mode, op0, XEXP (x, 1));
break;
case LSHIFTRT:
@ -6996,7 +7027,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 = simplify_gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1));
x = gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1));
}
/* If we have (and (lshiftrt FOO C1) C2) where the combination of the
@ -7018,7 +7049,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 = simplify_gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0),
x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0),
GEN_INT (GET_MODE_BITSIZE (GET_MODE (x))
- exact_log2 (mask + 1)));
@ -7085,8 +7116,7 @@ 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 = simplify_gen_binary (LSHIFTRT, GET_MODE (x),
XEXP (x, 0), XEXP (x, 1));
x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0), XEXP (x, 1));
shiftrt:
@ -7151,10 +7181,8 @@ 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 = 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));
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);
}
@ -7264,19 +7292,8 @@ if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse)
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);
}
*ptrue = gen_binary (code, mode, true0, true1);
*pfalse = gen_binary (code, mode, false0, false1);
return cond0 ? cond0 : cond1;
}
@ -7306,11 +7323,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 = simplify_gen_binary (MULT, mode, op0, const_true_rtx);
*pfalse = simplify_gen_binary (MULT, mode,
*ptrue = gen_binary (MULT, mode, op0, const_true_rtx);
*pfalse = 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;
@ -7816,7 +7833,7 @@ apply_distributive_law (rtx x)
|| GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD)
return x;
tem = simplify_gen_binary (code, GET_MODE (SUBREG_REG (lhs)),
tem = gen_binary (code, GET_MODE (SUBREG_REG (lhs)),
SUBREG_REG (lhs), SUBREG_REG (rhs));
return gen_lowpart (GET_MODE (x), tem);
@ -7843,7 +7860,7 @@ apply_distributive_law (rtx x)
return x;
/* Form the new inner operation, seeing if it simplifies first. */
tem = simplify_gen_binary (code, GET_MODE (x), lhs, rhs);
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 */
@ -7856,96 +7873,9 @@ 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 simplify_gen_binary (inner_code, GET_MODE (x),
return 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.
@ -8011,15 +7941,11 @@ simplify_and_const_int (rtx x, enum machine_mode mode, rtx varop,
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))));
(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
@ -8060,7 +7986,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 = simplify_gen_binary (AND, mode, varop, GEN_INT (constop));
x = gen_binary (AND, mode, varop, GEN_INT (constop));
else
{
@ -8579,10 +8505,8 @@ simplify_shift_const (rtx x, enum rtx_code code,
&& 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)))));
= gen_binary (ASHIFT, GET_MODE (varop), XEXP (varop, 0),
GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
continue;
}
break;
@ -8593,10 +8517,8 @@ simplify_shift_const (rtx x, enum rtx_code code,
&& 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)))));
= gen_binary (LSHIFTRT, GET_MODE (varop), XEXP (varop, 0),
GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
continue;
}
break;
@ -8841,7 +8763,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))
{
@ -8850,8 +8772,7 @@ simplify_shift_const (rtx x, enum rtx_code code,
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 = gen_binary (GET_CODE (varop), shift_mode, lhs, rhs);
varop = apply_distributive_law (varop);
count = 0;
@ -9105,8 +9026,7 @@ 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 = simplify_gen_binary (outer_op, result_mode, x,
GEN_INT (outer_const));
x = gen_binary (outer_op, result_mode, x, GEN_INT (outer_const));
}
return x;
@ -9339,6 +9259,63 @@ 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.
@ -10173,7 +10150,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
&& c1 != mask
&& c1 != GET_MODE_MASK (tmode))
{
op0 = simplify_gen_binary (AND, tmode,
op0 = gen_binary (AND, tmode,
SUBREG_REG (XEXP (op0, 0)),
gen_int_mode (c1, tmode));
op0 = gen_lowpart (mode, op0);
@ -10319,10 +10296,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 = simplify_gen_binary (ASHIFTRT, GET_MODE (op0),
add_const, XEXP (op0, 1));
rtx new_const = gen_binary (ASHIFTRT, GET_MODE (op0), add_const,
XEXP (op0, 1));
op0 = simplify_gen_binary (PLUS, tmode,
op0 = gen_binary (PLUS, tmode,
gen_lowpart (tmode, inner),
new_const);
continue;
@ -10477,7 +10454,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 = simplify_gen_binary (AND, tmode,
op0 = gen_binary (AND, tmode,
gen_lowpart (tmode,
XEXP (op0, 0)),
gen_lowpart (tmode,
@ -10496,11 +10473,10 @@ 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 = simplify_gen_binary (AND, tmode,
op0 = 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;
}
@ -10547,7 +10523,7 @@ reversed_comparison (rtx exp, enum machine_mode mode, rtx op0, rtx op1)
if (reversed_code == UNKNOWN)
return NULL_RTX;
else
return simplify_gen_relational (reversed_code, mode, VOIDmode, op0, op1);
return gen_binary (reversed_code, mode, op0, op1);
}
/* Utility function for following routine. Called when X is part of a value