summaryrefslogtreecommitdiff
path: root/compiler/cmm
diff options
context:
space:
mode:
authorGeoffrey Mainland <gmainlan@microsoft.com>2012-10-19 09:32:02 +0100
committerGeoffrey Mainland <gmainlan@microsoft.com>2013-02-01 22:00:23 +0000
commit515ba6f18b6ed8ac9167588b8c6099ef85d5e517 (patch)
treeda139c9b29dc342eca13592628913fd406229432 /compiler/cmm
parentf70b6b621153cd3af8b999eac4f6fab2162befa7 (diff)
downloadhaskell-515ba6f18b6ed8ac9167588b8c6099ef85d5e517.tar.gz
Add Cmm support for representing 128-bit-wide SIMD vectors.
Diffstat (limited to 'compiler/cmm')
-rw-r--r--compiler/cmm/CmmCallConv.hs7
-rw-r--r--compiler/cmm/CmmCommonBlockElim.hs1
-rw-r--r--compiler/cmm/CmmExpr.hs7
-rw-r--r--compiler/cmm/CmmType.hs86
-rw-r--r--compiler/cmm/PprC.hs2
-rw-r--r--compiler/cmm/PprCmmExpr.hs1
6 files changed, 89 insertions, 15 deletions
diff --git a/compiler/cmm/CmmCallConv.hs b/compiler/cmm/CmmCallConv.hs
index 7007872c0e..dd4d6a6c1a 100644
--- a/compiler/cmm/CmmCallConv.hs
+++ b/compiler/cmm/CmmCallConv.hs
@@ -67,8 +67,11 @@ assignArgumentsPos dflags off conv arg_ty reps = (stk_off, assignments)
assignments = reg_assts ++ stk_assts
assign_regs assts [] _ = (assts, [])
- assign_regs assts (r:rs) regs = if isFloatType ty then float else int
- where float = case (w, regs) of
+ assign_regs assts (r:rs) regs | isVecType ty = vec
+ | isFloatType ty = float
+ | otherwise = int
+ where vec = (assts, (r:rs))
+ float = case (w, regs) of
(W32, (vs, fs, ds, ls, s:ss)) -> k (RegisterParam (FloatReg s), (vs, fs, ds, ls, ss))
(W32, (vs, f:fs, ds, ls, ss))
| not hasSseRegs -> k (RegisterParam f, (vs, fs, ds, ls, ss))
diff --git a/compiler/cmm/CmmCommonBlockElim.hs b/compiler/cmm/CmmCommonBlockElim.hs
index 614edf23a2..522d323042 100644
--- a/compiler/cmm/CmmCommonBlockElim.hs
+++ b/compiler/cmm/CmmCommonBlockElim.hs
@@ -119,6 +119,7 @@ hash_block block =
hash_lit :: CmmLit -> Word32
hash_lit (CmmInt i _) = fromInteger i
hash_lit (CmmFloat r _) = truncate r
+ hash_lit (CmmVec ls) = hash_list hash_lit ls
hash_lit (CmmLabel _) = 119 -- ugh
hash_lit (CmmLabelOff _ i) = cvt $ 199 + i
hash_lit (CmmLabelDiffOff _ _ i) = cvt $ 299 + i
diff --git a/compiler/cmm/CmmExpr.hs b/compiler/cmm/CmmExpr.hs
index 87713c6b0d..dce962443b 100644
--- a/compiler/cmm/CmmExpr.hs
+++ b/compiler/cmm/CmmExpr.hs
@@ -33,6 +33,7 @@ import BlockId
import CLabel
import DynFlags
import Unique
+import Outputable (panic)
import Data.Set (Set)
import qualified Data.Set as Set
@@ -101,6 +102,7 @@ data CmmLit
-- it will be used as a signed or unsigned value (the CmmType doesn't
-- distinguish between signed & unsigned).
| CmmFloat Rational Width
+ | CmmVec [CmmLit] -- Vector literal
| CmmLabel CLabel -- Address of label
| CmmLabelOff CLabel Int -- Address of label + byte offset
@@ -133,6 +135,11 @@ cmmExprType dflags (CmmStackSlot _ _) = bWord dflags -- an address
cmmLitType :: DynFlags -> CmmLit -> CmmType
cmmLitType _ (CmmInt _ width) = cmmBits width
cmmLitType _ (CmmFloat _ width) = cmmFloat width
+cmmLitType _ (CmmVec []) = panic "cmmLitType: CmmVec []"
+cmmLitType cflags (CmmVec (l:ls)) = let ty = cmmLitType cflags l
+ in if all (`cmmEqType` ty) (map (cmmLitType cflags) ls)
+ then cmmVec (1+length ls) ty
+ else panic "cmmLitType: CmmVec"
cmmLitType dflags (CmmLabel lbl) = cmmLabelType dflags lbl
cmmLitType dflags (CmmLabelOff lbl _) = cmmLabelType dflags lbl
cmmLitType dflags (CmmLabelDiffOff {}) = bWord dflags
diff --git a/compiler/cmm/CmmType.hs b/compiler/cmm/CmmType.hs
index 9a443c1ae2..49a2dc1107 100644
--- a/compiler/cmm/CmmType.hs
+++ b/compiler/cmm/CmmType.hs
@@ -1,7 +1,7 @@
module CmmType
( CmmType -- Abstract
- , b8, b16, b32, b64, f32, f64, bWord, bHalfWord, gcWord
+ , b8, b16, b32, b64, b128, f32, f64, bWord, bHalfWord, gcWord
, cInt, cLong
, cmmBits, cmmFloat
, typeWidth, cmmEqType, cmmEqType_ignoring_ptrhood
@@ -17,6 +17,13 @@ module CmmType
, rEP_StgEntCounter_allocs
, ForeignHint(..)
+
+ , Length
+ , vec, vec2, vec4, vec8, vec16
+ , vec2f64, vec2b64, vec4f32, vec4b32, vec8b16, vec16b8
+ , cmmVec
+ , vecLength, vecElemType
+ , isVecType
)
where
@@ -42,10 +49,11 @@ import Data.Int
data CmmType -- The important one!
= CmmType CmmCat Width
-data CmmCat -- "Category" (not exported)
- = GcPtrCat -- GC pointer
- | BitsCat -- Non-pointer
- | FloatCat -- Float
+data CmmCat -- "Category" (not exported)
+ = GcPtrCat -- GC pointer
+ | BitsCat -- Non-pointer
+ | FloatCat -- Float
+ | VecCat Length CmmCat -- Vector
deriving( Eq )
-- See Note [Signed vs unsigned] at the end
@@ -53,9 +61,10 @@ instance Outputable CmmType where
ppr (CmmType cat wid) = ppr cat <> ppr (widthInBits wid)
instance Outputable CmmCat where
- ppr FloatCat = ptext $ sLit("F")
- ppr GcPtrCat = ptext $ sLit("P")
- ppr BitsCat = ptext $ sLit("I")
+ ppr FloatCat = ptext $ sLit("F")
+ ppr GcPtrCat = ptext $ sLit("P")
+ ppr BitsCat = ptext $ sLit("I")
+ ppr (VecCat n cat) = ppr cat <> text "x" <> ppr n <> text "V"
-- Why is CmmType stratified? For native code generation,
-- most of the time you just want to know what sort of register
@@ -77,10 +86,15 @@ cmmEqType_ignoring_ptrhood :: CmmType -> CmmType -> Bool
cmmEqType_ignoring_ptrhood (CmmType c1 w1) (CmmType c2 w2)
= c1 `weak_eq` c2 && w1==w2
where
- FloatCat `weak_eq` FloatCat = True
- FloatCat `weak_eq` _other = False
- _other `weak_eq` FloatCat = False
- _word1 `weak_eq` _word2 = True -- Ignores GcPtr
+ weak_eq :: CmmCat -> CmmCat -> Bool
+ FloatCat `weak_eq` FloatCat = True
+ FloatCat `weak_eq` _other = False
+ _other `weak_eq` FloatCat = False
+ (VecCat l1 cat1) `weak_eq` (VecCat l2 cat2) = l1 == l2
+ && cat1 `weak_eq` cat2
+ (VecCat {}) `weak_eq` _other = False
+ _other `weak_eq` (VecCat {}) = False
+ _word1 `weak_eq` _word2 = True -- Ignores GcPtr
--- Simple operations on CmmType -----
typeWidth :: CmmType -> Width
@@ -92,11 +106,12 @@ cmmFloat = CmmType FloatCat
-------- Common CmmTypes ------------
-- Floats and words of specific widths
-b8, b16, b32, b64, f32, f64 :: CmmType
+b8, b16, b32, b64, b128, f32, f64 :: CmmType
b8 = cmmBits W8
b16 = cmmBits W16
b32 = cmmBits W32
b64 = cmmBits W64
+b128 = cmmBits W128
f32 = cmmFloat W32
f64 = cmmFloat W64
@@ -244,6 +259,51 @@ narrowS W32 x = fromIntegral (fromIntegral x :: Int32)
narrowS W64 x = fromIntegral (fromIntegral x :: Int64)
narrowS _ _ = panic "narrowTo"
+-----------------------------------------------------------------------------
+-- SIMD
+-----------------------------------------------------------------------------
+
+type Length = Int
+
+vec :: Length -> CmmType -> CmmType
+vec l (CmmType cat w) = CmmType (VecCat l cat) vecw
+ where
+ vecw :: Width
+ vecw = widthFromBytes (l*widthInBytes w)
+
+vec2, vec4, vec8, vec16 :: CmmType -> CmmType
+vec2 = vec 2
+vec4 = vec 4
+vec8 = vec 8
+vec16 = vec 16
+
+vec2f64, vec2b64, vec4f32, vec4b32, vec8b16, vec16b8 :: CmmType
+vec2f64 = vec 2 f64
+vec2b64 = vec 2 b64
+vec4f32 = vec 4 f32
+vec4b32 = vec 4 b32
+vec8b16 = vec 8 b16
+vec16b8 = vec 16 b8
+
+cmmVec :: Int -> CmmType -> CmmType
+cmmVec n (CmmType cat w) =
+ CmmType (VecCat n cat) (widthFromBytes (n*widthInBytes w))
+
+vecLength :: CmmType -> Length
+vecLength (CmmType (VecCat l _) _) = l
+vecLength _ = panic "vecLength: not a vector"
+
+vecElemType :: CmmType -> CmmType
+vecElemType (CmmType (VecCat l cat) w) = CmmType cat scalw
+ where
+ scalw :: Width
+ scalw = widthFromBytes (widthInBytes w `div` l)
+vecElemType _ = panic "vecElemType: not a vector"
+
+isVecType :: CmmType -> Bool
+isVecType (CmmType (VecCat {}) _) = True
+isVecType _ = False
+
-------------------------------------------------------------------------
-- Hints
diff --git a/compiler/cmm/PprC.hs b/compiler/cmm/PprC.hs
index 45f46b83ba..2ca8b67d72 100644
--- a/compiler/cmm/PprC.hs
+++ b/compiler/cmm/PprC.hs
@@ -467,6 +467,8 @@ pprLit lit = case lit of
-- these constants come from <math.h>
-- see #1861
+ CmmVec {} -> panic "PprC printing vector literal"
+
CmmBlock bid -> mkW_ <> pprCLabelAddr (infoTblLbl bid)
CmmHighStackMark -> panic "PprC printing high stack mark"
CmmLabel clbl -> mkW_ <> pprCLabelAddr clbl
diff --git a/compiler/cmm/PprCmmExpr.hs b/compiler/cmm/PprCmmExpr.hs
index 71c84464ad..3c9fa063ff 100644
--- a/compiler/cmm/PprCmmExpr.hs
+++ b/compiler/cmm/PprCmmExpr.hs
@@ -194,6 +194,7 @@ pprLit lit = sdocWithDynFlags $ \dflags ->
space <> dcolon <+> ppr rep ]
CmmFloat f rep -> hsep [ double (fromRat f), dcolon, ppr rep ]
+ CmmVec lits -> char '<' <> commafy (map pprLit lits) <> char '>'
CmmLabel clbl -> ppr clbl
CmmLabelOff clbl i -> ppr clbl <> ppr_offset i
CmmLabelDiffOff clbl1 clbl2 i -> ppr clbl1 <> char '-'