From 6a7cc6cc61593fece34007e876c9d4ca33a77b85 Mon Sep 17 00:00:00 2001 From: "weiliang.lin@intel.com" Date: Mon, 29 Sep 2014 08:39:05 +0000 Subject: [PATCH] X87: fix the Sqrt issue. The test mjsunit/regress/regress-sqrt compares the result of Math.sqrt function when using full-compiler and crankshaft compiler seperately. But according to glibc bug fixing(https://sourceware.org/bugzilla/show_bug.cgi?id=14032). The glibc implementation of std::sqrt() (It is invoked in the generated code when full-compiler is used.) will change since glibc 2.19. In order to keep consistence of Math.sqrt translation in crankshaft compiler and the pass of mjsunit/regress/regress-sqrt. we translate the Math.sqrt func by calling the runtime function. BUG= R=weiliang.lin@intel.com Review URL: https://codereview.chromium.org/606403002 Patch from Chunyang Dai . git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24271 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x87/lithium-codegen-x87.cc | 65 ++++++++++++++++++++++++++++++++++++++---- src/x87/lithium-x87.cc | 6 ++-- src/x87/lithium-x87.h | 10 +++++-- 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/src/x87/lithium-codegen-x87.cc b/src/x87/lithium-codegen-x87.cc index 8f17258..00bbe5e 100644 --- a/src/x87/lithium-codegen-x87.cc +++ b/src/x87/lithium-codegen-x87.cc @@ -4021,12 +4021,65 @@ void LCodeGen::DoMathFround(LMathFround* instr) { void LCodeGen::DoMathSqrt(LMathSqrt* instr) { - X87Register input_reg = ToX87Register(instr->value()); - X87Register output_reg = ToX87Register(instr->result()); - DCHECK(output_reg.is(input_reg)); - USE(output_reg); - X87Fxch(input_reg); - __ fsqrt(); + X87Register input = ToX87Register(instr->value()); + X87Register result_reg = ToX87Register(instr->result()); + Register temp_result = ToRegister(instr->temp1()); + Register temp = ToRegister(instr->temp2()); + Label slow, done, smi, finish; + DCHECK(result_reg.is(input)); + + // Store input into Heap number and call runtime function kMathExpRT. + if (FLAG_inline_new) { + __ AllocateHeapNumber(temp_result, temp, no_reg, &slow); + __ jmp(&done, Label::kNear); + } + + // Slow case: Call the runtime system to do the number allocation. + __ bind(&slow); + { + // TODO(3095996): Put a valid pointer value in the stack slot where the + // result register is stored, as this register is in the pointer map, but + // contains an integer value. + __ Move(temp_result, Immediate(0)); + + // Preserve the value of all registers. + PushSafepointRegistersScope scope(this); + + __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); + __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); + RecordSafepointWithRegisters( + instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); + __ StoreToSafepointRegisterSlot(temp_result, eax); + } + __ bind(&done); + X87LoadForUsage(input); + __ fstp_d(FieldOperand(temp_result, HeapNumber::kValueOffset)); + + { + // Preserve the value of all registers. + PushSafepointRegistersScope scope(this); + + __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); + __ push(temp_result); + __ CallRuntimeSaveDoubles(Runtime::kMathSqrtRT); + RecordSafepointWithRegisters( + instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); + __ StoreToSafepointRegisterSlot(temp_result, eax); + } + X87PrepareToWrite(result_reg); + // return value of MathExpRT is Smi or Heap Number. + __ JumpIfSmi(temp_result, &smi); + // Heap number(double) + __ fld_d(FieldOperand(temp_result, HeapNumber::kValueOffset)); + __ jmp(&finish); + // SMI + __ bind(&smi); + __ SmiUntag(temp_result); + __ push(temp_result); + __ fild_s(MemOperand(esp, 0)); + __ pop(temp_result); + __ bind(&finish); + X87CommitWrite(result_reg); } diff --git a/src/x87/lithium-x87.cc b/src/x87/lithium-x87.cc index f46aef9..9304b89 100644 --- a/src/x87/lithium-x87.cc +++ b/src/x87/lithium-x87.cc @@ -1252,8 +1252,10 @@ LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) { LOperand* input = UseRegisterAtStart(instr->value()); - LMathSqrt* result = new(zone()) LMathSqrt(input); - return DefineSameAsFirst(result); + LOperand* temp1 = FixedTemp(ecx); + LOperand* temp2 = FixedTemp(edx); + LMathSqrt* result = new(zone()) LMathSqrt(input, temp1, temp2); + return MarkAsCall(DefineSameAsFirst(result), instr); } diff --git a/src/x87/lithium-x87.h b/src/x87/lithium-x87.h index cf0e7b2..dbb18ec 100644 --- a/src/x87/lithium-x87.h +++ b/src/x87/lithium-x87.h @@ -973,13 +973,19 @@ class LMathExp FINAL : public LTemplateInstruction<1, 1, 2> { }; -class LMathSqrt FINAL : public LTemplateInstruction<1, 1, 0> { +class LMathSqrt FINAL : public LTemplateInstruction<1, 1, 2> { public: - explicit LMathSqrt(LOperand* value) { + explicit LMathSqrt(LOperand* value, + LOperand* temp1, + LOperand* temp2) { inputs_[0] = value; + temps_[0] = temp1; + temps_[1] = temp2; } LOperand* value() { return inputs_[0]; } + LOperand* temp1() { return temps_[0]; } + LOperand* temp2() { return temps_[1]; } DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt") }; -- 2.7.4