{-# LANGUAGE BangPatterns #-}
module What4.Domains.Arithmetic
( ctz
, clz
, intLog2
, isPow2Integer
, bitsBelow
, rotateLeft
, rotateRight
) where
import Data.Bits (Bits(..), xor, shiftL, shiftR)
import Data.Parameterized.NatRepr
import What4.Domains.Arithmetic.Internal
( ctzOpt, clzOpt, intLog2Opt, isPow2IntegerOpt )
ctz :: NatRepr w -> Integer -> Integer
ctz :: forall (w :: Nat). NatRepr w -> Integer -> Integer
ctz = NatRepr w -> Integer -> Integer
forall (w :: Nat). NatRepr w -> Integer -> Integer
ctzOpt
clz :: NatRepr w -> Integer -> Integer
clz :: forall (w :: Nat). NatRepr w -> Integer -> Integer
clz = NatRepr w -> Integer -> Integer
forall (w :: Nat). NatRepr w -> Integer -> Integer
clzOpt
intLog2 :: Integer -> Int
intLog2 :: Integer -> Int
intLog2 = Integer -> Int
intLog2Opt
{-# INLINE intLog2 #-}
isPow2Integer :: Integer -> Bool
isPow2Integer :: Integer -> Bool
isPow2Integer = Integer -> Bool
isPow2IntegerOpt
{-# INLINE isPow2Integer #-}
bitsBelow :: Integer -> Integer
bitsBelow :: Integer -> Integer
bitsBelow Integer
n
| Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
0 = Integer
0
| Bool
otherwise = Int -> Integer
forall a. Bits a => Int -> a
bit (Integer -> Int
intLog2 Integer
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1
{-# INLINE bitsBelow #-}
rotateRight ::
NatRepr w ->
Integer ->
Integer ->
Integer
rotateRight :: forall (w :: Nat). NatRepr w -> Integer -> Integer -> Integer
rotateRight NatRepr w
w Integer
x Integer
n = Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
xor (Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftR Integer
x' Int
n') (NatRepr w -> Integer -> Integer
forall (w :: Nat). NatRepr w -> Integer -> Integer
toUnsigned NatRepr w
w (Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftL Integer
x' (NatRepr w -> Int
forall (n :: Nat). NatRepr n -> Int
widthVal NatRepr w
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n')))
where
x' :: Integer
x' = NatRepr w -> Integer -> Integer
forall (w :: Nat). NatRepr w -> Integer -> Integer
toUnsigned NatRepr w
w Integer
x
n' :: Int
n' = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer
n Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`rem` NatRepr w -> Integer
forall (n :: Nat). NatRepr n -> Integer
intValue NatRepr w
w)
rotateLeft ::
NatRepr w ->
Integer ->
Integer ->
Integer
rotateLeft :: forall (w :: Nat). NatRepr w -> Integer -> Integer -> Integer
rotateLeft NatRepr w
w Integer
x Integer
n = Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
xor (Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftR Integer
x' (NatRepr w -> Int
forall (n :: Nat). NatRepr n -> Int
widthVal NatRepr w
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n')) (NatRepr w -> Integer -> Integer
forall (w :: Nat). NatRepr w -> Integer -> Integer
toUnsigned NatRepr w
w (Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftL Integer
x' Int
n'))
where
x' :: Integer
x' = NatRepr w -> Integer -> Integer
forall (w :: Nat). NatRepr w -> Integer -> Integer
toUnsigned NatRepr w
w Integer
x
n' :: Int
n' = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer
n Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`rem` NatRepr w -> Integer
forall (n :: Nat). NatRepr n -> Integer
intValue NatRepr w
w)