mirror of
https://github.com/corda/corda.git
synced 2025-03-12 23:44:13 +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
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
#ifdef AVIAN_CONTINUATIONS
|
|
||||||
# error "Continuations not yet supported on ARM port"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
#define BYTES_PER_WORD 4
|
#define BYTES_PER_WORD 4
|
||||||
|
|
||||||
#define LOCAL(x) L##x
|
#define LOCAL(x) .L##x
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# define GLOBAL(x) _##x
|
# define GLOBAL(x) _##x
|
||||||
@ -33,6 +29,15 @@
|
|||||||
#define THREAD_EXCEPTION_OFFSET 2156
|
#define THREAD_EXCEPTION_OFFSET 2156
|
||||||
#define THREAD_EXCEPTION_HANDLER 2160
|
#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)
|
.globl GLOBAL(vmInvoke)
|
||||||
GLOBAL(vmInvoke):
|
GLOBAL(vmInvoke):
|
||||||
/*
|
/*
|
||||||
@ -83,12 +88,8 @@ LOCAL(vmInvoke_argumentTest):
|
|||||||
// we use r8 to hold the thread pointer, by convention
|
// we use r8 to hold the thread pointer, by convention
|
||||||
mov r8, r0
|
mov r8, r0
|
||||||
|
|
||||||
.global GLOBAL(beforecall)
|
|
||||||
GLOBAL(beforecall):
|
|
||||||
// load and call function address
|
// load and call function address
|
||||||
blx r1
|
blx r1
|
||||||
.global GLOBAL(aftercall)
|
|
||||||
GLOBAL(aftercall):
|
|
||||||
|
|
||||||
.globl GLOBAL(vmInvoke_returnAddress)
|
.globl GLOBAL(vmInvoke_returnAddress)
|
||||||
GLOBAL(vmInvoke_returnAddress):
|
GLOBAL(vmInvoke_returnAddress):
|
||||||
@ -99,6 +100,75 @@ GLOBAL(vmInvoke_returnAddress):
|
|||||||
.globl GLOBAL(vmInvoke_safeStack)
|
.globl GLOBAL(vmInvoke_safeStack)
|
||||||
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
|
mov ip, #0
|
||||||
str ip, [r8, #THREAD_STACK]
|
str ip, [r8, #THREAD_STACK]
|
||||||
|
|
||||||
@ -124,6 +194,71 @@ LOCAL(vmInvoke_return):
|
|||||||
|
|
||||||
.globl GLOBAL(vmJumpAndInvoke)
|
.globl GLOBAL(vmJumpAndInvoke)
|
||||||
GLOBAL(vmJumpAndInvoke):
|
GLOBAL(vmJumpAndInvoke):
|
||||||
// vmJumpAndInvoke should only be called when continuations are
|
#ifdef AVIAN_CONTINUATIONS
|
||||||
// enabled
|
// r0: thread
|
||||||
bkpt
|
// 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