Commit 515ba6f1 authored by gmainlan@microsoft.com's avatar gmainlan@microsoft.com
Browse files

Add Cmm support for representing 128-bit-wide SIMD vectors.

parent f70b6b62
...@@ -67,8 +67,11 @@ assignArgumentsPos dflags off conv arg_ty reps = (stk_off, assignments) ...@@ -67,8 +67,11 @@ assignArgumentsPos dflags off conv arg_ty reps = (stk_off, assignments)
assignments = reg_assts ++ stk_assts assignments = reg_assts ++ stk_assts
assign_regs assts [] _ = (assts, []) assign_regs assts [] _ = (assts, [])
assign_regs assts (r:rs) regs = if isFloatType ty then float else int assign_regs assts (r:rs) regs | isVecType ty = vec
where float = case (w, regs) of | 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, fs, ds, ls, s:ss)) -> k (RegisterParam (FloatReg s), (vs, fs, ds, ls, ss))
(W32, (vs, f:fs, ds, ls, ss)) (W32, (vs, f:fs, ds, ls, ss))
| not hasSseRegs -> k (RegisterParam f, (vs, fs, ds, ls, ss)) | not hasSseRegs -> k (RegisterParam f, (vs, fs, ds, ls, ss))
......
...@@ -119,6 +119,7 @@ hash_block block = ...@@ -119,6 +119,7 @@ hash_block block =
hash_lit :: CmmLit -> Word32 hash_lit :: CmmLit -> Word32
hash_lit (CmmInt i _) = fromInteger i hash_lit (CmmInt i _) = fromInteger i
hash_lit (CmmFloat r _) = truncate r hash_lit (CmmFloat r _) = truncate r
hash_lit (CmmVec ls) = hash_list hash_lit ls
hash_lit (CmmLabel _) = 119 -- ugh hash_lit (CmmLabel _) = 119 -- ugh
hash_lit (CmmLabelOff _ i) = cvt $ 199 + i hash_lit (CmmLabelOff _ i) = cvt $ 199 + i
hash_lit (CmmLabelDiffOff _ _ i) = cvt $ 299 + i hash_lit (CmmLabelDiffOff _ _ i) = cvt $ 299 + i
......
...@@ -33,6 +33,7 @@ import BlockId ...@@ -33,6 +33,7 @@ import BlockId
import CLabel import CLabel
import DynFlags import DynFlags
import Unique import Unique
import Outputable (panic)
import Data.Set (Set) import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
...@@ -101,6 +102,7 @@ data CmmLit ...@@ -101,6 +102,7 @@ data CmmLit
-- it will be used as a signed or unsigned value (the CmmType doesn't -- it will be used as a signed or unsigned value (the CmmType doesn't
-- distinguish between signed & unsigned). -- distinguish between signed & unsigned).
| CmmFloat Rational Width | CmmFloat Rational Width
| CmmVec [CmmLit] -- Vector literal
| CmmLabel CLabel -- Address of label | CmmLabel CLabel -- Address of label
| CmmLabelOff CLabel Int -- Address of label + byte offset | CmmLabelOff CLabel Int -- Address of label + byte offset
...@@ -133,6 +135,11 @@ cmmExprType dflags (CmmStackSlot _ _) = bWord dflags -- an address ...@@ -133,6 +135,11 @@ cmmExprType dflags (CmmStackSlot _ _) = bWord dflags -- an address
cmmLitType :: DynFlags -> CmmLit -> CmmType cmmLitType :: DynFlags -> CmmLit -> CmmType
cmmLitType _ (CmmInt _ width) = cmmBits width cmmLitType _ (CmmInt _ width) = cmmBits width
cmmLitType _ (CmmFloat _ width) = cmmFloat 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 (CmmLabel lbl) = cmmLabelType dflags lbl
cmmLitType dflags (CmmLabelOff lbl _) = cmmLabelType dflags lbl cmmLitType dflags (CmmLabelOff lbl _) = cmmLabelType dflags lbl
cmmLitType dflags (CmmLabelDiffOff {}) = bWord dflags cmmLitType dflags (CmmLabelDiffOff {}) = bWord dflags
......
module CmmType module CmmType
( CmmType -- Abstract ( CmmType -- Abstract
, b8, b16, b32, b64, f32, f64, bWord, bHalfWord, gcWord , b8, b16, b32, b64, b128, f32, f64, bWord, bHalfWord, gcWord
, cInt, cLong , cInt, cLong
, cmmBits, cmmFloat , cmmBits, cmmFloat
, typeWidth, cmmEqType, cmmEqType_ignoring_ptrhood , typeWidth, cmmEqType, cmmEqType_ignoring_ptrhood
...@@ -17,6 +17,13 @@ module CmmType ...@@ -17,6 +17,13 @@ module CmmType
, rEP_StgEntCounter_allocs , rEP_StgEntCounter_allocs
, ForeignHint(..) , ForeignHint(..)
, Length
, vec, vec2, vec4, vec8, vec16
, vec2f64, vec2b64, vec4f32, vec4b32, vec8b16, vec16b8
, cmmVec
, vecLength, vecElemType
, isVecType
) )
where where
...@@ -42,10 +49,11 @@ import Data.Int ...@@ -42,10 +49,11 @@ import Data.Int
data CmmType -- The important one! data CmmType -- The important one!
= CmmType CmmCat Width = CmmType CmmCat Width
data CmmCat -- "Category" (not exported) data CmmCat -- "Category" (not exported)
= GcPtrCat -- GC pointer = GcPtrCat -- GC pointer
| BitsCat -- Non-pointer | BitsCat -- Non-pointer
| FloatCat -- Float | FloatCat -- Float
| VecCat Length CmmCat -- Vector
deriving( Eq ) deriving( Eq )
-- See Note [Signed vs unsigned] at the end -- See Note [Signed vs unsigned] at the end
...@@ -53,9 +61,10 @@ instance Outputable CmmType where ...@@ -53,9 +61,10 @@ instance Outputable CmmType where
ppr (CmmType cat wid) = ppr cat <> ppr (widthInBits wid) ppr (CmmType cat wid) = ppr cat <> ppr (widthInBits wid)
instance Outputable CmmCat where instance Outputable CmmCat where
ppr FloatCat = ptext $ sLit("F") ppr FloatCat = ptext $ sLit("F")
ppr GcPtrCat = ptext $ sLit("P") ppr GcPtrCat = ptext $ sLit("P")
ppr BitsCat = ptext $ sLit("I") 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, -- Why is CmmType stratified? For native code generation,
-- most of the time you just want to know what sort of register -- most of the time you just want to know what sort of register
...@@ -77,10 +86,15 @@ cmmEqType_ignoring_ptrhood :: CmmType -> CmmType -> Bool ...@@ -77,10 +86,15 @@ cmmEqType_ignoring_ptrhood :: CmmType -> CmmType -> Bool
cmmEqType_ignoring_ptrhood (CmmType c1 w1) (CmmType c2 w2) cmmEqType_ignoring_ptrhood (CmmType c1 w1) (CmmType c2 w2)
= c1 `weak_eq` c2 && w1==w2 = c1 `weak_eq` c2 && w1==w2
where where
FloatCat `weak_eq` FloatCat = True weak_eq :: CmmCat -> CmmCat -> Bool
FloatCat `weak_eq` _other = False FloatCat `weak_eq` FloatCat = True
_other `weak_eq` FloatCat = False FloatCat `weak_eq` _other = False
_word1 `weak_eq` _word2 = True -- Ignores GcPtr _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 ----- --- Simple operations on CmmType -----
typeWidth :: CmmType -> Width typeWidth :: CmmType -> Width
...@@ -92,11 +106,12 @@ cmmFloat = CmmType FloatCat ...@@ -92,11 +106,12 @@ cmmFloat = CmmType FloatCat
-------- Common CmmTypes ------------ -------- Common CmmTypes ------------
-- Floats and words of specific widths -- Floats and words of specific widths
b8, b16, b32, b64, f32, f64 :: CmmType b8, b16, b32, b64, b128, f32, f64 :: CmmType
b8 = cmmBits W8 b8 = cmmBits W8
b16 = cmmBits W16 b16 = cmmBits W16
b32 = cmmBits W32 b32 = cmmBits W32
b64 = cmmBits W64 b64 = cmmBits W64
b128 = cmmBits W128
f32 = cmmFloat W32 f32 = cmmFloat W32
f64 = cmmFloat W64 f64 = cmmFloat W64
...@@ -244,6 +259,51 @@ narrowS W32 x = fromIntegral (fromIntegral x :: Int32) ...@@ -244,6 +259,51 @@ narrowS W32 x = fromIntegral (fromIntegral x :: Int32)
narrowS W64 x = fromIntegral (fromIntegral x :: Int64) narrowS W64 x = fromIntegral (fromIntegral x :: Int64)
narrowS _ _ = panic "narrowTo" 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 -- Hints
......
...@@ -467,6 +467,8 @@ pprLit lit = case lit of ...@@ -467,6 +467,8 @@ pprLit lit = case lit of
-- these constants come from <math.h> -- these constants come from <math.h>
-- see #1861 -- see #1861
CmmVec {} -> panic "PprC printing vector literal"
CmmBlock bid -> mkW_ <> pprCLabelAddr (infoTblLbl bid) CmmBlock bid -> mkW_ <> pprCLabelAddr (infoTblLbl bid)
CmmHighStackMark -> panic "PprC printing high stack mark" CmmHighStackMark -> panic "PprC printing high stack mark"
CmmLabel clbl -> mkW_ <> pprCLabelAddr clbl CmmLabel clbl -> mkW_ <> pprCLabelAddr clbl
......
...@@ -194,6 +194,7 @@ pprLit lit = sdocWithDynFlags $ \dflags -> ...@@ -194,6 +194,7 @@ pprLit lit = sdocWithDynFlags $ \dflags ->
space <> dcolon <+> ppr rep ] space <> dcolon <+> ppr rep ]
CmmFloat f rep -> hsep [ double (fromRat f), 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 CmmLabel clbl -> ppr clbl
CmmLabelOff clbl i -> ppr clbl <> ppr_offset i CmmLabelOff clbl i -> ppr clbl <> ppr_offset i
CmmLabelDiffOff clbl1 clbl2 i -> ppr clbl1 <> char '-' CmmLabelDiffOff clbl1 clbl2 i -> ppr clbl1 <> char '-'
......
...@@ -70,7 +70,8 @@ type UnresStatic = Either UnresLabel LlvmStatic ...@@ -70,7 +70,8 @@ type UnresStatic = Either UnresLabel LlvmStatic
-- | Translate a basic CmmType to an LlvmType. -- | Translate a basic CmmType to an LlvmType.
cmmToLlvmType :: CmmType -> LlvmType cmmToLlvmType :: CmmType -> LlvmType
cmmToLlvmType ty | isFloatType ty = widthToLlvmFloat $ typeWidth ty cmmToLlvmType ty | isVecType ty = LMVector (vecLength ty) (cmmToLlvmType (vecElemType ty))
| isFloatType ty = widthToLlvmFloat $ typeWidth ty
| otherwise = widthToLlvmInt $ typeWidth ty | otherwise = widthToLlvmInt $ typeWidth ty
-- | Translate a Cmm Float Width to a LlvmType. -- | Translate a Cmm Float Width to a LlvmType.
......
...@@ -171,6 +171,14 @@ genStaticLit (CmmInt i w) ...@@ -171,6 +171,14 @@ genStaticLit (CmmInt i w)
genStaticLit (CmmFloat r w) genStaticLit (CmmFloat r w)
= Right $ LMStaticLit (LMFloatLit (fromRational r) (widthToLlvmFloat w)) = Right $ LMStaticLit (LMFloatLit (fromRational r) (widthToLlvmFloat w))
genStaticLit (CmmVec ls)
= Right $ LMStaticLit (LMVectorLit (map toLlvmLit ls))
where
toLlvmLit :: CmmLit -> LlvmLit
toLlvmLit lit = case genStaticLit lit of
Right (LMStaticLit llvmLit) -> llvmLit
_ -> panic "genStaticLit"
-- Leave unresolved, will fix later -- Leave unresolved, will fix later
genStaticLit c@(CmmLabel _ ) = Left $ c genStaticLit c@(CmmLabel _ ) = Left $ c
genStaticLit c@(CmmLabelOff _ _) = Left $ c genStaticLit c@(CmmLabelOff _ _) = Left $ c
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment