| Index: src/ia32/lithium-codegen-ia32.cc
|
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
|
| index 16cff91b8c31ce65a6690d4a91eb68f9f407c89a..15a684cdfe18a303453909000308cc6d8d84e7b7 100644
|
| --- a/src/ia32/lithium-codegen-ia32.cc
|
| +++ b/src/ia32/lithium-codegen-ia32.cc
|
| @@ -5674,93 +5674,22 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
|
| XMMRegister input_reg = ToDoubleRegister(input);
|
| Register result_reg = ToRegister(result);
|
|
|
| + __ cvttsd2si(result_reg, Operand(input_reg));
|
| +
|
| if (instr->truncating()) {
|
| // Performs a truncating conversion of a floating point number as used by
|
| // the JS bitwise operations.
|
| - __ cvttsd2si(result_reg, Operand(input_reg));
|
| + Label fast_case_succeeded;
|
| __ cmp(result_reg, 0x80000000u);
|
| - if (CpuFeatures::IsSupported(SSE3)) {
|
| - // This will deoptimize if the exponent of the input in out of range.
|
| - CpuFeatureScope scope(masm(), SSE3);
|
| - Label convert, done;
|
| - __ j(not_equal, &done, Label::kNear);
|
| - __ sub(Operand(esp), Immediate(kDoubleSize));
|
| - __ movdbl(Operand(esp, 0), input_reg);
|
| - // Get exponent alone and check for too-big exponent.
|
| - __ mov(result_reg, Operand(esp, sizeof(int32_t)));
|
| - __ and_(result_reg, HeapNumber::kExponentMask);
|
| - const uint32_t kTooBigExponent =
|
| - (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
|
| - __ cmp(Operand(result_reg), Immediate(kTooBigExponent));
|
| - __ j(less, &convert, Label::kNear);
|
| - __ add(Operand(esp), Immediate(kDoubleSize));
|
| - DeoptimizeIf(no_condition, instr->environment());
|
| - __ bind(&convert);
|
| - // Do conversion, which cannot fail because we checked the exponent.
|
| - __ fld_d(Operand(esp, 0));
|
| - __ fisttp_d(Operand(esp, 0));
|
| - __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result.
|
| - __ add(Operand(esp), Immediate(kDoubleSize));
|
| - __ bind(&done);
|
| - } else {
|
| - Label done;
|
| - Register temp_reg = ToRegister(instr->temp());
|
| - XMMRegister xmm_scratch = xmm0;
|
| -
|
| - // If cvttsd2si succeeded, we're done. Otherwise, we attempt
|
| - // manual conversion.
|
| - __ j(not_equal, &done, Label::kNear);
|
| -
|
| - // Get high 32 bits of the input in result_reg and temp_reg.
|
| - __ pshufd(xmm_scratch, input_reg, 1);
|
| - __ movd(Operand(temp_reg), xmm_scratch);
|
| - __ mov(result_reg, temp_reg);
|
| -
|
| - // Prepare negation mask in temp_reg.
|
| - __ sar(temp_reg, kBitsPerInt - 1);
|
| -
|
| - // Extract the exponent from result_reg and subtract adjusted
|
| - // bias from it. The adjustment is selected in a way such that
|
| - // when the difference is zero, the answer is in the low 32 bits
|
| - // of the input, otherwise a shift has to be performed.
|
| - __ shr(result_reg, HeapNumber::kExponentShift);
|
| - __ and_(result_reg,
|
| - HeapNumber::kExponentMask >> HeapNumber::kExponentShift);
|
| - __ sub(Operand(result_reg),
|
| - Immediate(HeapNumber::kExponentBias +
|
| - HeapNumber::kExponentBits +
|
| - HeapNumber::kMantissaBits));
|
| - // Don't handle big (> kMantissaBits + kExponentBits == 63) or
|
| - // special exponents.
|
| - DeoptimizeIf(greater, instr->environment());
|
| -
|
| - // Zero out the sign and the exponent in the input (by shifting
|
| - // it to the left) and restore the implicit mantissa bit,
|
| - // i.e. convert the input to unsigned int64 shifted left by
|
| - // kExponentBits.
|
| - ExternalReference minus_zero = ExternalReference::address_of_minus_zero();
|
| - // Minus zero has the most significant bit set and the other
|
| - // bits cleared.
|
| - __ movdbl(xmm_scratch, Operand::StaticVariable(minus_zero));
|
| - __ psllq(input_reg, HeapNumber::kExponentBits);
|
| - __ por(input_reg, xmm_scratch);
|
| -
|
| - // Get the amount to shift the input right in xmm_scratch.
|
| - __ neg(result_reg);
|
| - __ movd(xmm_scratch, Operand(result_reg));
|
| -
|
| - // Shift the input right and extract low 32 bits.
|
| - __ psrlq(input_reg, xmm_scratch);
|
| - __ movd(Operand(result_reg), input_reg);
|
| -
|
| - // Use the prepared mask in temp_reg to negate the result if necessary.
|
| - __ xor_(result_reg, Operand(temp_reg));
|
| - __ sub(result_reg, Operand(temp_reg));
|
| - __ bind(&done);
|
| - }
|
| + __ j(not_equal, &fast_case_succeeded);
|
| + __ sub(esp, Immediate(kDoubleSize));
|
| + __ movdbl(MemOperand(esp, 0), input_reg);
|
| + DoubleToIStub stub(esp, result_reg, 0, true);
|
| + __ call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
|
| + __ add(esp, Immediate(kDoubleSize));
|
| + __ bind(&fast_case_succeeded);
|
| } else {
|
| Label done;
|
| - __ cvttsd2si(result_reg, Operand(input_reg));
|
| __ cvtsi2sd(xmm0, Operand(result_reg));
|
| __ ucomisd(xmm0, input_reg);
|
| DeoptimizeIf(not_equal, instr->environment());
|
|
|