Commit fd8b666a authored by Stefan Schulze Frielinghaus's avatar Stefan Schulze Frielinghaus Committed by Marge Bot

Implement s390x LLVM backend.

This patch adds support for the s390x architecture for the LLVM code
generator. The patch includes a register mapping of STG registers onto
s390x machine registers which enables a registerised build.
parent aa31ceaf
......@@ -195,6 +195,9 @@ AC_DEFUN([FPTOOLS_SET_HASKELL_PLATFORM_VARS],
powerpc64le)
test -z "[$]2" || eval "[$]2=\"ArchPPC_64 {ppc_64ABI = ELF_V2}\""
;;
s390x)
test -z "[$]2" || eval "[$]2=ArchS390X"
;;
sparc)
test -z "[$]2" || eval "[$]2=ArchSPARC"
;;
......@@ -217,7 +220,7 @@ AC_DEFUN([FPTOOLS_SET_HASKELL_PLATFORM_VARS],
mipsel)
test -z "[$]2" || eval "[$]2=ArchMipsel"
;;
hppa|hppa1_1|ia64|m68k|nios2|riscv32|riscv64|rs6000|s390|s390x|sh4|vax)
hppa|hppa1_1|ia64|m68k|nios2|riscv32|riscv64|rs6000|s390|sh4|vax)
test -z "[$]2" || eval "[$]2=ArchUnknown"
;;
*)
......
......@@ -12,6 +12,7 @@ import Reg
import qualified GHC.Platform.ARM as ARM
import qualified GHC.Platform.ARM64 as ARM64
import qualified GHC.Platform.PPC as PPC
import qualified GHC.Platform.S390X as S390X
import qualified GHC.Platform.SPARC as SPARC
import qualified GHC.Platform.X86 as X86
import qualified GHC.Platform.X86_64 as X86_64
......@@ -27,6 +28,7 @@ callerSaves platform
= case platformArch platform of
ArchX86 -> X86.callerSaves
ArchX86_64 -> X86_64.callerSaves
ArchS390X -> S390X.callerSaves
ArchSPARC -> SPARC.callerSaves
ArchARM {} -> ARM.callerSaves
ArchARM64 -> ARM64.callerSaves
......@@ -48,6 +50,7 @@ activeStgRegs platform
= case platformArch platform of
ArchX86 -> X86.activeStgRegs
ArchX86_64 -> X86_64.activeStgRegs
ArchS390X -> S390X.activeStgRegs
ArchSPARC -> SPARC.activeStgRegs
ArchARM {} -> ARM.activeStgRegs
ArchARM64 -> ARM64.activeStgRegs
......@@ -64,6 +67,7 @@ haveRegBase platform
= case platformArch platform of
ArchX86 -> X86.haveRegBase
ArchX86_64 -> X86_64.haveRegBase
ArchS390X -> S390X.haveRegBase
ArchSPARC -> SPARC.haveRegBase
ArchARM {} -> ARM.haveRegBase
ArchARM64 -> ARM64.haveRegBase
......@@ -80,6 +84,7 @@ globalRegMaybe platform
= case platformArch platform of
ArchX86 -> X86.globalRegMaybe
ArchX86_64 -> X86_64.globalRegMaybe
ArchS390X -> S390X.globalRegMaybe
ArchSPARC -> SPARC.globalRegMaybe
ArchARM {} -> ARM.globalRegMaybe
ArchARM64 -> ARM64.globalRegMaybe
......@@ -96,6 +101,7 @@ freeReg platform
= case platformArch platform of
ArchX86 -> X86.freeReg
ArchX86_64 -> X86_64.freeReg
ArchS390X -> S390X.freeReg
ArchSPARC -> SPARC.freeReg
ArchARM {} -> ARM.freeReg
ArchARM64 -> ARM64.freeReg
......
{-# LANGUAGE CPP #-}
module GHC.Platform.S390X where
import GhcPrelude
#define MACHREGS_NO_REGS 0
#define MACHREGS_s390x 1
#include "../../../includes/CodeGen.Platform.hs"
......@@ -285,6 +285,7 @@ Library
GHC.Platform.ARM64
GHC.Platform.NoRegs
GHC.Platform.PPC
GHC.Platform.S390X
GHC.Platform.SPARC
GHC.Platform.X86
GHC.Platform.X86_64
......
......@@ -71,6 +71,7 @@ genLlvmData (sec, Statics lbl xs) = do
label <- strCLabel_llvm lbl
static <- mapM genData xs
lmsec <- llvmSection sec
platform <- getLlvmPlatform
let types = map getStatType static
strucTy = LMStruct types
......@@ -79,7 +80,8 @@ genLlvmData (sec, Statics lbl xs) = do
struct = Just $ LMStaticStruc static tyAlias
link = linkage lbl
align = case sec of
Section CString _ -> Just 1
Section CString _ -> if (platformArch platform == ArchS390X)
then Just 2 else Just 1
_ -> Nothing
const = if isSecConstant sec then Constant else Global
varDef = LMGlobalVar label tyAlias link lmsec align const
......
......@@ -168,6 +168,7 @@ nativeCodeGen dflags this_mod modLoc h us cmms
ArchX86 -> nCG' (x86NcgImpl dflags)
ArchX86_64 -> nCG' (x86_64NcgImpl dflags)
ArchPPC -> nCG' (ppcNcgImpl dflags)
ArchS390X -> panic "nativeCodeGen: No NCG for S390X"
ArchSPARC -> nCG' (sparcNcgImpl dflags)
ArchSPARC64 -> panic "nativeCodeGen: No NCG for SPARC64"
ArchARM {} -> panic "nativeCodeGen: No NCG for ARM"
......
......@@ -119,6 +119,7 @@ trivColorable platform virtualRegSqueeze realRegSqueeze RcInteger conflicts excl
ArchAlpha -> panic "trivColorable ArchAlpha"
ArchMipseb -> panic "trivColorable ArchMipseb"
ArchMipsel -> panic "trivColorable ArchMipsel"
ArchS390X -> panic "trivColorable ArchS390X"
ArchJavaScript-> panic "trivColorable ArchJavaScript"
ArchUnknown -> panic "trivColorable ArchUnknown")
, count2 <- accSqueeze 0 cALLOCATABLE_REGS_INTEGER
......@@ -149,6 +150,7 @@ trivColorable platform virtualRegSqueeze realRegSqueeze RcFloat conflicts exclus
ArchAlpha -> panic "trivColorable ArchAlpha"
ArchMipseb -> panic "trivColorable ArchMipseb"
ArchMipsel -> panic "trivColorable ArchMipsel"
ArchS390X -> panic "trivColorable ArchS390X"
ArchJavaScript-> panic "trivColorable ArchJavaScript"
ArchUnknown -> panic "trivColorable ArchUnknown")
, count2 <- accSqueeze 0 cALLOCATABLE_REGS_FLOAT
......@@ -181,6 +183,7 @@ trivColorable platform virtualRegSqueeze realRegSqueeze RcDouble conflicts exclu
ArchAlpha -> panic "trivColorable ArchAlpha"
ArchMipseb -> panic "trivColorable ArchMipseb"
ArchMipsel -> panic "trivColorable ArchMipsel"
ArchS390X -> panic "trivColorable ArchS390X"
ArchJavaScript-> panic "trivColorable ArchJavaScript"
ArchUnknown -> panic "trivColorable ArchUnknown")
, count2 <- accSqueeze 0 cALLOCATABLE_REGS_DOUBLE
......
......@@ -75,6 +75,7 @@ maxSpillSlots dflags
ArchX86 -> X86.Instr.maxSpillSlots dflags
ArchX86_64 -> X86.Instr.maxSpillSlots dflags
ArchPPC -> PPC.Instr.maxSpillSlots dflags
ArchS390X -> panic "maxSpillSlots ArchS390X"
ArchSPARC -> SPARC.Instr.maxSpillSlots dflags
ArchSPARC64 -> panic "maxSpillSlots ArchSPARC64"
ArchARM _ _ _ -> panic "maxSpillSlots ArchARM"
......
......@@ -211,6 +211,7 @@ linearRegAlloc dflags entry_ids block_live sccs
= case platformArch platform of
ArchX86 -> go $ (frInitFreeRegs platform :: X86.FreeRegs)
ArchX86_64 -> go $ (frInitFreeRegs platform :: X86_64.FreeRegs)
ArchS390X -> panic "linearRegAlloc ArchS390X"
ArchSPARC -> go $ (frInitFreeRegs platform :: SPARC.FreeRegs)
ArchSPARC64 -> panic "linearRegAlloc ArchSPARC64"
ArchPPC -> go $ (frInitFreeRegs platform :: PPC.FreeRegs)
......
......@@ -44,6 +44,7 @@ targetVirtualRegSqueeze platform
ArchX86 -> X86.virtualRegSqueeze
ArchX86_64 -> X86.virtualRegSqueeze
ArchPPC -> PPC.virtualRegSqueeze
ArchS390X -> panic "targetVirtualRegSqueeze ArchS390X"
ArchSPARC -> SPARC.virtualRegSqueeze
ArchSPARC64 -> panic "targetVirtualRegSqueeze ArchSPARC64"
ArchPPC_64 _ -> PPC.virtualRegSqueeze
......@@ -62,6 +63,7 @@ targetRealRegSqueeze platform
ArchX86 -> X86.realRegSqueeze
ArchX86_64 -> X86.realRegSqueeze
ArchPPC -> PPC.realRegSqueeze
ArchS390X -> panic "targetRealRegSqueeze ArchS390X"
ArchSPARC -> SPARC.realRegSqueeze
ArchSPARC64 -> panic "targetRealRegSqueeze ArchSPARC64"
ArchPPC_64 _ -> PPC.realRegSqueeze
......@@ -79,6 +81,7 @@ targetClassOfRealReg platform
ArchX86 -> X86.classOfRealReg platform
ArchX86_64 -> X86.classOfRealReg platform
ArchPPC -> PPC.classOfRealReg
ArchS390X -> panic "targetClassOfRealReg ArchS390X"
ArchSPARC -> SPARC.classOfRealReg
ArchSPARC64 -> panic "targetClassOfRealReg ArchSPARC64"
ArchPPC_64 _ -> PPC.classOfRealReg
......@@ -96,6 +99,7 @@ targetMkVirtualReg platform
ArchX86 -> X86.mkVirtualReg
ArchX86_64 -> X86.mkVirtualReg
ArchPPC -> PPC.mkVirtualReg
ArchS390X -> panic "targetMkVirtualReg ArchS390X"
ArchSPARC -> SPARC.mkVirtualReg
ArchSPARC64 -> panic "targetMkVirtualReg ArchSPARC64"
ArchPPC_64 _ -> PPC.mkVirtualReg
......@@ -113,6 +117,7 @@ targetRegDotColor platform
ArchX86 -> X86.regDotColor platform
ArchX86_64 -> X86.regDotColor platform
ArchPPC -> PPC.regDotColor
ArchS390X -> panic "targetRegDotColor ArchS390X"
ArchSPARC -> SPARC.regDotColor
ArchSPARC64 -> panic "targetRegDotColor ArchSPARC64"
ArchPPC_64 _ -> PPC.regDotColor
......
......@@ -244,7 +244,7 @@ dnl --------------------------------------------------------------
AC_MSG_CHECKING(whether target supports a registerised ABI)
case "$TargetArch" in
i386|x86_64|powerpc|powerpc64|powerpc64le|arm|aarch64)
i386|x86_64|powerpc|powerpc64|powerpc64le|s390x|arm|aarch64)
UnregisterisedDefault=NO
AC_MSG_RESULT([yes])
;;
......@@ -279,7 +279,7 @@ AC_MSG_CHECKING(whether target supports tables next to code)
case "$Unregisterised" in
NO)
case "$TargetArch" in
ia64|powerpc64|powerpc64le)
ia64|powerpc64|powerpc64le|s390x)
TablesNextToCodeDefault=NO
AC_MSG_RESULT([no])
;;
......@@ -308,7 +308,7 @@ AC_SUBST(TablesNextToCode)
dnl ** Does target have runtime linker support?
dnl --------------------------------------------------------------
case "$target" in
powerpc64-*|powerpc64le-*|powerpc-ibm-aix*)
powerpc64-*|powerpc64le-*|powerpc-ibm-aix*|s390x-ibm-linux)
TargetHasRTSLinker=NO
;;
*)
......
......@@ -59,7 +59,7 @@ platformSupportsSharedLibs = do
ghcWithSMP :: Action Bool
ghcWithSMP = do
goodArch <- anyTargetArch ["i386", "x86_64", "sparc", "powerpc", "arm"]
goodArch <- anyTargetArch ["i386", "x86_64", "sparc", "powerpc", "arm", "s390x"]
ghcUnreg <- flag GhcUnregisterised
return $ goodArch && not ghcUnreg
......
......@@ -344,6 +344,42 @@ import Reg
# define f30 62
# define f31 63
#elif defined(MACHREGS_s390x)
# define r0 0
# define r1 1
# define r2 2
# define r3 3
# define r4 4
# define r5 5
# define r6 6
# define r7 7
# define r8 8
# define r9 9
# define r10 10
# define r11 11
# define r12 12
# define r13 13
# define r14 14
# define r15 15
# define f0 16
# define f1 17
# define f2 18
# define f3 19
# define f4 20
# define f5 21
# define f6 22
# define f7 23
# define f8 24
# define f9 25
# define f10 26
# define f11 27
# define f12 28
# define f13 29
# define f14 30
# define f15 31
#endif
callerSaves :: GlobalReg -> Bool
......@@ -630,7 +666,8 @@ haveRegBase = False
globalRegMaybe :: GlobalReg -> Maybe RealReg
#if defined(MACHREGS_i386) || defined(MACHREGS_x86_64) \
|| defined(MACHREGS_sparc) || defined(MACHREGS_powerpc) \
|| defined(MACHREGS_arm) || defined(MACHREGS_aarch64)
|| defined(MACHREGS_arm) || defined(MACHREGS_aarch64) \
|| defined(MACHREGS_s390x)
# if defined(REG_Base)
globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
# endif
......
......@@ -589,6 +589,78 @@ the stack. See Note [Overlapping global registers] for implications.
#define REG_D3 d14
#define REG_D4 d15
/* -----------------------------------------------------------------------------
The s390x register mapping
Register | Role(s) | Call effect
------------+-------------------------------------+-----------------
r0,r1 | - | caller-saved
r2 | Argument / return value | caller-saved
r3,r4,r5 | Arguments | caller-saved
r6 | Argument | callee-saved
r7...r11 | - | callee-saved
r12 | (Commonly used as GOT pointer) | callee-saved
r13 | (Commonly used as literal pool pointer) | callee-saved
r14 | Return address | caller-saved
r15 | Stack pointer | callee-saved
f0 | Argument / return value | caller-saved
f2,f4,f6 | Arguments | caller-saved
f1,f3,f5,f7 | - | caller-saved
f8...f15 | - | callee-saved
v0...v31 | - | caller-saved
Each general purpose register r0 through r15 as well as each floating-point
register f0 through f15 is 64 bits wide. Each vector register v0 through v31
is 128 bits wide.
Note, the vector registers v0 through v15 overlap with the floating-point
registers f0 through f15.
-------------------------------------------------------------------------- */
#elif defined(MACHREGS_s390x)
#define REG(x) __asm__("%" #x)
#define REG_Base r7
#define REG_Sp r8
#define REG_Hp r10
#define REG_R1 r11
#define REG_R2 r12
#define REG_R3 r13
#define REG_R4 r6
#define REG_R5 r2
#define REG_R6 r3
#define REG_R7 r4
#define REG_R8 r5
#define REG_SpLim r9
#define REG_MachSp r15
#define REG_F1 f8
#define REG_F2 f9
#define REG_F3 f10
#define REG_F4 f11
#define REG_F5 f0
#define REG_F6 f1
#define REG_D1 f12
#define REG_D2 f13
#define REG_D3 f14
#define REG_D4 f15
#define REG_D5 f2
#define REG_D6 f3
#define CALLER_SAVES_R5
#define CALLER_SAVES_R6
#define CALLER_SAVES_R7
#define CALLER_SAVES_R8
#define CALLER_SAVES_F5
#define CALLER_SAVES_F6
#define CALLER_SAVES_D5
#define CALLER_SAVES_D6
#else
#error Cannot find platform to give register info for
......
......@@ -67,6 +67,10 @@
#define MACHREGS_darwin 1
#endif
#if defined(s390x_HOST_ARCH)
#define MACHREGS_s390x 1
#endif
#endif
#include "MachRegs.h"
......@@ -336,6 +336,8 @@ write_barrier(void) {
#elif defined(powerpc_HOST_ARCH) || defined(powerpc64_HOST_ARCH) \
|| defined(powerpc64le_HOST_ARCH)
__asm__ __volatile__ ("lwsync" : : : "memory");
#elif defined(s390x_HOST_ARCH)
__asm__ __volatile__ ("" : : : "memory");
#elif defined(sparc_HOST_ARCH)
/* Sparc in TSO mode does not require store/store barriers. */
__asm__ __volatile__ ("" : : : "memory");
......@@ -357,6 +359,8 @@ store_load_barrier(void) {
#elif defined(powerpc_HOST_ARCH) || defined(powerpc64_HOST_ARCH) \
|| defined(powerpc64le_HOST_ARCH)
__asm__ __volatile__ ("sync" : : : "memory");
#elif defined(s390x_HOST_ARCH)
__asm__ __volatile__ ("bcr 14,0" : : : "memory");
#elif defined(sparc_HOST_ARCH)
__asm__ __volatile__ ("membar #StoreLoad" : : : "memory");
#elif defined(arm_HOST_ARCH)
......@@ -379,6 +383,8 @@ load_load_barrier(void) {
#elif defined(powerpc_HOST_ARCH) || defined(powerpc64_HOST_ARCH) \
|| defined(powerpc64le_HOST_ARCH)
__asm__ __volatile__ ("lwsync" : : : "memory");
#elif defined(s390x_HOST_ARCH)
__asm__ __volatile__ ("" : : : "memory");
#elif defined(sparc_HOST_ARCH)
/* Sparc in TSO mode does not require load/load barriers. */
__asm__ __volatile__ ("" : : : "memory");
......
......@@ -106,6 +106,7 @@ data Arch
| ArchPPC_64
{ ppc_64ABI :: PPC_64ABI
}
| ArchS390X
| ArchSPARC
| ArchSPARC64
| ArchARM
......@@ -145,6 +146,7 @@ stringEncodeArch = \case
ArchPPC_64 { ppc_64ABI = abi } -> case abi of
ELF_V1 -> "powerpc64"
ELF_V2 -> "powerpc64le"
ArchS390X -> "s390x"
ArchSPARC -> "sparc"
ArchSPARC64 -> "sparc64"
ArchARM { armISA = isa, armISAExt = _, armABI = _ } -> "arm" ++ vsuf
......
......@@ -76,6 +76,7 @@ data Arch = ArchSPARC
| ArchARM64
| ArchPPC64
| ArchPPC64LE
| ArchS390X
| ArchUnknown
deriving Show
......@@ -99,6 +100,8 @@ platform =
ArchPPC64
#elif defined(powerpc64le_HOST_ARCH)
ArchPPC64LE
#elif defined(s390x_HOST_ARCH)
ArchS390X
#else
# if defined(TABLES_NEXT_TO_CODE)
# error Unimplemented architecture
......@@ -268,6 +271,20 @@ mkJumpToAddr a = case platform of
0x618C0000 .|. lo16 w32,
0x7D8903A6, 0x4E800420 ]
ArchS390X ->
-- Let 0xAABBCCDDEEFFGGHH be the address to jump to.
-- The following code loads the address into scratch
-- register r1 and jumps to it.
--
-- 0: C0 1E AA BB CC DD llihf %r1,0xAABBCCDD
-- 6: C0 19 EE FF GG HH iilf %r1,0xEEFFGGHH
-- 12: 07 F1 br %r1
let w64 = fromIntegral (funPtrToInt a) :: Word64
in Left [ 0xC0, 0x1E, byte7 w64, byte6 w64, byte5 w64, byte4 w64,
0xC0, 0x19, byte3 w64, byte2 w64, byte1 w64, byte0 w64,
0x07, 0xF1 ]
-- This code must not be called. You either need to
-- add your architecture as a distinct case or
-- use non-TABLES_NEXT_TO_CODE mode
......
......@@ -33,6 +33,7 @@
,("powerpc64le-unknown-linux-gnu", ("e-m:e-i64:64-n32:64", "ppc64le", ""))
,("powerpc64le-unknown-linux-musl", ("e-m:e-i64:64-n32:64", "ppc64le", ""))
,("powerpc64le-unknown-linux", ("e-m:e-i64:64-n32:64", "ppc64le", ""))
,("s390x-ibm-linux", ("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64", "z10", ""))
,("i386-apple-darwin", ("e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128", "yonah", ""))
,("x86_64-apple-darwin", ("e-m:o-i64:64-f80:128-n8:16:32:64-S128", "core2", ""))
,("armv7-apple-ios", ("e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32", "generic", ""))
......
......@@ -192,7 +192,7 @@ ifeq "$(TargetArch_CPP)" "arm"
# We don't support load/store barriers pre-ARMv7. See #10433.
ArchSupportsSMP=$(if $(filter $(ARM_ISA),ARMv5 ARMv6),NO,YES)
else
ArchSupportsSMP=$(strip $(patsubst $(TargetArch_CPP), YES, $(findstring $(TargetArch_CPP), i386 x86_64 sparc powerpc powerpc64 powerpc64le aarch64)))
ArchSupportsSMP=$(strip $(patsubst $(TargetArch_CPP), YES, $(findstring $(TargetArch_CPP), i386 x86_64 sparc powerpc powerpc64 powerpc64le s390x aarch64)))
endif
# The THREADED_RTS requires `BaseReg` to be in a register and the
......@@ -365,7 +365,7 @@ FFIIncludeDir=@FFIIncludeDir@
# GHC needs arch-specific tweak at least in
# rts/Libdw.c:set_initial_registers()
GhcRtsWithLibdw=$(strip $(if $(filter $(TargetArch_CPP),i386 x86_64),@UseLibdw@,NO))
GhcRtsWithLibdw=$(strip $(if $(filter $(TargetArch_CPP),i386 x86_64 s390x),@UseLibdw@,NO))
################################################################################
#
......
......@@ -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
;
......
......@@ -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
......
......@@ -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
......@@ -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
......
......@@ -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)
......
......@@ -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
......
......@@ -70,6 +70,8 @@ TARGETS=(
"powerpc64le-unknown-linux-gnu"
"powerpc64le-unknown-linux-musl"
"powerpc64le-unknown-linux"
# Linux s390x
"s390x-ibm-linux"
#########################
# Darwin
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment