1a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%verify "executed" 2a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%verify "exception handled" 3a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 4a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Execute a "native inline" instruction, using "/range" semantics. 5a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Same idea as execute-inline, but we get the args differently. 6a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 7a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * We need to call an InlineOp4Func: 8a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 9a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 10a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * The first four args are in a0-a3, pointer to return value storage 11a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * is on the stack. The function's return value is a flag that tells 12a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * us if an exception was thrown. 13a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 14a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */ 15a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham lhu a2, offThread_subMode(rSELF) 16a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH(rBIX, 1) # rBIX<- BBBB 17a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham EXPORT_PC() # can throw 18a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham and a2, kSubModeDebugProfile # Any going on? 19a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bnez a2, .L${opcode}_debugmode # yes - take slow path 20a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham.L${opcode}_resume: 21a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham addu a1, rSELF, offThread_retval # a1<- &self->retval 22a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_OPA(a0) 23a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham sw a1, STACK_OFFSET_ARG04(sp) # push &self->retval 24a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham BAL(.L${opcode}_continue) # make call; will return after 25a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham lw gp, STACK_OFFSET_GP(sp) # restore gp 26a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beqz v0, common_exceptionThrown # returned false, handle exception 27a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH_ADVANCE_INST(3) # advance rPC, load rINST 28a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_INST_OPCODE(t0) # extract opcode from rINST 29a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GOTO_OPCODE(t0) # jump to next instruction 30a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 31a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%break 32a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 33a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 34a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Extract args, call function. 35a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * a0 = #of args (0-4) 36a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * rBIX = call index 37a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * ra = return addr, above [DO NOT JAL out of here w/o preserving ra] 38a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 39a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham.L${opcode}_continue: 40a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH(rOBJ, 2) # rOBJ <- CCCC 41a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beq a0, 0, 0f 42a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beq a0, 1, 1f 43a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beq a0, 2, 2f 44a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beq a0, 3, 3f 45a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beq a0, 4, 4f 46a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham JAL(common_abort) # too many arguments 47a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 48a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham4: 49a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham add t0, rOBJ, 3 50a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_VREG(a3, t0) 51a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham3: 52a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham add t0, rOBJ, 2 53a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_VREG(a2, t0) 54a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham2: 55a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham add t0, rOBJ, 1 56a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_VREG(a1, t0) 57a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham1: 58a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_VREG(a0, rOBJ) 59a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham0: 60a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham la rOBJ, gDvmInlineOpsTable # table of InlineOperation 61a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham EAS4(t1, rOBJ, rBIX) # t1 <- rINST + rBIX<<4 62a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham lw t9, 0(t1) 63a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham jr t9 # sizeof=16, "func" is first entry 64a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham # not reached 65a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 66a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 67a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * We're debugging or profiling. 68a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * rBIX: opIndex 69a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 70a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham.L${opcode}_debugmode: 71a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a0, rBIX 72a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham JAL(dvmResolveInlineNative) 73a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beqz v0, .L${opcode}_resume # did it resolve? no, just move on 74a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move rOBJ, v0 # remember method 75a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a0, v0 76a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a1, rSELF 77a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham JAL(dvmFastMethodTraceEnter) # (method, self) 78a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham addu a1, rSELF, offThread_retval # a1<- &self->retval 79a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_OPA(a0) # a0 <- A 80a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham # Stack should have 16/20 available 8146abe70f710c3e1b1c2ec1bd7fab35ed833ffba1Douglas Leung sw a1, STACK_OFFSET_ARG04(sp) # push &self->retval 82a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move rINST, rOBJ # rINST<- method 83a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham BAL(.L${opcode}_continue) # make call; will return after 84a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham lw gp, STACK_OFFSET_GP(sp) # restore gp 85a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move rOBJ, v0 # save result of inline 86a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a0, rINST # a0<- method 87a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a1, rSELF # a1<- self 88a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham JAL(dvmFastNativeMethodTraceExit) # (method, self) 89a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beqz rOBJ, common_exceptionThrown # returned false, handle exception 90a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH_ADVANCE_INST(3) # advance rPC, load rINST 91a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_INST_OPCODE(t0) # extract opcode from rINST 92a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GOTO_OPCODE(t0) # jump to next instruction 93