From: haitao.feng@intel.com Date: Tue, 10 Jun 2014 04:08:48 +0000 (+0000) Subject: Update DoNumberTagI to support x32 port. X-Git-Tag: upstream/4.7.83~8771 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6ea90a47836914cf7e7262a7012dcbeb3d2ada8e;p=platform%2Fupstream%2Fv8.git Update DoNumberTagI to support x32 port. R=verwaest@chromium.org Review URL: https://codereview.chromium.org/263123002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21726 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 4ebb33bd6..75ba04e48 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -4524,11 +4524,32 @@ void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { void LCodeGen::DoNumberTagI(LNumberTagI* instr) { + class DeferredNumberTagI V8_FINAL : public LDeferredCode { + public: + DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) + : LDeferredCode(codegen), instr_(instr) { } + virtual void Generate() V8_OVERRIDE { + codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(), + instr_->temp2(), SIGNED_INT32); + } + virtual LInstruction* instr() V8_OVERRIDE { return instr_; } + private: + LNumberTagI* instr_; + }; + LOperand* input = instr->value(); ASSERT(input->IsRegister() && input->Equals(instr->result())); Register reg = ToRegister(input); - __ Integer32ToSmi(reg, reg); + if (SmiValuesAre32Bits()) { + __ Integer32ToSmi(reg, reg); + } else { + ASSERT(SmiValuesAre31Bits()); + DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); + __ Integer32ToSmi(reg, reg); + __ j(overflow, deferred->entry()); + __ bind(deferred->exit()); + } } @@ -4538,7 +4559,8 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) { DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) : LDeferredCode(codegen), instr_(instr) { } virtual void Generate() V8_OVERRIDE { - codegen()->DoDeferredNumberTagU(instr_); + codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(), + instr_->temp2(), UNSIGNED_INT32); } virtual LInstruction* instr() V8_OVERRIDE { return instr_; } private: @@ -4557,16 +4579,31 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) { } -void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) { +void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr, + LOperand* value, + LOperand* temp1, + LOperand* temp2, + IntegerSignedness signedness) { Label done, slow; - Register reg = ToRegister(instr->value()); - Register tmp = ToRegister(instr->temp1()); - XMMRegister temp_xmm = ToDoubleRegister(instr->temp2()); + Register reg = ToRegister(value); + Register tmp = ToRegister(temp1); + XMMRegister temp_xmm = ToDoubleRegister(temp2); // Load value into temp_xmm which will be preserved across potential call to // runtime (MacroAssembler::EnterExitFrameEpilogue preserves only allocatable // XMM registers on x64). - __ LoadUint32(temp_xmm, reg); + if (signedness == SIGNED_INT32) { + ASSERT(SmiValuesAre31Bits()); + // There was overflow, so bits 30 and 31 of the original integer + // disagree. Try to allocate a heap number in new space and store + // the value in there. If that fails, call the runtime system. + __ SmiToInteger32(reg, reg); + __ xorl(reg, Immediate(0x80000000)); + __ cvtlsi2sd(temp_xmm, reg); + } else { + ASSERT(signedness == UNSIGNED_INT32); + __ LoadUint32(temp_xmm, reg); + } if (FLAG_inline_new) { __ AllocateHeapNumber(reg, tmp, &slow); @@ -4584,7 +4621,7 @@ void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) { // Preserve the value of all registers. PushSafepointRegistersScope scope(this); - // NumberTagU uses the context from the frame, rather than + // NumberTagIU uses the context from the frame, rather than // the environment's HContext or HInlinedContext value. // They only call Runtime::kHiddenAllocateHeapNumber. // The corresponding HChange instructions are added in a phase that does diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h index fb58a53cf..712c974ef 100644 --- a/src/x64/lithium-codegen-x64.h +++ b/src/x64/lithium-codegen-x64.h @@ -83,7 +83,14 @@ class LCodeGen: public LCodeGenBase { // Deferred code support. void DoDeferredNumberTagD(LNumberTagD* instr); - void DoDeferredNumberTagU(LNumberTagU* instr); + + enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 }; + void DoDeferredNumberTagIU(LInstruction* instr, + LOperand* value, + LOperand* temp1, + LOperand* temp2, + IntegerSignedness signedness); + void DoDeferredTaggedToI(LTaggedToI* instr, Label* done); void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr); void DoDeferredStackCheck(LStackCheck* instr); diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index d44d37dd7..bb2ecc06b 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1885,7 +1885,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { return AssignPointerMap(DefineSameAsFirst(result)); } else { LOperand* value = UseRegister(val); - LNumberTagI* result = new(zone()) LNumberTagI(value); + LOperand* temp1 = SmiValuesAre32Bits() ? NULL : TempRegister(); + LOperand* temp2 = SmiValuesAre32Bits() ? NULL : FixedTemp(xmm1); + LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2); return AssignPointerMap(DefineSameAsFirst(result)); } } else if (to.IsSmi()) { diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index f8387ece2..429d47406 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -1981,13 +1981,17 @@ class LUint32ToDouble V8_FINAL : public LTemplateInstruction<1, 1, 0> { }; -class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 0> { +class LNumberTagI V8_FINAL : public LTemplateInstruction<1, 1, 2> { public: - explicit LNumberTagI(LOperand* value) { + LNumberTagI(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(NumberTagI, "number-tag-i") };