blob: 3323564c65d84036d871d0382c21344a4fc445f5 [file] [log] [blame]
buzbee5bc5a7b2012-03-07 15:52:59 -08001#include "asm_support.h"
2
3 .balign 4
4
5 /* Deliver the given exception */
6 .extern artDeliverExceptionFromCode
7 /* Deliver an exception pending on a thread */
8 .extern artDeliverPendingException
9
10 /*
11 * Macro that sets up the callee save frame to conform with
12 * Runtime::CreateCalleeSaveMethod(kSaveAll)
13 * callee-save: s0-s8 + ra, 10 total + 2 words
14 */
15.macro SETUP_CALLEE_SAVE_FRAME
16 addiu sp, sp, 48
17 sw ra, 44(sp)
18 sw s8, 40(sp)
19 sw s7, 36(sp)
20 sw s6, 32(sp)
21 sw s5, 28(sp)
22 sw s4, 24(sp)
23 sw s3, 20(sp)
24 sw s2, 16(sp)
25 sw s1, 12(sp)
26 sw s0, 8(sp)
27 @ 2 open words, bottom will hold Method*
28.endm
29
30 /*
31 * Macro that sets up the callee save frame to conform with
32 * Runtime::CreateCalleeSaveMethod(kRefsOnly). Restoration assumes non-moving GC.
33 * Does not include rSUSPEND or rSELF
34 * callee-save: s2-s8 + ra, 8 total + 4 words
35 */
36.macro SETUP_REF_ONLY_CALLEE_SAVE_FRAME
37 addiu sp, sp, 48
38 sw ra, 44(sp)
39 sw s8, 40(sp)
40 sw s7, 36(sp)
41 sw s6, 32(sp)
42 sw s5, 28(sp)
43 sw s4, 24(sp)
44 sw s3, 20(sp)
45 sw s2, 16(sp)
46 @ 4 open words, bottom will hold Method*
47.endm
48
49.macro RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
50 lw ra, 44(sp)
51 addiu sp, sp, 48
52.endm
53
54.macro RESTORE_REF_ONLY_CALLEE_SAVE_FRAME_AND_RETURN
55 lw ra, 44(sp)
56 jr ra
57 addiu sp, sp, 48
58.endm
59
60 /*
61 * Macro that sets up the callee save frame to conform with
62 * Runtime::CreateCalleeSaveMethod(kRefsAndArgs). Restoration assumes non-moving GC.
63 * a1-a3, s2-s8, ra, 11 total + 1
64 */
65.macro SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
66 addiu sp, sp, 48
67 sw ra, 44(sp)
68 sw s8, 40(sp)
69 sw s7, 36(sp)
70 sw s6, 32(sp)
71 sw s5, 28(sp)
72 sw s4, 24(sp)
73 sw s3, 20(sp)
74 sw s2, 16(sp)
75 sw a3, 12(sp)
76 sw a2, 8(sp)
77 sw a1, 4(sp)
78 @ 1 open word, bottom will hold Method*
79.endm
80
81.macro RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
82 lw ra, 44(sp) @ restore ra
83 lw a1, 4(sp) @ restore non-callee save a1
84 lw a2, 8(sp) @ restore non-callee save a2
85 lw a3, 12(sp) @ restore non-callee save a3
86 addiu sp, sp, 48 @ strip frame
87.endm
88
89 /*
90 * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
91 * exception is Thread::Current()->exception_
92 */
93.macro DELIVER_PENDING_EXCEPTION
94 SETUP_CALLEE_SAVE_FRAME @ save callee saves for throw
95 move a0, rSELF @ pass Thread::Current
96 b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP)
97 move a1, sp @ pass SP
98.endm
99
100.macro RETURN_IF_NO_EXCEPTION
101 lw t0, THREAD_EXCEPTION_OFFSET(rSELF) @ load Thread::Current()->exception_
102 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
103 bnez t0, 1f @ success if no exception is pending
104 nop
105 jr ra
106 nop
1071:
108 DELIVER_PENDING_EXCEPTION
109.endm
110
111.macro RETURN_IF_ZERO
112 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
113 bnez v0, 1f @ success?
114 nop
115 jr ra @ return on success
116 nop
1171:
118 DELIVER_PENDING_EXCEPTION
119.endm
120
121.macro RETURN_IF_NONZERO
122 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
123 beqz v0, 1f @ success?
124 nop
125 jr ra @ return on success
126 nop
1271:
128 DELIVER_PENDING_EXCEPTION
129.endm
130
131 .global art_update_debugger
132 .extern artUpdateDebuggerFromCode
133 /*
134 * On entry, a0 and a1 must be preserved, a2 is dex PC
135 */
136art_update_debugger:
137 move a3, a0 @ stash away a0 so that it's saved as if it were an argument
138 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
139 move a0, a2 @ arg0 is dex PC
140 move a1, rSELF @ arg1 is Thread*
141 move a2, sp @ arg2 is sp
142 jal artUpdateDebuggerFromCode @ artUpdateDebuggerFromCode(int32_t, Thread*, Method**)
143 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
144 jr ra
145 move a0, a3 @ restore original a0
146
147 .global art_do_long_jump
148 /*
149 * On entry a0 is uint32_t* gprs_ and a1 is uint32_t* fprs_
150 * FIXME: just guessing about the shape of the jmpbuf. Where will pc be?
151 */
152art_do_long_jump:
153 l.s f0, 0(a1)
154 l.s f1, 4(a1)
155 l.s f2, 8(a1)
156 l.s f3, 12(a1)
157 l.s f4, 16(a1)
158 l.s f5, 20(a1)
159 l.s f6, 24(a1)
160 l.s f7, 28(a1)
161 l.s f8, 32(a1)
162 l.s f9, 36(a1)
163 l.s f10, 40(a1)
164 l.s f11, 44(a1)
165 l.s f12, 48(a1)
166 l.s f13, 52(a1)
167 l.s f14, 56(a1)
168 l.s f15, 60(a1)
169 l.s f16, 64(a1)
170 l.s f17, 68(a1)
171 l.s f18, 72(a1)
172 l.s f19, 76(a1)
173 l.s f20, 80(a1)
174 l.s f21, 84(a1)
175 l.s f22, 88(a1)
176 l.s f23, 92(a1)
177 l.s f24, 96(a1)
178 l.s f25, 100(a1)
179 l.s f26, 104(a1)
180 l.s f27, 108(a1)
181 l.s f28, 112(a1)
182 l.s f29, 116(a1)
183 l.s f30, 120(a1)
184 l.s f31, 124(a1)
185 lw at, 4(a0)
186 lw v0, 8(a0)
187 lw v1, 12(a0)
188 lw a1, 20(a0)
189 lw a2, 24(a0)
190 lw a3, 28(a0)
191 lw t0, 32(a0)
192 lw t1, 36(a0)
193 lw t2, 40(a0)
194 lw t3, 44(a0)
195 lw t4, 48(a0)
196 lw t5, 52(a0)
197 lw t6, 56(a0)
198 lw t7, 60(a0)
199 lw s0, 64(a0)
200 lw s1, 68(a0)
201 lw s2, 72(a0)
202 lw s3, 76(a0)
203 lw s4, 80(a0)
204 lw s5, 84(a0)
205 lw s6, 88(a0)
206 lw s7, 92(a0)
207 lw t8, 96(a0)
208 lw t9, 100(a0)
209 lw k0, 104(a0)
210 lw k1, 108(a0)
211 lw gp, 112(a0)
212 lw sp, 116(a0)
213 lw fp, 120(a0)
214 lw ra, 124(a0)
215 lw a0, 16(a0)
216 move v0, rzero @ clear result registers r0 and r1
217 jr ra @ do long jump
218 move v1, rzero
219
220 .global art_deliver_exception_from_code
221 /*
222 * Called by managed code, saves most registers (forms basis of long jump context) and passes
223 * the bottom of the stack. artDeliverExceptionFromCode will place the callee save Method* at
224 * the bottom of the thread. On entry r0 holds Throwable*
225 */
226art_deliver_exception_from_code:
227 SETUP_CALLEE_SAVE_FRAME
228 move a1, rSELF @ pass Thread::Current
229 b artDeliverExceptionFromCode @ artDeliverExceptionFromCode(Throwable*, Thread*, SP)
230 move a2, sp @ pass SP
231
232 .global art_throw_null_pointer_exception_from_code
233 .extern artThrowNullPointerExceptionFromCode
234 /*
235 * Called by managed code to create and deliver a NullPointerException
236 */
237art_throw_null_pointer_exception_from_code:
238 SETUP_CALLEE_SAVE_FRAME
239 move a0, rSELF @ pass Thread::Current
240 b artThrowNullPointerExceptionFromCode @ artThrowNullPointerExceptionFromCode(Thread*, SP)
241 move a1, sp @ pass SP
242
243 .global art_throw_div_zero_from_code
244 .extern artThrowDivZeroFromCode
245 /*
246 * Called by managed code to create and deliver an ArithmeticException
247 */
248art_throw_div_zero_from_code:
249 SETUP_CALLEE_SAVE_FRAME
250 move a0, rSELF @ pass Thread::Current
251 b artThrowDivZeroFromCode @ artThrowDivZeroFromCode(Thread*, SP)
252 move a1, sp @ pass SP
253
254 .global art_throw_array_bounds_from_code
255 .extern artThrowArrayBoundsFromCode
256 /*
257 * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException
258 */
259art_throw_array_bounds_from_code:
260 SETUP_CALLEE_SAVE_FRAME
261 move a2, rSELF @ pass Thread::Current
262 b artThrowArrayBoundsFromCode @ artThrowArrayBoundsFromCode(index, limit, Thread*, SP)
263 move a3, sp @ pass SP
264
265 .global art_throw_stack_overflow_from_code
266 .extern artThrowStackOverflowFromCode
267art_throw_stack_overflow_from_code:
268 SETUP_CALLEE_SAVE_FRAME
269 move a1, rSELF @ pass Thread::Current
270 b artThrowStackOverflowFromCode @ artThrowStackOverflowFromCode(method, Thread*, SP)
271 move a2, sp @ pass SP
272
273 .global art_throw_neg_array_size_from_code
274 .extern artThrowNegArraySizeFromCode
275art_throw_neg_array_size_from_code:
276 SETUP_CALLEE_SAVE_FRAME
277 move a1, rSELF @ pass Thread::Current
278 b artThrowNegArraySizeFromCode @ artThrowNegArraySizeFromCode(size, Thread*, SP)
279 move a2, sp @ pass SP
280
281 .global art_throw_no_such_method_from_code
282 .extern artThrowNoSuchMethodFromCode
283art_throw_no_such_method_from_code:
284 SETUP_CALLEE_SAVE_FRAME
285 move a1, rSELF @ pass Thread::Current
286 b artThrowNoSuchMethodFromCode @ artThrowNoSuchMethodFromCode(method_idx, Thread*, SP)
287 move a2, sp @ pass SP
288
289 .global art_throw_verification_error_from_code
290 .extern artThrowVerificationErrorFromCode
291art_throw_verification_error_from_code:
292 SETUP_CALLEE_SAVE_FRAME
293 move a2, rSELF @ pass Thread::Current
294 b artThrowVerificationErrorFromCode @ artThrowVerificationErrorFromCode(kind, ref, Thread*, SP)
295 move a3, sp @ pass SP
296
297 /*
298 * All generated callsites for interface invokes and invocation slow paths will load arguments
299 * as usual - except instead of loading arg0/a0 with the target Method*, arg0/a0 will contain
300 * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the
301 * stack and call the appropriate C helper.
302 * NOTE: "this" is first visable argument of the target, and so can be found in arg1/a1.
303 *
304 * The helper will attempt to locate the target and return a 64-bit result in v0/v1 consisting
305 * of the target Method* in v0 and method->code_ in v1.
306 *
307 * If unsuccessful, the helper will return NULL/NULL. There will bea pending exception in the
308 * thread and we branch to another stub to deliver it.
309 *
310 * On success this wrapper will restore arguments and *jump* to the target, leaving the lr
311 * pointing back to the original caller.
312 */
313.macro INVOKE_TRAMPOLINE c_name, cxx_name
314 .global \c_name
315 .extern \cxx_name
316\c_name:
317 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME @ save callee saves in case allocation triggers GC
318 lw a2, 48(sp) @ pass caller Method*
319 move a3, rSELF @ pass Thread::Current
320 sw sp, 0(sp) @ pass SP
321 jal \cxx_name @ (method_idx, this, caller, Thread*, SP)
322 move t0, v1 @ save v0->code_
323 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
324 bnez v0, 1f
325 nop
326 jr t0
327 nop
3281:
329 DELIVER_PENDING_EXCEPTION
330.endm
331
332INVOKE_TRAMPOLINE art_invoke_interface_trampoline, artInvokeInterfaceTrampoline
333INVOKE_TRAMPOLINE art_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
334
335INVOKE_TRAMPOLINE art_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
336INVOKE_TRAMPOLINE art_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
337INVOKE_TRAMPOLINE art_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
338INVOKE_TRAMPOLINE art_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
339
340 .global art_work_around_app_jni_bugs
341 .extern artWorkAroundAppJniBugs
342 /*
343 * Entry point of native methods when JNI bug compatibility is enabled.
344 */
345art_work_around_app_jni_bugs:
346 @ save registers that may contain arguments and LR that will be crushed by a call
347 addiu sp, sp, -32
348 sw a0, 28(sp)
349 sw a1, 24(sp)
350 sw a2, 20(sp)
351 sw a3, 16(sp)
352 sw ra, 12(sp)
353 move a0, rSELF @ pass Thread::Current
354 jal artWorkAroundAppJniBugs @ (Thread*, SP)
355 move a1, sp @ pass SP
356 move t0, v0 @ save target address
357 lw a0, 28(sp)
358 lw a1, 24(sp)
359 lw a2, 20(sp)
360 lw a3, 16(sp)
361 lw ra, 12(sp)
362 jr t0 @ tail call into JNI routine
363 addiu sp, sp, 32
364
365 .global art_handle_fill_data_from_code
366 .extern artHandleFillArrayDataFromCode
367 /*
368 * Entry from managed code that calls artHandleFillArrayDataFromCode and delivers exception on
369 * failure.
370 */
371art_handle_fill_data_from_code:
372 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case exception allocation triggers GC
373 move a2, rSELF @ pass Thread::Current
374 jal artHandleFillArrayDataFromCode @ (Array* array, const uint16_t* table, Thread*, SP)
375 move a3, sp @ pass SP
376 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
377 bnez v0, 1f @ success?
378 nop
379 jr ra @ return on success
380 nop
3811:
382 DELIVER_PENDING_EXCEPTION
383
384 .global art_lock_object_from_code
385 .extern artLockObjectFromCode
386 /*
387 * Entry from managed code that calls artLockObjectFromCode, may block for GC
388 */
389art_lock_object_from_code:
390 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case we block
391 move a1, rSELF @ pass Thread::Current
392 jal artLockObjectFromCode @ (Object* obj, Thread*, SP)
393 move a2, sp @ pass SP
394 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME_AND_RETURN
395
396 .global art_unlock_object_from_code
397 .extern artUnlockObjectFromCode
398 /*
399 * Entry from managed code that calls artUnlockObjectFromCode and delivers exception on failure.
400 */
401art_unlock_object_from_code:
402 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case exception allocation triggers GC
403 move a1, rSELF @ pass Thread::Current
404 jal artUnlockObjectFromCode @ (Object* obj, Thread*, SP)
405 move a2, sp @ pass SP
406 RETURN_IF_ZERO
407
408 .global art_check_cast_from_code
409 .extern artCheckCastFromCode
410 /*
411 * Entry from managed code that calls artCheckCastFromCode and delivers exception on failure.
412 */
413art_check_cast_from_code:
414 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case exception allocation triggers GC
415 move a2, rSELF @ pass Thread::Current
416 jal artCheckCastFromCode @ (Class* a, Class* b, Thread*, SP)
417 move a3, sp @ pass SP
418 RETURN_IF_ZERO
419
420 .global art_can_put_array_element_from_code
421 .extern artCanPutArrayElementFromCode
422 /*
423 * Entry from managed code that calls artCanPutArrayElementFromCode and delivers exception on
424 * failure.
425 */
426art_can_put_array_element_from_code:
427 bnez a0, 1f @ return if element == NULL
428 nop
429 jr ra
430 nop
4311:
432 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case exception allocation triggers GC
433 move a2, rSELF @ pass Thread::Current
434 jal artCanPutArrayElementFromCode @ (Object* element, Class* array_class, Thread*, SP)
435 move a3, sp @ pass SP
436 RETURN_IF_ZERO
437
438 .global art_initialize_static_storage_from_code
439 .extern artInitializeStaticStorageFromCode
440 /*
441 * Entry from managed code when uninitialized static storage, this stub will run the class
442 * initializer and deliver the exception on error. On success the static storage base is
443 * returned.
444 */
445art_initialize_static_storage_from_code:
446 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
447 move a2, rSELF @ pass Thread::Current
448 @ artInitializeStaticStorageFromCode(uint32_t type_idx, Method* referrer, Thread*, SP)
449 jal artInitializeStaticStorageFromCode
450 move a3, sp @ pass SP
451 RETURN_IF_NONZERO
452
453 .global art_initialize_type_from_code
454 .extern artInitializeTypeFromCode
455 /*
456 * Entry from managed code when dex cache misses for a type_idx
457 */
458art_initialize_type_from_code:
459 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
460 move a2, rSELF @ pass Thread::Current
461 @ artInitializeTypeFromCode(uint32_t type_idx, Method* referrer, Thread*, SP)
462 jal artInitializeTypeFromCode
463 move a3, sp @ pass SP
464 RETURN_IF_NONZERO
465
466 .global art_initialize_type_and_verify_access_from_code
467 .extern artInitializeTypeAndVerifyAccessFromCode
468 /*
469 * Entry from managed code when type_idx needs to be checked for access and dex cache may also
470 * miss
471 */
472art_initialize_type_and_verify_access_from_code:
473 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
474 move a2, rSELF @ pass Thread::Current
475 @ artInitializeTypeFromCode(uint32_t type_idx, Method* referrer, Thread*, SP)
476 jal artInitializeTypeAndVerifyAccessFromCode
477 move a3, sp @ pass SP
478 RETURN_IF_NONZERO
479
480 .global art_get32_static_from_code
481 .extern artGet32StaticFromCode
482 /*
483 * Called by managed code to resolve a static field and load a 32-bit primitive value
484 */
485art_get32_static_from_code:
486 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
487 lw a1, 48(sp) @ pass referrer's Method*
488 move a2, rSELF @ pass Thread::Current
489 jal artGet32StaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP)
490 move a3, sp @ pass SP
491 RETURN_IF_NO_EXCEPTION
492
493 .global art_get64_static_from_code
494 .extern artGet64StaticFromCode
495 /*
496 * Called by managed code to resolve a static field and load a 64-bit primitive value
497 */
498art_get64_static_from_code:
499 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
500 lw a1, 48(sp) @ pass referrer's Method*
501 move a2, rSELF @ pass Thread::Current
502 jal artGet64StaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP)
503 move a3, sp @ pass SP
504 RETURN_IF_NO_EXCEPTION
505
506 .global art_get_obj_static_from_code
507 .extern artGetObjStaticFromCode
508 /*
509 * Called by managed code to resolve a static field and load an object reference
510 */
511art_get_obj_static_from_code:
512 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
513 lw a1, 48(sp) @ pass referrer's Method*
514 move a2, rSELF @ pass Thread::Current
515 jal artGetObjStaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP)
516 move a3, sp @ pass SP
517 RETURN_IF_NO_EXCEPTION
518
519 .global art_get32_instance_from_code
520 .extern artGet32InstanceFromCode
521 /*
522 * Called by managed code to resolve an instance field and load a 32-bit primitive value
523 */
524art_get32_instance_from_code:
525 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
526 lw a2, 48(sp) @ pass referrer's Method*
527 move a3, rSELF @ pass Thread::Current
528 jal artGet32InstanceFromCode @ (field_idx, Object*, referrer, Thread*, SP)
529 sw sp, 0(sp) @ pass SP
530 RETURN_IF_NO_EXCEPTION
531
532 .global art_get64_instance_from_code
533 .extern artGet64InstanceFromCode
534 /*
535 * Called by managed code to resolve an instance field and load a 64-bit primitive value
536 */
537art_get64_instance_from_code:
538 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
539 lw a2, 48(sp) @ pass referrer's Method*
540 move a3, rSELF @ pass Thread::Current
541 jal artGet64InstanceFromCode @ (field_idx, Object*, referrer, Thread*, SP)
542 sw sp, 0(sp) @ pass SP
543 RETURN_IF_NO_EXCEPTION
544
545 .global art_get_obj_instance_from_code
546 .extern artGetObjInstanceFromCode
547 /*
548 * Called by managed code to resolve an instance field and load an object reference
549 */
550art_get_obj_instance_from_code:
551 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
552 lw a2, 48(sp) @ pass referrer's Method*
553 move a3, rSELF @ pass Thread::Current
554 jal artGetObjInstanceFromCode @ (field_idx, Object*, referrer, Thread*, SP)
555 sw sp, 0(sp) @ pass SP
556 RETURN_IF_NO_EXCEPTION
557
558 .global art_set32_static_from_code
559 .extern artSet32StaticFromCode
560 /*
561 * Called by managed code to resolve a static field and store a 32-bit primitive value
562 */
563art_set32_static_from_code:
564 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
565 lw a2, 48(sp) @ pass referrer's Method*
566 move a3, rSELF @ pass Thread::Current
567 jal artSet32StaticFromCode @ (field_idx, new_val, referrer, Thread*, SP)
568 sw sp, 0(sp) @ pass SP
569 RETURN_IF_ZERO
570
571 .global art_set64_static_from_code
572 .extern artSet32StaticFromCode
573 /*
574 * Called by managed code to resolve a static field and store a 64-bit primitive value
575 */
576
577art_set64_static_from_code:
578 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
579 lw a1, 48(sp) @ pass referrer's Method*
580 move t0, sp @ save SP
581 addui sp, sp, -16
582 sw rSELF, 0(sp) @ pass Thread::Current and sp
583 jal artSet64StaticFromCode @ (field_idx, referrer, new_val, Thread*, SP)
584 sw t0, 4(sp)
585 addui sp, #16 @ release out args
586 RETURN_IF_ZERO
587
588 .global art_set_obj_static_from_code
589 .extern artSetObjStaticFromCode
590 /*
591 * Called by managed code to resolve a static field and store an object reference
592 */
593art_set_obj_static_from_code:
594 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
595 lw a2, 48(sp) @ pass referrer's Method*
596 move a3, rSELF @ pass Thread::Current
597 jal artSetObjStaticFromCode @ (field_idx, new_val, referrer, Thread*, SP)
598 sw sp, 0(sp) @ pass SP
599 RETURN_IF_ZERO
600
601 .global art_set32_instance_from_code
602 .extern artSet32InstanceFromCode
603 /*
604 * Called by managed code to resolve an instance field and store a 32-bit primitive value
605 */
606art_set32_instance_from_code:
607 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
608 lw a4, 48(sp) @ pass referrer's Method*
609 move t0, sp @ save SP
610 addui sp, sp, -16
611 sw rSELF, 0(sp) @ pass Thread::Current and sp
612 jal artSet32InstanceFromCode @ (field_idx, Object*, new_val, referrer, Thread*, SP)
613 sw t0, 4(sp)
614 addiu sp, sp, 16 @ release out args
615 RETURN_IF_ZERO
616
617 .global art_set64_instance_from_code
618 .extern artSet32InstanceFromCode
619 /*
620 * Called by managed code to resolve an instance field and store a 64-bit primitive value
621 */
622art_set64_instance_from_code:
623 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
624 move t0, sp @ save SP
625 addui sp, sp, -16
626 sw rSELF, 0(sp) @ pass Thread::Current and sp
627 jal artSet64InstanceFromCode @ (field_idx, Object*, new_val, Thread*, SP)
628 sw t0, 4(sp)
629 addiu sp, sp, 16 @ release out args
630 RETURN_IF_ZERO
631
632 .global art_set_obj_instance_from_code
633 .extern artSetObjInstanceFromCode
634 /*
635 * Called by managed code to resolve an instance field and store an object reference
636 */
637art_set_obj_instance_from_code:
638 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
639 lw a3, 48(sp) @ pass referrer's Method*
640 move t0, sp @ save SP
641 addui sp, sp, -16
642 sw rSELF, 0(sp) @ pass Thread::Current and sp
643 jal artSetObjInstanceFromCode @ (field_idx, Object*, new_val, referrer, Thread*, SP)
644 sw t0, 4(sp)
645 addiu sp, sp, 16 @ release out args
646 RETURN_IF_ZERO
647
648 .global art_resolve_string_from_code
649 .extern artResolveStringFromCode
650 /*
651 * Entry from managed code to resolve a string, this stub will allocate a String and deliver an
652 * exception on error. On success the String is returned. R0 holds the referring method,
653 * R1 holds the string index. The fast path check for hit in strings cache has already been
654 * performed.
655 */
656art_resolve_string_from_code:
657 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
658 move a2, rSELF @ pass Thread::Current
659 @ artResolveStringFromCode(Method* referrer, uint32_t string_idx, Thread*, SP)
660 jal artResolveStringFromCode
661 move a3, sp @ pass SP
662 RETURN_IF_ZERO
663
664 .global art_alloc_object_from_code
665 .extern artAllocObjectFromCode
666 /*
667 * Called by managed code to allocate an object
668 */
669art_alloc_object_from_code:
670 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
671 move a2, rSELF @ pass Thread::Current
672 jal artAllocObjectFromCode @ (uint32_t type_idx, Method* method, Thread*, SP)
673 move a3, sp @ pass SP
674 RETURN_IF_NONZERO
675
676 .global art_alloc_object_from_code_with_access_check
677 .extern artAllocObjectFromCodeWithAccessCheck
678 /*
679 * Called by managed code to allocate an object when the caller doesn't know whether it has
680 * access to the created type
681 */
682art_alloc_object_from_code_with_access_check:
683 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
684 move a2, rSELF @ pass Thread::Current
685 jal artAllocObjectFromCodeWithAccessCheck @ (uint32_t type_idx, Method* method, Thread*, SP)
686 move a3, sp @ pass SP
687 RETURN_IF_NONZERO
688
689 .global art_alloc_array_from_code
690 .extern artAllocArrayFromCode
691 /*
692 * Called by managed code to allocate an array
693 */
694art_alloc_array_from_code:
695 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
696 move a3, r9 @ pass Thread::Current
697 @ artAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t component_count, Thread*, SP)
698 jal artAllocArrayFromCode
699 sw sp, 0(sp) @ pass SP
700 RETURN_IF_NONZERO
701
702 .global art_alloc_array_from_code_with_access_check
703 .extern artAllocArrayFromCodeWithAccessCheck
704 /*
705 * Called by managed code to allocate an array when the caller doesn't know whether it has
706 * access to the created type
707 */
708art_alloc_array_from_code_with_access_check:
709 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
710 move a3, rSELF @ pass Thread::Current
711 @ artAllocArrayFromCodeWithAccessCheck(type_idx, method, component_count, Thread*, SP)
712 jal artAllocArrayFromCodeWithAccessCheck
713 sw sp, 0(sp) @ pass SP
714 RETURN_IF_NONZERO
715
716 .global art_check_and_alloc_array_from_code
717 .extern artCheckAndAllocArrayFromCode
718 /*
719 * Called by managed code to allocate an array in a special case for FILLED_NEW_ARRAY
720 */
721art_check_and_alloc_array_from_code:
722 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
723 move a3, rSELF @ pass Thread::Current
724 @ artCheckAndAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t count, Thread* , SP)
725 jal artCheckAndAllocArrayFromCode
726 sw sp, 0(sp) @ pass SP
727 RETURN_IF_NONZERO
728
729 .global art_check_and_alloc_array_from_code_with_access_check
730 .extern artCheckAndAllocArrayFromCodeWithAccessCheck
731 /*
732 * Called by managed code to allocate an array in a special case for FILLED_NEW_ARRAY
733 */
734art_check_and_alloc_array_from_code_with_access_check:
735 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
736 move a3, rSELF @ pass Thread::Current
737 @ artCheckAndAllocArrayFromCodeWithAccessCheck(type_idx, method, count, Thread* , SP)
738 jal artCheckAndAllocArrayFromCodeWithAccessCheck
739 sw sp, 0(sp) @ pass SP
740 RETURN_IF_NONZERO
741
742 .global art_test_suspend
743 .extern artTestSuspendFromCode
744 /*
745 * Called by managed code when the value in rSUSPEND has been decremented to 0
746 */
747art_test_suspend:
748 lw a0, THREAD_SUSPEND_COUNT_OFFSET(rSELF)
749 bnez a0, 1f
750 move rSUSPEND, SUSPEND_CHECK_INTERVAL @ reset rSUSPEND to SUSPEND_CHECK_INTERVAL
751 jr ra
752 nop
7531:
754 move a0, rSELF
755 SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves for stack crawl
756 jal artTestSuspendFromCode @ (Thread*, SP)
757 move a1, sp
758 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME_AND_RETURN
759
760 .global art_proxy_invoke_handler
761 .extern artProxyInvokeHandler
762 /*
763 * Called by managed code that is attempting to call a method on a proxy class. On entry
764 * r0 holds the proxy method; r1, r2 and r3 may contain arguments
765 */
766art_proxy_invoke_handler:
767 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
768 sw a0, 0(sp) @ place proxy method at bottom of frame
769 move a2, rSELF @ pass Thread::Current
770 jalr artProxyInvokeHandler @ (Method* proxy method, receiver, Thread*, args...)
771 addui a3, sp, 12 @ pointer to r2/r3/LR/caller's Method**/out-args as second arg
772 lw t0, THREAD_EXCEPTION_OFFSET(rSELF) @ load Thread::Current()->exception_
773@FIXME - offsets here are probably wrong
774 lw ra, 44(sp) @ restore ra
775 lw v0, 12(sp)
776 lw v1, 14(sp)
777 bnez r0, 1f
778 addui sp, sp, 48 @ pop frame
779 jr ra
780 nop
7811:
782 DELIVER_PENDING_EXCEPTION
783
784 .global art_trace_entry_from_code
785 .extern artTraceMethodEntryFromCode
786 /*
787 * Routine that intercepts method calls
788 */
789art_trace_entry_from_code:
790 addui sp, sp, -16
791 sw a0, 0(sp)
792 sw a1, 4(sp)
793 sw a2, 8(sp)
794 sw a3, 12(sp)
795 move a2, ra @ pass ra
796 jalr artTraceMethodEntryFromCode @ (Method*, Thread*, LR)
797 move a1, rSELF @ pass Thread::Current
798 move t0, v0 @ t0 holds reference to code
799 lw a0, 0(sp)
800 lw a1, 4(sp)
801 lw a2, 8(sp)
802 lw a3, 12(sp)
803 jalr t0 @ call method
804 addui sp, sp, 16
805 /* intentional fallthrough */
806
807 .global art_trace_exit_from_code
808 .extern artTraceMethodExitFromCode
809 /*
810 * Routine that intercepts method returns
811 */
812art_trace_exit_from_code:
813 addui sp, sp, -16
814 sw v0, 0(sp)
815 jalr artTraceMethodExitFromCode @ ()
816 sw v1, 4(sp)
817 move ra, v0 @ restore link register
818 lw v0, 0(sp)
819 lw v1, 4(sp)
820 jr ra @ return
821 addui sp, sp, 16
822
823 .global art_shl_long
824art_shl_long:
825 /*
826 * Long integer shift. This is different from the generic 32/64-bit
827 * binary operations because vAA/vBB are 64-bit but vCC (the shift
828 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
829 * 6 bits.
830 * On entry:
831 * a0: low word
832 * a1: high word
833 * a2: shift count
834 */
835 /* shl-long vAA, vBB, vCC */
836 sll v0, a0, a2 @ rlo<- alo << (shift&31)
837 not v1, a2 @ rhi<- 31-shift (shift is 5b)
838 srl a0, 1
839 srl a0, v1 @ alo<- alo >> (32-(shift&31))
840 sll v1, a1, a2 @ rhi<- ahi << (shift&31)
841 or v1, a0 @ rhi<- rhi | alo
842 andi a2, 0x20 @ shift< shift & 0x20
843 movn v1, v0, a2 @ rhi<- rlo (if shift&0x20)
844 jr ra
845 movn v0, zero, a2 @ rlo<- 0 (if shift&0x20)
846
847 .balign 4
848 .global art_shr_long
849art_shr_long:
850 /*
851 * Long integer shift. This is different from the generic 32/64-bit
852 * binary operations because vAA/vBB are 64-bit but vCC (the shift
853 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
854 * 6 bits.
855 * On entry:
856 * a0: low word
857 * a1: high word
858 * a2: shift count
859 */
860 sra v1, a1, a2 @ rhi<- ahi >> (shift&31)
861 srl v0, a0, a2 @ rlo<- alo >> (shift&31)
862 sra a3, a1, 31 @ a3<- sign(ah)
863 not a0, a2 @ alo<- 31-shift (shift is 5b)
864 sll a1, 1
865 sll a1, a0 @ ahi<- ahi << (32-(shift&31))
866 or v0, a1 @ rlo<- rlo | ahi
867 andi a2, 0x20 @ shift & 0x20
868 movn v0, v1, a2 @ rlo<- rhi (if shift&0x20)
869 jr ra
870 movn v1, a3, a2 @ rhi<- sign(ahi) (if shift&0x20)
871
872 .balign 4
873 .global art_ushr_long
874art_ushr_long:
875 /*
876 * Long integer shift. This is different from the generic 32/64-bit
877 * binary operations because vAA/vBB are 64-bit but vCC (the shift
878 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
879 * 6 bits.
880 * On entry:
881 * r0: low word
882 * r1: high word
883 * r2: shift count
884 */
885 /* ushr-long vAA, vBB, vCC */
886 sra v1, a1, a2 @ rhi<- ahi >> (shift&31)
887 srl v0, a0, a2 @ rlo<- alo >> (shift&31)
888 sra a3, a1, 31 @ a3<- sign(ah)
889 not a0, a2 @ alo<- 31-shift (shift is 5b)
890 sll a1, 1
891 sll a1, a0 @ ahi<- ahi << (32-(shift&31))
892 or v0, a1 @ rlo<- rlo | ahi
893 andi a2, 0x20 @ shift & 0x20
894 movn v0, v1, a2 @ rlo<- rhi (if shift&0x20)
895 jr ra
896 movn v1, a3, a2 @ rhi<- sign(ahi) (if shift&0x20)