blob: ff310fe2902cb19eec7b4e9c92e13a095620f89b [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.text
.global dvmMterpStdRun
.type dvmMterpStdRun, %function
/*
* bool dvmMterpStdRun(MterpGlue* glue)
*
* Interpreter entry point. Returns changeInterp.
*
*/
dvmMterpStdRun:
push %ebp
movl %esp,%ebp
push %edi
push %esi
push %ebx
/* at this point, stack is misaligned by 1 word
We're allocating spill space for 6 words, plus
outgoing argument (5 words) and local variables
(4 words) - 15 words or 60 bytes total. See
diagram in header.S
*/
subl $$60,%esp
/* Set up "named" registers */
movl IN_ARG0(%ebp),%ecx
movl %ecx,rGLUE_SPILL(%ebp)
LOAD_PC_FROM_GLUE(%ecx)
LOAD_FP_FROM_GLUE(%ecx)
movl $$dvmAsmInstructionStart,rIBASE
/* Remember %esp for future "longjmp" */
movl %esp,offGlue_bailPtr(%ecx)
/* How to start? */
movb offGlue_entryPoint(%ecx),%al
/* Normal start? */
cmpb $$kInterpEntryInstr,%al
jne .Lnot_instr
/* Normal case: start executing the instruction at rPC */
FETCH_INST()
GOTO_NEXT
.Lnot_instr:
/* Reset to normal case */
movb $$kInterpEntryInstr,offGlue_entryPoint(%ecx)
cmpb $$kInterpEntryReturn,%al
je common_returnFromMethod
cmpb $$kInterpEntryThrow,%al
je common_exceptionThrown
movzx %al,%eax
movl %eax,OUT_ARG1(%esp)
movl $$.LstrBadEntryPoint,OUT_ARG0(%esp)
call printf
call dvmAbort
/* Not reached */
.global dvmMterpStdBail
.type dvmMterpStdBail, %function
/*
* void dvmMterpStdBail(MterpGlue* glue, bool changeInterp)
*
* Restore the stack pointer and PC from the save point established on entry.
* This is essentially the same as a longjmp, but should be cheaper. The
* last instruction causes us to return to whoever called dvmMterpStdRun.
*
* We're not going to build a standard frame here, so the arg accesses will
* look a little strange.
*
* On entry:
* esp+4 (arg0) MterpGlue* glue
* esp+8 (arg1) bool changeInterp
*/
dvmMterpStdBail:
movl 4(%esp),%ecx # grab glue
movl 8(%esp),%eax # changeInterp to return reg
movl offGlue_bailPtr(%ecx),%esp # Stack back to normal
addl $$60,%esp # Strip dvmMterpStdRun's frame
pop %ebx
pop %esi
pop %edi
pop %ebp
ret # return to dvmMterpStdRun's caller
/*
* Strings
*/
.section .rodata
.LstrBadEntryPoint:
.asciz "Bad entry point %d\n"