1 %verify "executed" 2 %verify "exception handled" 3 /* 4 * Execute a "native inline" instruction, using "/range" semantics. 5 * Same idea as execute-inline, but we get the args differently. 6 * 7 * We need to call an InlineOp4Func: 8 * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 9 * 10 * The first four args are in r0-r3, pointer to return value storage 11 * is on the stack. The function's return value is a flag that tells 12 * us if an exception was thrown. 13 */ 14 /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */ 15 ldrh r2, [rSELF, #offThread_subMode] 16 FETCH(r10, 1) @ r10<- BBBB 17 EXPORT_PC() @ can throw 18 ands r2, #kSubModeDebugProfile @ Any going on? 19 bne .L${opcode}_debugmode @ yes - take slow path 20 .L${opcode}_resume: 21 add r1, rSELF, #offThread_retval @ r1<- &self->retval 22 sub sp, sp, #8 @ make room for arg, +64 bit align 23 mov r0, rINST, lsr #8 @ r0<- AA 24 str r1, [sp] @ push &self->retval 25 bl .L${opcode}_continue @ make call; will return after 26 add sp, sp, #8 @ pop stack 27 cmp r0, #0 @ test boolean result of inline 28 beq common_exceptionThrown @ returned false, handle exception 29 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 30 GET_INST_OPCODE(ip) @ extract opcode from rINST 31 GOTO_OPCODE(ip) @ jump to next instruction 32 %break 33 34 /* 35 * Extract args, call function. 36 * r0 = #of args (0-4) 37 * r10 = call index 38 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 39 */ 40 .L${opcode}_continue: 41 rsb r0, r0, #4 @ r0<- 4-r0 42 FETCH(r9, 2) @ r9<- CCCC 43 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 44 bl common_abort @ (skipped due to ARM prefetch) 45 4: add ip, r9, #3 @ base+3 46 GET_VREG(r3, ip) @ r3<- vBase[3] 47 3: add ip, r9, #2 @ base+2 48 GET_VREG(r2, ip) @ r2<- vBase[2] 49 2: add ip, r9, #1 @ base+1 50 GET_VREG(r1, ip) @ r1<- vBase[1] 51 1: add ip, r9, #0 @ (nop) 52 GET_VREG(r0, ip) @ r0<- vBase[0] 53 0: 54 ldr r9, .L${opcode}_table @ table of InlineOperation 55 5: add r9, pc 56 ldr pc, [r9, r10, lsl #4] @ sizeof=16, "func" is first entry 57 @ (not reached) 58 59 60 /* 61 * We're debugging or profiling. 62 * r10: opIndex 63 */ 64 .L${opcode}_debugmode: 65 mov r0, r10 66 bl dvmResolveInlineNative 67 cmp r0, #0 @ did it resolve? 68 beq .L${opcode}_resume @ no, just move on 69 mov r9, r0 @ remember method 70 mov r1, rSELF 71 bl dvmFastMethodTraceEnter @ (method, self) 72 add r1, rSELF, #offThread_retval@ r1<- &self->retval 73 sub sp, sp, #8 @ make room for arg, +64 bit align 74 mov r0, rINST, lsr #8 @ r0<- B 75 mov rINST, r9 @ rINST<- method 76 str r1, [sp] @ push &self->retval 77 bl .L${opcode}_continue @ make call; will return after 78 mov r9, r0 @ save result of inline 79 add sp, sp, #8 @ pop stack 80 mov r0, rINST @ r0<- method 81 mov r1, rSELF 82 bl dvmFastNativeMethodTraceExit @ (method, self) 83 cmp r9, #0 @ test boolean result of inline 84 beq common_exceptionThrown @ returned false, handle exception 85 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 86 GET_INST_OPCODE(ip) @ extract opcode from rINST 87 GOTO_OPCODE(ip) @ jump to next instruction 88 89 90 91 92 .L${opcode}_table: 93 .word PCREL_REF(gDvmInlineOpsTable,5b) 94 95