Index: src/arm/lithium-codegen-arm.cc |
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
index 51126db7aae9550ba99f20a889b930b541ae8d47..651f3f19add8fcbaf779402571230fba0285fc38 100644 |
--- a/src/arm/lithium-codegen-arm.cc |
+++ b/src/arm/lithium-codegen-arm.cc |
@@ -4599,9 +4599,11 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) |
: LDeferredCode(codegen), instr_(instr) { } |
virtual void Generate() V8_OVERRIDE { |
- codegen()->DoDeferredNumberTagI(instr_, |
- instr_->value(), |
- SIGNED_INT32); |
+ codegen()->DoDeferredNumberTagIU(instr_, |
+ instr_->value(), |
+ instr_->temp1(), |
+ instr_->temp2(), |
+ SIGNED_INT32); |
} |
virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
private: |
@@ -4624,9 +4626,11 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) { |
DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) |
: LDeferredCode(codegen), instr_(instr) { } |
virtual void Generate() V8_OVERRIDE { |
- codegen()->DoDeferredNumberTagI(instr_, |
- instr_->value(), |
- UNSIGNED_INT32); |
+ codegen()->DoDeferredNumberTagIU(instr_, |
+ instr_->value(), |
+ instr_->temp1(), |
+ instr_->temp2(), |
+ UNSIGNED_INT32); |
} |
virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
private: |
@@ -4644,18 +4648,19 @@ void LCodeGen::DoNumberTagU(LNumberTagU* instr) { |
} |
-void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, |
- LOperand* value, |
- IntegerSignedness signedness) { |
- Label slow; |
+void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr, |
+ LOperand* value, |
+ LOperand* temp1, |
+ LOperand* temp2, |
+ IntegerSignedness signedness) { |
+ Label done, slow; |
Register src = ToRegister(value); |
Register dst = ToRegister(instr->result()); |
+ Register tmp1 = scratch0(); |
+ Register tmp2 = ToRegister(temp1); |
+ Register tmp3 = ToRegister(temp2); |
LowDwVfpRegister dbl_scratch = double_scratch0(); |
- // Preserve the value of all registers. |
- PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
- |
- Label done; |
if (signedness == SIGNED_INT32) { |
// There was overflow, so bits 30 and 31 of the original integer |
// disagree. Try to allocate a heap number in new space and store |
@@ -4672,38 +4677,40 @@ void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, |
} |
if (FLAG_inline_new) { |
- __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); |
- __ AllocateHeapNumber(r5, r3, r4, scratch0(), &slow, DONT_TAG_RESULT); |
- __ Move(dst, r5); |
+ __ LoadRoot(tmp3, Heap::kHeapNumberMapRootIndex); |
+ __ AllocateHeapNumber(dst, tmp1, tmp2, tmp3, &slow, DONT_TAG_RESULT); |
__ b(&done); |
} |
// 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. |
+ __ mov(dst, Operand::Zero()); |
- // 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. |
- __ mov(ip, Operand::Zero()); |
- __ StoreToSafepointRegisterSlot(ip, dst); |
- // NumberTagI and NumberTagD use the context from the frame, rather than |
- // the environment's HContext or HInlinedContext value. |
- // They only call Runtime::kAllocateHeapNumber. |
- // The corresponding HChange instructions are added in a phase that does |
- // not have easy access to the local context. |
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
- __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
- RecordSafepointWithRegisters( |
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
- __ Move(dst, r0); |
- __ sub(dst, dst, Operand(kHeapObjectTag)); |
+ // Preserve the value of all registers. |
+ PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
+ |
+ // NumberTagI and NumberTagD use the context from the frame, rather than |
+ // the environment's HContext or HInlinedContext value. |
+ // They only call Runtime::kAllocateHeapNumber. |
+ // The corresponding HChange instructions are added in a phase that does |
+ // not have easy access to the local context. |
+ __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
+ RecordSafepointWithRegisters( |
+ instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
+ __ sub(r0, r0, Operand(kHeapObjectTag)); |
+ __ StoreToSafepointRegisterSlot(r0, dst); |
+ } |
// Done. Put the value in dbl_scratch into the value of the allocated heap |
// number. |
__ bind(&done); |
__ vstr(dbl_scratch, dst, HeapNumber::kValueOffset); |
__ add(dst, dst, Operand(kHeapObjectTag)); |
- __ StoreToSafepointRegisterSlot(dst, dst); |
} |