blob: 071108586902b0b8a0efb18b7ca4d9ca9741d542 [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
Shih-wei Liaoc486c112011-09-13 16:43:52 -070012typedef void (*ThrowAme)(Method*, Thread*);
13
14ByteArray* CreateAbstractMethodErrorStub(ThrowAme throw_ame) {
15 UniquePtr<ArmAssembler> assembler( static_cast<ArmAssembler*>(Assembler::Create(kArm)) );
16
17 // R0 is the Method* already.
18
19 // Pass Thread::Current() in R1
20 __ mov(R1, ShifterOperand(R9));
21
22 // Call throw_ame to throw AbstractMethodError
23 __ LoadImmediate(R12, reinterpret_cast<int32_t>(throw_ame));
24 // Leaf call to routine that never returns
25 __ mov(PC, ShifterOperand(R12));
26
27 __ bkpt(0);
28
29 assembler->EmitSlowPaths();
30
31 size_t cs = assembler->CodeSize();
32 ByteArray* abstract_stub = ByteArray::Alloc(cs);
33 CHECK(abstract_stub != NULL);
34 MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
35 assembler->FinalizeInstructions(code);
36
37 return abstract_stub;
38}
39
Shih-wei Liao31384c52011-09-06 15:27:45 -070040ByteArray* CreateJniStub() {
41 UniquePtr<ArmAssembler> assembler( static_cast<ArmAssembler*>(Assembler::Create(kArm)) );
42
43 RegList save = (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) | (1 << LR);
44
45 // Build frame and save registers. Save 5 registers.
46 __ PushList(save);
47 // Ensure 16-byte alignment
48 __ AddConstant(SP, -12);
49
50 // Pass Thread::Current() in R0
51 __ mov(R0, ShifterOperand(R9));
52
53 // Call FindNativeMethod
Brian Carlstrom16192862011-09-12 17:50:06 -070054 __ LoadFromOffset(kLoadWord, R12, TR, OFFSETOF_MEMBER(Thread, pFindNativeMethod));
Shih-wei Liao31384c52011-09-06 15:27:45 -070055 __ blx(R12);
56
57 // Save result of FindNativeMethod in R12
58 __ mov(R12, ShifterOperand(R0));
59
60 // Restore registers (including outgoing arguments)
61 __ AddConstant(SP, 12);
62 __ PopList(save);
63
64 __ cmp(R12, ShifterOperand(0));
65
66 // If R12 != 0 tail call into native code
67 __ mov(PC, ShifterOperand(R12), NE);
68
69 // Return to caller to handle exception
70 __ mov(PC, ShifterOperand(LR));
71
72 assembler->EmitSlowPaths();
73
74 size_t cs = assembler->CodeSize();
75 ByteArray* jni_stub = ByteArray::Alloc(cs);
76 CHECK(jni_stub != NULL);
77 MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength());
78 assembler->FinalizeInstructions(code);
79
80 return jni_stub;
81}
82
83} // namespace arm
84} // namespace art