mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
185 lines
5.1 KiB
ArmAsm
185 lines
5.1 KiB
ArmAsm
/* Copyright (c) 2008-2015, Avian Contributors
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
for any purpose with or without fee is hereby granted, provided
|
|
that the above copyright notice and this permission notice appear
|
|
in all copies.
|
|
|
|
There is NO WARRANTY for this software. See license.txt for
|
|
details. */
|
|
|
|
#ifdef __x86_64__
|
|
|
|
#define CONTINUATION_NEXT 8
|
|
#define CONTINUATION_ADDRESS 32
|
|
#define CONTINUATION_RETURN_ADDRESS_OFFSET 40
|
|
#define CONTINUATION_FRAME_POINTER_OFFSET 48
|
|
#define CONTINUATION_LENGTH 56
|
|
#define CONTINUATION_BODY 64
|
|
|
|
// call the next continuation, if any
|
|
movq TARGET_THREAD_CONTINUATION(%rbx),%rcx
|
|
cmpq $0,%rcx
|
|
je LOCAL(vmInvoke_exit)
|
|
|
|
// allocate a frame of size (continuation.length * BYTES_PER_WORD)
|
|
// + CALLEE_SAVED_REGISTER_FOOTPRINT
|
|
movq CONTINUATION_LENGTH(%rcx),%rsi
|
|
shlq $3,%rsi
|
|
subq %rsi,%rsp
|
|
subq $CALLEE_SAVED_REGISTER_FOOTPRINT,%rsp
|
|
|
|
// copy the continuation body into the frame
|
|
leaq CONTINUATION_BODY(%rcx),%rdi
|
|
|
|
movq $0,%r9
|
|
jmp LOCAL(vmInvoke_continuationTest)
|
|
|
|
LOCAL(vmInvoke_continuationLoop):
|
|
movq (%rdi,%r9,1),%r8
|
|
movq %r8,(%rsp,%r9,1)
|
|
addq $8,%r9
|
|
|
|
LOCAL(vmInvoke_continuationTest):
|
|
cmpq %rsi,%r9
|
|
jb LOCAL(vmInvoke_continuationLoop)
|
|
|
|
// set the return address to vmInvoke_returnAddress
|
|
movq CONTINUATION_RETURN_ADDRESS_OFFSET(%rcx),%rdi
|
|
#if defined __MINGW32__ || defined __CYGWIN32__
|
|
leaq GLOBAL(vmInvoke_returnAddress)(%rip),%r10
|
|
#else
|
|
movq GLOBAL(vmInvoke_returnAddress)@GOTPCREL(%rip),%r10
|
|
#endif
|
|
movq %r10,(%rsp,%rdi,1)
|
|
|
|
#ifdef AVIAN_USE_FRAME_POINTER
|
|
// save the current base pointer in the frame and update it
|
|
movq CONTINUATION_FRAME_POINTER_OFFSET(%rcx),%rdi
|
|
movq %rbp,(%rsp,%rdi,1)
|
|
addq %rsp,%rdi
|
|
movq %rdi,%rbp
|
|
#endif
|
|
|
|
// consume the continuation
|
|
movq CONTINUATION_NEXT(%rcx),%rdi
|
|
movq %rdi,TARGET_THREAD_CONTINUATION(%rbx)
|
|
|
|
// call the continuation unless we're handling an exception
|
|
movq TARGET_THREAD_EXCEPTION(%rbx),%rsi
|
|
cmpq $0,%rsi
|
|
jne LOCAL(vmInvoke_handleException)
|
|
jmp *CONTINUATION_ADDRESS(%rcx)
|
|
|
|
LOCAL(vmInvoke_handleException):
|
|
// we're handling an exception - call the exception handler instead
|
|
movq $0,TARGET_THREAD_EXCEPTION(%rbx)
|
|
movq TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT(%rbx),%rdi
|
|
subq %rdi,%rsp
|
|
movq TARGET_THREAD_EXCEPTIONOFFSET(%rbx),%rdi
|
|
movq %rsi,(%rsp,%rdi,1)
|
|
|
|
jmp *TARGET_THREAD_EXCEPTIONHANDLER(%rbx)
|
|
|
|
LOCAL(vmInvoke_exit):
|
|
|
|
#elif defined __i386__
|
|
|
|
#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
|
|
|
|
#ifdef AVIAN_USE_FRAME_POINTER
|
|
# define CONTINUATION_ALIGNMENT_PADDING 8
|
|
#else
|
|
# define CONTINUATION_ALIGNMENT_PADDING 12
|
|
#endif
|
|
|
|
// call the next continuation, if any
|
|
movl TARGET_THREAD_CONTINUATION(%ebx),%ecx
|
|
cmpl $0,%ecx
|
|
je LOCAL(vmInvoke_exit)
|
|
|
|
// allocate a frame of size (continuation.length * BYTES_PER_WORD),
|
|
// plus stack alignment padding
|
|
movl CONTINUATION_LENGTH(%ecx),%esi
|
|
shll $2,%esi
|
|
leal CONTINUATION_ALIGNMENT_PADDING(%esi),%esi
|
|
subl %esi,%esp
|
|
|
|
// copy the continuation body into the frame
|
|
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,8(%esp,%edx,1)
|
|
addl $4,%edx
|
|
|
|
LOCAL(vmInvoke_continuationTest):
|
|
cmpl %esi,%edx
|
|
jb LOCAL(vmInvoke_continuationLoop)
|
|
|
|
pop %edx
|
|
pop %eax
|
|
|
|
// set the return address to vmInvoke_returnAddress
|
|
movl CONTINUATION_RETURN_ADDRESS_OFFSET(%ecx),%edi
|
|
#if defined __MINGW32__ || defined __CYGWIN32__
|
|
movl $GLOBAL(vmInvoke_returnAddress),%esi
|
|
#else
|
|
call LOCAL(getPC)
|
|
# if defined __APPLE__
|
|
LOCAL(vmInvoke_offset):
|
|
leal GLOBAL(vmInvoke_returnAddress)-LOCAL(vmInvoke_offset)(%esi),%esi
|
|
# else
|
|
addl $_GLOBAL_OFFSET_TABLE_,%esi
|
|
movl GLOBAL(vmInvoke_returnAddress)@GOT(%esi),%esi
|
|
# endif
|
|
#endif
|
|
movl %esi,(%esp,%edi,1)
|
|
|
|
#ifdef AVIAN_USE_FRAME_POINTER
|
|
// save the current base pointer in the frame and update it
|
|
movl CONTINUATION_FRAME_POINTER_OFFSET(%ecx),%edi
|
|
movl %ebp,(%esp,%edi,1)
|
|
addl %esp,%edi
|
|
movl %edi,%ebp
|
|
#endif
|
|
|
|
// consume the continuation
|
|
movl CONTINUATION_NEXT(%ecx),%edi
|
|
movl %edi,TARGET_THREAD_CONTINUATION(%ebx)
|
|
|
|
// call the continuation unless we're handling an exception
|
|
movl TARGET_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,TARGET_THREAD_EXCEPTION(%ebx)
|
|
movl TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT(%ebx),%edi
|
|
subl %edi,%esp
|
|
movl TARGET_THREAD_EXCEPTIONOFFSET(%ebx),%edi
|
|
movl %esi,(%esp,%edi,1)
|
|
|
|
jmp *TARGET_THREAD_EXCEPTIONHANDLER(%ebx)
|
|
|
|
LOCAL(vmInvoke_exit):
|
|
|
|
#else
|
|
# error unsupported architecture
|
|
#endif
|
|
|