module Data.Primitive.SIMD.FloatX4 (FloatX4) where
import Data.Primitive.SIMD.Class
import GHC.Types
import GHC.Prim
import GHC.Ptr
import GHC.ST
import Foreign.Storable
import Control.Monad.Primitive
import Data.Primitive.Types
import Data.Primitive.ByteArray
import Data.Primitive.Addr
import Data.Monoid
import Data.Typeable
import qualified Data.Vector.Primitive as PV
import qualified Data.Vector.Primitive.Mutable as PMV
import Data.Vector.Unboxed (Unbox)
import qualified Data.Vector.Unboxed as UV
import Data.Vector.Generic (Vector(..))
import Data.Vector.Generic.Mutable (MVector(..))
data FloatX4 = FloatX4 FloatX4# deriving Typeable
abs' :: Float -> Float
abs' (F# x) = F# (abs# x)
abs# :: Float# -> Float#
abs# x = case abs (F# x) of
F# y -> y
signum' :: Float -> Float
signum' (F# x) = F# (signum# x)
signum# :: Float# -> Float#
signum# x = case signum (F# x) of
F# y -> y
instance Eq FloatX4 where
a == b = case unpackFloatX4 a of
(x1, x2, x3, x4) -> case unpackFloatX4 b of
(y1, y2, y3, y4) -> x1 == y1 && x2 == y2 && x3 == y3 && x4 == y4
instance Ord FloatX4 where
a `compare` b = case unpackFloatX4 a of
(x1, x2, x3, x4) -> case unpackFloatX4 b of
(y1, y2, y3, y4) -> x1 `compare` y1 <> x2 `compare` y2 <> x3 `compare` y3 <> x4 `compare` y4
instance Show FloatX4 where
showsPrec _ a s = case unpackFloatX4 a of
(x1, x2, x3, x4) -> "FloatX4 (" ++ shows x1 (", " ++ shows x2 (", " ++ shows x3 (", " ++ shows x4 (")" ++ s))))
instance Num FloatX4 where
(+) = plusFloatX4
() = minusFloatX4
(*) = timesFloatX4
negate = negateFloatX4
abs = mapVector abs'
signum = mapVector signum'
fromInteger = broadcastVector . fromInteger
instance Fractional FloatX4 where
(/) = divideFloatX4
recip v = broadcastVector 1 / v
fromRational = broadcastVector . fromRational
instance Floating FloatX4 where
pi = broadcastVector pi
exp = mapVector exp
sqrt = mapVector sqrt
log = mapVector log
(**) = zipVector (**)
logBase = zipVector (**)
sin = mapVector sin
tan = mapVector tan
cos = mapVector cos
asin = mapVector asin
atan = mapVector atan
acos = mapVector acos
sinh = mapVector sinh
tanh = mapVector tanh
cosh = mapVector cosh
asinh = mapVector asinh
atanh = mapVector atanh
acosh = mapVector acosh
instance Storable FloatX4 where
sizeOf x = vectorSize x * elementSize x
alignment = sizeOf
peek (Ptr a) = readOffAddr (Addr a) 0
poke (Ptr a) = writeOffAddr (Addr a) 0
instance SIMDVector FloatX4 where
type Elem FloatX4 = Float
type ElemTuple FloatX4 = (Float, Float, Float, Float)
nullVector = broadcastVector 0
vectorSize _ = 4
elementSize _ = 4
broadcastVector = broadcastFloatX4
unsafeInsertVector = unsafeInsertFloatX4
packVector = packFloatX4
unpackVector = unpackFloatX4
mapVector = mapFloatX4
zipVector = zipFloatX4
foldVector = foldFloatX4
instance Prim FloatX4 where
sizeOf# a = let !(I# x) = sizeOf a in x
alignment# a = let !(I# x) = alignment a in x
indexByteArray# ba i = indexFloatX4Array (ByteArray ba) (I# i)
readByteArray# mba i s = let (ST r) = readFloatX4Array (MutableByteArray mba) (I# i) in r s
writeByteArray# mba i v s = let (ST r) = writeFloatX4Array (MutableByteArray mba) (I# i) v in case r s of { (# s', _ #) -> s' }
setByteArray# mba off n v s = let (ST r) = setByteArrayGeneric (MutableByteArray mba) (I# off) (I# n) v in case r s of { (# s', _ #) -> s' }
indexOffAddr# addr i = indexFloatX4OffAddr (Addr addr) (I# i)
readOffAddr# addr i s = let (ST r) = readFloatX4OffAddr (Addr addr) (I# i) in r s
writeOffAddr# addr i v s = let (ST r) = writeFloatX4OffAddr (Addr addr) (I# i) v in case r s of { (# s', _ #) -> s' }
setOffAddr# addr off n v s = let (ST r) = setOffAddrGeneric (Addr addr) (I# off) (I# n) v in case r s of { (# s', _ #) -> s' }
newtype instance UV.Vector FloatX4 = V_FloatX4 (PV.Vector FloatX4)
newtype instance UV.MVector s FloatX4 = MV_FloatX4 (PMV.MVector s FloatX4)
instance Vector UV.Vector FloatX4 where
basicUnsafeFreeze (MV_FloatX4 v) = V_FloatX4 <$> PV.unsafeFreeze v
basicUnsafeThaw (V_FloatX4 v) = MV_FloatX4 <$> PV.unsafeThaw v
basicLength (V_FloatX4 v) = PV.length v
basicUnsafeSlice start len (V_FloatX4 v) = V_FloatX4(PV.unsafeSlice start len v)
basicUnsafeIndexM (V_FloatX4 v) = PV.unsafeIndexM v
basicUnsafeCopy (MV_FloatX4 m) (V_FloatX4 v) = PV.unsafeCopy m v
elemseq _ = seq
instance MVector UV.MVector FloatX4 where
basicLength (MV_FloatX4 v) = PMV.length v
basicUnsafeSlice start len (MV_FloatX4 v) = MV_FloatX4(PMV.unsafeSlice start len v)
basicOverlaps (MV_FloatX4 v) (MV_FloatX4 w) = PMV.overlaps v w
basicUnsafeNew len = MV_FloatX4 <$> PMV.unsafeNew len
#if MIN_VERSION_vector(0,11,0)
basicInitialize (MV_FloatX4 v) = basicInitialize v
#endif
basicUnsafeRead (MV_FloatX4 v) = PMV.unsafeRead v
basicUnsafeWrite (MV_FloatX4 v) = PMV.unsafeWrite v
instance Unbox FloatX4
broadcastFloatX4 :: Float -> FloatX4
broadcastFloatX4 (F# x) = FloatX4 (broadcastFloatX4# x)
packFloatX4 :: (Float, Float, Float, Float) -> FloatX4
packFloatX4 (F# x1, F# x2, F# x3, F# x4) = FloatX4 (packFloatX4# (# x1, x2, x3, x4 #))
unpackFloatX4 :: FloatX4 -> (Float, Float, Float, Float)
unpackFloatX4 (FloatX4 m1) = case unpackFloatX4# m1 of
(# x1, x2, x3, x4 #) -> (F# x1, F# x2, F# x3, F# x4)
unsafeInsertFloatX4 :: FloatX4 -> Float -> Int -> FloatX4
unsafeInsertFloatX4 (FloatX4 m1) (F# y) _i@(I# ip) = FloatX4 (insertFloatX4# m1 y (ip -# 0#))
mapFloatX4 :: (Float -> Float) -> FloatX4 -> FloatX4
mapFloatX4 f = mapFloatX4# (\ x -> case f (F# x) of { F# y -> y})
mapFloatX4# :: (Float# -> Float#) -> FloatX4 -> FloatX4
mapFloatX4# f = \ v -> case unpackFloatX4 v of
(F# x1, F# x2, F# x3, F# x4) -> packFloatX4 (F# (f x1), F# (f x2), F# (f x3), F# (f x4))
zipFloatX4 :: (Float -> Float -> Float) -> FloatX4 -> FloatX4 -> FloatX4
zipFloatX4 f = \ v1 v2 -> case unpackFloatX4 v1 of
(x1, x2, x3, x4) -> case unpackFloatX4 v2 of
(y1, y2, y3, y4) -> packFloatX4 (f x1 y1, f x2 y2, f x3 y3, f x4 y4)
foldFloatX4 :: (Float -> Float -> Float) -> FloatX4 -> Float
foldFloatX4 f' = \ v -> case unpackFloatX4 v of
(x1, x2, x3, x4) -> x1 `f` x2 `f` x3 `f` x4
where f !x !y = f' x y
plusFloatX4 :: FloatX4 -> FloatX4 -> FloatX4
plusFloatX4 (FloatX4 m1_1) (FloatX4 m1_2) = FloatX4 (plusFloatX4# m1_1 m1_2)
minusFloatX4 :: FloatX4 -> FloatX4 -> FloatX4
minusFloatX4 (FloatX4 m1_1) (FloatX4 m1_2) = FloatX4 (minusFloatX4# m1_1 m1_2)
timesFloatX4 :: FloatX4 -> FloatX4 -> FloatX4
timesFloatX4 (FloatX4 m1_1) (FloatX4 m1_2) = FloatX4 (timesFloatX4# m1_1 m1_2)
divideFloatX4 :: FloatX4 -> FloatX4 -> FloatX4
divideFloatX4 (FloatX4 m1_1) (FloatX4 m1_2) = FloatX4 (divideFloatX4# m1_1 m1_2)
negateFloatX4 :: FloatX4 -> FloatX4
negateFloatX4 (FloatX4 m1_1) = FloatX4 (negateFloatX4# m1_1)
indexFloatX4Array :: ByteArray -> Int -> FloatX4
indexFloatX4Array (ByteArray a) (I# i) = FloatX4 (indexFloatX4Array# a i)
readFloatX4Array :: PrimMonad m => MutableByteArray (PrimState m) -> Int -> m FloatX4
readFloatX4Array (MutableByteArray a) (I# i) = primitive (\ s0 -> case readFloatX4Array# a ((i *# 1#) +# 0#) s0 of
(# s1, m1 #) -> (# s1, FloatX4 m1 #))
writeFloatX4Array :: PrimMonad m => MutableByteArray (PrimState m) -> Int -> FloatX4 -> m ()
writeFloatX4Array (MutableByteArray a) (I# i) (FloatX4 m1) = primitive_ (writeFloatX4Array# a ((i *# 1#) +# 0#) m1)
indexFloatX4OffAddr :: Addr -> Int -> FloatX4
indexFloatX4OffAddr (Addr a) (I# i) = FloatX4 (indexFloatX4OffAddr# (plusAddr# a (i *# 16#)) 0#)
readFloatX4OffAddr :: PrimMonad m => Addr -> Int -> m FloatX4
readFloatX4OffAddr (Addr a) (I# i) = primitive (\ s0 -> case (\ addr i' -> readFloatX4OffAddr# (plusAddr# addr i') 0#) a ((i *# 16#) +# 0#) s0 of
(# s1, m1 #) -> (# s1, FloatX4 m1 #))
writeFloatX4OffAddr :: PrimMonad m => Addr -> Int -> FloatX4 -> m ()
writeFloatX4OffAddr (Addr a) (I# i) (FloatX4 m1) = primitive_ (writeFloatX4OffAddr# (plusAddr# a ((i *# 16#) +# 0#)) 0# m1)