/* * 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"