diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc index 604526faa1..84996d2d99 100644 --- a/src/arm64/lithium-arm64.cc +++ b/src/arm64/lithium-arm64.cc @@ -520,6 +520,19 @@ LUnallocated* LChunkBuilder::TempRegister() { } +LUnallocated* LChunkBuilder::TempDoubleRegister() { + LUnallocated* operand = + new(zone()) LUnallocated(LUnallocated::MUST_HAVE_DOUBLE_REGISTER); + int vreg = allocator_->GetVirtualRegister(); + if (!allocator_->AllocationOk()) { + Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); + vreg = 0; + } + operand->set_virtual_register(vreg); + return operand; +} + + int LPlatformChunk::GetNextSpillIndex() { return spill_slot_count_++; } @@ -1102,7 +1115,8 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { } else { LOperand* value = UseRegister(val); LOperand* temp1 = TempRegister(); - LOperand* temp2 = instr->CanTruncateToInt32() ? NULL : FixedTemp(d24); + LOperand* temp2 = instr->CanTruncateToInt32() + ? NULL : TempDoubleRegister(); LInstruction* result = DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2)); if (!val->representation().IsSmi()) result = AssignEnvironment(result); @@ -1219,7 +1233,7 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { return AssignEnvironment( DefineAsRegister(new(zone()) LClampTToUint8(reg, TempRegister(), - FixedTemp(d24)))); + TempDoubleRegister()))); } } @@ -2562,8 +2576,7 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { ASSERT(instr->representation().IsDouble()); ASSERT(instr->value()->representation().IsDouble()); LOperand* input = UseRegister(instr->value()); - // TODO(all): Implement TempFPRegister. - LOperand* double_temp1 = FixedTemp(d24); // This was chosen arbitrarily. + LOperand* double_temp1 = TempDoubleRegister(); LOperand* temp1 = TempRegister(); LOperand* temp2 = TempRegister(); LOperand* temp3 = TempRegister(); @@ -2600,7 +2613,8 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { ASSERT(instr->value()->representation().IsDouble()); LOperand* input = UseRegister(instr->value()); if (instr->representation().IsInteger32()) { - LMathRoundI* result = new(zone()) LMathRoundI(input, FixedTemp(d24)); + LOperand* temp = TempDoubleRegister(); + LMathRoundI* result = new(zone()) LMathRoundI(input, temp); return AssignEnvironment(DefineAsRegister(result)); } else { ASSERT(instr->representation().IsDouble()); diff --git a/src/arm64/lithium-arm64.h b/src/arm64/lithium-arm64.h index 73e9e45876..3abc388fe1 100644 --- a/src/arm64/lithium-arm64.h +++ b/src/arm64/lithium-arm64.h @@ -3089,6 +3089,9 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase { // Temporary operand that must be in a register. MUST_USE_RESULT LUnallocated* TempRegister(); + // Temporary operand that must be in a double register. + MUST_USE_RESULT LUnallocated* TempDoubleRegister(); + // Temporary operand that must be in a fixed double register. MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg); diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc index 7cbae0cdad..c6e52ed824 100644 --- a/src/lithium-allocator.cc +++ b/src/lithium-allocator.cc @@ -46,7 +46,8 @@ UsePosition::UsePosition(LifetimePosition pos, register_beneficial_(true) { if (operand_ != NULL && operand_->IsUnallocated()) { LUnallocated* unalloc = LUnallocated::cast(operand_); - requires_reg_ = unalloc->HasRegisterPolicy(); + requires_reg_ = unalloc->HasRegisterPolicy() || + unalloc->HasDoubleRegisterPolicy(); register_beneficial_ = !unalloc->HasAnyPolicy(); } ASSERT(pos_.IsValid()); @@ -1005,6 +1006,15 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) { } Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); Define(curr_position, temp, NULL); + + if (temp->IsUnallocated()) { + LUnallocated* temp_unalloc = LUnallocated::cast(temp); + if (temp_unalloc->HasDoubleRegisterPolicy()) { + double_artificial_registers_.Add( + temp_unalloc->virtual_register() - first_artificial_register_, + zone()); + } + } } } } @@ -1095,7 +1105,6 @@ bool LAllocator::Allocate(LChunk* chunk) { void LAllocator::MeetRegisterConstraints() { LAllocatorPhase phase("L_Register constraints", this); - first_artificial_register_ = next_virtual_register_; const ZoneList* blocks = graph_->blocks(); for (int i = 0; i < blocks->length(); ++i) { HBasicBlock* block = blocks->at(i); diff --git a/src/lithium.cc b/src/lithium.cc index 77b0fda867..2265353f47 100644 --- a/src/lithium.cc +++ b/src/lithium.cc @@ -62,6 +62,9 @@ void LOperand::PrintTo(StringStream* stream) { case LUnallocated::MUST_HAVE_REGISTER: stream->Add("(R)"); break; + case LUnallocated::MUST_HAVE_DOUBLE_REGISTER: + stream->Add("(D)"); + break; case LUnallocated::WRITABLE_REGISTER: stream->Add("(WR)"); break; diff --git a/src/lithium.h b/src/lithium.h index edeef44e21..650bae6923 100644 --- a/src/lithium.h +++ b/src/lithium.h @@ -81,6 +81,7 @@ class LUnallocated : public LOperand { FIXED_REGISTER, FIXED_DOUBLE_REGISTER, MUST_HAVE_REGISTER, + MUST_HAVE_DOUBLE_REGISTER, WRITABLE_REGISTER, SAME_AS_FIRST_INPUT }; @@ -190,6 +191,10 @@ class LUnallocated : public LOperand { extended_policy() == WRITABLE_REGISTER || extended_policy() == MUST_HAVE_REGISTER); } + bool HasDoubleRegisterPolicy() const { + return basic_policy() == EXTENDED_POLICY && + extended_policy() == MUST_HAVE_DOUBLE_REGISTER; + } bool HasSameAsInputPolicy() const { return basic_policy() == EXTENDED_POLICY && extended_policy() == SAME_AS_FIRST_INPUT;