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