100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze/* 200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * We've detected a condition that will result in an exception, but the exception 300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * has not yet been thrown. Just bail out to the reference interpreter to deal with it. 400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * TUNING: for consistency, we may want to just go ahead and handle these here. 500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze */ 600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze 700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .extern MterpLogDivideByZeroException 800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunzecommon_errDivideByZero: 900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze EXPORT_PC 1000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze#if MTERP_LOGGING 1100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze move a0, rSELF 1200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze daddu a1, rFP, OFF_FP_SHADOWFRAME 1300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze jal MterpLogDivideByZeroException 1400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze#endif 1500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze b MterpCommonFallback 1600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze 1700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .extern MterpLogArrayIndexException 1800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunzecommon_errArrayIndex: 1900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze EXPORT_PC 2000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze#if MTERP_LOGGING 2100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze move a0, rSELF 2200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze daddu a1, rFP, OFF_FP_SHADOWFRAME 2300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze jal MterpLogArrayIndexException 2400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze#endif 2500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze b MterpCommonFallback 2600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze 2700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .extern MterpLogNullObjectException 2800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunzecommon_errNullObject: 2900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze EXPORT_PC 3000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze#if MTERP_LOGGING 3100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze move a0, rSELF 3200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze daddu a1, rFP, OFF_FP_SHADOWFRAME 3300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze jal MterpLogNullObjectException 3400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze#endif 3500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze b MterpCommonFallback 3600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze 3700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze/* 3800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * If we're here, something is out of the ordinary. If there is a pending 3900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * exception, handle it. Otherwise, roll back and retry with the reference 4000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * interpreter. 4100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze */ 4200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey FrunzeMterpPossibleException: 4300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze ld a0, THREAD_EXCEPTION_OFFSET(rSELF) 4400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze beqzc a0, MterpFallback # If not, fall back to reference interpreter. 4500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze /* intentional fallthrough - handle pending exception. */ 4600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze/* 4700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * On return from a runtime helper routine, we've found a pending exception. 4800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * Can we handle it here - or need to bail out to caller? 4900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * 5000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze */ 5100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .extern MterpHandleException 52db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze .extern MterpShouldSwitchInterpreters 5300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey FrunzeMterpException: 5400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze move a0, rSELF 5500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze daddu a1, rFP, OFF_FP_SHADOWFRAME 5600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze jal MterpHandleException # (self, shadow_frame) 5700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze beqzc v0, MterpExceptionReturn # no local catch, back to caller. 5800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze ld a0, OFF_FP_CODE_ITEM(rFP) 5900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze lwu a1, OFF_FP_DEX_PC(rFP) 6000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze REFRESH_IBASE 6100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze daddu rPC, a0, CODEITEM_INSNS_OFFSET 6200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze dlsa rPC, a1, rPC, 1 # generate new dex_pc_ptr 63db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze /* Do we need to switch interpreters? */ 64db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze jal MterpShouldSwitchInterpreters 65db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze bnezc v0, MterpFallback 6600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze /* resume execution at catch block */ 67db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze EXPORT_PC 6800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze FETCH_INST 6900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze GET_INST_OPCODE v0 7000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze GOTO_OPCODE v0 7100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze /* NOTE: no fallthrough */ 7200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze 7300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze/* 7400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * Check for suspend check request. Assumes rINST already loaded, rPC advanced and 7500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * still needs to get the opcode and branch to it, and flags are in ra. 7600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze */ 7700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .extern MterpSuspendCheck 7800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey FrunzeMterpCheckSuspendAndContinue: 7900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze REFRESH_IBASE 8000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze and ra, ra, (THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST) 8100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze bnez ra, check1 8200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze GET_INST_OPCODE v0 # extract opcode from rINST 8300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze GOTO_OPCODE v0 # jump to next instruction 8400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunzecheck1: 8500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze EXPORT_PC 8600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze move a0, rSELF 8700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze jal MterpSuspendCheck # (self) 88db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze bnezc v0, MterpFallback # Something in the environment changed, switch interpreters 8900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze GET_INST_OPCODE v0 # extract opcode from rINST 9000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze GOTO_OPCODE v0 # jump to next instruction 9100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze 9200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze/* 93db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze * On-stack replacement has happened, and now we've returned from the compiled method. 94db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze */ 95db045bea24d28ce6ad932fec4ce055af7be530e2Alexey FrunzeMterpOnStackReplacement: 96db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze#if MTERP_LOGGING 97db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze move a0, rSELF 98db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze daddu a1, rFP, OFF_FP_SHADOWFRAME 99db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze move a2, rINST # rINST contains offset 100db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze jal MterpLogOSR 101db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze#endif 102db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze li v0, 1 # Signal normal return 103db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze b MterpDone 104db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze 105db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze/* 10600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * Bail out to reference interpreter. 10700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze */ 10800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .extern MterpLogFallback 10900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey FrunzeMterpFallback: 11000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze EXPORT_PC 11100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze#if MTERP_LOGGING 11200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze move a0, rSELF 11300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze daddu a1, rFP, OFF_FP_SHADOWFRAME 11400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze jal MterpLogFallback 11500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze#endif 11600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey FrunzeMterpCommonFallback: 11700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze li v0, 0 # signal retry with reference interpreter. 11800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze b MterpDone 11900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze 12000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze/* 12100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * We pushed some registers on the stack in ExecuteMterpImpl, then saved 12200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * SP and RA. Here we restore SP, restore the registers, and then restore 12300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * RA to PC. 12400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * 12500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * On entry: 12600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * uint32_t* rFP (should still be live, pointer to base of vregs) 12700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze */ 12800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey FrunzeMterpExceptionReturn: 12900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze li v0, 1 # signal return to caller. 13000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze b MterpDone 13100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze/* 13200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * Returned value is expected in a0 and if it's not 64-bit, the 32 most 13300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * significant bits of a0 must be 0. 13400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze */ 13500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey FrunzeMterpReturn: 13600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze ld a2, OFF_FP_RESULT_REGISTER(rFP) 13700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze lw ra, THREAD_FLAGS_OFFSET(rSELF) 13800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze sd a0, 0(a2) 13900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze move a0, rSELF 14000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze and ra, ra, (THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST) 14100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze beqzc ra, check2 14200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze jal MterpSuspendCheck # (self) 14300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunzecheck2: 14400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze li v0, 1 # signal return to caller. 14500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey FrunzeMterpDone: 14600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze ld s5, STACK_OFFSET_S5(sp) 14700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .cfi_restore 21 14800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze ld s4, STACK_OFFSET_S4(sp) 14900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .cfi_restore 20 15000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze ld s3, STACK_OFFSET_S3(sp) 15100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .cfi_restore 19 15200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze ld s2, STACK_OFFSET_S2(sp) 15300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .cfi_restore 18 15400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze ld s1, STACK_OFFSET_S1(sp) 15500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .cfi_restore 17 15600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze ld s0, STACK_OFFSET_S0(sp) 15700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .cfi_restore 16 15800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze 15900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze ld ra, STACK_OFFSET_RA(sp) 16000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .cfi_restore 31 16100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze 16200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze ld t8, STACK_OFFSET_GP(sp) 16300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .cpreturn 16400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .cfi_restore 28 16500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze 16600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .set noreorder 16700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze jr ra 16800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze daddu sp, sp, STACK_SIZE 16900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .cfi_adjust_cfa_offset -STACK_SIZE 17000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze 17100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .cfi_endproc 17200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .size ExecuteMterpImpl, .-ExecuteMterpImpl 173