OP_EXECUTE_INLINE.S revision 99e3e6e72e3471eb85fc2e405866392b01c080fe
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 r0-r3, 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    ldrb    r2, [rSELF, #offThread_subMode]
18    FETCH(r10, 1)                       @ r10<- BBBB
19    EXPORT_PC()                         @ can throw
20    ands    r2, #kSubModeDebugProfile   @ Any going on?
21    bne     .L${opcode}_debugmode       @ yes - take slow path
22.L${opcode}_resume:
23    add     r1, rSELF, #offThread_retval  @ r1<- &self->retval
24    sub     sp, sp, #8                  @ make room for arg, +64 bit align
25    mov     r0, rINST, lsr #12          @ r0<- B
26    str     r1, [sp]                    @ push &self->retval
27    bl      .L${opcode}_continue        @ make call; will return after
28    add     sp, sp, #8                  @ pop stack
29    cmp     r0, #0                      @ test boolean result of inline
30    beq     common_exceptionThrown      @ returned false, handle exception
31    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
32    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
33    GOTO_OPCODE(ip)                     @ jump to next instruction
34%break
35
36    /*
37     * Extract args, call function.
38     *  r0 = #of args (0-4)
39     *  r10 = call index
40     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
41     *
42     * Other ideas:
43     * - Use a jump table from the main piece to jump directly into the
44     *   AND/LDR pairs.  Costs a data load, saves a branch.
45     * - Have five separate pieces that do the loading, so we can work the
46     *   interleave a little better.  Increases code size.
47     */
48.L${opcode}_continue:
49    rsb     r0, r0, #4                  @ r0<- 4-r0
50    FETCH(rINST, 2)                     @ rINST<- FEDC
51    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
52    bl      common_abort                @ (skipped due to ARM prefetch)
534:  and     ip, rINST, #0xf000          @ isolate F
54    ldr     r3, [rFP, ip, lsr #10]      @ r3<- vF (shift right 12, left 2)
553:  and     ip, rINST, #0x0f00          @ isolate E
56    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vE
572:  and     ip, rINST, #0x00f0          @ isolate D
58    ldr     r1, [rFP, ip, lsr #2]       @ r1<- vD
591:  and     ip, rINST, #0x000f          @ isolate C
60    ldr     r0, [rFP, ip, lsl #2]       @ r0<- vC
610:
62    ldr     rINST, .L${opcode}_table    @ table of InlineOperation
63    ldr     pc, [rINST, r10, lsl #4]    @ sizeof=16, "func" is first entry
64    @ (not reached)
65
66    /*
67     * We're debugging or profiling.
68     * r10: opIndex
69     */
70.L${opcode}_debugmode:
71    mov     r0, r10
72    bl      dvmResolveInlineNative
73    cmp     r0, #0                      @ did it resolve?
74    beq     .L${opcode}_resume          @ no, just move on
75    mov     r9, r0                      @ remember method
76    mov     r1, rSELF
77    bl      dvmFastMethodTraceEnter     @ (method, self)
78    add     r1, rSELF, #offThread_retval@ r1<- &self->retval
79    sub     sp, sp, #8                  @ make room for arg, +64 bit align
80    mov     r0, rINST, lsr #12          @ r0<- B
81    str     r1, [sp]                    @ push &self->retval
82    bl      .L${opcode}_continue        @ make call; will return after
83    mov     rINST, r0                   @ save result of inline
84    add     sp, sp, #8                  @ pop stack
85    mov     r0, r9                      @ r0<- method
86    mov     r1, rSELF
87    bl      dvmFastNativeMethodTraceExit @ (method, self)
88    cmp     rINST, #0                   @ test boolean result of inline
89    beq     common_exceptionThrown      @ returned false, handle exception
90    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
91    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
92    GOTO_OPCODE(ip)                     @ jump to next instruction
93
94
95
96
97.L${opcode}_table:
98    .word   gDvmInlineOpsTable
99