Implement ARM trampoline for llvm compiler.

Change-Id: Id851c4e98d08c2b5b2527860d045d7bed1a9797e
diff --git a/src/oat/runtime/arm/stub_arm.cc b/src/oat/runtime/arm/stub_arm.cc
index d6426e8..5a20748 100644
--- a/src/oat/runtime/arm/stub_arm.cc
+++ b/src/oat/runtime/arm/stub_arm.cc
@@ -27,6 +27,7 @@
 
 ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type) {
   UniquePtr<ArmAssembler> assembler(static_cast<ArmAssembler*>(Assembler::Create(kArm)));
+#if !defined(ART_USE_LLVM_COMPILER)
   // | Out args |
   // | Method*  | <- SP on entry
   // | LR       |    return address into caller
@@ -57,6 +58,25 @@
   __ bx(R12);  // Leaf call to method's code
 
   __ bkpt(0);
+#else // ART_USE_LLVM_COMPILER
+  RegList save = (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) | (1 << LR);
+  __ PushList(save);
+  __ LoadFromOffset(kLoadWord, R12, TR,
+                    ENTRYPOINT_OFFSET(pUnresolvedDirectMethodTrampolineFromCode));
+  __ mov(R2, ShifterOperand(TR));  // Pass Thread::Current() in R2
+  __ LoadImmediate(R3, type);  // Pass is_static
+  __ mov(R1, ShifterOperand(SP));  // Pass sp for Method** callee_addr
+  __ IncreaseFrameSize(12);         // 3 words of space for alignment
+  // Call to unresolved direct method trampoline (callee, callee_addr, Thread*, is_static)
+  __ blx(R12);
+  __ mov(R12, ShifterOperand(R0));  // Save code address returned into R12
+  __ DecreaseFrameSize(12);
+  __ PopList(save);
+  __ cmp(R12, ShifterOperand(0));
+  __ bx(R12, NE);                   // If R12 != 0 tail call method's code
+
+  __ bx(LR);                        // Return to caller to handle exception
+#endif // ART_USE_LLVM_COMPILER
 
   assembler->EmitSlowPaths();
   size_t cs = assembler->CodeSize();
@@ -72,6 +92,7 @@
 
 ByteArray* CreateAbstractMethodErrorStub() {
   UniquePtr<ArmAssembler> assembler(static_cast<ArmAssembler*>(Assembler::Create(kArm)));
+#if !defined(ART_USE_LLVM_COMPILER)
   // Save callee saves and ready frame for exception delivery
   RegList save = (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) | (1 << R8) | (1 << R9) |
                  (1 << R10) | (1 << R11) | (1 << LR);
@@ -92,6 +113,15 @@
   __ mov(PC, ShifterOperand(R12));  // Leaf call to routine that never returns
 
   __ bkpt(0);
+#else // ART_USE_LLVM_COMPILER
+  // R0 is the Method* already
+  __ mov(R1, ShifterOperand(R9));  // Pass Thread::Current() in R1
+  // Call to throw AbstractMethodError
+  __ LoadFromOffset(kLoadWord, R12, TR, ENTRYPOINT_OFFSET(pThrowAbstractMethodErrorFromCode));
+  __ mov(PC, ShifterOperand(R12));  // Leaf call to routine that never returns
+
+  __ bkpt(0);
+#endif // ART_USE_LLVM_COMPILER
 
   assembler->EmitSlowPaths();