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