Commit 50d6faa9 by Zachary Snow

yosys-compatible simple loop jump conversion

parent cadd7de2
...@@ -86,10 +86,10 @@ phases excludes = ...@@ -86,10 +86,10 @@ phases excludes =
, Convert.Package.convert , Convert.Package.convert
, Convert.Enum.convert , Convert.Enum.convert
, Convert.NestPI.convert , Convert.NestPI.convert
, Convert.ForDecl.convert
, Convert.Jump.convert , Convert.Jump.convert
, Convert.Foreach.convert , Convert.Foreach.convert
, selectExclude (Job.Interface, Convert.Interface.convert) , selectExclude (Job.Interface, Convert.Interface.convert)
, Convert.ForDecl.convert
, selectExclude (Job.Always , Convert.AlwaysKW.convert) , selectExclude (Job.Always , Convert.AlwaysKW.convert)
, selectExclude (Job.Succinct , Convert.RemoveComments.convert) , selectExclude (Job.Succinct , Convert.RemoveComments.convert)
] ]
......
{-# LANGUAGE PatternSynonyms #-}
{- sv2v {- sv2v
- Author: Zachary Snow <zach@zachjs.com> - Author: Zachary Snow <zach@zachjs.com>
- -
...@@ -116,6 +117,16 @@ convertStmts stmts = do ...@@ -116,6 +117,16 @@ convertStmts stmts = do
return stmts' return stmts'
pattern SimpleLoopInits :: Type -> Identifier -> Expr
-> Either [Decl] [(LHS, Expr)]
pattern SimpleLoopInits typ var expr = Left [Variable Local typ var [] expr]
pattern SimpleLoopGuard :: BinOp -> Identifier -> Expr -> Expr
pattern SimpleLoopGuard cmp var bound = BinOp cmp (Ident var) bound
pattern SimpleLoopIncrs :: Identifier -> AsgnOp -> Expr -> [(LHS, AsgnOp, Expr)]
pattern SimpleLoopIncrs var op step = [(LHSIdent var, op, step)]
-- rewrites the given statement, and returns the type of any unfinished jump -- rewrites the given statement, and returns the type of any unfinished jump
convertStmt :: Stmt -> State Info Stmt convertStmt :: Stmt -> State Info Stmt
...@@ -166,13 +177,22 @@ convertStmt (Case unique kw expr cases) = do ...@@ -166,13 +177,22 @@ convertStmt (Case unique kw expr cases) = do
modify $ \s -> s { sHasJump = hasJump } modify $ \s -> s { sHasJump = hasJump }
return $ Case unique kw expr cases' return $ Case unique kw expr cases'
convertStmt (For
(inits @ (SimpleLoopInits _ var1 _))
(comp @ (SimpleLoopGuard _ var2 _))
(incr @ (SimpleLoopIncrs var3 _ _))
stmt) =
if var1 /= var2 || var2 /= var3
then convertLoop False loop comp stmt
else convertLoop True loop comp stmt
where loop c s = For inits c incr s
convertStmt (For inits comp incr stmt) = convertStmt (For inits comp incr stmt) =
convertLoop loop comp stmt convertLoop False loop comp stmt
where loop c s = For inits c incr s where loop c s = For inits c incr s
convertStmt (While comp stmt) = convertStmt (While comp stmt) =
convertLoop While comp stmt convertLoop False While comp stmt
convertStmt (DoWhile comp stmt) = convertStmt (DoWhile comp stmt) =
convertLoop DoWhile comp stmt convertLoop False DoWhile comp stmt
convertStmt (Continue) = do convertStmt (Continue) = do
loopDepth <- gets sLoopDepth loopDepth <- gets sLoopDepth
...@@ -236,8 +256,8 @@ convertSubStmt stmt = do ...@@ -236,8 +256,8 @@ convertSubStmt stmt = do
put origState put origState
return (stmt', hasJump) return (stmt', hasJump)
convertLoop :: (Expr -> Stmt -> Stmt) -> Expr -> Stmt -> State Info Stmt convertLoop :: Bool -> (Expr -> Stmt -> Stmt) -> Expr -> Stmt -> State Info Stmt
convertLoop loop comp stmt = do convertLoop local loop comp stmt = do
-- save the loop state and increment loop depth -- save the loop state and increment loop depth
Info { sLoopDepth = origLoopDepth, sHasJump = origHasJump } <- get Info { sLoopDepth = origLoopDepth, sHasJump = origHasJump } <- get
assertMsg (not origHasJump) "has jump invariant failed" assertMsg (not origHasJump) "has jump invariant failed"
...@@ -249,11 +269,13 @@ convertLoop loop comp stmt = do ...@@ -249,11 +269,13 @@ convertLoop loop comp stmt = do
assertMsg (origLoopDepth + 1 == afterLoopDepth) "loop depth invariant failed" assertMsg (origLoopDepth + 1 == afterLoopDepth) "loop depth invariant failed"
modify $ \s -> s { sLoopDepth = origLoopDepth } modify $ \s -> s { sLoopDepth = origLoopDepth }
let comp' = BinOp LogAnd comp $ BinOp Lt (Ident jumpState) jsBreak let keepRunning = BinOp Lt (Ident jumpState) jsBreak
let body = Block Seq "" [] let comp' = if local then comp else BinOp LogAnd comp keepRunning
let body = Block Seq "" [] $
[ asgn jumpState jsNone [ asgn jumpState jsNone
, stmt' , stmt'
] ]
let body' = if local then If NoCheck keepRunning body Null else body
let jsStackIdent = jumpState ++ "_" ++ show origLoopDepth let jsStackIdent = jumpState ++ "_" ++ show origLoopDepth
let jsStackDecl = Variable Local jumpStateType jsStackIdent [] let jsStackDecl = Variable Local jumpStateType jsStackIdent []
(Ident jumpState) (Ident jumpState)
...@@ -271,13 +293,13 @@ convertLoop loop comp stmt = do ...@@ -271,13 +293,13 @@ convertLoop loop comp stmt = do
loop comp stmt' loop comp stmt'
else if origLoopDepth == 0 then else if origLoopDepth == 0 then
Block Seq "" [] Block Seq "" []
[ loop comp' body [ loop comp' body'
, jsCheckReturn , jsCheckReturn
] ]
else else
Block Seq "" Block Seq ""
[ jsStackDecl ] [ jsStackDecl ]
[ loop comp' body [ loop comp' body'
, jsStackRestore , jsStackRestore
] ]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment