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