|
1 | | -module Kroha.Backends.Nasm where |
| 1 | +module Kroha.Backends.Nasm (nasm) where |
2 | 2 |
|
3 | 3 | import Data.Tree |
| 4 | +import Data.Graph (buildG) |
4 | 5 | import Data.List (groupBy, intercalate) |
5 | 6 | import Control.Monad.Fix (fix) |
6 | 7 | import Control.Monad (join) |
7 | 8 | import Data.List.Extra (groupSort) |
| 9 | +import Data.Bifunctor (first) |
8 | 10 |
|
9 | 11 | import Kroha.Ast |
10 | | -import Kroha.Instructions hiding (target) |
| 12 | +import Kroha.Backends.Common |
| 13 | +import Kroha.Types |
| 14 | +import Kroha.Instructions (Instruction(..), LabelTarget(..), Target(..), Section) |
| 15 | +import Kroha.Errors |
11 | 16 |
|
12 | 17 | bytes :: Int -> Int |
13 | 18 | bytes x = ceiling ((toEnum x) / 8) |
@@ -36,32 +41,37 @@ nasm16I (CallI l args) = (fmap (((++) "push ") . target) . reverse |
36 | 41 | nasm16I (Jump l Nothing) = ["jmp " ++ label l] |
37 | 42 | nasm16I (Jump lbl (Just (l, c, r))) = ["cmp " ++ target l ++ ", " ++ target r, jump c ++ " " ++ label lbl] |
38 | 43 |
|
39 | | -nasmBodyWrap body = body |
40 | | - |
41 | | -makeFix :: Tree [Instruction] -> [String] |
42 | | -makeFix (Node i c) = join . fmap asmFix $ i |
43 | | - where asmFix (Body _ i) = fmap ((++) indent) . bodyWrap $ makeFix (c !! i) |
44 | | - asmFix i = asm i |
45 | | - (asm, indent, bodyWrap) = (nasm16I, " ", id) |
46 | | - |
47 | | -nasmSection :: Section -> [[String]] -> String |
48 | | -nasmSection section declarations = header <> body <> "\n\n" |
| 44 | +nasmSection :: Section -> String -> String |
| 45 | +nasmSection section body = header <> body <> "\n\n" |
49 | 46 | where header = "section ." ++ section ++ "\n" |
50 | | - body = intercalate "\n" . fmap (intercalate "\n") $ declarations |
51 | 47 |
|
52 | 48 | nasmType :: TypeName -> String |
53 | 49 | nasmType (TypeName "int8" ) = "db" |
54 | 50 | nasmType (TypeName "int16") = "dw" |
55 | 51 |
|
56 | | -nasmDeclaration :: Tree [Instruction] -> Declaration -> [String] |
57 | | -nasmDeclaration t (Frame l _) = [l ++ ":"] ++ makeFix t ++ ["leave", "ret"] |
58 | | -nasmDeclaration _ (GlobalVariable n t (IntegerLiteral l)) = [n ++ ": " ++ nasmType t ++ " " ++ show l] |
59 | | -nasmDeclaration _ (ConstantVariable n t (IntegerLiteral l)) = [n ++ ": " ++ nasmType t ++ " " ++ show l] |
60 | | -nasmDeclaration _ (ManualFrame l c) = [l ++ ":", c] |
61 | | -nasmDeclaration _ (ManualVariable v _ c) = [v ++ ": " ++ c] |
| 52 | +nasmDeclaration :: Declaration -> [String] -> String |
| 53 | +nasmDeclaration (Frame l _) body = l ++ ":\n" ++ intercalate "\n" body ++ "\nleave\nret\n" |
| 54 | +nasmDeclaration (ManualVariable v _ _) [body] = v ++ ": " ++ body ++ "\n" |
| 55 | +nasmDeclaration (ManualFrame l _) body = l ++ ":\n" ++ intercalate "\n" (fmap ((++) " ") body) |
| 56 | +nasmDeclaration (ManualVariable v _ _) body = v ++ ":\n" ++ intercalate "\n" (fmap ((++) " ") body) |
| 57 | +nasmDeclaration (GlobalVariable n t (IntegerLiteral l)) _ = n ++ ": " ++ nasmType t ++ " " ++ show l |
| 58 | +nasmDeclaration (ConstantVariable n t (IntegerLiteral l)) _ = n ++ ": " ++ nasmType t ++ " " ++ show l |
62 | 59 |
|
| 60 | +litType :: Literal -> Result TypeId |
| 61 | +litType l@(IntegerLiteral x) | x >= 0 && x < 65536 = Right 2 |
| 62 | + | otherwise = Left (BackendError (show l ++ " is not in [0; 65536)")) |
63 | 63 |
|
64 | | -runNasm :: [(Section, Declaration, Tree [Instruction])] -> String |
65 | | -runNasm = join . map mapper |
66 | | - where mapper (s, d, t) = nasmSection s [nasmDeclaration t d] |
| 64 | +nasmTypes = TypeConfig |
| 65 | + { types = (fmap . first) TypeName [("int8", 8), ("int16", 16), ("+literal+", 16)] |
| 66 | + , pointerType = 1 |
| 67 | + , registers = zip (join $ fmap (\x -> fmap ((:) x . pure) "lhx") "abcd") (cycle [0, 0, 1]) |
| 68 | + , typeCasts = buildG (0, 3) [(0, 2), (1, 2)] |
| 69 | + , literalType = litType } |
67 | 70 |
|
| 71 | +nasm = Backend |
| 72 | + { instruction = nasm16I |
| 73 | + , bodyWrap = id |
| 74 | + , indent = " " |
| 75 | + , section = nasmSection |
| 76 | + , declaration = nasmDeclaration |
| 77 | + , typeConfig = nasmTypes } |
0 commit comments