Home | History | Annotate | Download | only in mips
      1 /*
      2  * ===========================================================================
      3  *  Common subroutines and data
      4  * ===========================================================================
      5  */
      6 
      7     .text
      8     .align 2
      9 
     10 #if defined(WITH_JIT)
     11 #if defined(WITH_SELF_VERIFICATION)
     12 
     13 /*
     14  * "longjmp" to a translation after single-stepping.  Before returning
     15  * to translation, must save state for self-verification.
     16  */
     17     .global dvmJitResumeTranslation             # (Thread* self, u4* dFP)
     18 dvmJitResumeTranslation:
     19     move    rSELF, a0                           # restore self
     20     move    rPC, a1                             # restore Dalvik pc
     21     move    rFP, a2                             # restore Dalvik fp
     22     lw      rBIX, offThread_jitResumeNPC(rSELF)
     23     sw      zero, offThread_jitResumeNPC(rSELF) # reset resume address
     24     lw      sp, offThread_jitResumeNSP(rSELF)   # cut back native stack
     25     b       jitSVShadowRunStart                 # resume as if cache hit
     26                                                 # expects resume addr in rBIX
     27 
     28     .global dvmJitToInterpPunt
     29 dvmJitToInterpPunt:
     30     li        a2, kSVSPunt                 #  a2 <- interpreter entry point
     31     sw        zero, offThread_inJitCodeCache(rSELF) #  Back to the interp land
     32     b         jitSVShadowRunEnd            #  doesn't return
     33 
     34     .global dvmJitToInterpSingleStep
     35 dvmJitToInterpSingleStep:
     36     move      rPC, a0                      # set up dalvik pc
     37     EXPORT_PC()
     38     sw        ra, offThread_jitResumeNPC(rSELF)
     39     sw        a1, offThread_jitResumeDPC(rSELF)
     40     li        a2, kSVSSingleStep           #  a2 <- interpreter entry point
     41     b         jitSVShadowRunEnd            #  doesn't return
     42 
     43     .global dvmJitToInterpNoChainNoProfile
     44 dvmJitToInterpNoChainNoProfile:
     45     move      a0, rPC                      #  pass our target PC
     46     li        a2, kSVSNoProfile            #  a2 <- interpreter entry point
     47     sw        zero, offThread_inJitCodeCache(rSELF) #  Back to the interp land
     48     b         jitSVShadowRunEnd            #  doesn't return
     49 
     50     .global dvmJitToInterpTraceSelectNoChain
     51 dvmJitToInterpTraceSelectNoChain:
     52     move      a0, rPC                      #  pass our target PC
     53     li        a2, kSVSTraceSelect          #  a2 <- interpreter entry point
     54     sw        zero, offThread_inJitCodeCache(rSELF) #  Back to the interp land
     55     b         jitSVShadowRunEnd            #  doesn't return
     56 
     57     .global dvmJitToInterpTraceSelect
     58 dvmJitToInterpTraceSelect:
     59     lw        a0, 0(ra)                   #  pass our target PC
     60     li        a2, kSVSTraceSelect          #  a2 <- interpreter entry point
     61     sw        zero, offThread_inJitCodeCache(rSELF) #  Back to the interp land
     62     b         jitSVShadowRunEnd            #  doesn't return
     63 
     64     .global dvmJitToInterpBackwardBranch
     65 dvmJitToInterpBackwardBranch:
     66     lw        a0, 0(ra)                   #  pass our target PC
     67     li        a2, kSVSBackwardBranch       #  a2 <- interpreter entry point
     68     sw        zero, offThread_inJitCodeCache(rSELF) #  Back to the interp land
     69     b         jitSVShadowRunEnd            #  doesn't return
     70 
     71     .global dvmJitToInterpNormal
     72 dvmJitToInterpNormal:
     73     lw        a0, 0(ra)                   #  pass our target PC
     74     li        a2, kSVSNormal               #  a2 <- interpreter entry point
     75     sw        zero, offThread_inJitCodeCache(rSELF) #  Back to the interp land
     76     b         jitSVShadowRunEnd            #  doesn't return
     77 
     78     .global dvmJitToInterpNoChain
     79 dvmJitToInterpNoChain:
     80     move      a0, rPC                      #  pass our target PC
     81     li        a2, kSVSNoChain              #  a2 <- interpreter entry point
     82     sw        zero, offThread_inJitCodeCache(rSELF) #  Back to the interp land
     83     b         jitSVShadowRunEnd            #  doesn't return
     84 #else                                   /*  WITH_SELF_VERIFICATION */
     85 
     86 
     87 /*
     88  * "longjmp" to a translation after single-stepping.
     89  */
     90     .global dvmJitResumeTranslation             # (Thread* self, u4* dFP)
     91 dvmJitResumeTranslation:
     92     move    rSELF, a0                           # restore self
     93     move    rPC, a1                             # restore Dalvik pc
     94     move    rFP, a2                             # restore Dalvik fp
     95     lw      a0, offThread_jitResumeNPC(rSELF)
     96     sw      zero, offThread_jitResumeNPC(rSELF) # reset resume address
     97     lw      sp, offThread_jitResumeNSP(rSELF)   # cut back native stack
     98     jr      a0                                  # resume translation
     99 
    100 
    101 /*
    102  * Return from the translation cache to the interpreter when the compiler is
    103  * having issues translating/executing a Dalvik instruction. We have to skip
    104  * the code cache lookup otherwise it is possible to indefinitely bouce
    105  * between the interpreter and the code cache if the instruction that fails
    106  * to be compiled happens to be at a trace start.
    107  */
    108     .global dvmJitToInterpPunt
    109 dvmJitToInterpPunt:
    110     lw        gp, STACK_OFFSET_GP(sp)
    111     move      rPC, a0
    112 #if defined(WITH_JIT_TUNING)
    113     move      a0, ra
    114     JAL(dvmBumpPunt)
    115 #endif
    116     EXPORT_PC()
    117     sw        zero, offThread_inJitCodeCache(rSELF) # Back to the interp land
    118     lw        rIBASE, offThread_curHandlerTable(rSELF)
    119     FETCH_INST()
    120     GET_INST_OPCODE(t0)
    121     GOTO_OPCODE(t0)
    122 
    123 /*
    124  * Return to the interpreter to handle a single instruction.
    125  * On entry:
    126  *    rPC <= Dalvik PC of instrucion to interpret
    127  *    a1 <= Dalvik PC of resume instruction
    128  *    ra <= resume point in translation
    129  */
    130 
    131     .global dvmJitToInterpSingleStep
    132 dvmJitToInterpSingleStep:
    133     lw        gp, STACK_OFFSET_GP(sp)
    134     move      rPC, a0                       # set up dalvik pc
    135     EXPORT_PC()
    136     sw        ra, offThread_jitResumeNPC(rSELF)
    137     sw        sp, offThread_jitResumeNSP(rSELF)
    138     sw        a1, offThread_jitResumeDPC(rSELF)
    139     li        a1, 1
    140     sw        a1, offThread_singleStepCount(rSELF) # just step once
    141     move      a0, rSELF
    142     li        a1, kSubModeCountedStep
    143     JAL(dvmEnableSubMode)                   # (self, subMode)
    144     lw        rIBASE, offThread_curHandlerTable(rSELF)
    145     FETCH_INST()
    146     GET_INST_OPCODE(t0)
    147     GOTO_OPCODE(t0)
    148 /*
    149  * Return from the translation cache and immediately request
    150  * a translation for the exit target.  Commonly used for callees.
    151  */
    152     .global dvmJitToInterpTraceSelectNoChain
    153 dvmJitToInterpTraceSelectNoChain:
    154     lw        gp, STACK_OFFSET_GP(sp)
    155 #if defined(WITH_JIT_TUNING)
    156     JAL(dvmBumpNoChain)
    157 #endif
    158     move      a0, rPC
    159     move      a1, rSELF
    160     JAL(dvmJitGetTraceAddrThread)          # (pc, self)
    161     move      a0, v0
    162     sw        a0, offThread_inJitCodeCache(rSELF) # set the inJitCodeCache flag
    163     move      a1, rPC                      # arg1 of translation may need this
    164     move      ra, zero                     #  in case target is HANDLER_INTERPRET
    165     beqz      a0, 2f                       # 0 means translation does not exist
    166     jr        a0
    167 
    168 /*
    169  * Return from the translation cache and immediately request
    170  * a translation for the exit target.  Commonly used following
    171  * invokes.
    172  */
    173     .global dvmJitToInterpTraceSelect
    174 dvmJitToInterpTraceSelect:
    175     lw        gp, STACK_OFFSET_GP(sp)
    176     lw        rPC, (ra)                    #  get our target PC
    177     subu      rINST, ra, 8                 #  save start of chain branch
    178     move      a0, rPC
    179     move      a1, rSELF
    180     JAL(dvmJitGetTraceAddrThread)          # @ (pc, self)
    181     sw        v0, offThread_inJitCodeCache(rSELF) # set the inJitCodeCache flag
    182     beqz      v0, 2f
    183     move      a0, v0
    184     move      a1, rINST
    185     JAL(dvmJitChain)                       #  v0 <- dvmJitChain(codeAddr, chainAddr)
    186     move      a1, rPC                      #  arg1 of translation may need this
    187     move      ra, zero                     #  in case target is HANDLER_INTERPRET
    188     move      a0, v0
    189     beqz      a0, toInterpreter            #  didn't chain - resume with interpreter
    190 
    191     jr        a0                           #  continue native execution
    192 
    193 /* No translation, so request one if profiling isn't disabled */
    194 2:
    195     lw        rIBASE, offThread_curHandlerTable(rSELF)
    196     lw        a0, offThread_pJitProfTable(rSELF)
    197     FETCH_INST()
    198     li        t0, kJitTSelectRequestHot
    199     movn      a2, t0, a0                   #  ask for trace selection
    200     bnez      a0, common_selectTrace
    201     GET_INST_OPCODE(t0)
    202     GOTO_OPCODE(t0)
    203 
    204 /*
    205  * Return from the translation cache to the interpreter.
    206  * The return was done with a BLX from thumb mode, and
    207  * the following 32-bit word contains the target rPC value.
    208  * Note that lr (r14) will have its low-order bit set to denote
    209  * its thumb-mode origin.
    210  *
    211  * We'll need to stash our lr origin away, recover the new
    212  * target and then check to see if there is a translation available
    213  * for our new target.  If so, we do a translation chain and
    214  * go back to native execution.  Otherwise, it's back to the
    215  * interpreter (after treating this entry as a potential
    216  * trace start).
    217  */
    218     .global dvmJitToInterpNormal
    219 dvmJitToInterpNormal:
    220     lw        gp, STACK_OFFSET_GP(sp)
    221     lw        rPC, (ra)                    #  get our target PC
    222     subu      rINST, ra, 8                 #  save start of chain branch
    223 #if defined(WITH_JIT_TUNING)
    224     JAL(dvmBumpNormal)
    225 #endif
    226     move      a0, rPC
    227     move      a1, rSELF
    228     JAL(dvmJitGetTraceAddrThread)           # @ (pc, self)
    229     move      a0, v0
    230     sw        a0, offThread_inJitCodeCache(rSELF) #  set the inJitCodeCache flag
    231     beqz      a0, toInterpreter            #  go if not, otherwise do chain
    232     move      a1, rINST
    233     JAL(dvmJitChain)                       #  v0 <- dvmJitChain(codeAddr, chainAddr)
    234     move      a1, rPC                      #  arg1 of translation may need this
    235     move      ra, zero                     #  in case target is HANDLER_INTERPRET
    236     move      a0, v0
    237     beqz      a0, toInterpreter            #  didn't chain - resume with interpreter
    238 
    239     jr        a0                           #  continue native execution
    240 
    241 /*
    242  * Return from the translation cache to the interpreter to do method invocation.
    243  * Check if translation exists for the callee, but don't chain to it.
    244  */
    245     .global dvmJitToInterpNoChainNoProfile
    246 dvmJitToInterpNoChainNoProfile:
    247 #if defined(WITH_JIT_TUNING)
    248     JAL(dvmBumpNoChain)
    249 #endif
    250     move      a0, rPC
    251     move      a1, rSELF
    252     JAL(dvmJitGetTraceAddrThread)          # (pc, self)
    253     move      a0, v0
    254     sw        a0, offThread_inJitCodeCache(rSELF) #  set the inJitCodeCache flag
    255     move      a1, rPC                      #  arg1 of translation may need this
    256     move      ra, zero                     #  in case target is HANDLER_INTERPRET
    257     beqz      a0, footer235
    258 
    259     jr        a0                           #  continue native execution if so
    260 footer235:
    261     EXPORT_PC()
    262     lw        rIBASE, offThread_curHandlerTable(rSELF)
    263     FETCH_INST()
    264     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
    265     GOTO_OPCODE(t0)                        #  jump to next instruction
    266 
    267 /*
    268  * Return from the translation cache to the interpreter to do method invocation.
    269  * Check if translation exists for the callee, but don't chain to it.
    270  */
    271 
    272     .global dvmJitToInterpNoChain
    273 dvmJitToInterpNoChain:
    274     lw        gp, STACK_OFFSET_GP(sp)
    275 #if defined(WITH_JIT_TUNING)
    276     JAL(dvmBumpNoChain)
    277 #endif
    278     move      a0, rPC
    279     move      a1, rSELF
    280     JAL(dvmJitGetTraceAddrThread)          # (pc, self)
    281     move      a0, v0
    282     sw        a0, offThread_inJitCodeCache(rSELF) #  set the inJitCodeCache flag
    283     move      a1, rPC                      #  arg1 of translation may need this
    284     move      ra, zero                     #  in case target is HANDLER_INTERPRET
    285     beqz      a0, 1f
    286     jr        a0                           #  continue native execution if so
    287 1:
    288 #endif                                  /*  WITH_SELF_VERIFICATION */
    289 
    290 /*
    291  * No translation, restore interpreter regs and start interpreting.
    292  * rSELF & rFP were preserved in the translated code, and rPC has
    293  * already been restored by the time we get here.  We'll need to set
    294  * up rIBASE & rINST, and load the address of the JitTable into r0.
    295  */
    296 
    297 toInterpreter:
    298     EXPORT_PC()
    299     lw        rIBASE, offThread_curHandlerTable(rSELF)
    300     FETCH_INST()
    301     lw        a0, offThread_pJitProfTable(rSELF)
    302     lw        rIBASE, offThread_curHandlerTable(rSELF)
    303     # NOTE: intended fallthrough
    304 
    305 /*
    306  * Similar to common_updateProfile, but tests for null pJitProfTable
    307  * r0 holds pJifProfTAble, rINST is loaded, rPC is current and
    308  * rIBASE has been recently refreshed.
    309  */
    310 
    311 common_testUpdateProfile:
    312 
    313     beqz      a0, 4f
    314 
    315 /*
    316  * Common code to update potential trace start counter, and initiate
    317  * a trace-build if appropriate.
    318  * On entry here:
    319  *    r0    <= pJitProfTable (verified non-NULL)
    320  *    rPC   <= Dalvik PC
    321  *    rINST <= next instruction
    322  */
    323 common_updateProfile:
    324     srl       a3, rPC, 12                  #  cheap, but fast hash function
    325     xor       a3, a3, rPC
    326     andi      a3, a3, JIT_PROF_SIZE-1      #  eliminate excess bits
    327     addu      t1, a0, a3
    328     lbu       a1, (t1)                     #  get counter
    329     GET_INST_OPCODE(t0)
    330     subu      a1, a1, 1                    #  decrement counter
    331     sb        a1, (t1)                     #  and store it
    332     beqz      a1, 1f
    333     GOTO_OPCODE(t0)                        #  if not threshold, fallthrough otherwise
    334 1:
    335     /* Looks good, reset the counter */
    336     lw        a1, offThread_jitThreshold(rSELF)
    337     sb        a1, (t1)
    338     EXPORT_PC()
    339     move      a0, rPC
    340     move      a1, rSELF
    341     JAL(dvmJitGetTraceAddrThread)          # (pc, self)
    342     move      a0, v0
    343     sw        v0, offThread_inJitCodeCache(rSELF) #  set the inJitCodeCache flag
    344     move      a1, rPC                      #  arg1 of translation may need this
    345     move      ra, zero                     #  in case target is HANDLER_INTERPRET
    346 
    347 #if !defined(WITH_SELF_VERIFICATION)
    348     li        t0, kJitTSelectRequest       #  ask for trace selection
    349     movz      a2, t0, a0
    350     beqz      a0, common_selectTrace
    351     jr        a0                           #  jump to the translation
    352 #else
    353 
    354     bne       a0, zero, skip_ask_for_trace_selection
    355     li        a2, kJitTSelectRequest       #  ask for trace selection
    356     j         common_selectTrace
    357 
    358 skip_ask_for_trace_selection:
    359     /*
    360      * At this point, we have a target translation.  However, if
    361      * that translation is actually the interpret-only pseudo-translation
    362      * we want to treat it the same as no translation.
    363      */
    364     move      rBIX, a0                     #  save target
    365     jal       dvmCompilerGetInterpretTemplate
    366     # special case?
    367     bne       v0, rBIX, jitSVShadowRunStart  #  set up self verification shadow space
    368     # Need to clear the inJitCodeCache flag
    369     sw        zero, offThread_inJitCodeCache(rSELF) #  back to the interp land
    370     GET_INST_OPCODE(t0)
    371     GOTO_OPCODE(t0)
    372     /* no return */
    373 #endif
    374 
    375 /*
    376  * On entry:
    377  *  r2 is jit state.
    378  */
    379 
    380 common_selectTrace:
    381     lhu        a0, offThread_subMode(rSELF)
    382     andi       a0, (kSubModeJitTraceBuild | kSubModeJitSV)
    383     bnez       a0, 3f                      # already doing JIT work, continue
    384     sw         a2, offThread_jitState(rSELF)
    385     move       a0, rSELF
    386 
    387 /*
    388  * Call out to validate trace-building request.  If successful,
    389  * rIBASE will be swapped to to send us into single-stepping trace
    390  * building mode, so we need to refresh before we continue.
    391  */
    392 
    393     EXPORT_PC()
    394     SAVE_PC_TO_SELF()
    395     SAVE_FP_TO_SELF()
    396     JAL(dvmJitCheckTraceRequest)
    397 3:
    398     FETCH_INST()
    399     lw        rIBASE, offThread_curHandlerTable(rSELF)
    400 4:
    401     GET_INST_OPCODE(t0)                    # extract opcode from rINST
    402     GOTO_OPCODE(t0)
    403     /* no return */
    404 #endif
    405 
    406 #if defined(WITH_SELF_VERIFICATION)
    407 
    408 /*
    409  * Save PC and registers to shadow memory for self verification mode
    410  * before jumping to native translation.
    411  * On entry:
    412  *    rPC, rFP, rSELF: the values that they should contain
    413  *    r10: the address of the target translation.
    414  */
    415 jitSVShadowRunStart:
    416     move      a0, rPC                      #  r0 <- program counter
    417     move      a1, rFP                      #  r1 <- frame pointer
    418     move      a2, rSELF                    #  r2 <- InterpState pointer
    419     move      a3, rBIX                     #  r3 <- target translation
    420     jal       dvmSelfVerificationSaveState #  save registers to shadow space
    421     lw        rFP, offShadowSpace_shadowFP(v0) #  rFP <- fp in shadow space
    422     jr        rBIX                         #  jump to the translation
    423 
    424 /*
    425  * Restore PC, registers, and interpState to original values
    426  * before jumping back to the interpreter.
    427  */
    428 jitSVShadowRunEnd:
    429     move      a1, rFP                      #  pass ending fp
    430     move      a3, rSELF                    #  pass self ptr for convenience
    431     jal       dvmSelfVerificationRestoreState #  restore pc and fp values
    432     LOAD_PC_FP_FROM_SELF()                 #  restore pc, fp
    433     lw        a1, offShadowSpace_svState(a0) #  get self verification state
    434     beq       a1, zero, 1f                 #  check for punt condition
    435 
    436     # Setup SV single-stepping
    437     move      a0, rSELF
    438     li        a1, kSubModeJitSV
    439     JAL(dvmEnableSubMode)                  # (self, subMode)
    440     li        a2, kJitSelfVerification     #  ask for self verification
    441     sw        a2, offThread_jitState(rSELF)
    442     # Intentional fallthrough
    443 
    444 1:
    445     # exit to interpreter without check
    446     EXPORT_PC()
    447     lw        rIBASE, offThread_curHandlerTable(rSELF)
    448     FETCH_INST()
    449     GET_INST_OPCODE(t0)
    450     GOTO_OPCODE(t0)
    451 #endif
    452 
    453 /*
    454  * The equivalent of "goto bail", this calls through the "bail handler".
    455  * It will end this interpreter activation, and return to the caller
    456  * of dvmMterpStdRun.
    457  *
    458  * State registers will be saved to the "thread" area before bailing
    459  * debugging purposes
    460  */
    461     .ent common_gotoBail
    462 common_gotoBail:
    463     SAVE_PC_FP_TO_SELF()                   # export state to "thread"
    464     move      a0, rSELF                    # a0 <- self ptr
    465     b         dvmMterpStdBail              # call(self, changeInterp)
    466     .end common_gotoBail
    467 
    468 /*
    469  * The JIT's invoke method needs to remember the callsite class and
    470  * target pair.  Save them here so that they are available to
    471  * dvmCheckJit following the interpretation of this invoke.
    472  */
    473 #if defined(WITH_JIT)
    474 save_callsiteinfo:
    475     beqz    rOBJ, 1f
    476     lw      rOBJ, offObject_clazz(rOBJ)
    477 1:
    478     sw      a0, offThread_methodToCall(rSELF)
    479     sw      rOBJ, offThread_callsiteClass(rSELF)
    480     jr      ra
    481 #endif
    482 
    483 /*
    484  * Common code for method invocation with range.
    485  *
    486  * On entry:
    487  *  a0 is "Method* methodToCall", the method we're trying to call
    488  */
    489 common_invokeMethodRange:
    490 .LinvokeNewRange:
    491 #if defined(WITH_JIT)
    492     lhu      a1, offThread_subMode(rSELF)
    493     andi     a1, kSubModeJitTraceBuild
    494     beqz     a1, 1f
    495     JAL(save_callsiteinfo)
    496 #endif
    497     # prepare to copy args to "outs" area of current frame
    498 1:
    499     GET_OPA(a2)
    500     SAVEAREA_FROM_FP(rBIX, rFP)              #  rBIX <- stack save area
    501     beqz      a2, .LinvokeArgsDone
    502     FETCH(a1, 2)                           #  a1 <- CCCC
    503 .LinvokeRangeArgs:
    504     # a0=methodToCall, a1=CCCC, a2=count, rBIX=outs
    505     # (very few methods have > 10 args; could unroll for common cases)
    506     EAS2(a3, rFP, a1)
    507     sll       t0, a2, 2
    508     subu      rBIX, rBIX, t0
    509 
    510 1:
    511     lw        a1, 0(a3)
    512     addu      a3, a3, 4
    513     subu      a2, a2, 1
    514     sw        a1, 0(rBIX)
    515     addu      rBIX, 4
    516     bnez      a2, 1b
    517     b         .LinvokeArgsDone
    518 
    519 /*
    520  * Common code for method invocation without range.
    521  *
    522  * On entry:
    523  *  a0 is "Method* methodToCall", "rOBJ is this"
    524  */
    525 common_invokeMethodNoRange:
    526 .LinvokeNewNoRange:
    527 #if defined(WITH_JIT)
    528     lhu      a1, offThread_subMode(rSELF)
    529     andi     a1, kSubModeJitTraceBuild
    530     beqz     a1, 1f
    531     JAL(save_callsiteinfo)
    532 #endif
    533 
    534     # prepare to copy args to "outs" area of current frame
    535 1:
    536     GET_OPB(a2)
    537     SAVEAREA_FROM_FP(rBIX, rFP)
    538     beqz      a2, .LinvokeArgsDone
    539     FETCH(a1, 2)
    540 
    541     # a0=methodToCall, a1=GFED, a2=count,
    542 .LinvokeNonRange:
    543     beq       a2, 0, 0f
    544     beq       a2, 1, 1f
    545     beq       a2, 2, 2f
    546     beq       a2, 3, 3f
    547     beq       a2, 4, 4f
    548     beq       a2, 5, 5f
    549 
    550 5:
    551     and       t0, rINST, 0x0f00
    552     ESRN(t2, rFP, t0, 6)
    553     lw        a3, (t2)
    554     subu      rBIX, 4
    555     sw        a3, 0(rBIX)
    556 
    557 4:
    558     and       t0, a1, 0xf000
    559     ESRN(t2, rFP, t0, 10)
    560     lw        a3, (t2)
    561     subu      rBIX, 4
    562     sw        a3, 0(rBIX)
    563 
    564 3:
    565     and       t0, a1, 0x0f00
    566     ESRN(t2, rFP, t0, 6)
    567     lw        a3, (t2)
    568     subu      rBIX, 4
    569     sw        a3, 0(rBIX)
    570 
    571 2:
    572     and       t0, a1, 0x00f0
    573     ESRN(t2, rFP, t0, 2)
    574     lw        a3, (t2)
    575     subu      rBIX, 4
    576     sw        a3, 0(rBIX)
    577 
    578 1:
    579     and       t0, a1, 0x000f
    580     EASN(t2, rFP, t0, 2)
    581     lw        a3, (t2)
    582     subu      rBIX, 4
    583     sw        a3, 0(rBIX)
    584 
    585 0:
    586     #fall through .LinvokeArgsDone
    587 
    588 
    589 .LinvokeArgsDone:                          #  a0=methodToCall
    590     lhu       rOBJ, offMethod_registersSize(a0)
    591     lhu       a3, offMethod_outsSize(a0)
    592     lw        a2, offMethod_insns(a0)
    593     lw        rINST, offMethod_clazz(a0)
    594     # find space for the new stack frame, check for overflow
    595     SAVEAREA_FROM_FP(a1, rFP)              # a1 <- stack save area
    596     sll       t0, rOBJ, 2                    #  a1 <- newFp (old savearea - regsSize)
    597     subu      a1, a1, t0
    598     SAVEAREA_FROM_FP(rBIX, a1)
    599     lw        rOBJ, offThread_interpStackEnd(rSELF) #  t3 <- interpStackEnd
    600     sll       t2, a3, 2
    601     subu      t0, rBIX, t2
    602     lhu       ra, offThread_subMode(rSELF)
    603     lw        a3, offMethod_accessFlags(a0) #  a3 <- methodToCall->accessFlags
    604     bltu      t0, rOBJ, .LstackOverflow      #  yes, this frame will overflow stack
    605 
    606 
    607     # set up newSaveArea
    608 #ifdef EASY_GDB
    609     SAVEAREA_FROM_FP(t0, rFP)
    610     sw        t0, offStackSaveArea_prevSave(rBIX)
    611 #endif
    612     sw        rFP, (offStackSaveArea_prevFrame)(rBIX)
    613     sw        rPC, (offStackSaveArea_savedPc)(rBIX)
    614 #if defined(WITH_JIT)
    615     sw        zero, (offStackSaveArea_returnAddr)(rBIX)
    616 #endif
    617     sw        a0, (offStackSaveArea_method)(rBIX)
    618     # Profiling?
    619     bnez       ra, 2f
    620 1:
    621     and       t2, a3, ACC_NATIVE
    622     bnez      t2, .LinvokeNative
    623     lhu       rOBJ, (a2)           # rOBJ -< load Inst from New PC
    624     lw        a3, offClassObject_pDvmDex(rINST)
    625     move      rPC, a2              # Publish new rPC
    626     # Update state values for the new method
    627     # a0=methodToCall, a1=newFp, a3=newMethodClass, rOBJ=newINST
    628     sw        a0, offThread_method(rSELF)
    629     sw        a3, offThread_methodClassDex(rSELF)
    630     li        a2, 1
    631     sw        a2, offThread_debugIsMethodEntry(rSELF)
    632 
    633 #if defined(WITH_JIT)
    634     lw        a0, offThread_pJitProfTable(rSELF)
    635     move      rFP, a1                    # fp = newFp
    636     GET_PREFETCHED_OPCODE(t0, rOBJ)      # extract prefetched opcode from rOBJ
    637     move      rINST, rOBJ                # publish new rINST
    638     sw        a1, offThread_curFrame(rSELF)
    639     bnez      a0, common_updateProfile
    640     GOTO_OPCODE(t0)
    641 #else
    642     move      rFP, a1
    643     GET_PREFETCHED_OPCODE(t0, rOBJ)
    644     move      rINST, rOBJ
    645     sw        a1, offThread_curFrame(rSELF)
    646     GOTO_OPCODE(t0)
    647 #endif
    648 
    649 2:
    650     # Profiling - record method entry.  a0: methodToCall
    651     STACK_STORE(a0, 0)
    652     STACK_STORE(a1, 4)
    653     STACK_STORE(a2, 8)
    654     STACK_STORE(a3, 12)
    655     sw       rPC, offThread_pc(rSELF)          # update interpSave.pc
    656     move     a1, a0
    657     move     a0, rSELF
    658     JAL(dvmReportInvoke)
    659     STACK_LOAD(a3, 12)                         # restore a0-a3
    660     STACK_LOAD(a2, 8)
    661     STACK_LOAD(a1, 4)
    662     STACK_LOAD(a0, 0)
    663     b        1b
    664 .LinvokeNative:
    665     # Prep for the native call
    666     # a0=methodToCall, a1=newFp, rBIX=newSaveArea
    667     lhu       ra, offThread_subMode(rSELF)
    668     lw        t3, offThread_jniLocal_topCookie(rSELF)
    669     sw        a1, offThread_curFrame(rSELF)
    670     sw        t3, offStackSaveArea_localRefCookie(rBIX) # newFp->localRefCookie=top
    671     move      a2, a0
    672     move      a0, a1
    673     addu      a1, rSELF, offThread_retval
    674     move      a3, rSELF
    675 #ifdef ASSIST_DEBUGGER
    676     /* insert fake function header to help gdb find the stack frame */
    677     b         .Lskip
    678     .ent dalvik_mterp
    679 dalvik_mterp:
    680     STACK_STORE_FULL()
    681 .Lskip:
    682 #endif
    683     bnez      ra, 11f                          # Any special SubModes active?
    684     lw        t9, offMethod_nativeFunc(a2)
    685     jalr      t9
    686     lw        gp, STACK_OFFSET_GP(sp)
    687 7:
    688     # native return; rBIX=newSaveArea
    689     # equivalent to dvmPopJniLocals
    690     lw        a0, offStackSaveArea_localRefCookie(rBIX)
    691     lw        a1, offThread_exception(rSELF)
    692     sw        rFP, offThread_curFrame(rSELF)
    693     sw        a0, offThread_jniLocal_topCookie(rSELF)    # new top <- old top
    694     bnez      a1, common_exceptionThrown
    695 
    696     FETCH_ADVANCE_INST(3)
    697     GET_INST_OPCODE(t0)
    698     GOTO_OPCODE(t0)
    699 11:
    700     # a0=newFp, a1=&retval, a2=methodToCall, a3=self, ra=subModes
    701     SCRATCH_STORE(a0, 0)
    702     SCRATCH_STORE(a1, 4)
    703     SCRATCH_STORE(a2, 8)
    704     SCRATCH_STORE(a3, 12)
    705     move      a0, a2                    # a0 <- methodToCall
    706     move      a1, rSELF
    707     move      a2, rFP
    708     JAL(dvmReportPreNativeInvoke)       # (methodToCall, self, fp)
    709     SCRATCH_LOAD(a3, 12)                         # restore a0-a3
    710     SCRATCH_LOAD(a2, 8)
    711     SCRATCH_LOAD(a1, 4)
    712     SCRATCH_LOAD(a0, 0)
    713 
    714     # Call the native method
    715     lw       t9, offMethod_nativeFunc(a2)      # t9<-methodToCall->nativeFunc
    716     jalr     t9
    717     lw       gp, STACK_OFFSET_GP(sp)
    718 
    719     # Restore the pre-call arguments
    720     SCRATCH_LOAD(a3, 12)                         # restore a0-a3
    721     SCRATCH_LOAD(a2, 8)
    722     SCRATCH_LOAD(a1, 4)
    723     SCRATCH_LOAD(a0, 0)
    724 
    725     # Finish up any post-invoke subMode requirements
    726     move      a0, a2
    727     move      a1, rSELF
    728     move      a2, rFP
    729     JAL(dvmReportPostNativeInvoke)      # (methodToCall, self, fp)
    730     b         7b
    731 
    732 
    733 .LstackOverflow:       # a0=methodToCall
    734     move      a1, a0                    #  a1 <- methodToCall
    735     move      a0, rSELF                 # a0 <- self
    736     JAL(dvmHandleStackOverflow)         #  dvmHandleStackOverflow(self, methodToCall)
    737     b         common_exceptionThrown
    738 #ifdef ASSIST_DEBUGGER
    739     .end dalvik_mterp
    740 #endif
    741 
    742     /*
    743      * Common code for method invocation, calling through "glue code".
    744      *
    745      * TODO: now that we have range and non-range invoke handlers, this
    746      *       needs to be split into two.  Maybe just create entry points
    747      *       that set r9 and jump here?
    748      *
    749      * On entry:
    750      *  r0 is "Method* methodToCall", the method we're trying to call
    751      *  r9 is "bool methodCallRange", indicating if this is a /range variant
    752      */
    753 
    754 /*
    755  * Common code for handling a return instruction.
    756  *
    757  * This does not return.
    758  */
    759 common_returnFromMethod:
    760 .LreturnNew:
    761     lhu       t0, offThread_subMode(rSELF)
    762     SAVEAREA_FROM_FP(a0, rFP)
    763     lw        rOBJ, offStackSaveArea_savedPc(a0) # rOBJ = saveArea->savedPc
    764     bnez      t0, 19f
    765 14:
    766     lw        rFP, offStackSaveArea_prevFrame(a0) # fp = saveArea->prevFrame
    767     lw        a2, (offStackSaveArea_method - sizeofStackSaveArea)(rFP)
    768                                                # a2<- method we're returning to
    769     # is this a break frame?
    770     beqz      a2, common_gotoBail              # break frame, bail out completely
    771 
    772     lw        rBIX, offMethod_clazz(a2)        # rBIX<- method->clazz
    773     lw        rIBASE, offThread_curHandlerTable(rSELF) # refresh rIBASE
    774     PREFETCH_ADVANCE_INST(rINST, rOBJ, 3)      # advance rOBJ, update new rINST
    775     sw        a2, offThread_method(rSELF)      # self->method = newSave->method
    776     lw        a1, offClassObject_pDvmDex(rBIX) # r1<- method->clazz->pDvmDex
    777     sw        rFP, offThread_curFrame(rSELF)   # curFrame = fp
    778 #if defined(WITH_JIT)
    779     lw         rBIX, offStackSaveArea_returnAddr(a0)
    780     move       rPC, rOBJ                       # publish new rPC
    781     sw         a1, offThread_methodClassDex(rSELF)
    782     sw         rBIX, offThread_inJitCodeCache(rSELF) # may return to JIT'ed land
    783     beqz       rBIX, 15f                       # caller is compiled code
    784     move       t9, rBIX
    785     jalr       t9
    786     lw         gp, STACK_OFFSET_GP(sp)
    787 15:
    788     GET_INST_OPCODE(t0)                        # extract opcode from rINST
    789     GOTO_OPCODE(t0)                            # jump to next instruction
    790 #else
    791     GET_INST_OPCODE(t0)                        # extract opcode from rINST
    792     move       rPC, rOBJ                       # publish new rPC
    793     sw         a1, offThread_methodClassDex(rSELF)
    794     GOTO_OPCODE(t0)
    795 #endif
    796 
    797 19:
    798     # Handle special actions
    799     # On entry, a0: StackSaveArea
    800     lw         a1, offStackSaveArea_prevFrame(a0) # a1<- prevFP
    801     sw         rPC, offThread_pc(rSELF)        # update interpSave.pc
    802     sw         a1, offThread_curFrame(rSELF)   # update interpSave.curFrame
    803     move       a0, rSELF
    804     JAL(dvmReportReturn)
    805     SAVEAREA_FROM_FP(a0, rFP)                  # restore StackSaveArea
    806     b          14b
    807 
    808     .if 0
    809     /*
    810      * Return handling, calls through "glue code".
    811      */
    812 .LreturnOld:
    813     SAVE_PC_FP_TO_SELF()                       # export state
    814     move       a0, rSELF                       # arg to function
    815     JAL(dvmMterp_returnFromMethod)
    816     b          common_resumeAfterGlueCall
    817     .endif
    818 
    819 /*
    820  * Somebody has thrown an exception.  Handle it.
    821  *
    822  * If the exception processing code returns to us (instead of falling
    823  * out of the interpreter), continue with whatever the next instruction
    824  * now happens to be.
    825  *
    826  * This does not return.
    827  */
    828     .global dvmMterpCommonExceptionThrown
    829 dvmMterpCommonExceptionThrown:
    830 common_exceptionThrown:
    831 .LexceptionNew:
    832 
    833     EXPORT_PC()
    834     move     a0, rSELF
    835     JAL(dvmCheckSuspendPending)
    836     lw       rOBJ, offThread_exception(rSELF)
    837     move     a1, rSELF
    838     move     a0, rOBJ
    839     JAL(dvmAddTrackedAlloc)
    840     lhu      a2, offThread_subMode(rSELF)
    841     sw       zero, offThread_exception(rSELF)
    842 
    843     # Special subMode?
    844     bnez     a2, 7f                     # any special subMode handling needed?
    845 8:
    846     /* set up args and a local for "&fp" */
    847     sw       rFP, 20(sp)                 #  store rFP => tmp
    848     addu     t0, sp, 20                  #  compute &tmp
    849     sw       t0, STACK_OFFSET_ARG04(sp)  #  save it in arg4 as per ABI
    850     li       a3, 0                       #  a3 <- false
    851     lw       a1, offThread_method(rSELF)
    852     move     a0, rSELF
    853     lw       a1, offMethod_insns(a1)
    854     move     a2, rOBJ
    855     subu     a1, rPC, a1
    856     sra      a1, a1, 1
    857 
    858     /* call, r0 gets catchRelPc (a code-unit offset) */
    859     JAL(dvmFindCatchBlock)           # call(self, relPc, exc, scan?, &fp)
    860     lw        rFP, 20(sp)            # retrieve the updated rFP
    861 
    862     /* update frame pointer and check result from dvmFindCatchBlock */
    863     move      a0, v0
    864     bltz      v0, .LnotCaughtLocally
    865 
    866     /* fix earlier stack overflow if necessary; Preserve a0 */
    867     lbu       a1, offThread_stackOverflowed(rSELF)
    868     beqz      a1, 1f
    869     move      rBIX, a0
    870     move      a0, rSELF
    871     move      a1, rOBJ
    872     JAL(dvmCleanupStackOverflow)
    873     move      a0, rBIX
    874 
    875 1:
    876 
    877 /* adjust locals to match self->interpSave.curFrame and updated PC */
    878     SAVEAREA_FROM_FP(a1, rFP)           # a1<- new save area
    879     lw        a1, offStackSaveArea_method(a1)
    880     sw        a1, offThread_method(rSELF)
    881     lw        a2, offMethod_clazz(a1)
    882     lw        a3, offMethod_insns(a1)
    883     lw        a2, offClassObject_pDvmDex(a2)
    884     EAS1(rPC, a3, a0)
    885     sw        a2, offThread_methodClassDex(rSELF)
    886 
    887     /* release the tracked alloc on the exception */
    888     move      a0, rOBJ
    889     move      a1, rSELF
    890     JAL(dvmReleaseTrackedAlloc)
    891 
    892     /* restore the exception if the handler wants it */
    893     lw        rIBASE, offThread_curHandlerTable(rSELF)
    894     FETCH_INST()
    895     GET_INST_OPCODE(t0)
    896     bne       t0, OP_MOVE_EXCEPTION, 2f
    897     sw        rOBJ, offThread_exception(rSELF)
    898 2:
    899     GOTO_OPCODE(t0)
    900 
    901     # Manage debugger bookkeeping
    902 7:
    903     sw        rPC, offThread_pc(rSELF)
    904     sw        rFP, offThread_curFrame(rSELF)
    905     move      a0, rSELF
    906     move      a1, rOBJ
    907     JAL(dvmReportExceptionThrow)
    908     b         8b
    909 
    910 .LnotCaughtLocally:                     #  rOBJ = exception
    911     /* fix stack overflow if necessary */
    912     lbu       a1, offThread_stackOverflowed(rSELF)
    913     beqz      a1, 3f
    914     move      a0, rSELF
    915     move      a1, rOBJ
    916     JAL(dvmCleanupStackOverflow)           #  dvmCleanupStackOverflow(self, exception)
    917 
    918 3:
    919     # may want to show "not caught locally" debug messages here
    920 #if DVM_SHOW_EXCEPTION >= 2
    921     /* call __android_log_print(prio, tag, format, ...) */
    922     /* "Exception %s from %s:%d not caught locally" */
    923     lw        a0, offThread_method(rSELF)
    924     lw        a1, offMethod_insns(a0)
    925     subu      a1, rPC, a1
    926     sra       a1, a1, 1
    927     JAL(dvmLineNumFromPC)
    928     sw        v0, 20(sp)
    929     # dvmGetMethodSourceFile(method)
    930     lw        a0, offThread_method(rSELF)
    931     JAL(dvmGetMethodSourceFile)
    932     sw        v0, 16(sp)
    933     # exception->clazz->descriptor
    934     lw        a3, offObject_clazz(rOBJ)
    935     lw        a3, offClassObject_descriptor(a3)
    936     la        a2, .LstrExceptionNotCaughtLocally
    937     la        a1, .LstrLogTag
    938     li        a0, 3
    939     JAL(__android_log_print)
    940 #endif
    941     sw        rOBJ, offThread_exception(rSELF)
    942     move      a0, rOBJ
    943     move      a1, rSELF
    944     JAL(dvmReleaseTrackedAlloc)
    945     b         common_gotoBail
    946 
    947     /*
    948      * Exception handling, calls through "glue code".
    949      */
    950     .if     0
    951 .LexceptionOld:
    952     SAVE_PC_TO_SELF()                # export state
    953     SAVE_FP_TO_SELF()
    954     move     a0, rSELF               # arg to function
    955     JAL(dvmMterp_exceptionThrown)
    956     b       common_resumeAfterGlueCall
    957     .endif
    958 
    959 #if defined(WITH_JIT)
    960     /*
    961      * If the JIT is actively building a trace we need to make sure
    962      * that the field is fully resolved before including the current
    963      * instruction.
    964      *
    965      * On entry:
    966      *     rBIX: &dvmDex->pResFields[field]
    967      *     a0:  field pointer (must preserve)
    968      */
    969 common_verifyField:
    970      lhu     a3, offThread_subMode(rSELF)
    971      andi    a3, kSubModeJitTraceBuild
    972      bnez    a3, 1f                 # Not building trace, continue
    973      jr      ra
    974 1:
    975      lw      a1, (rBIX)
    976      beqz    a1, 2f                 # resolution complete ?
    977      jr      ra
    978 2:
    979     SCRATCH_STORE(a0, 0)
    980     SCRATCH_STORE(a1, 4)
    981     SCRATCH_STORE(a2, 8)
    982     SCRATCH_STORE(a3, 12)
    983     SCRATCH_STORE(ra, 16)
    984     move    a0, rSELF
    985     move    a1, rPC
    986     JAL(dvmJitEndTraceSelect)        #(self,pc) end trace before this inst)
    987     SCRATCH_LOAD(a0, 0)
    988     SCRATCH_LOAD(a1, 4)
    989     SCRATCH_LOAD(a2, 8)
    990     SCRATCH_LOAD(a3, 12)
    991     SCRATCH_LOAD(ra, 16)
    992     jr      ra                       # return
    993 #endif
    994 
    995 /*
    996  * After returning from a "glued" function, pull out the updated
    997  * values and start executing at the next instruction.
    998  */
    999 common_resumeAfterGlueCall:
   1000     LOAD_PC_FP_FROM_SELF()           #  pull rPC and rFP out of thread
   1001     lw      rIBASE, offThread_curHandlerTable(rSELF) # refresh
   1002     FETCH_INST()                     #  load rINST from rPC
   1003     GET_INST_OPCODE(t0)              #  extract opcode from rINST
   1004     GOTO_OPCODE(t0)                  #  jump to next instruction
   1005 
   1006 /*
   1007  * Invalid array index. Note that our calling convention is strange; we use a1
   1008  * and a3 because those just happen to be the registers all our callers are
   1009  * using. We move a3 before calling the C function, but a1 happens to match.
   1010  * a1: index
   1011  * a3: size
   1012  */
   1013 common_errArrayIndex:
   1014     EXPORT_PC()
   1015     move      a0, a3
   1016     JAL(dvmThrowArrayIndexOutOfBoundsException)
   1017     b         common_exceptionThrown
   1018 
   1019 /*
   1020  * Integer divide or mod by zero.
   1021  */
   1022 common_errDivideByZero:
   1023     EXPORT_PC()
   1024     la     a0, .LstrDivideByZero
   1025     JAL(dvmThrowArithmeticException)
   1026     b       common_exceptionThrown
   1027 
   1028 /*
   1029  * Attempt to allocate an array with a negative size.
   1030  * On entry: length in a1
   1031  */
   1032 common_errNegativeArraySize:
   1033     EXPORT_PC()
   1034     move    a0, a1                                # arg0 <- len
   1035     JAL(dvmThrowNegativeArraySizeException)    # (len)
   1036     b       common_exceptionThrown
   1037 
   1038 /*
   1039  * Invocation of a non-existent method.
   1040  * On entry: method name in a1
   1041  */
   1042 common_errNoSuchMethod:
   1043     EXPORT_PC()
   1044     move     a0, a1
   1045     JAL(dvmThrowNoSuchMethodError)
   1046     b       common_exceptionThrown
   1047 
   1048 /*
   1049  * We encountered a null object when we weren't expecting one.  We
   1050  * export the PC, throw a NullPointerException, and goto the exception
   1051  * processing code.
   1052  */
   1053 common_errNullObject:
   1054     EXPORT_PC()
   1055     li      a0, 0
   1056     JAL(dvmThrowNullPointerException)
   1057     b       common_exceptionThrown
   1058 
   1059 /*
   1060  * For debugging, cause an immediate fault. The source address will be in ra. Use a jal to jump here.
   1061  */
   1062 common_abort:
   1063     lw      zero,-4(zero)            #  generate SIGSEGV
   1064 
   1065 /*
   1066  * Spit out a "we were here", preserving all registers.
   1067  */
   1068     .macro SQUEAK num
   1069 common_squeak\num:
   1070     STACK_STORE_RA();
   1071     la        a0, .LstrSqueak
   1072     LOAD_IMM(a1, \num);
   1073     JAL(printf);
   1074     STACK_LOAD_RA();
   1075     RETURN;
   1076     .endm
   1077 
   1078     SQUEAK 0
   1079     SQUEAK 1
   1080     SQUEAK 2
   1081     SQUEAK 3
   1082     SQUEAK 4
   1083     SQUEAK 5
   1084 
   1085 /*
   1086  * Spit out the number in a0, preserving registers.
   1087  */
   1088 common_printNum:
   1089     STACK_STORE_RA()
   1090     MOVE_REG(a1, a0)
   1091     la        a0, .LstrSqueak
   1092     JAL(printf)
   1093     STACK_LOAD_RA()
   1094     RETURN
   1095 
   1096 /*
   1097  * Print a newline, preserving registers.
   1098  */
   1099 common_printNewline:
   1100     STACK_STORE_RA()
   1101     la        a0, .LstrNewline
   1102     JAL(printf)
   1103     STACK_LOAD_RA()
   1104     RETURN
   1105 
   1106     /*
   1107      * Print the 32-bit quantity in a0 as a hex value, preserving registers.
   1108      */
   1109 common_printHex:
   1110     STACK_STORE_RA()
   1111     MOVE_REG(a1, a0)
   1112     la        a0, .LstrPrintHex
   1113     JAL(printf)
   1114     STACK_LOAD_RA()
   1115 RETURN;
   1116 
   1117 /*
   1118  * Print the 64-bit quantity in a0-a1, preserving registers.
   1119  */
   1120 common_printLong:
   1121     STACK_STORE_RA()
   1122     MOVE_REG(a3, a1)
   1123     MOVE_REG(a2, a0)
   1124     la        a0, .LstrPrintLong
   1125     JAL(printf)
   1126     STACK_LOAD_RA()
   1127     RETURN;
   1128 
   1129 /*
   1130  * Print full method info.  Pass the Method* in a0.  Preserves regs.
   1131  */
   1132 common_printMethod:
   1133     STACK_STORE_RA()
   1134     JAL(dvmMterpPrintMethod)
   1135     STACK_LOAD_RA()
   1136     RETURN
   1137 
   1138 /*
   1139  * Call a C helper function that dumps regs and possibly some
   1140  * additional info.  Requires the C function to be compiled in.
   1141  */
   1142     .if 0
   1143 common_dumpRegs:
   1144     STACK_STORE_RA()
   1145     JAL(dvmMterpDumpMipsRegs)
   1146     STACK_LOAD_RA()
   1147     RETURN
   1148     .endif
   1149 
   1150 /*
   1151  * Zero-terminated ASCII string data.
   1152  */
   1153     .data
   1154 
   1155 .LstrBadEntryPoint:
   1156     .asciiz "Bad entry point %d\n"
   1157 .LstrDivideByZero:
   1158     .asciiz "divide by zero"
   1159 .LstrFilledNewArrayNotImpl:
   1160     .asciiz "filled-new-array only implemented for 'int'"
   1161 .LstrLogTag:
   1162     .asciiz  "mterp"
   1163 .LstrExceptionNotCaughtLocally:
   1164     .asciiz  "Exception %s from %s:%d not caught locally\n"
   1165 
   1166 .LstrNewline:
   1167     .asciiz "\n"
   1168 .LstrSqueak:
   1169     .asciiz "<%d>"
   1170 .LstrPrintHex:
   1171     .asciiz "<0x%x>"
   1172 .LstrPrintLong:
   1173     .asciiz "<%lld>"
   1174