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