Home | History | Annotate | Download | only in mips
      1 %verify "executed"
      2 %verify "exception handled"
      3     /*
      4      * Execute a "native inline" instruction, using "/range" semantics.
      5      * Same idea as execute-inline, but we get the args differently.
      6      *
      7      * We need to call an InlineOp4Func:
      8      *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
      9      *
     10      * The first four args are in a0-a3, pointer to return value storage
     11      * is on the stack.  The function's return value is a flag that tells
     12      * us if an exception was thrown.
     13      */
     14     /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */
     15     lhu       a2, offThread_subMode(rSELF)
     16     FETCH(rBIX, 1)                       # rBIX<- BBBB
     17     EXPORT_PC()                          # can throw
     18     and       a2, kSubModeDebugProfile   # Any going on?
     19     bnez      a2, .L${opcode}_debugmode  # yes - take slow path
     20 .L${opcode}_resume:
     21     addu      a1, rSELF, offThread_retval # a1<- &self->retval
     22     GET_OPA(a0)
     23     sw        a1, STACK_OFFSET_ARG04(sp)  # push &self->retval
     24     BAL(.L${opcode}_continue)             # make call; will return after
     25     lw        gp, STACK_OFFSET_GP(sp)     #  restore gp
     26     beqz      v0, common_exceptionThrown  # returned false, handle exception
     27     FETCH_ADVANCE_INST(3)                 # advance rPC, load rINST
     28     GET_INST_OPCODE(t0)                   # extract opcode from rINST
     29     GOTO_OPCODE(t0)                       # jump to next instruction
     30 
     31 %break
     32 
     33     /*
     34      * Extract args, call function.
     35      *  a0 = #of args (0-4)
     36      *  rBIX = call index
     37      *  ra = return addr, above  [DO NOT JAL out of here w/o preserving ra]
     38      */
     39 .L${opcode}_continue:
     40     FETCH(rOBJ, 2)                       # rOBJ <- CCCC
     41     beq       a0, 0, 0f
     42     beq       a0, 1, 1f
     43     beq       a0, 2, 2f
     44     beq       a0, 3, 3f
     45     beq       a0, 4, 4f
     46     JAL(common_abort)                      #  too many arguments
     47 
     48 4:
     49     add       t0, rOBJ, 3
     50     GET_VREG(a3, t0)
     51 3:
     52     add       t0, rOBJ, 2
     53     GET_VREG(a2, t0)
     54 2:
     55     add       t0, rOBJ, 1
     56     GET_VREG(a1, t0)
     57 1:
     58     GET_VREG(a0, rOBJ)
     59 0:
     60     la        rOBJ, gDvmInlineOpsTable      # table of InlineOperation
     61     EAS4(t1, rOBJ, rBIX)                    # t1 <- rINST + rBIX<<4
     62     lw        t9, 0(t1)
     63     jr        t9                            # sizeof=16, "func" is first entry
     64     # not reached
     65 
     66     /*
     67      * We're debugging or profiling.
     68      * rBIX: opIndex
     69      */
     70 .L${opcode}_debugmode:
     71     move      a0, rBIX
     72     JAL(dvmResolveInlineNative)
     73     beqz      v0, .L${opcode}_resume       #  did it resolve? no, just move on
     74     move      rOBJ, v0                     #  remember method
     75     move      a0, v0
     76     move      a1, rSELF
     77     JAL(dvmFastMethodTraceEnter)           #  (method, self)
     78     addu      a1, rSELF, offThread_retval  #  a1<- &self->retval
     79     GET_OPA(a0)                            #  a0 <- A
     80     # Stack should have 16/20 available
     81     sw        a1, STACK_OFFSET_ARG04(sp)   #  push &self->retval
     82     move      rINST, rOBJ                  #  rINST<- method
     83     BAL(.L${opcode}_continue)              #  make call; will return after
     84     lw        gp, STACK_OFFSET_GP(sp)      #  restore gp
     85     move      rOBJ, v0                     #  save result of inline
     86     move      a0, rINST                    #  a0<- method
     87     move      a1, rSELF                    #  a1<- self
     88     JAL(dvmFastNativeMethodTraceExit)      #  (method, self)
     89     beqz      rOBJ, common_exceptionThrown #  returned false, handle exception
     90     FETCH_ADVANCE_INST(3)                  #  advance rPC, load rINST
     91     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
     92     GOTO_OPCODE(t0)                        #  jump to next instruction
     93