1a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%verify "executed" 2a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%verify "exception handled" 3a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 4a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Execute a "native inline" instruction. 5a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 6a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * We need to call an InlineOp4Func: 7a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult) 8a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 9a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * The first four args are in a0-a3, pointer to return value storage 10a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * is on the stack. The function's return value is a flag that tells 11a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * us if an exception was thrown. 12a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 13a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * TUNING: could maintain two tables, pointer in Thread and 14a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * swap if profiler/debuggger active. 15a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 16a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 17a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham lhu a2, offThread_subMode(rSELF) 18a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH(rBIX, 1) # rBIX <- BBBB 19a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham EXPORT_PC() # can throw 20a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham and a2, kSubModeDebugProfile # Any going on? 21a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bnez a2, .L${opcode}_debugmode # yes - take slow path 22a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham.L${opcode}_resume: 23a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham addu a1, rSELF, offThread_retval # a1 <- &self->retval 24a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_OPB(a0) # a0 <- B 25a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham # Stack should have 16/20 available 26a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham sw a1, STACK_OFFSET_ARG04(sp) # push &self->retval 27a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham BAL(.L${opcode}_continue) # make call; will return after 28a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham lw gp, STACK_OFFSET_GP(sp) # restore gp 29a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham # test boolean result of inline 30a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beqz v0, common_exceptionThrown # returned false, handle exception 31a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH_ADVANCE_INST(3) # advance rPC, load rINST 32a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_INST_OPCODE(t0) # extract opcode from rINST 33a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GOTO_OPCODE(t0) # jump to next instruction 34a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%break 35a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 36a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 37a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Extract args, call function. 38a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * a0 = #of args (0-4) 39a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * rBIX = call index 40a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 41a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Other ideas: 42a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * - Use a jump table from the main piece to jump directly into the 43a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * AND/LW pairs. Costs a data load, saves a branch. 44a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * - Have five separate pieces that do the loading, so we can work the 45a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * interleave a little better. Increases code size. 46a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 47a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham.L${opcode}_continue: 48a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH(rINST, 2) # rINST <- FEDC 49a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beq a0, 0, 0f 50a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beq a0, 1, 1f 51a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beq a0, 2, 2f 52a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beq a0, 3, 3f 53a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beq a0, 4, 4f 54a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham JAL(common_abort) # too many arguments 55a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 56a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham4: 57a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham and t0, rINST, 0xf000 # isolate F 58a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham ESRN(t1, rFP, t0, 10) 59a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham lw a3, 0(t1) # a3 <- vF (shift right 12, left 2) 60a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham3: 61a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham and t0, rINST, 0x0f00 # isolate E 62a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham ESRN(t1, rFP, t0, 6) 63a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham lw a2, 0(t1) # a2 <- vE 64a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham2: 65a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham and t0, rINST, 0x00f0 # isolate D 66a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham ESRN(t1, rFP, t0, 2) 67a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham lw a1, 0(t1) # a1 <- vD 68a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham1: 69a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham and t0, rINST, 0x000f # isolate C 70a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham EASN(t1, rFP, t0, 2) 71a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham lw a0, 0(t1) # a0 <- vC 72a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham0: 73a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham la rINST, gDvmInlineOpsTable # table of InlineOperation 74a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham EAS4(t1, rINST, rBIX) # t1 <- rINST + rBIX<<4 75a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham lw t9, 0(t1) 76a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham jr t9 # sizeof=16, "func" is first entry 77a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham # (not reached) 78a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 79a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 80a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * We're debugging or profiling. 81a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * rBIX: opIndex 82a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 83a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham.L${opcode}_debugmode: 84a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a0, rBIX 85a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham JAL(dvmResolveInlineNative) 86a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beqz v0, .L${opcode}_resume # did it resolve? no, just move on 87a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move rOBJ, v0 # remember method 88a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a0, v0 89a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a1, rSELF 90a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham JAL(dvmFastMethodTraceEnter) # (method, self) 91a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham addu a1, rSELF, offThread_retval # a1<- &self->retval 92a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_OPB(a0) # a0 <- B 93a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham # Stack should have 16/20 available 9446abe70f710c3e1b1c2ec1bd7fab35ed833ffba1Douglas Leung sw a1, STACK_OFFSET_ARG04(sp) # push &self->retval 95a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham BAL(.L${opcode}_continue) # make call; will return after 96a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham lw gp, STACK_OFFSET_GP(sp) # restore gp 97a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move rINST, v0 # save result of inline 98a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a0, rOBJ # a0<- method 99a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a1, rSELF # a1<- self 10046abe70f710c3e1b1c2ec1bd7fab35ed833ffba1Douglas Leung JAL(dvmFastNativeMethodTraceExit) # (method, self) 10146abe70f710c3e1b1c2ec1bd7fab35ed833ffba1Douglas Leung beqz rINST, common_exceptionThrown # returned false, handle exception 102a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH_ADVANCE_INST(3) # advance rPC, load rINST 103a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_INST_OPCODE(t0) # extract opcode from rINST 104a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GOTO_OPCODE(t0) # jump to next instruction 105