mirror of https://github.com/zachjs/sv2v.git
improved handling of number literals
- elaborated literals larger than 32 bits are given an explicit size - constant folding no longer encodes illegal negative numbers
This commit is contained in:
parent
4b5e3232b9
commit
d2a0ba0d13
|
|
@ -82,7 +82,7 @@ convertExpr (DimFn f (Left t) (Number str)) =
|
|||
else case f of
|
||||
FnLeft -> fst r
|
||||
FnRight -> snd r
|
||||
FnIncrement -> endianCondExpr r (Number "1") (Number "-1")
|
||||
FnIncrement -> endianCondExpr r (Number "1") (UniOp UniSub $ Number "1")
|
||||
FnLow -> endianCondExpr r (snd r) (fst r)
|
||||
FnHigh -> endianCondExpr r (fst r) (snd r)
|
||||
FnSize -> rangeSize r
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ makeEnumItems (itemType, l) =
|
|||
++ show (zip keys vals)
|
||||
where
|
||||
keys = map fst l
|
||||
vals = tail $ scanl step (Number "-1") (map snd l)
|
||||
vals = tail $ scanl step (UniOp UniSub $ Number "1") (map snd l)
|
||||
noDuplicates = all (null . tail . flip elemIndices vals) vals
|
||||
step :: Expr -> Expr -> Expr
|
||||
step expr Nil = simplify $ BinOp Add expr (Number "1")
|
||||
|
|
|
|||
|
|
@ -65,8 +65,9 @@ convertStruct' isStruct sg fields =
|
|||
else map simplify $ repeat (Number "0")
|
||||
fieldHis =
|
||||
if isStruct
|
||||
then map simplify $ init $ scanr (BinOp Add) (Number "-1") fieldSizes
|
||||
else map simplify $ map (BinOp Add (Number "-1")) fieldSizes
|
||||
then map simplify $ init $ scanr (BinOp Add) minusOne fieldSizes
|
||||
else map simplify $ map (BinOp Add minusOne) fieldSizes
|
||||
minusOne = UniOp UniSub $ Number "1"
|
||||
|
||||
-- create the mapping structure for the unstructured fields
|
||||
keys = map snd fields
|
||||
|
|
|
|||
|
|
@ -233,10 +233,6 @@ simplify :: Expr -> Expr
|
|||
simplify (UniOp LogNot (Number "1")) = Number "0"
|
||||
simplify (UniOp LogNot (Number "0")) = Number "1"
|
||||
simplify (UniOp LogNot (BinOp Eq a b)) = BinOp Ne a b
|
||||
simplify (orig @ (UniOp UniSub (Number n))) =
|
||||
case readNumber n of
|
||||
Nothing -> orig
|
||||
Just x -> Number $ show (-x)
|
||||
simplify (orig @ (Repeat (Number n) exprs)) =
|
||||
case readNumber n of
|
||||
Nothing -> orig
|
||||
|
|
@ -252,7 +248,7 @@ simplify (Concat exprs) =
|
|||
simplify (orig @ (Call (Ident "$clog2") (Args [Number n] []))) =
|
||||
case readNumber n of
|
||||
Nothing -> orig
|
||||
Just x -> Number $ show $ clog2 x
|
||||
Just x -> toLiteral $ clog2 x
|
||||
simplify (Mux cc e1 e2) =
|
||||
case cc' of
|
||||
Number "1" -> e1'
|
||||
|
|
@ -274,10 +270,14 @@ simplify (BinOp Add (Number n1) (BinOp Add (Number n2) e)) =
|
|||
simplify $ BinOp Add (BinOp Add (Number n1) (Number n2)) e
|
||||
simplify (BinOp Ge (BinOp Sub e (Number "1")) (Number "0")) =
|
||||
simplify $ BinOp Ge e (Number "1")
|
||||
simplify (BinOp Add e1 (UniOp UniSub e2)) =
|
||||
simplify $ BinOp Sub e1 e2
|
||||
simplify (BinOp Add (UniOp UniSub e2) e1) =
|
||||
simplify $ BinOp Sub e1 e2
|
||||
simplify (BinOp Add (BinOp Sub (Number n1) e) (Number n2)) =
|
||||
case (readNumber n1, readNumber n2) of
|
||||
(Just x, Just y) ->
|
||||
simplify $ BinOp Sub (Number $ show (x + y)) e'
|
||||
simplify $ BinOp Sub (toLiteral (x + y)) e'
|
||||
_ -> nochange
|
||||
where
|
||||
e' = simplify e
|
||||
|
|
@ -295,33 +295,33 @@ simplify (BinOp op e1 e2) =
|
|||
(Add, e, BinOp Sub (Number "0") (Number "1")) -> BinOp Sub e (Number "1")
|
||||
(_ , Number a, Number b) ->
|
||||
case (op, readNumber a, readNumber b) of
|
||||
(Add, Just x, Just y) -> Number $ show (x + y)
|
||||
(Sub, Just x, Just y) -> Number $ show (x - y)
|
||||
(Mul, Just x, Just y) -> Number $ show (x * y)
|
||||
(Add, Just x, Just y) -> toLiteral (x + y)
|
||||
(Sub, Just x, Just y) -> toLiteral (x - y)
|
||||
(Mul, Just x, Just y) -> toLiteral (x * y)
|
||||
(Div, Just _, Just 0) -> Number "x"
|
||||
(Div, Just x, Just y) -> Number $ show (x `quot` y)
|
||||
(Mod, Just x, Just y) -> Number $ show (x `rem` y)
|
||||
(Pow, Just x, Just y) -> Number $ show (x ^ y)
|
||||
(Div, Just x, Just y) -> toLiteral (x `quot` y)
|
||||
(Mod, Just x, Just y) -> toLiteral (x `rem` y)
|
||||
(Pow, Just x, Just y) -> toLiteral (x ^ y)
|
||||
(Eq , Just x, Just y) -> bool $ x == y
|
||||
(Ne , Just x, Just y) -> bool $ x /= y
|
||||
(Gt , Just x, Just y) -> bool $ x > y
|
||||
(Ge , Just x, Just y) -> bool $ x >= y
|
||||
(Lt , Just x, Just y) -> bool $ x < y
|
||||
(Le , Just x, Just y) -> bool $ x <= y
|
||||
(ShiftAL, Just x, Just y) -> Number $ show $ shiftL x (toInt y)
|
||||
(ShiftAR, Just x, Just y) -> Number $ show $ shiftR x (toInt y)
|
||||
(ShiftL , Just x, Just y) -> Number $ show $ shiftL x (toInt y)
|
||||
(ShiftAL, Just x, Just y) -> toLiteral $ shiftL x (toInt y)
|
||||
(ShiftAR, Just x, Just y) -> toLiteral $ shiftR x (toInt y)
|
||||
(ShiftL , Just x, Just y) -> toLiteral $ shiftL x (toInt y)
|
||||
(ShiftR , Just x, Just y) ->
|
||||
if x < 0 && y > 0
|
||||
then BinOp ShiftR (Number a) (Number b)
|
||||
else Number $ show $ shiftR x (toInt y)
|
||||
else toLiteral $ shiftR x (toInt y)
|
||||
_ -> BinOp op e1' e2'
|
||||
where
|
||||
toInt :: Integer -> Int
|
||||
toInt = fromIntegral
|
||||
(Add, BinOp Add e (Number a), Number b) ->
|
||||
case (readNumber a, readNumber b) of
|
||||
(Just x, Just y) -> BinOp Add e $ Number $ show (x + y)
|
||||
(Just x, Just y) -> BinOp Add e $ toLiteral (x + y)
|
||||
_ -> BinOp op e1' e2'
|
||||
(Sub, e, Number "-1") -> BinOp Add e (Number "1")
|
||||
_ -> BinOp op e1' e2'
|
||||
|
|
@ -332,6 +332,16 @@ simplify (BinOp op e1 e2) =
|
|||
bool False = Number "0"
|
||||
simplify other = other
|
||||
|
||||
toLiteral :: Integer -> Expr
|
||||
toLiteral n =
|
||||
if n >= 4294967296
|
||||
then Number $ show (bits n) ++ "'d" ++ show n
|
||||
else Number $ show n
|
||||
|
||||
bits :: Integer -> Integer
|
||||
bits 0 = 0
|
||||
bits n = 1 + bits (quot n 2)
|
||||
|
||||
rangeSize :: Range -> Expr
|
||||
rangeSize (s, e) =
|
||||
endianCondExpr (s, e) a b
|
||||
|
|
|
|||
Loading…
Reference in New Issue