From 06533ad580c1afee4ee9b71fa956d2b8586c118a Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Fri, 14 Jul 2017 22:59:19 +0200 Subject: Fixes and improvements --- compiler.hs | 55 ++++++++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 29 deletions(-) (limited to 'compiler.hs') diff --git a/compiler.hs b/compiler.hs index 8a98a2d..eab7058 100644 --- a/compiler.hs +++ b/compiler.hs @@ -36,51 +36,48 @@ compile (Program inss) = runLineWriter $ do mapM_ compileIns inss emit0 epilogue -cursor :: String -cursor = "rbx" +cursorReg :: String +cursorReg = "rbx" + +cursorOffset :: Offset -> String +cursorOffset 0 = cursorReg +cursorOffset off = cursorReg ++ " + " ++ show off compileIns :: Instruction -> LineWriter () -compileIns (IAdd v off) = emit $ "add byte [" ++ cursor ++ " + " ++ show off ++ "], " ++ show v -compileIns (ISet v off) = emit $ "mov byte [" ++ cursor ++ " + " ++ show off ++ "], " ++ show v -compileIns (IMove from []) = do - emit $ "mov byte [" ++ cursor ++ " + " ++ show from ++ "], 0" -compileIns (IMove from [(o,m)]) = do - emit $ "mov al, [" ++ cursor ++ " + " ++ show from ++ "]" - if m == 1 then return () - else do - emit $ "mov cl, " ++ show m - emit "mul byte cl" - emit $ "add [" ++ cursor ++ " + " ++ show o ++ "], al" - emit $ "mov byte [" ++ cursor ++ " + " ++ show from ++ "], 0" -compileIns (IMove from tos) = do - emit $ "mov dl, [" ++ cursor ++ " + " ++ show from ++ "]" - emit $ "mov byte [" ++ cursor ++ " + " ++ show from ++ "], 0" - forM_ tos $ \(o,m) -> do - emit "mov al, dl" - if m == 1 then return () - else do - emit $ "mov cl, " ++ show m - emit "mul byte cl" - emit $ "add [" ++ cursor ++ " + " ++ show o ++ "], al" -compileIns (ISlide off) = emit $ "add " ++ cursor ++ ", " ++ show off +compileIns (IAdd v off) = emit $ "add byte [" ++ cursorOffset off ++ "], " ++ show v +compileIns (ISet v off) = emit $ "mov byte [" ++ cursorOffset off ++ "], " ++ show v +compileIns (ICopy _ _ 0) = return () +compileIns (ICopy from to m) = do + emit $ "mov al, [" ++ cursorOffset from ++ "]" + case m of + 1 -> return () + _ | Just p <- isTwoPower m -> emit $ "shl al, " ++ show p + | otherwise -> do + emit $ "mov cl, " ++ show m + emit "mul byte cl" + emit $ "add [" ++ cursorOffset to ++ "], al" +compileIns (ISlide off) = emit $ "add " ++ cursorReg ++ ", " ++ show off compileIns (ILoop inss off) = do loopid <- genId - emit $ "cmp byte [" ++ cursor ++ " + " ++ show off ++ "], 0" + emit $ "cmp byte [" ++ cursorOffset off ++ "], 0" emit $ "jz .Laf_" ++ show loopid emit0 $ ".Lbd_" ++ show loopid ++ ":" mapM_ compileIns inss - emit $ "cmp byte [" ++ cursor ++ " + " ++ show off ++ "], 0" + emit $ "cmp byte [" ++ cursorOffset off ++ "], 0" emit $ "jnz .Lbd_" ++ show loopid emit0 $ ".Laf_" ++ show loopid ++ ":" compileIns (IInput off) = do emit "call _getchar" - emit $ "mov [" ++ cursor ++ " + " ++ show off ++ "], al" + emit $ "mov [" ++ cursorOffset off ++ "], al" compileIns (IOutput off) = do emit "xor edi, edi" - emit $ "mov dil, [" ++ cursor ++ " + " ++ show off ++ "]" + emit $ "mov dil, [" ++ cursorOffset off ++ "]" emit "call _putchar" compileIns IStart = return () +isTwoPower :: Byte -> Maybe Int +isTwoPower v = findIndex (==v) (take 8 $ iterate (* 2) 1) + prologue :: String prologue = -- cgit v1.2.3-54-g00ecf