Fix calling conventions for UnresolvedDirectMethodTrampolineFromCode

Change-Id: I1b35c33d89f0526c80bc8d21e064617d0eac6cd1
diff --git a/src/stub_arm.cc b/src/stub_arm.cc
index 3768721..ae9acd62 100644
--- a/src/stub_arm.cc
+++ b/src/stub_arm.cc
@@ -15,24 +15,30 @@
   // | Out args |
   // | Method*  | <- SP on entry
   // | LR       |    return address into caller
+  // | ...      |    callee saves
   // | R3       |    possible argument
   // | R2       |    possible argument
   // | R1       |    possible argument
-  // | R0       |    method index (loaded from code and method array - will be converted to Method*)
-  RegList save = (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) | (1 << LR);
+  // | R0       |    junk on call to UnresolvedDirectMethodTrampolineFromCode, holds result Method*
+  // | Method*  |    Callee save Method* set up by UnresolvedDirectMethodTrampolineFromCode
+  // Save callee saves and ready frame for exception delivery
+  RegList save = (1 << R1) | (1 << R2) | (1 << R3) | (1 << R5) | (1 << R6) | (1 << R7) | (1 << R8) |
+                 (1 << R10) | (1 << R11) | (1 << LR);
+  // TODO: enable when GetCalleeSaveMethod is available at stub generation time
+  // DCHECK_EQ(save, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetCoreSpillMask());
   __ PushList(save);
-  __ mov(R1, ShifterOperand(SP));  // Pass address of saved R0... in R1
   __ LoadFromOffset(kLoadWord, R12, TR,
                     OFFSETOF_MEMBER(Thread, pUnresolvedDirectMethodTrampolineFromCode));
   __ mov(R2, ShifterOperand(TR));  // Pass Thread::Current() in R2
   __ LoadImmediate(R3, type);
-  __ IncreaseFrameSize(12);        // 3 words of space for alignment
+  __ IncreaseFrameSize(8);         // 2 words of space for alignment
+  __ mov(R1, ShifterOperand(SP));  // Pass SP
   // Call to unresolved direct method trampoline (method_idx, sp, Thread*, is_static)
   __ blx(R12);
   __ mov(R12, ShifterOperand(R0));  // Save code address returned into R12
-  // Restore registers which may have been modified by GC and R0 which will now hold the method*
-  __ DecreaseFrameSize(12);
-  __ PopList(save);
+  // Restore registers which may have been modified by GC, "R0" will hold the Method*
+  __ DecreaseFrameSize(4);
+  __ PopList((1 << R0) | save);
   __ bx(R12);  // Leaf call to method's code
 
   __ bkpt(0);
@@ -54,8 +60,13 @@
   // 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);
+  // TODO: enable when GetCalleeSaveMethod is available at stub generation time
+  // DCHECK_EQ(save, Runtime::Current()->GetCalleeSaveMethod(Runtime::kSaveAll)->GetCoreSpillMask());
   __ PushList(save);         // push {r4-r11, lr} - 9 words of callee saves
+  // TODO: enable when GetCalleeSaveMethod is available at stub generation time
+  // DCHECK_EQ(Runtime::Current()->GetCalleeSaveMethod(Runtime::kSaveAll)->GetFpSpillMask(), 0xFFFFU);
   __ Emit(0xed2d0a20);       // vpush {s0-s31}
+
   __ IncreaseFrameSize(12);  // 3 words of space, bottom word will hold callee save Method*
 
   // R0 is the Method* already