1a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /*
2a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * Unwind a frame from the Dalvik stack for compiled OP_RETURN_XXX.
3a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * If the stored value in returnAddr
4a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * is non-zero, the caller is compiled by the JIT thus return to the
5a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * address in the code cache following the invoke instruction. Otherwise
6a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * return to the special dvmJitToInterpNoChain entry point.
7a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     */
8a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(TEMPLATE_INLINE_PROFILING)
9a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    # preserve a0-a2 and ra
10a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    SCRATCH_STORE(a0, 0)
11a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    SCRATCH_STORE(a1, 4)
12a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    SCRATCH_STORE(a2, 8)
13a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    SCRATCH_STORE(ra, 12)
14a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
15a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    # a0=rSELF
16a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    move    a0, rSELF
17a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    la      t9, dvmFastMethodTraceExit
18a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    JALR(t9)
19a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    lw      gp, STACK_OFFSET_GP(sp)
20a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
21a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    # restore a0-a2 and ra
22a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    SCRATCH_LOAD(ra, 12)
23a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    SCRATCH_LOAD(a2, 8)
24a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    SCRATCH_LOAD(a1, 4)
25a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    SCRATCH_LOAD(a0, 0)
26a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
27a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    SAVEAREA_FROM_FP(a0, rFP)           # a0<- saveArea (old)
28a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    lw      t0, offStackSaveArea_prevFrame(a0)     # t0<- saveArea->prevFrame
29a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    lbu     t1, offThread_breakFlags(rSELF)        # t1<- breakFlags
30a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    lw      rPC, offStackSaveArea_savedPc(a0)      # rPC<- saveArea->savedPc
31a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if !defined(WITH_SELF_VERIFICATION)
32a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    lw      t2,  offStackSaveArea_returnAddr(a0)   # t2<- chaining cell ret
33a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#else
34a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    move    t2, zero                               # disable chaining
35a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
36a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    lw      a2, offStackSaveArea_method - sizeofStackSaveArea(t0)
37a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                                   # a2<- method we're returning to
38a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if !defined(WITH_SELF_VERIFICATION)
39a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    beq     a2, zero, 1f                           # bail to interpreter
40a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#else
41a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    bne     a2, zero, 2f
42a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    JALR(ra)                                       # punt to interpreter and compare state
43a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    # DOUG: assume this does not return ???
44a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham2:
45a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
46a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    la      t4, .LdvmJitToInterpNoChainNoProfile   # defined in footer.S
47a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    lw      a1, (t4)
48a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    move    rFP, t0                                # publish new FP
49a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    beq     a2, zero, 4f
50a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    lw      t0, offMethod_clazz(a2)                # t0<- method->clazz
51a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham4:
52a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
53a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    sw      a2, offThread_method(rSELF)            # self->method = newSave->method
54a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    lw      a0, offClassObject_pDvmDex(t0)         # a0<- method->clazz->pDvmDex
55a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    sw      rFP, offThread_curFrame(rSELF)         # self->curFrame = fp
56a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    add     rPC, rPC, 3*2                          # publish new rPC
57a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    sw      a0, offThread_methodClassDex(rSELF)
58a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    movn    t2, zero, t1                           # check the breadFlags and
59a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                                   # clear the chaining cell address
60a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    sw      t2, offThread_inJitCodeCache(rSELF)    # in code cache or not
61a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    beq     t2, zero, 3f                           # chaining cell exists?
62a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    JALR(t2)                                       # jump to the chaining cell
63a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    # DOUG: assume this does not return ???
64a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham3:
65a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_JIT_TUNING)
66a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    li      a0, kCallsiteInterpreted
67a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
68a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    j       a1                                     # callsite is interpreted
69a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham1:
70a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    sw      zero, offThread_inJitCodeCache(rSELF)  # reset inJitCodeCache
71a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    SAVE_PC_TO_SELF()                              # SAVE_PC_FP_TO_SELF()
72a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    SAVE_FP_TO_SELF()
73a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    la      t4, .LdvmMterpStdBail                  # defined in footer.S
74a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    lw      a2, (t4)
75a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    move    a0, rSELF                              # Expecting rSELF in a0
76a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    JALR(a2)                                       # exit the interpreter
77a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    # DOUG: assume this does not return ???
78