module Ivory.Language.Bits where
import Ivory.Language.Type
import Ivory.Language.Uint
import Ivory.Language.Cast
import qualified Ivory.Language.Syntax as AST
bitOp :: forall a. IvoryExpr a => AST.ExpOp -> a -> a -> a
bitOp op a b = wrapExpr (AST.ExpOp op [unwrapExpr a, unwrapExpr b])
class (Num a, IvoryExpr a) => IvoryBits a where
(.&) :: a -> a -> a
(.&) = bitOp AST.ExpBitAnd
(.|) :: a -> a -> a
(.|) = bitOp AST.ExpBitOr
(.^) :: a -> a -> a
(.^) = bitOp AST.ExpBitXor
iComplement :: a -> a
iComplement a = wrapExpr (AST.ExpOp AST.ExpBitComplement [unwrapExpr a])
iShiftL :: a -> a -> a
iShiftL = bitOp AST.ExpBitShiftL
iShiftR :: a -> a -> a
iShiftR = bitOp AST.ExpBitShiftR
instance IvoryBits Uint8
instance IvoryBits Uint16
instance IvoryBits Uint32
instance IvoryBits Uint64
class (IvoryBits a, IvoryBits b) => BitSplit a b | a -> b where
ubits :: a -> b
lbits :: a -> b
instance BitSplit Uint64 Uint32 where
ubits x = ivoryCast ((x `iShiftR` 32) .& 0xffffffff)
lbits x = ivoryCast (x .& 0xffffffff)
instance BitSplit Uint32 Uint16 where
ubits x = ivoryCast ((x `iShiftR` 16) .& 0xffff)
lbits x = ivoryCast (x .& 0xffff)
instance BitSplit Uint16 Uint8 where
ubits x = ivoryCast ((x `iShiftR` 8) .& 0xff)
lbits x = ivoryCast (x .& 0xff)
class (IvoryBits a, IvoryBits b) => BitCast a b where
bitCast :: a -> b
instance BitCast Uint64 Uint64 where
bitCast = id
instance BitCast Uint64 Uint32 where
bitCast = lbits
instance BitCast Uint64 Uint16 where
bitCast = lbits . lbits
instance BitCast Uint64 Uint8 where
bitCast = lbits . lbits . lbits
instance BitCast Uint32 Uint32 where
bitCast = id
instance BitCast Uint32 Uint16 where
bitCast = lbits
instance BitCast Uint32 Uint8 where
bitCast = lbits . lbits
instance BitCast Uint16 Uint16 where
bitCast = id
instance BitCast Uint16 Uint8 where
bitCast = lbits
instance BitCast Uint8 Uint8 where
bitCast = id
extractByte :: (BitCast a Uint8) => a -> (Uint8, a)
extractByte x = (bitCast x, x `iShiftR` 8)