add continuation support to 32-bit section of compile-x86.S

This commit is contained in:
Joel Dice 2009-05-24 00:32:49 -06:00
parent 18ec68c7b7
commit 9dbea21ec4

View File

@ -153,6 +153,10 @@ vmJumpAndInvoke:
// %rcx: stack // %rcx: stack
// %r8 : argumentFootprint // %r8 : argumentFootprint
// %r9 : arguments // %r9 : arguments
movq %rdi,%rbx
movq %rdx,%rbp
movq %rcx,%rsp
// set return address // set return address
movq vmInvoke_returnAddress@GOTPCREL(%rip),%r10 movq vmInvoke_returnAddress@GOTPCREL(%rip),%r10
@ -163,29 +167,38 @@ vmJumpAndInvoke:
jmp LOCAL(vmJumpAndInvoke_argumentTest) jmp LOCAL(vmJumpAndInvoke_argumentTest)
LOCAL(vmJumpAndInvoke_argumentLoop): LOCAL(vmJumpAndInvoke_argumentLoop):
movq (%r8,%r11,1),%r10 movq (%r9,%r11,1),%r10
movq %r10,8(%rsp,%r11,1) movq %r10,8(%rsp,%r11,1)
addq $8,%r11 addq $8,%r11
LOCAL(vmJumpAndInvoke_argumentTest): LOCAL(vmJumpAndInvoke_argumentTest):
cmpq %r8,%r11 cmpq %r8,%r11
jb LOCAL(vmJumpAndInvoke_argumentLoop) jb LOCAL(vmJumpAndInvoke_argumentLoop)
movq %rdi,%rbx
movq %rdx,%rbp
movq %rcx,%rsp
jmp *%rsi jmp *%rsi
#elif defined __i386__ #elif defined __i386__
#define THREAD_CONTINUATION 96
#define THREAD_EXCEPTION 36
#define THREAD_EXCEPTION_STACK 100
#define THREAD_EXCEPTION_OFFSET 104
#define THREAD_EXCEPTION_HANDLER 108
# if defined __APPLE__ || defined __MINGW32__ || defined __CYGWIN32__ #define CONTINUATION_NEXT 4
#define CONTINUATION_ADDRESS 16
#define CONTINUATION_RETURN_ADDRESS_OFFSET 20
#define CONTINUATION_FRAME_POINTER_OFFSET 24
#define CONTINUATION_LENGTH 28
#define CONTINUATION_BODY 32
#if defined __APPLE__ || defined __MINGW32__ || defined __CYGWIN32__
.globl _vmInvoke .globl _vmInvoke
_vmInvoke: _vmInvoke:
# else #else
.globl vmInvoke .globl vmInvoke
vmInvoke: vmInvoke:
# endif #endif
pushl %ebp pushl %ebp
movl %esp,%ebp movl %esp,%ebp
@ -214,25 +227,89 @@ vmInvoke:
// copy arguments into place // copy arguments into place
movl $0,%ecx movl $0,%ecx
movl 16(%ebp),%edx movl 16(%ebp),%edx
jmp LOCAL(test) jmp LOCAL(vmInvoke_argumentTest)
LOCAL(loop): LOCAL(vmInvoke_argumentLoop):
movl (%edx,%ecx,1),%eax movl (%edx,%ecx,1),%eax
movl %eax,(%esp,%ecx,1) movl %eax,(%esp,%ecx,1)
addl $4,%ecx addl $4,%ecx
LOCAL(test): LOCAL(vmInvoke_argumentTest):
cmpl 20(%ebp),%ecx cmpl 20(%ebp),%ecx
jb LOCAL(loop) jb LOCAL(vmInvoke_argumentLoop)
// call function // call function
call *12(%ebp) call *12(%ebp)
.globl vmInvoke_returnAddress
vmInvoke_returnAddress:
// restore stack pointer and callee-saved registers // restore stack pointer and callee-saved registers
movl %ebp,%ecx movl %ebp,%ecx
subl $16,%ecx subl $16,%ecx
movl %ecx,%esp movl %ecx,%esp
// call the next continuation, if any
movl THREAD_CONTINUATION(%ebx),%ecx
cmpl $0,%ecx
je LOCAL(vmInvoke_exit)
movl CONTINUATION_LENGTH(%ecx),%esi
shll $3,%esi
subl %esi,%esp
subl $48,%esp
leal CONTINUATION_BODY(%ecx),%edi
push %eax
push %edx
movl $0,%edx
jmp LOCAL(vmInvoke_continuationTest)
LOCAL(vmInvoke_continuationLoop):
movl (%edi,%edx,1),%eax
movl %eax,(%esp,%edx,1)
addl $8,%edx
LOCAL(vmInvoke_continuationTest):
cmpl %esi,%edx
jb LOCAL(vmInvoke_continuationLoop)
pop %edx
pop %eax
movl CONTINUATION_RETURN_ADDRESS_OFFSET(%ecx),%edi
call LOCAL(getPC)
addl $_GLOBAL_OFFSET_TABLE_,%esi
movl vmInvoke_returnAddress@GOT(%esi),%esi
movl %esi,(%esp,%edi,1)
movl CONTINUATION_FRAME_POINTER_OFFSET(%ecx),%edi
movl %ebp,(%esp,%edi,1)
addl %esp,%edi
movl %edi,%ebp
movl CONTINUATION_NEXT(%ecx),%edi
movl %edi,THREAD_CONTINUATION(%ebx)
// call the continuation unless we're handling an exception
movl THREAD_EXCEPTION(%ebx),%esi
cmpl $0,%esi
jne LOCAL(vmInvoke_handleException)
jmp *CONTINUATION_ADDRESS(%ecx)
LOCAL(vmInvoke_handleException):
// we're handling an exception - call the exception handler instead
movl $0,THREAD_EXCEPTION(%ebx)
movl THREAD_EXCEPTION_STACK(%ebx),%esp
movl THREAD_EXCEPTION_OFFSET(%ebx),%edi
movl %esi,(%esp,%edi,1)
jmp *THREAD_EXCEPTION_HANDLER(%ebx)
LOCAL(vmInvoke_exit):
// restore callee-saved registers
movl 0(%esp),%ebx movl 0(%esp),%ebx
movl 4(%esp),%esi movl 4(%esp),%esi
movl 8(%esp),%edi movl 8(%esp),%edi
@ -242,22 +319,64 @@ LOCAL(test):
addl $16,%esp addl $16,%esp
LOCAL(void): LOCAL(vmInvoke_void):
cmpl $VOID_TYPE,%ecx cmpl $VOID_TYPE,%ecx
jne LOCAL(int64) jne LOCAL(vmInvoke_int64)
jmp LOCAL(exit) jmp LOCAL(vmInvoke_return)
LOCAL(int64): LOCAL(vmInvoke_int64):
cmpl $INT64_TYPE,%ecx cmpl $INT64_TYPE,%ecx
jne LOCAL(int32) jne LOCAL(vmInvoke_int32)
jmp LOCAL(exit) jmp LOCAL(vmInvoke_return)
LOCAL(int32): LOCAL(vmInvoke_int32):
movl $0,%edx movl $0,%edx
LOCAL(exit): LOCAL(vmInvoke_return):
popl %ebp popl %ebp
ret ret
LOCAL(getPC):
movl (%esp),%esi
ret
.globl vmJumpAndInvoke
vmJumpAndInvoke:
// 8(%ebp): thread
// 12(%ebp): address
// 16(%ebp): base
// 20(%ebp): stack
// 24(%ebp): argumentFootprint
// 28(%ebp): arguments
movl 8(%ebp),%ebx
movl 20(%ebp),%esp
// set return address
call LOCAL(getPC)
addl $_GLOBAL_OFFSET_TABLE_,%esi
movl vmInvoke_returnAddress@GOT(%esi),%esi
movl %esi,(%esp)
// copy arguments into place
movl $0,%ecx
movl 24(%ebp),%esi
movl 28(%ebp),%eax
jmp LOCAL(vmJumpAndInvoke_argumentTest)
LOCAL(vmJumpAndInvoke_argumentLoop):
movl (%eax,%ecx,1),%edx
movl %edx,8(%esp,%ecx,1)
addl $8,%ecx
LOCAL(vmJumpAndInvoke_argumentTest):
cmpl %esi,%ecx
jb LOCAL(vmJumpAndInvoke_argumentLoop)
movl 12(%ebp),%esi
movl 16(%ebp),%ebp
jmp *%esi
#else #else
# error unsupported platform # error unsupported platform