1 /* 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 17 #include "asm_support_mips.S" 18 19 .set noreorder 20 .balign 4 21 22 .extern artPortableProxyInvokeHandler 23 ENTRY art_portable_proxy_invoke_handler 24 GENERATE_GLOBAL_POINTER 25 # Fake callee save ref and args frame set up, note portable doesn't use callee save frames. 26 # TODO: just save the registers that are needed in artPortableProxyInvokeHandler. 27 addiu $sp, $sp, -64 28 .cfi_adjust_cfa_offset 64 29 sw $ra, 60($sp) 30 .cfi_rel_offset 31, 60 31 sw $s8, 56($sp) 32 .cfi_rel_offset 30, 56 33 sw $gp, 52($sp) 34 .cfi_rel_offset 28, 52 35 sw $s7, 48($sp) 36 .cfi_rel_offset 23, 48 37 sw $s6, 44($sp) 38 .cfi_rel_offset 22, 44 39 sw $s5, 40($sp) 40 .cfi_rel_offset 21, 40 41 sw $s4, 36($sp) 42 .cfi_rel_offset 20, 36 43 sw $s3, 32($sp) 44 .cfi_rel_offset 19, 32 45 sw $s2, 28($sp) 46 .cfi_rel_offset 18, 28 47 sw $a3, 12($sp) 48 .cfi_rel_offset 7, 12 49 sw $a2, 8($sp) 50 .cfi_rel_offset 6, 8 51 sw $a1, 4($sp) 52 .cfi_rel_offset 5, 4 53 # Begin argument set up. 54 sw $a0, 0($sp) # place proxy method at bottom of frame 55 move $a2, rSELF # pass Thread::Current 56 jal artPortableProxyInvokeHandler # (Method* proxy method, receiver, Thread*, SP) 57 move $a3, $sp # pass $sp 58 lw $ra, 60($sp) # restore $ra 59 jr $ra 60 addiu $sp, $sp, 64 # pop frame 61 .cfi_adjust_cfa_offset -64 62 END art_portable_proxy_invoke_handler 63 64 /* 65 * Invocation stub for portable code. 66 * On entry: 67 * a0 = method pointer 68 * a1 = argument array or NULL for no argument methods 69 * a2 = size of argument array in bytes 70 * a3 = (managed) thread pointer 71 * [sp + 16] = JValue* result 72 * [sp + 20] = result type char 73 */ 74 ENTRY art_portable_invoke_stub 75 GENERATE_GLOBAL_POINTER 76 sw $a0, 0($sp) # save out a0 77 addiu $sp, $sp, -16 # spill s0, s1, fp, ra 78 .cfi_adjust_cfa_offset 16 79 sw $ra, 12($sp) 80 .cfi_rel_offset 31, 12 81 sw $fp, 8($sp) 82 .cfi_rel_offset 30, 8 83 sw $s1, 4($sp) 84 .cfi_rel_offset 17, 4 85 sw $s0, 0($sp) 86 .cfi_rel_offset 16, 0 87 move $fp, $sp # save sp in fp 88 .cfi_def_cfa_register 30 89 move $s1, $a3 # move managed thread pointer into s1 90 addiu $s0, $zero, SUSPEND_CHECK_INTERVAL # reset s0 to suspend check interval 91 addiu $t0, $a2, 16 # create space for method pointer in frame 92 srl $t0, $t0, 3 # shift the frame size right 3 93 sll $t0, $t0, 3 # shift the frame size left 3 to align to 16 bytes 94 subu $sp, $sp, $t0 # reserve stack space for argument array 95 addiu $a0, $sp, 4 # pass stack pointer + method ptr as dest for memcpy 96 jal memcpy # (dest, src, bytes) 97 addiu $sp, $sp, -16 # make space for argument slots for memcpy 98 addiu $sp, $sp, 16 # restore stack after memcpy 99 lw $a0, 16($fp) # restore method* 100 lw $a1, 4($sp) # copy arg value for a1 101 lw $a2, 8($sp) # copy arg value for a2 102 lw $a3, 12($sp) # copy arg value for a3 103 lw $t9, METHOD_PORTABLE_CODE_OFFSET_32($a0) # get pointer to the code 104 jalr $t9 # call the method 105 sw $zero, 0($sp) # store NULL for method* at bottom of frame 106 move $sp, $fp # restore the stack 107 lw $s0, 0($sp) 108 .cfi_restore 16 109 lw $s1, 4($sp) 110 .cfi_restore 17 111 lw $fp, 8($sp) 112 .cfi_restore 30 113 lw $ra, 12($sp) 114 .cfi_restore 31 115 addiu $sp, $sp, 16 116 .cfi_adjust_cfa_offset -16 117 lw $t0, 16($sp) # get result pointer 118 lw $t1, 20($sp) # get result type char 119 li $t2, 68 # put char 'D' into t2 120 beq $t1, $t2, 1f # branch if result type char == 'D' 121 li $t3, 70 # put char 'F' into t3 122 beq $t1, $t3, 1f # branch if result type char == 'F' 123 sw $v0, 0($t0) # store the result 124 jr $ra 125 sw $v1, 4($t0) # store the other half of the result 126 1: 127 s.s $f0, 0($t0) # store floating point result 128 jr $ra 129 s.s $f1, 4($t0) # store other half of floating point result 130 END art_portable_invoke_stub 131 132 UNIMPLEMENTED art_portable_resolution_trampoline 133 UNIMPLEMENTED art_portable_to_interpreter_bridge 134