Home | History | Annotate | Download | only in mips
      1 %verify "executed"
      2 %verify "exception handled"
      3     /*
      4      * Execute a "native inline" instruction.
      5      *
      6      * We need to call an InlineOp4Func:
      7      *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
      8      *
      9      * The first four args are in a0-a3, pointer to return value storage
     10      * is on the stack.  The function's return value is a flag that tells
     11      * us if an exception was thrown.
     12      *
     13      * TUNING: could maintain two tables, pointer in Thread and
     14      * swap if profiler/debuggger active.
     15      */
     16     /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
     17     lhu       a2, offThread_subMode(rSELF)
     18     FETCH(rBIX, 1)                         #  rBIX <- BBBB
     19     EXPORT_PC()                            #  can throw
     20     and       a2, kSubModeDebugProfile     #  Any going on?
     21     bnez      a2, .L${opcode}_debugmode    #  yes - take slow path
     22 .L${opcode}_resume:
     23     addu      a1, rSELF, offThread_retval  #  a1 <- &self->retval
     24     GET_OPB(a0)                            #  a0 <- B
     25     # Stack should have 16/20 available
     26     sw        a1, STACK_OFFSET_ARG04(sp)   #  push &self->retval
     27     BAL(.L${opcode}_continue)              #  make call; will return after
     28     lw        gp, STACK_OFFSET_GP(sp)      #  restore gp
     29     # test boolean result of inline
     30     beqz      v0, common_exceptionThrown   #  returned false, handle exception
     31     FETCH_ADVANCE_INST(3)                  #  advance rPC, load rINST
     32     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
     33     GOTO_OPCODE(t0)                        #  jump to next instruction
     34 %break
     35 
     36     /*
     37      * Extract args, call function.
     38      *  a0 = #of args (0-4)
     39      *  rBIX = call index
     40      *
     41      * Other ideas:
     42      * - Use a jump table from the main piece to jump directly into the
     43      *   AND/LW pairs.  Costs a data load, saves a branch.
     44      * - Have five separate pieces that do the loading, so we can work the
     45      *   interleave a little better.  Increases code size.
     46      */
     47 .L${opcode}_continue:
     48     FETCH(rINST, 2)                        #  rINST <- FEDC
     49     beq       a0, 0, 0f
     50     beq       a0, 1, 1f
     51     beq       a0, 2, 2f
     52     beq       a0, 3, 3f
     53     beq       a0, 4, 4f
     54     JAL(common_abort)                      #  too many arguments
     55 
     56 4:
     57     and       t0, rINST, 0xf000            #  isolate F
     58     ESRN(t1, rFP, t0, 10)
     59     lw        a3, 0(t1)                    #  a3 <- vF (shift right 12, left 2)
     60 3:
     61     and       t0, rINST, 0x0f00            #  isolate E
     62     ESRN(t1, rFP, t0, 6)
     63     lw        a2, 0(t1)                    #  a2 <- vE
     64 2:
     65     and       t0, rINST, 0x00f0            #  isolate D
     66     ESRN(t1, rFP, t0, 2)
     67     lw        a1, 0(t1)                    #  a1 <- vD
     68 1:
     69     and       t0, rINST, 0x000f            #  isolate C
     70     EASN(t1, rFP, t0, 2)
     71     lw        a0, 0(t1)                    #  a0 <- vC
     72 0:
     73     la        rINST, gDvmInlineOpsTable    #  table of InlineOperation
     74     EAS4(t1, rINST, rBIX)                  #  t1 <- rINST + rBIX<<4
     75     lw        t9, 0(t1)
     76     jr        t9                           #  sizeof=16, "func" is first entry
     77     # (not reached)
     78 
     79     /*
     80      * We're debugging or profiling.
     81      * rBIX: opIndex
     82      */
     83 .L${opcode}_debugmode:
     84     move      a0, rBIX
     85     JAL(dvmResolveInlineNative)
     86     beqz      v0, .L${opcode}_resume       #  did it resolve? no, just move on
     87     move      rOBJ, v0                     #  remember method
     88     move      a0, v0
     89     move      a1, rSELF
     90     JAL(dvmFastMethodTraceEnter)           #  (method, self)
     91     addu      a1, rSELF, offThread_retval  #  a1<- &self->retval
     92     GET_OPB(a0)                            #  a0 <- B
     93     # Stack should have 16/20 available
     94     sw        a1, STACK_OFFSET_ARG04(sp)   #  push &self->retval
     95     BAL(.L${opcode}_continue)              #  make call; will return after
     96     lw        gp, STACK_OFFSET_GP(sp)      #  restore gp
     97     move      rINST, v0                    #  save result of inline
     98     move      a0, rOBJ                     #  a0<- method
     99     move      a1, rSELF                    #  a1<- self
    100     JAL(dvmFastNativeMethodTraceExit)      #  (method, self)
    101     beqz      rINST, common_exceptionThrown   #  returned false, handle exception
    102     FETCH_ADVANCE_INST(3)                  #  advance rPC, load rINST
    103     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
    104     GOTO_OPCODE(t0)                        #  jump to next instruction
    105