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