A number of small changes:

  - Change ConstantD for +/-zero constants to use the fp_zero register.
  - Use Bfi in DoConstructDouble.
  - Use Tbz for positive dividend check in mod by constant.
  - Optimize some deoptimize checks.
  - Fix a couple of style/consistency issues.

BUG=
R=ulan@chromium.org

Review URL: https://codereview.chromium.org/272183003

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21311 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent fc437f40
...@@ -2009,10 +2009,9 @@ LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { ...@@ -2009,10 +2009,9 @@ LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
LOperand* lo = UseRegister(instr->lo()); LOperand* lo = UseRegisterAndClobber(instr->lo());
LOperand* hi = UseRegister(instr->hi()); LOperand* hi = UseRegister(instr->hi());
LOperand* temp = TempRegister(); return DefineAsRegister(new(zone()) LConstructDouble(hi, lo));
return DefineAsRegister(new(zone()) LConstructDouble(hi, lo, temp));
} }
......
...@@ -1041,17 +1041,15 @@ class LDoubleBits V8_FINAL : public LTemplateInstruction<1, 1, 0> { ...@@ -1041,17 +1041,15 @@ class LDoubleBits V8_FINAL : public LTemplateInstruction<1, 1, 0> {
}; };
class LConstructDouble V8_FINAL : public LTemplateInstruction<1, 2, 1> { class LConstructDouble V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public: public:
LConstructDouble(LOperand* hi, LOperand* lo, LOperand* temp) { LConstructDouble(LOperand* hi, LOperand* lo) {
inputs_[0] = hi; inputs_[0] = hi;
inputs_[1] = lo; inputs_[1] = lo;
temps_[0] = temp;
} }
LOperand* hi() { return inputs_[0]; } LOperand* hi() { return inputs_[0]; }
LOperand* lo() { return inputs_[1]; } LOperand* lo() { return inputs_[1]; }
LOperand* temp() { return temps_[0]; }
DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double") DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double")
}; };
......
...@@ -2290,7 +2290,7 @@ void LCodeGen::DoDoubleBits(LDoubleBits* instr) { ...@@ -2290,7 +2290,7 @@ void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
Register result_reg = ToRegister(instr->result()); Register result_reg = ToRegister(instr->result());
if (instr->hydrogen()->bits() == HDoubleBits::HIGH) { if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
__ Fmov(result_reg, value_reg); __ Fmov(result_reg, value_reg);
__ Mov(result_reg, Operand(result_reg, LSR, 32)); __ Lsr(result_reg, result_reg, 32);
} else { } else {
__ Fmov(result_reg.W(), value_reg.S()); __ Fmov(result_reg.W(), value_reg.S());
} }
...@@ -2300,12 +2300,12 @@ void LCodeGen::DoDoubleBits(LDoubleBits* instr) { ...@@ -2300,12 +2300,12 @@ void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
void LCodeGen::DoConstructDouble(LConstructDouble* instr) { void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
Register hi_reg = ToRegister(instr->hi()); Register hi_reg = ToRegister(instr->hi());
Register lo_reg = ToRegister(instr->lo()); Register lo_reg = ToRegister(instr->lo());
Register temp = ToRegister(instr->temp());
DoubleRegister result_reg = ToDoubleRegister(instr->result()); DoubleRegister result_reg = ToDoubleRegister(instr->result());
__ And(temp, lo_reg, Operand(0xffffffff)); // Insert the least significant 32 bits of hi_reg into the most significant
__ Orr(temp, temp, Operand(hi_reg, LSL, 32)); // 32 bits of lo_reg, and move to a floating point register.
__ Fmov(result_reg, temp); __ Bfi(lo_reg, hi_reg, 32, 32);
__ Fmov(result_reg, lo_reg);
} }
...@@ -2415,8 +2415,8 @@ void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) { ...@@ -2415,8 +2415,8 @@ void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
Register value = ToRegister(instr->value()); Register value = ToRegister(instr->value());
__ CheckMap(value, scratch, Heap::kHeapNumberMapRootIndex, __ CheckMap(value, scratch, Heap::kHeapNumberMapRootIndex,
instr->FalseLabel(chunk()), DO_SMI_CHECK); instr->FalseLabel(chunk()), DO_SMI_CHECK);
__ Ldr(double_scratch(), FieldMemOperand(value, HeapNumber::kValueOffset)); __ Ldr(scratch, FieldMemOperand(value, HeapNumber::kValueOffset));
__ JumpIfMinusZero(double_scratch(), instr->TrueLabel(chunk())); __ JumpIfMinusZero(scratch, instr->TrueLabel(chunk()));
} }
EmitGoto(instr->FalseDestination(chunk())); EmitGoto(instr->FalseDestination(chunk()));
} }
...@@ -2524,7 +2524,15 @@ void LCodeGen::DoCmpT(LCmpT* instr) { ...@@ -2524,7 +2524,15 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
void LCodeGen::DoConstantD(LConstantD* instr) { void LCodeGen::DoConstantD(LConstantD* instr) {
ASSERT(instr->result()->IsDoubleRegister()); ASSERT(instr->result()->IsDoubleRegister());
DoubleRegister result = ToDoubleRegister(instr->result()); DoubleRegister result = ToDoubleRegister(instr->result());
if (instr->value() == 0) {
if (copysign(1.0, instr->value()) == 1.0) {
__ Fmov(result, fp_zero);
} else {
__ Fneg(result, fp_zero);
}
} else {
__ Fmov(result, instr->value()); __ Fmov(result, instr->value());
}
} }
...@@ -2663,13 +2671,14 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { ...@@ -2663,13 +2671,14 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
// Check for (0 / -x) that will produce negative zero. // Check for (0 / -x) that will produce negative zero.
HDiv* hdiv = instr->hydrogen(); HDiv* hdiv = instr->hydrogen();
if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ Cmp(dividend, 0); DeoptimizeIfZero(dividend, instr->environment());
DeoptimizeIf(eq, instr->environment());
} }
// Check for (kMinInt / -1). // Check for (kMinInt / -1).
if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
__ Cmp(dividend, kMinInt); // Test dividend for kMinInt by subtracting one (cmp) and checking for
DeoptimizeIf(eq, instr->environment()); // overflow.
__ Cmp(dividend, 1);
DeoptimizeIf(vs, instr->environment());
} }
// Deoptimize if remainder will not be 0. // Deoptimize if remainder will not be 0.
if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
...@@ -3922,8 +3931,7 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { ...@@ -3922,8 +3931,7 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
// Check for (0 / -x) that will produce negative zero. // Check for (0 / -x) that will produce negative zero.
HMathFloorOfDiv* hdiv = instr->hydrogen(); HMathFloorOfDiv* hdiv = instr->hydrogen();
if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
__ Cmp(dividend, 0); DeoptimizeIfZero(dividend, instr->environment());
DeoptimizeIf(eq, instr->environment());
} }
// Easy case: We need no dynamic check for the dividend and the flooring // Easy case: We need no dynamic check for the dividend and the flooring
...@@ -3945,12 +3953,12 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { ...@@ -3945,12 +3953,12 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
__ TruncatingDiv(result, dividend, Abs(divisor)); __ TruncatingDiv(result, dividend, Abs(divisor));
if (divisor < 0) __ Neg(result, result); if (divisor < 0) __ Neg(result, result);
__ B(&done); __ B(&done);
__ bind(&needs_adjustment); __ Bind(&needs_adjustment);
__ Add(temp, dividend, Operand(divisor > 0 ? 1 : -1)); __ Add(temp, dividend, Operand(divisor > 0 ? 1 : -1));
__ TruncatingDiv(result, temp, Abs(divisor)); __ TruncatingDiv(result, temp, Abs(divisor));
if (divisor < 0) __ Neg(result, result); if (divisor < 0) __ Neg(result, result);
__ Sub(result, result, Operand(1)); __ Sub(result, result, Operand(1));
__ bind(&done); __ Bind(&done);
} }
...@@ -4217,8 +4225,7 @@ void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { ...@@ -4217,8 +4225,7 @@ void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) {
int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
Label dividend_is_not_negative, done; Label dividend_is_not_negative, done;
if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) { if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) {
__ Cmp(dividend, 0); __ Tbz(dividend, kWSignBit, &dividend_is_not_negative);
__ B(pl, &dividend_is_not_negative);
// Note that this is correct even for kMinInt operands. // Note that this is correct even for kMinInt operands.
__ Neg(dividend, dividend); __ Neg(dividend, dividend);
__ And(dividend, dividend, mask); __ And(dividend, dividend, mask);
......
...@@ -2343,6 +2343,16 @@ void MacroAssembler::JumpIfMinusZero(DoubleRegister input, ...@@ -2343,6 +2343,16 @@ void MacroAssembler::JumpIfMinusZero(DoubleRegister input,
} }
void MacroAssembler::JumpIfMinusZero(Register input,
Label* on_negative_zero) {
ASSERT(input.Is64Bits());
// Floating point value is in an integer register. Detect -0.0 by subtracting
// 1 (cmp), which will cause overflow.
Cmp(input, 1);
B(vs, on_negative_zero);
}
void MacroAssembler::ClampInt32ToUint8(Register output, Register input) { void MacroAssembler::ClampInt32ToUint8(Register output, Register input) {
// Clamp the value to [0..255]. // Clamp the value to [0..255].
Cmp(input.W(), Operand(input.W(), UXTB)); Cmp(input.W(), Operand(input.W(), UXTB));
......
...@@ -919,6 +919,10 @@ class MacroAssembler : public Assembler { ...@@ -919,6 +919,10 @@ class MacroAssembler : public Assembler {
// Jump to label if the input double register contains -0.0. // Jump to label if the input double register contains -0.0.
void JumpIfMinusZero(DoubleRegister input, Label* on_negative_zero); void JumpIfMinusZero(DoubleRegister input, Label* on_negative_zero);
// Jump to label if the input integer register contains the double precision
// floating point representation of -0.0.
void JumpIfMinusZero(Register input, Label* on_negative_zero);
// Generate code to do a lookup in the number string cache. If the number in // Generate code to do a lookup in the number string cache. If the number in
// the register object is found in the cache the generated code falls through // the register object is found in the cache the generated code falls through
// with the result in the result register. The object and the result register // with the result in the result register. The object and the result register
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment