ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegister(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
- LInstruction* result =
- DefineAsRegister(new(zone()) LDivByPowerOf2I(dividend, divisor));
- bool can_deopt =
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(0) && divisor < 0) ||
- (instr->CheckFlag(HValue::kCanOverflow) &&
- instr->left()->RangeCanInclude(kMinInt) && divisor == -1) ||
+ LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I(
+ dividend, divisor));
+ if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+ (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
(!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
- divisor != 1 && divisor != -1);
- return can_deopt ? AssignEnvironment(result) : result;
+ divisor != 1 && divisor != -1)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegister(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
- bool truncating = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32);
- LOperand* temp = truncating ? NULL : TempRegister();
- LInstruction* result =
- DefineAsRegister(new(zone()) LDivByConstI(dividend, divisor, temp));
- bool can_deopt =
- divisor == 0 ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(0) && divisor < 0) ||
- !truncating;
- return can_deopt ? AssignEnvironment(result) : result;
+ LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)
+ ? NULL : TempRegister();
+ LInstruction* result = DefineAsRegister(new(zone()) LDivByConstI(
+ dividend, divisor, temp));
+ if (divisor == 0 ||
+ (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+ !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
DefineAsRegister(new(zone()) LFlooringDivByConstI(dividend, divisor));
bool can_deopt =
divisor == 0 ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(0) && divisor < 0);
+ (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
return can_deopt ? AssignEnvironment(result) : result;
}
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegisterAtStart(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
- LInstruction* result =
- DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor));
- bool can_deopt =
- instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->CanBeNegative();
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I(
+ dividend, divisor));
+ if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
LOperand* dividend = UseRegister(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
LOperand* temp = TempRegister();
- LInstruction* result =
- DefineAsRegister(new(zone()) LModByConstI(dividend, divisor, temp));
- bool can_deopt =
- divisor == 0 ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->CanBeNegative());
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineAsRegister(new(zone()) LModByConstI(
+ dividend, divisor, temp));
+ if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegister(instr->left());
LOperand* divisor = UseRegister(instr->right());
- LInstruction* result =
- DefineAsRegister(new(zone()) LModI(dividend, divisor));
- bool can_deopt = (instr->right()->CanBeZero() ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->CanBeNegative() && instr->CanBeZero()));
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineAsRegister(new(zone()) LModI(dividend, divisor));
+ if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
LOperand* right() { return inputs_[1]; }
LOperand* temp() { return temps_[0]; }
- bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); }
-
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
};
// Check for (0 / -x) that will produce negative zero.
HDiv* hdiv = instr->hydrogen();
- if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ Cmp(dividend, 0);
DeoptimizeIf(eq, instr->environment());
}
// Check for (kMinInt / -1).
- if (hdiv->CheckFlag(HValue::kCanOverflow) &&
- hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1) {
+ if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
__ Cmp(dividend, kMinInt);
DeoptimizeIf(eq, instr->environment());
}
// Check for (0 / -x) that will produce negative zero.
HDiv* hdiv = instr->hydrogen();
- if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
DeoptimizeIfZero(dividend, instr->environment());
}
void LCodeGen::DoDivI(LDivI* instr) {
+ HBinaryOperation* hdiv = instr->hydrogen();
Register dividend = ToRegister32(instr->left());
Register divisor = ToRegister32(instr->right());
Register result = ToRegister32(instr->result());
- HValue* hdiv = instr->hydrogen_value();
// Issue the division first, and then check for any deopt cases whilst the
// result is computed.
__ Sdiv(result, dividend, divisor);
- if (hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+ if (hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
ASSERT_EQ(NULL, instr->temp());
return;
}
// Check for (0 / -x) that will produce negative zero.
HMathFloorOfDiv* hdiv = instr->hydrogen();
- if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ Cmp(dividend, 0);
DeoptimizeIf(eq, instr->environment());
}
// Check for negative zero.
HMod* hmod = instr->hydrogen();
- if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hmod->left()->CanBeNegative()) {
+ if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
Label remainder_not_zero;
__ Cbnz(result, &remainder_not_zero);
DeoptimizeIfNegative(dividend, instr->environment());
Label deopt, done;
// modulo = dividend - quotient * divisor
__ Sdiv(result, dividend, divisor);
- if (instr->hydrogen()->right()->CanBeZero()) {
+ if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
// Combine the deoptimization sites.
Label ok;
__ Cbnz(divisor, &ok);
__ Bind(&ok);
}
__ Msub(result, result, divisor, dividend);
- if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->hydrogen()->left()->CanBeNegative() &&
- instr->hydrogen()->CanBeZero()) {
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ Cbnz(result, &done);
if (deopt.is_bound()) { // TODO(all) This is a hack, remove this...
__ Tbnz(dividend, kWSignBit, &deopt);
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegister(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
- LInstruction* result =
- DefineAsRegister(new(zone()) LDivByPowerOf2I(dividend, divisor));
- bool can_deopt =
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(0) && divisor < 0) ||
- (instr->CheckFlag(HValue::kCanOverflow) &&
- instr->left()->RangeCanInclude(kMinInt) && divisor == -1) ||
+ LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I(
+ dividend, divisor));
+ if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+ (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
(!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
- divisor != 1 && divisor != -1);
- return can_deopt ? AssignEnvironment(result) : result;
+ divisor != 1 && divisor != -1)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegister(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
- LInstruction* result =
- DefineAsRegister(new(zone()) LDivByConstI(dividend, divisor));
- bool can_deopt =
- divisor == 0 ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(0) && divisor < 0) ||
- !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32);
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineAsRegister(new(zone()) LDivByConstI(
+ dividend, divisor));
+ if (divisor == 0 ||
+ (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+ !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
DefineAsRegister(new(zone()) LFlooringDivByConstI(dividend, divisor));
bool can_deopt =
divisor == 0 ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(0) && divisor < 0);
+ (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
return can_deopt ? AssignEnvironment(result) : result;
}
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegisterAtStart(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
- LInstruction* result =
- DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor));
- bool can_deopt =
- instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->CanBeNegative();
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I(
+ dividend, divisor));
+ if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegister(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
- LInstruction* result =
- DefineAsRegister(new(zone()) LModByConstI(dividend, divisor));
- bool can_deopt =
- divisor == 0 ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->CanBeNegative());
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineAsRegister(new(zone()) LModByConstI(
+ dividend, divisor));
+ if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
ASSERT(instr->representation().IsSmiOrInteger32());
ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().Equals(instr->representation()));
- if (CpuFeatures::IsSupported(SUDIV)) {
- LOperand* dividend = UseRegister(instr->left());
- LOperand* divisor = UseRegister(instr->right());
- LInstruction* result =
- DefineAsRegister(new(zone()) LModI(dividend, divisor, NULL, NULL));
- bool can_deopt = (instr->right()->CanBeZero() ||
- (instr->left()->RangeCanInclude(kMinInt) &&
- instr->right()->RangeCanInclude(-1) &&
- instr->CheckFlag(HValue::kBailoutOnMinusZero)) ||
- (instr->left()->CanBeNegative() &&
- instr->CanBeZero() &&
- instr->CheckFlag(HValue::kBailoutOnMinusZero)));
- return can_deopt ? AssignEnvironment(result) : result;
- } else {
- LOperand* dividend = UseRegister(instr->left());
- LOperand* divisor = UseRegister(instr->right());
- LOperand* temp = FixedTemp(d10);
- LOperand* temp2 = FixedTemp(d11);
- LInstruction* result =
- DefineAsRegister(new(zone()) LModI(dividend, divisor, temp, temp2));
- bool can_deopt = (instr->right()->CanBeZero() ||
- (instr->left()->CanBeNegative() &&
- instr->CanBeZero() &&
- instr->CheckFlag(HValue::kBailoutOnMinusZero)));
- return can_deopt ? AssignEnvironment(result) : result;
+ LOperand* dividend = UseRegister(instr->left());
+ LOperand* divisor = UseRegister(instr->right());
+ LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d10);
+ LOperand* temp2 = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d11);
+ LInstruction* result = DefineAsRegister(new(zone()) LModI(
+ dividend, divisor, temp, temp2));
+ if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ result = AssignEnvironment(result);
}
+ return result;
}
LOperand* right() { return inputs_[1]; }
LOperand* temp() { return temps_[0]; }
- bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); }
-
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
};
// Check for negative zero.
HMod* hmod = instr->hydrogen();
- if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hmod->left()->CanBeNegative()) {
+ if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
Label remainder_not_zero;
__ b(ne, &remainder_not_zero);
__ cmp(dividend, Operand::Zero());
void LCodeGen::DoModI(LModI* instr) {
HMod* hmod = instr->hydrogen();
- HValue* left = hmod->left();
- HValue* right = hmod->right();
if (CpuFeatures::IsSupported(SUDIV)) {
CpuFeatureScope scope(masm(), SUDIV);
Label done;
// Check for x % 0, sdiv might signal an exception. We have to deopt in this
// case because we can't return a NaN.
- if (right->CanBeZero()) {
+ if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
__ cmp(right_reg, Operand::Zero());
DeoptimizeIf(eq, instr->environment());
}
// Check for kMinInt % -1, sdiv will return kMinInt, which is not what we
// want. We have to deopt if we care about -0, because we can't return that.
- if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) {
+ if (hmod->CheckFlag(HValue::kCanOverflow)) {
Label no_overflow_possible;
__ cmp(left_reg, Operand(kMinInt));
__ b(ne, &no_overflow_possible);
__ mls(result_reg, result_reg, right_reg, left_reg);
// If we care about -0, test if the dividend is <0 and the result is 0.
- if (left->CanBeNegative() &&
- hmod->CanBeZero() &&
- hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ cmp(result_reg, Operand::Zero());
__ b(ne, &done);
__ cmp(left_reg, Operand::Zero());
Label done;
// Check for x % 0, we have to deopt in this case because we can't return a
// NaN.
- if (right->CanBeZero()) {
+ if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
__ cmp(right_reg, Operand::Zero());
DeoptimizeIf(eq, instr->environment());
}
__ sub(result_reg, left_reg, scratch, SetCC);
// If we care about -0, test if the dividend is <0 and the result is 0.
- if (left->CanBeNegative() &&
- hmod->CanBeZero() &&
- hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ b(ne, &done);
__ cmp(left_reg, Operand::Zero());
DeoptimizeIf(mi, instr->environment());
// Check for (0 / -x) that will produce negative zero.
HDiv* hdiv = instr->hydrogen();
- if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ cmp(dividend, Operand::Zero());
DeoptimizeIf(eq, instr->environment());
}
// Check for (kMinInt / -1).
- if (hdiv->CheckFlag(HValue::kCanOverflow) &&
- hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1) {
+ if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
__ cmp(dividend, Operand(kMinInt));
DeoptimizeIf(eq, instr->environment());
}
// Check for (0 / -x) that will produce negative zero.
HDiv* hdiv = instr->hydrogen();
- if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ cmp(dividend, Operand::Zero());
DeoptimizeIf(eq, instr->environment());
}
void LCodeGen::DoDivI(LDivI* instr) {
+ HBinaryOperation* hdiv = instr->hydrogen();
const Register left = ToRegister(instr->left());
const Register right = ToRegister(instr->right());
const Register result = ToRegister(instr->result());
// Check for x / 0.
- if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
+ if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
__ cmp(right, Operand::Zero());
DeoptimizeIf(eq, instr->environment());
}
// Check for (0 / -x) that will produce negative zero.
- if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
Label positive;
if (!instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
// Do the test only if it hadn't be done above.
}
// Check for (kMinInt / -1).
- if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow) &&
+ if (hdiv->CheckFlag(HValue::kCanOverflow) &&
(!CpuFeatures::IsSupported(SUDIV) ||
- !instr->hydrogen_value()->CheckFlag(
- HValue::kAllUsesTruncatingToInt32))) {
+ !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
// We don't need to check for overflow when truncating with sdiv
// support because, on ARM, sdiv kMinInt, -1 -> kMinInt.
__ cmp(left, Operand(kMinInt));
CpuFeatureScope scope(masm(), SUDIV);
__ sdiv(result, left, right);
- if (!instr->hydrogen_value()->CheckFlag(
- HInstruction::kAllUsesTruncatingToInt32)) {
+ if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
// Compute remainder and deopt if it's not zero.
const Register remainder = scratch0();
__ mls(remainder, result, right, left);
__ vcvt_s32_f64(double_scratch0().low(), vleft);
__ vmov(result, double_scratch0().low());
- if (!instr->hydrogen_value()->CheckFlag(
- HInstruction::kAllUsesTruncatingToInt32)) {
+ if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
// Deopt if exact conversion to integer was not possible.
// Use vright as scratch register.
__ vcvt_f64_s32(double_scratch0(), double_scratch0().low());
// Check for (0 / -x) that will produce negative zero.
HMathFloorOfDiv* hdiv = instr->hydrogen();
- if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ cmp(dividend, Operand::Zero());
DeoptimizeIf(eq, instr->environment());
}
// TODO(svenpanne) We should really use the null object pattern here.
bool HasRange() const { return range_ != NULL; }
bool CanBeNegative() const { return !HasRange() || range()->CanBeNegative(); }
- bool CanBeZero() const { return !HasRange() || range()->CanBeZero(); }
bool RangeCanInclude(int value) const {
return !HasRange() || range()->Includes(value);
}
// Check for negative zero.
HMod* hmod = instr->hydrogen();
- if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hmod->left()->CanBeNegative()) {
+ if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
Label remainder_not_zero;
__ j(not_zero, &remainder_not_zero, Label::kNear);
__ cmp(dividend, Immediate(0));
void LCodeGen::DoModI(LModI* instr) {
HMod* hmod = instr->hydrogen();
- HValue* left = hmod->left();
- HValue* right = hmod->right();
Register left_reg = ToRegister(instr->left());
ASSERT(left_reg.is(eax));
Label done;
// Check for x % 0, idiv would signal a divide error. We have to
// deopt in this case because we can't return a NaN.
- if (right->CanBeZero()) {
+ if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
__ test(right_reg, Operand(right_reg));
DeoptimizeIf(zero, instr->environment());
}
// Check for kMinInt % -1, idiv would signal a divide error. We
// have to deopt if we care about -0, because we can't return that.
- if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) {
+ if (hmod->CheckFlag(HValue::kCanOverflow)) {
Label no_overflow_possible;
__ cmp(left_reg, kMinInt);
__ j(not_equal, &no_overflow_possible, Label::kNear);
__ cdq();
// If we care about -0, test if the dividend is <0 and the result is 0.
- if (left->CanBeNegative() &&
- hmod->CanBeZero() &&
- hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
Label positive_left;
__ test(left_reg, Operand(left_reg));
__ j(not_sign, &positive_left, Label::kNear);
// Check for (0 / -x) that will produce negative zero.
HDiv* hdiv = instr->hydrogen();
- if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ test(dividend, dividend);
DeoptimizeIf(zero, instr->environment());
}
// Check for (kMinInt / -1).
- if (hdiv->CheckFlag(HValue::kCanOverflow) &&
- hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1) {
+ if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
__ cmp(dividend, kMinInt);
DeoptimizeIf(zero, instr->environment());
}
// Check for (0 / -x) that will produce negative zero.
HDiv* hdiv = instr->hydrogen();
- if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ test(dividend, dividend);
DeoptimizeIf(zero, instr->environment());
}
void LCodeGen::DoDivI(LDivI* instr) {
+ HBinaryOperation* hdiv = instr->hydrogen();
Register dividend = ToRegister(instr->left());
Register divisor = ToRegister(instr->right());
Register remainder = ToRegister(instr->temp());
ASSERT(!divisor.is(edx));
// Check for x / 0.
- HBinaryOperation* hdiv = instr->hydrogen();
if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
__ test(divisor, divisor);
DeoptimizeIf(zero, instr->environment());
__ cdq();
__ idiv(divisor);
- if (instr->is_flooring()) {
+ if (hdiv->IsMathFloorOfDiv()) {
Label done;
__ test(remainder, remainder);
__ j(zero, &done, Label::kNear);
__ sar(remainder, 31);
__ add(result, remainder);
__ bind(&done);
- } else if (!instr->hydrogen()->CheckFlag(
- HInstruction::kAllUsesTruncatingToInt32)) {
+ } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
// Deoptimize if remainder is not 0.
__ test(remainder, remainder);
DeoptimizeIf(not_zero, instr->environment());
// Check for (0 / -x) that will produce negative zero.
HMathFloorOfDiv* hdiv = instr->hydrogen();
- if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ test(dividend, dividend);
DeoptimizeIf(zero, instr->environment());
}
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegister(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
- LInstruction* result =
- DefineAsRegister(new(zone()) LDivByPowerOf2I(dividend, divisor));
- bool can_deopt =
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(0) && divisor < 0) ||
- (instr->CheckFlag(HValue::kCanOverflow) &&
- instr->left()->RangeCanInclude(kMinInt) && divisor == -1) ||
+ LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I(
+ dividend, divisor));
+ if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+ (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
(!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
- divisor != 1 && divisor != -1);
- return can_deopt ? AssignEnvironment(result) : result;
+ divisor != 1 && divisor != -1)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
int32_t divisor = instr->right()->GetInteger32Constant();
LOperand* temp1 = FixedTemp(eax);
LOperand* temp2 = FixedTemp(edx);
- LInstruction* result =
- DefineFixed(
- new(zone()) LDivByConstI(dividend, divisor, temp1, temp2), edx);
- bool can_deopt =
- divisor == 0 ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(0) && divisor < 0) ||
- !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32);
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineFixed(new(zone()) LDivByConstI(
+ dividend, divisor, temp1, temp2), edx);
+ if (divisor == 0 ||
+ (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+ !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
LOperand* dividend = UseFixed(instr->left(), eax);
LOperand* divisor = UseRegister(instr->right());
LOperand* temp = FixedTemp(edx);
- LInstruction* result =
- DefineFixed(new(zone()) LDivI(dividend, divisor, temp), eax);
- return AssignEnvironment(result);
+ LInstruction* result = DefineFixed(new(zone()) LDivI(
+ dividend, divisor, temp), eax);
+ if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+ instr->CheckFlag(HValue::kCanOverflow) ||
+ (!instr->IsMathFloorOfDiv() &&
+ !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
edx);
bool can_deopt =
divisor == 0 ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(0) && divisor < 0);
+ (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
return can_deopt ? AssignEnvironment(result) : result;
}
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegisterAtStart(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
- LInstruction* result =
- DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor));
- bool can_deopt =
- instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->CanBeNegative();
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I(
+ dividend, divisor));
+ if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
int32_t divisor = instr->right()->GetInteger32Constant();
LOperand* temp1 = FixedTemp(eax);
LOperand* temp2 = FixedTemp(edx);
- LInstruction* result =
- DefineFixed(
- new(zone()) LModByConstI(dividend, divisor, temp1, temp2), eax);
- bool can_deopt =
- divisor == 0 ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->CanBeNegative());
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineFixed(new(zone()) LModByConstI(
+ dividend, divisor, temp1, temp2), eax);
+ if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
LOperand* dividend = UseFixed(instr->left(), eax);
LOperand* divisor = UseRegister(instr->right());
LOperand* temp = FixedTemp(edx);
- LInstruction* result =
- DefineFixed(new(zone()) LModI(dividend, divisor, temp), edx);
- bool can_deopt = (instr->right()->CanBeZero() ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(kMinInt) &&
- instr->right()->RangeCanInclude(-1)) ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->CanBeNegative() &&
- instr->CanBeZero()));
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineFixed(new(zone()) LModI(
+ dividend, divisor, temp), edx);
+ if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
LOperand* right() { return inputs_[1]; }
LOperand* temp() { return temps_[0]; }
- bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); }
-
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
};
// Check for negative zero.
HMod* hmod = instr->hydrogen();
- if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hmod->left()->CanBeNegative()) {
+ if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
Label remainder_not_zero;
__ j(not_zero, &remainder_not_zero, Label::kNear);
__ cmpl(dividend, Immediate(0));
void LCodeGen::DoModI(LModI* instr) {
- if (instr->hydrogen()->RightIsPowerOf2()) {
- return DoModByPowerOf2I(reinterpret_cast<LModByPowerOf2I*>(instr));
- }
HMod* hmod = instr->hydrogen();
- HValue* left = hmod->left();
- HValue* right = hmod->right();
Register left_reg = ToRegister(instr->left());
ASSERT(left_reg.is(rax));
Label done;
// Check for x % 0, idiv would signal a divide error. We have to
// deopt in this case because we can't return a NaN.
- if (right->CanBeZero()) {
+ if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
__ testl(right_reg, right_reg);
DeoptimizeIf(zero, instr->environment());
}
// Check for kMinInt % -1, idiv would signal a divide error. We
// have to deopt if we care about -0, because we can't return that.
- if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) {
+ if (hmod->CheckFlag(HValue::kCanOverflow)) {
Label no_overflow_possible;
__ cmpl(left_reg, Immediate(kMinInt));
__ j(not_zero, &no_overflow_possible, Label::kNear);
__ cdq();
// If we care about -0, test if the dividend is <0 and the result is 0.
- if (left->CanBeNegative() &&
- hmod->CanBeZero() &&
- hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
Label positive_left;
__ testl(left_reg, left_reg);
__ j(not_sign, &positive_left, Label::kNear);
// Check for (0 / -x) that will produce negative zero.
HMathFloorOfDiv* hdiv = instr->hydrogen();
- if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ testl(dividend, dividend);
DeoptimizeIf(zero, instr->environment());
}
// Check for (0 / -x) that will produce negative zero.
HDiv* hdiv = instr->hydrogen();
- if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ testl(dividend, dividend);
DeoptimizeIf(zero, instr->environment());
}
// Check for (kMinInt / -1).
- if (hdiv->CheckFlag(HValue::kCanOverflow) &&
- hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1) {
+ if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
__ cmpl(dividend, Immediate(kMinInt));
DeoptimizeIf(zero, instr->environment());
}
// Check for (0 / -x) that will produce negative zero.
HDiv* hdiv = instr->hydrogen();
- if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
- hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ testl(dividend, dividend);
DeoptimizeIf(zero, instr->environment());
}
void LCodeGen::DoDivI(LDivI* instr) {
+ HBinaryOperation* hdiv = instr->hydrogen();
Register dividend = ToRegister(instr->left());
Register divisor = ToRegister(instr->right());
Register remainder = ToRegister(instr->temp());
ASSERT(!divisor.is(rdx));
// Check for x / 0.
- HBinaryOperation* hdiv = instr->hydrogen();
if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
__ testl(divisor, divisor);
DeoptimizeIf(zero, instr->environment());
__ cdq();
__ idivl(divisor);
- if (instr->is_flooring()) {
+ if (hdiv->IsMathFloorOfDiv()) {
Label done;
__ testl(remainder, remainder);
__ j(zero, &done, Label::kNear);
__ sarl(remainder, Immediate(31));
__ addl(result, remainder);
__ bind(&done);
- } else if (!instr->hydrogen()->CheckFlag(
- HInstruction::kAllUsesTruncatingToInt32)) {
+ } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
// Deoptimize if remainder is not 0.
__ testl(remainder, remainder);
DeoptimizeIf(not_zero, instr->environment());
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegister(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
- LInstruction* result =
- DefineAsRegister(new(zone()) LDivByPowerOf2I(dividend, divisor));
- bool can_deopt =
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(0) && divisor < 0) ||
- (instr->CheckFlag(HValue::kCanOverflow) &&
- instr->left()->RangeCanInclude(kMinInt) && divisor == -1) ||
+ LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I(
+ dividend, divisor));
+ if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+ (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
(!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
- divisor != 1 && divisor != -1);
- return can_deopt ? AssignEnvironment(result) : result;
+ divisor != 1 && divisor != -1)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
int32_t divisor = instr->right()->GetInteger32Constant();
LOperand* temp1 = FixedTemp(rax);
LOperand* temp2 = FixedTemp(rdx);
- LInstruction* result =
- DefineFixed(
- new(zone()) LDivByConstI(dividend, divisor, temp1, temp2), rdx);
- bool can_deopt =
- divisor == 0 ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(0) && divisor < 0) ||
- !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32);
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineFixed(new(zone()) LDivByConstI(
+ dividend, divisor, temp1, temp2), rdx);
+ if (divisor == 0 ||
+ (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+ !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
LOperand* dividend = UseFixed(instr->left(), rax);
LOperand* divisor = UseRegister(instr->right());
LOperand* temp = FixedTemp(rdx);
- LInstruction* result =
- DefineFixed(new(zone()) LDivI(dividend, divisor, temp), rax);
- return AssignEnvironment(result);
+ LInstruction* result = DefineFixed(new(zone()) LDivI(
+ dividend, divisor, temp), rax);
+ if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+ instr->CheckFlag(HValue::kCanOverflow) ||
+ (!instr->IsMathFloorOfDiv() &&
+ !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
rdx);
bool can_deopt =
divisor == 0 ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(0) && divisor < 0);
+ (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
return can_deopt ? AssignEnvironment(result) : result;
}
ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegisterAtStart(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
- LInstruction* result =
- DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor));
- bool can_deopt =
- instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->CanBeNegative();
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I(
+ dividend, divisor));
+ if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
int32_t divisor = instr->right()->GetInteger32Constant();
LOperand* temp1 = FixedTemp(rax);
LOperand* temp2 = FixedTemp(rdx);
- LInstruction* result =
- DefineFixed(
- new(zone()) LModByConstI(dividend, divisor, temp1, temp2), rax);
- bool can_deopt =
- divisor == 0 ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->CanBeNegative());
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineFixed(new(zone()) LModByConstI(
+ dividend, divisor, temp1, temp2), rax);
+ if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
LOperand* dividend = UseFixed(instr->left(), rax);
LOperand* divisor = UseRegister(instr->right());
LOperand* temp = FixedTemp(rdx);
- LInstruction* result =
- DefineFixed(new(zone()) LModI(dividend, divisor, temp), rdx);
- bool can_deopt = (instr->right()->CanBeZero() ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->RangeCanInclude(kMinInt) &&
- instr->right()->RangeCanInclude(-1)) ||
- (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
- instr->left()->CanBeNegative() &&
- instr->CanBeZero()));
- return can_deopt ? AssignEnvironment(result) : result;
+ LInstruction* result = DefineFixed(new(zone()) LModI(
+ dividend, divisor, temp), rdx);
+ if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
LOperand* right() { return inputs_[1]; }
LOperand* temp() { return temps_[0]; }
- bool is_flooring() { return hydrogen_value()->IsMathFloorOfDiv(); }
-
DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
};