ARM64: Introduce TempDoubleRegister as a lithium operand constraint.
authorbaptiste.afsa@arm.com <baptiste.afsa@arm.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 6 May 2014 12:11:00 +0000 (12:11 +0000)
committerbaptiste.afsa@arm.com <baptiste.afsa@arm.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 6 May 2014 12:11:00 +0000 (12:11 +0000)
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

src/arm64/lithium-arm64.cc
src/arm64/lithium-arm64.h
src/lithium-allocator.cc
src/lithium.cc
src/lithium.h

index 604526f..84996d2 100644 (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() {
   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());
index 73e9e45..3abc388 100644 (file)
@@ -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);
 
index 7cbae0c..c6e52ed 100644 (file)
@@ -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<HBasicBlock*>* blocks = graph_->blocks();
   for (int i = 0; i < blocks->length(); ++i) {
     HBasicBlock* block = blocks->at(i);
index 77b0fda..2265353 100644 (file)
@@ -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;
index edeef44..650bae6 100644 (file)
@@ -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;