blob: 2e2f6a630d159c652f82feaee4787f1d815e7feb [file] [log] [blame]
Shih-wei Liao31384c52011-09-06 15:27:45 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#include "assembler_arm.h"
4#include "jni_internal.h"
5#include "object.h"
6
7#define __ assembler->
8
9namespace art {
10namespace arm {
11
12ByteArray* CreateJniStub() {
13 UniquePtr<ArmAssembler> assembler( static_cast<ArmAssembler*>(Assembler::Create(kArm)) );
14
15 RegList save = (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) | (1 << LR);
16
17 // Build frame and save registers. Save 5 registers.
18 __ PushList(save);
19 // Ensure 16-byte alignment
20 __ AddConstant(SP, -12);
21
22 // Pass Thread::Current() in R0
23 __ mov(R0, ShifterOperand(R9));
24
25 // Call FindNativeMethod
26 __ LoadImmediate(R12, reinterpret_cast<int32_t>(&FindNativeMethod));
27 __ blx(R12);
28
29 // Save result of FindNativeMethod in R12
30 __ mov(R12, ShifterOperand(R0));
31
32 // Restore registers (including outgoing arguments)
33 __ AddConstant(SP, 12);
34 __ PopList(save);
35
36 __ cmp(R12, ShifterOperand(0));
37
38 // If R12 != 0 tail call into native code
39 __ mov(PC, ShifterOperand(R12), NE);
40
41 // Return to caller to handle exception
42 __ mov(PC, ShifterOperand(LR));
43
44 assembler->EmitSlowPaths();
45
46 size_t cs = assembler->CodeSize();
47 ByteArray* jni_stub = ByteArray::Alloc(cs);
48 CHECK(jni_stub != NULL);
49 MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength());
50 assembler->FinalizeInstructions(code);
51
52 return jni_stub;
53}
54
55} // namespace arm
56} // namespace art