ARM64: Introduce TempDoubleRegister as a lithium operand constraint.

R=ulan@chromium.org

Review URL: https://codereview.chromium.org/261933002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21168 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
baptiste.afsa@arm.com 2014-05-06 12:11:00 +00:00
parent 9b4bd33551
commit 4a9d0b0406
5 changed files with 41 additions and 7 deletions

View File

@ -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() { int LPlatformChunk::GetNextSpillIndex() {
return spill_slot_count_++; return spill_slot_count_++;
} }
@ -1102,7 +1115,8 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
} else { } else {
LOperand* value = UseRegister(val); LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister(); LOperand* temp1 = TempRegister();
LOperand* temp2 = instr->CanTruncateToInt32() ? NULL : FixedTemp(d24); LOperand* temp2 = instr->CanTruncateToInt32()
? NULL : TempDoubleRegister();
LInstruction* result = LInstruction* result =
DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2)); DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2));
if (!val->representation().IsSmi()) result = AssignEnvironment(result); if (!val->representation().IsSmi()) result = AssignEnvironment(result);
@ -1219,7 +1233,7 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
return AssignEnvironment( return AssignEnvironment(
DefineAsRegister(new(zone()) LClampTToUint8(reg, DefineAsRegister(new(zone()) LClampTToUint8(reg,
TempRegister(), TempRegister(),
FixedTemp(d24)))); TempDoubleRegister())));
} }
} }
@ -2562,8 +2576,7 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
ASSERT(instr->representation().IsDouble()); ASSERT(instr->representation().IsDouble());
ASSERT(instr->value()->representation().IsDouble()); ASSERT(instr->value()->representation().IsDouble());
LOperand* input = UseRegister(instr->value()); LOperand* input = UseRegister(instr->value());
// TODO(all): Implement TempFPRegister. LOperand* double_temp1 = TempDoubleRegister();
LOperand* double_temp1 = FixedTemp(d24); // This was chosen arbitrarily.
LOperand* temp1 = TempRegister(); LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister(); LOperand* temp2 = TempRegister();
LOperand* temp3 = TempRegister(); LOperand* temp3 = TempRegister();
@ -2600,7 +2613,8 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
ASSERT(instr->value()->representation().IsDouble()); ASSERT(instr->value()->representation().IsDouble());
LOperand* input = UseRegister(instr->value()); LOperand* input = UseRegister(instr->value());
if (instr->representation().IsInteger32()) { 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)); return AssignEnvironment(DefineAsRegister(result));
} else { } else {
ASSERT(instr->representation().IsDouble()); ASSERT(instr->representation().IsDouble());

View File

@ -3089,6 +3089,9 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
// Temporary operand that must be in a register. // Temporary operand that must be in a register.
MUST_USE_RESULT LUnallocated* TempRegister(); 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. // Temporary operand that must be in a fixed double register.
MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg); MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg);

View File

@ -46,7 +46,8 @@ UsePosition::UsePosition(LifetimePosition pos,
register_beneficial_(true) { register_beneficial_(true) {
if (operand_ != NULL && operand_->IsUnallocated()) { if (operand_ != NULL && operand_->IsUnallocated()) {
LUnallocated* unalloc = LUnallocated::cast(operand_); LUnallocated* unalloc = LUnallocated::cast(operand_);
requires_reg_ = unalloc->HasRegisterPolicy(); requires_reg_ = unalloc->HasRegisterPolicy() ||
unalloc->HasDoubleRegisterPolicy();
register_beneficial_ = !unalloc->HasAnyPolicy(); register_beneficial_ = !unalloc->HasAnyPolicy();
} }
ASSERT(pos_.IsValid()); ASSERT(pos_.IsValid());
@ -1005,6 +1006,15 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) {
} }
Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); Use(block_start_position, curr_position.InstructionEnd(), temp, NULL);
Define(curr_position, 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() { void LAllocator::MeetRegisterConstraints() {
LAllocatorPhase phase("L_Register constraints", this); LAllocatorPhase phase("L_Register constraints", this);
first_artificial_register_ = next_virtual_register_;
const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
for (int i = 0; i < blocks->length(); ++i) { for (int i = 0; i < blocks->length(); ++i) {
HBasicBlock* block = blocks->at(i); HBasicBlock* block = blocks->at(i);

View File

@ -62,6 +62,9 @@ void LOperand::PrintTo(StringStream* stream) {
case LUnallocated::MUST_HAVE_REGISTER: case LUnallocated::MUST_HAVE_REGISTER:
stream->Add("(R)"); stream->Add("(R)");
break; break;
case LUnallocated::MUST_HAVE_DOUBLE_REGISTER:
stream->Add("(D)");
break;
case LUnallocated::WRITABLE_REGISTER: case LUnallocated::WRITABLE_REGISTER:
stream->Add("(WR)"); stream->Add("(WR)");
break; break;

View File

@ -81,6 +81,7 @@ class LUnallocated : public LOperand {
FIXED_REGISTER, FIXED_REGISTER,
FIXED_DOUBLE_REGISTER, FIXED_DOUBLE_REGISTER,
MUST_HAVE_REGISTER, MUST_HAVE_REGISTER,
MUST_HAVE_DOUBLE_REGISTER,
WRITABLE_REGISTER, WRITABLE_REGISTER,
SAME_AS_FIRST_INPUT SAME_AS_FIRST_INPUT
}; };
@ -190,6 +191,10 @@ class LUnallocated : public LOperand {
extended_policy() == WRITABLE_REGISTER || extended_policy() == WRITABLE_REGISTER ||
extended_policy() == MUST_HAVE_REGISTER); extended_policy() == MUST_HAVE_REGISTER);
} }
bool HasDoubleRegisterPolicy() const {
return basic_policy() == EXTENDED_POLICY &&
extended_policy() == MUST_HAVE_DOUBLE_REGISTER;
}
bool HasSameAsInputPolicy() const { bool HasSameAsInputPolicy() const {
return basic_policy() == EXTENDED_POLICY && return basic_policy() == EXTENDED_POLICY &&
extended_policy() == SAME_AS_FIRST_INPUT; extended_policy() == SAME_AS_FIRST_INPUT;