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 * However, this annoys gcc when optimizations are enabled,
13 * causing a "may be used uninitialized" warning. Quieting
14 * the warnings incurs a slight penalty (5%: 373ns vs. 393ns
15 * on empty method). Note that valgrind is perfectly happy
16 * either way as the uninitialiezd values are never actually
17 * used.
18 */
19 u4 arg0, arg1, arg2, arg3;
20 arg0 = arg1 = arg2 = arg3 = 0;
21
22 EXPORT_PC();
23
24 vsrc1 = INST_B(inst); /* #of args */
25 ref = FETCH(1); /* inline call "ref" */
26 vdst = FETCH(2); /* 0-4 register indices */
27 ILOGV("|execute-inline args=%d @%d {regs=0x%04x}",
28 vsrc1, ref, vdst);
29
30 assert((vdst >> 16) == 0); // 16-bit type -or- high 16 bits clear
31 assert(vsrc1 <= 4);
32
33 switch (vsrc1) {
34 case 4:
35 arg3 = GET_REGISTER(vdst >> 12);
36 /* fall through */
37 case 3:
38 arg2 = GET_REGISTER((vdst & 0x0f00) >> 8);
39 /* fall through */
40 case 2:
41 arg1 = GET_REGISTER((vdst & 0x00f0) >> 4);
42 /* fall through */
43 case 1:
44 arg0 = GET_REGISTER(vdst & 0x0f);
45 /* fall through */
46 default: // case 0
47 ;
48 }
49
50 if (self->interpBreak.ctl.subMode & kSubModeDebugProfile) {
51 if (!dvmPerformInlineOp4Dbg(arg0, arg1, arg2, arg3, &retval, ref))
52 GOTO_exceptionThrown();
53 } else {
54 if (!dvmPerformInlineOp4Std(arg0, arg1, arg2, arg3, &retval, ref))
55 GOTO_exceptionThrown();
56 }
57 }
58 FINISH(3);
59 OP_END
60