HANDLE_OPCODE(OP_EXECUTE_INLINE)1 HANDLE_OPCODE(OP_EXECUTE_INLINE /*vB, {vD, vE, vF, vG}, inline@CCCC*/)
2 {
3 /*
4 * This has the same form as other method calls, but we ignore
5 * the 5th argument (vA). This is chiefly because the first four
6 * arguments to a function on ARM are in registers.
7 *
8 * We only set the arguments that are actually used, leaving
9 * the rest uninitialized. We're assuming that, if the method
10 * needs them, they'll be specified in the call.
11 *
12 * This annoys gcc when optimizations are enabled, causing a
13 * "may be used uninitialized" warning. We can quiet the warnings
14 * for a slight penalty (5%: 373ns vs. 393ns on empty method). Note
15 * that valgrind is perfectly happy with this arrangement, because
16 * the uninitialiezd values are never actually used.
17 */
18 u4 arg0, arg1, arg2, arg3;
19 //arg0 = arg1 = arg2 = arg3 = 0;
20
21 EXPORT_PC();
22
23 vsrc1 = INST_B(inst); /* #of args */
24 ref = FETCH(1); /* inline call "ref" */
25 vdst = FETCH(2); /* 0-4 register indices */
26 ILOGV("|execute-inline args=%d @%d {regs=0x%04x}",
27 vsrc1, ref, vdst);
28
29 assert((vdst >> 16) == 0); // 16-bit type -or- high 16 bits clear
30 assert(vsrc1 <= 4);
31
32 switch (vsrc1) {
33 case 4:
34 arg3 = GET_REGISTER(vdst >> 12);
35 /* fall through */
36 case 3:
37 arg2 = GET_REGISTER((vdst & 0x0f00) >> 8);
38 /* fall through */
39 case 2:
40 arg1 = GET_REGISTER((vdst & 0x00f0) >> 4);
41 /* fall through */
42 case 1:
43 arg0 = GET_REGISTER(vdst & 0x0f);
44 /* fall through */
45 default: // case 0
46 ;
47 }
48
49 #if INTERP_TYPE == INTERP_DBG
50 if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref))
51 GOTO_exceptionThrown();
52 #else
53 if (!dvmPerformInlineOp4Std(arg0, arg1, arg2, arg3, &retval, ref))
54 GOTO_exceptionThrown();
55 #endif
56 }
57 FINISH(3);
58 OP_END
59