module Data.Primitive.SIMD.DoubleX2 (DoubleX2) 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 DoubleX2 = DoubleX2 DoubleX2# deriving Typeable
abs' :: Double -> Double
abs' (D# x) = D# (abs# x)
abs# :: Double# -> Double#
abs# x = case abs (D# x) of
D# y -> y
signum' :: Double -> Double
signum' (D# x) = D# (signum# x)
signum# :: Double# -> Double#
signum# x = case signum (D# x) of
D# y -> y
instance Eq DoubleX2 where
a == b = case unpackDoubleX2 a of
(x1, x2) -> case unpackDoubleX2 b of
(y1, y2) -> x1 == y1 && x2 == y2
instance Ord DoubleX2 where
a `compare` b = case unpackDoubleX2 a of
(x1, x2) -> case unpackDoubleX2 b of
(y1, y2) -> x1 `compare` y1 <> x2 `compare` y2
instance Show DoubleX2 where
showsPrec _ a s = case unpackDoubleX2 a of
(x1, x2) -> "DoubleX2 (" ++ shows x1 (", " ++ shows x2 (")" ++ s))
instance Num DoubleX2 where
(+) = plusDoubleX2
() = minusDoubleX2
(*) = timesDoubleX2
negate = negateDoubleX2
abs = mapVector abs'
signum = mapVector signum'
fromInteger = broadcastVector . fromInteger
instance Fractional DoubleX2 where
(/) = divideDoubleX2
recip v = broadcastVector 1 / v
fromRational = broadcastVector . fromRational
instance Floating DoubleX2 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 DoubleX2 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 DoubleX2 where
type Elem DoubleX2 = Double
type ElemTuple DoubleX2 = (Double, Double)
nullVector = broadcastVector 0
vectorSize _ = 2
elementSize _ = 8
broadcastVector = broadcastDoubleX2
unsafeInsertVector = unsafeInsertDoubleX2
packVector = packDoubleX2
unpackVector = unpackDoubleX2
mapVector = mapDoubleX2
zipVector = zipDoubleX2
foldVector = foldDoubleX2
instance Prim DoubleX2 where
sizeOf# a = let !(I# x) = sizeOf a in x
alignment# a = let !(I# x) = alignment a in x
indexByteArray# ba i = indexDoubleX2Array (ByteArray ba) (I# i)
readByteArray# mba i s = let (ST r) = readDoubleX2Array (MutableByteArray mba) (I# i) in r s
writeByteArray# mba i v s = let (ST r) = writeDoubleX2Array (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 = indexDoubleX2OffAddr (Addr addr) (I# i)
readOffAddr# addr i s = let (ST r) = readDoubleX2OffAddr (Addr addr) (I# i) in r s
writeOffAddr# addr i v s = let (ST r) = writeDoubleX2OffAddr (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 DoubleX2 = V_DoubleX2 (PV.Vector DoubleX2)
newtype instance UV.MVector s DoubleX2 = MV_DoubleX2 (PMV.MVector s DoubleX2)
instance Vector UV.Vector DoubleX2 where
basicUnsafeFreeze (MV_DoubleX2 v) = V_DoubleX2 <$> PV.unsafeFreeze v
basicUnsafeThaw (V_DoubleX2 v) = MV_DoubleX2 <$> PV.unsafeThaw v
basicLength (V_DoubleX2 v) = PV.length v
basicUnsafeSlice start len (V_DoubleX2 v) = V_DoubleX2(PV.unsafeSlice start len v)
basicUnsafeIndexM (V_DoubleX2 v) = PV.unsafeIndexM v
basicUnsafeCopy (MV_DoubleX2 m) (V_DoubleX2 v) = PV.unsafeCopy m v
elemseq _ = seq
instance MVector UV.MVector DoubleX2 where
basicLength (MV_DoubleX2 v) = PMV.length v
basicUnsafeSlice start len (MV_DoubleX2 v) = MV_DoubleX2(PMV.unsafeSlice start len v)
basicOverlaps (MV_DoubleX2 v) (MV_DoubleX2 w) = PMV.overlaps v w
basicUnsafeNew len = MV_DoubleX2 <$> PMV.unsafeNew len
#if MIN_VERSION_vector(0,11,0)
basicInitialize (MV_DoubleX2 v) = basicInitialize v
#endif
basicUnsafeRead (MV_DoubleX2 v) = PMV.unsafeRead v
basicUnsafeWrite (MV_DoubleX2 v) = PMV.unsafeWrite v
instance Unbox DoubleX2
broadcastDoubleX2 :: Double -> DoubleX2
broadcastDoubleX2 (D# x) = DoubleX2 (broadcastDoubleX2# x)
packDoubleX2 :: (Double, Double) -> DoubleX2
packDoubleX2 (D# x1, D# x2) = DoubleX2 (packDoubleX2# (# x1, x2 #))
unpackDoubleX2 :: DoubleX2 -> (Double, Double)
unpackDoubleX2 (DoubleX2 m1) = case unpackDoubleX2# m1 of
(# x1, x2 #) -> (D# x1, D# x2)
unsafeInsertDoubleX2 :: DoubleX2 -> Double -> Int -> DoubleX2
unsafeInsertDoubleX2 (DoubleX2 m1) (D# y) _i@(I# ip) = DoubleX2 (insertDoubleX2# m1 y (ip -# 0#))
mapDoubleX2 :: (Double -> Double) -> DoubleX2 -> DoubleX2
mapDoubleX2 f = mapDoubleX2# (\ x -> case f (D# x) of { D# y -> y})
mapDoubleX2# :: (Double# -> Double#) -> DoubleX2 -> DoubleX2
mapDoubleX2# f = \ v -> case unpackDoubleX2 v of
(D# x1, D# x2) -> packDoubleX2 (D# (f x1), D# (f x2))
zipDoubleX2 :: (Double -> Double -> Double) -> DoubleX2 -> DoubleX2 -> DoubleX2
zipDoubleX2 f = \ v1 v2 -> case unpackDoubleX2 v1 of
(x1, x2) -> case unpackDoubleX2 v2 of
(y1, y2) -> packDoubleX2 (f x1 y1, f x2 y2)
foldDoubleX2 :: (Double -> Double -> Double) -> DoubleX2 -> Double
foldDoubleX2 f' = \ v -> case unpackDoubleX2 v of
(x1, x2) -> x1 `f` x2
where f !x !y = f' x y
plusDoubleX2 :: DoubleX2 -> DoubleX2 -> DoubleX2
plusDoubleX2 (DoubleX2 m1_1) (DoubleX2 m1_2) = DoubleX2 (plusDoubleX2# m1_1 m1_2)
minusDoubleX2 :: DoubleX2 -> DoubleX2 -> DoubleX2
minusDoubleX2 (DoubleX2 m1_1) (DoubleX2 m1_2) = DoubleX2 (minusDoubleX2# m1_1 m1_2)
timesDoubleX2 :: DoubleX2 -> DoubleX2 -> DoubleX2
timesDoubleX2 (DoubleX2 m1_1) (DoubleX2 m1_2) = DoubleX2 (timesDoubleX2# m1_1 m1_2)
divideDoubleX2 :: DoubleX2 -> DoubleX2 -> DoubleX2
divideDoubleX2 (DoubleX2 m1_1) (DoubleX2 m1_2) = DoubleX2 (divideDoubleX2# m1_1 m1_2)
negateDoubleX2 :: DoubleX2 -> DoubleX2
negateDoubleX2 (DoubleX2 m1_1) = DoubleX2 (negateDoubleX2# m1_1)
indexDoubleX2Array :: ByteArray -> Int -> DoubleX2
indexDoubleX2Array (ByteArray a) (I# i) = DoubleX2 (indexDoubleX2Array# a i)
readDoubleX2Array :: PrimMonad m => MutableByteArray (PrimState m) -> Int -> m DoubleX2
readDoubleX2Array (MutableByteArray a) (I# i) = primitive (\ s0 -> case readDoubleX2Array# a ((i *# 1#) +# 0#) s0 of
(# s1, m1 #) -> (# s1, DoubleX2 m1 #))
writeDoubleX2Array :: PrimMonad m => MutableByteArray (PrimState m) -> Int -> DoubleX2 -> m ()
writeDoubleX2Array (MutableByteArray a) (I# i) (DoubleX2 m1) = primitive_ (writeDoubleX2Array# a ((i *# 1#) +# 0#) m1)
indexDoubleX2OffAddr :: Addr -> Int -> DoubleX2
indexDoubleX2OffAddr (Addr a) (I# i) = DoubleX2 (indexDoubleX2OffAddr# (plusAddr# a (i *# 16#)) 0#)
readDoubleX2OffAddr :: PrimMonad m => Addr -> Int -> m DoubleX2
readDoubleX2OffAddr (Addr a) (I# i) = primitive (\ s0 -> case (\ addr i' -> readDoubleX2OffAddr# (plusAddr# addr i') 0#) a ((i *# 16#) +# 0#) s0 of
(# s1, m1 #) -> (# s1, DoubleX2 m1 #))
writeDoubleX2OffAddr :: PrimMonad m => Addr -> Int -> DoubleX2 -> m ()
writeDoubleX2OffAddr (Addr a) (I# i) (DoubleX2 m1) = primitive_ (writeDoubleX2OffAddr# (plusAddr# a ((i *# 16#) +# 0#)) 0# m1)