mirror of
https://github.com/corda/corda.git
synced 2025-03-12 15:34:58 +00:00
implement continuations support for ARM
This commit is contained in:
parent
36a8ba28e5
commit
0f0427f23b
@ -8,17 +8,13 @@
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
#ifdef AVIAN_CONTINUATIONS
|
||||
# error "Continuations not yet supported on ARM port"
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
|
||||
.text
|
||||
|
||||
#define BYTES_PER_WORD 4
|
||||
|
||||
#define LOCAL(x) L##x
|
||||
#define LOCAL(x) .L##x
|
||||
|
||||
#ifdef __APPLE__
|
||||
# define GLOBAL(x) _##x
|
||||
@ -33,6 +29,15 @@
|
||||
#define THREAD_EXCEPTION_OFFSET 2156
|
||||
#define THREAD_EXCEPTION_HANDLER 2160
|
||||
|
||||
#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
|
||||
|
||||
#define ARGUMENT_BASE (BYTES_PER_WORD * 2)
|
||||
|
||||
.globl GLOBAL(vmInvoke)
|
||||
GLOBAL(vmInvoke):
|
||||
/*
|
||||
@ -83,12 +88,8 @@ LOCAL(vmInvoke_argumentTest):
|
||||
// we use r8 to hold the thread pointer, by convention
|
||||
mov r8, r0
|
||||
|
||||
.global GLOBAL(beforecall)
|
||||
GLOBAL(beforecall):
|
||||
// load and call function address
|
||||
blx r1
|
||||
.global GLOBAL(aftercall)
|
||||
GLOBAL(aftercall):
|
||||
|
||||
.globl GLOBAL(vmInvoke_returnAddress)
|
||||
GLOBAL(vmInvoke_returnAddress):
|
||||
@ -99,6 +100,75 @@ GLOBAL(vmInvoke_returnAddress):
|
||||
.globl GLOBAL(vmInvoke_safeStack)
|
||||
GLOBAL(vmInvoke_safeStack):
|
||||
|
||||
#ifdef AVIAN_CONTINUATIONS
|
||||
// call the next continuation, if any
|
||||
ldr r5,[r8,#THREAD_CONTINUATION]
|
||||
cmp r5,#0
|
||||
beq LOCAL(vmInvoke_exit)
|
||||
|
||||
ldr r6,[r5,#CONTINUATION_LENGTH]
|
||||
lsl r6,r6,#2
|
||||
neg r7,r6
|
||||
add r7,r7,#-80
|
||||
mov r4,sp
|
||||
str r4,[sp,r7]!
|
||||
|
||||
add r7,r5,#CONTINUATION_BODY
|
||||
|
||||
mov r11,#0
|
||||
add r10,sp,#ARGUMENT_BASE
|
||||
b LOCAL(vmInvoke_continuationTest)
|
||||
|
||||
LOCAL(vmInvoke_continuationLoop):
|
||||
ldr r9,[r7,r11]
|
||||
str r9,[r10,r11]
|
||||
add r11,r11,#4
|
||||
|
||||
LOCAL(vmInvoke_continuationTest):
|
||||
cmp r11,r6
|
||||
ble LOCAL(vmInvoke_continuationLoop)
|
||||
|
||||
ldr r7,[r5,#CONTINUATION_RETURN_ADDRESS_OFFSET]
|
||||
ldr r10,LOCAL(vmInvoke_returnAddress_word)
|
||||
ldr r11,LOCAL(vmInvoke_getAddress_word)
|
||||
LOCAL(vmInvoke_getAddress):
|
||||
add r11,pc,r11
|
||||
ldr r11,[r11,r10]
|
||||
str r11,[sp,r7]
|
||||
|
||||
ldr r7,[r5,#CONTINUATION_FRAME_POINTER_OFFSET]
|
||||
ldr r11,[sp]
|
||||
add r7,r7,sp
|
||||
str r11,[r7]
|
||||
str r7,[sp]
|
||||
|
||||
ldr r7,[r5,#CONTINUATION_NEXT]
|
||||
str r7,[r8,#THREAD_CONTINUATION]
|
||||
|
||||
// call the continuation unless we're handling an exception
|
||||
ldr r7,[r8,#THREAD_EXCEPTION]
|
||||
cmp r7,#0
|
||||
bne LOCAL(vmInvoke_handleException)
|
||||
ldr r7,[r5,#CONTINUATION_ADDRESS]
|
||||
bx r7
|
||||
|
||||
LOCAL(vmInvoke_handleException):
|
||||
// we're handling an exception - call the exception handler instead
|
||||
mov r11,#0
|
||||
str r11,[r8,#THREAD_EXCEPTION]
|
||||
ldr r11,[r8,#THREAD_EXCEPTION_STACK_ADJUSTMENT]
|
||||
ldr r9,[sp]
|
||||
neg r11,r11
|
||||
str r9,[sp,r11]!
|
||||
ldr r11,[r8,#THREAD_EXCEPTION_OFFSET]
|
||||
str r7,[sp,r11]
|
||||
|
||||
ldr r7,[r8,#THREAD_EXCEPTION_HANDLER]
|
||||
bx r7
|
||||
|
||||
LOCAL(vmInvoke_exit):
|
||||
#endif // AVIAN_CONTINUATIONS
|
||||
|
||||
mov ip, #0
|
||||
str ip, [r8, #THREAD_STACK]
|
||||
|
||||
@ -124,6 +194,71 @@ LOCAL(vmInvoke_return):
|
||||
|
||||
.globl GLOBAL(vmJumpAndInvoke)
|
||||
GLOBAL(vmJumpAndInvoke):
|
||||
// vmJumpAndInvoke should only be called when continuations are
|
||||
// enabled
|
||||
bkpt
|
||||
#ifdef AVIAN_CONTINUATIONS
|
||||
// r0: thread
|
||||
// r1: address
|
||||
// r2: (unused)
|
||||
// r3: stack
|
||||
// [sp,#0]: argumentFootprint
|
||||
// [sp,#4]: arguments
|
||||
// [sp,#8]: frameSize
|
||||
|
||||
ldr r4,[sp]
|
||||
ldr r5,[sp,#4]
|
||||
ldr r6,[sp,#8]
|
||||
|
||||
// restore (pseudo)-stack pointer (we don't want to touch the real
|
||||
// stack pointer, since we haven't copied the arguments yet)
|
||||
ldr r3,[r3]
|
||||
|
||||
// make everything between sp and r3 one big stack frame while we
|
||||
// shuffle things around
|
||||
str r3,[sp]
|
||||
|
||||
// allocate new frame, adding room for callee-saved registers
|
||||
neg r10,r6
|
||||
add r10,r10,#-80
|
||||
mov r2,r3
|
||||
str r2,[r3,r10]!
|
||||
|
||||
mov r8,r0
|
||||
|
||||
// copy arguments into place
|
||||
mov r6,#0
|
||||
add r9,r3,#ARGUMENT_BASE
|
||||
b LOCAL(vmJumpAndInvoke_argumentTest)
|
||||
|
||||
LOCAL(vmJumpAndInvoke_argumentLoop):
|
||||
ldr r12,[r5,r6]
|
||||
str r12,[r9,r6]
|
||||
add r6,r6,#4
|
||||
|
||||
LOCAL(vmJumpAndInvoke_argumentTest):
|
||||
cmp r6,r4
|
||||
ble LOCAL(vmJumpAndInvoke_argumentLoop)
|
||||
|
||||
// the arguments have been copied, so we can set the real stack
|
||||
// pointer now
|
||||
mov sp,r3
|
||||
|
||||
// set return address to vmInvoke_returnAddress
|
||||
ldr r10,LOCAL(vmInvoke_returnAddress_word)
|
||||
ldr r11,LOCAL(vmJumpAndInvoke_getAddress_word)
|
||||
LOCAL(vmJumpAndInvoke_getAddress):
|
||||
add r11,pc,r11
|
||||
ldr lr,[r11,r10]
|
||||
|
||||
bx r1
|
||||
#else // not AVIAN_CONTINUATIONS
|
||||
// vmJumpAndInvoke should only be called when continuations are
|
||||
// enabled
|
||||
bkpt
|
||||
#endif // not AVIAN_CONTINUATIONS
|
||||
|
||||
LOCAL(vmInvoke_returnAddress_word):
|
||||
.word GLOBAL(vmInvoke_returnAddress)(GOT)
|
||||
LOCAL(vmInvoke_getAddress_word):
|
||||
.word _GLOBAL_OFFSET_TABLE_-(LOCAL(vmInvoke_getAddress)+8)
|
||||
LOCAL(vmJumpAndInvoke_getAddress_word):
|
||||
.word _GLOBAL_OFFSET_TABLE_-(LOCAL(vmJumpAndInvoke_getAddress)+8)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user