module HaskellWorks.Data.Simd.Internal.Bits where

import Data.Bits.Pext
import Data.Word
import HaskellWorks.Data.Bits.BitWise

import qualified Data.Vector.Storable as DVS

testWord8s :: Word64 -> Word64
testWord8s :: Word64 -> Word64
testWord8s Word64
w =  let w8s :: Word64
w8s = Word64
w
                    w4s :: Word64
w4s = Word64
w8s Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.|. (Word64
w8s Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
4)
                    w2s :: Word64
w2s = Word64
w4s Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.|. (Word64
w4s Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
2)
                    w1s :: Word64
w1s = Word64
w2s Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.|. (Word64
w2s Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
1)
                in  Word64 -> Word64 -> Word64
forall a. Pext a => a -> a -> a
pext Word64
w1s Word64
0x0101010101010101
{-# INLINE testWord8s #-}

zipOr :: DVS.Vector Word64 -> DVS.Vector Word64 -> DVS.Vector Word64
zipOr :: Vector Word64 -> Vector Word64 -> Vector Word64
zipOr Vector Word64
as Vector Word64
bs = Int -> (Vector Word64 -> Word64) -> Vector Word64
forall a. Storable a => Int -> (Vector a -> a) -> Vector a
DVS.constructN (Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
as Int -> Int -> Int
forall a. Ord a => a -> a -> a
`max` Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
bs) Vector Word64 -> Word64
go
  where go :: DVS.Vector Word64 -> Word64
        go :: Vector Word64 -> Word64
go Vector Word64
u =
          let ui :: Int
ui = Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
u
          in if Int
ui Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
as Bool -> Bool -> Bool
&& Int
ui Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
bs
            then Vector Word64 -> Int -> Word64
forall a. Storable a => Vector a -> Int -> a
DVS.unsafeIndex Vector Word64
as Int
ui Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.|. Vector Word64 -> Int -> Word64
forall a. Storable a => Vector a -> Int -> a
DVS.unsafeIndex Vector Word64
bs Int
ui
            else [Char] -> Word64
forall a. HasCallStack => [Char] -> a
error [Char]
"Different sized vectors"
{-# INLINE zipOr #-}

zip2Or :: [DVS.Vector Word64] -> [DVS.Vector Word64] -> [DVS.Vector Word64]
zip2Or :: [Vector Word64] -> [Vector Word64] -> [Vector Word64]
zip2Or (Vector Word64
a:[Vector Word64]
as) (Vector Word64
b:[Vector Word64]
bs) = Vector Word64 -> Vector Word64 -> Vector Word64
zipOr Vector Word64
a Vector Word64
bVector Word64 -> [Vector Word64] -> [Vector Word64]
forall a. a -> [a] -> [a]
:[Vector Word64] -> [Vector Word64] -> [Vector Word64]
zip2Or [Vector Word64]
as [Vector Word64]
bs
zip2Or (Vector Word64
a:[Vector Word64]
as) []     = Vector Word64
aVector Word64 -> [Vector Word64] -> [Vector Word64]
forall a. a -> [a] -> [a]
:[Vector Word64] -> [Vector Word64] -> [Vector Word64]
zip2Or [Vector Word64]
as []
zip2Or []     (Vector Word64
b:[Vector Word64]
bs) = Vector Word64
bVector Word64 -> [Vector Word64] -> [Vector Word64]
forall a. a -> [a] -> [a]
:[Vector Word64] -> [Vector Word64] -> [Vector Word64]
zip2Or [] [Vector Word64]
bs
zip2Or []     []     = []
{-# INLINE zip2Or #-}

zipAnd :: DVS.Vector Word64 -> DVS.Vector Word64 -> DVS.Vector Word64
zipAnd :: Vector Word64 -> Vector Word64 -> Vector Word64
zipAnd Vector Word64
as Vector Word64
bs = Int -> (Vector Word64 -> Word64) -> Vector Word64
forall a. Storable a => Int -> (Vector a -> a) -> Vector a
DVS.constructN (Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
as Int -> Int -> Int
forall a. Ord a => a -> a -> a
`max` Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
bs) Vector Word64 -> Word64
go
  where go :: DVS.Vector Word64 -> Word64
        go :: Vector Word64 -> Word64
go Vector Word64
u =
          let ui :: Int
ui = Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
u
          in if Int
ui Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
as Bool -> Bool -> Bool
&& Int
ui Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Vector Word64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word64
bs
            then Vector Word64 -> Int -> Word64
forall a. Storable a => Vector a -> Int -> a
DVS.unsafeIndex Vector Word64
as Int
ui Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Vector Word64 -> Int -> Word64
forall a. Storable a => Vector a -> Int -> a
DVS.unsafeIndex Vector Word64
bs Int
ui
            else [Char] -> Word64
forall a. HasCallStack => [Char] -> a
error [Char]
"Different sized vectors"
{-# INLINE zipAnd #-}

zip2And :: [DVS.Vector Word64] -> [DVS.Vector Word64] -> [DVS.Vector Word64]
zip2And :: [Vector Word64] -> [Vector Word64] -> [Vector Word64]
zip2And (Vector Word64
a:[Vector Word64]
as) (Vector Word64
b:[Vector Word64]
bs) = Vector Word64 -> Vector Word64 -> Vector Word64
zipAnd Vector Word64
a Vector Word64
bVector Word64 -> [Vector Word64] -> [Vector Word64]
forall a. a -> [a] -> [a]
:[Vector Word64] -> [Vector Word64] -> [Vector Word64]
zip2And [Vector Word64]
as [Vector Word64]
bs
zip2And (Vector Word64
a:[Vector Word64]
as) []     = Vector Word64
aVector Word64 -> [Vector Word64] -> [Vector Word64]
forall a. a -> [a] -> [a]
:[Vector Word64] -> [Vector Word64] -> [Vector Word64]
zip2And [Vector Word64]
as []
zip2And []     (Vector Word64
b:[Vector Word64]
bs) = Vector Word64
bVector Word64 -> [Vector Word64] -> [Vector Word64]
forall a. a -> [a] -> [a]
:[Vector Word64] -> [Vector Word64] -> [Vector Word64]
zip2And [] [Vector Word64]
bs
zip2And []     []     = []
{-# INLINE zip2And #-}