1%default { "isrange":"0", "routine":"NoRange" }
2%verify "executed"
3%verify "unknown method"
4    /*
5     * Handle a direct method call.
6     *
7     * (We could defer the "is 'this' pointer null" test to the common
8     * method invocation code, and use a flag to indicate that static
9     * calls don't count.  If we do this as part of copying the arguments
10     * out we could avoiding loading the first arg twice.)
11     *
12     * for: invoke-direct, invoke-direct/range
13     */
14    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
15    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
16    movl      rSELF,%ecx
17    movzwl    2(rPC),%eax              # eax<- BBBB
18    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
19    EXPORT_PC
20    movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
21    movzwl    4(rPC),rIBASE            # rIBASE<- GFED or CCCC
22    movl      (%ecx,%eax,4),%eax       # eax<- resolved methodToCall
23    .if       (!$isrange)
24    andl      $$0xf,rIBASE             # rIBASE<- D (or stays CCCC)
25    .endif
26    testl     %eax,%eax                # already resolved?
27    GET_VREG_R  %ecx rIBASE            # ecx<- "this" ptr
28    je        .L${opcode}_resolve      # not resolved, do it now
29.L${opcode}_finish:
30    testl     %ecx,%ecx                # null "this"?
31    jne       common_invokeMethod${routine}  # no, continue on
32    jmp       common_errNullObject
33
34    /*
35     * On entry:
36     *   TMP_SPILL  <- "this" register
37     * Things a bit ugly on this path, but it's the less
38     * frequent one.  We'll have to do some reloading.
39     */
40.L${opcode}_resolve:
41     SPILL_TMP1(%ecx)
42     movl     rSELF,%ecx
43     movl     offThread_method(%ecx),%ecx  # ecx<- self->method
44     movzwl   2(rPC),%eax      # reference (BBBB or CCCC)
45     movl     offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
46     movl     $$METHOD_DIRECT,OUT_ARG2(%esp)
47     movl     %eax,OUT_ARG1(%esp)
48     movl     %ecx,OUT_ARG0(%esp)
49     call     dvmResolveMethod # eax<- call(clazz, ref, flags)
50     UNSPILL_TMP1(%ecx)
51     testl    %eax,%eax
52     jne      .L${opcode}_finish
53     jmp      common_exceptionThrown
54