diff options
author | Geoffrey Mainland <gmainlan@microsoft.com> | 2012-10-19 09:32:02 +0100 |
---|---|---|
committer | Geoffrey Mainland <gmainlan@microsoft.com> | 2013-02-01 22:00:23 +0000 |
commit | 515ba6f18b6ed8ac9167588b8c6099ef85d5e517 (patch) | |
tree | da139c9b29dc342eca13592628913fd406229432 /compiler/cmm | |
parent | f70b6b621153cd3af8b999eac4f6fab2162befa7 (diff) | |
download | haskell-515ba6f18b6ed8ac9167588b8c6099ef85d5e517.tar.gz |
Add Cmm support for representing 128-bit-wide SIMD vectors.
Diffstat (limited to 'compiler/cmm')
-rw-r--r-- | compiler/cmm/CmmCallConv.hs | 7 | ||||
-rw-r--r-- | compiler/cmm/CmmCommonBlockElim.hs | 1 | ||||
-rw-r--r-- | compiler/cmm/CmmExpr.hs | 7 | ||||
-rw-r--r-- | compiler/cmm/CmmType.hs | 86 | ||||
-rw-r--r-- | compiler/cmm/PprC.hs | 2 | ||||
-rw-r--r-- | compiler/cmm/PprCmmExpr.hs | 1 |
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 '-' |