module IR.BitVec where import IR.Boolean type BitVec = [BExpr] bvConst :: Int -> Int -> BitVec bvConst width val = [if testBit i then BTrue else BFalse | i <- [0..width-1]] where testBit i = (val `div` (2^i)) `mod` 2 == 1 bvVar :: Int -> Int -> BitVec bvVar start width = [BVar (start + i) | i <- [0..width-1]] bvNot :: BitVec -> BitVec bvNot = map bnot bvAnd :: BitVec -> BitVec -> BitVec bvAnd = zipWith band bvOr :: BitVec -> BitVec -> BitVec bvOr = zipWith bor bvXor :: BitVec -> BitVec -> BitVec bvXor = zipWith bxor halfAdder :: BExpr -> BExpr -> (BExpr, BExpr) halfAdder a b = (bxor a b, band a b) fullAdder :: BExpr -> BExpr -> BExpr -> (BExpr, BExpr) fullAdder a b cin = let (s1, c1) = halfAdder a b (s2, c2) = halfAdder s1 cin in (s2, bor c1 c2) bvAdd :: BitVec -> BitVec -> BitVec bvAdd [] [] = [] bvAdd as bs = go as bs BFalse where go [] [] _ = [] go (a:as') (b:bs') cin = let (s, cout) = fullAdder a b cin in s : go as' bs' cout go _ _ _ = [] bvEq :: BitVec -> BitVec -> BExpr bvEq as bs = foldr band BTrue (zipWith xnor as bs) where xnor a b = bnot (bxor a b)