1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "executed"
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "exception handled"
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Execute a "native inline" instruction.
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
6b0a0541b59d1126ff77c88de742b4a74579fe296Andy McFadden     * We need to call an InlineOp4Func:
7b0a0541b59d1126ff77c88de742b4a74579fe296Andy McFadden     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
9b0a0541b59d1126ff77c88de742b4a74579fe296Andy McFadden     * The first four args are in r0-r3, pointer to return value storage
10b0a0541b59d1126ff77c88de742b4a74579fe296Andy McFadden     * is on the stack.  The function's return value is a flag that tells
11b0a0541b59d1126ff77c88de742b4a74579fe296Andy McFadden     * us if an exception was thrown.
129a3147c7412f4794434b4c2604aa2ba784867774buzbee     *
139a3147c7412f4794434b4c2604aa2ba784867774buzbee     * TUNING: could maintain two tables, pointer in Thread and
149a3147c7412f4794434b4c2604aa2ba784867774buzbee     * swap if profiler/debuggger active.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
17389e258a5b9b2afb7bfaee3344c615d3310fae4ebuzbee    ldrh    r2, [rSELF, #offThread_subMode]
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FETCH(r10, 1)                       @ r10<- BBBB
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    EXPORT_PC()                         @ can throw
209a3147c7412f4794434b4c2604aa2ba784867774buzbee    ands    r2, #kSubModeDebugProfile   @ Any going on?
219a3147c7412f4794434b4c2604aa2ba784867774buzbee    bne     .L${opcode}_debugmode       @ yes - take slow path
229a3147c7412f4794434b4c2604aa2ba784867774buzbee.L${opcode}_resume:
239a3147c7412f4794434b4c2604aa2ba784867774buzbee    add     r1, rSELF, #offThread_retval  @ r1<- &self->retval
24b0a0541b59d1126ff77c88de742b4a74579fe296Andy McFadden    sub     sp, sp, #8                  @ make room for arg, +64 bit align
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r0, rINST, lsr #12          @ r0<- B
269f601a917c8878204482c37aec7005054b6776fabuzbee    str     r1, [sp]                    @ push &self->retval
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bl      .L${opcode}_continue        @ make call; will return after
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    add     sp, sp, #8                  @ pop stack
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmp     r0, #0                      @ test boolean result of inline
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    beq     common_exceptionThrown      @ returned false, handle exception
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GOTO_OPCODE(ip)                     @ jump to next instruction
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%break
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Extract args, call function.
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  r0 = #of args (0-4)
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  r10 = call index
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Other ideas:
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * - Use a jump table from the main piece to jump directly into the
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *   AND/LDR pairs.  Costs a data load, saves a branch.
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * - Have five separate pieces that do the loading, so we can work the
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *   interleave a little better.  Increases code size.
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_continue:
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    rsb     r0, r0, #4                  @ r0<- 4-r0
5099e3e6e72e3471eb85fc2e405866392b01c080febuzbee    FETCH(rINST, 2)                     @ rINST<- FEDC
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bl      common_abort                @ (skipped due to ARM prefetch)
5399e3e6e72e3471eb85fc2e405866392b01c080febuzbee4:  and     ip, rINST, #0xf000          @ isolate F
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ldr     r3, [rFP, ip, lsr #10]      @ r3<- vF (shift right 12, left 2)
5599e3e6e72e3471eb85fc2e405866392b01c080febuzbee3:  and     ip, rINST, #0x0f00          @ isolate E
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vE
5799e3e6e72e3471eb85fc2e405866392b01c080febuzbee2:  and     ip, rINST, #0x00f0          @ isolate D
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ldr     r1, [rFP, ip, lsr #2]       @ r1<- vD
5999e3e6e72e3471eb85fc2e405866392b01c080febuzbee1:  and     ip, rINST, #0x000f          @ isolate C
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ldr     r0, [rFP, ip, lsl #2]       @ r0<- vC
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project0:
6299e3e6e72e3471eb85fc2e405866392b01c080febuzbee    ldr     rINST, .L${opcode}_table    @ table of InlineOperation
635dfcc78af479937ba8dafceefd9b1931a88dfaafArd Biesheuvel5:  add     rINST, pc
6499e3e6e72e3471eb85fc2e405866392b01c080febuzbee    ldr     pc, [rINST, r10, lsl #4]    @ sizeof=16, "func" is first entry
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @ (not reached)
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
679a3147c7412f4794434b4c2604aa2ba784867774buzbee    /*
689a3147c7412f4794434b4c2604aa2ba784867774buzbee     * We're debugging or profiling.
699a3147c7412f4794434b4c2604aa2ba784867774buzbee     * r10: opIndex
709a3147c7412f4794434b4c2604aa2ba784867774buzbee     */
719a3147c7412f4794434b4c2604aa2ba784867774buzbee.L${opcode}_debugmode:
729a3147c7412f4794434b4c2604aa2ba784867774buzbee    mov     r0, r10
739a3147c7412f4794434b4c2604aa2ba784867774buzbee    bl      dvmResolveInlineNative
749a3147c7412f4794434b4c2604aa2ba784867774buzbee    cmp     r0, #0                      @ did it resolve?
759a3147c7412f4794434b4c2604aa2ba784867774buzbee    beq     .L${opcode}_resume          @ no, just move on
7699e3e6e72e3471eb85fc2e405866392b01c080febuzbee    mov     r9, r0                      @ remember method
779a3147c7412f4794434b4c2604aa2ba784867774buzbee    mov     r1, rSELF
789a3147c7412f4794434b4c2604aa2ba784867774buzbee    bl      dvmFastMethodTraceEnter     @ (method, self)
799a3147c7412f4794434b4c2604aa2ba784867774buzbee    add     r1, rSELF, #offThread_retval@ r1<- &self->retval
809a3147c7412f4794434b4c2604aa2ba784867774buzbee    sub     sp, sp, #8                  @ make room for arg, +64 bit align
819a3147c7412f4794434b4c2604aa2ba784867774buzbee    mov     r0, rINST, lsr #12          @ r0<- B
829a3147c7412f4794434b4c2604aa2ba784867774buzbee    str     r1, [sp]                    @ push &self->retval
839a3147c7412f4794434b4c2604aa2ba784867774buzbee    bl      .L${opcode}_continue        @ make call; will return after
8499e3e6e72e3471eb85fc2e405866392b01c080febuzbee    mov     rINST, r0                   @ save result of inline
859a3147c7412f4794434b4c2604aa2ba784867774buzbee    add     sp, sp, #8                  @ pop stack
8699e3e6e72e3471eb85fc2e405866392b01c080febuzbee    mov     r0, r9                      @ r0<- method
879a3147c7412f4794434b4c2604aa2ba784867774buzbee    mov     r1, rSELF
8899e3e6e72e3471eb85fc2e405866392b01c080febuzbee    bl      dvmFastNativeMethodTraceExit @ (method, self)
8999e3e6e72e3471eb85fc2e405866392b01c080febuzbee    cmp     rINST, #0                   @ test boolean result of inline
9099e3e6e72e3471eb85fc2e405866392b01c080febuzbee    beq     common_exceptionThrown      @ returned false, handle exception
919a3147c7412f4794434b4c2604aa2ba784867774buzbee    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
929a3147c7412f4794434b4c2604aa2ba784867774buzbee    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
939a3147c7412f4794434b4c2604aa2ba784867774buzbee    GOTO_OPCODE(ip)                     @ jump to next instruction
949a3147c7412f4794434b4c2604aa2ba784867774buzbee
959a3147c7412f4794434b4c2604aa2ba784867774buzbee
969a3147c7412f4794434b4c2604aa2ba784867774buzbee
979a3147c7412f4794434b4c2604aa2ba784867774buzbee
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_table:
995dfcc78af479937ba8dafceefd9b1931a88dfaafArd Biesheuvel    .word   PCREL_REF(gDvmInlineOpsTable,5b)
100