OP_EXECUTE_INLINE_RANGE.S revision a8b91c52fd8a90b784835dfe1f8898035266c4dd
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
484:
49    add       t0, rOBJ, 3
50    GET_VREG(a3, t0)
513:
52    add       t0, rOBJ, 2
53    GET_VREG(a2, t0)
542:
55    add       t0, rOBJ, 1
56    GET_VREG(a1, t0)
571:
58    GET_VREG(a0, rOBJ)
590:
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, 16(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