limited progress on typeof signedness

- ensure concats and repeats stay unsigned
- defer unbased-unsized conversion to enable cast semantics
- disable inaccurate folding of binary operations of based numbers
- fix typeof and size cast binop signedness logic
- fix typeof $unsigned and $signed
- test harness allows production of `integer unsigned`
This commit is contained in:
Zachary Snow
2021-02-01 10:17:50 -05:00
parent 275130e0b0
commit b8759776ca
9 changed files with 342 additions and 28 deletions
+7 -3
View File
@@ -36,8 +36,13 @@ simplifyStep (UniOp LogNot (BinOp Ne a b)) = BinOp Eq a b
simplifyStep (UniOp UniSub (UniOp UniSub e)) = e
simplifyStep (UniOp UniSub (BinOp Sub e1 e2)) = BinOp Sub e2 e1
simplifyStep (e @ (Concat [Pattern{}])) = e
simplifyStep (Concat [e]) = e
simplifyStep (Concat [Number (Decimal size _ value)]) =
Number $ Decimal size False value
simplifyStep (Concat [Number (Based size _ base value kinds)]) =
Number $ Based size False base value kinds
simplifyStep (Concat [e @ Stream{}]) = e
simplifyStep (Concat [e @ Concat{}]) = e
simplifyStep (Concat [e @ Repeat{}]) = e
simplifyStep (Concat es) = Concat $ filter (/= Concat []) es
simplifyStep (Repeat (Dec 0) _) = Concat []
simplifyStep (Repeat (Dec 1) es) = Concat es
@@ -107,7 +112,6 @@ simplifyBinOp op e1 e2 =
(Dec x, SizDec y) -> constantFold orig op x y
(Bas x, Dec y) -> constantFold orig op x y
(Dec x, Bas y) -> constantFold orig op x y
(Bas x, Bas y) -> constantFold orig op x y
(NegDec x, Dec y) -> constantFold orig op (-x) y
(Dec x, NegDec y) -> constantFold orig op x (-y)
(NegDec x, NegDec y) -> constantFold orig op (-x) (-y)
+23 -8
View File
@@ -59,9 +59,6 @@ traverseGenItemM = traverseGenItemExprsM traverseExprM
traverseStmtM :: Stmt -> Scoper Type Stmt
traverseStmtM = traverseStmtExprsM traverseExprM
pattern ConvertedUU :: Integer -> Integer -> Expr
pattern ConvertedUU a b = Number (Based 1 True Binary a b)
traverseExprM :: Expr -> Scoper Type Expr
traverseExprM =
traverseNestedExprsM convertExprM
@@ -104,10 +101,24 @@ traverseExprM =
convertExprM other = return other
convertCastM :: Expr -> Expr -> Scoper Type Expr
convertCastM (RawNum n) (ConvertedUU a b) =
convertCastM (RawNum n) (Number (Based 1 True Binary a b)) =
return $ Number $ Based (fromIntegral n) True Binary
(extend a) (extend b)
where
extend 0 = 0
extend 1 = (2 ^ n) - 1
extend _ = error "not possible"
convertCastM (RawNum n) (Number (UnbasedUnsized ch)) =
return $ Number $ Based (fromIntegral n) False Binary
(extend a) (extend b)
where
(a, b) = case ch of
'0' -> (0, 0)
'1' -> (1, 0)
'x' -> (0, 1)
'z' -> (1, 1)
_ -> error $ "unexpected unbased-unsized digit: " ++ [ch]
extend :: Integer -> Integer
extend 0 = 0
extend 1 = (2 ^ n) - 1
extend _ = error "not possible"
@@ -183,6 +194,10 @@ exprSigning scopes (BinOp op e1 e2) =
ShiftAL -> curry fst
ShiftAR -> curry fst
_ -> \_ _ -> Just Unspecified
exprSigning _ (Number n) =
Just $ if numberIsSigned n
then Signed
else Unsigned
exprSigning scopes expr =
case lookupElem scopes expr of
Just (_, _, t) -> typeSigning t
@@ -191,11 +206,11 @@ exprSigning scopes expr =
combineSigning :: Maybe Signing -> Maybe Signing -> Maybe Signing
combineSigning Nothing _ = Nothing
combineSigning _ Nothing = Nothing
combineSigning (Just Unspecified) msg = msg
combineSigning msg (Just Unspecified) = msg
combineSigning (Just Signed) _ = Just Signed
combineSigning _ (Just Signed) = Just Signed
combineSigning (Just Unspecified) _ = Just Unspecified
combineSigning _ (Just Unspecified) = Just Unspecified
combineSigning (Just Unsigned) _ = Just Unsigned
combineSigning _ (Just Unsigned) = Just Unsigned
combineSigning (Just Signed) (Just Signed) = Just Signed
typeSigning :: Type -> Maybe Signing
typeSigning (Net _ sg _) = Just sg
+52 -15
View File
@@ -117,16 +117,18 @@ typeof (Number n) =
typeof (Call (Ident x) args) = typeofCall x args
typeof (orig @ (Bit e _)) = do
t <- typeof e
let t' = popRange t
case t of
TypeOf{} -> lookupTypeOf orig
Alias{} -> return $ TypeOf orig
_ -> return $ popRange t
_ -> return $ typeSignednessOverride t' Unsigned t'
typeof (orig @ (Range e mode r)) = do
t <- typeof e
let t' = replaceRange (lo, hi) t
return $ case t of
TypeOf{} -> TypeOf orig
Alias{} -> TypeOf orig
_ -> replaceRange (lo, hi) t
_ -> typeSignednessOverride t' Unsigned t'
where
lo = fst r
hi = case mode of
@@ -145,12 +147,12 @@ typeof (orig @ (Dot e x)) = do
case lookup x $ map swap fields of
Just typ -> typ
Nothing -> TypeOf orig
typeof (Cast (Right s) _) = return $ typeOfSize s
typeof (UniOp op expr) = typeofUniOp op expr
typeof (BinOp op a b) = typeofBinOp op a b
typeof (Mux _ a b) = largerSizeType a b
typeof (Concat exprs) = return $ typeOfSize $ concatSize exprs
typeof (Repeat reps exprs) = return $ typeOfSize size
typeof (Concat exprs) = return $ typeOfSize Unsigned $ concatSize exprs
typeof (Stream _ _ exprs) = return $ typeOfSize Unsigned $ concatSize exprs
typeof (Repeat reps exprs) = return $ typeOfSize Unsigned size
where size = BinOp Mul reps (concatSize exprs)
typeof (String str) =
return $ IntegerVector TBit Unspecified [r]
@@ -167,12 +169,22 @@ unescapedLength (_ : rest) = 1 + unescapedLength rest
-- type of a standard (non-member) function call
typeofCall :: String -> Args -> Scoper Type Type
typeofCall "$unsigned" (Args [e] []) = typeof e
typeofCall "$signed" (Args [e] []) = typeof e
typeofCall "$unsigned" (Args [e] []) = return $ typeOfSize Unsigned $ sizeof e
typeofCall "$signed" (Args [e] []) = return $ typeOfSize Signed $ sizeof e
typeofCall "$clog2" (Args [_] []) =
return $ IntegerAtom TInteger Unspecified
typeofCall fnName _ = typeof $ Ident fnName
-- replaces the signing of a type if possible
typeSignednessOverride :: Type -> Signing -> Type -> Type
typeSignednessOverride fallback sg t =
case t of
IntegerVector base _ rs -> IntegerVector base sg rs
IntegerAtom base _ -> IntegerAtom base sg
Net base _ rs -> Net base sg rs
Implicit _ rs -> Implicit sg rs
_ -> fallback
-- type of a unary operator expression
typeofUniOp :: UniOp -> Expr -> Scoper Type Type
typeofUniOp UniAdd e = typeof e
@@ -222,9 +234,36 @@ largerSizeType a (Number (Based 1 _ _ _ _)) = typeof a
largerSizeType a b = do
t <- typeof a
u <- typeof b
return $ if t == u
then t
else typeOfSize $ largerSizeOf a b
let sg = binopSignedness (typeSignedness t) (typeSignedness u)
return $
if t == u then
t
else if sg == Unspecified then
TypeOf $ BinOp Add a b
else
typeOfSize sg $ largerSizeOf a b
-- returns the signedness of a traditional arithmetic binop, if possible
binopSignedness :: Signing -> Signing -> Signing
binopSignedness Unspecified _ = Unspecified
binopSignedness _ Unspecified = Unspecified
binopSignedness Unsigned _ = Unsigned
binopSignedness _ Unsigned = Unsigned
binopSignedness Signed Signed = Signed
-- returns the signedness of the given type, if possible
typeSignedness :: Type -> Signing
typeSignedness (Net _ sg _) = signednessFallback Unsigned sg
typeSignedness (Implicit sg _) = signednessFallback Unsigned sg
typeSignedness (IntegerVector _ sg _) = signednessFallback Unsigned sg
typeSignedness (IntegerAtom t sg ) = signednessFallback fallback sg
where fallback = if t == TTime then Unsigned else Signed
typeSignedness _ = Unspecified
-- helper for producing the former signing when the latter is unspecified
signednessFallback :: Signing -> Signing -> Signing
signednessFallback fallback Unspecified = fallback
signednessFallback _ sg = sg
-- returns the total size of concatenated list of expressions
concatSize :: [Expr] -> Expr
@@ -245,12 +284,10 @@ largerSizeOf a b =
where cond = BinOp Ge (sizeof a) (sizeof b)
-- produces a generic type of the given size
typeOfSize :: Expr -> Type
typeOfSize size =
typeOfSize :: Signing -> Expr -> Type
typeOfSize sg size =
IntegerVector TLogic sg [(hi, RawNum 0)]
where
sg = Unspecified -- suitable for now
hi = BinOp Sub size (RawNum 1)
where hi = BinOp Sub size (RawNum 1)
-- combines a type with unpacked ranges
injectRanges :: Type -> [Range] -> Type