Home | History | Annotate | Download | only in mips
      1 /*
      2  * ===========================================================================
      3  *  Common subroutines and data
      4  * ===========================================================================
      5  */
      6 
      7     .text
      8     .align 2
      9 
     10 /*
     11  * We've detected a condition that will result in an exception, but the exception
     12  * has not yet been thrown.  Just bail out to the reference interpreter to deal with it.
     13  * TUNING: for consistency, we may want to just go ahead and handle these here.
     14  */
     15 common_errDivideByZero:
     16     EXPORT_PC()
     17 #if MTERP_LOGGING
     18     move  a0, rSELF
     19     addu  a1, rFP, OFF_FP_SHADOWFRAME
     20     JAL(MterpLogDivideByZeroException)
     21 #endif
     22     b MterpCommonFallback
     23 
     24 common_errArrayIndex:
     25     EXPORT_PC()
     26 #if MTERP_LOGGING
     27     move  a0, rSELF
     28     addu  a1, rFP, OFF_FP_SHADOWFRAME
     29     JAL(MterpLogArrayIndexException)
     30 #endif
     31     b MterpCommonFallback
     32 
     33 common_errNegativeArraySize:
     34     EXPORT_PC()
     35 #if MTERP_LOGGING
     36     move  a0, rSELF
     37     addu  a1, rFP, OFF_FP_SHADOWFRAME
     38     JAL(MterpLogNegativeArraySizeException)
     39 #endif
     40     b MterpCommonFallback
     41 
     42 common_errNoSuchMethod:
     43     EXPORT_PC()
     44 #if MTERP_LOGGING
     45     move  a0, rSELF
     46     addu  a1, rFP, OFF_FP_SHADOWFRAME
     47     JAL(MterpLogNoSuchMethodException)
     48 #endif
     49     b MterpCommonFallback
     50 
     51 common_errNullObject:
     52     EXPORT_PC()
     53 #if MTERP_LOGGING
     54     move  a0, rSELF
     55     addu  a1, rFP, OFF_FP_SHADOWFRAME
     56     JAL(MterpLogNullObjectException)
     57 #endif
     58     b MterpCommonFallback
     59 
     60 common_exceptionThrown:
     61     EXPORT_PC()
     62 #if MTERP_LOGGING
     63     move  a0, rSELF
     64     addu  a1, rFP, OFF_FP_SHADOWFRAME
     65     JAL(MterpLogExceptionThrownException)
     66 #endif
     67     b MterpCommonFallback
     68 
     69 MterpSuspendFallback:
     70     EXPORT_PC()
     71 #if MTERP_LOGGING
     72     move  a0, rSELF
     73     addu  a1, rFP, OFF_FP_SHADOWFRAME
     74     lw    a2, THREAD_FLAGS_OFFSET(rSELF)
     75     JAL(MterpLogSuspendFallback)
     76 #endif
     77     b MterpCommonFallback
     78 
     79 /*
     80  * If we're here, something is out of the ordinary.  If there is a pending
     81  * exception, handle it.  Otherwise, roll back and retry with the reference
     82  * interpreter.
     83  */
     84 MterpPossibleException:
     85     lw      a0, THREAD_EXCEPTION_OFFSET(rSELF)
     86     beqz    a0, MterpFallback          # If exception, fall back to reference interpreter.
     87     /* intentional fallthrough - handle pending exception. */
     88 /*
     89  * On return from a runtime helper routine, we've found a pending exception.
     90  * Can we handle it here - or need to bail out to caller?
     91  *
     92  */
     93 MterpException:
     94     move    a0, rSELF
     95     addu    a1, rFP, OFF_FP_SHADOWFRAME
     96     JAL(MterpHandleException)                    # (self, shadow_frame)
     97     beqz    v0, MterpExceptionReturn             # no local catch, back to caller.
     98     lw      a0, OFF_FP_CODE_ITEM(rFP)
     99     lw      a1, OFF_FP_DEX_PC(rFP)
    100     lw      rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)
    101     addu    rPC, a0, CODEITEM_INSNS_OFFSET
    102     sll     a1, a1, 1
    103     addu    rPC, rPC, a1                         # generate new dex_pc_ptr
    104     /* Do we need to switch interpreters? */
    105     JAL(MterpShouldSwitchInterpreters)
    106     bnez    v0, MterpFallback
    107     /* resume execution at catch block */
    108     EXPORT_PC()
    109     FETCH_INST()
    110     GET_INST_OPCODE(t0)
    111     GOTO_OPCODE(t0)
    112     /* NOTE: no fallthrough */
    113 
    114 /*
    115  * Check for suspend check request.  Assumes rINST already loaded, rPC advanced and
    116  * still needs to get the opcode and branch to it, and flags are in lr.
    117  */
    118 MterpCheckSuspendAndContinue:
    119     lw      rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)  # refresh rIBASE
    120     and     ra, (THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST)
    121     bnez    ra, 1f
    122     GET_INST_OPCODE(t0)                 # extract opcode from rINST
    123     GOTO_OPCODE(t0)                     # jump to next instruction
    124 1:
    125     EXPORT_PC()
    126     move    a0, rSELF
    127     JAL(MterpSuspendCheck)              # (self)
    128     bnez    v0, MterpFallback
    129     GET_INST_OPCODE(t0)                 # extract opcode from rINST
    130     GOTO_OPCODE(t0)                     # jump to next instruction
    131 
    132 /*
    133  * On-stack replacement has happened, and now we've returned from the compiled method.
    134  */
    135 MterpOnStackReplacement:
    136 #if MTERP_LOGGING
    137     move    a0, rSELF
    138     addu    a1, rFP, OFF_FP_SHADOWFRAME
    139     move    a2, rINST
    140     JAL(MterpLogOSR)
    141 #endif
    142     li      v0, 1                       # Signal normal return
    143     b       MterpDone
    144 
    145 /*
    146  * Bail out to reference interpreter.
    147  */
    148 MterpFallback:
    149     EXPORT_PC()
    150 #if MTERP_LOGGING
    151     move  a0, rSELF
    152     addu  a1, rFP, OFF_FP_SHADOWFRAME
    153     JAL(MterpLogFallback)
    154 #endif
    155 MterpCommonFallback:
    156     move    v0, zero                    # signal retry with reference interpreter.
    157     b       MterpDone
    158 /*
    159  * We pushed some registers on the stack in ExecuteMterpImpl, then saved
    160  * SP and LR.  Here we restore SP, restore the registers, and then restore
    161  * LR to PC.
    162  *
    163  * On entry:
    164  *  uint32_t* rFP  (should still be live, pointer to base of vregs)
    165  */
    166 MterpExceptionReturn:
    167     li      v0, 1                       # signal return to caller.
    168     b       MterpDone
    169 MterpReturn:
    170     lw      a2, OFF_FP_RESULT_REGISTER(rFP)
    171     sw      v0, 0(a2)
    172     sw      v1, 4(a2)
    173     li      v0, 1                       # signal return to caller.
    174 MterpDone:
    175 /* Restore from the stack and return. Frame size = STACK_SIZE */
    176     STACK_LOAD_FULL()
    177     jalr    zero, ra
    178 
    179     .end ExecuteMterpImpl
    180