packages feed

bits-extras (empty) → 0.1.0

raw patch · 9 files changed

+1447/−0 lines, 9 filesdep +basesetup-changed

Dependencies added: base

Files

+ Data/Bits/Atomic.hs view
@@ -0,0 +1,735 @@+{-# LANGUAGE ForeignFunctionInterface #-}+-- | Atomic bit operations, using GCC's built-in atomic operations in small C+-- wrapper functions called through the FFI. See+-- <http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Atomic-Builtins.html> or the+-- version corresponding to your compiler for more detail.+--+-- The C code dynamically links to @libgcc_s@, which can cause problems in+-- GHCi. GHCi does not currently support sonames and tries to open+-- @libgcc_s.so@ while ignoring e.g. @libgcc_s.so.1@. A possible workaround+-- for GHCi on a linux system: @ln -s \/lib\/libgcc_s.so.1 \/lib\/libgcc_s.so@+module Data.Bits.Atomic (+    -- * Atomic bit operations on 'Word'-sized memory locations+    AtomicBits(..),+    -- * Utility+    memoryBarrier+) where+import Data.Bits+import Data.Word+import Data.Int+import Foreign.Ptr++-- | Atomic bit operations on a memory location. +--+-- Instances: 'Word', 'Word8', 'Word16', 'Word32', 'Word64', 'Int', 'Int8',+-- 'Int16', 'Int32', 'Int64'.+class Bits x => AtomicBits x where+    -- | Atomic @(+)@, returning the original value.+    fetchAndAdd :: Ptr x -> x -> IO x+    -- | Atomic @(-)@, returning the originial value.+    fetchAndSub :: Ptr x -> x -> IO x+    -- | Atomic @(.|.)@, returning the original value.+    fetchAndOr :: Ptr x -> x -> IO x+    -- | Atomic @(.&.)@, returning the original value.+    fetchAndAnd :: Ptr x -> x -> IO x+    -- | Atomic @xor@, returning the original value.+    fetchAndXor :: Ptr x -> x -> IO x+    -- | Atomic @nand@, returning the original value.+    fetchAndNand :: Ptr x -> x -> IO x+    -- | Atomic @(+)@, returning the updated value.+    addAndFetch :: Ptr x -> x -> IO x+    -- | Atomic @(-)@, returning the updated value.+    subAndFetch :: Ptr x -> x -> IO x+    -- | Atomic @(.|.)@, returning the updated value.+    orAndFetch :: Ptr x -> x -> IO x+    -- | Atomic @(.&.)@, returning the updated value.+    andAndFetch :: Ptr x -> x -> IO x+    -- | Atomic @xor@, returning the updated value.+    xorAndFetch :: Ptr x -> x -> IO x+    -- | Atomic @nand@, returning the updated value.+    nandAndFetch :: Ptr x -> x -> IO x+    -- | Atomic @CAS@ with boolean return.+    compareAndSwapBool :: Ptr x  -- ^ The memory location to update+                       -> x  -- ^ Old value+                       -> x  -- ^ Intended new value+                       -> IO Bool -- ^ 'True' if swapped, 'False' otherwise++    -- | Atomic @CAS@, returning the original value.+    compareAndSwap :: Ptr x  -- ^ The memory location to update+                   -> x  -- ^ Old value+                   -> x  -- ^ Intended new value+                   -> IO x -- ^ Original value++    -- | Atomically update the memory location with the value 1 and return the+    -- original value, 0 in case 'lockRelease' was previously called or @1@ if+    -- another call to 'lockTestAndSet' aquired the lock earlier. Implies an+    -- /aquire barrier/.+    lockTestAndSet :: Ptr x -> IO x+    -- | Release the lock by writing a @0@. Includes a /release barrier/.+    lockRelease :: Ptr x -> IO ()+++-- | A full memory barrier.+foreign import ccall unsafe "atomic-bitops-gcc.h mem_barrier"+    memoryBarrier :: IO ()++foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_add_8"+    fetch_and_add_8 :: Ptr Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_sub_8"+    fetch_and_sub_8 :: Ptr Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_or_8"+    fetch_and_or_8 :: Ptr Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_and_8"+    fetch_and_and_8 :: Ptr Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_xor_8"+    fetch_and_xor_8 :: Ptr Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_nand_8"+    fetch_and_nand_8 :: Ptr Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h add_and_fetch_8"+    add_and_fetch_8 :: Ptr Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h sub_and_fetch_8"+    sub_and_fetch_8 :: Ptr Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h or_and_fetch_8"+    or_and_fetch_8 :: Ptr Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h and_and_fetch_8"+    and_and_fetch_8 :: Ptr Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h xor_and_fetch_8"+    xor_and_fetch_8 :: Ptr Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h nand_and_fetch_8"+    nand_and_fetch_8 :: Ptr Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h bool_compare_and_swap_8"+    bool_compare_and_swap_8 :: Ptr Word8 -> Word8 -> Word8 -> IO Bool+foreign import ccall unsafe "atomic-bitops-gcc.h val_compare_and_swap_8"+    val_compare_and_swap_8 :: Ptr Word8 -> Word8 -> Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h lock_test_and_set_8"+    lock_test_and_set_8 :: Ptr Word8 -> IO Word8+foreign import ccall unsafe "atomic-bitops-gcc.h lock_release_8"+    lock_release_8 :: Ptr Word8 -> IO ()++instance AtomicBits Word8 where+    fetchAndAdd = fetch_and_add_8+    {-# INLINE fetchAndAdd #-}+    fetchAndSub = fetch_and_sub_8+    {-# INLINE fetchAndSub #-}+    fetchAndOr = fetch_and_or_8+    {-# INLINE fetchAndOr #-}+    fetchAndAnd = fetch_and_and_8+    {-# INLINE fetchAndAnd #-}+    fetchAndXor = fetch_and_xor_8+    {-# INLINE fetchAndXor #-}+    fetchAndNand = fetch_and_nand_8+    {-# INLINE fetchAndNand #-}+    addAndFetch = add_and_fetch_8+    {-# INLINE addAndFetch #-}+    subAndFetch = sub_and_fetch_8+    {-# INLINE subAndFetch #-}+    orAndFetch = or_and_fetch_8+    {-# INLINE orAndFetch #-}+    andAndFetch = and_and_fetch_8+    {-# INLINE andAndFetch #-}+    xorAndFetch = xor_and_fetch_8+    {-# INLINE xorAndFetch #-}+    nandAndFetch = nand_and_fetch_8+    {-# INLINE nandAndFetch #-}+    compareAndSwapBool = bool_compare_and_swap_8+    {-# INLINE compareAndSwapBool #-}+    compareAndSwap = val_compare_and_swap_8+    {-# INLINE compareAndSwap #-}+    lockTestAndSet = lock_test_and_set_8+    {-# INLINE lockTestAndSet #-}+    lockRelease = lock_release_8+    {-# INLINE lockRelease #-}+    +foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_add_16"+    fetch_and_add_16 :: Ptr Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_sub_16"+    fetch_and_sub_16 :: Ptr Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_or_16"+    fetch_and_or_16 :: Ptr Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_and_16"+    fetch_and_and_16 :: Ptr Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_xor_16"+    fetch_and_xor_16 :: Ptr Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_nand_16"+    fetch_and_nand_16 :: Ptr Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h add_and_fetch_16"+    add_and_fetch_16 :: Ptr Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h sub_and_fetch_16"+    sub_and_fetch_16 :: Ptr Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h or_and_fetch_16"+    or_and_fetch_16 :: Ptr Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h and_and_fetch_16"+    and_and_fetch_16 :: Ptr Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h xor_and_fetch_16"+    xor_and_fetch_16 :: Ptr Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h nand_and_fetch_16"+    nand_and_fetch_16 :: Ptr Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h bool_compare_and_swap_16"+    bool_compare_and_swap_16 :: Ptr Word16 -> Word16 -> Word16 -> IO Bool+foreign import ccall unsafe "atomic-bitops-gcc.h val_compare_and_swap_16"+    val_compare_and_swap_16 :: Ptr Word16 -> Word16 -> Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h lock_test_and_set_16"+    lock_test_and_set_16 :: Ptr Word16 -> IO Word16+foreign import ccall unsafe "atomic-bitops-gcc.h lock_release_16"+    lock_release_16 :: Ptr Word16 -> IO ()++instance AtomicBits Word16 where+    fetchAndAdd = fetch_and_add_16+    {-# INLINE fetchAndAdd #-}+    fetchAndSub = fetch_and_sub_16+    {-# INLINE fetchAndSub #-}+    fetchAndOr = fetch_and_or_16+    {-# INLINE fetchAndOr #-}+    fetchAndAnd = fetch_and_and_16+    {-# INLINE fetchAndAnd #-}+    fetchAndXor = fetch_and_xor_16+    {-# INLINE fetchAndXor #-}+    fetchAndNand = fetch_and_nand_16+    {-# INLINE fetchAndNand #-}+    addAndFetch = add_and_fetch_16+    {-# INLINE addAndFetch #-}+    subAndFetch = sub_and_fetch_16+    {-# INLINE subAndFetch #-}+    orAndFetch = or_and_fetch_16+    {-# INLINE orAndFetch #-}+    andAndFetch = and_and_fetch_16+    {-# INLINE andAndFetch #-}+    xorAndFetch = xor_and_fetch_16+    {-# INLINE xorAndFetch #-}+    nandAndFetch = nand_and_fetch_16+    {-# INLINE nandAndFetch #-}+    compareAndSwapBool = bool_compare_and_swap_16+    {-# INLINE compareAndSwapBool #-}+    compareAndSwap = val_compare_and_swap_16+    {-# INLINE compareAndSwap #-}+    lockTestAndSet = lock_test_and_set_16+    {-# INLINE lockTestAndSet #-}+    lockRelease = lock_release_16+    {-# INLINE lockRelease #-}+    +foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_add_32"+    fetch_and_add_32 :: Ptr Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_sub_32"+    fetch_and_sub_32 :: Ptr Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_or_32"+    fetch_and_or_32 :: Ptr Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_and_32"+    fetch_and_and_32 :: Ptr Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_xor_32"+    fetch_and_xor_32 :: Ptr Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_nand_32"+    fetch_and_nand_32 :: Ptr Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h add_and_fetch_32"+    add_and_fetch_32 :: Ptr Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h sub_and_fetch_32"+    sub_and_fetch_32 :: Ptr Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h or_and_fetch_32"+    or_and_fetch_32 :: Ptr Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h and_and_fetch_32"+    and_and_fetch_32 :: Ptr Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h xor_and_fetch_32"+    xor_and_fetch_32 :: Ptr Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h nand_and_fetch_32"+    nand_and_fetch_32 :: Ptr Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h bool_compare_and_swap_32"+    bool_compare_and_swap_32 :: Ptr Word32 -> Word32 -> Word32 -> IO Bool+foreign import ccall unsafe "atomic-bitops-gcc.h val_compare_and_swap_32"+    val_compare_and_swap_32 :: Ptr Word32 -> Word32 -> Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h lock_test_and_set_32"+    lock_test_and_set_32 :: Ptr Word32 -> IO Word32+foreign import ccall unsafe "atomic-bitops-gcc.h lock_release_32"+    lock_release_32 :: Ptr Word32 -> IO ()++instance AtomicBits Word32 where+    fetchAndAdd = fetch_and_add_32+    {-# INLINE fetchAndAdd #-}+    fetchAndSub = fetch_and_sub_32+    {-# INLINE fetchAndSub #-}+    fetchAndOr = fetch_and_or_32+    {-# INLINE fetchAndOr #-}+    fetchAndAnd = fetch_and_and_32+    {-# INLINE fetchAndAnd #-}+    fetchAndXor = fetch_and_xor_32+    {-# INLINE fetchAndXor #-}+    fetchAndNand = fetch_and_nand_32+    {-# INLINE fetchAndNand #-}+    addAndFetch = add_and_fetch_32+    {-# INLINE addAndFetch #-}+    subAndFetch = sub_and_fetch_32+    {-# INLINE subAndFetch #-}+    orAndFetch = or_and_fetch_32+    {-# INLINE orAndFetch #-}+    andAndFetch = and_and_fetch_32+    {-# INLINE andAndFetch #-}+    xorAndFetch = xor_and_fetch_32+    {-# INLINE xorAndFetch #-}+    nandAndFetch = nand_and_fetch_32+    {-# INLINE nandAndFetch #-}+    compareAndSwapBool = bool_compare_and_swap_32+    {-# INLINE compareAndSwapBool #-}+    compareAndSwap = val_compare_and_swap_32+    {-# INLINE compareAndSwap #-}+    lockTestAndSet = lock_test_and_set_32+    {-# INLINE lockTestAndSet #-}+    lockRelease = lock_release_32+    {-# INLINE lockRelease #-}+    +foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_add_64"+    fetch_and_add_64 :: Ptr Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_sub_64"+    fetch_and_sub_64 :: Ptr Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_or_64"+    fetch_and_or_64 :: Ptr Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_and_64"+    fetch_and_and_64 :: Ptr Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_xor_64"+    fetch_and_xor_64 :: Ptr Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_nand_64"+    fetch_and_nand_64 :: Ptr Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h add_and_fetch_64"+    add_and_fetch_64 :: Ptr Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h sub_and_fetch_64"+    sub_and_fetch_64 :: Ptr Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h or_and_fetch_64"+    or_and_fetch_64 :: Ptr Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h and_and_fetch_64"+    and_and_fetch_64 :: Ptr Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h xor_and_fetch_64"+    xor_and_fetch_64 :: Ptr Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h nand_and_fetch_64"+    nand_and_fetch_64 :: Ptr Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h bool_compare_and_swap_64"+    bool_compare_and_swap_64 :: Ptr Word64 -> Word64 -> Word64 -> IO Bool+foreign import ccall unsafe "atomic-bitops-gcc.h val_compare_and_swap_64"+    val_compare_and_swap_64 :: Ptr Word64 -> Word64 -> Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h lock_test_and_set_64"+    lock_test_and_set_64 :: Ptr Word64 -> IO Word64+foreign import ccall unsafe "atomic-bitops-gcc.h lock_release_64"+    lock_release_64 :: Ptr Word64 -> IO ()++instance AtomicBits Word64 where+    fetchAndAdd = fetch_and_add_64+    {-# INLINE fetchAndAdd #-}+    fetchAndSub = fetch_and_sub_64+    {-# INLINE fetchAndSub #-}+    fetchAndOr = fetch_and_or_64+    {-# INLINE fetchAndOr #-}+    fetchAndAnd = fetch_and_and_64+    {-# INLINE fetchAndAnd #-}+    fetchAndXor = fetch_and_xor_64+    {-# INLINE fetchAndXor #-}+    fetchAndNand = fetch_and_nand_64+    {-# INLINE fetchAndNand #-}+    addAndFetch = add_and_fetch_64+    {-# INLINE addAndFetch #-}+    subAndFetch = sub_and_fetch_64+    {-# INLINE subAndFetch #-}+    orAndFetch = or_and_fetch_64+    {-# INLINE orAndFetch #-}+    andAndFetch = and_and_fetch_64+    {-# INLINE andAndFetch #-}+    xorAndFetch = xor_and_fetch_64+    {-# INLINE xorAndFetch #-}+    nandAndFetch = nand_and_fetch_64+    {-# INLINE nandAndFetch #-}+    compareAndSwapBool = bool_compare_and_swap_64+    {-# INLINE compareAndSwapBool #-}+    compareAndSwap = val_compare_and_swap_64+    {-# INLINE compareAndSwap #-}+    lockTestAndSet = lock_test_and_set_64+    {-# INLINE lockTestAndSet #-}+    lockRelease = lock_release_64+    {-# INLINE lockRelease #-}+    +foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_add_word"+    fetch_and_add_word :: Ptr Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_sub_word"+    fetch_and_sub_word :: Ptr Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_or_word"+    fetch_and_or_word :: Ptr Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_and_word"+    fetch_and_and_word :: Ptr Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_xor_word"+    fetch_and_xor_word :: Ptr Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h fetch_and_nand_word"+    fetch_and_nand_word :: Ptr Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h add_and_fetch_word"+    add_and_fetch_word :: Ptr Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h sub_and_fetch_word"+    sub_and_fetch_word :: Ptr Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h or_and_fetch_word"+    or_and_fetch_word :: Ptr Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h and_and_fetch_word"+    and_and_fetch_word :: Ptr Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h xor_and_fetch_word"+    xor_and_fetch_word :: Ptr Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h nand_and_fetch_word"+    nand_and_fetch_word :: Ptr Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h bool_compare_and_swap_word"+    bool_compare_and_swap_word :: Ptr Word -> Word -> Word -> IO Bool+foreign import ccall unsafe "atomic-bitops-gcc.h val_compare_and_swap_word"+    val_compare_and_swap_word :: Ptr Word -> Word -> Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h lock_test_and_set_word"+    lock_test_and_set_word :: Ptr Word -> IO Word+foreign import ccall unsafe "atomic-bitops-gcc.h lock_release_word"+    lock_release_word :: Ptr Word -> IO ()++instance AtomicBits Word where+    fetchAndAdd = fetch_and_add_word+    {-# INLINE fetchAndAdd #-}+    fetchAndSub = fetch_and_sub_word+    {-# INLINE fetchAndSub #-}+    fetchAndOr = fetch_and_or_word+    {-# INLINE fetchAndOr #-}+    fetchAndAnd = fetch_and_and_word+    {-# INLINE fetchAndAnd #-}+    fetchAndXor = fetch_and_xor_word+    {-# INLINE fetchAndXor #-}+    fetchAndNand = fetch_and_nand_word+    {-# INLINE fetchAndNand #-}+    addAndFetch = add_and_fetch_word+    {-# INLINE addAndFetch #-}+    subAndFetch = sub_and_fetch_word+    {-# INLINE subAndFetch #-}+    orAndFetch = or_and_fetch_word+    {-# INLINE orAndFetch #-}+    andAndFetch = and_and_fetch_word+    {-# INLINE andAndFetch #-}+    xorAndFetch = xor_and_fetch_word+    {-# INLINE xorAndFetch #-}+    nandAndFetch = nand_and_fetch_word+    {-# INLINE nandAndFetch #-}+    compareAndSwapBool = bool_compare_and_swap_word+    {-# INLINE compareAndSwapBool #-}+    compareAndSwap = val_compare_and_swap_word+    {-# INLINE compareAndSwap #-}+    lockTestAndSet = lock_test_and_set_word+    {-# INLINE lockTestAndSet #-}+    lockRelease = lock_release_word+    {-# INLINE lockRelease #-}+++instance AtomicBits Int where+    fetchAndAdd p v = fmap fromIntegral $ fetch_and_add_word +                                        (castPtr p :: Ptr Word)+                                        (fromIntegral v)+    {-# INLINE fetchAndAdd #-}+    fetchAndSub p v = fmap fromIntegral $ fetch_and_sub_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral v)+    {-# INLINE fetchAndSub #-}+    fetchAndOr p v = fmap fromIntegral $ fetch_and_or_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral v)+    {-# INLINE fetchAndOr #-}+    fetchAndAnd p v = fmap fromIntegral $ fetch_and_and_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral v)+    {-# INLINE fetchAndAnd #-}+    fetchAndXor p v = fmap fromIntegral $ fetch_and_xor_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral v)+    {-# INLINE fetchAndXor #-}+    fetchAndNand p v = fmap fromIntegral $ fetch_and_nand_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral v)+    {-# INLINE fetchAndNand #-}+    addAndFetch p v = fmap fromIntegral $ add_and_fetch_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral v)+    {-# INLINE addAndFetch #-}+    subAndFetch p v = fmap fromIntegral $ sub_and_fetch_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral v)+    {-# INLINE subAndFetch #-}+    orAndFetch p v = fmap fromIntegral $ or_and_fetch_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral v)+    {-# INLINE orAndFetch #-}+    andAndFetch p v = fmap fromIntegral $ and_and_fetch_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral v)+    {-# INLINE andAndFetch #-}+    xorAndFetch p v = fmap fromIntegral $ xor_and_fetch_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral v)+    {-# INLINE xorAndFetch #-}+    nandAndFetch p v = fmap fromIntegral $ nand_and_fetch_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral v)+    {-# INLINE nandAndFetch #-}+    compareAndSwapBool p o n = bool_compare_and_swap_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral o)+                                        (fromIntegral n)+    {-# INLINE compareAndSwapBool #-}+    compareAndSwap p o n = fmap fromIntegral $ val_compare_and_swap_word+                                        (castPtr p :: Ptr Word)+                                        (fromIntegral o)+                                        (fromIntegral n)+    {-# INLINE compareAndSwap #-}+    lockTestAndSet p = fmap fromIntegral $ lock_test_and_set_word +                                        (castPtr p :: Ptr Word)+    {-# INLINE lockTestAndSet #-}+    lockRelease p = lock_release_word (castPtr p :: Ptr Word)+    {-# INLINE lockRelease #-}++instance AtomicBits Int8 where+    fetchAndAdd p v = fmap fromIntegral $ fetch_and_add_8 +                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral v)+    {-# INLINE fetchAndAdd #-}+    fetchAndSub p v = fmap fromIntegral $ fetch_and_sub_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral v)+    {-# INLINE fetchAndSub #-}+    fetchAndOr p v = fmap fromIntegral $ fetch_and_or_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral v)+    {-# INLINE fetchAndOr #-}+    fetchAndAnd p v = fmap fromIntegral $ fetch_and_and_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral v)+    {-# INLINE fetchAndAnd #-}+    fetchAndXor p v = fmap fromIntegral $ fetch_and_xor_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral v)+    {-# INLINE fetchAndXor #-}+    fetchAndNand p v = fmap fromIntegral $ fetch_and_nand_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral v)+    {-# INLINE fetchAndNand #-}+    addAndFetch p v = fmap fromIntegral $ add_and_fetch_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral v)+    {-# INLINE addAndFetch #-}+    subAndFetch p v = fmap fromIntegral $ sub_and_fetch_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral v)+    {-# INLINE subAndFetch #-}+    orAndFetch p v = fmap fromIntegral $ or_and_fetch_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral v)+    {-# INLINE orAndFetch #-}+    andAndFetch p v = fmap fromIntegral $ and_and_fetch_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral v)+    {-# INLINE andAndFetch #-}+    xorAndFetch p v = fmap fromIntegral $ xor_and_fetch_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral v)+    {-# INLINE xorAndFetch #-}+    nandAndFetch p v = fmap fromIntegral $ nand_and_fetch_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral v)+    {-# INLINE nandAndFetch #-}+    compareAndSwapBool p o n = bool_compare_and_swap_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral o)+                                        (fromIntegral n)+    {-# INLINE compareAndSwapBool #-}+    compareAndSwap p o n = fmap fromIntegral $ val_compare_and_swap_8+                                        (castPtr p :: Ptr Word8)+                                        (fromIntegral o)+                                        (fromIntegral n)+    {-# INLINE compareAndSwap #-}+    lockTestAndSet p = fmap fromIntegral $ lock_test_and_set_8 +                                        (castPtr p :: Ptr Word8)+    {-# INLINE lockTestAndSet #-}+    lockRelease p = lock_release_8 (castPtr p :: Ptr Word8)+    {-# INLINE lockRelease #-}++instance AtomicBits Int16 where+    fetchAndAdd p v = fmap fromIntegral $ fetch_and_add_16 +                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral v)+    {-# INLINE fetchAndAdd #-}+    fetchAndSub p v = fmap fromIntegral $ fetch_and_sub_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral v)+    {-# INLINE fetchAndSub #-}+    fetchAndOr p v = fmap fromIntegral $ fetch_and_or_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral v)+    {-# INLINE fetchAndOr #-}+    fetchAndAnd p v = fmap fromIntegral $ fetch_and_and_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral v)+    {-# INLINE fetchAndAnd #-}+    fetchAndXor p v = fmap fromIntegral $ fetch_and_xor_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral v)+    {-# INLINE fetchAndXor #-}+    fetchAndNand p v = fmap fromIntegral $ fetch_and_nand_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral v)+    {-# INLINE fetchAndNand #-}+    addAndFetch p v = fmap fromIntegral $ add_and_fetch_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral v)+    {-# INLINE addAndFetch #-}+    subAndFetch p v = fmap fromIntegral $ sub_and_fetch_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral v)+    {-# INLINE subAndFetch #-}+    orAndFetch p v = fmap fromIntegral $ or_and_fetch_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral v)+    {-# INLINE orAndFetch #-}+    andAndFetch p v = fmap fromIntegral $ and_and_fetch_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral v)+    {-# INLINE andAndFetch #-}+    xorAndFetch p v = fmap fromIntegral $ xor_and_fetch_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral v)+    {-# INLINE xorAndFetch #-}+    nandAndFetch p v = fmap fromIntegral $ nand_and_fetch_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral v)+    {-# INLINE nandAndFetch #-}+    compareAndSwapBool p o n = bool_compare_and_swap_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral o)+                                        (fromIntegral n)+    {-# INLINE compareAndSwapBool #-}+    compareAndSwap p o n = fmap fromIntegral $ val_compare_and_swap_16+                                        (castPtr p :: Ptr Word16)+                                        (fromIntegral o)+                                        (fromIntegral n)+    {-# INLINE compareAndSwap #-}+    lockTestAndSet p = fmap fromIntegral $ lock_test_and_set_16 +                                        (castPtr p :: Ptr Word16)+    {-# INLINE lockTestAndSet #-}+    lockRelease p = lock_release_16 (castPtr p :: Ptr Word16)+    {-# INLINE lockRelease #-}++instance AtomicBits Int32 where+    fetchAndAdd p v = fmap fromIntegral $ fetch_and_add_32 +                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral v)+    {-# INLINE fetchAndAdd #-}+    fetchAndSub p v = fmap fromIntegral $ fetch_and_sub_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral v)+    {-# INLINE fetchAndSub #-}+    fetchAndOr p v = fmap fromIntegral $ fetch_and_or_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral v)+    {-# INLINE fetchAndOr #-}+    fetchAndAnd p v = fmap fromIntegral $ fetch_and_and_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral v)+    {-# INLINE fetchAndAnd #-}+    fetchAndXor p v = fmap fromIntegral $ fetch_and_xor_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral v)+    {-# INLINE fetchAndXor #-}+    fetchAndNand p v = fmap fromIntegral $ fetch_and_nand_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral v)+    {-# INLINE fetchAndNand #-}+    addAndFetch p v = fmap fromIntegral $ add_and_fetch_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral v)+    {-# INLINE addAndFetch #-}+    subAndFetch p v = fmap fromIntegral $ sub_and_fetch_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral v)+    {-# INLINE subAndFetch #-}+    orAndFetch p v = fmap fromIntegral $ or_and_fetch_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral v)+    {-# INLINE orAndFetch #-}+    andAndFetch p v = fmap fromIntegral $ and_and_fetch_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral v)+    {-# INLINE andAndFetch #-}+    xorAndFetch p v = fmap fromIntegral $ xor_and_fetch_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral v)+    {-# INLINE xorAndFetch #-}+    nandAndFetch p v = fmap fromIntegral $ nand_and_fetch_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral v)+    {-# INLINE nandAndFetch #-}+    compareAndSwapBool p o n = bool_compare_and_swap_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral o)+                                        (fromIntegral n)+    {-# INLINE compareAndSwapBool #-}+    compareAndSwap p o n = fmap fromIntegral $ val_compare_and_swap_32+                                        (castPtr p :: Ptr Word32)+                                        (fromIntegral o)+                                        (fromIntegral n)+    {-# INLINE compareAndSwap #-}+    lockTestAndSet p = fmap fromIntegral $ lock_test_and_set_32 +                                        (castPtr p :: Ptr Word32)+    {-# INLINE lockTestAndSet #-}+    lockRelease p = lock_release_32 (castPtr p :: Ptr Word32)+    {-# INLINE lockRelease #-}++instance AtomicBits Int64 where+    fetchAndAdd p v = fmap fromIntegral $ fetch_and_add_64 +                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral v)+    {-# INLINE fetchAndAdd #-}+    fetchAndSub p v = fmap fromIntegral $ fetch_and_sub_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral v)+    {-# INLINE fetchAndSub #-}+    fetchAndOr p v = fmap fromIntegral $ fetch_and_or_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral v)+    {-# INLINE fetchAndOr #-}+    fetchAndAnd p v = fmap fromIntegral $ fetch_and_and_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral v)+    {-# INLINE fetchAndAnd #-}+    fetchAndXor p v = fmap fromIntegral $ fetch_and_xor_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral v)+    {-# INLINE fetchAndXor #-}+    fetchAndNand p v = fmap fromIntegral $ fetch_and_nand_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral v)+    {-# INLINE fetchAndNand #-}+    addAndFetch p v = fmap fromIntegral $ add_and_fetch_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral v)+    {-# INLINE addAndFetch #-}+    subAndFetch p v = fmap fromIntegral $ sub_and_fetch_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral v)+    {-# INLINE subAndFetch #-}+    orAndFetch p v = fmap fromIntegral $ or_and_fetch_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral v)+    {-# INLINE orAndFetch #-}+    andAndFetch p v = fmap fromIntegral $ and_and_fetch_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral v)+    {-# INLINE andAndFetch #-}+    xorAndFetch p v = fmap fromIntegral $ xor_and_fetch_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral v)+    {-# INLINE xorAndFetch #-}+    nandAndFetch p v = fmap fromIntegral $ nand_and_fetch_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral v)+    {-# INLINE nandAndFetch #-}+    compareAndSwapBool p o n = bool_compare_and_swap_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral o)+                                        (fromIntegral n)+    {-# INLINE compareAndSwapBool #-}+    compareAndSwap p o n = fmap fromIntegral $ val_compare_and_swap_64+                                        (castPtr p :: Ptr Word64)+                                        (fromIntegral o)+                                        (fromIntegral n)+    {-# INLINE compareAndSwap #-}+    lockTestAndSet p = fmap fromIntegral $ lock_test_and_set_64 +                                        (castPtr p :: Ptr Word64)+    {-# INLINE lockTestAndSet #-}+    lockRelease p = lock_release_64 (castPtr p :: Ptr Word64)+    {-# INLINE lockRelease #-}
+ Data/Bits/Extras.hs view
@@ -0,0 +1,206 @@+{-# LANGUAGE ForeignFunctionInterface #-}+-- | Extended bit operations, implemented using GCC builtins (see+-- <http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Other-Builtins.html>).+module Data.Bits.Extras (+    ExtraBits(..)+) where+import Data.Bits+import Data.Word+import Data.Int++-- | Instances provided: 'Word', 'Word8', 'Word16', 'Word32', 'Word64', 'Int', 'Int8', 'Int16', 'Int32', 'Int64'+class Bits x => ExtraBits x where+    -- | Returns one plus the index of the least significant 1-bit of x, or if+    -- x is zero, returns zero. +    lowestBitPlus1 :: x -> Word32+    -- | Returns the number of leading 0-bits in x, starting at the most+    -- significant bit position. If x is 0, the result is undefined. +    leadingZeros :: x -> Word32+    -- | Returns the number of trailing 0-bits in x, starting at the least+    -- significant bit position. If x is 0, the result is undefined. +    trailingZeros :: x -> Word32+    -- | Returns the number of 1-bits in x. +    populationCount :: x -> Word32+    -- | Returns the parity of x, i.e. the number of 1-bits in x modulo 2. +    parity :: x -> Word32+    -- | Returns x with the order of the bytes reversed; for example,+    -- 0xaabbccdd becomes 0xddccbbaa. Byte here always means exactly 8 bits. +    byteSwap :: x -> x++instance ExtraBits Word where+    lowestBitPlus1 = c_ffsl+    {-# INLINE lowestBitPlus1 #-}+    leadingZeros = c_clzl+    {-# INLINE leadingZeros #-}+    trailingZeros = c_ctzl+    {-# INLINE trailingZeros #-}+    populationCount = c_popcountl+    {-# INLINE populationCount #-}+    parity = c_parityl+    {-# INLINE parity #-}+    byteSwap = if bitSize (undefined :: Word) == 32 +                then fromIntegral . c_bswap32 . fromIntegral+                else fromIntegral . c_bswap64 . fromIntegral+    {-# INLINE byteSwap #-}++instance ExtraBits Word8 where+    lowestBitPlus1 = c_ffs . fromIntegral+    {-# INLINE lowestBitPlus1 #-}+    leadingZeros w = (c_clz $ fromIntegral w) - 24+    {-# INLINE leadingZeros #-}+    trailingZeros = c_ctz . (0xff00 .|.) . fromIntegral+    {-# INLINE trailingZeros #-}+    populationCount = c_popcount . fromIntegral+    {-# INLINE populationCount #-}+    parity = c_parity . fromIntegral+    {-# INLINE parity #-}+    byteSwap = id+    {-# INLINE byteSwap #-}++instance ExtraBits Word16 where+    lowestBitPlus1 = c_ffs . fromIntegral+    {-# INLINE lowestBitPlus1 #-}+    leadingZeros w = (c_clz $ fromIntegral w) - 16+    {-# INLINE leadingZeros #-}+    trailingZeros = c_ctz . (0xffff0000 .|.) . fromIntegral+    {-# INLINE trailingZeros #-}+    populationCount = c_popcount . fromIntegral+    {-# INLINE populationCount #-}+    parity = c_parity . fromIntegral+    {-# INLINE parity #-}+    byteSwap w = w `shiftR` 8 .|. w `shiftL` 8+    {-# INLINE byteSwap #-}++instance ExtraBits Word32 where+    lowestBitPlus1 = c_ffs+    {-# INLINE lowestBitPlus1 #-}+    leadingZeros = c_clz+    {-# INLINE leadingZeros #-}+    trailingZeros = c_ctz+    {-# INLINE trailingZeros #-}+    populationCount = c_popcount+    {-# INLINE populationCount #-}+    parity = c_parity+    {-# INLINE parity #-}+    byteSwap = c_bswap32+    {-# INLINE byteSwap #-}++instance ExtraBits Word64 where+    lowestBitPlus1 = c_ffsll+    {-# INLINE lowestBitPlus1 #-}+    leadingZeros = c_clzll+    {-# INLINE leadingZeros #-}+    trailingZeros = c_ctzll+    {-# INLINE trailingZeros #-}+    populationCount = c_popcountll+    {-# INLINE populationCount #-}+    parity = c_parityll+    {-# INLINE parity #-}+    byteSwap = c_bswap64+    {-# INLINE byteSwap #-}++instance ExtraBits Int where+    lowestBitPlus1 = c_ffsl . fromIntegral+    {-# INLINE lowestBitPlus1 #-}+    leadingZeros = c_clzl . fromIntegral+    {-# INLINE leadingZeros #-}+    trailingZeros = c_ctzl . fromIntegral+    {-# INLINE trailingZeros #-}+    populationCount = c_popcountl . fromIntegral+    {-# INLINE populationCount #-}+    parity = c_parityl . fromIntegral+    {-# INLINE parity #-}+    byteSwap = if bitSize (undefined :: Int) == 32+                then fromIntegral . c_bswap32 . fromIntegral+                else fromIntegral . c_bswap64 . fromIntegral+    {-# INLINE byteSwap #-}++instance ExtraBits Int8 where+    lowestBitPlus1 i = lowestBitPlus1 (fromIntegral i :: Word8)+    leadingZeros i = leadingZeros (fromIntegral i :: Word8)+    trailingZeros i = trailingZeros (fromIntegral i :: Word8)+    populationCount = c_popcount . fromIntegral+    {-# INLINE populationCount #-}+    parity = c_parity . fromIntegral+    {-# INLINE parity #-}+    byteSwap = id++instance ExtraBits Int16 where+    lowestBitPlus1 i = lowestBitPlus1 (fromIntegral i :: Word16)+    leadingZeros i = leadingZeros (fromIntegral i :: Word16)+    trailingZeros i = trailingZeros (fromIntegral i :: Word16)+    populationCount = c_popcount . fromIntegral+    {-# INLINE populationCount #-}+    parity = c_parity . fromIntegral+    {-# INLINE parity #-}+    byteSwap i = fromIntegral . byteSwap $ (fromIntegral i :: Word16)++instance ExtraBits Int32 where+    lowestBitPlus1 = c_ffs . fromIntegral+    {-# INLINE lowestBitPlus1 #-}+    leadingZeros = c_clz . fromIntegral+    {-# INLINE leadingZeros #-}+    trailingZeros = c_ctz . fromIntegral+    {-# INLINE trailingZeros #-}+    populationCount = c_popcount . fromIntegral+    {-# INLINE populationCount #-}+    parity = c_parity . fromIntegral+    {-# INLINE parity #-}+    byteSwap = fromIntegral . c_bswap32 . fromIntegral+    {-# INLINE byteSwap #-}++instance ExtraBits Int64 where+    lowestBitPlus1 = fromIntegral . c_ffsll . fromIntegral+    {-# INLINE lowestBitPlus1 #-}+    leadingZeros = fromIntegral . c_clzll . fromIntegral+    {-# INLINE leadingZeros #-}+    trailingZeros = fromIntegral . c_ctzll . fromIntegral+    {-# INLINE trailingZeros #-}+    populationCount = fromIntegral . c_popcountll . fromIntegral+    {-# INLINE populationCount #-}+    parity = fromIntegral . c_parityll . fromIntegral+    {-# INLINE parity #-}+    byteSwap = fromIntegral . c_bswap64 . fromIntegral+    {-# INLINE byteSwap #-}+++-- 32-bit variants+foreign import ccall unsafe "bitops-gcc.h ffs"+    c_ffs :: Word32 -> Word32+foreign import ccall unsafe "bitops-gcc.h clz"+    c_clz :: Word32 -> Word32+foreign import ccall unsafe "bitops-gcc.h ctz"+    c_ctz :: Word32 -> Word32+foreign import ccall unsafe "bitops-gcc.h popcount"+    c_popcount :: Word32 -> Word32+foreign import ccall unsafe "bitops-gcc.h parity"+    c_parity :: Word32 -> Word32+foreign import ccall unsafe "bitops-gcc.h bswap32"+    c_bswap32 :: Word32 -> Word32++-- 64-bit versions+foreign import ccall unsafe "bitops-gcc.h ffsll"+    c_ffsll :: Word64 -> Word32+foreign import ccall unsafe "bitops-gcc.h clzll"+    c_clzll :: Word64 -> Word32+foreign import ccall unsafe "bitops-gcc.h ctzll"+    c_ctzll :: Word64 -> Word32+foreign import ccall unsafe "bitops-gcc.h popcountll"+    c_popcountll :: Word64 -> Word32+foreign import ccall unsafe "bitops-gcc.h parityll"+    c_parityll :: Word64 -> Word32+foreign import ccall unsafe "bitops-gcc.h bswap64"+    c_bswap64 :: Word64 -> Word64++-- Word-sized versions+foreign import ccall unsafe "bitops-gcc.h ffsl"+    c_ffsl :: Word -> Word32+foreign import ccall unsafe "bitops-gcc.h clzl"+    c_clzl :: Word -> Word32+foreign import ccall unsafe "bitops-gcc.h ctzl"+    c_ctzl :: Word -> Word32+foreign import ccall unsafe "bitops-gcc.h popcountl"+    c_popcountl :: Word -> Word32+foreign import ccall unsafe "bitops-gcc.h parityl"+    c_parityl :: Word -> Word32+
+ License.txt view
@@ -0,0 +1,26 @@+Copyright (c) The Regents of the University of California.+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.+3. Neither the name of the University nor the names of its contributors+   may be used to endorse or promote products derived from this software+   without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ bits-extras.cabal view
@@ -0,0 +1,52 @@+Name:               bits-extras+Version:            0.1.0+License:            BSD3+License-File:       License.txt+Maintainer:         Gabriel Wicke <wicke@wikidev.net>+Author:             Gabriel Wicke <wicke@wikidev.net>+Synopsis:       Efficient atomic and non-atomic bit operations not found in Data.Bits+Description:        Mostly wraps low-level bit operations provided by GCC+                    builtins, which translate to specialized instructions+                    where available. +                    .+                    Atomic operations include CAS+                    (compare-and-swap), lock, fetch & add and similar+                    primitives suitable for low-level shared-memory+                    synchronization.+                    .+                    Primitives from the 'Extras' subpackage would be useful to+                    have in the proper 'Data.Bits' package, although this+                    would probably require broader support across different+                    compiler backends.+                    .+                    Relevant Hackage tickets:+                    .+                    * <http://hackage.haskell.org/trac/ghc/ticket/3563>+                    .+                    * <http://hackage.haskell.org/trac/ghc/ticket/4102>+Category:           Data+Stability:          experimental+Build-Type:         Simple+Cabal-Version: >= 1.6+Extra-Source-Files: cbits/bitops-gcc.c cbits/bitops-gcc.h+Source-Repository head+    type: mercurial+    location: http://dev.wikidev.net/hg/bits-extras/+--extra-tmp-files: cbits/bitops-gcc.h+library+    Exposed-Modules:  Data.Bits.Extras Data.Bits.Atomic+    Build-Depends:    base >= 4 && < 6+    GHC-Options:      -Wall -O2 -funbox-strict-fields+    GHC-Prof-Options: -auto-all+    C-Sources:        cbits/bitops-gcc.c cbits/atomic-bitops-gcc.c+    --CC-Options:       -O3 -fomit-frame-pointer -march=native -Wall+    -- Try link-time optimization (inlining) with gcc 4.5:+    -- CC-Options:       -fomit-frame-pointer -march=native -Wall -flto+    CC-Options:       -fomit-frame-pointer -march=native -Wall+    Extra-Libraries:  gcc_s+    Include-Dirs:     cbits+    Install-Includes: bitops-gcc.h atomic-bitops-gcc.h+    Extensions:       ForeignFunctionInterface+    --Includes:       bitops-gcc.h+    --LD-Options:     -flto+    --hs-source-dirs: .
+ cbits/atomic-bitops-gcc.c view
@@ -0,0 +1,278 @@+#include "atomic-bitops-gcc.h"++void mem_barrier (void) {return __sync_synchronize ();}++/* 8-bit */+inline unsigned char fetch_and_add_8 (unsigned char *p, unsigned char v) {+	return __sync_fetch_and_add (p, v);+}+inline unsigned char fetch_and_sub_8 (unsigned char *p, unsigned char v) {+	return __sync_fetch_and_sub (p, v);+}+inline unsigned char fetch_and_or_8 (unsigned char *p, unsigned char v) {+	return __sync_fetch_and_or (p, v);+}+inline unsigned char fetch_and_and_8 (unsigned char *p, unsigned char v) {+	return __sync_fetch_and_and (p, v);+}+inline unsigned char fetch_and_xor_8 (unsigned char *p, unsigned char v) {+	return __sync_fetch_and_xor (p, v);+}+inline unsigned char fetch_and_nand_8 (unsigned char *p, unsigned char v) {+	return __sync_fetch_and_nand (p, v);+}+inline unsigned char add_and_fetch_8 (unsigned char *p, unsigned char v) {+	return __sync_add_and_fetch (p, v);+}+inline unsigned char sub_and_fetch_8 (unsigned char *p, unsigned char v) {+	return __sync_sub_and_fetch (p, v);+}+inline unsigned char or_and_fetch_8 (unsigned char *p, unsigned char v) {+	return __sync_or_and_fetch (p, v);+}+inline unsigned char and_and_fetch_8 (unsigned char *p, unsigned char v) {+	return __sync_and_and_fetch (p, v);+}+inline unsigned char xor_and_fetch_8 (unsigned char *p, unsigned char v) {+	return __sync_xor_and_fetch (p, v);+}+inline unsigned char nand_and_fetch_8 (unsigned char *p, unsigned char v) {+	return __sync_nand_and_fetch (p, v);+}+inline unsigned int+bool_compare_and_swap_8 (unsigned char *p, unsigned char old, unsigned char new) {+	return __sync_bool_compare_and_swap (p, old, new);+}+inline unsigned char+val_compare_and_swap_8 (unsigned char *p, unsigned char old, unsigned char new) {+	return __sync_val_compare_and_swap (p, old, new);+}+inline unsigned char lock_test_and_set_8 (unsigned char *p) {+	// Only immediate 0/1 appear to be widely supported, so hardcode it+	// here+	return __sync_lock_test_and_set (p, 1);+}+void lock_release_8 (unsigned char *p) {+	// Writes a 0 to *p+	return __sync_lock_release (p);+}++/* 16-bit */+inline unsigned short fetch_and_add_16 (unsigned short *p, unsigned short v) {+	return __sync_fetch_and_add (p, v);+}+inline unsigned short fetch_and_sub_16 (unsigned short *p, unsigned short v) {+	return __sync_fetch_and_sub (p, v);+}+inline unsigned short fetch_and_or_16 (unsigned short *p, unsigned short v) {+	return __sync_fetch_and_or (p, v);+}+inline unsigned short fetch_and_and_16 (unsigned short *p, unsigned short v) {+	return __sync_fetch_and_and (p, v);+}+inline unsigned short fetch_and_xor_16 (unsigned short *p, unsigned short v) {+	return __sync_fetch_and_xor (p, v);+}+inline unsigned short fetch_and_nand_16 (unsigned short *p, unsigned short v) {+	return __sync_fetch_and_nand (p, v);+}+inline unsigned short add_and_fetch_16 (unsigned short *p, unsigned short v) {+	return __sync_add_and_fetch (p, v);+}+inline unsigned short sub_and_fetch_16 (unsigned short *p, unsigned short v) {+	return __sync_sub_and_fetch (p, v);+}+inline unsigned short or_and_fetch_16 (unsigned short *p, unsigned short v) {+	return __sync_or_and_fetch (p, v);+}+inline unsigned short and_and_fetch_16 (unsigned short *p, unsigned short v) {+	return __sync_and_and_fetch (p, v);+}+inline unsigned short xor_and_fetch_16 (unsigned short *p, unsigned short v) {+	return __sync_xor_and_fetch (p, v);+}+inline unsigned short nand_and_fetch_16 (unsigned short *p, unsigned short v) {+	return __sync_nand_and_fetch (p, v);+}+inline unsigned int+bool_compare_and_swap_16 (unsigned short *p, unsigned short old, unsigned short new) {+	return __sync_bool_compare_and_swap (p, old, new);+}+inline unsigned short+val_compare_and_swap_16 (unsigned short *p, unsigned short old, unsigned short new) {+	return __sync_val_compare_and_swap (p, old, new);+}+inline unsigned short lock_test_and_set_16 (unsigned short *p) {+	// Only immediate 0/1 appear to be widely supported, so hardcode it+	// here+	return __sync_lock_test_and_set (p, 1);+}+void lock_release_16 (unsigned short *p) {+	// Writes a 0 to *p+	return __sync_lock_release (p);+}++/* 32-bit */+inline unsigned int fetch_and_add_32 (unsigned int *p, unsigned int v) {+	return __sync_fetch_and_add (p, v);+}+inline unsigned int fetch_and_sub_32 (unsigned int *p, unsigned int v) {+	return __sync_fetch_and_sub (p, v);+}+inline unsigned int fetch_and_or_32 (unsigned int *p, unsigned int v) {+	return __sync_fetch_and_or (p, v);+}+inline unsigned int fetch_and_and_32 (unsigned int *p, unsigned int v) {+	return __sync_fetch_and_and (p, v);+}+inline unsigned int fetch_and_xor_32 (unsigned int *p, unsigned int v) {+	return __sync_fetch_and_xor (p, v);+}+inline unsigned int fetch_and_nand_32 (unsigned int *p, unsigned int v) {+	return __sync_fetch_and_nand (p, v);+}+inline unsigned int add_and_fetch_32 (unsigned int *p, unsigned int v) {+	return __sync_add_and_fetch (p, v);+}+inline unsigned int sub_and_fetch_32 (unsigned int *p, unsigned int v) {+	return __sync_sub_and_fetch (p, v);+}+inline unsigned int or_and_fetch_32 (unsigned int *p, unsigned int v) {+	return __sync_or_and_fetch (p, v);+}+inline unsigned int and_and_fetch_32 (unsigned int *p, unsigned int v) {+	return __sync_and_and_fetch (p, v);+}+inline unsigned int xor_and_fetch_32 (unsigned int *p, unsigned int v) {+	return __sync_xor_and_fetch (p, v);+}+inline unsigned int nand_and_fetch_32 (unsigned int *p, unsigned int v) {+	return __sync_nand_and_fetch (p, v);+}+inline unsigned int+bool_compare_and_swap_32 (unsigned int *p, unsigned int old, unsigned int new) {+	return __sync_bool_compare_and_swap (p, old, new);+}+inline unsigned int+val_compare_and_swap_32 (unsigned int *p, unsigned int old, unsigned int new) {+	return __sync_val_compare_and_swap (p, old, new);+}+inline unsigned int lock_test_and_set_32 (unsigned int *p) {+	// Only immediate 0/1 appear to be widely supported, so hardcode it+	// here+	return __sync_lock_test_and_set (p, 1);+}+void lock_release_32 (unsigned int *p) {+	// Writes a 0 to *p+	return __sync_lock_release (p);+}++/* 64-bit */+inline unsigned long long fetch_and_add_64 (unsigned long long *p, unsigned long long v) {+	return __sync_fetch_and_add (p, v);+}+inline unsigned long long fetch_and_sub_64 (unsigned long long *p, unsigned long long v) {+	return __sync_fetch_and_sub (p, v);+}+inline unsigned long long fetch_and_or_64 (unsigned long long *p, unsigned long long v) {+	return __sync_fetch_and_or (p, v);+}+inline unsigned long long fetch_and_and_64 (unsigned long long *p, unsigned long long v) {+	return __sync_fetch_and_and (p, v);+}+inline unsigned long long fetch_and_xor_64 (unsigned long long *p, unsigned long long v) {+	return __sync_fetch_and_xor (p, v);+}+inline unsigned long long fetch_and_nand_64 (unsigned long long *p, unsigned long long v) {+	return __sync_fetch_and_nand (p, v);+}+inline unsigned long long add_and_fetch_64 (unsigned long long *p, unsigned long long v) {+	return __sync_add_and_fetch (p, v);+}+inline unsigned long long sub_and_fetch_64 (unsigned long long *p, unsigned long long v) {+	return __sync_sub_and_fetch (p, v);+}+inline unsigned long long or_and_fetch_64 (unsigned long long *p, unsigned long long v) {+	return __sync_or_and_fetch (p, v);+}+inline unsigned long long and_and_fetch_64 (unsigned long long *p, unsigned long long v) {+	return __sync_and_and_fetch (p, v);+}+inline unsigned long long xor_and_fetch_64 (unsigned long long *p, unsigned long long v) {+	return __sync_xor_and_fetch (p, v);+}+inline unsigned long long nand_and_fetch_64 (unsigned long long *p, unsigned long long v) {+	return __sync_nand_and_fetch (p, v);+}+inline unsigned int+bool_compare_and_swap_64 (unsigned long long *p, unsigned long long old, unsigned long long new) {+	return __sync_bool_compare_and_swap (p, old, new);+}+inline unsigned long long+val_compare_and_swap_64 (unsigned long long *p, unsigned long long old, unsigned long long new) {+	return __sync_val_compare_and_swap (p, old, new);+}+inline unsigned long long lock_test_and_set_64 (unsigned long long *p) {+	// Only immediate 0/1 appear to be widely supported, so hardcode it+	// here+	return __sync_lock_test_and_set (p, 1);+}+void lock_release_64 (unsigned long long *p) {+	// Writes a 0 to *p+	return __sync_lock_release (p);+}++/* Word-sized */+inline unsigned long fetch_and_add_word (unsigned long *p, unsigned long v) {+	return __sync_fetch_and_add (p, v);+}+inline unsigned long fetch_and_sub_word (unsigned long *p, unsigned long v) {+	return __sync_fetch_and_sub (p, v);+}+inline unsigned long fetch_and_or_word (unsigned long *p, unsigned long v) {+	return __sync_fetch_and_or (p, v);+}+inline unsigned long fetch_and_and_word (unsigned long *p, unsigned long v) {+	return __sync_fetch_and_and (p, v);+}+inline unsigned long fetch_and_xor_word (unsigned long *p, unsigned long v) {+	return __sync_fetch_and_xor (p, v);+}+inline unsigned long fetch_and_nand_word (unsigned long *p, unsigned long v) {+	return __sync_fetch_and_nand (p, v);+}+inline unsigned long add_and_fetch_word (unsigned long *p, unsigned long v) {+	return __sync_add_and_fetch (p, v);+}+inline unsigned long sub_and_fetch_word (unsigned long *p, unsigned long v) {+	return __sync_sub_and_fetch (p, v);+}+inline unsigned long or_and_fetch_word (unsigned long *p, unsigned long v) {+	return __sync_or_and_fetch (p, v);+}+inline unsigned long and_and_fetch_word (unsigned long *p, unsigned long v) {+	return __sync_and_and_fetch (p, v);+}+inline unsigned long xor_and_fetch_word (unsigned long *p, unsigned long v) {+	return __sync_xor_and_fetch (p, v);+}+inline unsigned long nand_and_fetch_word (unsigned long *p, unsigned long v) {+	return __sync_nand_and_fetch (p, v);+}+inline unsigned int+bool_compare_and_swap_word (unsigned long *p, unsigned long old, unsigned long new) {+	return __sync_bool_compare_and_swap (p, old, new);+}+inline unsigned long+val_compare_and_swap_word (unsigned long *p, unsigned long old, unsigned long new) {+	return __sync_val_compare_and_swap (p, old, new);+}+inline unsigned long lock_test_and_set_word (unsigned long *p) {+	// Only immediate 0/1 appear to be widely supported, so hardcode it+	// here+	return __sync_lock_test_and_set (p, 1);+}+void lock_release_word (unsigned long *p) {+	// Writes a 0 to *p+	return __sync_lock_release (p);+}
+ cbits/atomic-bitops-gcc.h view
@@ -0,0 +1,105 @@+// GCC atomic builtins, see http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Atomic-Builtins.html++/* No size */+void mem_barrier (void);++/* 8-bit */+inline unsigned char fetch_and_add_8 (unsigned char *, unsigned char );+inline unsigned char fetch_and_sub_8 (unsigned char *, unsigned char );+inline unsigned char fetch_and_or_8 (unsigned char *, unsigned char );+inline unsigned char fetch_and_and_8 (unsigned char *, unsigned char );+inline unsigned char fetch_and_xor_8 (unsigned char *, unsigned char );+inline unsigned char fetch_and_nand_8 (unsigned char *, unsigned char );+inline unsigned char add_and_fetch_8 (unsigned char *, unsigned char );+inline unsigned char sub_and_fetch_8 (unsigned char *, unsigned char );+inline unsigned char or_and_fetch_8 (unsigned char *, unsigned char );+inline unsigned char and_and_fetch_8 (unsigned char *, unsigned char );+inline unsigned char xor_and_fetch_8 (unsigned char *, unsigned char );+inline unsigned char nand_and_fetch_8 (unsigned char *, unsigned char );+inline unsigned int+bool_compare_and_swap_8 (unsigned char *, unsigned char, unsigned char);+inline unsigned char+val_compare_and_swap_8 (unsigned char *, unsigned char , unsigned char);+inline unsigned char lock_test_and_set_8 (unsigned char *);+void lock_release_8 (unsigned char *);++/* 16-bit */+inline unsigned short fetch_and_add_16 (unsigned short *, unsigned short );+inline unsigned short fetch_and_sub_16 (unsigned short *, unsigned short );+inline unsigned short fetch_and_or_16 (unsigned short *, unsigned short );+inline unsigned short fetch_and_and_16 (unsigned short *, unsigned short );+inline unsigned short fetch_and_xor_16 (unsigned short *, unsigned short );+inline unsigned short fetch_and_nand_16 (unsigned short *, unsigned short );+inline unsigned short add_and_fetch_16 (unsigned short *, unsigned short );+inline unsigned short sub_and_fetch_16 (unsigned short *, unsigned short );+inline unsigned short or_and_fetch_16 (unsigned short *, unsigned short );+inline unsigned short and_and_fetch_16 (unsigned short *, unsigned short );+inline unsigned short xor_and_fetch_16 (unsigned short *, unsigned short );+inline unsigned short nand_and_fetch_16 (unsigned short *, unsigned short );+inline unsigned int+bool_compare_and_swap_16 (unsigned short *, unsigned short , unsigned short );+inline unsigned short+val_compare_and_swap_16 (unsigned short *, unsigned short , unsigned short );+inline unsigned short lock_test_and_set_16 (unsigned short *);+void lock_release_16 (unsigned short *);+++/* 32-bit */+inline unsigned int fetch_and_add_32 (unsigned int *, unsigned int );+inline unsigned int fetch_and_sub_32 (unsigned int *, unsigned int );+inline unsigned int fetch_and_or_32 (unsigned int *, unsigned int );+inline unsigned int fetch_and_and_32 (unsigned int *, unsigned int );+inline unsigned int fetch_and_xor_32 (unsigned int *, unsigned int );+inline unsigned int fetch_and_nand_32 (unsigned int *, unsigned int );+inline unsigned int add_and_fetch_32 (unsigned int *, unsigned int );+inline unsigned int sub_and_fetch_32 (unsigned int *, unsigned int );+inline unsigned int or_and_fetch_32 (unsigned int *, unsigned int );+inline unsigned int and_and_fetch_32 (unsigned int *, unsigned int );+inline unsigned int xor_and_fetch_32 (unsigned int *, unsigned int );+inline unsigned int nand_and_fetch_32 (unsigned int *, unsigned int );+inline unsigned int+bool_compare_and_swap_32 (unsigned int *, unsigned int , unsigned int );+inline unsigned int+val_compare_and_swap_32 (unsigned int *, unsigned int , unsigned int );+inline unsigned int lock_test_and_set_32 (unsigned int *);+void lock_release_32 (unsigned int *);++/* 64-bit */+inline unsigned long long fetch_and_add_64 (unsigned long long *, unsigned long long );+inline unsigned long long fetch_and_sub_64 (unsigned long long *, unsigned long long );+inline unsigned long long fetch_and_or_64 (unsigned long long *, unsigned long long );+inline unsigned long long fetch_and_and_64 (unsigned long long *, unsigned long long );+inline unsigned long long fetch_and_xor_64 (unsigned long long *, unsigned long long );+inline unsigned long long fetch_and_nand_64 (unsigned long long *, unsigned long long );+inline unsigned long long add_and_fetch_64 (unsigned long long *, unsigned long long );+inline unsigned long long sub_and_fetch_64 (unsigned long long *, unsigned long long );+inline unsigned long long or_and_fetch_64 (unsigned long long *, unsigned long long );+inline unsigned long long and_and_fetch_64 (unsigned long long *, unsigned long long );+inline unsigned long long xor_and_fetch_64 (unsigned long long *, unsigned long long );+inline unsigned long long nand_and_fetch_64 (unsigned long long *, unsigned long long );+inline unsigned int+bool_compare_and_swap_64 (unsigned long long *, unsigned long long , unsigned long long );+inline unsigned long long+val_compare_and_swap_64 (unsigned long long *, unsigned long long , unsigned long long );+inline unsigned long long lock_test_and_set_64 (unsigned long long *);+void lock_release_64 (unsigned long long *);++/* Word */+inline unsigned long fetch_and_add_word (unsigned long *, unsigned long );+inline unsigned long fetch_and_sub_word (unsigned long *, unsigned long );+inline unsigned long fetch_and_or_word (unsigned long *, unsigned long );+inline unsigned long fetch_and_and_word (unsigned long *, unsigned long );+inline unsigned long fetch_and_xor_word (unsigned long *, unsigned long );+inline unsigned long fetch_and_nand_word (unsigned long *, unsigned long );+inline unsigned long add_and_fetch_word (unsigned long *, unsigned long );+inline unsigned long sub_and_fetch_word (unsigned long *, unsigned long );+inline unsigned long or_and_fetch_word (unsigned long *, unsigned long );+inline unsigned long and_and_fetch_word (unsigned long *, unsigned long );+inline unsigned long xor_and_fetch_word (unsigned long *, unsigned long );+inline unsigned long nand_and_fetch_word (unsigned long *, unsigned long );+inline unsigned int+bool_compare_and_swap_word (unsigned long *, unsigned long , unsigned long );+inline unsigned long+val_compare_and_swap_word (unsigned long *, unsigned long , unsigned long );+inline unsigned long lock_test_and_set_word (unsigned long *);+void lock_release_word (unsigned long *);
+ cbits/bitops-gcc.c view
@@ -0,0 +1,21 @@+#include "bitops-gcc.h"++inline unsigned int ffs (unsigned int x) { return __builtin_ffs (x); }+inline unsigned int clz (unsigned int x) { return __builtin_clz (x); }+inline unsigned int ctz (unsigned int x) { return __builtin_ctz (x); }+inline unsigned int popcount (unsigned int x) { return __builtin_popcount (x); }+inline unsigned int parity (unsigned int x) { return __builtin_parity (x); }+inline unsigned int bswap32 (unsigned int x) { return __builtin_bswap32(x); }++inline unsigned int ffsll (unsigned long long x) { return __builtin_ffsll (x); }+inline unsigned int clzll (unsigned long long x) { return __builtin_clzll (x); }+inline unsigned int ctzll (unsigned long long x) { return __builtin_ctzll (x); }+inline unsigned int popcountll (unsigned long long x) { return __builtin_popcountll (x); }+inline unsigned int parityll (unsigned long long x) { return __builtin_parityll (x); }+inline unsigned long long bswap64 (unsigned long long x) { return __builtin_bswap64(x); }++inline unsigned int ffsl (unsigned long x) { return __builtin_ffsll (x); }+inline unsigned int clzl (unsigned long x) { return __builtin_clzll (x); }+inline unsigned int ctzl (unsigned long x) { return __builtin_ctzll (x); }+inline unsigned int popcountl (unsigned long x) { return __builtin_popcountll (x); }+inline unsigned int parityl (unsigned long x) { return __builtin_parityll (x); }
+ cbits/bitops-gcc.h view
@@ -0,0 +1,22 @@+/* Word-sized */+inline unsigned int ffsl (unsigned long);+inline unsigned int clzl (unsigned long); +inline unsigned int ctzl (unsigned long);+inline unsigned int popcountl (unsigned long);+inline unsigned int parityl (unsigned long);++/* 32-bit */+inline unsigned int ffs (unsigned int);+inline unsigned int clz (unsigned int); +inline unsigned int ctz (unsigned int);+inline unsigned int popcount (unsigned int);+inline unsigned int parity (unsigned int);+inline unsigned int bswap32 (unsigned int);++/* 64-bit */+inline unsigned int ffsll (unsigned long long);+inline unsigned int clzll (unsigned long long);+inline unsigned int ctzll (unsigned long long);+inline unsigned int popcountll (unsigned long long);+inline unsigned int parityll (unsigned long long);+inline unsigned long long bswap64 (unsigned long long);