diff options
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 120 |
1 files changed, 96 insertions, 24 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index dc452dbdc26..ad9066b6b3e 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 @@ -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) |