module LLVM.Extra.Multi.Vector.Memory where
import qualified LLVM.Extra.Multi.Vector as MultiVector
import qualified LLVM.Extra.Multi.Vector.Instance as Inst
import qualified LLVM.Extra.Multi.Value.Memory as MultiMem
import LLVM.Extra.MemoryPrivate (decomposeFromLoad, composeFromStore, )
import qualified LLVM.Core as LLVM
import LLVM.Core (CodeGenFunction, Value, )
import qualified Type.Data.Num.Decimal as TypeNum
import Type.Data.Num.Decimal ((:*:), )
import Foreign.Ptr (Ptr, )
import Control.Applicative (liftA2, liftA3, )
import Data.Word (Word8, Word16, Word32, Word64)
import Data.Int (Int8, Int16, Int32, Int64)
class
(TypeNum.Positive n, MultiVector.C a, LLVM.IsSized (Struct n a)) =>
C n a where
type Struct n a :: *
load :: Value (Ptr (Struct n a)) -> CodeGenFunction r (MultiVector.T n a)
load ptr = decompose =<< LLVM.load ptr
store :: MultiVector.T n a -> Value (Ptr (Struct n a)) -> CodeGenFunction r ()
store r ptr = flip LLVM.store ptr =<< compose r
decompose :: Value (Struct n a) -> CodeGenFunction r (MultiVector.T n a)
decompose = decomposeFromLoad load
compose :: MultiVector.T n a -> CodeGenFunction r (Value (Struct n a))
compose = composeFromStore store
instance
(TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D8)) =>
C n Word8 where
type Struct n Word8 = LLVM.Vector n Word8
load = fmap MultiVector.consPrim . LLVM.load
store = LLVM.store . MultiVector.deconsPrim
decompose = return . MultiVector.consPrim
compose = return . MultiVector.deconsPrim
instance
(TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D16)) =>
C n Word16 where
type Struct n Word16 = LLVM.Vector n Word16
load = fmap MultiVector.consPrim . LLVM.load
store = LLVM.store . MultiVector.deconsPrim
decompose = return . MultiVector.consPrim
compose = return . MultiVector.deconsPrim
instance
(TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D32)) =>
C n Word32 where
type Struct n Word32 = LLVM.Vector n Word32
load = fmap MultiVector.consPrim . LLVM.load
store = LLVM.store . MultiVector.deconsPrim
decompose = return . MultiVector.consPrim
compose = return . MultiVector.deconsPrim
instance
(TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D64)) =>
C n Word64 where
type Struct n Word64 = LLVM.Vector n Word64
load = fmap MultiVector.consPrim . LLVM.load
store = LLVM.store . MultiVector.deconsPrim
decompose = return . MultiVector.consPrim
compose = return . MultiVector.deconsPrim
instance
(TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D8)) =>
C n Int8 where
type Struct n Int8 = LLVM.Vector n Int8
load = fmap MultiVector.consPrim . LLVM.load
store = LLVM.store . MultiVector.deconsPrim
decompose = return . MultiVector.consPrim
compose = return . MultiVector.deconsPrim
instance
(TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D16)) =>
C n Int16 where
type Struct n Int16 = LLVM.Vector n Int16
load = fmap MultiVector.consPrim . LLVM.load
store = LLVM.store . MultiVector.deconsPrim
decompose = return . MultiVector.consPrim
compose = return . MultiVector.deconsPrim
instance
(TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D32)) =>
C n Int32 where
type Struct n Int32 = LLVM.Vector n Int32
load = fmap MultiVector.consPrim . LLVM.load
store = LLVM.store . MultiVector.deconsPrim
decompose = return . MultiVector.consPrim
compose = return . MultiVector.deconsPrim
instance
(TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D64)) =>
C n Int64 where
type Struct n Int64 = LLVM.Vector n Int64
load = fmap MultiVector.consPrim . LLVM.load
store = LLVM.store . MultiVector.deconsPrim
decompose = return . MultiVector.consPrim
compose = return . MultiVector.deconsPrim
instance
(TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D32)) =>
C n Float where
type Struct n Float = LLVM.Vector n Float
load = fmap MultiVector.consPrim . LLVM.load
store = LLVM.store . MultiVector.deconsPrim
decompose = return . MultiVector.consPrim
compose = return . MultiVector.deconsPrim
instance
(TypeNum.Positive n, TypeNum.Positive (n :*: TypeNum.D64)) =>
C n Double where
type Struct n Double = LLVM.Vector n Double
load = fmap MultiVector.consPrim . LLVM.load
store = LLVM.store . MultiVector.deconsPrim
decompose = return . MultiVector.consPrim
compose = return . MultiVector.deconsPrim
instance (C n a, C n b) => C n (a,b) where
type Struct n (a,b) = (LLVM.Struct (Struct n a, (Struct n b, ())))
decompose ab =
liftA2 MultiVector.zip
(decompose =<< LLVM.extractvalue ab TypeNum.d0)
(decompose =<< LLVM.extractvalue ab TypeNum.d1)
compose ab =
case MultiVector.unzip ab of
(a,b) -> do
sa <- compose a
sb <- compose b
ra <- LLVM.insertvalue (LLVM.value LLVM.undef) sa TypeNum.d0
LLVM.insertvalue ra sb TypeNum.d1
instance (C n a, C n b, C n c) => C n (a,b,c) where
type Struct n (a,b,c) =
(LLVM.Struct (Struct n a, (Struct n b, (Struct n c, ()))))
decompose abc =
liftA3 MultiVector.zip3
(decompose =<< LLVM.extractvalue abc TypeNum.d0)
(decompose =<< LLVM.extractvalue abc TypeNum.d1)
(decompose =<< LLVM.extractvalue abc TypeNum.d2)
compose abc =
case MultiVector.unzip3 abc of
(a,b,c) -> do
sa <- compose a
sb <- compose b
sc <- compose c
ra <- LLVM.insertvalue (LLVM.value LLVM.undef) sa TypeNum.d0
rb <- LLVM.insertvalue ra sb TypeNum.d1
LLVM.insertvalue rb sc TypeNum.d2
instance (C n a) => MultiMem.C (LLVM.Vector n a) where
type Struct (LLVM.Vector n a) = Struct n a
load = fmap Inst.toMultiValue . load
store = store . Inst.fromMultiValue
decompose = fmap Inst.toMultiValue . decompose
compose = compose . Inst.fromMultiValue