summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorGeoffrey Mainland <gmainlan@microsoft.com>2012-10-31 15:42:01 +0000
committerGeoffrey Mainland <gmainlan@microsoft.com>2013-02-01 22:00:24 +0000
commit33bfc6a700eaab9bc06974d6f71a80e61d9177c9 (patch)
tree842bf82b7dbdafe04820349e5e991800a3cf0646 /includes
parent1811440833da92eefd7b7255915855fddc64994c (diff)
downloadhaskell-33bfc6a700eaab9bc06974d6f71a80e61d9177c9.tar.gz
Add support for passing SSE vectors in registers.
This patch adds support for 6 XMM registers on x86-64 which overlap with the F and D registers and may hold 128-bit wide SIMD vectors. Because there is not a good way to attach type information to STG registers, we aggressively bitcast in the LLVM back-end.
Diffstat (limited to 'includes')
-rw-r--r--includes/CodeGen.Platform.hs26
-rw-r--r--includes/stg/MachRegs.h24
-rw-r--r--includes/stg/Regs.h42
-rw-r--r--includes/stg/Types.h2
4 files changed, 82 insertions, 12 deletions
diff --git a/includes/CodeGen.Platform.hs b/includes/CodeGen.Platform.hs
index 14642bd1c5..beff19601d 100644
--- a/includes/CodeGen.Platform.hs
+++ b/includes/CodeGen.Platform.hs
@@ -388,36 +388,54 @@ activeStgRegs = [
#ifdef REG_D1
,DoubleReg 1
#endif
+#ifdef REG_XMM1
+ ,XmmReg 1
+#endif
#ifdef REG_F2
,FloatReg 2
#endif
#ifdef REG_D2
,DoubleReg 2
#endif
+#ifdef REG_XMM2
+ ,XmmReg 2
+#endif
#ifdef REG_F3
,FloatReg 3
#endif
#ifdef REG_D3
,DoubleReg 3
#endif
+#ifdef REG_XMM3
+ ,XmmReg 3
+#endif
#ifdef REG_F4
,FloatReg 4
#endif
#ifdef REG_D4
,DoubleReg 4
#endif
+#ifdef REG_XMM4
+ ,XmmReg 4
+#endif
#ifdef REG_F5
,FloatReg 5
#endif
#ifdef REG_D5
,DoubleReg 5
#endif
+#ifdef REG_XMM5
+ ,XmmReg 5
+#endif
#ifdef REG_F6
,FloatReg 6
#endif
#ifdef REG_D6
,DoubleReg 6
#endif
+#ifdef REG_XMM6
+ ,XmmReg 6
+#endif
#else /* MAX_REAL_SSE_REG == 0 */
#ifdef REG_F1
,FloatReg 1
@@ -569,6 +587,14 @@ globalRegMaybe (DoubleReg 6) =
Just (RealRegSingle REG_D6)
# endif
# endif
+#if MAX_REAL_SSE_REG != 0
+globalRegMaybe (XmmReg 1) = Just (RealRegSingle REG_XMM1)
+globalRegMaybe (XmmReg 2) = Just (RealRegSingle REG_XMM2)
+globalRegMaybe (XmmReg 3) = Just (RealRegSingle REG_XMM3)
+globalRegMaybe (XmmReg 4) = Just (RealRegSingle REG_XMM4)
+globalRegMaybe (XmmReg 5) = Just (RealRegSingle REG_XMM5)
+globalRegMaybe (XmmReg 6) = Just (RealRegSingle REG_XMM6)
+# endif
# ifdef REG_Sp
globalRegMaybe Sp = Just (RealRegSingle REG_Sp)
# endif
diff --git a/includes/stg/MachRegs.h b/includes/stg/MachRegs.h
index 6dc81f63c1..76bdb1fc21 100644
--- a/includes/stg/MachRegs.h
+++ b/includes/stg/MachRegs.h
@@ -167,12 +167,12 @@
#define REG_D5 xmm5
#define REG_D6 xmm6
-#define REG_SSE1 xmm1
-#define REG_SSE2 xmm2
-#define REG_SSE3 xmm3
-#define REG_SSE4 xmm4
-#define REG_SSE5 xmm5
-#define REG_SSE6 xmm6
+#define REG_XMM1 xmm1
+#define REG_XMM2 xmm2
+#define REG_XMM3 xmm3
+#define REG_XMM4 xmm4
+#define REG_XMM5 xmm5
+#define REG_XMM6 xmm6
#if !defined(mingw32_HOST_OS)
#define CALLER_SAVES_R3
@@ -199,13 +199,13 @@
#define CALLER_SAVES_D6
#endif
-#define CALLER_SAVES_SSE1
-#define CALLER_SAVES_SSE2
-#define CALLER_SAVES_SSE3
-#define CALLER_SAVES_SSE4
-#define CALLER_SAVES_SSE5
+#define CALLER_SAVES_XMM1
+#define CALLER_SAVES_XMM2
+#define CALLER_SAVES_XMM3
+#define CALLER_SAVES_XMM4
+#define CALLER_SAVES_XMM5
#if !defined(mingw32_HOST_OS)
-#define CALLER_SAVES_SSE6
+#define CALLER_SAVES_XMM6
#endif
#define MAX_REAL_VANILLA_REG 6
diff --git a/includes/stg/Regs.h b/includes/stg/Regs.h
index fd1577e71a..10ae2851ac 100644
--- a/includes/stg/Regs.h
+++ b/includes/stg/Regs.h
@@ -81,6 +81,12 @@ typedef struct {
StgDouble rD4;
StgDouble rD5;
StgDouble rD6;
+ StgWord128 rXMM1;
+ StgWord128 rXMM2;
+ StgWord128 rXMM3;
+ StgWord128 rXMM4;
+ StgWord128 rXMM5;
+ StgWord128 rXMM6;
StgWord64 rL1;
StgPtr rSp;
StgPtr rSpLim;
@@ -270,6 +276,42 @@ GLOBAL_REG_DECL(StgDouble,D6,REG_D6)
#define D6 (BaseReg->rD6)
#endif
+#if defined(REG_XMM1) && !defined(NO_GLOBAL_REG_DECLS)
+GLOBAL_REG_DECL(StgWord128,XMM1,REG_XMM1)
+#else
+#define XMM1 (BaseReg->rXMM1)
+#endif
+
+#if defined(REG_XMM2) && !defined(NO_GLOBAL_REG_DECLS)
+GLOBAL_REG_DECL(StgWord128,XMM2,REG_XMM2)
+#else
+#define XMM2 (BaseReg->rXMM2)
+#endif
+
+#if defined(REG_XMM3) && !defined(NO_GLOBAL_REG_DECLS)
+GLOBAL_REG_DECL(StgWord128,XMM3,REG_XMM3)
+#else
+#define XMM3 (BaseReg->rXMM3)
+#endif
+
+#if defined(REG_XMM4) && !defined(NO_GLOBAL_REG_DECLS)
+GLOBAL_REG_DECL(StgWord128,XMM4,REG_XMM4)
+#else
+#define XMM4 (BaseReg->rXMM4)
+#endif
+
+#if defined(REG_XMM5) && !defined(NO_GLOBAL_REG_DECLS)
+GLOBAL_REG_DECL(StgWord128,XMM5,REG_XMM5)
+#else
+#define XMM5 (BaseReg->rXMM5)
+#endif
+
+#if defined(REG_XMM6) && !defined(NO_GLOBAL_REG_DECLS)
+GLOBAL_REG_DECL(StgWord128,XMM6,REG_XMM6)
+#else
+#define XMM6 (BaseReg->rXMM6)
+#endif
+
#if defined(REG_L1) && !defined(NO_GLOBAL_REG_DECLS)
GLOBAL_REG_DECL(StgWord64,L1,REG_L1)
#else
diff --git a/includes/stg/Types.h b/includes/stg/Types.h
index d6bdc9042b..ccc06a175b 100644
--- a/includes/stg/Types.h
+++ b/includes/stg/Types.h
@@ -83,6 +83,8 @@ typedef unsigned long long int StgWord64;
#error cannot find a way to define StgInt64
#endif
+typedef struct { StgWord64 h; StgWord64 l; } StgWord128;
+
/*
* Define the standard word size we'll use on this machine: make it
* big enough to hold a pointer.