summaryrefslogtreecommitdiff
path: root/includes/stg
diff options
context:
space:
mode:
authorStefan Schulze Frielinghaus <stefansf@linux.ibm.com>2019-10-08 12:32:15 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2019-10-22 02:39:03 -0400
commitfd8b666acfee5524a2d7c8b845a3782f6a89bec7 (patch)
tree4ce0d732ef341bcffa721f6d25f2cf4dcd476fd8 /includes/stg
parentaa31ceaf7568802590f73a740ffbc8b800096342 (diff)
downloadhaskell-fd8b666acfee5524a2d7c8b845a3782f6a89bec7.tar.gz
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.
Diffstat (limited to 'includes/stg')
-rw-r--r--includes/stg/MachRegs.h72
-rw-r--r--includes/stg/MachRegsForHost.h4
-rw-r--r--includes/stg/SMP.h6
3 files changed, 82 insertions, 0 deletions
diff --git a/includes/stg/MachRegs.h b/includes/stg/MachRegs.h
index 0afc88152e..ea1125bbf8 100644
--- a/includes/stg/MachRegs.h
+++ b/includes/stg/MachRegs.h
@@ -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
diff --git a/includes/stg/MachRegsForHost.h b/includes/stg/MachRegsForHost.h
index 135c7974bd..3597b2be90 100644
--- a/includes/stg/MachRegsForHost.h
+++ b/includes/stg/MachRegsForHost.h
@@ -67,6 +67,10 @@
#define MACHREGS_darwin 1
#endif
+#if defined(s390x_HOST_ARCH)
+#define MACHREGS_s390x 1
+#endif
+
#endif
#include "MachRegs.h"
diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h
index 4be11d1f64..2d6a220a9e 100644
--- a/includes/stg/SMP.h
+++ b/includes/stg/SMP.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");