Stop converting from Location to ManagedRegister.

Now the source of truth is the Location object that knows
which register (core, pair, fpu) it needs to refer to.

Change-Id: I62401343d7479ecfb24b5ed161ec7829cda5a0b1
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index f5437a1..393eb1a 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -30,10 +30,6 @@
 
 namespace art {
 
-x86_64::X86_64ManagedRegister Location::AsX86_64() const {
-  return reg().AsX86_64();
-}
-
 namespace x86_64 {
 
 static constexpr bool kExplicitStackOverflowCheck = false;
@@ -44,10 +40,6 @@
 static constexpr int kNumberOfPushedRegistersAtEntry = 1;
 static constexpr int kCurrentMethodStackOffset = 0;
 
-static Location X86_64CpuLocation(Register reg) {
-  return Location::RegisterLocation(X86_64ManagedRegister::FromCpuRegister(reg));
-}
-
 static constexpr Register kRuntimeParameterCoreRegisters[] = { RDI, RSI, RDX };
 static constexpr size_t kRuntimeParameterCoreRegistersLength =
     arraysize(kRuntimeParameterCoreRegisters);
@@ -144,8 +136,8 @@
     CodeGeneratorX86_64* x64_codegen = reinterpret_cast<CodeGeneratorX86_64*>(codegen);
     __ Bind(GetEntryLabel());
     InvokeRuntimeCallingConvention calling_convention;
-    x64_codegen->Move(X86_64CpuLocation(calling_convention.GetRegisterAt(0)), index_location_);
-    x64_codegen->Move(X86_64CpuLocation(calling_convention.GetRegisterAt(1)), length_location_);
+    x64_codegen->Move(Location::RegisterLocation(calling_convention.GetRegisterAt(0)), index_location_);
+    x64_codegen->Move(Location::RegisterLocation(calling_convention.GetRegisterAt(1)), length_location_);
     __ gs()->call(Address::Absolute(
         QUICK_ENTRYPOINT_OFFSET(kX86_64WordSize, pThrowArrayBounds), true));
     codegen->RecordPcInfo(instruction_, instruction_->GetDexPc());
@@ -208,8 +200,8 @@
         assembler_(codegen->GetAssembler()),
         codegen_(codegen) {}
 
-ManagedRegister CodeGeneratorX86_64::AllocateFreeRegister(Primitive::Type type,
-                                                          bool* blocked_registers) const {
+Location CodeGeneratorX86_64::AllocateFreeRegister(Primitive::Type type,
+                                                   bool* blocked_registers) const {
   switch (type) {
     case Primitive::kPrimLong:
     case Primitive::kPrimByte:
@@ -219,21 +211,21 @@
     case Primitive::kPrimInt:
     case Primitive::kPrimNot: {
       size_t reg = AllocateFreeRegisterInternal(blocked_registers, kNumberOfCpuRegisters);
-      return X86_64ManagedRegister::FromCpuRegister(static_cast<Register>(reg));
+      return Location::RegisterLocation(reg);
     }
 
     case Primitive::kPrimFloat:
     case Primitive::kPrimDouble: {
       size_t reg = AllocateFreeRegisterInternal(
           blocked_registers + kNumberOfCpuRegisters, kNumberOfFloatRegisters);
-      return X86_64ManagedRegister::FromXmmRegister(static_cast<FloatRegister>(reg));
+      return Location::FpuRegisterLocation(reg);
     }
 
     case Primitive::kPrimVoid:
       LOG(FATAL) << "Unreachable type " << type;
   }
 
-  return ManagedRegister::NoRegister();
+  return Location();
 }
 
 void CodeGeneratorX86_64::SetupBlockedRegisters(bool* blocked_registers) const {
@@ -331,37 +323,37 @@
   }
   if (destination.IsRegister()) {
     if (source.IsRegister()) {
-      __ movq(destination.AsX86_64().AsCpuRegister(), source.AsX86_64().AsCpuRegister());
+      __ movq(destination.As<CpuRegister>(), source.As<CpuRegister>());
     } else if (source.IsFpuRegister()) {
-      __ movd(destination.AsX86_64().AsCpuRegister(), source.AsX86_64().AsXmmRegister());
+      __ movd(destination.As<CpuRegister>(), source.As<XmmRegister>());
     } else if (source.IsStackSlot()) {
-      __ movl(destination.AsX86_64().AsCpuRegister(),
+      __ movl(destination.As<CpuRegister>(),
               Address(CpuRegister(RSP), source.GetStackIndex()));
     } else {
       DCHECK(source.IsDoubleStackSlot());
-      __ movq(destination.AsX86_64().AsCpuRegister(),
+      __ movq(destination.As<CpuRegister>(),
               Address(CpuRegister(RSP), source.GetStackIndex()));
     }
   } else if (destination.IsFpuRegister()) {
     if (source.IsRegister()) {
-      __ movd(destination.AsX86_64().AsXmmRegister(), source.AsX86_64().AsCpuRegister());
+      __ movd(destination.As<XmmRegister>(), source.As<CpuRegister>());
     } else if (source.IsFpuRegister()) {
-      __ movaps(destination.AsX86_64().AsXmmRegister(), source.AsX86_64().AsXmmRegister());
+      __ movaps(destination.As<XmmRegister>(), source.As<XmmRegister>());
     } else if (source.IsStackSlot()) {
-      __ movss(destination.AsX86_64().AsXmmRegister(),
+      __ movss(destination.As<XmmRegister>(),
               Address(CpuRegister(RSP), source.GetStackIndex()));
     } else {
       DCHECK(source.IsDoubleStackSlot());
-      __ movsd(destination.AsX86_64().AsXmmRegister(),
+      __ movsd(destination.As<XmmRegister>(),
                Address(CpuRegister(RSP), source.GetStackIndex()));
     }
   } else if (destination.IsStackSlot()) {
     if (source.IsRegister()) {
       __ movl(Address(CpuRegister(RSP), destination.GetStackIndex()),
-              source.AsX86_64().AsCpuRegister());
+              source.As<CpuRegister>());
     } else if (source.IsFpuRegister()) {
       __ movss(Address(CpuRegister(RSP), destination.GetStackIndex()),
-               source.AsX86_64().AsXmmRegister());
+               source.As<XmmRegister>());
     } else {
       DCHECK(source.IsStackSlot());
       __ movl(CpuRegister(TMP), Address(CpuRegister(RSP), source.GetStackIndex()));
@@ -371,10 +363,10 @@
     DCHECK(destination.IsDoubleStackSlot());
     if (source.IsRegister()) {
       __ movq(Address(CpuRegister(RSP), destination.GetStackIndex()),
-              source.AsX86_64().AsCpuRegister());
+              source.As<CpuRegister>());
     } else if (source.IsFpuRegister()) {
       __ movsd(Address(CpuRegister(RSP), destination.GetStackIndex()),
-               source.AsX86_64().AsXmmRegister());
+               source.As<XmmRegister>());
     } else {
       DCHECK(source.IsDoubleStackSlot());
       __ movq(CpuRegister(TMP), Address(CpuRegister(RSP), source.GetStackIndex()));
@@ -389,14 +381,14 @@
   if (instruction->AsIntConstant() != nullptr) {
     Immediate imm(instruction->AsIntConstant()->GetValue());
     if (location.IsRegister()) {
-      __ movl(location.AsX86_64().AsCpuRegister(), imm);
+      __ movl(location.As<CpuRegister>(), imm);
     } else {
       __ movl(Address(CpuRegister(RSP), location.GetStackIndex()), imm);
     }
   } else if (instruction->AsLongConstant() != nullptr) {
     int64_t value = instruction->AsLongConstant()->GetValue();
     if (location.IsRegister()) {
-      __ movq(location.AsX86_64().AsCpuRegister(), Immediate(value));
+      __ movq(location.As<CpuRegister>(), Immediate(value));
     } else {
       __ movq(CpuRegister(TMP), Immediate(value));
       __ movq(Address(CpuRegister(RSP), location.GetStackIndex()), CpuRegister(TMP));
@@ -497,7 +489,7 @@
       // Materialized condition, compare against 0.
       Location lhs = if_instr->GetLocations()->InAt(0);
       if (lhs.IsRegister()) {
-        __ cmpl(lhs.AsX86_64().AsCpuRegister(), Immediate(0));
+        __ cmpl(lhs.As<CpuRegister>(), Immediate(0));
       } else {
         __ cmpl(Address(CpuRegister(RSP), lhs.GetStackIndex()), Immediate(0));
       }
@@ -507,12 +499,12 @@
     Location lhs = cond->GetLocations()->InAt(0);
     Location rhs = cond->GetLocations()->InAt(1);
     if (rhs.IsRegister()) {
-      __ cmpl(lhs.AsX86_64().AsCpuRegister(), rhs.AsX86_64().AsCpuRegister());
+      __ cmpl(lhs.As<CpuRegister>(), rhs.As<CpuRegister>());
     } else if (rhs.IsConstant()) {
-      __ cmpl(lhs.AsX86_64().AsCpuRegister(),
+      __ cmpl(lhs.As<CpuRegister>(),
               Immediate(rhs.GetConstant()->AsIntConstant()->GetValue()));
     } else {
-      __ cmpl(lhs.AsX86_64().AsCpuRegister(), Address(CpuRegister(RSP), rhs.GetStackIndex()));
+      __ cmpl(lhs.As<CpuRegister>(), Address(CpuRegister(RSP), rhs.GetStackIndex()));
     }
     __ j(X86_64Condition(cond->AsCondition()->GetCondition()),
          codegen_->GetLabelOf(if_instr->IfTrueSuccessor()));
@@ -578,17 +570,17 @@
 void InstructionCodeGeneratorX86_64::VisitCondition(HCondition* comp) {
   if (comp->NeedsMaterialization()) {
     LocationSummary* locations = comp->GetLocations();
-    CpuRegister reg = locations->Out().AsX86_64().AsCpuRegister();
+    CpuRegister reg = locations->Out().As<CpuRegister>();
     // Clear register: setcc only sets the low byte.
     __ xorq(reg, reg);
     if (locations->InAt(1).IsRegister()) {
-      __ cmpq(locations->InAt(0).AsX86_64().AsCpuRegister(),
-              locations->InAt(1).AsX86_64().AsCpuRegister());
+      __ cmpq(locations->InAt(0).As<CpuRegister>(),
+              locations->InAt(1).As<CpuRegister>());
     } else if (locations->InAt(1).IsConstant()) {
-      __ cmpq(locations->InAt(0).AsX86_64().AsCpuRegister(),
+      __ cmpq(locations->InAt(0).As<CpuRegister>(),
               Immediate(locations->InAt(1).GetConstant()->AsIntConstant()->GetValue()));
     } else {
-      __ cmpq(locations->InAt(0).AsX86_64().AsCpuRegister(),
+      __ cmpq(locations->InAt(0).As<CpuRegister>(),
               Address(CpuRegister(RSP), locations->InAt(1).GetStackIndex()));
     }
     __ setcc(X86_64Condition(comp->GetCondition()), reg);
@@ -656,22 +648,23 @@
   LocationSummary* locations = compare->GetLocations();
   switch (compare->InputAt(0)->GetType()) {
     case Primitive::kPrimLong:
-      __ cmpq(locations->InAt(0).AsX86_64().AsCpuRegister(),
-              locations->InAt(1).AsX86_64().AsCpuRegister());
+      __ cmpq(locations->InAt(0).As<CpuRegister>(),
+              locations->InAt(1).As<CpuRegister>());
       break;
     default:
       LOG(FATAL) << "Unimplemented compare type " << compare->InputAt(0)->GetType();
   }
 
-  __ movl(locations->Out().AsX86_64().AsCpuRegister(), Immediate(0));
+  CpuRegister output = locations->Out().As<CpuRegister>();
+  __ movl(output, Immediate(0));
   __ j(kEqual, &done);
   __ j(kGreater, &greater);
 
-  __ movl(locations->Out().AsX86_64().AsCpuRegister(), Immediate(-1));
+  __ movl(output, Immediate(-1));
   __ jmp(&done);
 
   __ Bind(&greater);
-  __ movl(locations->Out().AsX86_64().AsCpuRegister(), Immediate(1));
+  __ movl(output, Immediate(1));
 
   __ Bind(&done);
 }
@@ -714,13 +707,13 @@
     case Primitive::kPrimInt:
     case Primitive::kPrimNot:
     case Primitive::kPrimLong:
-      locations->SetInAt(0, X86_64CpuLocation(RAX));
+      locations->SetInAt(0, Location::RegisterLocation(RAX));
       break;
 
     case Primitive::kPrimFloat:
     case Primitive::kPrimDouble:
       locations->SetInAt(0,
-          Location::FpuRegisterLocation(X86_64ManagedRegister::FromXmmRegister(XMM0)));
+          Location::FpuRegisterLocation(XMM0));
       break;
 
     default:
@@ -738,12 +731,12 @@
       case Primitive::kPrimInt:
       case Primitive::kPrimNot:
       case Primitive::kPrimLong:
-        DCHECK_EQ(ret->GetLocations()->InAt(0).AsX86_64().AsCpuRegister().AsRegister(), RAX);
+        DCHECK_EQ(ret->GetLocations()->InAt(0).As<CpuRegister>().AsRegister(), RAX);
         break;
 
       case Primitive::kPrimFloat:
       case Primitive::kPrimDouble:
-        DCHECK_EQ(ret->GetLocations()->InAt(0).AsX86_64().AsXmmRegister().AsFloatRegister(),
+        DCHECK_EQ(ret->GetLocations()->InAt(0).As<XmmRegister>().AsFloatRegister(),
                   XMM0);
         break;
 
@@ -766,7 +759,7 @@
       uint32_t index = gp_index_++;
       stack_index_++;
       if (index < calling_convention.GetNumberOfRegisters()) {
-        return X86_64CpuLocation(calling_convention.GetRegisterAt(index));
+        return Location::RegisterLocation(calling_convention.GetRegisterAt(index));
       } else {
         return Location::StackSlot(calling_convention.GetStackOffsetOf(stack_index_ - 1));
       }
@@ -777,7 +770,7 @@
       stack_index_ += 2;
       if (index < calling_convention.GetNumberOfRegisters()) {
         gp_index_ += 1;
-        return X86_64CpuLocation(calling_convention.GetRegisterAt(index));
+        return Location::RegisterLocation(calling_convention.GetRegisterAt(index));
       } else {
         gp_index_ += 2;
         return Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(stack_index_ - 2));
@@ -788,8 +781,7 @@
       uint32_t index = fp_index_++;
       stack_index_++;
       if (index < calling_convention.GetNumberOfFpuRegisters()) {
-        return Location::FpuRegisterLocation(X86_64ManagedRegister::FromXmmRegister(
-            calling_convention.GetFpuRegisterAt(index)));
+        return Location::FpuRegisterLocation(calling_convention.GetFpuRegisterAt(index));
       } else {
         return Location::StackSlot(calling_convention.GetStackOffsetOf(stack_index_ - 1));
       }
@@ -799,8 +791,7 @@
       uint32_t index = fp_index_++;
       stack_index_ += 2;
       if (index < calling_convention.GetNumberOfFpuRegisters()) {
-        return Location::FpuRegisterLocation(X86_64ManagedRegister::FromXmmRegister(
-            calling_convention.GetFpuRegisterAt(index)));
+        return Location::FpuRegisterLocation(calling_convention.GetFpuRegisterAt(index));
       } else {
         return Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(stack_index_ - 2));
       }
@@ -818,7 +809,7 @@
 }
 
 void InstructionCodeGeneratorX86_64::VisitInvokeStatic(HInvokeStatic* invoke) {
-  CpuRegister temp = invoke->GetLocations()->GetTemp(0).AsX86_64().AsCpuRegister();
+  CpuRegister temp = invoke->GetLocations()->GetTemp(0).As<CpuRegister>();
   uint32_t heap_reference_size = sizeof(mirror::HeapReference<mirror::Object>);
   size_t index_in_cache = mirror::Array::DataOffset(heap_reference_size).SizeValue() +
       invoke->GetIndexInDexCache() * heap_reference_size;
@@ -850,7 +841,7 @@
 void LocationsBuilderX86_64::HandleInvoke(HInvoke* invoke) {
   LocationSummary* locations =
       new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall);
-  locations->AddTemp(X86_64CpuLocation(RDI));
+  locations->AddTemp(Location::RegisterLocation(RDI));
 
   InvokeDexCallingConventionVisitor calling_convention_visitor;
   for (size_t i = 0; i < invoke->InputCount(); i++) {
@@ -866,7 +857,7 @@
     case Primitive::kPrimInt:
     case Primitive::kPrimNot:
     case Primitive::kPrimLong:
-      locations->SetOut(X86_64CpuLocation(RAX));
+      locations->SetOut(Location::RegisterLocation(RAX));
       break;
 
     case Primitive::kPrimVoid:
@@ -874,14 +865,13 @@
 
     case Primitive::kPrimDouble:
     case Primitive::kPrimFloat:
-      locations->SetOut(
-          Location::FpuRegisterLocation(X86_64ManagedRegister::FromXmmRegister(XMM0)));
+      locations->SetOut(Location::FpuRegisterLocation(XMM0));
       break;
   }
 }
 
 void InstructionCodeGeneratorX86_64::VisitInvokeVirtual(HInvokeVirtual* invoke) {
-  CpuRegister temp = invoke->GetLocations()->GetTemp(0).AsX86_64().AsCpuRegister();
+  CpuRegister temp = invoke->GetLocations()->GetTemp(0).As<CpuRegister>();
   size_t method_offset = mirror::Class::EmbeddedVTableOffset().SizeValue() +
           invoke->GetVTableIndex() * sizeof(mirror::Class::VTableEntry);
   LocationSummary* locations = invoke->GetLocations();
@@ -892,7 +882,7 @@
     __ movq(temp, Address(CpuRegister(RSP), receiver.GetStackIndex()));
     __ movq(temp, Address(temp, class_offset));
   } else {
-    __ movq(temp, Address(receiver.AsX86_64().AsCpuRegister(), class_offset));
+    __ movq(temp, Address(receiver.As<CpuRegister>(), class_offset));
   }
   // temp = temp->GetMethodAt(method_offset);
   __ movl(temp, Address(temp, method_offset));
@@ -943,28 +933,28 @@
   switch (add->GetResultType()) {
     case Primitive::kPrimInt: {
       if (second.IsRegister()) {
-        __ addl(first.AsX86_64().AsCpuRegister(), second.AsX86_64().AsCpuRegister());
+        __ addl(first.As<CpuRegister>(), second.As<CpuRegister>());
       } else if (second.IsConstant()) {
         HConstant* instruction = second.GetConstant();
         Immediate imm(instruction->AsIntConstant()->GetValue());
-        __ addl(first.AsX86_64().AsCpuRegister(), imm);
+        __ addl(first.As<CpuRegister>(), imm);
       } else {
-        __ addl(first.AsX86_64().AsCpuRegister(),
+        __ addl(first.As<CpuRegister>(),
                 Address(CpuRegister(RSP), second.GetStackIndex()));
       }
       break;
     }
 
     case Primitive::kPrimLong: {
-      __ addq(first.AsX86_64().AsCpuRegister(), second.AsX86_64().AsCpuRegister());
+      __ addq(first.As<CpuRegister>(), second.As<CpuRegister>());
       break;
     }
 
     case Primitive::kPrimFloat: {
       if (second.IsFpuRegister()) {
-        __ addss(first.AsX86_64().AsXmmRegister(), second.AsX86_64().AsXmmRegister());
+        __ addss(first.As<XmmRegister>(), second.As<XmmRegister>());
       } else {
-        __ addss(first.AsX86_64().AsXmmRegister(),
+        __ addss(first.As<XmmRegister>(),
                  Address(CpuRegister(RSP), second.GetStackIndex()));
       }
       break;
@@ -972,10 +962,9 @@
 
     case Primitive::kPrimDouble: {
       if (second.IsFpuRegister()) {
-        __ addsd(first.AsX86_64().AsXmmRegister(), second.AsX86_64().AsXmmRegister());
+        __ addsd(first.As<XmmRegister>(), second.As<XmmRegister>());
       } else {
-        __ addsd(first.AsX86_64().AsXmmRegister(),
-                 Address(CpuRegister(RSP), second.GetStackIndex()));
+        __ addsd(first.As<XmmRegister>(), Address(CpuRegister(RSP), second.GetStackIndex()));
       }
       break;
     }
@@ -1016,26 +1005,26 @@
 
 void InstructionCodeGeneratorX86_64::VisitSub(HSub* sub) {
   LocationSummary* locations = sub->GetLocations();
-  DCHECK_EQ(locations->InAt(0).AsX86_64().AsCpuRegister().AsRegister(),
-            locations->Out().AsX86_64().AsCpuRegister().AsRegister());
+  DCHECK_EQ(locations->InAt(0).As<CpuRegister>().AsRegister(),
+            locations->Out().As<CpuRegister>().AsRegister());
   switch (sub->GetResultType()) {
     case Primitive::kPrimInt: {
       if (locations->InAt(1).IsRegister()) {
-        __ subl(locations->InAt(0).AsX86_64().AsCpuRegister(),
-                locations->InAt(1).AsX86_64().AsCpuRegister());
+        __ subl(locations->InAt(0).As<CpuRegister>(),
+                locations->InAt(1).As<CpuRegister>());
       } else if (locations->InAt(1).IsConstant()) {
         HConstant* instruction = locations->InAt(1).GetConstant();
         Immediate imm(instruction->AsIntConstant()->GetValue());
-        __ subl(locations->InAt(0).AsX86_64().AsCpuRegister(), imm);
+        __ subl(locations->InAt(0).As<CpuRegister>(), imm);
       } else {
-        __ subl(locations->InAt(0).AsX86_64().AsCpuRegister(),
+        __ subl(locations->InAt(0).As<CpuRegister>(),
                 Address(CpuRegister(RSP), locations->InAt(1).GetStackIndex()));
       }
       break;
     }
     case Primitive::kPrimLong: {
-      __ subq(locations->InAt(0).AsX86_64().AsCpuRegister(),
-              locations->InAt(1).AsX86_64().AsCpuRegister());
+      __ subq(locations->InAt(0).As<CpuRegister>(),
+              locations->InAt(1).As<CpuRegister>());
       break;
     }
 
@@ -1055,9 +1044,9 @@
   LocationSummary* locations =
       new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCall);
   InvokeRuntimeCallingConvention calling_convention;
-  locations->AddTemp(X86_64CpuLocation(calling_convention.GetRegisterAt(0)));
-  locations->AddTemp(X86_64CpuLocation(calling_convention.GetRegisterAt(1)));
-  locations->SetOut(X86_64CpuLocation(RAX));
+  locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
+  locations->AddTemp(Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
+  locations->SetOut(Location::RegisterLocation(RAX));
 }
 
 void InstructionCodeGeneratorX86_64::VisitNewInstance(HNewInstance* instruction) {
@@ -1097,9 +1086,9 @@
 
 void InstructionCodeGeneratorX86_64::VisitNot(HNot* instruction) {
   LocationSummary* locations = instruction->GetLocations();
-  DCHECK_EQ(locations->InAt(0).AsX86_64().AsCpuRegister().AsRegister(),
-            locations->Out().AsX86_64().AsCpuRegister().AsRegister());
-  __ xorq(locations->Out().AsX86_64().AsCpuRegister(), Immediate(1));
+  DCHECK_EQ(locations->InAt(0).As<CpuRegister>().AsRegister(),
+            locations->Out().As<CpuRegister>().AsRegister());
+  __ xorq(locations->Out().As<CpuRegister>(), Immediate(1));
 }
 
 void LocationsBuilderX86_64::VisitPhi(HPhi* instruction) {
@@ -1132,8 +1121,8 @@
 
 void InstructionCodeGeneratorX86_64::VisitInstanceFieldSet(HInstanceFieldSet* instruction) {
   LocationSummary* locations = instruction->GetLocations();
-  CpuRegister obj = locations->InAt(0).AsX86_64().AsCpuRegister();
-  CpuRegister value = locations->InAt(1).AsX86_64().AsCpuRegister();
+  CpuRegister obj = locations->InAt(0).As<CpuRegister>();
+  CpuRegister value = locations->InAt(1).As<CpuRegister>();
   size_t offset = instruction->GetFieldOffset().SizeValue();
   Primitive::Type field_type = instruction->GetFieldType();
 
@@ -1154,8 +1143,8 @@
     case Primitive::kPrimNot: {
       __ movl(Address(obj, offset), value);
       if (field_type == Primitive::kPrimNot) {
-        CpuRegister temp = locations->GetTemp(0).AsX86_64().AsCpuRegister();
-        CpuRegister card = locations->GetTemp(1).AsX86_64().AsCpuRegister();
+        CpuRegister temp = locations->GetTemp(0).As<CpuRegister>();
+        CpuRegister card = locations->GetTemp(1).As<CpuRegister>();
         codegen_->MarkGCCard(temp, card, obj, value);
       }
       break;
@@ -1184,8 +1173,8 @@
 
 void InstructionCodeGeneratorX86_64::VisitInstanceFieldGet(HInstanceFieldGet* instruction) {
   LocationSummary* locations = instruction->GetLocations();
-  CpuRegister obj = locations->InAt(0).AsX86_64().AsCpuRegister();
-  CpuRegister out = locations->Out().AsX86_64().AsCpuRegister();
+  CpuRegister obj = locations->InAt(0).As<CpuRegister>();
+  CpuRegister out = locations->Out().As<CpuRegister>();
   size_t offset = instruction->GetFieldOffset().SizeValue();
 
   switch (instruction->GetType()) {
@@ -1246,7 +1235,7 @@
   Location obj = locations->InAt(0);
 
   if (obj.IsRegister()) {
-    __ cmpl(obj.AsX86_64().AsCpuRegister(), Immediate(0));
+    __ cmpl(obj.As<CpuRegister>(), Immediate(0));
   } else if (obj.IsStackSlot()) {
     __ cmpl(Address(CpuRegister(RSP), obj.GetStackIndex()), Immediate(0));
   } else {
@@ -1269,54 +1258,54 @@
 
 void InstructionCodeGeneratorX86_64::VisitArrayGet(HArrayGet* instruction) {
   LocationSummary* locations = instruction->GetLocations();
-  CpuRegister obj = locations->InAt(0).AsX86_64().AsCpuRegister();
+  CpuRegister obj = locations->InAt(0).As<CpuRegister>();
   Location index = locations->InAt(1);
 
   switch (instruction->GetType()) {
     case Primitive::kPrimBoolean: {
       uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint8_t)).Uint32Value();
-      CpuRegister out = locations->Out().AsX86_64().AsCpuRegister();
+      CpuRegister out = locations->Out().As<CpuRegister>();
       if (index.IsConstant()) {
         __ movzxb(out, Address(obj,
             (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset));
       } else {
-        __ movzxb(out, Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_1, data_offset));
+        __ movzxb(out, Address(obj, index.As<CpuRegister>(), TIMES_1, data_offset));
       }
       break;
     }
 
     case Primitive::kPrimByte: {
       uint32_t data_offset = mirror::Array::DataOffset(sizeof(int8_t)).Uint32Value();
-      CpuRegister out = locations->Out().AsX86_64().AsCpuRegister();
+      CpuRegister out = locations->Out().As<CpuRegister>();
       if (index.IsConstant()) {
         __ movsxb(out, Address(obj,
             (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset));
       } else {
-        __ movsxb(out, Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_1, data_offset));
+        __ movsxb(out, Address(obj, index.As<CpuRegister>(), TIMES_1, data_offset));
       }
       break;
     }
 
     case Primitive::kPrimShort: {
       uint32_t data_offset = mirror::Array::DataOffset(sizeof(int16_t)).Uint32Value();
-      CpuRegister out = locations->Out().AsX86_64().AsCpuRegister();
+      CpuRegister out = locations->Out().As<CpuRegister>();
       if (index.IsConstant()) {
         __ movsxw(out, Address(obj,
             (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset));
       } else {
-        __ movsxw(out, Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_2, data_offset));
+        __ movsxw(out, Address(obj, index.As<CpuRegister>(), TIMES_2, data_offset));
       }
       break;
     }
 
     case Primitive::kPrimChar: {
       uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint16_t)).Uint32Value();
-      CpuRegister out = locations->Out().AsX86_64().AsCpuRegister();
+      CpuRegister out = locations->Out().As<CpuRegister>();
       if (index.IsConstant()) {
         __ movzxw(out, Address(obj,
             (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset));
       } else {
-        __ movzxw(out, Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_2, data_offset));
+        __ movzxw(out, Address(obj, index.As<CpuRegister>(), TIMES_2, data_offset));
       }
       break;
     }
@@ -1325,24 +1314,24 @@
     case Primitive::kPrimNot: {
       DCHECK_EQ(sizeof(mirror::HeapReference<mirror::Object>), sizeof(int32_t));
       uint32_t data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value();
-      CpuRegister out = locations->Out().AsX86_64().AsCpuRegister();
+      CpuRegister out = locations->Out().As<CpuRegister>();
       if (index.IsConstant()) {
         __ movl(out, Address(obj,
             (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset));
       } else {
-        __ movl(out, Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_4, data_offset));
+        __ movl(out, Address(obj, index.As<CpuRegister>(), TIMES_4, data_offset));
       }
       break;
     }
 
     case Primitive::kPrimLong: {
       uint32_t data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Uint32Value();
-      CpuRegister out = locations->Out().AsX86_64().AsCpuRegister();
+      CpuRegister out = locations->Out().As<CpuRegister>();
       if (index.IsConstant()) {
         __ movq(out, Address(obj,
             (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset));
       } else {
-        __ movq(out, Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_8, data_offset));
+        __ movq(out, Address(obj, index.As<CpuRegister>(), TIMES_8, data_offset));
       }
       break;
     }
@@ -1363,9 +1352,9 @@
       instruction, is_object ? LocationSummary::kCall : LocationSummary::kNoCall);
   if (is_object) {
     InvokeRuntimeCallingConvention calling_convention;
-    locations->SetInAt(0, X86_64CpuLocation(calling_convention.GetRegisterAt(0)));
-    locations->SetInAt(1, X86_64CpuLocation(calling_convention.GetRegisterAt(1)));
-    locations->SetInAt(2, X86_64CpuLocation(calling_convention.GetRegisterAt(2)));
+    locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0)));
+    locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
+    locations->SetInAt(2, Location::RegisterLocation(calling_convention.GetRegisterAt(2)));
   } else {
     locations->SetInAt(0, Location::RequiresRegister(), Location::kDiesAtEntry);
     locations->SetInAt(
@@ -1381,7 +1370,7 @@
 
 void InstructionCodeGeneratorX86_64::VisitArraySet(HArraySet* instruction) {
   LocationSummary* locations = instruction->GetLocations();
-  CpuRegister obj = locations->InAt(0).AsX86_64().AsCpuRegister();
+  CpuRegister obj = locations->InAt(0).As<CpuRegister>();
   Location index = locations->InAt(1);
   Location value = locations->InAt(2);
   Primitive::Type value_type = instruction->GetComponentType();
@@ -1393,16 +1382,16 @@
       if (index.IsConstant()) {
         size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset;
         if (value.IsRegister()) {
-          __ movb(Address(obj, offset), value.AsX86_64().AsCpuRegister());
+          __ movb(Address(obj, offset), value.As<CpuRegister>());
         } else {
           __ movb(Address(obj, offset), Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
         }
       } else {
         if (value.IsRegister()) {
-          __ movb(Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_1, data_offset),
-                  value.AsX86_64().AsCpuRegister());
+          __ movb(Address(obj, index.As<CpuRegister>(), TIMES_1, data_offset),
+                  value.As<CpuRegister>());
         } else {
-          __ movb(Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_1, data_offset),
+          __ movb(Address(obj, index.As<CpuRegister>(), TIMES_1, data_offset),
                   Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
         }
       }
@@ -1415,16 +1404,16 @@
       if (index.IsConstant()) {
         size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset;
         if (value.IsRegister()) {
-          __ movw(Address(obj, offset), value.AsX86_64().AsCpuRegister());
+          __ movw(Address(obj, offset), value.As<CpuRegister>());
         } else {
           __ movw(Address(obj, offset), Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
         }
       } else {
         if (value.IsRegister()) {
-          __ movw(Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_2, data_offset),
-                  value.AsX86_64().AsCpuRegister());
+          __ movw(Address(obj, index.As<CpuRegister>(), TIMES_2, data_offset),
+                  value.As<CpuRegister>());
         } else {
-          __ movw(Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_2, data_offset),
+          __ movw(Address(obj, index.As<CpuRegister>(), TIMES_2, data_offset),
                   Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
         }
       }
@@ -1436,16 +1425,16 @@
       if (index.IsConstant()) {
         size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
         if (value.IsRegister()) {
-          __ movl(Address(obj, offset), value.AsX86_64().AsCpuRegister());
+          __ movl(Address(obj, offset), value.As<CpuRegister>());
         } else {
           __ movl(Address(obj, offset), Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
         }
       } else {
         if (value.IsRegister()) {
-          __ movl(Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_4, data_offset),
-                  value.AsX86_64().AsCpuRegister());
+          __ movl(Address(obj, index.As<CpuRegister>(), TIMES_4, data_offset),
+                  value.As<CpuRegister>());
         } else {
-          __ movl(Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_4, data_offset),
+          __ movl(Address(obj, index.As<CpuRegister>(), TIMES_4, data_offset),
                   Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
         }
       }
@@ -1464,11 +1453,11 @@
       if (index.IsConstant()) {
         size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset;
         DCHECK(value.IsRegister());
-        __ movq(Address(obj, offset), value.AsX86_64().AsCpuRegister());
+        __ movq(Address(obj, offset), value.As<CpuRegister>());
       } else {
         DCHECK(value.IsRegister());
-        __ movq(Address(obj, index.AsX86_64().AsCpuRegister(), TIMES_8, data_offset),
-                value.AsX86_64().AsCpuRegister());
+        __ movq(Address(obj, index.As<CpuRegister>(), TIMES_8, data_offset),
+                value.As<CpuRegister>());
       }
       break;
     }
@@ -1492,8 +1481,8 @@
 void InstructionCodeGeneratorX86_64::VisitArrayLength(HArrayLength* instruction) {
   LocationSummary* locations = instruction->GetLocations();
   uint32_t offset = mirror::Array::LengthOffset().Uint32Value();
-  CpuRegister obj = locations->InAt(0).AsX86_64().AsCpuRegister();
-  CpuRegister out = locations->Out().AsX86_64().AsCpuRegister();
+  CpuRegister obj = locations->InAt(0).As<CpuRegister>();
+  CpuRegister out = locations->Out().As<CpuRegister>();
   __ movl(out, Address(obj, offset));
 }
 
@@ -1513,8 +1502,8 @@
       instruction, locations->InAt(0), locations->InAt(1));
   codegen_->AddSlowPath(slow_path);
 
-  CpuRegister index = locations->InAt(0).AsX86_64().AsCpuRegister();
-  CpuRegister length = locations->InAt(1).AsX86_64().AsCpuRegister();
+  CpuRegister index = locations->InAt(0).As<CpuRegister>();
+  CpuRegister length = locations->InAt(1).As<CpuRegister>();
 
   __ cmpl(index, length);
   __ j(kAboveEqual, slow_path->GetEntryLabel());
@@ -1596,18 +1585,18 @@
 
   if (source.IsRegister()) {
     if (destination.IsRegister()) {
-      __ movq(destination.AsX86_64().AsCpuRegister(), source.AsX86_64().AsCpuRegister());
+      __ movq(destination.As<CpuRegister>(), source.As<CpuRegister>());
     } else if (destination.IsStackSlot()) {
       __ movl(Address(CpuRegister(RSP), destination.GetStackIndex()),
-              source.AsX86_64().AsCpuRegister());
+              source.As<CpuRegister>());
     } else {
       DCHECK(destination.IsDoubleStackSlot());
       __ movq(Address(CpuRegister(RSP), destination.GetStackIndex()),
-              source.AsX86_64().AsCpuRegister());
+              source.As<CpuRegister>());
     }
   } else if (source.IsStackSlot()) {
     if (destination.IsRegister()) {
-      __ movl(destination.AsX86_64().AsX86_64().AsCpuRegister(),
+      __ movl(destination.As<CpuRegister>(),
               Address(CpuRegister(RSP), source.GetStackIndex()));
     } else {
       DCHECK(destination.IsStackSlot());
@@ -1616,7 +1605,7 @@
     }
   } else if (source.IsDoubleStackSlot()) {
     if (destination.IsRegister()) {
-      __ movq(destination.AsX86_64().AsX86_64().AsCpuRegister(),
+      __ movq(destination.As<CpuRegister>(),
               Address(CpuRegister(RSP), source.GetStackIndex()));
     } else {
       DCHECK(destination.IsDoubleStackSlot());
@@ -1628,14 +1617,14 @@
     if (constant->IsIntConstant()) {
       Immediate imm(constant->AsIntConstant()->GetValue());
       if (destination.IsRegister()) {
-        __ movl(destination.AsX86_64().AsCpuRegister(), imm);
+        __ movl(destination.As<CpuRegister>(), imm);
       } else {
         __ movl(Address(CpuRegister(RSP), destination.GetStackIndex()), imm);
       }
     } else if (constant->IsLongConstant()) {
       int64_t value = constant->AsLongConstant()->GetValue();
       if (destination.IsRegister()) {
-        __ movq(destination.AsX86_64().AsCpuRegister(), Immediate(value));
+        __ movq(destination.As<CpuRegister>(), Immediate(value));
       } else {
         __ movq(CpuRegister(TMP), Immediate(value));
         __ movq(Address(CpuRegister(RSP), destination.GetStackIndex()), CpuRegister(TMP));
@@ -1692,17 +1681,17 @@
   Location destination = move->GetDestination();
 
   if (source.IsRegister() && destination.IsRegister()) {
-    __ xchgq(destination.AsX86_64().AsCpuRegister(), source.AsX86_64().AsCpuRegister());
+    __ xchgq(destination.As<CpuRegister>(), source.As<CpuRegister>());
   } else if (source.IsRegister() && destination.IsStackSlot()) {
-    Exchange32(source.AsX86_64().AsCpuRegister(), destination.GetStackIndex());
+    Exchange32(source.As<CpuRegister>(), destination.GetStackIndex());
   } else if (source.IsStackSlot() && destination.IsRegister()) {
-    Exchange32(destination.AsX86_64().AsCpuRegister(), source.GetStackIndex());
+    Exchange32(destination.As<CpuRegister>(), source.GetStackIndex());
   } else if (source.IsStackSlot() && destination.IsStackSlot()) {
     Exchange32(destination.GetStackIndex(), source.GetStackIndex());
   } else if (source.IsRegister() && destination.IsDoubleStackSlot()) {
-    Exchange64(source.AsX86_64().AsCpuRegister(), destination.GetStackIndex());
+    Exchange64(source.As<CpuRegister>(), destination.GetStackIndex());
   } else if (source.IsDoubleStackSlot() && destination.IsRegister()) {
-    Exchange64(destination.AsX86_64().AsCpuRegister(), source.GetStackIndex());
+    Exchange64(destination.As<CpuRegister>(), source.GetStackIndex());
   } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) {
     Exchange64(destination.GetStackIndex(), source.GetStackIndex());
   } else {