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 /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */ 14 FETCH(r10, 1) @ r10<- BBBB 15 add r1, rGLUE, #offGlue_retval @ r1<- &glue->retval 16 EXPORT_PC() @ can throw 17 sub sp, sp, #8 @ make room for arg, +64 bit align 18 mov r0, rINST, lsr #12 @ r0<- B 19 str r1, [sp] @ push &glue->retval 20 bl .L${opcode}_continue @ make call; will return after 21 add sp, sp, #8 @ pop stack 22 cmp r0, #0 @ test boolean result of inline 23 beq common_exceptionThrown @ returned false, handle exception 24 FETCH_ADVANCE_INST(3) @ advance rPC, load rINST 25 GET_INST_OPCODE(ip) @ extract opcode from rINST 26 GOTO_OPCODE(ip) @ jump to next instruction 27 %break 28 29 /* 30 * Extract args, call function. 31 * r0 = #of args (0-4) 32 * r10 = call index 33 * lr = return addr, above [DO NOT bl out of here w/o preserving LR] 34 * 35 * Other ideas: 36 * - Use a jump table from the main piece to jump directly into the 37 * AND/LDR pairs. Costs a data load, saves a branch. 38 * - Have five separate pieces that do the loading, so we can work the 39 * interleave a little better. Increases code size. 40 */ 41 .L${opcode}_continue: 42 rsb r0, r0, #4 @ r0<- 4-r0 43 FETCH(r9, 2) @ r9<- FEDC 44 add pc, pc, r0, lsl #3 @ computed goto, 2 instrs each 45 bl common_abort @ (skipped due to ARM prefetch) 46 4: and ip, r9, #0xf000 @ isolate F 47 ldr r3, [rFP, ip, lsr #10] @ r3<- vF (shift right 12, left 2) 48 3: and ip, r9, #0x0f00 @ isolate E 49 ldr r2, [rFP, ip, lsr #6] @ r2<- vE 50 2: and ip, r9, #0x00f0 @ isolate D 51 ldr r1, [rFP, ip, lsr #2] @ r1<- vD 52 1: and ip, r9, #0x000f @ isolate C 53 ldr r0, [rFP, ip, lsl #2] @ r0<- vC 54 0: 55 ldr r9, .L${opcode}_table @ table of InlineOperation 56 LDR_PC "[r9, r10, lsl #4]" @ sizeof=16, "func" is first entry 57 @ (not reached) 58 59 .L${opcode}_table: 60 .word gDvmInlineOpsTable 61