diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/compiler/codegen/GenCommon.cc | 2 | ||||
| -rw-r--r-- | src/compiler/codegen/mips/ArchFactory.cc | 5 | ||||
| -rw-r--r-- | src/compiler/codegen/mips/Assemble.cc | 6 | ||||
| -rw-r--r-- | src/compiler/codegen/mips/Mips32/Factory.cc | 6 | ||||
| -rw-r--r-- | src/compiler/codegen/mips/MipsLIR.h | 2 | ||||
| -rw-r--r-- | src/oat/runtime/mips/runtime_support_mips.S | 201 | ||||
| -rw-r--r-- | src/oat/runtime/mips/stub_mips.cc | 69 | ||||
| -rw-r--r-- | src/oat/runtime/support_invoke.cc | 18 | ||||
| -rw-r--r-- | src/oat/runtime/support_stubs.cc | 25 | ||||
| -rw-r--r-- | src/runtime.cc | 8 |
10 files changed, 226 insertions, 116 deletions
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc index d948d2d8f2..c1d46611a5 100644 --- a/src/compiler/codegen/GenCommon.cc +++ b/src/compiler/codegen/GenCommon.cc @@ -1202,7 +1202,7 @@ void genConstString(CompilationUnit* cUnit, uint32_t string_idx, #if !defined(TARGET_X86) int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pResolveStringFromCode)); #endif - loadWordDisp(cUnit, rRET0, offset_of_string, rARG0); + loadWordDisp(cUnit, rARG0, offset_of_string, rRET0); loadConstant(cUnit, rARG1, string_idx); #if defined(TARGET_ARM) opRegImm(cUnit, kOpCmp, rRET0, 0); // Is resolved? diff --git a/src/compiler/codegen/mips/ArchFactory.cc b/src/compiler/codegen/mips/ArchFactory.cc index 4a61efb4a0..f51e722d1f 100644 --- a/src/compiler/codegen/mips/ArchFactory.cc +++ b/src/compiler/codegen/mips/ArchFactory.cc @@ -107,9 +107,8 @@ void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset); */ int loadHelper(CompilationUnit* cUnit, int offset) { - int tReg = oatAllocTemp(cUnit); - loadWordDisp(cUnit, rSELF, offset, tReg); - return tReg; + loadWordDisp(cUnit, rSELF, offset, r_T9); + return r_T9; } void spillCoreRegs(CompilationUnit* cUnit) diff --git a/src/compiler/codegen/mips/Assemble.cc b/src/compiler/codegen/mips/Assemble.cc index 8c906ccdb3..f19c1f1e29 100644 --- a/src/compiler/codegen/mips/Assemble.cc +++ b/src/compiler/codegen/mips/Assemble.cc @@ -400,7 +400,7 @@ MipsEncodingMap EncodingMap[kMipsLast] = { ENCODING_MAP(kMipsDelta, 0x27e00000, kFmtBitBlt, 20, 16, kFmtBitBlt, 15, 0, kFmtUnused, 15, 0, kFmtUnused, -1, -1, IS_QUAD_OP | REG_DEF0 | REG_USE_LR | - NEEDS_FIXUP, "addiu", "!0r,r_ra,0x!1h(!1d)", 4), + NEEDS_FIXUP, "addiu", "!0r,ra,0x!1h(!1d)", 4), ENCODING_MAP(kMipsDeltaHi, 0x3C000000, kFmtBitBlt, 20, 16, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, IS_QUAD_OP | REG_DEF0 | NEEDS_FIXUP, @@ -409,10 +409,10 @@ MipsEncodingMap EncodingMap[kMipsLast] = { kFmtBlt5_2, 16, 21, kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, IS_QUAD_OP | REG_DEF0_USE0 | NEEDS_FIXUP, "ori", "!0r,!0r,0x!1h(!1d)", 4), - ENCODING_MAP(kMipsCurrPC, 0x04110020, + ENCODING_MAP(kMipsCurrPC, 0x04110001, kFmtUnused, -1, -1, kFmtUnused, -1, -1, kFmtUnused, -1, -1, kFmtUnused, -1, -1, NO_OPERAND | IS_BRANCH | REG_DEF_LR, - "pc2ra", "; r_ra <- .+8", 4), + "addiu", "ra,pc,8", 4), ENCODING_MAP(kMipsSync, 0x0000000f, kFmtBitBlt, 10, 6, kFmtUnused, -1, -1, kFmtUnused, -1, -1, kFmtUnused, -1, -1, IS_UNARY_OP, diff --git a/src/compiler/codegen/mips/Mips32/Factory.cc b/src/compiler/codegen/mips/Mips32/Factory.cc index ad220f8aba..63c92ebcec 100644 --- a/src/compiler/codegen/mips/Mips32/Factory.cc +++ b/src/compiler/codegen/mips/Mips32/Factory.cc @@ -31,7 +31,7 @@ static int coreRegs[] = {r_ZERO, r_AT, r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, static int reservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP, r_RA}; static int coreTemps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2, - r_T3, r_T4, r_T5, r_T6, r_T7, r_T8, r_T9}; + r_T3, r_T4, r_T5, r_T6, r_T7, r_T8}; #ifdef __mips_hard_float static int fpRegs[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7, r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15}; @@ -607,8 +607,8 @@ LIR *loadBaseDispBody(CompilationUnit *cUnit, int rBase, oatFreeTemp(cUnit, rTmp); } else { int rTmp = (rBase == rDest) ? oatAllocFreeTemp(cUnit) : rDest; - res = loadConstant(cUnit, rTmp, displacement); - load = newLIR3(cUnit, opcode, rDest, rBase, rTmp); + res = opRegRegImm(cUnit, kOpAdd, rTmp, rBase, displacement); + load = newLIR3(cUnit, opcode, rDest, 0, rTmp); if (rTmp != rDest) oatFreeTemp(cUnit, rTmp); } diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h index ab4f844dba..5e5147a96b 100644 --- a/src/compiler/codegen/mips/MipsLIR.h +++ b/src/compiler/codegen/mips/MipsLIR.h @@ -301,7 +301,7 @@ enum NativeRegisterPool { #define rARG3 r_ARG3 #define rRET0 r_RESULT0 #define rRET1 r_RESULT1 -#define rINVOKE_TGT r_V0 +#define rINVOKE_TGT r_T9 /* Shift encodings */ enum MipsShiftEncodings { diff --git a/src/oat/runtime/mips/runtime_support_mips.S b/src/oat/runtime/mips/runtime_support_mips.S index 2f7d120aae..cbf895a641 100644 --- a/src/oat/runtime/mips/runtime_support_mips.S +++ b/src/oat/runtime/mips/runtime_support_mips.S @@ -32,19 +32,21 @@ /* * Macro that sets up the callee save frame to conform with * Runtime::CreateCalleeSaveMethod(kSaveAll) - * callee-save: $s2-$s8 + $ra, 8 total + 2 words + * callee-save: $s0-$s8 + $ra, 10 total + 4 words */ .macro SETUP_SAVE_ALL_CALLEE_SAVE_FRAME - addiu $sp, $sp, -48 - sw $ra, 44($sp) - sw $s8, 40($sp) - sw $s7, 36($sp) - sw $s6, 32($sp) - sw $s5, 28($sp) - sw $s4, 24($sp) - sw $s3, 20($sp) - sw $s2, 16($sp) - # 4 open words, bottom will hold Method* + addiu $sp, $sp, -64 + sw $ra, 60($sp) + sw $s8, 56($sp) + sw $s7, 52($sp) + sw $s6, 48($sp) + sw $s5, 44($sp) + sw $s4, 40($sp) + sw $s3, 36($sp) + sw $s2, 32($sp) + sw $s1, 28($sp) + sw $s0, 24($sp) + # 2 words for alignment, 4 open words for args $a0-$a3, bottom will hold Method* .endm /* @@ -63,7 +65,7 @@ sw $s4, 24($sp) sw $s3, 20($sp) sw $s2, 16($sp) - # 4 open words, bottom will hold Method* + # 4 open words for args $a0-$a3, bottom will hold Method* .endm .macro RESTORE_REF_ONLY_CALLEE_SAVE_FRAME @@ -80,7 +82,7 @@ /* * Macro that sets up the callee save frame to conform with * Runtime::CreateCalleeSaveMethod(kRefsAndArgs). Restoration assumes non-moving GC. - * $a1-$a3, $s2-$s8, $ra, 11 total + 1 + * $a1-$a3, $s2-$s8, $ra, 11 total + Method* */ .macro SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME addiu $sp, $sp, -48 @@ -95,7 +97,7 @@ sw $a3, 12($sp) sw $a2, 8($sp) sw $a1, 4($sp) - # 1 open word, bottom will hold Method* + # bottom will hold Method* .endm .macro RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME @@ -155,6 +157,7 @@ */ ALIGN_FUNCTION_ENTRY art_update_debugger: + .cpload $25 move $a3, $a0 # stash away $a0 so that it's saved as if it were an argument SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME move $a0, $a2 # arg0 is dex PC @@ -247,6 +250,7 @@ art_do_long_jump: */ ALIGN_FUNCTION_ENTRY art_deliver_exception_from_code: + .cpload $25 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME move $a1, rSELF # pass Thread::Current jal artDeliverExceptionFromCode # artDeliverExceptionFromCode(Throwable*, Thread*, $sp) @@ -259,6 +263,7 @@ art_deliver_exception_from_code: */ ALIGN_FUNCTION_ENTRY art_throw_null_pointer_exception_from_code: + .cpload $25 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME move $a0, rSELF # pass Thread::Current jal artThrowNullPointerExceptionFromCode # artThrowNullPointerExceptionFromCode(Thread*, $sp) @@ -271,6 +276,7 @@ art_throw_null_pointer_exception_from_code: */ ALIGN_FUNCTION_ENTRY art_throw_div_zero_from_code: + .cpload $25 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME move $a0, rSELF # pass Thread::Current jal artThrowDivZeroFromCode # artThrowDivZeroFromCode(Thread*, $sp) @@ -283,6 +289,7 @@ art_throw_div_zero_from_code: */ ALIGN_FUNCTION_ENTRY art_throw_array_bounds_from_code: + .cpload $25 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME move $a2, rSELF # pass Thread::Current jal artThrowArrayBoundsFromCode # artThrowArrayBoundsFromCode(index, limit, Thread*, $sp) @@ -295,6 +302,7 @@ art_throw_array_bounds_from_code: */ ALIGN_FUNCTION_ENTRY art_throw_stack_overflow_from_code: + .cpload $25 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME move $a1, rSELF # pass Thread::Current jal artThrowStackOverflowFromCode # artThrowStackOverflowFromCode(method, Thread*, $sp) @@ -307,6 +315,7 @@ art_throw_stack_overflow_from_code: */ ALIGN_FUNCTION_ENTRY art_throw_no_such_method_from_code: + .cpload $25 SETUP_SAVE_ALL_CALLEE_SAVE_FRAME move $a1, rSELF # pass Thread::Current jal artThrowNoSuchMethodFromCode # artThrowNoSuchMethodFromCode(method_idx, Thread*, $sp) @@ -322,7 +331,7 @@ art_throw_no_such_method_from_code: * The helper will attempt to locate the target and return a 64-bit result in $v0/$v1 consisting * of the target Method* in $v0 and method->code_ in $v1. * - * If unsuccessful, the helper will return NULL/NULL. There will bea pending exception in the + * If unsuccessful, the helper will return NULL/NULL. There will be a pending exception in the * thread and we branch to another stub to deliver it. * * On success this wrapper will restore arguments and *jump* to the target, leaving the lr @@ -332,16 +341,21 @@ art_throw_no_such_method_from_code: .global \c_name .extern \cxx_name \c_name: + .cpload $25 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME # save callee saves in case allocation triggers GC lw $a2, 48($sp) # pass caller Method* + move $t0, $sp # save $sp + addiu $sp, $sp, -16 # make space for extra args move $a3, rSELF # pass Thread::Current - sw $sp, 0($sp) # pass $sp jal \cxx_name # (method_idx, this, caller, Thread*, $sp) - move $t0, $v1 # save $v0->code_ + sw $t0, 16($sp) # pass $sp + addiu $sp, $sp, 16 # release out args + move $a0, $v0 # save target Method* + move $t0, $v1 # save $v0->code_ RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME - bnez $v0, 1f + beqz $v0, 1f nop - jr $t0 + jr $t0 nop 1: DELIVER_PENDING_EXCEPTION @@ -362,22 +376,23 @@ INVOKE_TRAMPOLINE art_invoke_virtual_trampoline_with_access_check, artInvokeVirt */ ALIGN_FUNCTION_ENTRY art_work_around_app_jni_bugs: + .cpload $25 # save registers that may contain arguments and LR that will be crushed by a call addiu $sp, $sp, -32 - sw $a0, 28($sp) - sw $a1, 24($sp) + sw $ra, 28($sp) + sw $a3, 24($sp) sw $a2, 20($sp) - sw $a3, 16($sp) - sw $ra, 12($sp) + sw $a1, 16($sp) + sw $a0, 12($sp) move $a0, rSELF # pass Thread::Current jal artWorkAroundAppJniBugs # (Thread*, $sp) move $a1, $sp # pass $sp move $t0, $v0 # save target address - lw $a0, 28($sp) - lw $a1, 24($sp) + lw $a0, 12($sp) + lw $a1, 16($sp) lw $a2, 20($sp) - lw $a3, 16($sp) - lw $ra, 12($sp) + lw $a3, 24($sp) + lw $ra, 28($sp) jr $t0 # tail call into JNI routine addiu $sp, $sp, 32 @@ -389,6 +404,7 @@ art_work_around_app_jni_bugs: */ ALIGN_FUNCTION_ENTRY art_handle_fill_data_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case exception allocation triggers GC move $a2, rSELF # pass Thread::Current jal artHandleFillArrayDataFromCode # (Array*, const DexFile::Payload*, Thread*, $sp) @@ -408,6 +424,7 @@ art_handle_fill_data_from_code: */ ALIGN_FUNCTION_ENTRY art_lock_object_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case we block move $a1, rSELF # pass Thread::Current jal artLockObjectFromCode # (Object* obj, Thread*, $sp) @@ -421,6 +438,7 @@ art_lock_object_from_code: */ ALIGN_FUNCTION_ENTRY art_unlock_object_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case exception allocation triggers GC move $a1, rSELF # pass Thread::Current jal artUnlockObjectFromCode # (Object* obj, Thread*, $sp) @@ -434,6 +452,7 @@ art_unlock_object_from_code: */ ALIGN_FUNCTION_ENTRY art_check_cast_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case exception allocation triggers GC move $a2, rSELF # pass Thread::Current jal artCheckCastFromCode # (Class* a, Class* b, Thread*, $sp) @@ -448,6 +467,7 @@ art_check_cast_from_code: */ ALIGN_FUNCTION_ENTRY art_can_put_array_element_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case exception allocation triggers GC move $a2, rSELF # pass Thread::Current jal artCanPutArrayElementFromCode # (Object* element, Class* array_class, Thread*, $sp) @@ -463,6 +483,7 @@ art_can_put_array_element_from_code: */ ALIGN_FUNCTION_ENTRY art_initialize_static_storage_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC move $a2, rSELF # pass Thread::Current # artInitializeStaticStorageFromCode(uint32_t type_idx, Method* referrer, Thread*, $sp) @@ -477,6 +498,7 @@ art_initialize_static_storage_from_code: */ ALIGN_FUNCTION_ENTRY art_initialize_type_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC move $a2, rSELF # pass Thread::Current # artInitializeTypeFromCode(uint32_t type_idx, Method* referrer, Thread*, $sp) @@ -492,6 +514,7 @@ art_initialize_type_from_code: */ ALIGN_FUNCTION_ENTRY art_initialize_type_and_verify_access_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC move $a2, rSELF # pass Thread::Current # artInitializeTypeFromCode(uint32_t type_idx, Method* referrer, Thread*, $sp) @@ -506,10 +529,11 @@ art_initialize_type_and_verify_access_from_code: */ ALIGN_FUNCTION_ENTRY art_get32_static_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC lw $a1, 48($sp) # pass referrer's Method* move $a2, rSELF # pass Thread::Current - jal artGet32StaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp) + jal artGet32StaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp) move $a3, $sp # pass $sp RETURN_IF_NO_EXCEPTION @@ -520,10 +544,11 @@ art_get32_static_from_code: */ ALIGN_FUNCTION_ENTRY art_get64_static_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC lw $a1, 48($sp) # pass referrer's Method* move $a2, rSELF # pass Thread::Current - jal artGet64StaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp) + jal artGet64StaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp) move $a3, $sp # pass $sp RETURN_IF_NO_EXCEPTION @@ -534,10 +559,11 @@ art_get64_static_from_code: */ ALIGN_FUNCTION_ENTRY art_get_obj_static_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC lw $a1, 48($sp) # pass referrer's Method* move $a2, rSELF # pass Thread::Current - jal artGetObjStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp) + jal artGetObjStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp) move $a3, $sp # pass $sp RETURN_IF_NO_EXCEPTION @@ -548,11 +574,15 @@ art_get_obj_static_from_code: */ ALIGN_FUNCTION_ENTRY art_get32_instance_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC lw $a2, 48($sp) # pass referrer's Method* + move $t0, $sp # save $sp + addiu $sp, $sp, -16 # make space for extra args move $a3, rSELF # pass Thread::Current - jal artGet32InstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp) - sw $sp, 0($sp) # pass $sp + jal artGet32InstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp) + sw $t0, 16($sp) # pass $sp + addiu $sp, $sp, 16 # release out args RETURN_IF_NO_EXCEPTION .global art_get64_instance_from_code @@ -562,11 +592,15 @@ art_get32_instance_from_code: */ ALIGN_FUNCTION_ENTRY art_get64_instance_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC lw $a2, 48($sp) # pass referrer's Method* + move $t0, $sp # save $sp + addiu $sp, $sp, -16 # make space for extra args move $a3, rSELF # pass Thread::Current - jal artGet64InstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp) - sw $sp, 0($sp) # pass $sp + jal artGet64InstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp) + sw $t0, 16($sp) # pass $sp + addiu $sp, $sp, 16 # release out args RETURN_IF_NO_EXCEPTION .global art_get_obj_instance_from_code @@ -576,11 +610,15 @@ art_get64_instance_from_code: */ ALIGN_FUNCTION_ENTRY art_get_obj_instance_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC lw $a2, 48($sp) # pass referrer's Method* + move $t0, $sp # save $sp + addiu $sp, $sp, -16 # make space for extra args move $a3, rSELF # pass Thread::Current - jal artGetObjInstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp) - sw $sp, 0($sp) # pass $sp + jal artGetObjInstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp) + sw $t0, 16($sp) # pass $sp + addiu $sp, $sp, 16 # release out args RETURN_IF_NO_EXCEPTION .global art_set32_static_from_code @@ -590,11 +628,15 @@ art_get_obj_instance_from_code: */ ALIGN_FUNCTION_ENTRY art_set32_static_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC lw $a2, 48($sp) # pass referrer's Method* + move $t0, $sp # save $sp + addiu $sp, $sp, -16 # make space for extra args move $a3, rSELF # pass Thread::Current - jal artSet32StaticFromCode # (field_idx, new_val, referrer, Thread*, $sp) - sw $sp, 0($sp) # pass $sp + jal artSet32StaticFromCode # (field_idx, new_val, referrer, Thread*, $sp) + sw $t0, 16($sp) # pass $sp + addiu $sp, $sp, 16 # release out args RETURN_IF_ZERO .global art_set64_static_from_code @@ -604,14 +646,15 @@ art_set32_static_from_code: */ ALIGN_FUNCTION_ENTRY art_set64_static_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC lw $a1, 48($sp) # pass referrer's Method* move $t0, $sp # save $sp - addiu $sp, $sp, -16 - sw rSELF, 0($sp) # pass Thread::Current and $sp + addiu $sp, $sp, -16 # make space for extra args + sw rSELF, 16($sp) # pass Thread::Current jal artSet64StaticFromCode # (field_idx, referrer, new_val, Thread*, $sp) - sw $t0, 4($sp) - addiu $sp, #16 # release out args + sw $t0, 20($sp) # pass $sp + addiu $sp, $sp, 16 # release out args RETURN_IF_ZERO .global art_set_obj_static_from_code @@ -621,11 +664,15 @@ art_set64_static_from_code: */ ALIGN_FUNCTION_ENTRY art_set_obj_static_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC lw $a2, 48($sp) # pass referrer's Method* + move $t0, $sp # save $sp + addiu $sp, $sp, -16 # make space for extra args move $a3, rSELF # pass Thread::Current - jal artSetObjStaticFromCode # (field_idx, new_val, referrer, Thread*, $sp) - sw $sp, 0($sp) # pass $sp + jal artSetObjStaticFromCode # (field_idx, new_val, referrer, Thread*, $sp) + sw $t0, 16($sp) # pass $sp + addiu $sp, $sp, 16 # release out args RETURN_IF_ZERO .global art_set32_instance_from_code @@ -635,13 +682,14 @@ art_set_obj_static_from_code: */ ALIGN_FUNCTION_ENTRY art_set32_instance_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC lw $a3, 48($sp) # pass referrer's Method* move $t0, $sp # save $sp - addiu $sp, $sp, -16 - sw rSELF, 0($sp) # pass Thread::Current and $sp + addiu $sp, $sp, -16 # make space for extra args + sw rSELF, 16($sp) # pass Thread::Current jal artSet32InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*, $sp) - sw $t0, 4($sp) + sw $t0, 20($sp) # pass $sp addiu $sp, $sp, 16 # release out args RETURN_IF_ZERO @@ -652,12 +700,13 @@ art_set32_instance_from_code: */ ALIGN_FUNCTION_ENTRY art_set64_instance_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC move $t0, $sp # save $sp - addiu $sp, $sp, -16 - sw rSELF, 0($sp) # pass Thread::Current and $sp - jal artSet64InstanceFromCode # (field_idx, Object*, new_val, Thread*, $sp) - sw $t0, 4($sp) + addiu $sp, $sp, -16 # make space for extra args + sw rSELF, 16($sp) # pass Thread::Current + jal artSet64InstanceFromCode # (field_idx, Object*, new_val, Thread*, $sp) + sw $t0, 20($sp) # pass $sp addiu $sp, $sp, 16 # release out args RETURN_IF_ZERO @@ -668,13 +717,14 @@ art_set64_instance_from_code: */ ALIGN_FUNCTION_ENTRY art_set_obj_instance_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC lw $a3, 48($sp) # pass referrer's Method* move $t0, $sp # save $sp - addiu $sp, $sp, -16 - sw rSELF, 0($sp) # pass Thread::Current and $sp - jal artSetObjInstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*, $sp) - sw $t0, 4($sp) + addiu $sp, $sp, -16 # make space for extra args + sw rSELF, 16($sp) # pass Thread::Current + jal artSetObjInstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*, $sp) + sw $t0, 20($sp) # pass $sp addiu $sp, $sp, 16 # release out args RETURN_IF_ZERO @@ -688,12 +738,13 @@ art_set_obj_instance_from_code: */ ALIGN_FUNCTION_ENTRY art_resolve_string_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC move $a2, rSELF # pass Thread::Current # artResolveStringFromCode(Method* referrer, uint32_t string_idx, Thread*, $sp) jal artResolveStringFromCode move $a3, $sp # pass $sp - RETURN_IF_ZERO + RETURN_IF_NONZERO .global art_alloc_object_from_code .extern artAllocObjectFromCode @@ -702,6 +753,7 @@ art_resolve_string_from_code: */ ALIGN_FUNCTION_ENTRY art_alloc_object_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC move $a2, rSELF # pass Thread::Current jal artAllocObjectFromCode # (uint32_t type_idx, Method* method, Thread*, $sp) @@ -716,6 +768,7 @@ art_alloc_object_from_code: */ ALIGN_FUNCTION_ENTRY art_alloc_object_from_code_with_access_check: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC move $a2, rSELF # pass Thread::Current jal artAllocObjectFromCodeWithAccessCheck # (uint32_t type_idx, Method* method, Thread*, $sp) @@ -729,11 +782,15 @@ art_alloc_object_from_code_with_access_check: */ ALIGN_FUNCTION_ENTRY art_alloc_array_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC move $a3, rSELF # pass Thread::Current + move $t0, $sp # save $sp + addiu $sp, $sp, -16 # make space for extra args # artAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t component_count, Thread*, $sp) jal artAllocArrayFromCode - sw $sp, 0($sp) # pass $sp + sw $t0, 16($sp) # pass $sp + addiu $sp, $sp, 16 # release out args RETURN_IF_NONZERO .global art_alloc_array_from_code_with_access_check @@ -744,11 +801,15 @@ art_alloc_array_from_code: */ ALIGN_FUNCTION_ENTRY art_alloc_array_from_code_with_access_check: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC move $a3, rSELF # pass Thread::Current + move $t0, $sp # save $sp + addiu $sp, $sp, -16 # make space for extra args # artAllocArrayFromCodeWithAccessCheck(type_idx, method, component_count, Thread*, $sp) jal artAllocArrayFromCodeWithAccessCheck - sw $sp, 0($sp) # pass $sp + sw $t0, 16($sp) # pass $sp + addiu $sp, $sp, 16 # release out args RETURN_IF_NONZERO .global art_check_and_alloc_array_from_code @@ -758,11 +819,15 @@ art_alloc_array_from_code_with_access_check: */ ALIGN_FUNCTION_ENTRY art_check_and_alloc_array_from_code: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC move $a3, rSELF # pass Thread::Current + move $t0, $sp # save $sp + addiu $sp, $sp, -16 # make space for extra args # artCheckAndAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t count, Thread* , $sp) jal artCheckAndAllocArrayFromCode - sw $sp, 0($sp) # pass $sp + sw $t0, 16($sp) # pass $sp + addiu $sp, $sp, 16 # release out args RETURN_IF_NONZERO .global art_check_and_alloc_array_from_code_with_access_check @@ -772,11 +837,15 @@ art_check_and_alloc_array_from_code: */ ALIGN_FUNCTION_ENTRY art_check_and_alloc_array_from_code_with_access_check: + .cpload $25 SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC - move $a3, rSELF # pass Thread::Current + move $a3, rSELF # pass Thread::Current + move $t0, $sp # save $sp + addiu $sp, $sp, -16 # make space for extra args # artCheckAndAllocArrayFromCodeWithAccessCheck(type_idx, method, count, Thread* , $sp) jal artCheckAndAllocArrayFromCodeWithAccessCheck - sw $sp, 0($sp) # pass $sp + sw $t0, 16($sp) # pass $sp + addiu $sp, $sp, 16 # release out args RETURN_IF_NONZERO .global art_test_suspend @@ -806,16 +875,16 @@ art_test_suspend: */ ALIGN_FUNCTION_ENTRY art_proxy_invoke_handler: + .cpload $25 SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME sw $a0, 0($sp) # place proxy method at bottom of frame move $a2, rSELF # pass Thread::Current jal artProxyInvokeHandler # (Method* proxy method, receiver, Thread*, args...) - addiu $a3, $sp, 12 # pointer to r2/r3/LR/caller's Method**/out-args as second arg + addiu $a3, $sp, 8 # pointer to a2/a3/ra/caller's Method**/out-args as second arg lw $t0, THREAD_EXCEPTION_OFFSET(rSELF) # load Thread::Current()->exception_ -#FIXME - offsets here are probably wrong lw $ra, 44($sp) # restore $ra - lw $v0, 12($sp) - lw $v1, 14($sp) + lw $v0, 8($sp) + lw $v1, 12($sp) bnez $t0, 1f addiu $sp, $sp, 48 # pop frame jr $ra @@ -830,6 +899,7 @@ art_proxy_invoke_handler: */ ALIGN_FUNCTION_ENTRY art_trace_entry_from_code: + .cpload $25 addiu $sp, $sp, -16 sw $a0, 0($sp) sw $a1, 4($sp) @@ -854,6 +924,7 @@ art_trace_entry_from_code: */ ALIGN_FUNCTION_ENTRY art_trace_exit_from_code: + .cpload $25 addiu $sp, $sp, -16 sw $v0, 0($sp) jal artTraceMethodExitFromCode # () diff --git a/src/oat/runtime/mips/stub_mips.cc b/src/oat/runtime/mips/stub_mips.cc index 9691308092..9fd65c89a4 100644 --- a/src/oat/runtime/mips/stub_mips.cc +++ b/src/oat/runtime/mips/stub_mips.cc @@ -30,28 +30,27 @@ namespace mips { ByteArray* MipsCreateResolutionTrampoline(Runtime::TrampolineType type) { UniquePtr<MipsAssembler> assembler(static_cast<MipsAssembler*>(Assembler::Create(kMips))); #if !defined(ART_USE_LLVM_COMPILER) - // | Out args | - // | Method* | <- SP on entry - // | RA | return address into caller - // | ... | callee saves - // | A3 | possible argument - // | A2 | possible argument - // | A1 | possible argument - // | A0 | junk on call to UnresolvedDirectMethodTrampolineFromCode, holds result Method* - // | Method* | Callee save Method* set up by UnresolvedDirectMethodTrampolineFromCode + // | Out args | + // | Method* | <- SP on entry + // | RA | return address into caller + // | ... | callee saves + // | A3 | possible argument + // | A2 | possible argument + // | A1 | possible argument + // | A0/Method* | Callee save Method* set up by UnresolvedDirectMethodTrampolineFromCode // Save callee saves and ready frame for exception delivery - __ AddConstant(SP, SP, -64); - __ StoreToOffset(kStoreWord, RA, SP, 60); - __ StoreToOffset(kStoreWord, FP, SP, 56); - __ StoreToOffset(kStoreWord, S7, SP, 52); - __ StoreToOffset(kStoreWord, S6, SP, 48); - __ StoreToOffset(kStoreWord, S5, SP, 44); - __ StoreToOffset(kStoreWord, S4, SP, 40); - __ StoreToOffset(kStoreWord, S3, SP, 36); - __ StoreToOffset(kStoreWord, S2, SP, 32); - __ StoreToOffset(kStoreWord, A3, SP, 28); - __ StoreToOffset(kStoreWord, A2, SP, 24); - __ StoreToOffset(kStoreWord, A1, SP, 20); + __ AddConstant(SP, SP, -48); + __ StoreToOffset(kStoreWord, RA, SP, 44); + __ StoreToOffset(kStoreWord, FP, SP, 40); + __ StoreToOffset(kStoreWord, S7, SP, 36); + __ StoreToOffset(kStoreWord, S6, SP, 32); + __ StoreToOffset(kStoreWord, S5, SP, 28); + __ StoreToOffset(kStoreWord, S4, SP, 24); + __ StoreToOffset(kStoreWord, S3, SP, 20); + __ StoreToOffset(kStoreWord, S2, SP, 16); + __ StoreToOffset(kStoreWord, A3, SP, 12); + __ StoreToOffset(kStoreWord, A2, SP, 8); + __ StoreToOffset(kStoreWord, A1, SP, 4); __ LoadFromOffset(kLoadWord, T9, S1, ENTRYPOINT_OFFSET(pUnresolvedDirectMethodTrampolineFromCode)); @@ -61,20 +60,20 @@ ByteArray* MipsCreateResolutionTrampoline(Runtime::TrampolineType type) { __ Jalr(T9); // Call to unresolved direct method trampoline (method_idx, sp, Thread*, is_static) // Restore registers which may have been modified by GC - __ LoadFromOffset(kLoadWord, A1, SP, 20); - __ LoadFromOffset(kLoadWord, A2, SP, 24); - __ LoadFromOffset(kLoadWord, A3, SP, 28); - __ LoadFromOffset(kLoadWord, S2, SP, 32); - __ LoadFromOffset(kLoadWord, S3, SP, 36); - __ LoadFromOffset(kLoadWord, S4, SP, 40); - __ LoadFromOffset(kLoadWord, S5, SP, 44); - __ LoadFromOffset(kLoadWord, S6, SP, 48); - __ LoadFromOffset(kLoadWord, S7, SP, 52); - __ LoadFromOffset(kLoadWord, FP, SP, 56); - __ LoadFromOffset(kLoadWord, RA, SP, 60); - __ AddConstant(SP, SP, 64); - - __ Move(A0, V0); // Put returned Method* into A0 + __ LoadFromOffset(kLoadWord, A0, SP, 0); + __ LoadFromOffset(kLoadWord, A1, SP, 4); + __ LoadFromOffset(kLoadWord, A2, SP, 8); + __ LoadFromOffset(kLoadWord, A3, SP, 12); + __ LoadFromOffset(kLoadWord, S2, SP, 16); + __ LoadFromOffset(kLoadWord, S3, SP, 20); + __ LoadFromOffset(kLoadWord, S4, SP, 24); + __ LoadFromOffset(kLoadWord, S5, SP, 28); + __ LoadFromOffset(kLoadWord, S6, SP, 32); + __ LoadFromOffset(kLoadWord, S7, SP, 36); + __ LoadFromOffset(kLoadWord, FP, SP, 40); + __ LoadFromOffset(kLoadWord, RA, SP, 44); + __ AddConstant(SP, SP, 48); + __ Jr(V0); // Leaf call to method's code __ Break(); diff --git a/src/oat/runtime/support_invoke.cc b/src/oat/runtime/support_invoke.cc index e66749d4a3..4f16afee4e 100644 --- a/src/oat/runtime/support_invoke.cc +++ b/src/oat/runtime/support_invoke.cc @@ -74,6 +74,24 @@ extern "C" uint64_t artInvokeInterfaceTrampoline(AbstractMethod* interface_metho DCHECK_EQ(32U, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes()); uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp)); uintptr_t caller_pc = regs[7]; +#elif defined(__mips__) + // On entry the stack pointed by sp is: + // | argN | | + // | ... | | + // | arg4 | | + // | arg3 spill | | Caller's frame + // | arg2 spill | | + // | arg1 spill | | + // | Method* | --- + // | RA | + // | ... | callee saves + // | A3 | arg3 + // | A2 | arg2 + // | A1 | arg1 + // | A0/Method* | <- sp + DCHECK_EQ(48U, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes()); + uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp)); + uintptr_t caller_pc = regs[11]; #else UNIMPLEMENTED(FATAL); uintptr_t caller_pc = 0; diff --git a/src/oat/runtime/support_stubs.cc b/src/oat/runtime/support_stubs.cc index fa8356e27a..9e33c43026 100644 --- a/src/oat/runtime/support_stubs.cc +++ b/src/oat/runtime/support_stubs.cc @@ -54,7 +54,8 @@ const void* UnresolvedDirectMethodTrampolineFromCode(AbstractMethod* called, Abs DCHECK_EQ(48U, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes()); AbstractMethod** caller_sp = reinterpret_cast<AbstractMethod**>(reinterpret_cast<byte*>(sp) + 48); uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp) + kPointerSize); - uintptr_t caller_pc = regs[10]; + uint32_t pc_offset = 10; + uintptr_t caller_pc = regs[pc_offset]; #elif defined(__i386__) // On entry the stack pointed by sp is: // | argN | | @@ -74,6 +75,26 @@ const void* UnresolvedDirectMethodTrampolineFromCode(AbstractMethod* called, Abs AbstractMethod** caller_sp = reinterpret_cast<AbstractMethod**>(reinterpret_cast<byte*>(sp) + 32); uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp)); uintptr_t caller_pc = regs[7]; +#elif defined(__mips__) + // On entry the stack pointed by sp is: + // | argN | | + // | ... | | + // | arg4 | | + // | arg3 spill | | Caller's frame + // | arg2 spill | | + // | arg1 spill | | + // | Method* | --- + // | RA | + // | ... | callee saves + // | A3 | arg3 + // | A2 | arg2 + // | A1 | arg1 + // | A0/Method* | <- sp + DCHECK_EQ(48U, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes()); + AbstractMethod** caller_sp = reinterpret_cast<AbstractMethod**>(reinterpret_cast<byte*>(sp) + 48); + uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp)); + uint32_t pc_offset = 11; + uintptr_t caller_pc = regs[pc_offset]; #else UNIMPLEMENTED(FATAL); AbstractMethod** caller_sp = NULL; @@ -173,7 +194,7 @@ const void* UnresolvedDirectMethodTrampolineFromCode(AbstractMethod* called, Abs cur_arg = cur_arg + (c == 'J' || c == 'D' ? 2 : 1); } // Place into local references incoming arguments from the caller's stack arguments - cur_arg += 11; // skip LR, Method* and spills for R1 to R3 and callee saves + cur_arg += pc_offset + 1; // skip LR/RA, Method* and spills for R1-R3/A1-A3 and callee saves while (shorty_index < shorty_len) { char c = shorty[shorty_index]; shorty_index++; diff --git a/src/runtime.cc b/src/runtime.cc index 62447dfb1c..e3384df1a7 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -1014,8 +1014,8 @@ AbstractMethod* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_set, (1 << art::arm::R8) | (1 << art::arm::R10) | (1 << art::arm::R11); uint32_t arg_spills = (1 << art::arm::R1) | (1 << art::arm::R2) | (1 << art::arm::R3); uint32_t all_spills = (1 << art::arm::R4) | (1 << art::arm::R9); - uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills :0) | - (type == kSaveAll ? all_spills :0) | (1 << art::arm::LR); + uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills : 0) | + (type == kSaveAll ? all_spills : 0) | (1 << art::arm::LR); uint32_t fp_all_spills = (1 << art::arm::S0) | (1 << art::arm::S1) | (1 << art::arm::S2) | (1 << art::arm::S3) | (1 << art::arm::S4) | (1 << art::arm::S5) | (1 << art::arm::S6) | (1 << art::arm::S7) | (1 << art::arm::S8) | @@ -1039,9 +1039,11 @@ AbstractMethod* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_set, (1 << art::mips::S5) | (1 << art::mips::S6) | (1 << art::mips::S7) | (1 << art::mips::FP); uint32_t arg_spills = (1 << art::mips::A1) | (1 << art::mips::A2) | (1 << art::mips::A3); + uint32_t all_spills = (1 << art::mips::S0) | (1 << art::mips::S1); uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills : 0) | - (1 << art::mips::RA); + (type == kSaveAll ? all_spills : 0) | (1 << art::mips::RA); size_t frame_size = RoundUp((__builtin_popcount(core_spills) /* gprs */ + + (type == kRefsAndArgs ? 0 : 3) /* always reserve arg space */ + 1 /* Method* */) * kPointerSize, kStackAlignment); method->SetFrameSizeInBytes(frame_size); method->SetCoreSpillMask(core_spills); |