aboutsummaryrefslogtreecommitdiff
path: root/gcc/simplify-rtx.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r--gcc/simplify-rtx.c122
1 files changed, 97 insertions, 25 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index dc452dbdc26..ce6a27d61eb 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -757,7 +757,10 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
for (i = 0; i < 4; i++)
tmp[i] = ~tmp[i];
real_from_target (&d, tmp, mode);
+ /* APPLE LOCAL mainline 2005-03-17 4050475 */
+ break;
}
+ break;
default:
gcc_unreachable ();
}
@@ -955,7 +958,10 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
/* (neg (plus X 1)) can become (not X). */
if (GET_CODE (op) == PLUS
- && XEXP (op, 1) == const1_rtx)
+ /* APPLE LOCAL begin disallow generating (not (SYM)) */
+ && XEXP (op, 1) == const1_rtx
+ && GET_CODE (XEXP (op, 0)) != SYMBOL_REF)
+ /* APPLE LOCAL end disallow generating (not (SYM)) */
return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
/* Similarly, (neg (not X)) is (plus X 1). */
@@ -973,9 +979,12 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
return simplify_gen_binary (MINUS, mode, XEXP (op, 1),
XEXP (op, 0));
+ /* APPLE LOCAL begin don't allow subtraction of symbol address */
if (GET_CODE (op) == PLUS
&& !HONOR_SIGNED_ZEROS (mode)
- && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
+ && !HONOR_SIGN_DEPENDENT_ROUNDING (mode)
+ && GET_CODE (XEXP (op, 0)) != SYMBOL_REF)
+ /* APPLE LOCAL end don't allow subtraction of symbol address */
{
/* (neg (plus A C)) is simplified to (minus -C A). */
if (GET_CODE (XEXP (op, 1)) == CONST_INT
@@ -1071,7 +1080,7 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
target mode is the same as the variable's promotion. */
if (GET_CODE (op) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op)
- && SUBREG_PROMOTED_UNSIGNED_P (op)
+ && SUBREG_PROMOTED_UNSIGNED_P (op) > 0
&& GET_MODE (XEXP (op, 0)) == mode)
return XEXP (op, 0);
@@ -1550,48 +1559,69 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
if (! FLOAT_MODE_P (mode))
{
- HOST_WIDE_INT coeff0 = 1, coeff1 = 1;
+ HOST_WIDE_INT coeff0h = 0, coeff1h = 0;
+ unsigned HOST_WIDE_INT coeff0l = 1, coeff1l = 1;
rtx lhs = op0, rhs = op1;
if (GET_CODE (lhs) == NEG)
- coeff0 = -1, lhs = XEXP (lhs, 0);
+ {
+ coeff0l = -1;
+ coeff0h = -1;
+ lhs = XEXP (lhs, 0);
+ }
else if (GET_CODE (lhs) == MULT
&& GET_CODE (XEXP (lhs, 1)) == CONST_INT)
{
- coeff0 = INTVAL (XEXP (lhs, 1)), lhs = XEXP (lhs, 0);
+ coeff0l = INTVAL (XEXP (lhs, 1));
+ coeff0h = INTVAL (XEXP (lhs, 1)) < 0 ? -1 : 0;
+ lhs = XEXP (lhs, 0);
}
else if (GET_CODE (lhs) == ASHIFT
&& GET_CODE (XEXP (lhs, 1)) == CONST_INT
&& INTVAL (XEXP (lhs, 1)) >= 0
&& INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
{
- coeff0 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
+ coeff0l = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
+ coeff0h = 0;
lhs = XEXP (lhs, 0);
}
if (GET_CODE (rhs) == NEG)
- coeff1 = -1, rhs = XEXP (rhs, 0);
+ {
+ coeff1l = -1;
+ coeff1h = -1;
+ rhs = XEXP (rhs, 0);
+ }
else if (GET_CODE (rhs) == MULT
&& GET_CODE (XEXP (rhs, 1)) == CONST_INT)
{
- coeff1 = INTVAL (XEXP (rhs, 1)), rhs = XEXP (rhs, 0);
+ coeff1l = INTVAL (XEXP (rhs, 1));
+ coeff1h = INTVAL (XEXP (rhs, 1)) < 0 ? -1 : 0;
+ rhs = XEXP (rhs, 0);
}
else if (GET_CODE (rhs) == ASHIFT
&& GET_CODE (XEXP (rhs, 1)) == CONST_INT
&& INTVAL (XEXP (rhs, 1)) >= 0
&& INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
{
- coeff1 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
+ coeff1l = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
+ coeff1h = 0;
rhs = XEXP (rhs, 0);
}
if (rtx_equal_p (lhs, rhs))
{
rtx orig = gen_rtx_PLUS (mode, op0, op1);
- tem = simplify_gen_binary (MULT, mode, lhs,
- GEN_INT (coeff0 + coeff1));
+ rtx coeff;
+ unsigned HOST_WIDE_INT l;
+ HOST_WIDE_INT h;
+
+ add_double (coeff0l, coeff0h, coeff1l, coeff1h, &l, &h);
+ coeff = immed_double_const (l, h, mode);
+
+ tem = simplify_gen_binary (MULT, mode, lhs, coeff);
return rtx_cost (tem, SET) <= rtx_cost (orig, SET)
- ? tem : 0;
+ ? tem : 0;
}
}
@@ -1681,7 +1711,12 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
return simplify_gen_unary (NEG, mode, op1, mode);
/* (-1 - a) is ~a. */
- if (trueop0 == constm1_rtx)
+ /* APPLE LOCAL begin disallow generating (not (SYM))
+ But not when a is relocatable (this arises temporarily when
+ pulling 386 global addresses out of a loop). */
+ if (trueop0 == constm1_rtx
+ && GET_CODE (op1) != SYMBOL_REF )
+ /* APPLE LOCAL end disallow generating (not (SYM)) */
return simplify_gen_unary (NOT, mode, op1, mode);
/* Subtracting 0 has no effect unless the mode has signed zeros
@@ -1700,46 +1735,69 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
if (! FLOAT_MODE_P (mode))
{
- HOST_WIDE_INT coeff0 = 1, coeff1 = 1;
+ HOST_WIDE_INT coeff0h = 0, negcoeff1h = -1;
+ unsigned HOST_WIDE_INT coeff0l = 1, negcoeff1l = -1;
rtx lhs = op0, rhs = op1;
if (GET_CODE (lhs) == NEG)
- coeff0 = -1, lhs = XEXP (lhs, 0);
+ {
+ coeff0l = -1;
+ coeff0h = -1;
+ lhs = XEXP (lhs, 0);
+ }
else if (GET_CODE (lhs) == MULT
&& GET_CODE (XEXP (lhs, 1)) == CONST_INT)
{
- coeff0 = INTVAL (XEXP (lhs, 1)), lhs = XEXP (lhs, 0);
+ coeff0l = INTVAL (XEXP (lhs, 1));
+ coeff0h = INTVAL (XEXP (lhs, 1)) < 0 ? -1 : 0;
+ lhs = XEXP (lhs, 0);
}
else if (GET_CODE (lhs) == ASHIFT
&& GET_CODE (XEXP (lhs, 1)) == CONST_INT
&& INTVAL (XEXP (lhs, 1)) >= 0
&& INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
{
- coeff0 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
+ coeff0l = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
+ coeff0h = 0;
lhs = XEXP (lhs, 0);
}
if (GET_CODE (rhs) == NEG)
- coeff1 = - 1, rhs = XEXP (rhs, 0);
+ {
+ negcoeff1l = 1;
+ negcoeff1h = 0;
+ rhs = XEXP (rhs, 0);
+ }
else if (GET_CODE (rhs) == MULT
&& GET_CODE (XEXP (rhs, 1)) == CONST_INT)
{
- coeff1 = INTVAL (XEXP (rhs, 1)), rhs = XEXP (rhs, 0);
+ negcoeff1l = -INTVAL (XEXP (rhs, 1));
+ negcoeff1h = INTVAL (XEXP (rhs, 1)) <= 0 ? 0 : -1;
+ rhs = XEXP (rhs, 0);
}
else if (GET_CODE (rhs) == ASHIFT
&& GET_CODE (XEXP (rhs, 1)) == CONST_INT
&& INTVAL (XEXP (rhs, 1)) >= 0
&& INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
{
- coeff1 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
+ negcoeff1l = -(((HOST_WIDE_INT) 1)
+ << INTVAL (XEXP (rhs, 1)));
+ negcoeff1h = -1;
rhs = XEXP (rhs, 0);
}
if (rtx_equal_p (lhs, rhs))
{
rtx orig = gen_rtx_MINUS (mode, op0, op1);
- tem = simplify_gen_binary (MULT, mode, lhs,
- GEN_INT (coeff0 - coeff1));
+ rtx coeff;
+ unsigned HOST_WIDE_INT l;
+ HOST_WIDE_INT h;
+
+ add_double (coeff0l, coeff0h, negcoeff1l, negcoeff1h,
+ &l, &h);
+ coeff = immed_double_const (l, h, mode);
+
+ tem = simplify_gen_binary (MULT, mode, lhs, coeff);
return rtx_cost (tem, SET) <= rtx_cost (orig, SET)
? tem : 0;
}
@@ -1826,6 +1884,17 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
|| val != HOST_BITS_PER_WIDE_INT - 1))
return simplify_gen_binary (ASHIFT, mode, op0, GEN_INT (val));
+ /* Likewise for multipliers wider than a word. */
+ else if (GET_CODE (trueop1) == CONST_DOUBLE
+ && (GET_MODE (trueop1) == VOIDmode
+ || GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_INT)
+ && GET_MODE (op0) == mode
+ && CONST_DOUBLE_LOW (trueop1) == 0
+ && (val = exact_log2 (CONST_DOUBLE_HIGH (trueop1))) >= 0)
+ return simplify_gen_binary (ASHIFT, mode, op0,
+ GEN_INT (val
+ + HOST_BITS_PER_WIDE_INT));
+
/* x*2 is x+x and x*(-1) is -x */
if (GET_CODE (trueop1) == CONST_DOUBLE
&& GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_FLOAT
@@ -1882,7 +1951,8 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
if (trueop0 == trueop1
&& ! side_effects_p (op0)
&& GET_MODE_CLASS (mode) != MODE_CC)
- return const0_rtx;
+ /* APPLE LOCAL mainline 2005-04-13 */
+ return CONST0_RTX (mode);
/* Canonicalize XOR of the most significant bit to PLUS. */
if ((GET_CODE (op1) == CONST_INT
@@ -2849,7 +2919,7 @@ simplify_relational_operation_1 (enum rtx_code code, enum machine_mode mode,
/* If op0 is a comparison, extract the comparison arguments form it. */
if (code == NE)
{
- if (GET_MODE (op0) == cmp_mode)
+ if (GET_MODE (op0) == mode)
return simplify_rtx (op0);
else
return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
@@ -2886,6 +2956,8 @@ simplify_relational_operation_1 (enum rtx_code code, enum machine_mode mode,
&& op1 == const0_rtx
&& GET_MODE_CLASS (mode) == MODE_INT
&& cmp_mode != VOIDmode
+ /* ??? Work-around BImode bugs in the ia64 backend. */
+ && mode != BImode
&& cmp_mode != BImode
&& nonzero_bits (op0, cmp_mode) == 1
&& STORE_FLAG_VALUE == 1)