Support unresolved methods in Optimizing

Change-Id: If2da02b50d2fa668cd58f134a005f1752e7746b1
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index 0787e49..bf0d2e2 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -856,6 +856,11 @@
   }
 }
 
+void CodeGeneratorMIPS64::MoveConstant(Location location, int32_t value) {
+  DCHECK(location.IsRegister());
+  __ LoadConst32(location.AsRegister<GpuRegister>(), value);
+}
+
 Location CodeGeneratorMIPS64::GetStackLocation(HLoadLocal* load) const {
   Primitive::Type type = load->GetType();
 
@@ -973,6 +978,16 @@
   stream << Mips64ManagedRegister::FromFpuRegister(FpuRegister(reg));
 }
 
+void CodeGeneratorMIPS64::InvokeRuntime(QuickEntrypointEnum entrypoint,
+                                     HInstruction* instruction,
+                                     uint32_t dex_pc,
+                                     SlowPathCode* slow_path) {
+  InvokeRuntime(GetThreadOffset<kMips64WordSize>(entrypoint).Int32Value(),
+                instruction,
+                dex_pc,
+                slow_path);
+}
+
 void CodeGeneratorMIPS64::InvokeRuntime(int32_t entry_point_offset,
                                         HInstruction* instruction,
                                         uint32_t dex_pc,
@@ -2326,6 +2341,17 @@
   // Will be generated at use site.
 }
 
+void LocationsBuilderMIPS64::VisitInvokeUnresolved(HInvokeUnresolved* invoke) {
+  // The trampoline uses the same calling convention as dex calling conventions,
+  // except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain
+  // the method_idx.
+  HandleInvoke(invoke);
+}
+
+void InstructionCodeGeneratorMIPS64::VisitInvokeUnresolved(HInvokeUnresolved* invoke) {
+  codegen_->GenerateInvokeUnresolvedRuntimeCall(invoke);
+}
+
 void LocationsBuilderMIPS64::HandleInvoke(HInvoke* invoke) {
   InvokeDexCallingConventionVisitorMIPS64 calling_convention_visitor;
   CodeGenerator::CreateCommonInvokeLocationSummary(invoke, &calling_convention_visitor);
@@ -2775,11 +2801,10 @@
   LocationSummary* locations = instruction->GetLocations();
   // Move an uint16_t value to a register.
   __ LoadConst32(locations->GetTemp(0).AsRegister<GpuRegister>(), instruction->GetTypeIndex());
-  codegen_->InvokeRuntime(
-      GetThreadOffset<kMips64WordSize>(instruction->GetEntrypoint()).Int32Value(),
-      instruction,
-      instruction->GetDexPc(),
-      nullptr);
+  codegen_->InvokeRuntime(instruction->GetEntrypoint(),
+                          instruction,
+                          instruction->GetDexPc(),
+                          nullptr);
   CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>();
 }
 
@@ -2796,11 +2821,10 @@
   LocationSummary* locations = instruction->GetLocations();
   // Move an uint16_t value to a register.
   __ LoadConst32(locations->GetTemp(0).AsRegister<GpuRegister>(), instruction->GetTypeIndex());
-  codegen_->InvokeRuntime(
-      GetThreadOffset<kMips64WordSize>(instruction->GetEntrypoint()).Int32Value(),
-      instruction,
-      instruction->GetDexPc(),
-      nullptr);
+  codegen_->InvokeRuntime(instruction->GetEntrypoint(),
+                          instruction,
+                          instruction->GetDexPc(),
+                          nullptr);
   CheckEntrypointTypes<kQuickAllocObjectWithAccessCheck, void*, uint32_t, ArtMethod*>();
 }