fix ARM tails=true and continuations=true builds

This commit is contained in:
Joel Dice
2011-01-29 18:09:47 -07:00
parent 03f18ea00c
commit 6296350d76
2 changed files with 31 additions and 42 deletions

View File

@ -1617,7 +1617,7 @@ argumentFootprint(unsigned footprint)
} }
void void
nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED, nextFrame(ArchitectureContext* c, uint32_t* start, unsigned size UNUSED,
unsigned footprint, int32_t*, void* link, void*, unsigned footprint, int32_t*, void* link, void*,
unsigned targetParameterFootprint UNUSED, void** ip, void** stack) unsigned targetParameterFootprint UNUSED, void** ip, void** stack)
{ {
@ -1640,7 +1640,8 @@ nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED,
if (instruction <= start + 2) { if (instruction <= start + 2) {
*ip = link; *ip = link;
*stack = reinterpret_cast<void**>(*stack) + offset; *stack = static_cast<void**>(*stack) + offset;
return;
} }
if (*instruction == 0xe12fff1e) { // return if (*instruction == 0xe12fff1e) { // return
@ -1654,14 +1655,23 @@ nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED,
- StackAlignmentInWords; - StackAlignmentInWords;
} }
// todo: check for post-non-tail-call stack adjustment of the form // check for post-non-tail-call stack adjustment of the form "add
// "add sp, sp, #offset" // sp, sp, #offset":
if ((*instruction >> 12) == 0xe24dd) {
// todo: use frameTable to check for and handle tail calls unsigned value = *instruction & 0xff;
unsigned rotation = (*instruction >> 8) & 0xf;
switch (rotation) {
case 0: offset -= value / BytesPerWord; break;
case 15: offset -= value; break;
default: abort(c);
}
} }
*ip = reinterpret_cast<void**>(*stack)[offset - 1]; // todo: check for and handle tail calls
*stack = reinterpret_cast<void**>(*stack) + offset; }
*ip = static_cast<void**>(*stack)[offset - 1];
*stack = static_cast<void**>(*stack) + offset;
} }
void void
@ -2204,14 +2214,15 @@ class MyAssembler: public Assembler {
if (TailCalls) { if (TailCalls) {
if (offset) { if (offset) {
footprint += FrameHeaderSize;
Register link(LinkRegister); Register link(LinkRegister);
Memory returnAddressSrc Memory returnAddressSrc
(StackRegister, (footprint - 1) * BytesPerWord); (StackRegister, (footprint - 1) * BytesPerWord);
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &link); moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &link);
Register stack(StackRegister); Register stack(StackRegister);
ResolvedPromise footprintPromise ResolvedPromise footprintPromise((footprint - offset) * BytesPerWord);
((footprint - offset + 1) * BytesPerWord);
Constant footprintConstant(&footprintPromise); Constant footprintConstant(&footprintPromise);
addC(&c, BytesPerWord, &footprintConstant, &stack, &stack); addC(&c, BytesPerWord, &footprintConstant, &stack, &stack);

View File

@ -37,8 +37,6 @@
#define CONTINUATION_LENGTH 28 #define CONTINUATION_LENGTH 28
#define CONTINUATION_BODY 32 #define CONTINUATION_BODY 32
#define ARGUMENT_BASE (BYTES_PER_WORD * 2)
.globl GLOBAL(vmInvoke) .globl GLOBAL(vmInvoke)
GLOBAL(vmInvoke): GLOBAL(vmInvoke):
/* /*
@ -117,12 +115,11 @@ GLOBAL(vmInvoke_safeStack):
add r7,r5,#CONTINUATION_BODY add r7,r5,#CONTINUATION_BODY
mov r11,#0 mov r11,#0
add r10,sp,#ARGUMENT_BASE
b LOCAL(vmInvoke_continuationTest) b LOCAL(vmInvoke_continuationTest)
LOCAL(vmInvoke_continuationLoop): LOCAL(vmInvoke_continuationLoop):
ldr r9,[r7,r11] ldr r9,[r7,r11]
str r9,[r10,r11] str r9,[sp,r11]
add r11,r11,#4 add r11,r11,#4
LOCAL(vmInvoke_continuationTest): LOCAL(vmInvoke_continuationTest):
@ -137,12 +134,6 @@ LOCAL(vmInvoke_getAddress):
ldr r11,[r11,r10] ldr r11,[r11,r10]
str r11,[sp,r7] 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] ldr r7,[r5,#CONTINUATION_NEXT]
str r7,[r8,#THREAD_CONTINUATION] str r7,[r8,#THREAD_CONTINUATION]
@ -198,40 +189,27 @@ GLOBAL(vmJumpAndInvoke):
#ifdef AVIAN_CONTINUATIONS #ifdef AVIAN_CONTINUATIONS
// r0: thread // r0: thread
// r1: address // r1: address
// r2: (unused) // r2: stack
// r3: stack // r3: argumentFootprint
// [sp,#0]: argumentFootprint // [sp,#0]: arguments
// [sp,#4]: arguments // [sp,#4]: frameSize
// [sp,#8]: frameSize
ldr r4,[sp] ldr r5,[sp,#0]
ldr r5,[sp,#4] ldr r6,[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 // allocate new frame, adding room for callee-saved registers
neg r10,r6 sub r2,r2,r6
add r10,r10,#-80 sub r2,r2,#80
mov r2,r3
str r2,[r3,r10]!
mov r8,r0 mov r8,r0
// copy arguments into place // copy arguments into place
mov r6,#0 mov r6,#0
add r9,r3,#ARGUMENT_BASE
b LOCAL(vmJumpAndInvoke_argumentTest) b LOCAL(vmJumpAndInvoke_argumentTest)
LOCAL(vmJumpAndInvoke_argumentLoop): LOCAL(vmJumpAndInvoke_argumentLoop):
ldr r12,[r5,r6] ldr r12,[r5,r6]
str r12,[r9,r6] str r12,[r2,r6]
add r6,r6,#4 add r6,r6,#4
LOCAL(vmJumpAndInvoke_argumentTest): LOCAL(vmJumpAndInvoke_argumentTest):
@ -240,7 +218,7 @@ LOCAL(vmJumpAndInvoke_argumentTest):
// the arguments have been copied, so we can set the real stack // the arguments have been copied, so we can set the real stack
// pointer now // pointer now
mov sp,r3 mov sp,r2
// set return address to vmInvoke_returnAddress // set return address to vmInvoke_returnAddress
ldr r10,LOCAL(vmInvoke_returnAddress_word) ldr r10,LOCAL(vmInvoke_returnAddress_word)