blob: 95fcd7389c3143f850385588575786133dc23a64 [file] [log] [blame]
Elliott Hughes0f3c5532012-03-30 14:51:51 -07001/*
2 * Copyright (C) 2012 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
Ian Rogers7655f292013-07-29 11:07:13 -070017#include "asm_support_mips.S"
buzbee5bc5a7b2012-03-07 15:52:59 -080018
Mathieu Chartier7410f292013-11-24 13:17:35 -080019#include "arch/quick_alloc_entrypoints.S"
20
jeffhao07030602012-09-26 14:33:14 -070021 .set noreorder
buzbee5bc5a7b2012-03-07 15:52:59 -080022 .balign 4
23
24 /* Deliver the given exception */
25 .extern artDeliverExceptionFromCode
26 /* Deliver an exception pending on a thread */
jeffhao8161c032012-10-31 15:50:00 -070027 .extern artDeliverPendingExceptionFromCode
buzbee5bc5a7b2012-03-07 15:52:59 -080028
29 /*
30 * Macro that sets up the callee save frame to conform with
31 * Runtime::CreateCalleeSaveMethod(kSaveAll)
Jeff Hao1f3bc2f2013-04-30 15:17:19 -070032 * callee-save: $s0-$s8 + $gp + $ra, 11 total + 1 word padding + 4 open words for args
buzbee5bc5a7b2012-03-07 15:52:59 -080033 */
Ian Rogers57b86d42012-03-27 16:05:41 -070034.macro SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
jeffhaofa147e22012-10-12 17:03:32 -070035 addiu $sp, $sp, -64
Jeff Haod4c3f7d2013-02-14 14:14:44 -080036 .cfi_adjust_cfa_offset 64
Andreas Gampe5c1e4352014-04-21 19:28:24 -070037
38 // Ugly compile-time check, but we only have the preprocessor.
39#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 64)
40#error "SAVE_ALL_CALLEE_SAVE_FRAME(MIPS) size not as expected."
41#endif
42
jeffhaofa147e22012-10-12 17:03:32 -070043 sw $ra, 60($sp)
Jeff Haod4c3f7d2013-02-14 14:14:44 -080044 .cfi_rel_offset 31, 60
jeffhaofa147e22012-10-12 17:03:32 -070045 sw $s8, 56($sp)
Jeff Haod4c3f7d2013-02-14 14:14:44 -080046 .cfi_rel_offset 30, 56
Jeff Hao1f3bc2f2013-04-30 15:17:19 -070047 sw $gp, 52($sp)
48 .cfi_rel_offset 28, 52
49 sw $s7, 48($sp)
50 .cfi_rel_offset 23, 48
51 sw $s6, 44($sp)
52 .cfi_rel_offset 22, 44
53 sw $s5, 40($sp)
54 .cfi_rel_offset 21, 40
55 sw $s4, 36($sp)
56 .cfi_rel_offset 20, 36
57 sw $s3, 32($sp)
58 .cfi_rel_offset 19, 32
59 sw $s2, 28($sp)
60 .cfi_rel_offset 18, 28
61 sw $s1, 24($sp)
62 .cfi_rel_offset 17, 24
63 sw $s0, 20($sp)
64 .cfi_rel_offset 16, 20
65 # 1 word for alignment, 4 open words for args $a0-$a3, bottom will hold Method*
buzbee5bc5a7b2012-03-07 15:52:59 -080066.endm
67
68 /*
69 * Macro that sets up the callee save frame to conform with
70 * Runtime::CreateCalleeSaveMethod(kRefsOnly). Restoration assumes non-moving GC.
71 * Does not include rSUSPEND or rSELF
Jeff Hao1f3bc2f2013-04-30 15:17:19 -070072 * callee-save: $s2-$s8 + $gp + $ra, 9 total + 3 words padding + 4 open words for args
buzbee5bc5a7b2012-03-07 15:52:59 -080073 */
74.macro SETUP_REF_ONLY_CALLEE_SAVE_FRAME
jeffhao4eb68ed2012-10-17 16:41:07 -070075 addiu $sp, $sp, -64
Jeff Haod4c3f7d2013-02-14 14:14:44 -080076 .cfi_adjust_cfa_offset 64
Andreas Gampe5c1e4352014-04-21 19:28:24 -070077
78 // Ugly compile-time check, but we only have the preprocessor.
79#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 64)
80#error "REFS_ONLY_CALLEE_SAVE_FRAME(MIPS) size not as expected."
81#endif
82
jeffhao4eb68ed2012-10-17 16:41:07 -070083 sw $ra, 60($sp)
Jeff Haod4c3f7d2013-02-14 14:14:44 -080084 .cfi_rel_offset 31, 60
jeffhao4eb68ed2012-10-17 16:41:07 -070085 sw $s8, 56($sp)
Jeff Haod4c3f7d2013-02-14 14:14:44 -080086 .cfi_rel_offset 30, 56
Jeff Hao1f3bc2f2013-04-30 15:17:19 -070087 sw $gp, 52($sp)
88 .cfi_rel_offset 28, 52
89 sw $s7, 48($sp)
90 .cfi_rel_offset 23, 48
91 sw $s6, 44($sp)
92 .cfi_rel_offset 22, 44
93 sw $s5, 40($sp)
94 .cfi_rel_offset 21, 40
95 sw $s4, 36($sp)
96 .cfi_rel_offset 20, 36
97 sw $s3, 32($sp)
98 .cfi_rel_offset 19, 32
99 sw $s2, 28($sp)
100 .cfi_rel_offset 18, 28
jeffhaofc6a30e2012-10-18 18:24:15 -0700101 # 3 words for alignment and extra args, 4 open words for args $a0-$a3, bottom will hold Method*
buzbee5bc5a7b2012-03-07 15:52:59 -0800102.endm
103
104.macro RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
jeffhao4eb68ed2012-10-17 16:41:07 -0700105 lw $ra, 60($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800106 .cfi_restore 31
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700107 lw $s8, 56($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800108 .cfi_restore 30
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700109 lw $gp, 52($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800110 .cfi_restore 28
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700111 lw $s7, 48($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800112 .cfi_restore 23
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700113 lw $s6, 44($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800114 .cfi_restore 22
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700115 lw $s5, 40($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800116 .cfi_restore 21
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700117 lw $s4, 36($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800118 .cfi_restore 20
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700119 lw $s3, 32($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800120 .cfi_restore 19
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700121 lw $s2, 28($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800122 .cfi_restore 18
jeffhao4eb68ed2012-10-17 16:41:07 -0700123 addiu $sp, $sp, 64
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800124 .cfi_adjust_cfa_offset -64
buzbee5bc5a7b2012-03-07 15:52:59 -0800125.endm
126
127.macro RESTORE_REF_ONLY_CALLEE_SAVE_FRAME_AND_RETURN
jeffhao4eb68ed2012-10-17 16:41:07 -0700128 lw $ra, 60($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800129 .cfi_restore 31
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700130 lw $s8, 56($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800131 .cfi_restore 30
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700132 lw $gp, 52($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800133 .cfi_restore 28
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700134 lw $s7, 48($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800135 .cfi_restore 23
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700136 lw $s6, 44($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800137 .cfi_restore 22
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700138 lw $s5, 40($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800139 .cfi_restore 21
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700140 lw $s4, 36($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800141 .cfi_restore 20
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700142 lw $s3, 32($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800143 .cfi_restore 19
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700144 lw $s2, 28($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800145 .cfi_restore 18
jeffhao7fbee072012-08-24 17:56:54 -0700146 jr $ra
jeffhao4eb68ed2012-10-17 16:41:07 -0700147 addiu $sp, $sp, 64
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800148 .cfi_adjust_cfa_offset -64
buzbee5bc5a7b2012-03-07 15:52:59 -0800149.endm
150
151 /*
152 * Macro that sets up the callee save frame to conform with
153 * Runtime::CreateCalleeSaveMethod(kRefsAndArgs). Restoration assumes non-moving GC.
Jeff Hao1f3bc2f2013-04-30 15:17:19 -0700154 * callee-save: $a1-$a3, $s2-$s8 + $gp + $ra, 12 total + 3 words padding + method*
buzbee5bc5a7b2012-03-07 15:52:59 -0800155 */
156.macro SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
Jeff Hao1f3bc2f2013-04-30 15:17:19 -0700157 addiu $sp, $sp, -64
158 .cfi_adjust_cfa_offset 64
Andreas Gampe5c1e4352014-04-21 19:28:24 -0700159
160 // Ugly compile-time check, but we only have the preprocessor.
161#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 64)
162#error "REFS_AND_ARGS_CALLEE_SAVE_FRAME(MIPS) size not as expected."
163#endif
164
Jeff Hao1f3bc2f2013-04-30 15:17:19 -0700165 sw $ra, 60($sp)
166 .cfi_rel_offset 31, 60
167 sw $s8, 56($sp)
168 .cfi_rel_offset 30, 56
169 sw $gp, 52($sp)
170 .cfi_rel_offset 28, 52
171 sw $s7, 48($sp)
172 .cfi_rel_offset 23, 48
173 sw $s6, 44($sp)
174 .cfi_rel_offset 22, 44
175 sw $s5, 40($sp)
176 .cfi_rel_offset 21, 40
177 sw $s4, 36($sp)
178 .cfi_rel_offset 20, 36
179 sw $s3, 32($sp)
180 .cfi_rel_offset 19, 32
181 sw $s2, 28($sp)
182 .cfi_rel_offset 18, 28
jeffhao7fbee072012-08-24 17:56:54 -0700183 sw $a3, 12($sp)
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800184 .cfi_rel_offset 7, 12
jeffhao7fbee072012-08-24 17:56:54 -0700185 sw $a2, 8($sp)
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800186 .cfi_rel_offset 6, 8
jeffhao7fbee072012-08-24 17:56:54 -0700187 sw $a1, 4($sp)
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800188 .cfi_rel_offset 5, 4
jeffhaofa147e22012-10-12 17:03:32 -0700189 # bottom will hold Method*
buzbee5bc5a7b2012-03-07 15:52:59 -0800190.endm
191
192.macro RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700193 lw $ra, 60($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800194 .cfi_restore 31
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700195 lw $s8, 56($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800196 .cfi_restore 30
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700197 lw $gp, 52($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800198 .cfi_restore 28
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700199 lw $s7, 48($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800200 .cfi_restore 23
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700201 lw $s6, 44($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800202 .cfi_restore 22
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700203 lw $s5, 40($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800204 .cfi_restore 21
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700205 lw $s4, 36($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800206 .cfi_restore 20
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700207 lw $s3, 32($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800208 .cfi_restore 19
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700209 lw $s2, 28($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800210 .cfi_restore 18
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700211 lw $a3, 12($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800212 .cfi_restore 7
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700213 lw $a2, 8($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800214 .cfi_restore 6
Mathieu Chartier2a6c7b72013-10-16 11:16:33 -0700215 lw $a1, 4($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800216 .cfi_restore 5
Ian Rogers468532e2013-08-05 10:56:33 -0700217 addiu $sp, $sp, 64 # pop frame
Jeff Hao1f3bc2f2013-04-30 15:17:19 -0700218 .cfi_adjust_cfa_offset -64
buzbee5bc5a7b2012-03-07 15:52:59 -0800219.endm
220
221 /*
222 * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
223 * exception is Thread::Current()->exception_
224 */
225.macro DELIVER_PENDING_EXCEPTION
jeffhao8161c032012-10-31 15:50:00 -0700226 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME # save callee saves for throw
227 move $a0, rSELF # pass Thread::Current
228 la $t9, artDeliverPendingExceptionFromCode
229 jr $t9 # artDeliverPendingExceptionFromCode(Thread*, $sp)
230 move $a1, $sp # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800231.endm
232
233.macro RETURN_IF_NO_EXCEPTION
jeffhao7fbee072012-08-24 17:56:54 -0700234 lw $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
buzbee5bc5a7b2012-03-07 15:52:59 -0800235 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
jeffhao8161c032012-10-31 15:50:00 -0700236 bnez $t0, 1f # success if no exception is pending
buzbee5bc5a7b2012-03-07 15:52:59 -0800237 nop
jeffhao7fbee072012-08-24 17:56:54 -0700238 jr $ra
buzbee5bc5a7b2012-03-07 15:52:59 -0800239 nop
2401:
241 DELIVER_PENDING_EXCEPTION
242.endm
243
244.macro RETURN_IF_ZERO
245 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
jeffhao7fbee072012-08-24 17:56:54 -0700246 bnez $v0, 1f # success?
buzbee5bc5a7b2012-03-07 15:52:59 -0800247 nop
jeffhao7fbee072012-08-24 17:56:54 -0700248 jr $ra # return on success
buzbee5bc5a7b2012-03-07 15:52:59 -0800249 nop
2501:
251 DELIVER_PENDING_EXCEPTION
252.endm
253
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800254.macro RETURN_IF_RESULT_IS_NON_ZERO
buzbee5bc5a7b2012-03-07 15:52:59 -0800255 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
jeffhao7fbee072012-08-24 17:56:54 -0700256 beqz $v0, 1f # success?
buzbee5bc5a7b2012-03-07 15:52:59 -0800257 nop
jeffhao7fbee072012-08-24 17:56:54 -0700258 jr $ra # return on success
buzbee5bc5a7b2012-03-07 15:52:59 -0800259 nop
2601:
261 DELIVER_PENDING_EXCEPTION
262.endm
263
buzbee5bc5a7b2012-03-07 15:52:59 -0800264 /*
jeffhao7fbee072012-08-24 17:56:54 -0700265 * On entry $a0 is uint32_t* gprs_ and $a1 is uint32_t* fprs_
buzbee5bc5a7b2012-03-07 15:52:59 -0800266 * FIXME: just guessing about the shape of the jmpbuf. Where will pc be?
267 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800268ENTRY art_quick_do_long_jump
jeffhao7fbee072012-08-24 17:56:54 -0700269 l.s $f0, 0($a1)
270 l.s $f1, 4($a1)
271 l.s $f2, 8($a1)
272 l.s $f3, 12($a1)
273 l.s $f4, 16($a1)
274 l.s $f5, 20($a1)
275 l.s $f6, 24($a1)
276 l.s $f7, 28($a1)
277 l.s $f8, 32($a1)
278 l.s $f9, 36($a1)
279 l.s $f10, 40($a1)
280 l.s $f11, 44($a1)
281 l.s $f12, 48($a1)
282 l.s $f13, 52($a1)
283 l.s $f14, 56($a1)
284 l.s $f15, 60($a1)
285 l.s $f16, 64($a1)
286 l.s $f17, 68($a1)
287 l.s $f18, 72($a1)
288 l.s $f19, 76($a1)
289 l.s $f20, 80($a1)
290 l.s $f21, 84($a1)
291 l.s $f22, 88($a1)
292 l.s $f23, 92($a1)
293 l.s $f24, 96($a1)
294 l.s $f25, 100($a1)
295 l.s $f26, 104($a1)
296 l.s $f27, 108($a1)
297 l.s $f28, 112($a1)
298 l.s $f29, 116($a1)
299 l.s $f30, 120($a1)
300 l.s $f31, 124($a1)
301 lw $at, 4($a0)
302 lw $v0, 8($a0)
303 lw $v1, 12($a0)
304 lw $a1, 20($a0)
305 lw $a2, 24($a0)
306 lw $a3, 28($a0)
307 lw $t0, 32($a0)
308 lw $t1, 36($a0)
309 lw $t2, 40($a0)
310 lw $t3, 44($a0)
311 lw $t4, 48($a0)
312 lw $t5, 52($a0)
313 lw $t6, 56($a0)
314 lw $t7, 60($a0)
315 lw $s0, 64($a0)
316 lw $s1, 68($a0)
317 lw $s2, 72($a0)
318 lw $s3, 76($a0)
319 lw $s4, 80($a0)
320 lw $s5, 84($a0)
321 lw $s6, 88($a0)
322 lw $s7, 92($a0)
323 lw $t8, 96($a0)
324 lw $t9, 100($a0)
325 lw $k0, 104($a0)
326 lw $k1, 108($a0)
327 lw $gp, 112($a0)
328 lw $sp, 116($a0)
329 lw $fp, 120($a0)
330 lw $ra, 124($a0)
331 lw $a0, 16($a0)
332 move $v0, $zero # clear result registers r0 and r1
333 jr $ra # do long jump
334 move $v1, $zero
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800335END art_quick_do_long_jump
buzbee5bc5a7b2012-03-07 15:52:59 -0800336
buzbee5bc5a7b2012-03-07 15:52:59 -0800337 /*
338 * Called by managed code, saves most registers (forms basis of long jump context) and passes
339 * the bottom of the stack. artDeliverExceptionFromCode will place the callee save Method* at
340 * the bottom of the thread. On entry r0 holds Throwable*
341 */
Ian Rogers468532e2013-08-05 10:56:33 -0700342ENTRY art_quick_deliver_exception
jeffhao12051ea2013-01-10 11:24:31 -0800343 GENERATE_GLOBAL_POINTER
Ian Rogers57b86d42012-03-27 16:05:41 -0700344 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
jeffhao8161c032012-10-31 15:50:00 -0700345 move $a1, rSELF # pass Thread::Current
346 la $t9, artDeliverExceptionFromCode
347 jr $t9 # artDeliverExceptionFromCode(Throwable*, Thread*, $sp)
348 move $a2, $sp # pass $sp
Ian Rogers468532e2013-08-05 10:56:33 -0700349END art_quick_deliver_exception
buzbee5bc5a7b2012-03-07 15:52:59 -0800350
buzbee5bc5a7b2012-03-07 15:52:59 -0800351 /*
352 * Called by managed code to create and deliver a NullPointerException
353 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800354 .extern artThrowNullPointerExceptionFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700355ENTRY art_quick_throw_null_pointer_exception
jeffhao12051ea2013-01-10 11:24:31 -0800356 GENERATE_GLOBAL_POINTER
Ian Rogers86bcdc22014-02-21 22:06:38 -0800357.Lart_quick_throw_null_pointer_exception_gp_set:
Ian Rogers57b86d42012-03-27 16:05:41 -0700358 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
jeffhao8161c032012-10-31 15:50:00 -0700359 move $a0, rSELF # pass Thread::Current
360 la $t9, artThrowNullPointerExceptionFromCode
361 jr $t9 # artThrowNullPointerExceptionFromCode(Thread*, $sp)
362 move $a1, $sp # pass $sp
Ian Rogers468532e2013-08-05 10:56:33 -0700363END art_quick_throw_null_pointer_exception
buzbee5bc5a7b2012-03-07 15:52:59 -0800364
buzbee5bc5a7b2012-03-07 15:52:59 -0800365 /*
366 * Called by managed code to create and deliver an ArithmeticException
367 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800368 .extern artThrowDivZeroFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700369ENTRY art_quick_throw_div_zero
jeffhao12051ea2013-01-10 11:24:31 -0800370 GENERATE_GLOBAL_POINTER
Ian Rogers57b86d42012-03-27 16:05:41 -0700371 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
jeffhao7fbee072012-08-24 17:56:54 -0700372 move $a0, rSELF # pass Thread::Current
jeffhao8161c032012-10-31 15:50:00 -0700373 la $t9, artThrowDivZeroFromCode
374 jr $t9 # artThrowDivZeroFromCode(Thread*, $sp)
jeffhao7fbee072012-08-24 17:56:54 -0700375 move $a1, $sp # pass $sp
Ian Rogers468532e2013-08-05 10:56:33 -0700376END art_quick_throw_div_zero
buzbee5bc5a7b2012-03-07 15:52:59 -0800377
buzbee5bc5a7b2012-03-07 15:52:59 -0800378 /*
379 * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException
380 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800381 .extern artThrowArrayBoundsFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700382ENTRY art_quick_throw_array_bounds
jeffhao12051ea2013-01-10 11:24:31 -0800383 GENERATE_GLOBAL_POINTER
Ian Rogers86bcdc22014-02-21 22:06:38 -0800384.Lart_quick_throw_array_bounds_gp_set:
Ian Rogers57b86d42012-03-27 16:05:41 -0700385 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
jeffhao8161c032012-10-31 15:50:00 -0700386 move $a2, rSELF # pass Thread::Current
387 la $t9, artThrowArrayBoundsFromCode
388 jr $t9 # artThrowArrayBoundsFromCode(index, limit, Thread*, $sp)
389 move $a3, $sp # pass $sp
Ian Rogers468532e2013-08-05 10:56:33 -0700390END art_quick_throw_array_bounds
buzbee5bc5a7b2012-03-07 15:52:59 -0800391
Ian Rogers57b86d42012-03-27 16:05:41 -0700392 /*
393 * Called by managed code to create and deliver a StackOverflowError.
394 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800395 .extern artThrowStackOverflowFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700396ENTRY art_quick_throw_stack_overflow
jeffhao12051ea2013-01-10 11:24:31 -0800397 GENERATE_GLOBAL_POINTER
Ian Rogers57b86d42012-03-27 16:05:41 -0700398 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
jeffhao8161c032012-10-31 15:50:00 -0700399 move $a0, rSELF # pass Thread::Current
400 la $t9, artThrowStackOverflowFromCode
401 jr $t9 # artThrowStackOverflowFromCode(Thread*, $sp)
402 move $a1, $sp # pass $sp
Ian Rogers468532e2013-08-05 10:56:33 -0700403END art_quick_throw_stack_overflow
buzbee5bc5a7b2012-03-07 15:52:59 -0800404
Ian Rogers57b86d42012-03-27 16:05:41 -0700405 /*
406 * Called by managed code to create and deliver a NoSuchMethodError.
407 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800408 .extern artThrowNoSuchMethodFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700409ENTRY art_quick_throw_no_such_method
jeffhao12051ea2013-01-10 11:24:31 -0800410 GENERATE_GLOBAL_POINTER
Ian Rogers57b86d42012-03-27 16:05:41 -0700411 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
jeffhao8161c032012-10-31 15:50:00 -0700412 move $a1, rSELF # pass Thread::Current
413 la $t9, artThrowNoSuchMethodFromCode
414 jr $t9 # artThrowNoSuchMethodFromCode(method_idx, Thread*, $sp)
415 move $a2, $sp # pass $sp
Ian Rogers468532e2013-08-05 10:56:33 -0700416END art_quick_throw_no_such_method
buzbee5bc5a7b2012-03-07 15:52:59 -0800417
buzbee5bc5a7b2012-03-07 15:52:59 -0800418 /*
419 * All generated callsites for interface invokes and invocation slow paths will load arguments
jeffhao7fbee072012-08-24 17:56:54 -0700420 * as usual - except instead of loading arg0/$a0 with the target Method*, arg0/$a0 will contain
buzbee5bc5a7b2012-03-07 15:52:59 -0800421 * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the
422 * stack and call the appropriate C helper.
jeffhao7fbee072012-08-24 17:56:54 -0700423 * NOTE: "this" is first visable argument of the target, and so can be found in arg1/$a1.
buzbee5bc5a7b2012-03-07 15:52:59 -0800424 *
jeffhao7fbee072012-08-24 17:56:54 -0700425 * The helper will attempt to locate the target and return a 64-bit result in $v0/$v1 consisting
426 * of the target Method* in $v0 and method->code_ in $v1.
buzbee5bc5a7b2012-03-07 15:52:59 -0800427 *
jeffhaofa147e22012-10-12 17:03:32 -0700428 * If unsuccessful, the helper will return NULL/NULL. There will be a pending exception in the
buzbee5bc5a7b2012-03-07 15:52:59 -0800429 * thread and we branch to another stub to deliver it.
430 *
431 * On success this wrapper will restore arguments and *jump* to the target, leaving the lr
432 * pointing back to the original caller.
433 */
434.macro INVOKE_TRAMPOLINE c_name, cxx_name
buzbee5bc5a7b2012-03-07 15:52:59 -0800435 .extern \cxx_name
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800436ENTRY \c_name
jeffhao12051ea2013-01-10 11:24:31 -0800437 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700438 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME # save callee saves in case allocation triggers GC
Jeff Hao1f3bc2f2013-04-30 15:17:19 -0700439 lw $a2, 64($sp) # pass caller Method*
jeffhaofa147e22012-10-12 17:03:32 -0700440 move $t0, $sp # save $sp
Jeff Hao58df3272013-04-22 15:28:53 -0700441 addiu $sp, $sp, -32 # make space for extra args
442 .cfi_adjust_cfa_offset 32
jeffhao7fbee072012-08-24 17:56:54 -0700443 move $a3, rSELF # pass Thread::Current
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800444 .cfi_rel_offset 28, 12
jeffhao7fbee072012-08-24 17:56:54 -0700445 jal \cxx_name # (method_idx, this, caller, Thread*, $sp)
jeffhaofa147e22012-10-12 17:03:32 -0700446 sw $t0, 16($sp) # pass $sp
Jeff Hao58df3272013-04-22 15:28:53 -0700447 addiu $sp, $sp, 32 # release out args
448 .cfi_adjust_cfa_offset -32
jeffhaofa147e22012-10-12 17:03:32 -0700449 move $a0, $v0 # save target Method*
jeffhao30a33172012-10-22 18:16:22 -0700450 move $t9, $v1 # save $v0->code_
buzbee5bc5a7b2012-03-07 15:52:59 -0800451 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
jeffhaofa147e22012-10-12 17:03:32 -0700452 beqz $v0, 1f
buzbee5bc5a7b2012-03-07 15:52:59 -0800453 nop
jeffhao30a33172012-10-22 18:16:22 -0700454 jr $t9
buzbee5bc5a7b2012-03-07 15:52:59 -0800455 nop
4561:
457 DELIVER_PENDING_EXCEPTION
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800458END \c_name
buzbee5bc5a7b2012-03-07 15:52:59 -0800459.endm
460
Logan Chien8dbb7082013-01-25 20:31:17 +0800461INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline, artInvokeInterfaceTrampoline
462INVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
buzbee5bc5a7b2012-03-07 15:52:59 -0800463
Logan Chien8dbb7082013-01-25 20:31:17 +0800464INVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck
465INVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck
466INVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
467INVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
buzbee5bc5a7b2012-03-07 15:52:59 -0800468
Jeff Hao79fe5392013-04-24 18:41:58 -0700469 /*
Ian Rogersef7d42f2014-01-06 12:55:46 -0800470 * Invocation stub for quick code.
Jeff Hao5d917302013-02-27 17:57:33 -0800471 * On entry:
472 * a0 = method pointer
473 * a1 = argument array or NULL for no argument methods
474 * a2 = size of argument array in bytes
475 * a3 = (managed) thread pointer
Jeff Hao6474d192013-03-26 14:08:09 -0700476 * [sp + 16] = JValue* result
Ian Rogers0177e532014-02-11 16:30:46 -0800477 * [sp + 20] = shorty
Jeff Hao5d917302013-02-27 17:57:33 -0800478 */
479ENTRY art_quick_invoke_stub
480 GENERATE_GLOBAL_POINTER
481 sw $a0, 0($sp) # save out a0
482 addiu $sp, $sp, -16 # spill s0, s1, fp, ra
483 .cfi_adjust_cfa_offset 16
484 sw $ra, 12($sp)
485 .cfi_rel_offset 31, 12
486 sw $fp, 8($sp)
487 .cfi_rel_offset 30, 8
488 sw $s1, 4($sp)
489 .cfi_rel_offset 17, 4
490 sw $s0, 0($sp)
491 .cfi_rel_offset 16, 0
492 move $fp, $sp # save sp in fp
493 .cfi_def_cfa_register 30
494 move $s1, $a3 # move managed thread pointer into s1
495 addiu $s0, $zero, SUSPEND_CHECK_INTERVAL # reset s0 to suspend check interval
496 addiu $t0, $a2, 16 # create space for method pointer in frame
497 srl $t0, $t0, 3 # shift the frame size right 3
498 sll $t0, $t0, 3 # shift the frame size left 3 to align to 16 bytes
499 subu $sp, $sp, $t0 # reserve stack space for argument array
500 addiu $a0, $sp, 4 # pass stack pointer + method ptr as dest for memcpy
501 jal memcpy # (dest, src, bytes)
502 addiu $sp, $sp, -16 # make space for argument slots for memcpy
503 addiu $sp, $sp, 16 # restore stack after memcpy
504 lw $a0, 16($fp) # restore method*
505 lw $a1, 4($sp) # copy arg value for a1
506 lw $a2, 8($sp) # copy arg value for a2
507 lw $a3, 12($sp) # copy arg value for a3
Ian Rogersef7d42f2014-01-06 12:55:46 -0800508 lw $t9, METHOD_QUICK_CODE_OFFSET($a0) # get pointer to the code
Jeff Hao5d917302013-02-27 17:57:33 -0800509 jalr $t9 # call the method
510 sw $zero, 0($sp) # store NULL for method* at bottom of frame
511 move $sp, $fp # restore the stack
512 lw $s0, 0($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800513 .cfi_restore 16
Jeff Hao5d917302013-02-27 17:57:33 -0800514 lw $s1, 4($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800515 .cfi_restore 17
Jeff Hao5d917302013-02-27 17:57:33 -0800516 lw $fp, 8($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800517 .cfi_restore 30
Jeff Hao5d917302013-02-27 17:57:33 -0800518 lw $ra, 12($sp)
Dave Allisonbbb32c22013-11-05 18:25:18 -0800519 .cfi_restore 31
Jeff Hao5d917302013-02-27 17:57:33 -0800520 addiu $sp, $sp, 16
521 .cfi_adjust_cfa_offset -16
522 lw $t0, 16($sp) # get result pointer
Ian Rogers0177e532014-02-11 16:30:46 -0800523 lw $t1, 20($sp) # get shorty
524 lb $t1, 0($t1) # get result type char
Jeff Hao6474d192013-03-26 14:08:09 -0700525 li $t2, 68 # put char 'D' into t2
526 beq $t1, $t2, 1f # branch if result type char == 'D'
527 li $t3, 70 # put char 'F' into t3
528 beq $t1, $t3, 1f # branch if result type char == 'F'
Jeff Hao5d917302013-02-27 17:57:33 -0800529 sw $v0, 0($t0) # store the result
Jeff Hao6474d192013-03-26 14:08:09 -0700530 jr $ra
Jeff Hao5d917302013-02-27 17:57:33 -0800531 sw $v1, 4($t0) # store the other half of the result
Jeff Hao6474d192013-03-26 14:08:09 -07005321:
Jeff Hao19ca8cf2013-03-15 18:16:51 -0700533 s.s $f0, 0($t0) # store floating point result
Jeff Hao5d917302013-02-27 17:57:33 -0800534 jr $ra
Jeff Hao19ca8cf2013-03-15 18:16:51 -0700535 s.s $f1, 4($t0) # store other half of floating point result
Jeff Hao5d917302013-02-27 17:57:33 -0800536END art_quick_invoke_stub
537
538 /*
buzbee5bc5a7b2012-03-07 15:52:59 -0800539 * Entry from managed code that calls artHandleFillArrayDataFromCode and delivers exception on
540 * failure.
541 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800542 .extern artHandleFillArrayDataFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700543ENTRY art_quick_handle_fill_data
jeffhao12051ea2013-01-10 11:24:31 -0800544 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700545 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case exception allocation triggers GC
546 move $a2, rSELF # pass Thread::Current
547 jal artHandleFillArrayDataFromCode # (Array*, const DexFile::Payload*, Thread*, $sp)
548 move $a3, $sp # pass $sp
jeffhaofc6a30e2012-10-18 18:24:15 -0700549 RETURN_IF_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700550END art_quick_handle_fill_data
buzbee5bc5a7b2012-03-07 15:52:59 -0800551
buzbee5bc5a7b2012-03-07 15:52:59 -0800552 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700553 * Entry from managed code that calls artLockObjectFromCode, may block for GC.
buzbee5bc5a7b2012-03-07 15:52:59 -0800554 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800555 .extern artLockObjectFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700556ENTRY art_quick_lock_object
jeffhao12051ea2013-01-10 11:24:31 -0800557 GENERATE_GLOBAL_POINTER
Ian Rogers86bcdc22014-02-21 22:06:38 -0800558 beqz $a0, .Lart_quick_throw_null_pointer_exception_gp_set
Ian Rogersa9a82542013-10-04 11:17:26 -0700559 nop
jeffhao7fbee072012-08-24 17:56:54 -0700560 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case we block
561 move $a1, rSELF # pass Thread::Current
562 jal artLockObjectFromCode # (Object* obj, Thread*, $sp)
563 move $a2, $sp # pass $sp
Ian Rogers6bcd1632013-10-08 18:50:47 -0700564 RETURN_IF_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700565END art_quick_lock_object
buzbee5bc5a7b2012-03-07 15:52:59 -0800566
buzbee5bc5a7b2012-03-07 15:52:59 -0800567 /*
568 * Entry from managed code that calls artUnlockObjectFromCode and delivers exception on failure.
569 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800570 .extern artUnlockObjectFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700571ENTRY art_quick_unlock_object
jeffhao12051ea2013-01-10 11:24:31 -0800572 GENERATE_GLOBAL_POINTER
Ian Rogers86bcdc22014-02-21 22:06:38 -0800573 beqz $a0, .Lart_quick_throw_null_pointer_exception_gp_set
Ian Rogersa9a82542013-10-04 11:17:26 -0700574 nop
jeffhao7fbee072012-08-24 17:56:54 -0700575 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case exception allocation triggers GC
576 move $a1, rSELF # pass Thread::Current
577 jal artUnlockObjectFromCode # (Object* obj, Thread*, $sp)
578 move $a2, $sp # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800579 RETURN_IF_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700580END art_quick_unlock_object
buzbee5bc5a7b2012-03-07 15:52:59 -0800581
buzbee5bc5a7b2012-03-07 15:52:59 -0800582 /*
583 * Entry from managed code that calls artCheckCastFromCode and delivers exception on failure.
584 */
Ian Rogersa9a82542013-10-04 11:17:26 -0700585 .extern artThrowClassCastException
Ian Rogers468532e2013-08-05 10:56:33 -0700586ENTRY art_quick_check_cast
jeffhao12051ea2013-01-10 11:24:31 -0800587 GENERATE_GLOBAL_POINTER
Ian Rogersa9a82542013-10-04 11:17:26 -0700588 addiu $sp, $sp, -16
589 .cfi_adjust_cfa_offset 16
590 sw $ra, 12($sp)
591 .cfi_rel_offset 31, 12
592 sw $t9, 8($sp)
593 sw $a1, 4($sp)
594 sw $a0, 0($sp)
595 jal artIsAssignableFromCode
596 nop
Ian Rogers86bcdc22014-02-21 22:06:38 -0800597 beqz $v0, .Lthrow_class_cast_exception
Ian Rogersa9a82542013-10-04 11:17:26 -0700598 lw $ra, 12($sp)
599 jr $ra
600 addiu $sp, $sp, 16
601 .cfi_adjust_cfa_offset -16
Ian Rogers86bcdc22014-02-21 22:06:38 -0800602.Lthrow_class_cast_exception:
Ian Rogersa9a82542013-10-04 11:17:26 -0700603 lw $t9, 8($sp)
604 lw $a1, 4($sp)
605 lw $a0, 0($sp)
606 addiu $sp, $sp, 16
607 .cfi_adjust_cfa_offset -16
608 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
609 move $a2, rSELF # pass Thread::Current
610 la $t9, artThrowClassCastException
611 jr $t9 # artThrowClassCastException (Class*, Class*, Thread*, SP)
612 move $a3, $sp # pass $sp
Ian Rogers468532e2013-08-05 10:56:33 -0700613END art_quick_check_cast
buzbee5bc5a7b2012-03-07 15:52:59 -0800614
buzbee5bc5a7b2012-03-07 15:52:59 -0800615 /*
Ian Rogersa9a82542013-10-04 11:17:26 -0700616 * Entry from managed code for array put operations of objects where the value being stored
617 * needs to be checked for compatibility.
618 * a0 = array, a1 = index, a2 = value
buzbee5bc5a7b2012-03-07 15:52:59 -0800619 */
Ian Rogersa9a82542013-10-04 11:17:26 -0700620ENTRY art_quick_aput_obj_with_null_and_bound_check
jeffhao12051ea2013-01-10 11:24:31 -0800621 GENERATE_GLOBAL_POINTER
Ian Rogers86bcdc22014-02-21 22:06:38 -0800622 bnez $a0, .Lart_quick_aput_obj_with_bound_check_gp_set
Ian Rogersa9a82542013-10-04 11:17:26 -0700623 nop
Ian Rogers86bcdc22014-02-21 22:06:38 -0800624 b .Lart_quick_throw_null_pointer_exception_gp_set
Ian Rogersa9a82542013-10-04 11:17:26 -0700625 nop
626END art_quick_aput_obj_with_null_and_bound_check
627
628ENTRY art_quick_aput_obj_with_bound_check
629 GENERATE_GLOBAL_POINTER
Ian Rogers86bcdc22014-02-21 22:06:38 -0800630.Lart_quick_aput_obj_with_bound_check_gp_set:
Ian Rogersa9a82542013-10-04 11:17:26 -0700631 lw $t0, ARRAY_LENGTH_OFFSET($a0)
632 sltu $t1, $a1, $t0
Ian Rogers86bcdc22014-02-21 22:06:38 -0800633 bnez $t1, .Lart_quick_aput_obj_gp_set
Ian Rogersa9a82542013-10-04 11:17:26 -0700634 nop
635 move $a0, $a1
Ian Rogers86bcdc22014-02-21 22:06:38 -0800636 b .Lart_quick_throw_array_bounds_gp_set
Ian Rogersa9a82542013-10-04 11:17:26 -0700637 move $a1, $t0
638END art_quick_aput_obj_with_bound_check
639
640ENTRY art_quick_aput_obj
641 GENERATE_GLOBAL_POINTER
Ian Rogers86bcdc22014-02-21 22:06:38 -0800642.Lart_quick_aput_obj_gp_set:
643 beqz $a2, .Ldo_aput_null
Ian Rogersa9a82542013-10-04 11:17:26 -0700644 nop
645 lw $t0, CLASS_OFFSET($a0)
646 lw $t1, CLASS_OFFSET($a2)
647 lw $t0, CLASS_COMPONENT_TYPE_OFFSET($t0)
Ian Rogers86bcdc22014-02-21 22:06:38 -0800648 bne $t1, $t0, .Lcheck_assignability # value's type == array's component type - trivial assignability
Ian Rogersa9a82542013-10-04 11:17:26 -0700649 nop
Ian Rogers86bcdc22014-02-21 22:06:38 -0800650.Ldo_aput:
Ian Rogersa9a82542013-10-04 11:17:26 -0700651 sll $a1, $a1, 2
652 add $t0, $a0, $a1
653 sw $a2, OBJECT_ARRAY_DATA_OFFSET($t0)
654 lw $t0, THREAD_CARD_TABLE_OFFSET(rSELF)
655 srl $t1, $a0, 7
656 add $t1, $t1, $t0
657 sb $t0, ($t1)
658 jr $ra
659 nop
Ian Rogers86bcdc22014-02-21 22:06:38 -0800660.Ldo_aput_null:
Ian Rogersa9a82542013-10-04 11:17:26 -0700661 sll $a1, $a1, 2
662 add $t0, $a0, $a1
663 sw $a2, OBJECT_ARRAY_DATA_OFFSET($t0)
664 jr $ra
665 nop
Ian Rogers86bcdc22014-02-21 22:06:38 -0800666.Lcheck_assignability:
Ian Rogersa9a82542013-10-04 11:17:26 -0700667 addiu $sp, $sp, -32
668 .cfi_adjust_cfa_offset 32
669 sw $ra, 28($sp)
670 .cfi_rel_offset 31, 28
671 sw $t9, 12($sp)
672 sw $a2, 8($sp)
673 sw $a1, 4($sp)
674 sw $a0, 0($sp)
675 move $a1, $t1
676 move $a0, $t0
677 jal artIsAssignableFromCode # (Class*, Class*)
678 nop
679 lw $ra, 28($sp)
680 lw $t9, 12($sp)
681 lw $a2, 8($sp)
682 lw $a1, 4($sp)
683 lw $a0, 0($sp)
684 add $sp, 32
685 .cfi_adjust_cfa_offset -32
Ian Rogers86bcdc22014-02-21 22:06:38 -0800686 bnez $v0, .Ldo_aput
Ian Rogersa9a82542013-10-04 11:17:26 -0700687 nop
688 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
689 move $a1, $a2
690 move $a2, rSELF # pass Thread::Current
691 la $t9, artThrowArrayStoreException
692 jr $t9 # artThrowArrayStoreException(Class*, Class*, Thread*, SP)
693 move $a3, $sp # pass $sp
694END art_quick_aput_obj
buzbee5bc5a7b2012-03-07 15:52:59 -0800695
buzbee5bc5a7b2012-03-07 15:52:59 -0800696 /*
697 * Entry from managed code when uninitialized static storage, this stub will run the class
698 * initializer and deliver the exception on error. On success the static storage base is
699 * returned.
700 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800701 .extern artInitializeStaticStorageFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700702ENTRY art_quick_initialize_static_storage
jeffhao12051ea2013-01-10 11:24:31 -0800703 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700704 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
705 move $a2, rSELF # pass Thread::Current
706 # artInitializeStaticStorageFromCode(uint32_t type_idx, Method* referrer, Thread*, $sp)
buzbee5bc5a7b2012-03-07 15:52:59 -0800707 jal artInitializeStaticStorageFromCode
jeffhao7fbee072012-08-24 17:56:54 -0700708 move $a3, $sp # pass $sp
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800709 RETURN_IF_RESULT_IS_NON_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700710END art_quick_initialize_static_storage
buzbee5bc5a7b2012-03-07 15:52:59 -0800711
buzbee5bc5a7b2012-03-07 15:52:59 -0800712 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700713 * Entry from managed code when dex cache misses for a type_idx.
buzbee5bc5a7b2012-03-07 15:52:59 -0800714 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800715 .extern artInitializeTypeFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700716ENTRY art_quick_initialize_type
jeffhao12051ea2013-01-10 11:24:31 -0800717 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700718 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
719 move $a2, rSELF # pass Thread::Current
720 # artInitializeTypeFromCode(uint32_t type_idx, Method* referrer, Thread*, $sp)
buzbee5bc5a7b2012-03-07 15:52:59 -0800721 jal artInitializeTypeFromCode
jeffhao7fbee072012-08-24 17:56:54 -0700722 move $a3, $sp # pass $sp
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800723 RETURN_IF_RESULT_IS_NON_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700724END art_quick_initialize_type
buzbee5bc5a7b2012-03-07 15:52:59 -0800725
buzbee5bc5a7b2012-03-07 15:52:59 -0800726 /*
727 * Entry from managed code when type_idx needs to be checked for access and dex cache may also
Ian Rogers57b86d42012-03-27 16:05:41 -0700728 * miss.
buzbee5bc5a7b2012-03-07 15:52:59 -0800729 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800730 .extern artInitializeTypeAndVerifyAccessFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700731ENTRY art_quick_initialize_type_and_verify_access
jeffhao12051ea2013-01-10 11:24:31 -0800732 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700733 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
734 move $a2, rSELF # pass Thread::Current
735 # artInitializeTypeFromCode(uint32_t type_idx, Method* referrer, Thread*, $sp)
buzbee5bc5a7b2012-03-07 15:52:59 -0800736 jal artInitializeTypeAndVerifyAccessFromCode
jeffhao7fbee072012-08-24 17:56:54 -0700737 move $a3, $sp # pass $sp
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800738 RETURN_IF_RESULT_IS_NON_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700739END art_quick_initialize_type_and_verify_access
buzbee5bc5a7b2012-03-07 15:52:59 -0800740
buzbee5bc5a7b2012-03-07 15:52:59 -0800741 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700742 * Called by managed code to resolve a static field and load a 32-bit primitive value.
buzbee5bc5a7b2012-03-07 15:52:59 -0800743 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800744 .extern artGet32StaticFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700745ENTRY art_quick_get32_static
jeffhao12051ea2013-01-10 11:24:31 -0800746 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700747 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jeffhao4eb68ed2012-10-17 16:41:07 -0700748 lw $a1, 64($sp) # pass referrer's Method*
jeffhao7fbee072012-08-24 17:56:54 -0700749 move $a2, rSELF # pass Thread::Current
jeffhaofa147e22012-10-12 17:03:32 -0700750 jal artGet32StaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp)
jeffhao7fbee072012-08-24 17:56:54 -0700751 move $a3, $sp # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800752 RETURN_IF_NO_EXCEPTION
Ian Rogers468532e2013-08-05 10:56:33 -0700753END art_quick_get32_static
buzbee5bc5a7b2012-03-07 15:52:59 -0800754
buzbee5bc5a7b2012-03-07 15:52:59 -0800755 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700756 * Called by managed code to resolve a static field and load a 64-bit primitive value.
buzbee5bc5a7b2012-03-07 15:52:59 -0800757 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800758 .extern artGet64StaticFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700759ENTRY art_quick_get64_static
jeffhao12051ea2013-01-10 11:24:31 -0800760 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700761 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jeffhao4eb68ed2012-10-17 16:41:07 -0700762 lw $a1, 64($sp) # pass referrer's Method*
jeffhao7fbee072012-08-24 17:56:54 -0700763 move $a2, rSELF # pass Thread::Current
jeffhaofa147e22012-10-12 17:03:32 -0700764 jal artGet64StaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp)
jeffhao7fbee072012-08-24 17:56:54 -0700765 move $a3, $sp # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800766 RETURN_IF_NO_EXCEPTION
Ian Rogers468532e2013-08-05 10:56:33 -0700767END art_quick_get64_static
buzbee5bc5a7b2012-03-07 15:52:59 -0800768
buzbee5bc5a7b2012-03-07 15:52:59 -0800769 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700770 * Called by managed code to resolve a static field and load an object reference.
buzbee5bc5a7b2012-03-07 15:52:59 -0800771 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800772 .extern artGetObjStaticFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700773ENTRY art_quick_get_obj_static
jeffhao12051ea2013-01-10 11:24:31 -0800774 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700775 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jeffhao4eb68ed2012-10-17 16:41:07 -0700776 lw $a1, 64($sp) # pass referrer's Method*
jeffhao7fbee072012-08-24 17:56:54 -0700777 move $a2, rSELF # pass Thread::Current
jeffhaofa147e22012-10-12 17:03:32 -0700778 jal artGetObjStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp)
jeffhao7fbee072012-08-24 17:56:54 -0700779 move $a3, $sp # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800780 RETURN_IF_NO_EXCEPTION
Ian Rogers468532e2013-08-05 10:56:33 -0700781END art_quick_get_obj_static
buzbee5bc5a7b2012-03-07 15:52:59 -0800782
buzbee5bc5a7b2012-03-07 15:52:59 -0800783 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700784 * Called by managed code to resolve an instance field and load a 32-bit primitive value.
buzbee5bc5a7b2012-03-07 15:52:59 -0800785 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800786 .extern artGet32InstanceFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700787ENTRY art_quick_get32_instance
jeffhao12051ea2013-01-10 11:24:31 -0800788 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700789 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jeffhao4eb68ed2012-10-17 16:41:07 -0700790 lw $a2, 64($sp) # pass referrer's Method*
jeffhao7fbee072012-08-24 17:56:54 -0700791 move $a3, rSELF # pass Thread::Current
jeffhaofa147e22012-10-12 17:03:32 -0700792 jal artGet32InstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp)
jeffhao4eb68ed2012-10-17 16:41:07 -0700793 sw $sp, 16($sp) # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800794 RETURN_IF_NO_EXCEPTION
Ian Rogers468532e2013-08-05 10:56:33 -0700795END art_quick_get32_instance
buzbee5bc5a7b2012-03-07 15:52:59 -0800796
buzbee5bc5a7b2012-03-07 15:52:59 -0800797 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700798 * Called by managed code to resolve an instance field and load a 64-bit primitive value.
buzbee5bc5a7b2012-03-07 15:52:59 -0800799 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800800 .extern artGet64InstanceFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700801ENTRY art_quick_get64_instance
jeffhao12051ea2013-01-10 11:24:31 -0800802 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700803 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jeffhao4eb68ed2012-10-17 16:41:07 -0700804 lw $a2, 64($sp) # pass referrer's Method*
jeffhao7fbee072012-08-24 17:56:54 -0700805 move $a3, rSELF # pass Thread::Current
jeffhaofa147e22012-10-12 17:03:32 -0700806 jal artGet64InstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp)
jeffhao4eb68ed2012-10-17 16:41:07 -0700807 sw $sp, 16($sp) # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800808 RETURN_IF_NO_EXCEPTION
Ian Rogers468532e2013-08-05 10:56:33 -0700809END art_quick_get64_instance
buzbee5bc5a7b2012-03-07 15:52:59 -0800810
buzbee5bc5a7b2012-03-07 15:52:59 -0800811 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700812 * Called by managed code to resolve an instance field and load an object reference.
buzbee5bc5a7b2012-03-07 15:52:59 -0800813 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800814 .extern artGetObjInstanceFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700815ENTRY art_quick_get_obj_instance
jeffhao12051ea2013-01-10 11:24:31 -0800816 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700817 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jeffhao4eb68ed2012-10-17 16:41:07 -0700818 lw $a2, 64($sp) # pass referrer's Method*
jeffhao7fbee072012-08-24 17:56:54 -0700819 move $a3, rSELF # pass Thread::Current
jeffhaofa147e22012-10-12 17:03:32 -0700820 jal artGetObjInstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp)
jeffhao4eb68ed2012-10-17 16:41:07 -0700821 sw $sp, 16($sp) # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800822 RETURN_IF_NO_EXCEPTION
Ian Rogers468532e2013-08-05 10:56:33 -0700823END art_quick_get_obj_instance
buzbee5bc5a7b2012-03-07 15:52:59 -0800824
buzbee5bc5a7b2012-03-07 15:52:59 -0800825 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700826 * Called by managed code to resolve a static field and store a 32-bit primitive value.
buzbee5bc5a7b2012-03-07 15:52:59 -0800827 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800828 .extern artSet32StaticFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700829ENTRY art_quick_set32_static
jeffhao12051ea2013-01-10 11:24:31 -0800830 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700831 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jeffhao4eb68ed2012-10-17 16:41:07 -0700832 lw $a2, 64($sp) # pass referrer's Method*
jeffhao7fbee072012-08-24 17:56:54 -0700833 move $a3, rSELF # pass Thread::Current
jeffhaofa147e22012-10-12 17:03:32 -0700834 jal artSet32StaticFromCode # (field_idx, new_val, referrer, Thread*, $sp)
jeffhao4eb68ed2012-10-17 16:41:07 -0700835 sw $sp, 16($sp) # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800836 RETURN_IF_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700837END art_quick_set32_static
buzbee5bc5a7b2012-03-07 15:52:59 -0800838
buzbee5bc5a7b2012-03-07 15:52:59 -0800839 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700840 * Called by managed code to resolve a static field and store a 64-bit primitive value.
buzbee5bc5a7b2012-03-07 15:52:59 -0800841 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800842 .extern artSet32StaticFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700843ENTRY art_quick_set64_static
jeffhao12051ea2013-01-10 11:24:31 -0800844 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700845 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jeffhao4eb68ed2012-10-17 16:41:07 -0700846 lw $a1, 64($sp) # pass referrer's Method*
jeffhaofa147e22012-10-12 17:03:32 -0700847 sw rSELF, 16($sp) # pass Thread::Current
jeffhao7fbee072012-08-24 17:56:54 -0700848 jal artSet64StaticFromCode # (field_idx, referrer, new_val, Thread*, $sp)
jeffhao4eb68ed2012-10-17 16:41:07 -0700849 sw $sp, 20($sp) # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800850 RETURN_IF_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700851END art_quick_set64_static
buzbee5bc5a7b2012-03-07 15:52:59 -0800852
buzbee5bc5a7b2012-03-07 15:52:59 -0800853 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700854 * Called by managed code to resolve a static field and store an object reference.
buzbee5bc5a7b2012-03-07 15:52:59 -0800855 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800856 .extern artSetObjStaticFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700857ENTRY art_quick_set_obj_static
jeffhao12051ea2013-01-10 11:24:31 -0800858 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700859 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jeffhao4eb68ed2012-10-17 16:41:07 -0700860 lw $a2, 64($sp) # pass referrer's Method*
jeffhao7fbee072012-08-24 17:56:54 -0700861 move $a3, rSELF # pass Thread::Current
jeffhaofa147e22012-10-12 17:03:32 -0700862 jal artSetObjStaticFromCode # (field_idx, new_val, referrer, Thread*, $sp)
jeffhao4eb68ed2012-10-17 16:41:07 -0700863 sw $sp, 16($sp) # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800864 RETURN_IF_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700865END art_quick_set_obj_static
buzbee5bc5a7b2012-03-07 15:52:59 -0800866
buzbee5bc5a7b2012-03-07 15:52:59 -0800867 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700868 * Called by managed code to resolve an instance field and store a 32-bit primitive value.
buzbee5bc5a7b2012-03-07 15:52:59 -0800869 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800870 .extern artSet32InstanceFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700871ENTRY art_quick_set32_instance
jeffhao12051ea2013-01-10 11:24:31 -0800872 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700873 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jeffhao4eb68ed2012-10-17 16:41:07 -0700874 lw $a3, 64($sp) # pass referrer's Method*
jeffhaofa147e22012-10-12 17:03:32 -0700875 sw rSELF, 16($sp) # pass Thread::Current
jeffhao7fbee072012-08-24 17:56:54 -0700876 jal artSet32InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*, $sp)
jeffhao4eb68ed2012-10-17 16:41:07 -0700877 sw $sp, 20($sp) # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800878 RETURN_IF_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700879END art_quick_set32_instance
buzbee5bc5a7b2012-03-07 15:52:59 -0800880
buzbee5bc5a7b2012-03-07 15:52:59 -0800881 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700882 * Called by managed code to resolve an instance field and store a 64-bit primitive value.
buzbee5bc5a7b2012-03-07 15:52:59 -0800883 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800884 .extern artSet32InstanceFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700885ENTRY art_quick_set64_instance
jeffhao12051ea2013-01-10 11:24:31 -0800886 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700887 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jeffhaofa147e22012-10-12 17:03:32 -0700888 sw rSELF, 16($sp) # pass Thread::Current
889 jal artSet64InstanceFromCode # (field_idx, Object*, new_val, Thread*, $sp)
jeffhao4eb68ed2012-10-17 16:41:07 -0700890 sw $sp, 20($sp) # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800891 RETURN_IF_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700892END art_quick_set64_instance
buzbee5bc5a7b2012-03-07 15:52:59 -0800893
buzbee5bc5a7b2012-03-07 15:52:59 -0800894 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700895 * Called by managed code to resolve an instance field and store an object reference.
buzbee5bc5a7b2012-03-07 15:52:59 -0800896 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800897 .extern artSetObjInstanceFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700898ENTRY art_quick_set_obj_instance
jeffhao12051ea2013-01-10 11:24:31 -0800899 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700900 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
jeffhao4eb68ed2012-10-17 16:41:07 -0700901 lw $a3, 64($sp) # pass referrer's Method*
jeffhaofa147e22012-10-12 17:03:32 -0700902 sw rSELF, 16($sp) # pass Thread::Current
903 jal artSetObjInstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*, $sp)
jeffhao4eb68ed2012-10-17 16:41:07 -0700904 sw $sp, 20($sp) # pass $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800905 RETURN_IF_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700906END art_quick_set_obj_instance
buzbee5bc5a7b2012-03-07 15:52:59 -0800907
buzbee5bc5a7b2012-03-07 15:52:59 -0800908 /*
909 * Entry from managed code to resolve a string, this stub will allocate a String and deliver an
910 * exception on error. On success the String is returned. R0 holds the referring method,
911 * R1 holds the string index. The fast path check for hit in strings cache has already been
912 * performed.
913 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800914 .extern artResolveStringFromCode
Ian Rogers468532e2013-08-05 10:56:33 -0700915ENTRY art_quick_resolve_string
jeffhao12051ea2013-01-10 11:24:31 -0800916 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700917 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
918 move $a2, rSELF # pass Thread::Current
919 # artResolveStringFromCode(Method* referrer, uint32_t string_idx, Thread*, $sp)
buzbee5bc5a7b2012-03-07 15:52:59 -0800920 jal artResolveStringFromCode
jeffhao7fbee072012-08-24 17:56:54 -0700921 move $a3, $sp # pass $sp
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800922 RETURN_IF_RESULT_IS_NON_ZERO
Ian Rogers468532e2013-08-05 10:56:33 -0700923END art_quick_resolve_string
buzbee5bc5a7b2012-03-07 15:52:59 -0800924
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800925
926// Macro to facilitate adding new allocation entrypoints.
927.macro TWO_ARG_DOWNCALL name, entrypoint, return
928 .extern \entrypoint
929ENTRY \name
jeffhao12051ea2013-01-10 11:24:31 -0800930 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700931 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
932 move $a2, rSELF # pass Thread::Current
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800933 jal \entrypoint
jeffhao7fbee072012-08-24 17:56:54 -0700934 move $a3, $sp # pass $sp
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800935 \return
936END \name
937.endm
buzbee5bc5a7b2012-03-07 15:52:59 -0800938
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800939.macro THREE_ARG_DOWNCALL name, entrypoint, return
940 .extern \entrypoint
941ENTRY \name
jeffhao12051ea2013-01-10 11:24:31 -0800942 GENERATE_GLOBAL_POINTER
jeffhao7fbee072012-08-24 17:56:54 -0700943 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
944 move $a3, rSELF # pass Thread::Current
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800945 jal \entrypoint
jeffhao4eb68ed2012-10-17 16:41:07 -0700946 sw $sp, 16($sp) # pass $sp
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800947 \return
948END \name
949.endm
buzbee5bc5a7b2012-03-07 15:52:59 -0800950
Mathieu Chartier7410f292013-11-24 13:17:35 -0800951// Generate the allocation entrypoints for each allocator.
952GENERATE_ALL_ALLOC_ENTRYPOINTS
Hiroshi Yamauchi3b4c1892013-09-12 21:33:12 -0700953
buzbee5bc5a7b2012-03-07 15:52:59 -0800954 /*
Ian Rogers57b86d42012-03-27 16:05:41 -0700955 * Called by managed code when the value in rSUSPEND has been decremented to 0.
buzbee5bc5a7b2012-03-07 15:52:59 -0800956 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800957 .extern artTestSuspendFromCode
958ENTRY art_quick_test_suspend
jeffhao12051ea2013-01-10 11:24:31 -0800959 GENERATE_GLOBAL_POINTER
Ian Rogers474b6da2012-09-25 00:20:38 -0700960 lh $a0, THREAD_FLAGS_OFFSET(rSELF)
jeffhao7fbee072012-08-24 17:56:54 -0700961 bnez $a0, 1f
962 addi rSUSPEND, $zero, SUSPEND_CHECK_INTERVAL # reset rSUSPEND to SUSPEND_CHECK_INTERVAL
963 jr $ra
buzbee5bc5a7b2012-03-07 15:52:59 -0800964 nop
9651:
jeffhao7fbee072012-08-24 17:56:54 -0700966 move $a0, rSELF
967 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves for stack crawl
968 jal artTestSuspendFromCode # (Thread*, $sp)
969 move $a1, $sp
buzbee5bc5a7b2012-03-07 15:52:59 -0800970 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME_AND_RETURN
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800971END art_quick_test_suspend
buzbee5bc5a7b2012-03-07 15:52:59 -0800972
buzbee5bc5a7b2012-03-07 15:52:59 -0800973 /*
974 * Called by managed code that is attempting to call a method on a proxy class. On entry
Ian Rogers57b86d42012-03-27 16:05:41 -0700975 * r0 holds the proxy method; r1, r2 and r3 may contain arguments.
buzbee5bc5a7b2012-03-07 15:52:59 -0800976 */
Jeff Hao5fa60c32013-04-04 17:57:01 -0700977 .extern artQuickProxyInvokeHandler
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800978ENTRY art_quick_proxy_invoke_handler
jeffhao12051ea2013-01-10 11:24:31 -0800979 GENERATE_GLOBAL_POINTER
buzbee5bc5a7b2012-03-07 15:52:59 -0800980 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
jeffhao7fbee072012-08-24 17:56:54 -0700981 sw $a0, 0($sp) # place proxy method at bottom of frame
982 move $a2, rSELF # pass Thread::Current
Jeff Hao5fa60c32013-04-04 17:57:01 -0700983 jal artQuickProxyInvokeHandler # (Method* proxy method, receiver, Thread*, SP)
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800984 move $a3, $sp # pass $sp
jeffhao7fbee072012-08-24 17:56:54 -0700985 lw $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
Mathieu Chartier19841522013-10-22 11:29:00 -0700986 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
jeffhao7fbee072012-08-24 17:56:54 -0700987 bnez $t0, 1f
Mathieu Chartier19841522013-10-22 11:29:00 -0700988 nop
jeffhao7fbee072012-08-24 17:56:54 -0700989 jr $ra
buzbee5bc5a7b2012-03-07 15:52:59 -0800990 nop
9911:
992 DELIVER_PENDING_EXCEPTION
Jeff Haod4c3f7d2013-02-14 14:14:44 -0800993END art_quick_proxy_invoke_handler
buzbee5bc5a7b2012-03-07 15:52:59 -0800994
Jeff Hao88474b42013-10-23 16:24:40 -0700995 /*
996 * Called to resolve an imt conflict. t0 is a hidden argument that holds the target method's
997 * dex method index.
998 */
999ENTRY art_quick_imt_conflict_trampoline
1000 GENERATE_GLOBAL_POINTER
1001 lw $a0, 0($sp) # load caller Method*
1002 lw $a0, METHOD_DEX_CACHE_METHODS_OFFSET($a0) # load dex_cache_resolved_methods
1003 sll $t0, 2 # convert target method offset to bytes
1004 add $a0, $t0 # get address of target method
1005 lw $a0, OBJECT_ARRAY_DATA_OFFSET($a0) # load the target method
1006 la $t9, art_quick_invoke_interface_trampoline
1007 jr $t9
1008END art_quick_imt_conflict_trampoline
1009
Ian Rogers468532e2013-08-05 10:56:33 -07001010 .extern artQuickResolutionTrampoline
1011ENTRY art_quick_resolution_trampoline
Ian Rogers7db619b2013-01-16 18:35:48 -08001012 GENERATE_GLOBAL_POINTER
1013 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
Ian Rogers468532e2013-08-05 10:56:33 -07001014 move $a2, rSELF # pass Thread::Current
Ian Rogers65d1b222013-09-27 10:59:41 -07001015 jal artQuickResolutionTrampoline # (Method* called, receiver, Thread*, SP)
Ian Rogers468532e2013-08-05 10:56:33 -07001016 move $a3, $sp # pass $sp
Ian Rogers468532e2013-08-05 10:56:33 -07001017 beqz $v0, 1f
1018 lw $a0, 0($sp) # load resolved method to $a0
Mathieu Chartier19841522013-10-22 11:29:00 -07001019 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
Ian Rogers65d1b222013-09-27 10:59:41 -07001020 move $t9, $v0 # code pointer must be in $t9 to generate the global pointer
Ian Rogers468532e2013-08-05 10:56:33 -07001021 jr $v0 # tail call to method
Mathieu Chartier19841522013-10-22 11:29:00 -07001022 nop
Ian Rogers468532e2013-08-05 10:56:33 -070010231:
Mathieu Chartier19841522013-10-22 11:29:00 -07001024 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
Ian Rogers468532e2013-08-05 10:56:33 -07001025 DELIVER_PENDING_EXCEPTION
1026END art_quick_resolution_trampoline
1027
Andreas Gampe2da88232014-02-27 12:26:20 -08001028UNIMPLEMENTED art_quick_generic_jni_trampoline
1029
Ian Rogers468532e2013-08-05 10:56:33 -07001030 .extern artQuickToInterpreterBridge
1031ENTRY art_quick_to_interpreter_bridge
1032 GENERATE_GLOBAL_POINTER
1033 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
Ian Rogers7db619b2013-01-16 18:35:48 -08001034 move $a1, rSELF # pass Thread::Current
Ian Rogers468532e2013-08-05 10:56:33 -07001035 jal artQuickToInterpreterBridge # (Method* method, Thread*, SP)
Ian Rogers7db619b2013-01-16 18:35:48 -08001036 move $a2, $sp # pass $sp
1037 lw $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_
Mathieu Chartier19841522013-10-22 11:29:00 -07001038 RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
Ian Rogers7db619b2013-01-16 18:35:48 -08001039 bnez $t0, 1f
Mathieu Chartier19841522013-10-22 11:29:00 -07001040 nop
Ian Rogers7db619b2013-01-16 18:35:48 -08001041 jr $ra
1042 nop
10431:
1044 DELIVER_PENDING_EXCEPTION
Ian Rogers468532e2013-08-05 10:56:33 -07001045END art_quick_to_interpreter_bridge
Ian Rogers7db619b2013-01-16 18:35:48 -08001046
buzbee5bc5a7b2012-03-07 15:52:59 -08001047 /*
jeffhao725a9572012-11-13 18:20:12 -08001048 * Routine that intercepts method calls and returns.
buzbee5bc5a7b2012-03-07 15:52:59 -08001049 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001050 .extern artInstrumentationMethodEntryFromCode
1051 .extern artInstrumentationMethodExitFromCode
Ian Rogers468532e2013-08-05 10:56:33 -07001052ENTRY art_quick_instrumentation_entry
jeffhao12051ea2013-01-10 11:24:31 -08001053 GENERATE_GLOBAL_POINTER
Ian Rogers62d6c772013-02-27 08:32:07 -08001054 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
jeffhao12051ea2013-01-10 11:24:31 -08001055 move $t0, $sp # remember bottom of caller's frame
Ian Rogers62d6c772013-02-27 08:32:07 -08001056 addiu $sp, $sp, -32 # space for args, pad (3 words), arguments (5 words)
1057 .cfi_adjust_cfa_offset 32
1058 sw $a0, 28($sp) # save arg0
1059 sw $ra, 16($sp) # pass $ra
1060 move $a3, $t0 # pass $sp
1061 jal artInstrumentationMethodEntryFromCode # (Method*, Object*, Thread*, SP, LR)
1062 move $a2, rSELF # pass Thread::Current
jeffhao8161c032012-10-31 15:50:00 -07001063 move $t9, $v0 # $t9 holds reference to code
Ian Rogers62d6c772013-02-27 08:32:07 -08001064 lw $a0, 28($sp) # restore arg0
1065 addiu $sp, $sp, 32 # remove args
1066 .cfi_adjust_cfa_offset -32
1067 RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
jeffhao8161c032012-10-31 15:50:00 -07001068 jalr $t9 # call method
Ian Rogers62d6c772013-02-27 08:32:07 -08001069 nop
Ian Rogers468532e2013-08-05 10:56:33 -07001070END art_quick_instrumentation_entry
buzbee5bc5a7b2012-03-07 15:52:59 -08001071 /* intentional fallthrough */
Ian Rogers468532e2013-08-05 10:56:33 -07001072 .global art_quick_instrumentation_exit
1073art_quick_instrumentation_exit:
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001074 .cfi_startproc
jeffhao12051ea2013-01-10 11:24:31 -08001075 addiu $t9, $ra, 4 # put current address into $t9 to rebuild $gp
1076 GENERATE_GLOBAL_POINTER
1077 move $t0, $sp # remember bottom of caller's frame
Ian Rogers62d6c772013-02-27 08:32:07 -08001078 SETUP_REF_ONLY_CALLEE_SAVE_FRAME
1079 addiu $sp, $sp, -48 # save return values and set up args
1080 .cfi_adjust_cfa_offset 48
1081 sw $v0, 32($sp)
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001082 .cfi_rel_offset 2, 0
Ian Rogers62d6c772013-02-27 08:32:07 -08001083 sw $v1, 36($sp)
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001084 .cfi_rel_offset 3, 4
Ian Rogers62d6c772013-02-27 08:32:07 -08001085 s.s $f0, 40($sp)
1086 s.s $f1, 44($sp)
1087 s.s $f0, 16($sp) # pass fpr result
1088 s.s $f1, 20($sp)
1089 move $a2, $v0 # pass gpr result
1090 move $a3, $v1
jeffhao12051ea2013-01-10 11:24:31 -08001091 move $a1, $t0 # pass $sp
Ian Rogers62d6c772013-02-27 08:32:07 -08001092 jal artInstrumentationMethodExitFromCode # (Thread*, SP, gpr_res, fpr_res)
jeffhao12051ea2013-01-10 11:24:31 -08001093 move $a0, rSELF # pass Thread::Current
1094 move $t0, $v0 # set aside returned link register
1095 move $ra, $v1 # set link register for deoptimization
Ian Rogers62d6c772013-02-27 08:32:07 -08001096 lw $v0, 32($sp) # restore return values
1097 lw $v1, 36($sp)
1098 l.s $f0, 40($sp)
1099 l.s $f1, 44($sp)
jeffhao12051ea2013-01-10 11:24:31 -08001100 jr $t0 # return
Ian Rogers62d6c772013-02-27 08:32:07 -08001101 addiu $sp, $sp, 112 # 48 bytes of args + 64 bytes of callee save frame
1102 .cfi_adjust_cfa_offset -112
Ian Rogers468532e2013-08-05 10:56:33 -07001103END art_quick_instrumentation_exit
buzbee5bc5a7b2012-03-07 15:52:59 -08001104
jeffhao12051ea2013-01-10 11:24:31 -08001105 /*
Ian Rogers62d6c772013-02-27 08:32:07 -08001106 * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization
1107 * will long jump to the upcall with a special exception of -1.
jeffhao12051ea2013-01-10 11:24:31 -08001108 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001109 .extern artDeoptimize
1110 .extern artEnterInterpreterFromDeoptimize
1111ENTRY art_quick_deoptimize
jeffhao12051ea2013-01-10 11:24:31 -08001112 GENERATE_GLOBAL_POINTER
Jeff Hao14dd5a82013-04-11 10:23:36 -07001113 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
Ian Rogers62d6c772013-02-27 08:32:07 -08001114 move $a0, rSELF # pass Thread::current
1115 jal artDeoptimize # artDeoptimize(Thread*, SP)
jeffhao12051ea2013-01-10 11:24:31 -08001116 # Returns caller method's frame size.
Ian Rogers62d6c772013-02-27 08:32:07 -08001117 move $a1, $sp # pass $sp
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001118END art_quick_deoptimize
jeffhao12051ea2013-01-10 11:24:31 -08001119
buzbee5bc5a7b2012-03-07 15:52:59 -08001120 /*
1121 * Long integer shift. This is different from the generic 32/64-bit
1122 * binary operations because vAA/vBB are 64-bit but vCC (the shift
1123 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
1124 * 6 bits.
1125 * On entry:
jeffhao7fbee072012-08-24 17:56:54 -07001126 * $a0: low word
1127 * $a1: high word
1128 * $a2: shift count
buzbee5bc5a7b2012-03-07 15:52:59 -08001129 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001130ENTRY art_quick_shl_long
buzbee5bc5a7b2012-03-07 15:52:59 -08001131 /* shl-long vAA, vBB, vCC */
jeffhao7fbee072012-08-24 17:56:54 -07001132 sll $v0, $a0, $a2 # rlo<- alo << (shift&31)
1133 not $v1, $a2 # rhi<- 31-shift (shift is 5b)
1134 srl $a0, 1
1135 srl $a0, $v1 # alo<- alo >> (32-(shift&31))
1136 sll $v1, $a1, $a2 # rhi<- ahi << (shift&31)
1137 or $v1, $a0 # rhi<- rhi | alo
1138 andi $a2, 0x20 # shift< shift & 0x20
1139 movn $v1, $v0, $a2 # rhi<- rlo (if shift&0x20)
1140 jr $ra
jeffhaofc6a30e2012-10-18 18:24:15 -07001141 movn $v0, $zero, $a2 # rlo<- 0 (if shift&0x20)
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001142END art_quick_shl_long
buzbee5bc5a7b2012-03-07 15:52:59 -08001143
buzbee5bc5a7b2012-03-07 15:52:59 -08001144 /*
1145 * Long integer shift. This is different from the generic 32/64-bit
1146 * binary operations because vAA/vBB are 64-bit but vCC (the shift
1147 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
1148 * 6 bits.
1149 * On entry:
jeffhao7fbee072012-08-24 17:56:54 -07001150 * $a0: low word
1151 * $a1: high word
1152 * $a2: shift count
buzbee5bc5a7b2012-03-07 15:52:59 -08001153 */
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001154 .global art_quick_shr_long
1155ENTRY art_quick_shr_long
jeffhao7fbee072012-08-24 17:56:54 -07001156 sra $v1, $a1, $a2 # rhi<- ahi >> (shift&31)
1157 srl $v0, $a0, $a2 # rlo<- alo >> (shift&31)
1158 sra $a3, $a1, 31 # $a3<- sign(ah)
1159 not $a0, $a2 # alo<- 31-shift (shift is 5b)
1160 sll $a1, 1
1161 sll $a1, $a0 # ahi<- ahi << (32-(shift&31))
1162 or $v0, $a1 # rlo<- rlo | ahi
1163 andi $a2, 0x20 # shift & 0x20
1164 movn $v0, $v1, $a2 # rlo<- rhi (if shift&0x20)
1165 jr $ra
1166 movn $v1, $a3, $a2 # rhi<- sign(ahi) (if shift&0x20)
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001167END art_quick_shr_long
buzbee5bc5a7b2012-03-07 15:52:59 -08001168
buzbee5bc5a7b2012-03-07 15:52:59 -08001169 /*
1170 * Long integer shift. This is different from the generic 32/64-bit
1171 * binary operations because vAA/vBB are 64-bit but vCC (the shift
1172 * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
1173 * 6 bits.
1174 * On entry:
1175 * r0: low word
1176 * r1: high word
1177 * r2: shift count
1178 */
1179 /* ushr-long vAA, vBB, vCC */
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001180 .global art_quick_ushr_long
1181ENTRY art_quick_ushr_long
jeffhaofc6a30e2012-10-18 18:24:15 -07001182 srl $v1, $a1, $a2 # rhi<- ahi >> (shift&31)
jeffhao7fbee072012-08-24 17:56:54 -07001183 srl $v0, $a0, $a2 # rlo<- alo >> (shift&31)
jeffhao7fbee072012-08-24 17:56:54 -07001184 not $a0, $a2 # alo<- 31-shift (shift is 5b)
1185 sll $a1, 1
1186 sll $a1, $a0 # ahi<- ahi << (32-(shift&31))
1187 or $v0, $a1 # rlo<- rlo | ahi
1188 andi $a2, 0x20 # shift & 0x20
1189 movn $v0, $v1, $a2 # rlo<- rhi (if shift&0x20)
1190 jr $ra
jeffhaofc6a30e2012-10-18 18:24:15 -07001191 movn $v1, $zero, $a2 # rhi<- 0 (if shift&0x20)
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001192END art_quick_ushr_long
jeffhao7fbee072012-08-24 17:56:54 -07001193
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001194ENTRY art_quick_indexof
jeffhao7fbee072012-08-24 17:56:54 -07001195 jr $ra
jeffhao07030602012-09-26 14:33:14 -07001196 nop
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001197END art_quick_indexof
jeffhao7fbee072012-08-24 17:56:54 -07001198
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001199ENTRY art_quick_string_compareto
jeffhao7fbee072012-08-24 17:56:54 -07001200 jr $ra
jeffhao07030602012-09-26 14:33:14 -07001201 nop
Jeff Haod4c3f7d2013-02-14 14:14:44 -08001202END art_quick_string_compareto