From b5c3b18f29e5c8ed47360d3ce3cfedd3569f84a3 Mon Sep 17 00:00:00 2001 From: "whesse@chromium.org" Date: Tue, 22 Feb 2011 12:02:47 +0000 Subject: [PATCH] X64 Crankshaft: Implement DoubleToI in optimizing compiler. Review URL: http://codereview.chromium.org/6551009 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6889 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x64/lithium-codegen-x64.cc | 37 ++++++++++++++++++++++++++++++++++++- src/x64/lithium-x64.cc | 8 ++------ src/x64/lithium-x64.h | 5 ++--- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index b04535d..9fa7470 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -2869,7 +2869,42 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { void LCodeGen::DoDoubleToI(LDoubleToI* instr) { - Abort("Unimplemented: %s", "DoDoubleToI"); + LOperand* input = instr->InputAt(0); + ASSERT(input->IsDoubleRegister()); + LOperand* result = instr->result(); + ASSERT(result->IsRegister()); + + XMMRegister input_reg = ToDoubleRegister(input); + Register result_reg = ToRegister(result); + + if (instr->truncating()) { + // Performs a truncating conversion of a floating point number as used by + // the JS bitwise operations. + __ cvttsd2siq(result_reg, input_reg); + __ movq(kScratchRegister, V8_INT64_C(0x8000000000000000), RelocInfo::NONE); + __ cmpl(result_reg, kScratchRegister); + DeoptimizeIf(equal, instr->environment()); + } else { + __ cvttsd2si(result_reg, input_reg); + __ cvtlsi2sd(xmm0, result_reg); + __ ucomisd(xmm0, input_reg); + DeoptimizeIf(not_equal, instr->environment()); + DeoptimizeIf(parity_even, instr->environment()); // NaN. + if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { + NearLabel done; + // The integer converted back is equal to the original. We + // only have to test if we got -0 as an input. + __ testl(result_reg, result_reg); + __ j(not_zero, &done); + __ movmskpd(result_reg, input_reg); + // Bit 0 contains the sign of the double in input_reg. + // If input was positive, we are ok and return 0, otherwise + // deoptimize. + __ andl(result_reg, Immediate(1)); + DeoptimizeIf(not_zero, instr->environment()); + __ bind(&done); + } + } } diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 60af65c..957f97f 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1577,12 +1577,8 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { return AssignPointerMap(Define(result, result_temp)); } else { ASSERT(to.IsInteger32()); - bool needs_temp = instr->CanTruncateToInt32() && - !CpuFeatures::IsSupported(SSE3); - LOperand* value = needs_temp ? - UseTempRegister(instr->value()) : UseRegister(instr->value()); - LOperand* temp = needs_temp ? TempRegister() : NULL; - return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp))); + LOperand* value = UseRegister(instr->value()); + return AssignEnvironment(DefineAsRegister(new LDoubleToI(value))); } } else if (from.IsInteger32()) { if (to.IsTagged()) { diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index e2ee325..ddff413 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -1405,11 +1405,10 @@ class LNumberTagD: public LTemplateInstruction<1, 1, 1> { // Sometimes truncating conversion from a tagged value to an int32. -class LDoubleToI: public LTemplateInstruction<1, 1, 1> { +class LDoubleToI: public LTemplateInstruction<1, 1, 0> { public: - LDoubleToI(LOperand* value, LOperand* temp) { + explicit LDoubleToI(LOperand* value) { inputs_[0] = value; - temps_[0] = temp; } DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i") -- 2.7.4