blob: 652224368fc132f9da9fb33f01805f4363bdce53 [file] [log] [blame]
Ian Rogers9651f422011-09-19 20:26:07 -07001#include "asm_support.h"
2
buzbee54330722011-08-23 16:46:55 -07003#if defined(__arm__)
4
5 .balign 4
buzbee4a3164f2011-09-03 11:25:10 -07006
Ian Rogers67375ac2011-09-14 00:55:44 -07007 .global art_deliver_exception
8 .extern artDeliverExceptionHelper
Ian Rogersbdb03912011-09-14 00:55:44 -07009 /*
Ian Rogers67375ac2011-09-14 00:55:44 -070010 * Called by managed code, saves mosts registers (forms basis of long jump context).
Ian Rogersbdb03912011-09-14 00:55:44 -070011 * artThrowExceptionHelper will place a mock Method* at the bottom of the thread.
12 * r0 holds Throwable
13 */
Ian Rogers67375ac2011-09-14 00:55:44 -070014art_deliver_exception:
Ian Rogersbdb03912011-09-14 00:55:44 -070015 stmdb sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
Ian Rogers67375ac2011-09-14 00:55:44 -070016 sub sp, #16 @ 4 words of space, bottom word will hold Method*
Ian Rogers9651f422011-09-19 20:26:07 -070017 mov r1, r9 @ pass Thread::Current
18 mov r2, sp @ pass SP
19 b artDeliverExceptionHelper @ artDeliverExceptionHelper(Throwable*, Thread*, SP)
20
21 .global art_throw_null_pointer_exception_from_code
22 .extern artThrowNullPointerExceptionFromCodeHelper
23 /*
24 * Create NPE and deliver
25 */
26art_throw_null_pointer_exception_from_code:
27 stmdb sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
28 sub sp, #16 @ 4 words of space, bottom word will hold Method*
29 mov r0, r9 @ pass Thread::Current
30 mov r1, sp @ pass SP
31 b artThrowNullPointerExceptionFromCodeHelper @ artThrowNullPointerExceptionFromCodeHelper(Thread*, SP)
32
33 .global art_throw_div_zero_from_code
34 .extern artThrowDivZeroFromCodeHelper
35 /*
36 * Create ArithmeticException and deliver
37 */
38art_throw_div_zero_from_code:
39 stmdb sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
40 sub sp, #16 @ 4 words of space, bottom word will hold Method*
41 mov r0, r9 @ pass Thread::Current
42 mov r1, sp @ pass SP
43 b artThrowDivZeroFromCodeHelper @ artThrowDivZeroFromCodeHelper(Thread*, SP)
44
45 .global art_throw_array_bounds_from_code
46 .extern artThrowArrayBoundsFromCodeHelper
47 /*
48 * Create ArrayIndexOutOfBoundsException and deliver
49 */
50art_throw_array_bounds_from_code:
51 stmdb sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
52 sub sp, #16 @ 4 words of space, bottom word will hold Method*
53 mov r2, r9 @ pass Thread::Current
54 mov r3, sp @ pass SP
55 b artThrowArrayBoundsFromCodeHelper @ artThrowArrayBoundsFromCodeHelper(index, limit, Thread*, SP)
Ian Rogersbdb03912011-09-14 00:55:44 -070056
buzbee4a3164f2011-09-03 11:25:10 -070057 .global art_invoke_interface_trampoline
58 .extern artFindInterfaceMethodInCache
59 .extern artFailedInvokeInterface
60art_invoke_interface_trampoline:
61 /*
62 * All generated callsites for interface invokes will load arguments
63 * as usual - except instead of loading arg0/r0 with the target
64 * Method*, arg0/r0 will contain the method_idx. This wrapper will
65 * save arg1-arg3, load the caller's Method*, align the stack and
66 * call the helper artFindInterfaceMethodInCache(idx, this, method);
67 * NOTE: "this" is first visable argument of the target, and so can be
68 * found in arg1/r1.
69 *
70 * artFindInterfaceMethodInCache will attempt to locate the target
71 * and return a 64-bit result in r0/r1 consisting of the target
72 * Method* in r0 and method->code_ in r1.
73 *
74 * If unsuccessful, artFindInterfaceMethodInCache will return
75 * NULL/NULL. This is somewhat different than the usual
76 * mechanism of helper routines performing the unwind & throw.
77 * The reason is that this trampoline is not unwindable. In the
78 * event artFindInterfaceMethodInCache fails to resolve, the wrapper
79 * will prepare an unwindable environment and jump to another helper
80 * to do unwind/throw.
81 *
82 * On success this wrapper will restore arguments and *jump* to the
83 * target, leaving the lr pointing back to the original caller.
84 */
85 stmdb sp!, {r1, r2, r3, lr}
86 ldr r2, [sp, #16] @ load caller's Method*
87 bl artFindInterfaceMethodInCache @ (method_idx, this, callerMethod)
88 mov r12, r1 @ save r0->code_
89 ldmia sp!, {r1, r2, r3, lr} @ restore arguments
90 cmp r0, #0 @ did we find the target?
91 bxne r12 @ tail call to target if so
92 b artFailedInvokeInterface @ Will appear as if called directly
93
buzbee54330722011-08-23 16:46:55 -070094 .global art_shl_long
95art_shl_long:
96 /*
97 * Long integer shift. This is different from the generic 32/64-bit
98 * binary operations because vAA/vBB are 64-bit but vCC (the shift
99 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
100 * 6 bits.
101 * On entry:
102 * r0: low word
103 * r1: high word
104 * r2: shift count
105 */
106 /* shl-long vAA, vBB, vCC */
107 and r2, r2, #63 @ r2<- r2 & 0x3f
108 mov r1, r1, asl r2 @ r1<- r1 << r2
109 rsb r3, r2, #32 @ r3<- 32 - r2
110 orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2))
111 subs ip, r2, #32 @ ip<- r2 - 32
112 movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32)
113 mov r0, r0, asl r2 @ r0<- r0 << r2
114 bx lr
115
116 .balign 4
117 .global art_shr_long
118art_shr_long:
119 /*
120 * Long integer shift. This is different from the generic 32/64-bit
121 * binary operations because vAA/vBB are 64-bit but vCC (the shift
122 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
123 * 6 bits.
124 * On entry:
125 * r0: low word
126 * r1: high word
127 * r2: shift count
128 */
129 /* shr-long vAA, vBB, vCC */
130 and r2, r2, #63 @ r0<- r0 & 0x3f
131 mov r0, r0, lsr r2 @ r0<- r2 >> r2
132 rsb r3, r2, #32 @ r3<- 32 - r2
133 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
134 subs ip, r2, #32 @ ip<- r2 - 32
135 movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32)
136 mov r1, r1, asr r2 @ r1<- r1 >> r2
137 bx lr
138
139 .balign 4
140 .global art_ushr_long
141art_ushr_long:
142 /*
143 * Long integer shift. This is different from the generic 32/64-bit
144 * binary operations because vAA/vBB are 64-bit but vCC (the shift
145 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
146 * 6 bits.
147 * On entry:
148 * r0: low word
149 * r1: high word
150 * r2: shift count
151 */
152 /* ushr-long vAA, vBB, vCC */
153 and r2, r2, #63 @ r0<- r0 & 0x3f
154 mov r0, r0, lsr r2 @ r0<- r2 >> r2
155 rsb r3, r2, #32 @ r3<- 32 - r2
156 orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2))
157 subs ip, r2, #32 @ ip<- r2 - 32
158 movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32)
159 mov r1, r1, lsr r2 @ r1<- r1 >>> r2
160 bx lr
161
buzbeec1f45042011-09-21 16:03:19 -0700162 .balign 4
163 .global art_test_suspend
164 .extern artCheckSuspendFromCode
165art_test_suspend:
166 /*
167 * Check to see if there's a pending suspend request on our thread.
168 * reset rSUSPEND to SUSPEND_CHECK_INTERVAL.
169 * On entry, rSUSPEND holds the suspend request value
170 * [TUNING: move load of suspend check value into this stub.
171 */
172 cmp rSUSPEND, #0
173 mov rSUSPEND, #SUSPEND_CHECK_INTERVAL
174 bxeq rLR
175 mov r0, rSELF
176 b artCheckSuspendFromCode
177
178
buzbee54330722011-08-23 16:46:55 -0700179#endif
Ian Rogers67375ac2011-09-14 00:55:44 -0700180
181#if defined(__i386__)
182
183 .global art_deliver_exception
184 .extern artDeliverExceptionHelper
Ian Rogers67375ac2011-09-14 00:55:44 -0700185 /*
186 * Called by managed code, saves callee saves and then calls artThrowExceptionHelper
187 * that will place a mock Method* at the bottom of the stack.
188 * EAX holds the exception.
189 */
190art_deliver_exception:
191 // Create frame
192 pushl %edi // Save callee saves
193 pushl %esi
194 pushl %ebp
195 pushl %ebx
196 pushl $0
197 pushl $0
198 pushl $0 // Will be clobbered to be Method*
199 mov %esp, %ecx
200 // Outgoing argument set up
201 pushl $0 // Alignment padding
Ian Rogers9651f422011-09-19 20:26:07 -0700202 pushl %ecx // pass SP
203 pushl %fs:THREAD_SELF_OFFSET // pass fs:offsetof(Thread,self_)
204 pushl %eax // pass Throwable*
205 call artDeliverExceptionHelper // artDeliverExceptionHelper(Throwable*, Thread*, SP)
Ian Rogers67375ac2011-09-14 00:55:44 -0700206 int3
207
208#endif