{-# LANGUAGE MagicHash        #-}
{-# LANGUAGE UnliftedFFITypes #-}

module Data.Bit.Gmp
  ( mpnCom
  , mpnPopcount
  , mpnAndN
  , mpnIorN
  , mpnXorN
  , mpnAndnN
  , mpnIornN
  , mpnNandN
  , mpnNiorN
  , mpnXnorN
  ) where

import Control.Monad.ST
import Control.Monad.ST.Unsafe
import Data.Primitive.ByteArray
import GHC.Exts
import System.IO.Unsafe

foreign import ccall unsafe "__gmpn_com"
  mpn_com :: MutableByteArray# s -> ByteArray# -> Int# -> IO ()

mpnCom :: MutableByteArray s -> ByteArray -> Int -> ST s ()
mpnCom :: MutableByteArray s -> ByteArray -> Int -> ST s ()
mpnCom (MutableByteArray MutableByteArray# s
res#) (ByteArray ByteArray#
arg#) (I# Int#
limbs#) =
  IO () -> ST s ()
forall a s. IO a -> ST s a
unsafeIOToST (MutableByteArray# s -> ByteArray# -> Int# -> IO ()
forall s. MutableByteArray# s -> ByteArray# -> Int# -> IO ()
mpn_com MutableByteArray# s
res# ByteArray#
arg# Int#
limbs#)
{-# INLINE mpnCom #-}

foreign import ccall unsafe "__gmpn_popcount"
  mpn_popcount :: ByteArray# -> Int# -> IO Word

mpnPopcount :: ByteArray -> Int -> Word
mpnPopcount :: ByteArray -> Int -> Word
mpnPopcount (ByteArray ByteArray#
arg#) (I# Int#
limbs#) =
  IO Word -> Word
forall a. IO a -> a
unsafeDupablePerformIO (ByteArray# -> Int# -> IO Word
mpn_popcount ByteArray#
arg# Int#
limbs#)
{-# INLINE mpnPopcount #-}

foreign import ccall unsafe "__gmpn_and_n"
  mpn_and_n :: MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()

mpnAndN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnAndN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnAndN (MutableByteArray MutableByteArray# s
res#) (ByteArray ByteArray#
arg1#) (ByteArray ByteArray#
arg2#) (I# Int#
limbs#) =
  IO () -> ST s ()
forall a s. IO a -> ST s a
unsafeIOToST (MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
forall s.
MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
mpn_and_n MutableByteArray# s
res# ByteArray#
arg1# ByteArray#
arg2# Int#
limbs#)
{-# INLINE mpnAndN #-}

foreign import ccall unsafe "__gmpn_ior_n"
  mpn_ior_n :: MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()

mpnIorN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnIorN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnIorN (MutableByteArray MutableByteArray# s
res#) (ByteArray ByteArray#
arg1#) (ByteArray ByteArray#
arg2#) (I# Int#
limbs#) =
  IO () -> ST s ()
forall a s. IO a -> ST s a
unsafeIOToST (MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
forall s.
MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
mpn_ior_n MutableByteArray# s
res# ByteArray#
arg1# ByteArray#
arg2# Int#
limbs#)
{-# INLINE mpnIorN #-}

foreign import ccall unsafe "__gmpn_xor_n"
  mpn_xor_n :: MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()

mpnXorN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnXorN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnXorN (MutableByteArray MutableByteArray# s
res#) (ByteArray ByteArray#
arg1#) (ByteArray ByteArray#
arg2#) (I# Int#
limbs#) =
  IO () -> ST s ()
forall a s. IO a -> ST s a
unsafeIOToST (MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
forall s.
MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
mpn_xor_n MutableByteArray# s
res# ByteArray#
arg1# ByteArray#
arg2# Int#
limbs#)
{-# INLINE mpnXorN #-}

foreign import ccall unsafe "__gmpn_andn_n"
  mpn_andn_n :: MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()

mpnAndnN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnAndnN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnAndnN (MutableByteArray MutableByteArray# s
res#) (ByteArray ByteArray#
arg1#) (ByteArray ByteArray#
arg2#) (I# Int#
limbs#) =
  IO () -> ST s ()
forall a s. IO a -> ST s a
unsafeIOToST (MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
forall s.
MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
mpn_andn_n MutableByteArray# s
res# ByteArray#
arg1# ByteArray#
arg2# Int#
limbs#)
{-# INLINE mpnAndnN #-}

foreign import ccall unsafe "__gmpn_iorn_n"
  mpn_iorn_n :: MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()

mpnIornN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnIornN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnIornN (MutableByteArray MutableByteArray# s
res#) (ByteArray ByteArray#
arg1#) (ByteArray ByteArray#
arg2#) (I# Int#
limbs#) =
  IO () -> ST s ()
forall a s. IO a -> ST s a
unsafeIOToST (MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
forall s.
MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
mpn_iorn_n MutableByteArray# s
res# ByteArray#
arg1# ByteArray#
arg2# Int#
limbs#)
{-# INLINE mpnIornN #-}

foreign import ccall unsafe "__gmpn_nand_n"
  mpn_nand_n :: MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()

mpnNandN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnNandN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnNandN (MutableByteArray MutableByteArray# s
res#) (ByteArray ByteArray#
arg1#) (ByteArray ByteArray#
arg2#) (I# Int#
limbs#) =
  IO () -> ST s ()
forall a s. IO a -> ST s a
unsafeIOToST (MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
forall s.
MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
mpn_nand_n MutableByteArray# s
res# ByteArray#
arg1# ByteArray#
arg2# Int#
limbs#)
{-# INLINE mpnNandN #-}

foreign import ccall unsafe "__gmpn_nior_n"
  mpn_nior_n :: MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()

mpnNiorN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnNiorN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnNiorN (MutableByteArray MutableByteArray# s
res#) (ByteArray ByteArray#
arg1#) (ByteArray ByteArray#
arg2#) (I# Int#
limbs#) =
  IO () -> ST s ()
forall a s. IO a -> ST s a
unsafeIOToST (MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
forall s.
MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
mpn_nior_n MutableByteArray# s
res# ByteArray#
arg1# ByteArray#
arg2# Int#
limbs#)
{-# INLINE mpnNiorN #-}

foreign import ccall unsafe "__gmpn_xnor_n"
  mpn_xnor_n :: MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()

mpnXnorN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnXnorN :: MutableByteArray s -> ByteArray -> ByteArray -> Int -> ST s ()
mpnXnorN (MutableByteArray MutableByteArray# s
res#) (ByteArray ByteArray#
arg1#) (ByteArray ByteArray#
arg2#) (I# Int#
limbs#) =
  IO () -> ST s ()
forall a s. IO a -> ST s a
unsafeIOToST (MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
forall s.
MutableByteArray# s -> ByteArray# -> ByteArray# -> Int# -> IO ()
mpn_xnor_n MutableByteArray# s
res# ByteArray#
arg1# ByteArray#
arg2# Int#
limbs#)
{-# INLINE mpnXnorN #-}