From 1903bc190deaa42e72560ed1a18ecef2f2f2efdc Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Thu, 2 Jul 2020 23:33:03 -0600 Subject: [PATCH] use unbounded integers --- src/Convert/SizeCast.hs | 4 +--- src/Convert/TypeOf.hs | 3 +-- src/Language/SystemVerilog/AST/Expr.hs | 28 +++++++++----------------- test/basic/shift.sv | 20 ++++++++++++++++++ 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/Convert/SizeCast.hs b/src/Convert/SizeCast.hs index e9ec593..12ac644 100644 --- a/src/Convert/SizeCast.hs +++ b/src/Convert/SizeCast.hs @@ -66,9 +66,7 @@ traverseExprM = where str = (show size) ++ "'d" ++ (show num) size = s' - num = if size >= 32 - then n' -- already read as 32 bits - else n' `mod` (2 ^ s') + num = n' `mod` (2 ^ s') _ -> convertCastM (Number s) (Number n) convertExprM (orig @ (Cast (Right DimsFn{}) _)) = return orig diff --git a/src/Convert/TypeOf.hs b/src/Convert/TypeOf.hs index da4e340..42580cf 100644 --- a/src/Convert/TypeOf.hs +++ b/src/Convert/TypeOf.hs @@ -12,7 +12,6 @@ module Convert.TypeOf (convert) where import Data.List (elemIndex) -import Data.Int (Int32) import Data.Tuple (swap) import qualified Data.Map.Strict as Map @@ -140,7 +139,7 @@ typeof (Repeat reps exprs) = return $ typeOfSize size typeof other = lookupTypeOf other -- determines the size and sign of a number literal -parseNumber :: String -> (Int32, Signing) +parseNumber :: String -> (Integer, Signing) parseNumber s = case elemIndex '\'' s of Nothing -> (32, Signed) diff --git a/src/Language/SystemVerilog/AST/Expr.hs b/src/Language/SystemVerilog/AST/Expr.hs index 52f1603..114d2fc 100644 --- a/src/Language/SystemVerilog/AST/Expr.hs +++ b/src/Language/SystemVerilog/AST/Expr.hs @@ -27,9 +27,7 @@ module Language.SystemVerilog.AST.Expr ) where import Data.Bits (shiftL, shiftR) -import Data.Int (Int32) import Data.List (intercalate) -import Data.Word (Word32) import Numeric (readHex) import Text.Printf (printf) import Text.Read (readMaybe) @@ -191,12 +189,12 @@ showExprOrRange :: ExprOrRange -> String showExprOrRange (Left x) = show x showExprOrRange (Right x) = show x -clog2Help :: Int32 -> Int32 -> Int32 +clog2Help :: Integer -> Integer -> Integer clog2Help p n = if p >= n then 0 else 1 + clog2Help (p*2) n -clog2 :: Int32 -> Int32 +clog2 :: Integer -> Integer clog2 n = if n < 2 then 0 else clog2Help 1 n -readNumber :: String -> Maybe Int32 +readNumber :: String -> Maybe Integer readNumber ('3' : '2' : '\'' : 'd' : rest) = readMaybe rest readNumber ( '\'' : 'd' : rest) = readMaybe rest readNumber ('3' : '2' : '\'' : 'h' : rest) = @@ -207,13 +205,7 @@ readNumber ('\'' : 'h' : rest) = case readHex rest of [(v, _)] -> Just v _ -> Nothing -readNumber n = - case readMaybe n of - Nothing -> Nothing - Just res -> - if show res == n - then Just res - else Nothing +readNumber n = readMaybe n showUniOpPrec :: Expr -> ShowS showUniOpPrec (e @ UniOp{}) = (showParen True . shows) e @@ -308,16 +300,14 @@ simplify (BinOp op e1 e2) = (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) - (ShiftR , Just x, Just y) -> -- does not sign extend - Number $ show $ toInt32 $ shiftR (toWord32 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) _ -> BinOp op e1' e2' where - toInt :: Int32 -> Int + toInt :: Integer -> Int toInt = fromIntegral - toWord32 :: Int32 -> Word32 - toWord32 = fromIntegral - toInt32 :: Word32 -> Int32 - toInt32 = 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) diff --git a/test/basic/shift.sv b/test/basic/shift.sv index f747719..53b891d 100644 --- a/test/basic/shift.sv +++ b/test/basic/shift.sv @@ -26,5 +26,25 @@ module top; `TEST(2, 1); `TEST(2, 2); `TEST(2, 3); + + `TEST(-8589934592, 0); + `TEST(-8589934592, 1); + `TEST(-8589934592, 2); + `TEST(-8589934592, 3); + + `TEST(-8589934593, 0); + `TEST(-8589934593, 1); + `TEST(-8589934593, 2); + `TEST(-8589934593, 3); + + `TEST(8589934592, 0); + `TEST(8589934592, 1); + `TEST(8589934592, 2); + `TEST(8589934592, 3); + + `TEST(8589934593, 0); + `TEST(8589934593, 1); + `TEST(8589934593, 2); + `TEST(8589934593, 3); end endmodule