diff options
author | Geoffrey Mainland <gmainlan@microsoft.com> | 2012-10-31 15:42:01 +0000 |
---|---|---|
committer | Geoffrey Mainland <gmainlan@microsoft.com> | 2013-02-01 22:00:24 +0000 |
commit | 33bfc6a700eaab9bc06974d6f71a80e61d9177c9 (patch) | |
tree | 842bf82b7dbdafe04820349e5e991800a3cf0646 /includes | |
parent | 1811440833da92eefd7b7255915855fddc64994c (diff) | |
download | haskell-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.hs | 26 | ||||
-rw-r--r-- | includes/stg/MachRegs.h | 24 | ||||
-rw-r--r-- | includes/stg/Regs.h | 42 | ||||
-rw-r--r-- | includes/stg/Types.h | 2 |
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. |