{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiWayIf        #-}

module HaskellWorks.Data.Simd.Logical
  ( XorBits(..)
  , OrBits(..)
  , AndBits(..)
  , AndNotBits(..)
  , NotBits(..)
  ) where

import Data.Word
import HaskellWorks.Data.Simd.Capabilities

import qualified Data.Vector.Storable                 as DVS
import qualified HaskellWorks.Data.Simd.Logical.Avx2  as AVX2
import qualified HaskellWorks.Data.Simd.Logical.Stock as STOCK

class XorBits a where
  xorBits :: a -> a -> a

instance XorBits (DVS.Vector Word64) where
  xorBits :: Vector Word64 -> Vector Word64 -> Vector Word64
xorBits Vector Word64
a Vector Word64
b = if
    | Bool
avx2Enabled -> forall a. XorBits a => a -> a -> a
AVX2.xorBits  Vector Word64
a Vector Word64
b
    | Bool
True        -> forall a. XorBits a => a -> a -> a
STOCK.xorBits Vector Word64
a Vector Word64
b
  {-# INLINE xorBits #-}

class OrBits a where
  orBits :: a -> a -> a

instance OrBits (DVS.Vector Word64) where
  orBits :: Vector Word64 -> Vector Word64 -> Vector Word64
orBits Vector Word64
a Vector Word64
b = if
    | Bool
avx2Enabled -> forall a. OrBits a => a -> a -> a
AVX2.orBits  Vector Word64
a Vector Word64
b
    | Bool
True        -> forall a. OrBits a => a -> a -> a
STOCK.orBits Vector Word64
a Vector Word64
b
  {-# INLINE orBits #-}

class AndBits a where
  andBits :: a -> a -> a

instance AndBits (DVS.Vector Word64) where
  andBits :: Vector Word64 -> Vector Word64 -> Vector Word64
andBits Vector Word64
a Vector Word64
b = if
    | Bool
avx2Enabled -> forall a. AndBits a => a -> a -> a
AVX2.andBits  Vector Word64
a Vector Word64
b
    | Bool
True        -> forall a. AndBits a => a -> a -> a
STOCK.andBits Vector Word64
a Vector Word64
b
  {-# INLINE andBits #-}

class AndNotBits a where
  andNotBits :: a -> a -> a

instance AndNotBits (DVS.Vector Word64) where
  andNotBits :: Vector Word64 -> Vector Word64 -> Vector Word64
andNotBits Vector Word64
a Vector Word64
b = if
    | Bool
avx2Enabled -> forall a. AndNotBits a => a -> a -> a
AVX2.andNotBits  Vector Word64
a Vector Word64
b
    | Bool
True        -> forall a. AndNotBits a => a -> a -> a
STOCK.andNotBits Vector Word64
a Vector Word64
b
  {-# INLINE andNotBits #-}

class NotBits a where
  notBits :: a -> a

instance NotBits (DVS.Vector Word64) where
  notBits :: Vector Word64 -> Vector Word64
notBits Vector Word64
a = if
    | Bool
avx2Enabled -> forall a. NotBits a => a -> a
AVX2.notBits  Vector Word64
a
    | Bool
True        -> forall a. NotBits a => a -> a
STOCK.notBits Vector Word64
a
  {-# INLINE notBits #-}