summaryrefslogtreecommitdiff
path: root/rts/StgCRunAsm.S
diff options
context:
space:
mode:
authorPeter Trommler <ptrommler@acm.org>2016-03-11 16:16:40 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-06-28 09:19:11 -0400
commitd8ba9e6f951a2f8c6e2429a8b2dcb035c392908f (patch)
treeb2b6376c4a656b7b5b8fda0922615d978f3c3c9e /rts/StgCRunAsm.S
parent0e83efa24636c72811e4c79fe1c7e4f7cf3170cd (diff)
downloadhaskell-d8ba9e6f951a2f8c6e2429a8b2dcb035c392908f.tar.gz
RTS: Refactor Haskell-C glue for PPC 64-bit
Make sure the stack is 16 byte aligned even when reserved stack bytes are not a multiple of 16 bytes. Avoid saving r2 (TOC). On ELF v1 the function descriptor of StgReturn has the same TOC as StgRun, on ELF v2 the TOC is recomputed in the function prologue. Use the ABI provided functions to save clobbered GPRs and FPRs. Improve comments. Describe what the stack looks like and how it relates to the respective ABIs.
Diffstat (limited to 'rts/StgCRunAsm.S')
-rw-r--r--rts/StgCRunAsm.S134
1 files changed, 45 insertions, 89 deletions
diff --git a/rts/StgCRunAsm.S b/rts/StgCRunAsm.S
index b332be2010..60f1bf9a13 100644
--- a/rts/StgCRunAsm.S
+++ b/rts/StgCRunAsm.S
@@ -7,109 +7,65 @@
#if defined(powerpc64le_HOST_ARCH)
# if defined(linux_HOST_OS)
-# define STACK_FRAME_SIZE RESERVED_C_STACK_BYTES+304
+/* 64-bit PowerPC ELF V2 ABI Revision 1.4
+ *
+ * Stack frame organization (see Figure 2.18, ELF V2 ABI Revision 1.4, p 31)
+ *
+ * +-> Back Chain (points to the prevoius stack frame)
+ * | Floating point register save area (f14-f31)
+ * | General register save area (r14-r31)
+ * | ... unused (optional) save areas (size 0)
+ * | Local variable space
+ * | Parameter save area (8 doublewords)
+ * | ... stack header (TOC, LR, CR)
+ * +-- Back chain <---- SP (r1)
+ *
+ * We save all callee-saves general purpose registers (r14-r31, _savegpr1_14)
+ * and all callee-saves floating point registers (f14-31, _savefpr14) and
+ * the return address of the caller (LR), which is saved in the caller's
+ * stack frame as required by the ABI. We only modify the CR0 and CR1 fields
+ * of the condition register and those are caller-saves, so we don't save CR.
+ *
+ * StgReturn restores all saved registers from their respective locations
+ * on the stack before returning to the caller.
+ *
+ * There is no need to save the TOC register (r2) because we will return
+ * through StgReturn. All calls to StgReturn will be to the global entry
+ * point and we compute the TOC from the entry address of StgReturn, which
+ * is required to be in r12 by the ABI.
+ */
+# define STACK_FRAME_SIZE (RESERVED_C_STACK_BYTES+288+15) & ~15
.file "StgCRun.c"
.abiversion 2
.section ".toc","aw"
.section ".text"
.align 2
-.globl StgRun
-.hidden StgRun
-.type StgRun,@function
+ .globl StgRun
+ .hidden StgRun
+ .type StgRun,@function
StgRun:
-.localentry StgRun,.-StgRun
+ .localentry StgRun,.-StgRun
mflr 0
- mr 5, 1
- std 0, 16(1)
+ addi 12,1,-(8*18)
+ bl _savegpr1_14
+ bl _savefpr_14
stdu 1, -(STACK_FRAME_SIZE)(1)
- std 2, -296(5)
- std 14, -288(5)
- std 15, -280(5)
- std 16, -272(5)
- std 17, -264(5)
- std 18, -256(5)
- std 19, -248(5)
- std 20, -240(5)
- std 21, -232(5)
- std 22, -224(5)
- std 23, -216(5)
- std 24, -208(5)
- std 25, -200(5)
- std 26, -192(5)
- std 27, -184(5)
- std 28, -176(5)
- std 29, -168(5)
- std 30, -160(5)
- std 31, -152(5)
- stfd 14, -144(5)
- stfd 15, -136(5)
- stfd 16, -128(5)
- stfd 17, -120(5)
- stfd 18, -112(5)
- stfd 19, -104(5)
- stfd 20, -96(5)
- stfd 21, -88(5)
- stfd 22, -80(5)
- stfd 23, -72(5)
- stfd 24, -64(5)
- stfd 25, -56(5)
- stfd 26, -48(5)
- stfd 27, -40(5)
- stfd 28, -32(5)
- stfd 29, -24(5)
- stfd 30, -16(5)
- stfd 31, -8(5)
mr 27, 4
mtctr 3
mr 12, 3
bctr
-.globl StgReturn
-.type StgReturn,@function
+
+ .globl StgReturn
+ .type StgReturn,@function
StgReturn:
-.localentry StgReturn,.-StgReturn
+ addis 2,12,.TOC.-StgReturn@ha
+ addi 2,2,.TOC.-StgReturn@l
+ .localentry StgReturn,.-StgReturn
mr 3,14
- la 5, STACK_FRAME_SIZE(1)
- ld 2, -296(5)
- ld 14, -288(5)
- ld 15, -280(5)
- ld 16, -272(5)
- ld 17, -264(5)
- ld 18, -256(5)
- ld 19, -248(5)
- ld 20, -240(5)
- ld 21, -232(5)
- ld 22, -224(5)
- ld 23, -216(5)
- ld 24, -208(5)
- ld 25, -200(5)
- ld 26, -192(5)
- ld 27, -184(5)
- ld 28, -176(5)
- ld 29, -168(5)
- ld 30, -160(5)
- ld 31, -152(5)
- lfd 14, -144(5)
- lfd 15, -136(5)
- lfd 16, -128(5)
- lfd 17, -120(5)
- lfd 18, -112(5)
- lfd 19, -104(5)
- lfd 20, -96(5)
- lfd 21, -88(5)
- lfd 22, -80(5)
- lfd 23, -72(5)
- lfd 24, -64(5)
- lfd 25, -56(5)
- lfd 26, -48(5)
- lfd 27, -40(5)
- lfd 28, -32(5)
- lfd 29, -24(5)
- lfd 30, -16(5)
- lfd 31, -8(5)
- mr 1, 5
- ld 0, 16(1)
- mtlr 0
- blr
+ la 1, STACK_FRAME_SIZE(1)
+ addi 12,1,-(8*18)
+ bl _restgpr1_14
+ b _restfpr_14
.section .note.GNU-stack,"",@progbits
# else // linux_HOST_OS