1%verify "executed"
2%verify "exception handled"
3    /*
4     * Execute a "native inline" instruction.
5     *
6     * We will be calling through a function table:
7     *
8     * (*gDvmInlineOpsTable[opIndex].func)(arg0, arg1, arg2, arg3, pResult)
9     *
10     * Ignores argument count - always loads 4.
11     *
12     */
13    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
14    movl      rSELF,%ecx
15    EXPORT_PC
16    movzwl    2(rPC),%eax               # eax<- BBBB
17    SPILL(rIBASE)                       # preserve rIBASE
18    movl      offThread_subMode(%ecx), %edx # edx<- submode flags
19    andl      $$kSubModeDebugProfile, %edx # debug or profile mode active?
20    jnz       .L${opcode}_debugprofile   # yes, take slow path
21.L${opcode}_resume:
22    leal      offThread_retval(%ecx),%ecx # ecx<- &self->retval
23    movl      %ecx,OUT_ARG4(%esp)
24    call      .L${opcode}_continue      # make call; will return after
25    UNSPILL(rIBASE)                     # restore rIBASE
26    testl     %eax,%eax                 # successful?
27    jz        common_exceptionThrown    # no, handle exception
28    FETCH_INST_OPCODE 3 %ecx
29    ADVANCE_PC 3
30    GOTO_NEXT_R %ecx
31
32.L${opcode}_continue:
33    /*
34     * Extract args, call function.
35     *  ecx = #of args (0-4)
36     *  eax = call index
37     *  @esp = return addr
38     *  esp is -4 from normal
39     *
40     *  Go ahead and load all 4 args, even if not used.
41     */
42    movzwl    4(rPC),rIBASE
43
44    movl      $$0xf,%ecx
45    andl      rIBASE,%ecx
46    GET_VREG_R  %ecx %ecx
47    sarl      $$4,rIBASE
48    movl      %ecx,4+OUT_ARG0(%esp)
49
50    movl      $$0xf,%ecx
51    andl      rIBASE,%ecx
52    GET_VREG_R  %ecx %ecx
53    sarl      $$4,rIBASE
54    movl      %ecx,4+OUT_ARG1(%esp)
55
56    movl      $$0xf,%ecx
57    andl      rIBASE,%ecx
58    GET_VREG_R  %ecx %ecx
59    sarl      $$4,rIBASE
60    movl      %ecx,4+OUT_ARG2(%esp)
61
62    movl      $$0xf,%ecx
63    andl      rIBASE,%ecx
64    GET_VREG_R  %ecx %ecx
65    sarl      $$4,rIBASE
66    movl      %ecx,4+OUT_ARG3(%esp)
67
68    sall      $$4,%eax      # index *= sizeof(table entry)
69    jmp       *gDvmInlineOpsTable(%eax)
70    # will return to caller of .L${opcode}_continue
71
72    /*
73     * We're debugging or profiling.
74     * eax: opIndex
75     */
76.L${opcode}_debugprofile:
77    movl      %eax,OUT_ARG0(%esp)       # arg0<- BBBB
78    SPILL_TMP1(%eax)                    # save opIndex
79    call      dvmResolveInlineNative    # dvmResolveInlineNative(opIndex)
80    movl      rSELF,%ecx                # restore self
81    testl     %eax,%eax                 # method resolved?
82    movl      %eax,%edx                 # save possibly resolved method in edx
83    UNSPILL_TMP1(%eax)                  # in case not resolved, restore opIndex
84    jz        .L${opcode}_resume        # not resolved, just move on
85    SPILL_TMP2(%edx)                    # save method
86    movl      %edx,OUT_ARG0(%esp)       # arg0<- method
87    movl      %ecx,OUT_ARG1(%esp)       # arg1<- self
88    call      dvmFastMethodTraceEnter   # dvmFastMethodTraceEnter(method,self)
89    movl      rSELF,%ecx                # restore self
90    UNSPILL_TMP1(%eax)                  # restore opIndex
91    leal      offThread_retval(%ecx),%ecx # ecx<- &self->retval
92    movl      %ecx,OUT_ARG4(%esp)       # needed for pResult of inline operation handler
93    call      .L${opcode}_continue      # make call; will return after
94    SPILL_TMP1(%eax)                    # save result of inline
95    UNSPILL_TMP2(%eax)                  # restore method
96    movl      rSELF,%ecx                # restore self
97    movl      %eax,OUT_ARG0(%esp)       # arg0<- method
98    movl      %ecx,OUT_ARG1(%esp)       # arg1<- self
99    call      dvmFastNativeMethodTraceExit # dvmFastNativeMethodTraceExit(method,self)
100    UNSPILL(rIBASE)                     # restore rIBASE
101    UNSPILL_TMP1(%eax)                  # restore result of inline
102    testl     %eax,%eax                 # successful?
103    jz        common_exceptionThrown    # no, handle exception
104    FETCH_INST_OPCODE 3 %ecx
105    ADVANCE_PC 3
106    GOTO_NEXT_R %ecx
107