blob: c62e035dacb54ec97c24d982a3be17234f62f72f [file] [log] [blame]
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "asm_support_mips64.S"
18
19#include "arch/quick_alloc_entrypoints.S"
20
21 .set noreorder
22 .balign 16
23
24 /* Deliver the given exception */
25 .extern artDeliverExceptionFromCode
26 /* Deliver an exception pending on a thread */
27 .extern artDeliverPendingExceptionFromCode
28
29 /*
Goran Jakovljevic04568812015-04-23 15:27:23 +020030 * Macro that sets up $gp and stores the previous $gp value to $t8.
31 * This macro modifies v1 and t8.
32 */
33.macro SETUP_GP
34 move $v1, $ra
35 bal 1f
36 nop
371:
38 .cpsetup $ra, $t8, 1b
39 move $ra, $v1
40.endm
41
42 /*
Andreas Gampe1a5c4062015-01-15 12:10:47 -080043 * Macro that sets up the callee save frame to conform with
44 * Runtime::CreateCalleeSaveMethod(kSaveAll)
45 * callee-save: padding + $f24-$f31 + $s0-$s7 + $gp + $ra + $s8 = 19 total + 1x8 bytes padding
46 */
47.macro SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
48 daddiu $sp, $sp, -160
49 .cfi_adjust_cfa_offset 160
50
51 // Ugly compile-time check, but we only have the preprocessor.
52#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 160)
53#error "SAVE_ALL_CALLEE_SAVE_FRAME(MIPS64) size not as expected."
54#endif
55
56 sd $ra, 152($sp)
57 .cfi_rel_offset 31, 152
58 sd $s8, 144($sp)
59 .cfi_rel_offset 30, 144
Goran Jakovljevic04568812015-04-23 15:27:23 +020060 sd $t8, 136($sp) # t8 holds caller's gp, now save it to the stack.
61 .cfi_rel_offset 28, 136 # Value from gp is pushed, so set the cfi offset accordingly.
Andreas Gampe1a5c4062015-01-15 12:10:47 -080062 sd $s7, 128($sp)
63 .cfi_rel_offset 23, 128
64 sd $s6, 120($sp)
65 .cfi_rel_offset 22, 120
66 sd $s5, 112($sp)
67 .cfi_rel_offset 21, 112
68 sd $s4, 104($sp)
69 .cfi_rel_offset 20, 104
70 sd $s3, 96($sp)
71 .cfi_rel_offset 19, 96
72 sd $s2, 88($sp)
73 .cfi_rel_offset 18, 88
74 sd $s1, 80($sp)
75 .cfi_rel_offset 17, 80
76 sd $s0, 72($sp)
77 .cfi_rel_offset 16, 72
78
79 // FP callee-saves
80 s.d $f31, 64($sp)
81 s.d $f30, 56($sp)
82 s.d $f29, 48($sp)
83 s.d $f28, 40($sp)
84 s.d $f27, 32($sp)
85 s.d $f26, 24($sp)
86 s.d $f25, 16($sp)
87 s.d $f24, 8($sp)
88
89 # load appropriate callee-save-method
90 ld $v0, %got(_ZN3art7Runtime9instance_E)($gp)
91 ld $v0, 0($v0)
92 THIS_LOAD_REQUIRES_READ_BARRIER
Mathieu Chartiere401d142015-04-22 13:56:20 -070093 ld $v0, RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET($v0)
94 sd $v0, 0($sp) # Place ArtMethod* at bottom of stack.
Andreas Gampe1a5c4062015-01-15 12:10:47 -080095 sd $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame.
96.endm
97
98 /*
99 * Macro that sets up the callee save frame to conform with
100 * Runtime::CreateCalleeSaveMethod(kRefsOnly). Restoration assumes
101 * non-moving GC.
102 * Does not include rSUSPEND or rSELF
103 * callee-save: padding + $s2-$s7 + $gp + $ra + $s8 = 9 total + 1x8 bytes padding
104 */
105.macro SETUP_REFS_ONLY_CALLEE_SAVE_FRAME
106 daddiu $sp, $sp, -80
107 .cfi_adjust_cfa_offset 80
108
109 // Ugly compile-time check, but we only have the preprocessor.
110#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 80)
111#error "REFS_ONLY_CALLEE_SAVE_FRAME(MIPS64) size not as expected."
112#endif
113
114 sd $ra, 72($sp)
115 .cfi_rel_offset 31, 72
116 sd $s8, 64($sp)
117 .cfi_rel_offset 30, 64
Goran Jakovljevic04568812015-04-23 15:27:23 +0200118 sd $t8, 56($sp) # t8 holds caller's gp, now save it to the stack.
119 .cfi_rel_offset 28, 56 # Value from gp is pushed, so set the cfi offset accordingly.
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800120 sd $s7, 48($sp)
121 .cfi_rel_offset 23, 48
122 sd $s6, 40($sp)
123 .cfi_rel_offset 22, 40
124 sd $s5, 32($sp)
125 .cfi_rel_offset 21, 32
126 sd $s4, 24($sp)
127 .cfi_rel_offset 20, 24
128 sd $s3, 16($sp)
129 .cfi_rel_offset 19, 16
130 sd $s2, 8($sp)
131 .cfi_rel_offset 18, 8
132 # load appropriate callee-save-method
133 ld $v0, %got(_ZN3art7Runtime9instance_E)($gp)
134 ld $v0, 0($v0)
135 THIS_LOAD_REQUIRES_READ_BARRIER
Mathieu Chartiere401d142015-04-22 13:56:20 -0700136 ld $v0, RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET($v0)
137 sd $v0, 0($sp) # Place Method* at bottom of stack.
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800138 sd $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame.
139.endm
140
141.macro RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
142 ld $ra, 72($sp)
143 .cfi_restore 31
144 ld $s8, 64($sp)
145 .cfi_restore 30
Goran Jakovljevic04568812015-04-23 15:27:23 +0200146 ld $t8, 56($sp) # Restore gp back to it's temp storage.
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800147 .cfi_restore 28
148 ld $s7, 48($sp)
149 .cfi_restore 23
150 ld $s6, 40($sp)
151 .cfi_restore 22
152 ld $s5, 32($sp)
153 .cfi_restore 21
154 ld $s4, 24($sp)
155 .cfi_restore 20
156 ld $s3, 16($sp)
157 .cfi_restore 19
158 ld $s2, 8($sp)
159 .cfi_restore 18
160 daddiu $sp, $sp, 80
161 .cfi_adjust_cfa_offset -80
Goran Jakovljevic04568812015-04-23 15:27:23 +0200162 .cpreturn
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800163.endm
164
165.macro RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME_AND_RETURN
166 ld $ra, 72($sp)
167 .cfi_restore 31
168 ld $s8, 64($sp)
169 .cfi_restore 30
Goran Jakovljevic04568812015-04-23 15:27:23 +0200170 ld $t8, 56($sp) # Restore gp back to it's temp storage.
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800171 .cfi_restore 28
172 ld $s7, 48($sp)
173 .cfi_restore 23
174 ld $s6, 40($sp)
175 .cfi_restore 22
176 ld $s5, 32($sp)
177 .cfi_restore 21
178 ld $s4, 24($sp)
179 .cfi_restore 20
180 ld $s3, 16($sp)
181 .cfi_restore 19
182 ld $s2, 8($sp)
183 .cfi_restore 18
Goran Jakovljevic04568812015-04-23 15:27:23 +0200184 .cpreturn
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800185 jalr $zero, $ra
186 daddiu $sp, $sp, 80
187 .cfi_adjust_cfa_offset -80
188.endm
189
190// This assumes the top part of these stack frame types are identical.
191#define REFS_AND_ARGS_MINUS_REFS_SIZE (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE - FRAME_SIZE_REFS_ONLY_CALLEE_SAVE)
192
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800193.macro SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_INTERNAL
194 daddiu $sp, $sp, -208
195 .cfi_adjust_cfa_offset 208
196
197 // Ugly compile-time check, but we only have the preprocessor.
198#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 208)
199#error "REFS_AND_ARGS_CALLEE_SAVE_FRAME(MIPS64) size not as expected."
200#endif
201
202 sd $ra, 200($sp) # = kQuickCalleeSaveFrame_RefAndArgs_LrOffset
203 .cfi_rel_offset 31, 200
204 sd $s8, 192($sp)
205 .cfi_rel_offset 30, 192
Goran Jakovljevic04568812015-04-23 15:27:23 +0200206 sd $t8, 184($sp) # t8 holds caller's gp, now save it to the stack.
207 .cfi_rel_offset 28, 184 # Value from gp is pushed, so set the cfi offset accordingly.
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800208 sd $s7, 176($sp)
209 .cfi_rel_offset 23, 176
210 sd $s6, 168($sp)
211 .cfi_rel_offset 22, 168
212 sd $s5, 160($sp)
213 .cfi_rel_offset 21, 160
214 sd $s4, 152($sp)
215 .cfi_rel_offset 20, 152
216 sd $s3, 144($sp)
217 .cfi_rel_offset 19, 144
218 sd $s2, 136($sp)
219 .cfi_rel_offset 18, 136
220
221 sd $a7, 128($sp)
222 .cfi_rel_offset 11, 128
223 sd $a6, 120($sp)
224 .cfi_rel_offset 10, 120
225 sd $a5, 112($sp)
226 .cfi_rel_offset 9, 112
227 sd $a4, 104($sp)
228 .cfi_rel_offset 8, 104
229 sd $a3, 96($sp)
230 .cfi_rel_offset 7, 96
231 sd $a2, 88($sp)
232 .cfi_rel_offset 6, 88
233 sd $a1, 80($sp) # = kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset
234 .cfi_rel_offset 5, 80
235
236 s.d $f19, 72($sp)
237 s.d $f18, 64($sp)
238 s.d $f17, 56($sp)
239 s.d $f16, 48($sp)
240 s.d $f15, 40($sp)
241 s.d $f14, 32($sp)
242 s.d $f13, 24($sp) # = kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset
243 s.d $f12, 16($sp) # This isn't necessary to store.
Douglas Leung8223b802015-04-28 17:22:29 -0700244 # 1x8 bytes padding + Method*
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800245.endm
246
Douglas Leung8223b802015-04-28 17:22:29 -0700247 /*
248 * Macro that sets up the callee save frame to conform with
249 * Runtime::CreateCalleeSaveMethod(kRefsAndArgs). Restoration assumes
250 * non-moving GC.
251 * callee-save: padding + $f12-$f19 + $a1-$a7 + $s2-$s7 + $gp + $ra + $s8 = 24 total + 1 words padding + Method*
252 */
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800253.macro SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME
254 SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_INTERNAL
255 # load appropriate callee-save-method
256 ld $v0, %got(_ZN3art7Runtime9instance_E)($gp)
257 ld $v0, 0($v0)
258 THIS_LOAD_REQUIRES_READ_BARRIER
Mathieu Chartiere401d142015-04-22 13:56:20 -0700259 ld $v0, RUNTIME_REFS_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET($v0)
260 sd $v0, 0($sp) # Place Method* at bottom of stack.
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800261 sd $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame.
262.endm
263
Douglas Leung8223b802015-04-28 17:22:29 -0700264.macro SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_A0
265 SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_INTERNAL
Mathieu Chartiere401d142015-04-22 13:56:20 -0700266 sd $a0, 0($sp) # Place Method* at bottom of stack.
Douglas Leung8223b802015-04-28 17:22:29 -0700267 sd $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame.
268.endm
269
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800270.macro RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
271 ld $ra, 200($sp)
272 .cfi_restore 31
273 ld $s8, 192($sp)
274 .cfi_restore 30
Goran Jakovljevic04568812015-04-23 15:27:23 +0200275 ld $t8, 184($sp) # Restore gp back to it's temp storage.
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800276 .cfi_restore 28
277 ld $s7, 176($sp)
278 .cfi_restore 23
279 ld $s6, 168($sp)
280 .cfi_restore 22
281 ld $s5, 160($sp)
282 .cfi_restore 21
283 ld $s4, 152($sp)
284 .cfi_restore 20
285 ld $s3, 144($sp)
286 .cfi_restore 19
287 ld $s2, 136($sp)
288 .cfi_restore 18
289
290 ld $a7, 128($sp)
291 .cfi_restore 11
292 ld $a6, 120($sp)
293 .cfi_restore 10
294 ld $a5, 112($sp)
295 .cfi_restore 9
296 ld $a4, 104($sp)
297 .cfi_restore 8
298 ld $a3, 96($sp)
299 .cfi_restore 7
300 ld $a2, 88($sp)
301 .cfi_restore 6
302 ld $a1, 80($sp)
303 .cfi_restore 5
304
305 l.d $f19, 72($sp)
306 l.d $f18, 64($sp)
307 l.d $f17, 56($sp)
308 l.d $f16, 48($sp)
309 l.d $f15, 40($sp)
310 l.d $f14, 32($sp)
311 l.d $f13, 24($sp)
312 l.d $f12, 16($sp)
313
Goran Jakovljevic04568812015-04-23 15:27:23 +0200314 .cpreturn
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800315 daddiu $sp, $sp, 208
316 .cfi_adjust_cfa_offset -208
317.endm
318
319 /*
320 * Macro that set calls through to artDeliverPendingExceptionFromCode,
321 * where the pending
322 * exception is Thread::Current()->exception_
323 */
324.macro DELIVER_PENDING_EXCEPTION
Goran Jakovljevic04568812015-04-23 15:27:23 +0200325 SETUP_GP
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800326 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME # save callee saves for throw
327 dla $t9, artDeliverPendingExceptionFromCode
328 jalr $zero, $t9 # artDeliverPendingExceptionFromCode(Thread*)
329 move $a0, rSELF # pass Thread::Current
330.endm
331
332.macro RETURN_IF_NO_EXCEPTION
333 ld $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
334 RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
335 bne $t0, $zero, 1f # success if no exception is pending
336 nop
337 jalr $zero, $ra
338 nop
3391:
340 DELIVER_PENDING_EXCEPTION
341.endm
342
343.macro RETURN_IF_ZERO
344 RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
345 bne $v0, $zero, 1f # success?
346 nop
347 jalr $zero, $ra # return on success
348 nop
3491:
350 DELIVER_PENDING_EXCEPTION
351.endm
352
353.macro RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
354 RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
355 beq $v0, $zero, 1f # success?
356 nop
357 jalr $zero, $ra # return on success
358 nop
3591:
360 DELIVER_PENDING_EXCEPTION
361.endm
362
363 /*
364 * On entry $a0 is uint32_t* gprs_ and $a1 is uint32_t* fprs_
365 * FIXME: just guessing about the shape of the jmpbuf. Where will pc be?
366 */
Goran Jakovljevic04568812015-04-23 15:27:23 +0200367ENTRY_NO_GP art_quick_do_long_jump
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800368 l.d $f0, 0($a1)
369 l.d $f1, 8($a1)
370 l.d $f2, 16($a1)
371 l.d $f3, 24($a1)
372 l.d $f4, 32($a1)
373 l.d $f5, 40($a1)
374 l.d $f6, 48($a1)
375 l.d $f7, 56($a1)
376 l.d $f8, 64($a1)
377 l.d $f9, 72($a1)
378 l.d $f10, 80($a1)
379 l.d $f11, 88($a1)
380 l.d $f12, 96($a1)
381 l.d $f13, 104($a1)
382 l.d $f14, 112($a1)
383 l.d $f15, 120($a1)
384 l.d $f16, 128($a1)
385 l.d $f17, 136($a1)
386 l.d $f18, 144($a1)
387 l.d $f19, 152($a1)
388 l.d $f20, 160($a1)
389 l.d $f21, 168($a1)
390 l.d $f22, 176($a1)
391 l.d $f23, 184($a1)
392 l.d $f24, 192($a1)
393 l.d $f25, 200($a1)
394 l.d $f26, 208($a1)
395 l.d $f27, 216($a1)
396 l.d $f28, 224($a1)
397 l.d $f29, 232($a1)
398 l.d $f30, 240($a1)
399 l.d $f31, 248($a1)
400 .set push
401 .set nomacro
402 .set noat
403# no need to load zero
404 ld $at, 8($a0)
405 .set pop
406 ld $v0, 16($a0)
407 ld $v1, 24($a0)
408# a0 has to be loaded last
409 ld $a1, 40($a0)
410 ld $a2, 48($a0)
411 ld $a3, 56($a0)
412 ld $a4, 64($a0)
413 ld $a5, 72($a0)
414 ld $a6, 80($a0)
415 ld $a7, 88($a0)
416 ld $t0, 96($a0)
417 ld $t1, 104($a0)
418 ld $t2, 112($a0)
419 ld $t3, 120($a0)
420 ld $s0, 128($a0)
421 ld $s1, 136($a0)
422 ld $s2, 144($a0)
423 ld $s3, 152($a0)
424 ld $s4, 160($a0)
425 ld $s5, 168($a0)
426 ld $s6, 176($a0)
427 ld $s7, 184($a0)
428 ld $t8, 192($a0)
429 ld $t9, 200($a0)
430# no need to load k0, k1
431 ld $gp, 224($a0)
432 ld $sp, 232($a0)
433 ld $s8, 240($a0)
434 ld $ra, 248($a0)
435 ld $a0, 32($a0)
436 move $v0, $zero # clear result registers v0 and v1
437 jalr $zero, $ra # do long jump
438 move $v1, $zero
439END art_quick_do_long_jump
440
Maja Gagic6ea651f2015-02-24 16:55:04 +0100441 /*
442 * Called by managed code, saves most registers (forms basis of long jump
443 * context) and passes the bottom of the stack.
444 * artDeliverExceptionFromCode will place the callee save Method* at
445 * the bottom of the thread. On entry v0 holds Throwable*
446 */
447ENTRY art_quick_deliver_exception
448 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
449 dla $t9, artDeliverExceptionFromCode
450 jalr $zero, $t9 # artDeliverExceptionFromCode(Throwable*, Thread*)
451 move $a1, rSELF # pass Thread::Current
452END art_quick_deliver_exception
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800453
Maja Gagic6ea651f2015-02-24 16:55:04 +0100454 /*
455 * Called by managed code to create and deliver a NullPointerException
456 */
457 .extern artThrowNullPointerExceptionFromCode
458ENTRY art_quick_throw_null_pointer_exception
459.Lart_quick_throw_null_pointer_exception_gp_set:
460 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
461 dla $t9, artThrowNullPointerExceptionFromCode
462 jalr $zero, $t9 # artThrowNullPointerExceptionFromCode(Thread*)
463 move $a0, rSELF # pass Thread::Current
464END art_quick_throw_null_pointer_exception
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800465
Maja Gagic6ea651f2015-02-24 16:55:04 +0100466 /*
467 * Called by managed code to create and deliver an ArithmeticException
468 */
469 .extern artThrowDivZeroFromCode
470ENTRY art_quick_throw_div_zero
471 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
472 dla $t9, artThrowDivZeroFromCode
473 jalr $zero, $t9 # artThrowDivZeroFromCode(Thread*)
474 move $a0, rSELF # pass Thread::Current
475END art_quick_throw_div_zero
476
477 /*
478 * Called by managed code to create and deliver an
479 * ArrayIndexOutOfBoundsException
480 */
481 .extern artThrowArrayBoundsFromCode
482ENTRY art_quick_throw_array_bounds
483.Lart_quick_throw_array_bounds_gp_set:
484 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
485 dla $t9, artThrowArrayBoundsFromCode
486 jalr $zero, $t9 # artThrowArrayBoundsFromCode(index, limit, Thread*)
487 move $a2, rSELF # pass Thread::Current
488END art_quick_throw_array_bounds
489
490 /*
491 * Called by managed code to create and deliver a StackOverflowError.
492 */
493 .extern artThrowStackOverflowFromCode
494ENTRY art_quick_throw_stack_overflow
495 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
496 dla $t9, artThrowStackOverflowFromCode
497 jalr $zero, $t9 # artThrowStackOverflowFromCode(Thread*)
498 move $a0, rSELF # pass Thread::Current
499END art_quick_throw_stack_overflow
500
501 /*
502 * Called by managed code to create and deliver a NoSuchMethodError.
503 */
504 .extern artThrowNoSuchMethodFromCode
505ENTRY art_quick_throw_no_such_method
506 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
507 dla $t9, artThrowNoSuchMethodFromCode
508 jalr $zero, $t9 # artThrowNoSuchMethodFromCode(method_idx, Thread*)
509 move $a1, rSELF # pass Thread::Current
510END art_quick_throw_no_such_method
511
512 /*
513 * All generated callsites for interface invokes and invocation slow paths will load arguments
514 * as usual - except instead of loading arg0/$a0 with the target Method*, arg0/$a0 will contain
515 * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the
516 * stack and call the appropriate C helper.
517 * NOTE: "this" is first visable argument of the target, and so can be found in arg1/$a1.
518 *
519 * The helper will attempt to locate the target and return a 128-bit result in $v0/$v1 consisting
520 * of the target Method* in $v0 and method->code_ in $v1.
521 *
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700522 * If unsuccessful, the helper will return null/null. There will be a pending exception in the
Maja Gagic6ea651f2015-02-24 16:55:04 +0100523 * thread and we branch to another stub to deliver it.
524 *
525 * On success this wrapper will restore arguments and *jump* to the target, leaving the ra
526 * pointing back to the original caller.
527 */
528.macro INVOKE_TRAMPOLINE c_name, cxx_name
529 .extern \cxx_name
530ENTRY \c_name
531 SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME # save callee saves in case allocation triggers GC
Nicolas Geoffray7ea6a172015-05-19 18:58:54 +0100532 move $a2, rSELF # pass Thread::Current
533 jal \cxx_name # (method_idx, this, Thread*, $sp)
534 move $a3, $sp # pass $sp
Maja Gagic6ea651f2015-02-24 16:55:04 +0100535 move $a0, $v0 # save target Method*
536 move $t9, $v1 # save $v0->code_
537 RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
538 beq $v0, $zero, 1f
539 nop
540 jalr $zero, $t9
541 nop
5421:
543 DELIVER_PENDING_EXCEPTION
544END \c_name
545.endm
546
547INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline, artInvokeInterfaceTrampoline
548INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
549
550INVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
551INVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
552INVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
553INVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800554
555 # On entry:
556 # t0 = shorty
557 # t1 = ptr to arg_array
558 # t2 = number of argument bytes remain
559 # v0 = ptr to stack frame where to copy arg_array
560 # This macro modifies t3, t9 and v0
561.macro LOOP_OVER_SHORTY_LOADING_REG gpu, fpu, label
562 lbu $t3, 0($t0) # get argument type from shorty
563 beqz $t3, \label
564 daddiu $t0, 1
565 li $t9, 68 # put char 'D' into t9
566 beq $t9, $t3, 1f # branch if result type char == 'D'
567 li $t9, 70 # put char 'F' into t9
568 beq $t9, $t3, 2f # branch if result type char == 'F'
569 li $t9, 74 # put char 'J' into t9
570 beq $t9, $t3, 3f # branch if result type char == 'J'
571 nop
Maja Gagic6ea651f2015-02-24 16:55:04 +0100572 lw $\gpu, 0($t1)
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800573 sw $\gpu, 0($v0)
574 daddiu $v0, 4
575 daddiu $t1, 4
576 b 4f
577 daddiu $t2, -4 # delay slot
578
5791: # found double
580 lwu $t3, 0($t1)
581 mtc1 $t3, $\fpu
582 sw $t3, 0($v0)
583 lwu $t3, 4($t1)
584 mthc1 $t3, $\fpu
585 sw $t3, 4($v0)
586 daddiu $v0, 8
587 daddiu $t1, 8
588 b 4f
589 daddiu $t2, -8 # delay slot
590
5912: # found float
592 lwu $t3, 0($t1)
593 mtc1 $t3, $\fpu
594 sw $t3, 0($v0)
595 daddiu $v0, 4
596 daddiu $t1, 4
597 b 4f
598 daddiu $t2, -4 # delay slot
599
6003: # found long (8 bytes)
601 lwu $t3, 0($t1)
602 sw $t3, 0($v0)
603 lwu $t9, 4($t1)
604 sw $t9, 4($v0)
605 dsll $t9, $t9, 32
606 or $\gpu, $t9, $t3
607 daddiu $v0, 8
608 daddiu $t1, 8
609 daddiu $t2, -8
6104:
611.endm
612
613 /*
614 * Invocation stub for quick code.
615 * On entry:
616 * a0 = method pointer
617 * a1 = argument array that must at least contain the this ptr.
618 * a2 = size of argument array in bytes
619 * a3 = (managed) thread pointer
620 * a4 = JValue* result
621 * a5 = shorty
622 */
Goran Jakovljevic04568812015-04-23 15:27:23 +0200623ENTRY_NO_GP art_quick_invoke_stub
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800624 # push a4, a5, s0(rSUSPEND), s1(rSELF), s8, ra onto the stack
625 daddiu $sp, $sp, -48
626 .cfi_adjust_cfa_offset 48
627 sd $ra, 40($sp)
628 .cfi_rel_offset 31, 40
629 sd $s8, 32($sp)
630 .cfi_rel_offset 30, 32
631 sd $s1, 24($sp)
632 .cfi_rel_offset 17, 24
633 sd $s0, 16($sp)
634 .cfi_rel_offset 16, 16
635 sd $a5, 8($sp)
636 .cfi_rel_offset 9, 8
637 sd $a4, 0($sp)
638 .cfi_rel_offset 8, 0
639
640 daddiu $s0, $zero, SUSPEND_CHECK_INTERVAL # reset rSUSPEND to SUSPEND_CHECK_INTERVAL
641 move $s1, $a3 # move managed thread pointer into s1 (rSELF)
642 move $s8, $sp # save sp in s8 (fp)
643
Mathieu Chartiere401d142015-04-22 13:56:20 -0700644 daddiu $t3, $a2, 24 # add 8 for ArtMethod* and 16 for stack alignment
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800645 dsrl $t3, $t3, 4 # shift the frame size right 4
646 dsll $t3, $t3, 4 # shift the frame size left 4 to align to 16 bytes
647 dsubu $sp, $sp, $t3 # reserve stack space for argument array
648
649 daddiu $t0, $a5, 1 # t0 = shorty[1] (skip 1 for return type)
650 daddiu $t1, $a1, 4 # t1 = ptr to arg_array[4] (skip this ptr)
651 daddiu $t2, $a2, -4 # t2 = number of argument bytes remain (skip this ptr)
652 daddiu $v0, $sp, 8 # v0 points to where to copy arg_array
653 LOOP_OVER_SHORTY_LOADING_REG a2, f14, call_fn
654 LOOP_OVER_SHORTY_LOADING_REG a3, f15, call_fn
655 LOOP_OVER_SHORTY_LOADING_REG a4, f16, call_fn
656 LOOP_OVER_SHORTY_LOADING_REG a5, f17, call_fn
657 LOOP_OVER_SHORTY_LOADING_REG a6, f18, call_fn
658 LOOP_OVER_SHORTY_LOADING_REG a7, f19, call_fn
659
660 # copy arguments onto stack (t2 should be multiples of 4)
661 ble $t2, $zero, call_fn # t2 = number of argument bytes remain
6621:
663 lw $t3, 0($t1) # load from argument array
664 daddiu $t1, $t1, 4
665 sw $t3, 0($v0) # save to stack
666 daddiu $t2, -4
667 bgt $t2, $zero, 1b # t2 = number of argument bytes remain
668 daddiu $v0, $v0, 4
669
670call_fn:
671 # call method (a0 and a1 have been untouched)
672 lwu $a1, 0($a1) # make a1 = this ptr
Mathieu Chartiere401d142015-04-22 13:56:20 -0700673 sw $a1, 8($sp) # copy this ptr (skip 8 bytes for ArtMethod*)
674 sd $zero, 0($sp) # store null for ArtMethod* at bottom of frame
675 ld $t9, ART_METHOD_QUICK_CODE_OFFSET_64($a0) # get pointer to the code
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800676 jalr $t9 # call the method
677 nop
678 move $sp, $s8 # restore sp
679
680 # pop a4, a5, s1(rSELF), s8, ra off of the stack
681 ld $a4, 0($sp)
682 .cfi_restore 8
683 ld $a5, 8($sp)
684 .cfi_restore 9
685 ld $s0, 16($sp)
686 .cfi_restore 16
687 ld $s1, 24($sp)
688 .cfi_restore 17
689 ld $s8, 32($sp)
690 .cfi_restore 30
691 ld $ra, 40($sp)
692 .cfi_restore 31
693 daddiu $sp, $sp, 48
694 .cfi_adjust_cfa_offset -48
695
696 # a4 = JValue* result
697 # a5 = shorty string
698 lbu $t1, 0($a5) # get result type from shorty
699 li $t2, 68 # put char 'D' into t2
700 beq $t1, $t2, 1f # branch if result type char == 'D'
701 li $t3, 70 # put char 'F' into t3
702 beq $t1, $t3, 1f # branch if result type char == 'F'
703 sw $v0, 0($a4) # store the result
704 dsrl $v1, $v0, 32
705 jalr $zero, $ra
706 sw $v1, 4($a4) # store the other half of the result
7071:
708 mfc1 $v0, $f0
709 mfhc1 $v1, $f0
710 sw $v0, 0($a4) # store the result
711 jalr $zero, $ra
712 sw $v1, 4($a4) # store the other half of the result
713END art_quick_invoke_stub
714
715 /*
716 * Invocation static stub for quick code.
717 * On entry:
718 * a0 = method pointer
719 * a1 = argument array that must at least contain the this ptr.
720 * a2 = size of argument array in bytes
721 * a3 = (managed) thread pointer
722 * a4 = JValue* result
723 * a5 = shorty
724 */
Goran Jakovljevic04568812015-04-23 15:27:23 +0200725ENTRY_NO_GP art_quick_invoke_static_stub
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800726
727 # push a4, a5, s0(rSUSPEND), s1(rSELF), s8, ra, onto the stack
728 daddiu $sp, $sp, -48
729 .cfi_adjust_cfa_offset 48
730 sd $ra, 40($sp)
731 .cfi_rel_offset 31, 40
732 sd $s8, 32($sp)
733 .cfi_rel_offset 30, 32
734 sd $s1, 24($sp)
735 .cfi_rel_offset 17, 24
736 sd $s0, 16($sp)
737 .cfi_rel_offset 16, 16
738 sd $a5, 8($sp)
739 .cfi_rel_offset 9, 8
740 sd $a4, 0($sp)
741 .cfi_rel_offset 8, 0
742
743 daddiu $s0, $zero, SUSPEND_CHECK_INTERVAL # reset rSUSPEND to SUSPEND_CHECK_INTERVAL
744 move $s1, $a3 # move managed thread pointer into s1 (rSELF)
745 move $s8, $sp # save sp in s8 (fp)
746
Mathieu Chartiere401d142015-04-22 13:56:20 -0700747 daddiu $t3, $a2, 24 # add 8 for ArtMethod* and 16 for stack alignment
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800748 dsrl $t3, $t3, 4 # shift the frame size right 4
749 dsll $t3, $t3, 4 # shift the frame size left 4 to align to 16 bytes
750 dsubu $sp, $sp, $t3 # reserve stack space for argument array
751
752 daddiu $t0, $a5, 1 # t0 = shorty[1] (skip 1 for return type)
753 move $t1, $a1 # t1 = arg_array
754 move $t2, $a2 # t2 = number of argument bytes remain
Mathieu Chartiere401d142015-04-22 13:56:20 -0700755 daddiu $v0, $sp, 8 # v0 points to where to copy arg_array
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800756 LOOP_OVER_SHORTY_LOADING_REG a1, f13, call_sfn
757 LOOP_OVER_SHORTY_LOADING_REG a2, f14, call_sfn
758 LOOP_OVER_SHORTY_LOADING_REG a3, f15, call_sfn
759 LOOP_OVER_SHORTY_LOADING_REG a4, f16, call_sfn
760 LOOP_OVER_SHORTY_LOADING_REG a5, f17, call_sfn
761 LOOP_OVER_SHORTY_LOADING_REG a6, f18, call_sfn
762 LOOP_OVER_SHORTY_LOADING_REG a7, f19, call_sfn
763
764 # copy arguments onto stack (t2 should be multiples of 4)
765 ble $t2, $zero, call_sfn # t2 = number of argument bytes remain
7661:
767 lw $t3, 0($t1) # load from argument array
768 daddiu $t1, $t1, 4
769 sw $t3, 0($v0) # save to stack
770 daddiu $t2, -4
771 bgt $t2, $zero, 1b # t2 = number of argument bytes remain
772 daddiu $v0, $v0, 4
773
774call_sfn:
775 # call method (a0 has been untouched)
Mathieu Chartiere401d142015-04-22 13:56:20 -0700776 sd $zero, 0($sp) # store null for ArtMethod* at bottom of frame
777 ld $t9, ART_METHOD_QUICK_CODE_OFFSET_64($a0) # get pointer to the code
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800778 jalr $t9 # call the method
779 nop
780 move $sp, $s8 # restore sp
781
782 # pop a4, a5, s0(rSUSPEND), s1(rSELF), s8, ra off of the stack
783 ld $a4, 0($sp)
784 .cfi_restore 8
785 ld $a5, 8($sp)
786 .cfi_restore 9
787 ld $s0, 16($sp)
788 .cfi_restore 16
789 ld $s1, 24($sp)
790 .cfi_restore 17
791 ld $s8, 32($sp)
792 .cfi_restore 30
793 ld $ra, 40($sp)
794 .cfi_restore 31
795 daddiu $sp, $sp, 48
796 .cfi_adjust_cfa_offset -48
797
798 # a4 = JValue* result
799 # a5 = shorty string
800 lbu $t1, 0($a5) # get result type from shorty
801 li $t2, 68 # put char 'D' into t2
802 beq $t1, $t2, 1f # branch if result type char == 'D'
803 li $t3, 70 # put char 'F' into t3
804 beq $t1, $t3, 1f # branch if result type char == 'F'
805 sw $v0, 0($a4) # store the result
806 dsrl $v1, $v0, 32
807 jalr $zero, $ra
808 sw $v1, 4($a4) # store the other half of the result
8091:
810 mfc1 $v0, $f0
811 mfhc1 $v1, $f0
812 sw $v0, 0($a4) # store the result
813 jalr $zero, $ra
814 sw $v1, 4($a4) # store the other half of the result
815END art_quick_invoke_static_stub
816
Maja Gagic6ea651f2015-02-24 16:55:04 +0100817 /*
818 * Entry from managed code that calls artHandleFillArrayDataFromCode and
819 * delivers exception on failure.
820 */
821 .extern artHandleFillArrayDataFromCode
822ENTRY art_quick_handle_fill_data
823 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case exception allocation triggers GC
Mathieu Chartiere401d142015-04-22 13:56:20 -0700824 ld $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +0100825 jal artHandleFillArrayDataFromCode # (payload offset, Array*, method, Thread*)
826 move $a3, rSELF # pass Thread::Current
827 RETURN_IF_ZERO
828END art_quick_handle_fill_data
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800829
Maja Gagic6ea651f2015-02-24 16:55:04 +0100830 /*
831 * Entry from managed code that calls artLockObjectFromCode, may block for GC.
832 */
833 .extern artLockObjectFromCode
834ENTRY art_quick_lock_object
835 beq $a0, $zero, .Lart_quick_throw_null_pointer_exception_gp_set
836 nop
837 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case we block
838 jal artLockObjectFromCode # (Object* obj, Thread*)
839 move $a1, rSELF # pass Thread::Current
840 RETURN_IF_ZERO
841END art_quick_lock_object
Andreas Gampe1a5c4062015-01-15 12:10:47 -0800842
Maja Gagic6ea651f2015-02-24 16:55:04 +0100843 /*
844 * Entry from managed code that calls artUnlockObjectFromCode and delivers exception on failure.
845 */
846 .extern artUnlockObjectFromCode
847ENTRY art_quick_unlock_object
848 beq $a0, $zero, .Lart_quick_throw_null_pointer_exception_gp_set
849 nop
850 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case exception allocation triggers GC
851 jal artUnlockObjectFromCode # (Object* obj, Thread*)
852 move $a1, rSELF # pass Thread::Current
853 RETURN_IF_ZERO
854END art_quick_unlock_object
855
856 /*
857 * Entry from managed code that calls artCheckCastFromCode and delivers exception on failure.
858 */
859 .extern artThrowClassCastException
860ENTRY art_quick_check_cast
861 daddiu $sp, $sp, -32
862 .cfi_adjust_cfa_offset 32
863 sd $ra, 24($sp)
864 .cfi_rel_offset 31, 24
865 sd $t9, 16($sp)
866 sd $a1, 8($sp)
867 sd $a0, 0($sp)
868 jal artIsAssignableFromCode
Goran Jakovljevic04568812015-04-23 15:27:23 +0200869 .cpreturn # Restore gp from t8 in branch delay slot.
870 # t8 may be clobbered in artIsAssignableFromCode.
Maja Gagic6ea651f2015-02-24 16:55:04 +0100871 beq $v0, $zero, .Lthrow_class_cast_exception
872 ld $ra, 24($sp)
873 jalr $zero, $ra
874 daddiu $sp, $sp, 32
875 .cfi_adjust_cfa_offset -32
876.Lthrow_class_cast_exception:
877 ld $t9, 16($sp)
878 ld $a1, 8($sp)
879 ld $a0, 0($sp)
880 daddiu $sp, $sp, 32
881 .cfi_adjust_cfa_offset -32
Goran Jakovljevic04568812015-04-23 15:27:23 +0200882 SETUP_GP
Maja Gagic6ea651f2015-02-24 16:55:04 +0100883 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
884 dla $t9, artThrowClassCastException
885 jalr $zero, $t9 # artThrowClassCastException (Class*, Class*, Thread*)
886 move $a2, rSELF # pass Thread::Current
887END art_quick_check_cast
888
889 /*
890 * Entry from managed code for array put operations of objects where the value being stored
891 * needs to be checked for compatibility.
892 * a0 = array, a1 = index, a2 = value
893 */
894ENTRY art_quick_aput_obj_with_null_and_bound_check
895 bne $a0, $zero, .Lart_quick_aput_obj_with_bound_check_gp_set
896 nop
897 b .Lart_quick_throw_null_pointer_exception_gp_set
898 nop
899END art_quick_aput_obj_with_null_and_bound_check
900
901ENTRY art_quick_aput_obj_with_bound_check
902 lwu $t0, MIRROR_ARRAY_LENGTH_OFFSET($a0)
903 sltu $t1, $a1, $t0
904 bne $t1, $zero, .Lart_quick_aput_obj_gp_set
905 nop
906 move $a0, $a1
907 b .Lart_quick_throw_array_bounds_gp_set
908 move $a1, $t0
909END art_quick_aput_obj_with_bound_check
910
911ENTRY art_quick_aput_obj
912 beq $a2, $zero, .Ldo_aput_null
913 nop
914 lwu $t0, MIRROR_OBJECT_CLASS_OFFSET($a0)
915 lwu $t1, MIRROR_OBJECT_CLASS_OFFSET($a2)
916 lwu $t0, MIRROR_CLASS_COMPONENT_TYPE_OFFSET($t0)
917 bne $t1, $t0, .Lcheck_assignability # value's type == array's component type - trivial assignability
918 nop
919.Ldo_aput:
920 dsll $a1, $a1, 2
921 daddu $t0, $a0, $a1
922 sw $a2, MIRROR_OBJECT_ARRAY_DATA_OFFSET($t0)
923 ld $t0, THREAD_CARD_TABLE_OFFSET(rSELF)
924 dsrl $t1, $a0, 7
925 daddu $t1, $t1, $t0
926 sb $t0, ($t1)
927 jalr $zero, $ra
Goran Jakovljevic04568812015-04-23 15:27:23 +0200928 .cpreturn # Restore gp from t8 in branch delay slot.
Maja Gagic6ea651f2015-02-24 16:55:04 +0100929.Ldo_aput_null:
930 dsll $a1, $a1, 2
931 daddu $t0, $a0, $a1
932 sw $a2, MIRROR_OBJECT_ARRAY_DATA_OFFSET($t0)
933 jalr $zero, $ra
Goran Jakovljevic04568812015-04-23 15:27:23 +0200934 .cpreturn # Restore gp from t8 in branch delay slot.
Maja Gagic6ea651f2015-02-24 16:55:04 +0100935.Lcheck_assignability:
936 daddiu $sp, $sp, -64
937 .cfi_adjust_cfa_offset 64
938 sd $ra, 56($sp)
939 .cfi_rel_offset 31, 56
940 sd $t9, 24($sp)
941 sd $a2, 16($sp)
942 sd $a1, 8($sp)
943 sd $a0, 0($sp)
944 move $a1, $t1
945 move $a0, $t0
946 jal artIsAssignableFromCode # (Class*, Class*)
Goran Jakovljevic04568812015-04-23 15:27:23 +0200947 .cpreturn # Restore gp from t8 in branch delay slot.
948 # t8 may be clobbered in artIsAssignableFromCode.
Maja Gagic6ea651f2015-02-24 16:55:04 +0100949 ld $ra, 56($sp)
950 ld $t9, 24($sp)
951 ld $a2, 16($sp)
952 ld $a1, 8($sp)
953 ld $a0, 0($sp)
954 daddiu $sp, $sp, 64
955 .cfi_adjust_cfa_offset -64
Goran Jakovljevic04568812015-04-23 15:27:23 +0200956 SETUP_GP
Maja Gagic6ea651f2015-02-24 16:55:04 +0100957 bne $v0, $zero, .Ldo_aput
958 nop
959 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
960 move $a1, $a2
961 dla $t9, artThrowArrayStoreException
962 jalr $zero, $t9 # artThrowArrayStoreException(Class*, Class*, Thread*)
963 move $a2, rSELF # pass Thread::Current
964END art_quick_aput_obj
965
966 /*
Maja Gagic6ea651f2015-02-24 16:55:04 +0100967 * Called by managed code to resolve a static field and load a boolean primitive value.
968 */
969 .extern artGetBooleanStaticFromCode
970ENTRY art_quick_get_boolean_static
971 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -0700972 ld $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +0100973 jal artGetBooleanStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
974 move $a2, rSELF # pass Thread::Current
975 RETURN_IF_NO_EXCEPTION
976END art_quick_get_boolean_static
977
978 /*
979 * Called by managed code to resolve a static field and load a byte primitive value.
980 */
981 .extern artGetByteStaticFromCode
982ENTRY art_quick_get_byte_static
983 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -0700984 ld $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +0100985 jal artGetByteStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
986 move $a2, rSELF # pass Thread::Current
987 RETURN_IF_NO_EXCEPTION
988END art_quick_get_byte_static
989
990 /*
991 * Called by managed code to resolve a static field and load a char primitive value.
992 */
993 .extern artGetCharStaticFromCode
994ENTRY art_quick_get_char_static
995 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -0700996 ld $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +0100997 jal artGetCharStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
998 move $a2, rSELF # pass Thread::Current
999 RETURN_IF_NO_EXCEPTION
1000END art_quick_get_char_static
1001
1002 /*
1003 * Called by managed code to resolve a static field and load a short primitive value.
1004 */
1005 .extern artGetShortStaticFromCode
1006ENTRY art_quick_get_short_static
1007 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001008 ld $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001009 jal artGetShortStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
1010 move $a2, rSELF # pass Thread::Current
1011 RETURN_IF_NO_EXCEPTION
1012END art_quick_get_short_static
1013
1014 /*
1015 * Called by managed code to resolve a static field and load a 32-bit primitive value.
1016 */
1017 .extern artGet32StaticFromCode
1018ENTRY art_quick_get32_static
1019 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001020 ld $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001021 jal artGet32StaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
1022 move $a2, rSELF # pass Thread::Current
1023 RETURN_IF_NO_EXCEPTION
1024END art_quick_get32_static
1025
1026 /*
1027 * Called by managed code to resolve a static field and load a 64-bit primitive value.
1028 */
1029 .extern artGet64StaticFromCode
1030ENTRY art_quick_get64_static
1031 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001032 ld $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001033 jal artGet64StaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
1034 move $a2, rSELF # pass Thread::Current
1035 RETURN_IF_NO_EXCEPTION
1036END art_quick_get64_static
1037
1038 /*
1039 * Called by managed code to resolve a static field and load an object reference.
1040 */
1041 .extern artGetObjStaticFromCode
1042ENTRY art_quick_get_obj_static
1043 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001044 ld $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001045 jal artGetObjStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*)
1046 move $a2, rSELF # pass Thread::Current
1047 RETURN_IF_NO_EXCEPTION
1048END art_quick_get_obj_static
1049
1050 /*
1051 * Called by managed code to resolve an instance field and load a boolean primitive value.
1052 */
1053 .extern artGetBooleanInstanceFromCode
1054ENTRY art_quick_get_boolean_instance
1055 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001056 ld $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001057 jal artGetBooleanInstanceFromCode # (field_idx, Object*, referrer, Thread*)
1058 move $a3, rSELF # pass Thread::Current
1059 RETURN_IF_NO_EXCEPTION
1060END art_quick_get_boolean_instance
1061
1062 /*
1063 * Called by managed code to resolve an instance field and load a byte primitive value.
1064 */
1065 .extern artGetByteInstanceFromCode
1066ENTRY art_quick_get_byte_instance
1067 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001068 ld $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001069 jal artGetByteInstanceFromCode # (field_idx, Object*, referrer, Thread*)
1070 move $a3, rSELF # pass Thread::Current
1071 RETURN_IF_NO_EXCEPTION
1072END art_quick_get_byte_instance
1073
1074 /*
1075 * Called by managed code to resolve an instance field and load a char primitive value.
1076 */
1077 .extern artGetCharInstanceFromCode
1078ENTRY art_quick_get_char_instance
1079 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001080 ld $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001081 jal artGetCharInstanceFromCode # (field_idx, Object*, referrer, Thread*)
1082 move $a3, rSELF # pass Thread::Current
1083 RETURN_IF_NO_EXCEPTION
1084END art_quick_get_char_instance
1085
1086 /*
1087 * Called by managed code to resolve an instance field and load a short primitive value.
1088 */
1089 .extern artGetShortInstanceFromCode
1090ENTRY art_quick_get_short_instance
1091 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001092 ld $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001093 jal artGetShortInstanceFromCode # (field_idx, Object*, referrer, Thread*)
1094 move $a3, rSELF # pass Thread::Current
1095 RETURN_IF_NO_EXCEPTION
1096END art_quick_get_short_instance
1097
1098 /*
1099 * Called by managed code to resolve an instance field and load a 32-bit primitive value.
1100 */
1101 .extern artGet32InstanceFromCode
1102ENTRY art_quick_get32_instance
1103 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001104 ld $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001105 jal artGet32InstanceFromCode # (field_idx, Object*, referrer, Thread*)
1106 move $a3, rSELF # pass Thread::Current
1107 RETURN_IF_NO_EXCEPTION
1108END art_quick_get32_instance
1109
1110 /*
1111 * Called by managed code to resolve an instance field and load a 64-bit primitive value.
1112 */
1113 .extern artGet64InstanceFromCode
1114ENTRY art_quick_get64_instance
1115 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001116 ld $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001117 jal artGet64InstanceFromCode # (field_idx, Object*, referrer, Thread*)
1118 move $a3, rSELF # pass Thread::Current
1119 RETURN_IF_NO_EXCEPTION
1120END art_quick_get64_instance
1121
1122 /*
1123 * Called by managed code to resolve an instance field and load an object reference.
1124 */
1125 .extern artGetObjInstanceFromCode
1126ENTRY art_quick_get_obj_instance
1127 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001128 ld $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001129 jal artGetObjInstanceFromCode # (field_idx, Object*, referrer, Thread*)
1130 move $a3, rSELF # pass Thread::Current
1131 RETURN_IF_NO_EXCEPTION
1132END art_quick_get_obj_instance
1133
1134 /*
1135 * Called by managed code to resolve a static field and store a 8-bit primitive value.
1136 */
1137 .extern artSet8StaticFromCode
1138ENTRY art_quick_set8_static
1139 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001140 ld $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001141 jal artSet8StaticFromCode # (field_idx, new_val, referrer, Thread*)
1142 move $a3, rSELF # pass Thread::Current
1143 RETURN_IF_ZERO
1144END art_quick_set8_static
1145
1146 /*
1147 * Called by managed code to resolve a static field and store a 16-bit primitive value.
1148 */
1149 .extern artSet16StaticFromCode
1150ENTRY art_quick_set16_static
1151 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001152 ld $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001153 jal artSet16StaticFromCode # (field_idx, new_val, referrer, Thread*)
1154 move $a3, rSELF # pass Thread::Current
1155 RETURN_IF_ZERO
1156END art_quick_set16_static
1157
1158 /*
1159 * Called by managed code to resolve a static field and store a 32-bit primitive value.
1160 */
1161 .extern artSet32StaticFromCode
1162ENTRY art_quick_set32_static
1163 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001164 ld $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001165 jal artSet32StaticFromCode # (field_idx, new_val, referrer, Thread*)
1166 move $a3, rSELF # pass Thread::Current
1167 RETURN_IF_ZERO
1168END art_quick_set32_static
1169
1170 /*
1171 * Called by managed code to resolve a static field and store a 64-bit primitive value.
1172 */
1173 .extern artSet64StaticFromCode
1174ENTRY art_quick_set64_static
1175 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
1176 move $a2, $a1 # pass new_val
Mathieu Chartiere401d142015-04-22 13:56:20 -07001177 ld $a1, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001178 jal artSet64StaticFromCode # (field_idx, referrer, new_val, Thread*)
1179 move $a3, rSELF # pass Thread::Current
1180 RETURN_IF_ZERO
1181END art_quick_set64_static
1182
1183 /*
1184 * Called by managed code to resolve a static field and store an object reference.
1185 */
1186 .extern artSetObjStaticFromCode
1187ENTRY art_quick_set_obj_static
1188 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001189 ld $a2, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001190 jal artSetObjStaticFromCode # (field_idx, new_val, referrer, Thread*)
1191 move $a3, rSELF # pass Thread::Current
1192 RETURN_IF_ZERO
1193END art_quick_set_obj_static
1194
1195 /*
1196 * Called by managed code to resolve an instance field and store a 8-bit primitive value.
1197 */
1198 .extern artSet8InstanceFromCode
1199ENTRY art_quick_set8_instance
1200 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001201 ld $a3, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001202 jal artSet8InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*)
1203 move $a4, rSELF # pass Thread::Current
1204 RETURN_IF_ZERO
1205END art_quick_set8_instance
1206
1207 /*
1208 * Called by managed code to resolve an instance field and store a 16-bit primitive value.
1209 */
1210 .extern artSet16InstanceFromCode
1211ENTRY art_quick_set16_instance
1212 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001213 ld $a3, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001214 jal artSet16InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*)
1215 move $a4, rSELF # pass Thread::Current
1216 RETURN_IF_ZERO
1217END art_quick_set16_instance
1218
1219 /*
1220 * Called by managed code to resolve an instance field and store a 32-bit primitive value.
1221 */
1222 .extern artSet32InstanceFromCode
1223ENTRY art_quick_set32_instance
1224 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001225 ld $a3, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001226 jal artSet32InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*)
1227 move $a4, rSELF # pass Thread::Current
1228 RETURN_IF_ZERO
1229END art_quick_set32_instance
1230
1231 /*
1232 * Called by managed code to resolve an instance field and store a 64-bit primitive value.
1233 */
1234 .extern artSet64InstanceFromCode
1235ENTRY art_quick_set64_instance
1236 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001237 ld $a3, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001238 jal artSet64InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*)
1239 move $a4, rSELF # pass Thread::Current
1240 RETURN_IF_ZERO
1241END art_quick_set64_instance
1242
1243 /*
1244 * Called by managed code to resolve an instance field and store an object reference.
1245 */
1246 .extern artSetObjInstanceFromCode
1247ENTRY art_quick_set_obj_instance
1248 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Mathieu Chartiere401d142015-04-22 13:56:20 -07001249 ld $a3, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE($sp) # pass referrer's Method*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001250 jal artSetObjInstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*)
1251 move $a4, rSELF # pass Thread::Current
1252 RETURN_IF_ZERO
1253END art_quick_set_obj_instance
1254
Vladimir Marko5ea536a2015-04-20 20:11:30 +01001255// Macro to facilitate adding new allocation entrypoints.
1256.macro ONE_ARG_DOWNCALL name, entrypoint, return
1257 .extern \entrypoint
1258ENTRY \name
Maja Gagic6ea651f2015-02-24 16:55:04 +01001259 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
Vladimir Marko5ea536a2015-04-20 20:11:30 +01001260 jal \entrypoint
1261 move $a1, rSELF # pass Thread::Current
1262 \return
1263END \name
1264.endm
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001265
1266// Macro to facilitate adding new allocation entrypoints.
1267.macro TWO_ARG_DOWNCALL name, entrypoint, return
Maja Gagic6ea651f2015-02-24 16:55:04 +01001268 .extern \entrypoint
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001269ENTRY \name
Maja Gagic6ea651f2015-02-24 16:55:04 +01001270 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
1271 jal \entrypoint
1272 move $a2, rSELF # pass Thread::Current
1273 \return
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001274END \name
1275.endm
1276
1277.macro THREE_ARG_DOWNCALL name, entrypoint, return
Maja Gagic6ea651f2015-02-24 16:55:04 +01001278 .extern \entrypoint
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001279ENTRY \name
Maja Gagic6ea651f2015-02-24 16:55:04 +01001280 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
1281 jal \entrypoint
1282 move $a3, rSELF # pass Thread::Current
1283 \return
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001284END \name
1285.endm
1286
Vladimir Markoe85e1232015-04-28 14:14:58 +01001287.macro FOUR_ARG_DOWNCALL name, entrypoint, return
1288 .extern \entrypoint
1289ENTRY \name
1290 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
1291 jal \entrypoint
1292 move $a4, rSELF # pass Thread::Current
1293 \return
1294END \name
1295.endm
1296
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001297// Generate the allocation entrypoints for each allocator.
1298GENERATE_ALL_ALLOC_ENTRYPOINTS
1299
Maja Gagic6ea651f2015-02-24 16:55:04 +01001300 /*
Vladimir Marko5ea536a2015-04-20 20:11:30 +01001301 * Entry from managed code to resolve a string, this stub will allocate a String and deliver an
1302 * exception on error. On success the String is returned. A0 holds the string index. The fast
1303 * path check for hit in strings cache has already been performed.
1304 */
1305ONE_ARG_DOWNCALL art_quick_resolve_string, artResolveStringFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
1306
1307 /*
1308 * Entry from managed code when uninitialized static storage, this stub will run the class
1309 * initializer and deliver the exception on error. On success the static storage base is
1310 * returned.
1311 */
1312ONE_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
1313
1314 /*
1315 * Entry from managed code when dex cache misses for a type_idx.
1316 */
1317ONE_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
1318
1319 /*
1320 * Entry from managed code when type_idx needs to be checked for access and dex cache may also
1321 * miss.
1322 */
1323ONE_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER
1324
1325 /*
Maja Gagic6ea651f2015-02-24 16:55:04 +01001326 * Called by managed code when the value in rSUSPEND has been decremented to 0.
1327 */
1328 .extern artTestSuspendFromCode
1329ENTRY art_quick_test_suspend
1330 lh $a0, THREAD_FLAGS_OFFSET(rSELF)
1331 bne $a0, $zero, 1f
1332 daddiu rSUSPEND, $zero, SUSPEND_CHECK_INTERVAL # reset rSUSPEND to SUSPEND_CHECK_INTERVAL
1333 jalr $zero, $ra
Goran Jakovljevic04568812015-04-23 15:27:23 +02001334 .cpreturn # Restore gp from t8 in branch delay slot.
Maja Gagic6ea651f2015-02-24 16:55:04 +010013351:
1336 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves for stack crawl
1337 jal artTestSuspendFromCode # (Thread*)
1338 move $a0, rSELF
1339 RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME_AND_RETURN
1340END art_quick_test_suspend
Douglas Leung6461d192015-01-30 18:13:58 -08001341
1342 /*
1343 * Called by managed code that is attempting to call a method on a proxy class. On entry
1344 * r0 holds the proxy method; r1, r2 and r3 may contain arguments.
1345 */
1346 .extern artQuickProxyInvokeHandler
1347ENTRY art_quick_proxy_invoke_handler
Douglas Leung8223b802015-04-28 17:22:29 -07001348 SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_A0
Douglas Leung6461d192015-01-30 18:13:58 -08001349 move $a2, rSELF # pass Thread::Current
1350 jal artQuickProxyInvokeHandler # (Method* proxy method, receiver, Thread*, SP)
1351 move $a3, $sp # pass $sp
1352 ld $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
1353 daddiu $sp, $sp, REFS_AND_ARGS_MINUS_REFS_SIZE # skip a0-a7 and f12-f19
1354 RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
1355 bne $t0, $zero, 1f
1356 dmtc1 $v0, $f0 # place return value to FP return value
1357 jalr $zero, $ra
1358 dmtc1 $v1, $f1 # place return value to FP return value
13591:
1360 DELIVER_PENDING_EXCEPTION
1361END art_quick_proxy_invoke_handler
1362
Maja Gagic6ea651f2015-02-24 16:55:04 +01001363 /*
1364 * Called to resolve an imt conflict. t0 is a hidden argument that holds the target method's
1365 * dex method index.
1366 */
1367ENTRY art_quick_imt_conflict_trampoline
Maja Gagic6ea651f2015-02-24 16:55:04 +01001368 dla $t9, art_quick_invoke_interface_trampoline
Goran Jakovljevic04568812015-04-23 15:27:23 +02001369 .cpreturn
Maja Gagic6ea651f2015-02-24 16:55:04 +01001370 jalr $zero, $t9
Nicolas Geoffray8ea18d02015-05-26 16:29:08 +01001371 move $a0, $t0
Maja Gagic6ea651f2015-02-24 16:55:04 +01001372END art_quick_imt_conflict_trampoline
Andreas Gampecc7c39d2015-01-30 17:04:45 -08001373
1374 .extern artQuickResolutionTrampoline
1375ENTRY art_quick_resolution_trampoline
1376 SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME
1377 move $a2, rSELF # pass Thread::Current
1378 jal artQuickResolutionTrampoline # (Method* called, receiver, Thread*, SP)
1379 move $a3, $sp # pass $sp
1380 beq $v0, $zero, 1f
Mathieu Chartiere401d142015-04-22 13:56:20 -07001381 ld $a0, 0($sp) # load resolved method in $a0
Andreas Gampecc7c39d2015-01-30 17:04:45 -08001382 # artQuickResolutionTrampoline puts resolved method in *SP
1383 RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
1384 move $t9, $v0 # code pointer must be in $t9 to generate the global pointer
1385 jalr $zero, $t9 # tail call to method
1386 nop
13871:
1388 RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
1389 DELIVER_PENDING_EXCEPTION
1390END art_quick_resolution_trampoline
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001391
1392 .extern artQuickGenericJniTrampoline
1393 .extern artQuickGenericJniEndTrampoline
1394ENTRY art_quick_generic_jni_trampoline
Douglas Leung8223b802015-04-28 17:22:29 -07001395 SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_A0
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001396 move $s8, $sp # save $sp
1397
1398 # prepare for call to artQuickGenericJniTrampoline(Thread*, SP)
1399 move $a0, rSELF # pass Thread::Current
1400 move $a1, $sp # pass $sp
1401 jal artQuickGenericJniTrampoline # (Thread*, SP)
1402 daddiu $sp, $sp, -5120 # reserve space on the stack
1403
1404 # The C call will have registered the complete save-frame on success.
1405 # The result of the call is:
1406 # v0: ptr to native code, 0 on error.
1407 # v1: ptr to the bottom of the used area of the alloca, can restore stack till here.
1408 beq $v0, $zero, 1f # check entry error
1409 move $t9, $v0 # save the code ptr
1410 move $sp, $v1 # release part of the alloca
1411
1412 # Load parameters from stack into registers
1413 ld $a0, 0($sp)
1414 ld $a1, 8($sp)
1415 ld $a2, 16($sp)
1416 ld $a3, 24($sp)
1417 ld $a4, 32($sp)
1418 ld $a5, 40($sp)
1419 ld $a6, 48($sp)
1420 ld $a7, 56($sp)
1421 # Load FPRs the same as GPRs. Look at BuildNativeCallFrameStateMachine.
1422 l.d $f12, 0($sp)
1423 l.d $f13, 8($sp)
1424 l.d $f14, 16($sp)
1425 l.d $f15, 24($sp)
1426 l.d $f16, 32($sp)
1427 l.d $f17, 40($sp)
1428 l.d $f18, 48($sp)
1429 l.d $f19, 56($sp)
1430 jalr $t9 # native call
1431 daddiu $sp, $sp, 64
1432
1433 # result sign extension is handled in C code
1434 # prepare for call to artQuickGenericJniEndTrampoline(Thread*, result, result_f)
1435 move $a0, rSELF # pass Thread::Current
1436 move $a1, $v0
1437 jal artQuickGenericJniEndTrampoline
1438 dmfc1 $a2, $f0
1439
1440 ld $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
Nicolas Geoffray126d6592015-03-03 14:28:35 +00001441 bne $t0, $zero, 1f # check for pending exceptions
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001442 move $sp, $s8 # tear down the alloca
1443
1444 # tear dpown the callee-save frame
1445 RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
1446
1447 jalr $zero, $ra
1448 dmtc1 $v0, $f0 # place return value to FP return value
1449
14501:
Nicolas Geoffray126d6592015-03-03 14:28:35 +00001451 ld $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF)
1452 # This will create a new save-all frame, required by the runtime.
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001453 DELIVER_PENDING_EXCEPTION
1454END art_quick_generic_jni_trampoline
1455
1456 .extern artQuickToInterpreterBridge
1457ENTRY art_quick_to_interpreter_bridge
1458 SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME
1459 move $a1, rSELF # pass Thread::Current
1460 jal artQuickToInterpreterBridge # (Method* method, Thread*, SP)
1461 move $a2, $sp # pass $sp
1462 ld $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
1463 daddiu $sp, $sp, REFS_AND_ARGS_MINUS_REFS_SIZE # skip a0-a7 and f12-f19
1464 RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME
1465 bne $t0, $zero, 1f
1466 dmtc1 $v0, $f0 # place return value to FP return value
1467 jalr $zero, $ra
1468 dmtc1 $v1, $f1 # place return value to FP return value
14691:
1470 DELIVER_PENDING_EXCEPTION
1471END art_quick_to_interpreter_bridge
1472
1473 /*
1474 * Routine that intercepts method calls and returns.
1475 */
1476 .extern artInstrumentationMethodEntryFromCode
1477 .extern artInstrumentationMethodExitFromCode
1478ENTRY art_quick_instrumentation_entry
1479 SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME
1480 daddiu $sp, $sp, -16 # space for saving arg0
1481 .cfi_adjust_cfa_offset 16
1482 sd $a0, 0($sp) # save arg0
1483 move $a3, $ra # pass $ra
1484 jal artInstrumentationMethodEntryFromCode # (Method*, Object*, Thread*, RA)
1485 move $a2, rSELF # pass Thread::Current
1486 move $t9, $v0 # $t9 holds reference to code
1487 ld $a0, 0($sp) # restore arg0
1488 daddiu $sp, $sp, 16 # remove args
1489 .cfi_adjust_cfa_offset -16
1490 RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME
1491 jalr $t9 # call method
1492 nop
1493END art_quick_instrumentation_entry
1494 /* intentional fallthrough */
1495 .global art_quick_instrumentation_exit
1496art_quick_instrumentation_exit:
1497 .cfi_startproc
Goran Jakovljevic04568812015-04-23 15:27:23 +02001498 SETUP_GP
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001499 move $ra, $zero # link register is to here, so clobber with 0 for later checks
1500 SETUP_REFS_ONLY_CALLEE_SAVE_FRAME
1501 move $t0, $sp # remember bottom of caller's frame
1502 daddiu $sp, $sp, -16 # save return values and set up args
1503 .cfi_adjust_cfa_offset 16
1504 sd $v0, 0($sp)
1505 .cfi_rel_offset 2, 0
1506 s.d $f0, 8($sp)
1507 mov.d $f15, $f0 # pass fpr result
1508 move $a2, $v0 # pass gpr result
1509 move $a1, $t0 # pass $sp
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001510 move $a0, rSELF # pass Thread::Current
Goran Jakovljevic04568812015-04-23 15:27:23 +02001511 jal artInstrumentationMethodExitFromCode # (Thread*, SP, gpr_res, fpr_res)
1512 .cpreturn # Restore gp from t8 in branch delay slot. gp is not used anymore,
1513 # and t8 may be clobbered in artInstrumentationMethodExitFromCode.
1514
Douglas Leungf96e8bd2015-03-27 15:38:30 -07001515 move $t9, $v0 # set aside returned link register
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001516 move $ra, $v1 # set link register for deoptimization
1517 ld $v0, 0($sp) # restore return values
1518 l.d $f0, 8($sp)
Douglas Leungf96e8bd2015-03-27 15:38:30 -07001519 jalr $zero, $t9 # return
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001520 daddiu $sp, $sp, 16+FRAME_SIZE_REFS_ONLY_CALLEE_SAVE # 16 bytes of saved values + ref_only callee save frame
1521 .cfi_adjust_cfa_offset -(16+FRAME_SIZE_REFS_ONLY_CALLEE_SAVE)
1522END art_quick_instrumentation_exit
1523
Maja Gagic6ea651f2015-02-24 16:55:04 +01001524 /*
1525 * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization
1526 * will long jump to the upcall with a special exception of -1.
1527 */
1528 .extern artDeoptimize
1529 .extern artEnterInterpreterFromDeoptimize
1530ENTRY art_quick_deoptimize
1531 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
1532 jal artDeoptimize # artDeoptimize(Thread*, SP)
1533 # Returns caller method's frame size.
1534 move $a0, rSELF # pass Thread::current
1535END art_quick_deoptimize
1536
Andreas Gampe1a5c4062015-01-15 12:10:47 -08001537UNIMPLEMENTED art_quick_indexof
1538UNIMPLEMENTED art_quick_string_compareto