packages feed

hw-prim-bits-0.1.0.5: src/HaskellWorks/Prim/Bits/Emul.hs

module HaskellWorks.Prim.Bits.Emul
  ( pdep32
  , pdep64
  , pext32
  , pext64
  ) where

import Data.Bits
import Data.Int
import Data.Word

pdep64 :: Word64 -> Word64 -> Word64
pdep64 = pdep64' 0

pdep32 :: Word32 -> Word32 -> Word32
pdep32 src mask = fromIntegral (pdep64 (fromIntegral src) (fromIntegral mask))

pdep64' :: Word64 -> Word64 -> Word64 -> Word64
pdep64' result src mask = if lowest /= 0
  then pdep64' (result .|. (lsb .&. lowest)) (src `shiftR` 1) (mask .&. complement lowest)
  else result
  where lowest  = (-mask) .&. mask
        lsb     = fromIntegral ((fromIntegral (src `shiftL` 63) :: Int64) `shiftR` 63)


pext64 :: Word64 -> Word64 -> Word64
pext64 = pext64' 0 0 0

pext32 :: Word32 -> Word32 -> Word32
pext32 src mask = fromIntegral (pext64 (fromIntegral src) (fromIntegral mask))

pext64' :: Word64 -> Int -> Int -> Word64 -> Word64 -> Word64
pext64' result offset index src mask = if index /= 64
  then if maskBit /= 0
          then pext64' (result .|. (srcBit `shiftL` offset)) (offset + 1) (index + 1) src mask
          else pext64'  result                               offset       (index + 1) src mask
  else result
  where srcBit  = (src  `shiftR` index) .&. 1
        maskBit = (mask `shiftR` index) .&. 1