1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18    .text
19    .global dvmMterpStdRun
20    .type   dvmMterpStdRun, %function
21/*
22 * bool dvmMterpStdRun(MterpGlue* glue)
23 *
24 * Interpreter entry point.  Returns changeInterp.
25 *
26 */
27dvmMterpStdRun:
28    push    %ebp
29    movl    %esp,%ebp
30    push    %edi
31    push    %esi
32    push    %ebx
33
34/* at this point, stack is misaligned by 1 word
35   We're allocating spill space for 6 words, plus
36   outgoing argument (5 words) and local variables
37   (4 words) - 15 words or 60 bytes total. See
38   diagram in header.S
39*/
40    subl   $$60,%esp
41
42/* Set up "named" registers */
43    movl    IN_ARG0(%ebp),%ecx
44    movl    %ecx,rGLUE_SPILL(%ebp)
45    LOAD_PC_FROM_GLUE(%ecx)
46    LOAD_FP_FROM_GLUE(%ecx)
47    movl    $$dvmAsmInstructionStart,rIBASE
48
49/* Remember %esp for future "longjmp" */
50    movl    %esp,offGlue_bailPtr(%ecx)
51
52/* How to start? */
53    movb    offGlue_entryPoint(%ecx),%al
54
55/* Normal start? */
56    cmpb    $$kInterpEntryInstr,%al
57    jne     .Lnot_instr
58
59   /* Normal case: start executing the instruction at rPC */
60    FETCH_INST()
61    GOTO_NEXT
62
63.Lnot_instr:
64    /* Reset to normal case */
65    movb   $$kInterpEntryInstr,offGlue_entryPoint(%ecx)
66    cmpb   $$kInterpEntryReturn,%al
67    je     common_returnFromMethod
68    cmpb   $$kInterpEntryThrow,%al
69    je     common_exceptionThrown
70    movzx  %al,%eax
71    movl   %eax,OUT_ARG1(%esp)
72    movl   $$.LstrBadEntryPoint,OUT_ARG0(%esp)
73    call   printf
74    call   dvmAbort
75    /* Not reached */
76
77
78    .global dvmMterpStdBail
79    .type   dvmMterpStdBail, %function
80/*
81 * void dvmMterpStdBail(MterpGlue* glue, bool changeInterp)
82 *
83 * Restore the stack pointer and PC from the save point established on entry.
84 * This is essentially the same as a longjmp, but should be cheaper.  The
85 * last instruction causes us to return to whoever called dvmMterpStdRun.
86 *
87 * We're not going to build a standard frame here, so the arg accesses will
88 * look a little strange.
89 *
90 * On entry:
91 *  esp+4 (arg0)  MterpGlue* glue
92 *  esp+8 (arg1)  bool changeInterp
93 */
94dvmMterpStdBail:
95    movl    4(%esp),%ecx                 # grab glue
96    movl    8(%esp),%eax                 # changeInterp to return reg
97    movl    offGlue_bailPtr(%ecx),%esp   # Stack back to normal
98    addl    $$60,%esp                    # Strip dvmMterpStdRun's frame
99    pop     %ebx
100    pop     %esi
101    pop     %edi
102    pop     %ebp
103    ret                                  # return to dvmMterpStdRun's caller
104
105
106/*
107 * Strings
108 */
109    .section    .rodata
110.LstrBadEntryPoint:
111    .asciz  "Bad entry point %d\n"
112