{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
module Data.SBV.Core.Splittable (Splittable(..)) where
import Data.Bits (Bits(..))
import Data.Word (Word8, Word16, Word32, Word64)
import Data.SBV.Core.Operations
import Data.SBV.Core.Data
import Data.SBV.Core.Model ()
infixr 5 #
class Splittable a b | b -> a where
split :: a -> (b, b)
(#) :: b -> b -> a
extend :: b -> a
{-# MINIMAL split, (#), extend #-}
genSplit :: (Integral a, Num b) => Int -> a -> (b, b)
genSplit ss x = (fromIntegral ((ix `shiftR` ss) .&. mask), fromIntegral (ix .&. mask))
where ix = toInteger x
mask = 2 ^ ss - 1
genJoin :: (Integral b, Num a) => Int -> b -> b -> a
genJoin ss x y = fromIntegral ((ix `shiftL` ss) .|. iy)
where ix = toInteger x
iy = toInteger y
instance Splittable Word64 Word32 where
split = genSplit 32
(#) = genJoin 32
extend b = 0 # b
instance Splittable Word32 Word16 where
split = genSplit 16
(#) = genJoin 16
extend b = 0 # b
instance Splittable Word16 Word8 where
split = genSplit 8
(#) = genJoin 8
extend b = 0 # b
instance Splittable SWord64 SWord32 where
split (SBV x) = (SBV (svExtract 63 32 x), SBV (svExtract 31 0 x))
SBV a # SBV b = SBV (svJoin a b)
extend b = 0 # b
instance Splittable SWord32 SWord16 where
split (SBV x) = (SBV (svExtract 31 16 x), SBV (svExtract 15 0 x))
SBV a # SBV b = SBV (svJoin a b)
extend b = 0 # b
instance Splittable SWord16 SWord8 where
split (SBV x) = (SBV (svExtract 15 8 x), SBV (svExtract 7 0 x))
SBV a # SBV b = SBV (svJoin a b)
extend b = 0 # b