blob: f97d6a5d8b87e60aadf03ce0885e45a48bc7e89e [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(Thread* self)
*
* Interpreter entry point. Returns changeInterp.
*
*/
dvmMterpStdRun:
push %ebp # save caller base pointer
movl %esp, %ebp # set our %ebp
movl rSELF, %ecx # get incoming rSELF
/*
* At this point we've allocated one slot on the stack
* via push and stack is 8-byte aligned. Allocate space
* for 9 spill slots, 4 local slots, 5 arg slots to bring
* us to 16-byte alignment
*/
subl $$(FRAME_SIZE-4), %esp
/* Spill callee save regs */
movl %edi,EDI_SPILL(%ebp)
movl %esi,ESI_SPILL(%ebp)
movl %ebx,EBX_SPILL(%ebp)
/* Set up "named" registers */
movl offThread_pc(%ecx),rPC
movl offThread_curFrame(%ecx),rFP
movl offThread_curHandlerTable(%ecx),rIBASE
/* Remember %esp for future "longjmp" */
movl %esp,offThread_bailPtr(%ecx)
/* Fetch next instruction before potential jump */
FETCH_INST
#if defined(WITH_JIT)
GET_JIT_PROF_TABLE %ecx %eax
movl $$0, offThread_inJitCodeCache(%ecx)
cmpl $$0, %eax
jne common_updateProfile # set up %ebx & %edx & rPC
#endif
/* Normal case: start executing the instruction at rPC */
GOTO_NEXT
.global dvmMterpStdBail
.type dvmMterpStdBail, %function
/*
* void dvmMterpStdBail(Thread* self, 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) Thread* self
* esp+8 (arg1) bool changeInterp
*/
dvmMterpStdBail:
movl 4(%esp),%ecx # grab self
movl 8(%esp),%eax # changeInterp to return reg
movl offThread_bailPtr(%ecx),%esp # Restore "setjmp" esp
movl %esp,%ebp
addl $$(FRAME_SIZE-4), %ebp # Restore %ebp at point of setjmp
movl EDI_SPILL(%ebp),%edi
movl ESI_SPILL(%ebp),%esi
movl EBX_SPILL(%ebp),%ebx
movl %ebp, %esp # strip frame
pop %ebp # restore caller's ebp
ret # return to dvmMterpStdRun's caller
#ifdef WITH_JIT
.global dvmNcgInvokeInterpreter
.type dvmNcgInvokeInterpreter, %function
/* input: start of method in %eax */
dvmNcgInvokeInterpreter:
movl %eax, rPC
movl rSELF, %ecx
movl offThread_curHandlerTable(%ecx),rIBASE
FETCH_INST_R %ecx # %edx<- opcode
GOTO_NEXT_R %ecx # start executing the instruction at rPC
#endif
/*
* Strings
*/
.section .rodata
.LstrBadEntryPoint:
.asciz "Bad entry point %d\n"