From 6296350d7616f6b45546415caf7bc8e8b13717ef Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sat, 29 Jan 2011 18:09:47 -0700 Subject: [PATCH] fix ARM tails=true and continuations=true builds --- src/arm.cpp | 29 ++++++++++++++++++++--------- src/compile-arm.S | 44 +++++++++++--------------------------------- 2 files changed, 31 insertions(+), 42 deletions(-) diff --git a/src/arm.cpp b/src/arm.cpp index 8db2de4692..4abb6cf17e 100644 --- a/src/arm.cpp +++ b/src/arm.cpp @@ -1617,7 +1617,7 @@ argumentFootprint(unsigned footprint) } 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 targetParameterFootprint UNUSED, void** ip, void** stack) { @@ -1640,7 +1640,8 @@ nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED, if (instruction <= start + 2) { *ip = link; - *stack = reinterpret_cast(*stack) + offset; + *stack = static_cast(*stack) + offset; + return; } if (*instruction == 0xe12fff1e) { // return @@ -1654,14 +1655,23 @@ nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED, - StackAlignmentInWords; } - // todo: check for post-non-tail-call stack adjustment of the form - // "add sp, sp, #offset" + // check for post-non-tail-call stack adjustment of the form "add + // sp, sp, #offset": + if ((*instruction >> 12) == 0xe24dd) { + 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); + } + } - // todo: use frameTable to check for and handle tail calls + // todo: check for and handle tail calls } - *ip = reinterpret_cast(*stack)[offset - 1]; - *stack = reinterpret_cast(*stack) + offset; + *ip = static_cast(*stack)[offset - 1]; + *stack = static_cast(*stack) + offset; } void @@ -2204,14 +2214,15 @@ class MyAssembler: public Assembler { if (TailCalls) { if (offset) { + footprint += FrameHeaderSize; + Register link(LinkRegister); Memory returnAddressSrc (StackRegister, (footprint - 1) * BytesPerWord); moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &link); Register stack(StackRegister); - ResolvedPromise footprintPromise - ((footprint - offset + 1) * BytesPerWord); + ResolvedPromise footprintPromise((footprint - offset) * BytesPerWord); Constant footprintConstant(&footprintPromise); addC(&c, BytesPerWord, &footprintConstant, &stack, &stack); diff --git a/src/compile-arm.S b/src/compile-arm.S index a7b0963a49..8af887fdbb 100644 --- a/src/compile-arm.S +++ b/src/compile-arm.S @@ -36,8 +36,6 @@ #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): @@ -117,12 +115,11 @@ GLOBAL(vmInvoke_safeStack): 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] + str r9,[sp,r11] add r11,r11,#4 LOCAL(vmInvoke_continuationTest): @@ -137,12 +134,6 @@ LOCAL(vmInvoke_getAddress): 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] @@ -198,40 +189,27 @@ GLOBAL(vmJumpAndInvoke): #ifdef AVIAN_CONTINUATIONS // r0: thread // r1: address - // r2: (unused) - // r3: stack - // [sp,#0]: argumentFootprint - // [sp,#4]: arguments - // [sp,#8]: frameSize + // r2: stack + // r3: argumentFootprint + // [sp,#0]: arguments + // [sp,#4]: 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] + ldr r5,[sp,#0] + ldr r6,[sp,#4] // allocate new frame, adding room for callee-saved registers - neg r10,r6 - add r10,r10,#-80 - mov r2,r3 - str r2,[r3,r10]! + sub r2,r2,r6 + sub r2,r2,#80 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] + str r12,[r2,r6] add r6,r6,#4 LOCAL(vmJumpAndInvoke_argumentTest): @@ -240,7 +218,7 @@ LOCAL(vmJumpAndInvoke_argumentTest): // the arguments have been copied, so we can set the real stack // pointer now - mov sp,r3 + mov sp,r2 // set return address to vmInvoke_returnAddress ldr r10,LOCAL(vmInvoke_returnAddress_word)