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
This commit is contained in:
parent
87df0b0eb7
commit
6ea90a4783
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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()) {
|
||||
|
@ -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")
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user