diff options
Diffstat (limited to 'rts')
-rw-r--r-- | rts/Capability.h | 4 | ||||
-rw-r--r-- | rts/Libdw.c | 29 | ||||
-rw-r--r-- | rts/StgCRunAsm.S | 92 | ||||
-rw-r--r-- | rts/ghc.mk | 2 | ||||
-rw-r--r-- | rts/linker/Elf.c | 6 | ||||
-rw-r--r-- | rts/rts.cabal.in | 2 |
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" (®s[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 |