13b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee/*
23b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * ===========================================================================
33b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee *  Common subroutines and data
43b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * ===========================================================================
53b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee */
63b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
73b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
83b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee/*
93b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * We've detected a condition that will result in an exception, but the exception
103b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * has not yet been thrown.  Just bail out to the reference interpreter to deal with it.
113b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * TUNING: for consistency, we may want to just go ahead and handle these here.
123b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee */
133b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbeecommon_errDivideByZero:
143b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    EXPORT_PC
153b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#if MTERP_LOGGING
163b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov  x0, xSELF
173b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    add  x1, xFP, #OFF_FP_SHADOWFRAME
183b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    bl MterpLogDivideByZeroException
193b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#endif
203b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    b MterpCommonFallback
213b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
223b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbeecommon_errArrayIndex:
233b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    EXPORT_PC
243b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#if MTERP_LOGGING
253b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov  x0, xSELF
263b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    add  x1, xFP, #OFF_FP_SHADOWFRAME
273b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    bl MterpLogArrayIndexException
283b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#endif
293b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    b MterpCommonFallback
303b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
313b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbeecommon_errNegativeArraySize:
323b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    EXPORT_PC
333b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#if MTERP_LOGGING
343b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov  x0, xSELF
353b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    add  x1, xFP, #OFF_FP_SHADOWFRAME
363b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    bl MterpLogNegativeArraySizeException
373b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#endif
383b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    b MterpCommonFallback
393b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
403b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbeecommon_errNoSuchMethod:
413b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    EXPORT_PC
423b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#if MTERP_LOGGING
433b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov  x0, xSELF
443b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    add  x1, xFP, #OFF_FP_SHADOWFRAME
453b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    bl MterpLogNoSuchMethodException
463b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#endif
473b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    b MterpCommonFallback
483b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
493b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbeecommon_errNullObject:
503b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    EXPORT_PC
513b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#if MTERP_LOGGING
523b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov  x0, xSELF
533b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    add  x1, xFP, #OFF_FP_SHADOWFRAME
543b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    bl MterpLogNullObjectException
553b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#endif
563b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    b MterpCommonFallback
573b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
583b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbeecommon_exceptionThrown:
593b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    EXPORT_PC
603b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#if MTERP_LOGGING
613b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov  x0, xSELF
623b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    add  x1, xFP, #OFF_FP_SHADOWFRAME
633b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    bl MterpLogExceptionThrownException
643b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#endif
653b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    b MterpCommonFallback
663b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
673b0b4b9d09baae7234fc26b7970b3ec55560735eBill BuzbeeMterpSuspendFallback:
683b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    EXPORT_PC
693b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#if MTERP_LOGGING
703b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov  x0, xSELF
713b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    add  x1, xFP, #OFF_FP_SHADOWFRAME
723b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    ldr  x2, [xSELF, #THREAD_FLAGS_OFFSET]
733b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    bl MterpLogSuspendFallback
743b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#endif
753b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    b MterpCommonFallback
763b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
773b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee/*
783b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * If we're here, something is out of the ordinary.  If there is a pending
793b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * exception, handle it.  Otherwise, roll back and retry with the reference
803b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * interpreter.
813b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee */
823b0b4b9d09baae7234fc26b7970b3ec55560735eBill BuzbeeMterpPossibleException:
833b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    ldr     x0, [xSELF, #THREAD_EXCEPTION_OFFSET]
843b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    cbz     x0, MterpFallback                       // If not, fall back to reference interpreter.
853b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    /* intentional fallthrough - handle pending exception. */
863b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee/*
873b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * On return from a runtime helper routine, we've found a pending exception.
883b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * Can we handle it here - or need to bail out to caller?
893b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee *
903b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee */
913b0b4b9d09baae7234fc26b7970b3ec55560735eBill BuzbeeMterpException:
923b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov     x0, xSELF
933b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    add     x1, xFP, #OFF_FP_SHADOWFRAME
943b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    bl      MterpHandleException                    // (self, shadow_frame)
953b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    cbz     w0, MterpExceptionReturn                // no local catch, back to caller.
96fc9555dac51a3cf12bb13f4e3781d2f2f6c9f91fMathieu Chartier    ldr     x0, [xFP, #OFF_FP_DEX_INSTRUCTIONS]
973b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    ldr     w1, [xFP, #OFF_FP_DEX_PC]
983b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    ldr     xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET]
99fc9555dac51a3cf12bb13f4e3781d2f2f6c9f91fMathieu Chartier    add     xPC, x0, x1, lsl #1                     // generate new dex_pc_ptr
100fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee    /* Do we need to switch interpreters? */
101fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee    bl      MterpShouldSwitchInterpreters
102fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee    cbnz    w0, MterpFallback
1033b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    /* resume execution at catch block */
104fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee    EXPORT_PC
1053b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    FETCH_INST
1063b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    GET_INST_OPCODE ip
1073b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    GOTO_OPCODE ip
1083b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    /* NOTE: no fallthrough */
1091d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee/*
1101d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * Common handling for branches with support for Jit profiling.
1111d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * On entry:
1121d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee *    wINST          <= signed offset
1131d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee *    wPROFILE       <= signed hotness countdown (expanded to 32 bits)
1141d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee *    condition bits <= set to establish sign of offset (use "NoFlags" entry if not)
1151d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee *
1161d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * We have quite a few different cases for branch profiling, OSR detection and
1171d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * suspend check support here.
1181d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee *
1191d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * Taken backward branches:
1201d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee *    If profiling active, do hotness countdown and report if we hit zero.
1211d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee *    If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
1221d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee *    Is there a pending suspend request?  If so, suspend.
1231d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee *
1241d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * Taken forward branches and not-taken backward branches:
1251d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee *    If in osr check mode, see if our target is a compiled loop header entry and do OSR if so.
1261d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee *
1271d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * Our most common case is expected to be a taken backward branch with active jit profiling,
1281d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * but no full OSR check and no pending suspend request.
1291d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * Next most common case is not-taken branch with no full OSR check.
1301d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee *
1311d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee */
1321d011d9306fd4ff57d72411775d415a86f5ed398Bill BuzbeeMterpCommonTakenBranchNoFlags:
1331d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    cmp     wINST, #0
1341d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    b.gt    .L_forward_branch           // don't add forward branches to hotness
1351d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    tbnz    wPROFILE, #31, .L_no_count_backwards  // go if negative
1361d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    subs    wPROFILE, wPROFILE, #1      // countdown
1371d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    b.eq    .L_add_batch                // counted down to zero - report
1381d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee.L_resume_backward_branch:
1391d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    ldr     lr, [xSELF, #THREAD_FLAGS_OFFSET]
1401d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    add     w2, wINST, wINST            // w2<- byte offset
1411d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    FETCH_ADVANCE_INST_RB w2            // update rPC, load wINST
1421d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    REFRESH_IBASE
1433049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi    ands    lr, lr, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
1441d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    b.ne    .L_suspend_request_pending
1451d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    GET_INST_OPCODE ip                  // extract opcode from wINST
1461d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    GOTO_OPCODE ip                      // jump to next instruction
1471d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee
1481d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee.L_suspend_request_pending:
1491d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    EXPORT_PC
1501d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    mov     x0, xSELF
1511d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    bl      MterpSuspendCheck           // (self)
1521d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    cbnz    x0, MterpFallback
1531d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    REFRESH_IBASE                       // might have changed during suspend
1541d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    GET_INST_OPCODE ip                  // extract opcode from wINST
1551d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    GOTO_OPCODE ip                      // jump to next instruction
1561d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee
1571d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee.L_no_count_backwards:
1581d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    cmp     wPROFILE, #JIT_CHECK_OSR    // possible OSR re-entry?
1591d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    b.ne    .L_resume_backward_branch
1601d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    mov     x0, xSELF
1611d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    add     x1, xFP, #OFF_FP_SHADOWFRAME
1621d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    mov     x2, xINST
1631d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    EXPORT_PC
1641d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    bl      MterpMaybeDoOnStackReplacement  // (self, shadow_frame, offset)
1651d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    cbnz    x0, MterpOnStackReplacement
1661d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    b       .L_resume_backward_branch
1671d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee
1681d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee.L_forward_branch:
1691d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    cmp     wPROFILE, #JIT_CHECK_OSR    // possible OSR re-entry?
1701d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    b.eq    .L_check_osr_forward
1711d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee.L_resume_forward_branch:
1721d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    add     w2, wINST, wINST            // w2<- byte offset
1731d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    FETCH_ADVANCE_INST_RB w2            // update rPC, load wINST
1741d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    GET_INST_OPCODE ip                  // extract opcode from wINST
1751d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    GOTO_OPCODE ip                      // jump to next instruction
1761d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee
1771d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee.L_check_osr_forward:
1781d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    mov     x0, xSELF
1791d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    add     x1, xFP, #OFF_FP_SHADOWFRAME
1801d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    mov     x2, xINST
1811d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    EXPORT_PC
1821d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    bl      MterpMaybeDoOnStackReplacement  // (self, shadow_frame, offset)
1831d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    cbnz    x0, MterpOnStackReplacement
1841d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    b       .L_resume_forward_branch
1851d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee
1861d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee.L_add_batch:
1871d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    add     x1, xFP, #OFF_FP_SHADOWFRAME
1881d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    strh    wPROFILE, [x1, #SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET]
1891d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    ldr     x0, [xFP, #OFF_FP_METHOD]
1901d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    mov     x2, xSELF
1911d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    bl      MterpAddHotnessBatch        // (method, shadow_frame, self)
1921d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    mov     wPROFILE, w0                // restore new hotness countdown to wPROFILE
1931d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    b       .L_no_count_backwards
1941d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee
1951d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee/*
1961d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * Entered from the conditional branch handlers when OSR check request active on
1971d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * not-taken path.  All Dalvik not-taken conditional branch offsets are 2.
1981d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee */
1991d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee.L_check_not_taken_osr:
2001d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    mov     x0, xSELF
2011d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    add     x1, xFP, #OFF_FP_SHADOWFRAME
2021d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    mov     x2, #2
2031d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    EXPORT_PC
2041d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    bl      MterpMaybeDoOnStackReplacement  // (self, shadow_frame, offset)
2051d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    cbnz    x0, MterpOnStackReplacement
2061d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    FETCH_ADVANCE_INST 2
2071d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    GET_INST_OPCODE ip                  // extract opcode from wINST
2081d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    GOTO_OPCODE ip                      // jump to next instruction
2091d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee
2103b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
2113b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee/*
2123b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * Check for suspend check request.  Assumes wINST already loaded, xPC advanced and
2133b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * still needs to get the opcode and branch to it, and flags are in lr.
2143b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee */
2153b0b4b9d09baae7234fc26b7970b3ec55560735eBill BuzbeeMterpCheckSuspendAndContinue:
2163b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    ldr     xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET]  // refresh xIBASE
2173049324f4ef71b5d7a3de49bd77c75f07dbf8f3aHiroshi Yamauchi    ands    w7, w7, #THREAD_SUSPEND_OR_CHECKPOINT_REQUEST
2183b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    b.ne    check1
2193b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    GET_INST_OPCODE ip                  // extract opcode from wINST
2203b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    GOTO_OPCODE ip                      // jump to next instruction
2213b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbeecheck1:
2223b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    EXPORT_PC
2233b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov     x0, xSELF
2243b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    bl      MterpSuspendCheck           // (self)
225fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee    cbnz    x0, MterpFallback           // Something in the environment changed, switch interpreters
2263b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    GET_INST_OPCODE ip                  // extract opcode from wINST
2273b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    GOTO_OPCODE ip                      // jump to next instruction
2283b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
2293b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee/*
230fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee * On-stack replacement has happened, and now we've returned from the compiled method.
231fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee */
232fd522f9039befff986701ff05054ffdd1be1dd33Bill BuzbeeMterpOnStackReplacement:
233fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee#if MTERP_LOGGING
234fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee    mov  x0, xSELF
235fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee    add  x1, xFP, #OFF_FP_SHADOWFRAME
236e6220220cdd20d81da336528d9b1642edf65655aVladimir Marko    sxtw x2, wINST
237fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee    bl MterpLogOSR
238fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee#endif
239fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee    mov  x0, #1                         // Signal normal return
240fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee    b    MterpDone
241fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee
242fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee/*
2433b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * Bail out to reference interpreter.
2443b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee */
2453b0b4b9d09baae7234fc26b7970b3ec55560735eBill BuzbeeMterpFallback:
2463b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    EXPORT_PC
2473b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#if MTERP_LOGGING
2483b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov  x0, xSELF
2493b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    add  x1, xFP, #OFF_FP_SHADOWFRAME
2503b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    bl MterpLogFallback
2513b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#endif
2523b0b4b9d09baae7234fc26b7970b3ec55560735eBill BuzbeeMterpCommonFallback:
2533b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov     x0, #0                                  // signal retry with reference interpreter.
2543b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    b       MterpDone
2553b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
2563b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee/*
2573b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * We pushed some registers on the stack in ExecuteMterpImpl, then saved
2583b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * SP and LR.  Here we restore SP, restore the registers, and then restore
2593b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * LR to PC.
2603b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee *
2613b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee * On entry:
2623b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee *  uint32_t* xFP  (should still be live, pointer to base of vregs)
2633b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee */
2643b0b4b9d09baae7234fc26b7970b3ec55560735eBill BuzbeeMterpExceptionReturn:
2653b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov     x0, #1                                  // signal return to caller.
2663b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    b MterpDone
2673b0b4b9d09baae7234fc26b7970b3ec55560735eBill BuzbeeMterpReturn:
2683b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    ldr     x2, [xFP, #OFF_FP_RESULT_REGISTER]
2693b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    str     x0, [x2]
2703b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    mov     x0, #1                                  // signal return to caller.
2713b0b4b9d09baae7234fc26b7970b3ec55560735eBill BuzbeeMterpDone:
2721d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee/*
2731d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * At this point, we expect wPROFILE to be non-zero.  If negative, hotness is disabled or we're
2741d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * checking for OSR.  If greater than zero, we might have unreported hotness to register
2751d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * (the difference between the ending wPROFILE and the cached hotness counter).  wPROFILE
2761d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * should only reach zero immediately after a hotness decrement, and is then reset to either
2771d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee * a negative special state or the new non-zero countdown value.
2781d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee */
2791d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    cmp     wPROFILE, #0
2801d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    bgt     MterpProfileActive                      // if > 0, we may have some counts to report.
281112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    .cfi_remember_state
282112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    RESTORE_TWO_REGS                fp, lr, 64
283112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    RESTORE_TWO_REGS                xPC, xFP, 48
284112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    RESTORE_TWO_REGS                xSELF, xINST, 32
285112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    RESTORE_TWO_REGS                xIBASE, xREFS, 16
286112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    RESTORE_TWO_REGS_DECREASE_FRAME xPROFILE, x27, 80
2871d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    ret
288112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    .cfi_restore_state                              // Reset unwind info so following code unwinds.
289112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    .cfi_def_cfa_offset 80                          // workaround for clang bug: 31975598
2901d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee
2911d011d9306fd4ff57d72411775d415a86f5ed398Bill BuzbeeMterpProfileActive:
2921d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    mov     xINST, x0                               // stash return value
2931d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    /* Report cached hotness counts */
2941d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    ldr     x0, [xFP, #OFF_FP_METHOD]
2951d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    add     x1, xFP, #OFF_FP_SHADOWFRAME
2961d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    mov     x2, xSELF
2971d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    strh    wPROFILE, [x1, #SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET]
2981d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    bl      MterpAddHotnessBatch                    // (method, shadow_frame, self)
2991d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee    mov     x0, xINST                               // restore return value
300112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    RESTORE_TWO_REGS                fp, lr, 64
301112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    RESTORE_TWO_REGS                xPC, xFP, 48
302112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    RESTORE_TWO_REGS                xSELF, xINST, 32
303112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    RESTORE_TWO_REGS                xIBASE, xREFS, 16
304112aa1088cf283d57c533be17d79c4b638665651Vladimir Marko    RESTORE_TWO_REGS_DECREASE_FRAME xPROFILE, x27, 80
3053b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee    ret
3063b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee
307