summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
Diffstat (limited to 'rts')
-rw-r--r--rts/Capability.h4
-rw-r--r--rts/Libdw.c29
-rw-r--r--rts/StgCRunAsm.S92
-rw-r--r--rts/ghc.mk2
-rw-r--r--rts/linker/Elf.c6
-rw-r--r--rts/rts.cabal.in2
6 files changed, 132 insertions, 3 deletions
diff --git a/rts/Capability.h b/rts/Capability.h
index 2a5f127793..0833006b0c 100644
--- a/rts/Capability.h
+++ b/rts/Capability.h
@@ -160,7 +160,9 @@ struct Capability_ {
} // typedef Capability is defined in RtsAPI.h
// We never want a Capability to overlap a cache line with anything
// else, so round it up to a cache line size:
-#if !defined(mingw32_HOST_OS)
+#if defined(s390x_HOST_ARCH)
+ ATTRIBUTE_ALIGNED(256)
+#elif !defined(mingw32_HOST_OS)
ATTRIBUTE_ALIGNED(64)
#endif
;
diff --git a/rts/Libdw.c b/rts/Libdw.c
index 33a40a1f37..d45d9d0e5d 100644
--- a/rts/Libdw.c
+++ b/rts/Libdw.c
@@ -330,6 +330,35 @@ static bool set_initial_registers(Dwfl_Thread *thread,
);
return dwfl_thread_state_registers(thread, 0, 9, regs);
}
+#elif defined(s390x_HOST_ARCH)
+static bool set_initial_registers(Dwfl_Thread *thread,
+ void *arg STG_UNUSED) {
+ Dwarf_Word regs[32];
+ __asm__ ("stmg %%r0,%%r15,0(%0)\n\t"
+ "std %%f0, 128(0,%0)\n\t"
+ "std %%f2, 136(0,%0)\n\t"
+ "std %%f4, 144(0,%0)\n\t"
+ "std %%f6, 152(0,%0)\n\t"
+ "std %%f1, 160(0,%0)\n\t"
+ "std %%f3, 168(0,%0)\n\t"
+ "std %%f5, 176(0,%0)\n\t"
+ "std %%f7, 184(0,%0)\n\t"
+ "std %%f8, 192(0,%0)\n\t"
+ "std %%f10, 200(0,%0)\n\t"
+ "std %%f12, 208(0,%0)\n\t"
+ "std %%f14, 216(0,%0)\n\t"
+ "std %%f9, 224(0,%0)\n\t"
+ "std %%f11, 232(0,%0)\n\t"
+ "std %%f13, 240(0,%0)\n\t"
+ "std %%f15, 248(0,%0)\n\t"
+ "larl %%r0,0\n\t"
+ "stg %%r0, 112(0,%0)\n\t"
+ : /* no output */
+ :"r" (&regs[0]) /* input */
+ :"%r0" /* clobbered */
+ );
+ return dwfl_thread_state_registers(thread, 0, 32, regs);
+}
#else
# error "Please implement set_initial_registers() for your arch"
#endif
diff --git a/rts/StgCRunAsm.S b/rts/StgCRunAsm.S
index 1dd74d3652..946f5775ea 100644
--- a/rts/StgCRunAsm.S
+++ b/rts/StgCRunAsm.S
@@ -180,4 +180,96 @@ StgReturn:
blr
# endif // aix_HOST_OS
+
+#elif defined(s390x_HOST_ARCH)
+# define STACK_FRAME_SIZE (RESERVED_C_STACK_BYTES+160)
+ .text
+ .align 8
+ .globl StgRun
+ .type StgRun, @function
+StgRun:
+ .cfi_startproc
+ /* save callee-saved registers */
+ stmg %r6,%r14,16(%r15)
+ std %f8, 88(%r15)
+ std %f9, 96(%r15)
+ std %f10, 104(%r15)
+ std %f11, 112(%r15)
+ std %f12, 120(%r15)
+ std %f13, 128(%r15)
+ std %f14, 136(%r15)
+ std %f15, 144(%r15)
+ .cfi_offset 6, -144
+ .cfi_offset 7, -136
+ .cfi_offset 8, -128
+ .cfi_offset 9, -120
+ .cfi_offset 10, -112
+ .cfi_offset 11, -104
+ .cfi_offset 12, -96
+ .cfi_offset 13, -88
+ .cfi_offset 14, -80
+ .cfi_offset 15, -72
+ .cfi_offset 24, -64
+ .cfi_offset 28, -56
+ .cfi_offset 25, -48
+ .cfi_offset 29, -40
+ .cfi_offset 26, -32
+ .cfi_offset 30, -24
+ .cfi_offset 27, -16
+ .cfi_offset 31, -8
+ /* allocate stack frame */
+ aghi %r15,-STACK_FRAME_SIZE
+ .cfi_def_cfa_offset -(STACK_FRAME_SIZE+160)
+ /* set STGs BaseReg from S390Xs r3 */
+ lgr %r7,%r3
+ /* jump to STG function */
+ br %r2
+ .cfi_endproc
+ .size StgRun, .-StgRun
+
+ .text
+ .align 8
+ .globl StgReturn
+ .type StgReturn, @function
+StgReturn:
+ .cfi_startproc
+ /* set return value from STGs R1 (S390Xs r11) */
+ lgr %r2,%r11
+ /* deallocate stack frame */
+ aghi %r15,STACK_FRAME_SIZE
+ .cfi_def_cfa_offset (STACK_FRAME_SIZE+160)
+ /* restore callee-saved registers */
+ lmg %r6,%r14, 16(%r15)
+ ld %f8, 88(%r15)
+ ld %f9, 96(%r15)
+ ld %f10, 104(%r15)
+ ld %f11, 112(%r15)
+ ld %f12, 120(%r15)
+ ld %f13, 128(%r15)
+ ld %f14, 136(%r15)
+ ld %f15, 144(%r15)
+ .cfi_restore 6
+ .cfi_restore 7
+ .cfi_restore 8
+ .cfi_restore 9
+ .cfi_restore 10
+ .cfi_restore 11
+ .cfi_restore 12
+ .cfi_restore 13
+ .cfi_restore 14
+ .cfi_restore 24
+ .cfi_restore 28
+ .cfi_restore 25
+ .cfi_restore 29
+ .cfi_restore 26
+ .cfi_restore 30
+ .cfi_restore 27
+ .cfi_restore 31
+ .cfi_def_cfa 15, 160
+ /* jump back to caller of StgRun() */
+ br %r14
+ .cfi_endproc
+ .size StgReturn, .-StgReturn
+
+ .section .note.GNU-stack,"",@progbits
#endif
diff --git a/rts/ghc.mk b/rts/ghc.mk
index c07cfaec86..dca22fb733 100644
--- a/rts/ghc.mk
+++ b/rts/ghc.mk
@@ -55,7 +55,7 @@ ifneq "$(findstring $(TargetArch_CPP), i386 powerpc powerpc64)" ""
rts_S_SRCS += rts/AdjustorAsm.S
endif
# this matches substrings of powerpc64le, including "powerpc" and "powerpc64"
-ifneq "$(findstring $(TargetArch_CPP), powerpc64le)" ""
+ifneq "$(findstring $(TargetArch_CPP), powerpc64le s390x)" ""
# unregisterised builds use the mini interpreter
ifneq "$(GhcUnregisterised)" "YES"
rts_S_SRCS += rts/StgCRunAsm.S
diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c
index 0882f8d349..79786ccd3d 100644
--- a/rts/linker/Elf.c
+++ b/rts/linker/Elf.c
@@ -391,6 +391,12 @@ ocVerifyImage_ELF ( ObjectCode* oc )
oc->fileName);
return 0;
#endif
+#if defined(EM_S390)
+ case EM_S390: IF_DEBUG(linker,debugBelch( "s390" ));
+ errorBelch("%s: RTS linker not implemented on s390",
+ oc->fileName);
+ return 0;
+#endif
#if defined(EM_X86_64)
case EM_X86_64: IF_DEBUG(linker,debugBelch( "x86_64" )); break;
#elif defined(EM_AMD64)
diff --git a/rts/rts.cabal.in b/rts/rts.cabal.in
index 99f1e7296d..30c829ad42 100644
--- a/rts/rts.cabal.in
+++ b/rts/rts.cabal.in
@@ -370,7 +370,7 @@ library
if arch(i386) || arch(powerpc) || arch(powerpc64)
asm-sources: AdjustorAsm.S
- if arch(powerpc) || arch(powerpc64) || arch(powerpc64le)
+ if arch(powerpc) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
asm-sources: StgCRunAsm.S
c-sources: Adjustor.c