Index: src/lithium-allocator.cc |
diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc |
index 29c31942e44387903929e80e83241003a84ba8c2..5b68a2f0f8572024f18502fea0cb0783638a968b 100644 |
--- a/src/lithium-allocator.cc |
+++ b/src/lithium-allocator.cc |
@@ -238,6 +238,12 @@ LOperand* LiveRange::CreateAssignedOperand(Zone* zone) { |
case DOUBLE_REGISTERS: |
op = LDoubleRegister::Create(assigned_register(), zone); |
break; |
+ case FLOAT32x4_REGISTERS: |
+ op = LFloat32x4Register::Create(assigned_register(), zone); |
+ break; |
+ case INT32x4_REGISTERS: |
+ op = LInt32x4Register::Create(assigned_register(), zone); |
+ break; |
default: |
UNREACHABLE(); |
} |
@@ -488,6 +494,7 @@ void LiveRange::ConvertOperands(Zone* zone) { |
if (use_pos->HasOperand()) { |
ASSERT(op->IsRegister() || op->IsDoubleRegister() || |
+ op->IsFloat32x4Register() || op->IsInt32x4Register() || |
!use_pos->RequiresRegister()); |
use_pos->operand()->ConvertTo(op->kind(), op->index()); |
} |
@@ -554,6 +561,7 @@ LAllocator::LAllocator(int num_values, HGraph* graph) |
active_live_ranges_(8, zone()), |
inactive_live_ranges_(8, zone()), |
reusable_slots_(8, zone()), |
+ reusable_xmm_slots_(8, zone()), |
next_virtual_register_(num_values), |
first_artificial_register_(num_values), |
mode_(UNALLOCATED_REGISTERS), |
@@ -873,6 +881,16 @@ void LAllocator::MeetConstraintsBetween(LInstruction* first, |
double_artificial_registers_.Add( |
cur_input->virtual_register() - first_artificial_register_, |
zone()); |
+ } else if (RequiredRegisterKind(input_copy->virtual_register()) == |
+ FLOAT32x4_REGISTERS) { |
+ float32x4_artificial_registers_.Add( |
+ cur_input->virtual_register() - first_artificial_register_, |
+ zone()); |
+ } else if (RequiredRegisterKind(input_copy->virtual_register()) == |
+ INT32x4_REGISTERS) { |
+ int32x4_artificial_registers_.Add( |
+ cur_input->virtual_register() - first_artificial_register_, |
+ zone()); |
} |
AddConstraintsGapMove(gap_index, input_copy, cur_input); |
@@ -1185,8 +1203,12 @@ void LAllocator::ResolveControlFlow(LiveRange* range, |
if (branch->HasPointerMap()) { |
if (HasTaggedValue(range->id())) { |
branch->pointer_map()->RecordPointer(cur_op, chunk()->zone()); |
- } else if (!cur_op->IsDoubleStackSlot() && |
- !cur_op->IsDoubleRegister()) { |
+ } else if (!cur_op->IsDoubleStackSlot() && |
+ !cur_op->IsDoubleRegister() && |
+ !cur_op->IsFloat32x4StackSlot() && |
+ !cur_op->IsFloat32x4Register() && |
+ !cur_op->IsInt32x4StackSlot() && |
+ !cur_op->IsInt32x4Register()) { |
branch->pointer_map()->RemovePointer(cur_op); |
} |
} |
@@ -1512,6 +1534,10 @@ void LAllocator::AllocateRegisters() { |
if (live_ranges_[i] != NULL) { |
if (live_ranges_[i]->Kind() == mode_) { |
AddToUnhandledUnsorted(live_ranges_[i]); |
+ } else if (mode_ == DOUBLE_REGISTERS && |
+ (live_ranges_[i]->Kind() == FLOAT32x4_REGISTERS || |
+ live_ranges_[i]->Kind() == INT32x4_REGISTERS)) { |
+ AddToUnhandledUnsorted(live_ranges_[i]); |
} |
} |
} |
@@ -1519,6 +1545,7 @@ void LAllocator::AllocateRegisters() { |
ASSERT(UnhandledIsSorted()); |
ASSERT(reusable_slots_.is_empty()); |
+ ASSERT(reusable_xmm_slots_.is_empty()); |
ASSERT(active_live_ranges_.is_empty()); |
ASSERT(inactive_live_ranges_.is_empty()); |
@@ -1610,6 +1637,7 @@ void LAllocator::AllocateRegisters() { |
} |
reusable_slots_.Rewind(0); |
+ reusable_xmm_slots_.Rewind(0); |
active_live_ranges_.Rewind(0); |
inactive_live_ranges_.Rewind(0); |
} |
@@ -1646,10 +1674,20 @@ RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const { |
HValue* value = graph_->LookupValue(virtual_register); |
if (value != NULL && value->representation().IsDouble()) { |
return DOUBLE_REGISTERS; |
+ } else if (value != NULL && (value->representation().IsFloat32x4())) { |
+ return FLOAT32x4_REGISTERS; |
+ } else if (value != NULL && (value->representation().IsInt32x4())) { |
+ return INT32x4_REGISTERS; |
} |
} else if (double_artificial_registers_.Contains( |
virtual_register - first_artificial_register_)) { |
return DOUBLE_REGISTERS; |
+ } else if (float32x4_artificial_registers_.Contains( |
+ virtual_register - first_artificial_register_)) { |
+ return FLOAT32x4_REGISTERS; |
+ } else if (int32x4_artificial_registers_.Contains( |
+ virtual_register - first_artificial_register_)) { |
+ return INT32x4_REGISTERS; |
} |
return GENERAL_REGISTERS; |
@@ -1732,19 +1770,29 @@ void LAllocator::FreeSpillSlot(LiveRange* range) { |
int index = range->TopLevel()->GetSpillOperand()->index(); |
if (index >= 0) { |
- reusable_slots_.Add(range, zone()); |
+ if (range->Kind() == FLOAT32x4_REGISTERS) { |
+ reusable_xmm_slots_.Add(range, zone()); |
+ } else if (range->Kind() == INT32x4_REGISTERS) { |
+ reusable_xmm_slots_.Add(range, zone()); |
+ } else { |
+ reusable_slots_.Add(range, zone()); |
+ } |
} |
} |
LOperand* LAllocator::TryReuseSpillSlot(LiveRange* range) { |
- if (reusable_slots_.is_empty()) return NULL; |
- if (reusable_slots_.first()->End().Value() > |
+ ZoneList<LiveRange*>* reusable_slots = |
+ (range->Kind() == FLOAT32x4_REGISTERS || |
+ range->Kind() == INT32x4_REGISTERS) |
+ ? &reusable_xmm_slots_ : &reusable_slots_; |
+ if (reusable_slots->is_empty()) return NULL; |
+ if (reusable_slots->first()->End().Value() > |
range->TopLevel()->Start().Value()) { |
return NULL; |
} |
- LOperand* result = reusable_slots_.first()->TopLevel()->GetSpillOperand(); |
- reusable_slots_.Remove(0); |
+ LOperand* result = reusable_slots->first()->TopLevel()->GetSpillOperand(); |
+ reusable_slots->Remove(0); |
return result; |
} |
@@ -1811,7 +1859,8 @@ bool LAllocator::TryAllocateFreeReg(LiveRange* current) { |
} |
LOperand* hint = current->FirstHint(); |
- if (hint != NULL && (hint->IsRegister() || hint->IsDoubleRegister())) { |
+ if (hint != NULL && (hint->IsRegister() || hint->IsDoubleRegister() || |
+ hint->IsFloat32x4Register() || hint->IsInt32x4Register())) { |
int register_index = hint->index(); |
TraceAlloc( |
"Found reg hint %s (free until [%d) for live range %d (end %d[).\n", |
@@ -2162,7 +2211,15 @@ void LAllocator::Spill(LiveRange* range) { |
if (!first->HasAllocatedSpillOperand()) { |
LOperand* op = TryReuseSpillSlot(range); |
- if (op == NULL) op = chunk_->GetNextSpillSlot(range->Kind()); |
+ if (op == NULL) { |
+ op = chunk_->GetNextSpillSlot(range->Kind()); |
+ } else if (range->Kind() == FLOAT32x4_REGISTERS && |
+ op->kind() != LOperand::FLOAT32x4_STACK_SLOT) { |
+ op = LFloat32x4StackSlot::Create(op->index(), zone()); |
+ } else if (range->Kind() == INT32x4_REGISTERS && |
+ op->kind() != LOperand::INT32x4_STACK_SLOT) { |
+ op = LInt32x4StackSlot::Create(op->index(), zone()); |
+ } |
first->SetSpillOperand(op); |
} |
range->MakeSpilled(chunk()->zone()); |