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 a0-a3, 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 lhu a2, offThread_subMode(rSELF) 16 FETCH(rBIX, 1) # rBIX<- BBBB 17 EXPORT_PC() # can throw 18 and a2, kSubModeDebugProfile # Any going on? 19 bnez a2, .L${opcode}_debugmode # yes - take slow path 20 .L${opcode}_resume: 21 addu a1, rSELF, offThread_retval # a1<- &self->retval 22 GET_OPA(a0) 23 sw a1, STACK_OFFSET_ARG04(sp) # push &self->retval 24 BAL(.L${opcode}_continue) # make call; will return after 25 lw gp, STACK_OFFSET_GP(sp) # restore gp 26 beqz v0, common_exceptionThrown # returned false, handle exception 27 FETCH_ADVANCE_INST(3) # advance rPC, load rINST 28 GET_INST_OPCODE(t0) # extract opcode from rINST 29 GOTO_OPCODE(t0) # jump to next instruction 30 31 %break 32 33 /* 34 * Extract args, call function. 35 * a0 = #of args (0-4) 36 * rBIX = call index 37 * ra = return addr, above [DO NOT JAL out of here w/o preserving ra] 38 */ 39 .L${opcode}_continue: 40 FETCH(rOBJ, 2) # rOBJ <- CCCC 41 beq a0, 0, 0f 42 beq a0, 1, 1f 43 beq a0, 2, 2f 44 beq a0, 3, 3f 45 beq a0, 4, 4f 46 JAL(common_abort) # too many arguments 47 48 4: 49 add t0, rOBJ, 3 50 GET_VREG(a3, t0) 51 3: 52 add t0, rOBJ, 2 53 GET_VREG(a2, t0) 54 2: 55 add t0, rOBJ, 1 56 GET_VREG(a1, t0) 57 1: 58 GET_VREG(a0, rOBJ) 59 0: 60 la rOBJ, gDvmInlineOpsTable # table of InlineOperation 61 EAS4(t1, rOBJ, rBIX) # t1 <- rINST + rBIX<<4 62 lw t9, 0(t1) 63 jr t9 # sizeof=16, "func" is first entry 64 # not reached 65 66 /* 67 * We're debugging or profiling. 68 * rBIX: opIndex 69 */ 70 .L${opcode}_debugmode: 71 move a0, rBIX 72 JAL(dvmResolveInlineNative) 73 beqz v0, .L${opcode}_resume # did it resolve? no, just move on 74 move rOBJ, v0 # remember method 75 move a0, v0 76 move a1, rSELF 77 JAL(dvmFastMethodTraceEnter) # (method, self) 78 addu a1, rSELF, offThread_retval # a1<- &self->retval 79 GET_OPA(a0) # a0 <- A 80 # Stack should have 16/20 available 81 sw a1, STACK_OFFSET_ARG04(sp) # push &self->retval 82 move rINST, rOBJ # rINST<- method 83 BAL(.L${opcode}_continue) # make call; will return after 84 lw gp, STACK_OFFSET_GP(sp) # restore gp 85 move rOBJ, v0 # save result of inline 86 move a0, rINST # a0<- method 87 move a1, rSELF # a1<- self 88 JAL(dvmFastNativeMethodTraceExit) # (method, self) 89 beqz rOBJ, common_exceptionThrown # returned false, handle exception 90 FETCH_ADVANCE_INST(3) # advance rPC, load rINST 91 GET_INST_OPCODE(t0) # extract opcode from rINST 92 GOTO_OPCODE(t0) # jump to next instruction 93