Initial ARM JNI compiler support.
Change-Id: I85183eec9a2645e6cb074b4b18bc6af800a77e06
diff --git a/src/jni_compiler_test.cc b/src/jni_compiler_test.cc
index 225ca5c..9c88c84 100644
--- a/src/jni_compiler_test.cc
+++ b/src/jni_compiler_test.cc
@@ -31,26 +31,47 @@
thk_asm.movl(EDI, Address(ESP, 12)); // EDI = method
thk_asm.pushl(Immediate(0)); // push pad
thk_asm.pushl(Immediate(0)); // push pad
- thk_asm.pushl(Address(ESP, 40)); // push pad or jlong high
- thk_asm.pushl(Address(ESP, 40)); // push jint or jlong low
- thk_asm.pushl(Address(ESP, 40)); // push jint or jlong high
- thk_asm.pushl(Address(ESP, 40)); // push jint or jlong low
- thk_asm.pushl(Address(ESP, 40)); // push jobject
+ thk_asm.pushl(Address(ESP, 44)); // push pad or jlong high
+ thk_asm.pushl(Address(ESP, 44)); // push jint or jlong low
+ thk_asm.pushl(Address(ESP, 44)); // push jint or jlong high
+ thk_asm.pushl(Address(ESP, 44)); // push jint or jlong low
+ thk_asm.pushl(Address(ESP, 44)); // push jobject
thk_asm.call(EAX); // Continue in method->GetCode()
thk_asm.addl(ESP, Immediate(28)); // pop arguments
thk_asm.popl(EDI); // restore EDI
thk_asm.ret();
+#elif defined(__arm__)
+ thk_asm.AddConstant(SP, -32); // Build frame
+ thk_asm.StoreToOffset(kStoreWord, LR, SP, 28); // Spill link register
+ thk_asm.StoreToOffset(kStoreWord, R9, SP, 24); // Spill R9
+ thk_asm.mov(R12, ShifterOperand(R0)); // R12 = method->GetCode()
+ thk_asm.mov(R0, ShifterOperand(R1)); // R0 = method
+ thk_asm.mov(R9, ShifterOperand(R2)); // R9 = Thread::Current()
+ thk_asm.mov(R1, ShifterOperand(R3)); // R1 = arg1 (jint/jlong low)
+ thk_asm.LoadFromOffset(kLoadWord, R3, SP, 44); // R3 = arg5 (pad/jlong high)
+ thk_asm.StoreToOffset(kStoreWord, R3, SP, 4);
+ thk_asm.LoadFromOffset(kLoadWord, R3, SP, 40); // R3 = arg4 (jint/jlong low)
+ thk_asm.StoreToOffset(kStoreWord, R3, SP, 0);
+ thk_asm.LoadFromOffset(kLoadWord, R3, SP, 36); // R3 = arg3 (jint/jlong high)
+ thk_asm.LoadFromOffset(kLoadWord, R2, SP, 32); // R2 = arg2 (jint/jlong high)
+ thk_asm.blx(R12); // Branch and link R12
+ thk_asm.LoadFromOffset(kLoadWord, LR, SP, 28); // Fill link register
+ thk_asm.LoadFromOffset(kLoadWord, R9, SP, 24); // Fill R9
+ thk_asm.AddConstant(SP, 32); // Remove frame
+ thk_asm.mov(PC, ShifterOperand(LR)); // Return
#else
- LOG(FATAL) << "Unimplemented";
+#error Unimplemented
#endif
size_t cs = thk_asm.CodeSize();
MemoryRegion code(thunk_, cs);
thk_asm.FinalizeInstructions(code);
thunk_entry1_ = reinterpret_cast<jint (*)(const void*, art::Method*,
- jobject, jint, jint, jint)
+ Thread*, jobject, jint, jint,
+ jint)
>(code.pointer());
thunk_entry2_ = reinterpret_cast<jdouble (*)(const void*, art::Method*,
- jobject, jdouble, jdouble)
+ Thread*, jobject, jdouble,
+ jdouble)
>(code.pointer());
}
@@ -69,7 +90,8 @@
EXPECT_EQ(0u, Thread::Current()->NumShbHandles());
EXPECT_EQ(Thread::kRunnable, Thread::Current()->GetState());
// perform call
- result.i = (*thunk_entry1_)(method->GetCode(), method, a.l, b.i, c.i, d.i);
+ result.i = (*thunk_entry1_)(method->GetCode(), method, Thread::Current(),
+ a.l, b.i, c.i, d.i);
// sanity check post-call
EXPECT_EQ(0u, Thread::Current()->NumShbHandles());
EXPECT_EQ(Thread::kRunnable, Thread::Current()->GetState());
@@ -85,7 +107,8 @@
EXPECT_EQ(0u, Thread::Current()->NumShbHandles());
EXPECT_EQ(Thread::kRunnable, Thread::Current()->GetState());
// perform call
- result.d = (*thunk_entry2_)(method->GetCode(), method, a.l, b.d, c.d);
+ result.d = (*thunk_entry2_)(method->GetCode(), method, Thread::Current(),
+ a.l, b.d, c.d);
// sanity check post-call
EXPECT_EQ(0u, Thread::Current()->NumShbHandles());
EXPECT_EQ(Thread::kRunnable, Thread::Current()->GetState());
@@ -94,8 +117,10 @@
void* thunk_;
size_t thunk_code_size_;
- jint (*thunk_entry1_)(const void*, Method*, jobject, jint, jint, jint);
- jdouble (*thunk_entry2_)(const void*, Method*, jobject, jdouble, jdouble);
+ jint (*thunk_entry1_)(const void*, Method*, Thread*, jobject, jint, jint,
+ jint);
+ jdouble (*thunk_entry2_)(const void*, Method*, Thread*, jobject, jdouble,
+ jdouble);
};
int gJava_MyClass_foo_calls = 0;