blob: 46aaad503f64f5fe8eb26dca3d5279025c2f438d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
{-# LANGUAGE TupleSections #-}
module Lower(lowerIR) where
import AST (Name)
import Data.List
import qualified Data.Map.Strict as Map
import Intermediate
-- Not yet regalloc'd
data AsmProgram' = AsmProgram' [(Label, [AsmInstr'])]
data AsmInstr'
= Li Ref Int
| Mv Ref Ref
| Arith Arith Ref Ref Ref
| Not Ref Ref
| Call Ref Label
| Jcc CCond Ref Label
| JccR CCond Ref Ref
| Load Int Ref Ref
| Store Int Ref Ref
newtype Label = Label String
data Arith = Add | Sub | Mul | Div | Lt | Lte | And | Or | Xor | Sll | Slr | Sar
data CCond = CCZ | CCNZ
type GFDMap = Map.Map Name GlobFuncDef
type BId = Int
-- Calling convention:
-- Upon function entry, the stack should look as follows:
-- - Closure item 1
-- - Closure item 2
-- ...
-- - Closure item N
-- - Argument 1
-- - Arugment 2
-- ...
-- - Argument M
-- - Link register [pushed by callee]
lowerIR :: IRProgram -> AsmProgram'
lowerIR (IRProgram bbs gfds datatbl) =
let argcmap = floodArgCount gfds bbs
in AsmProgram' [(Label ("BB" ++ show bid), lowerBB bb gfds argcmap)
| bb@(BB bid _ _) <- bbs]
lowerBB :: BB -> GFDMap -> Map.Map BId Int -> [AsmInstr']
lowerBB (BB bid inss term) gfds argcmap = concatMap (\ins -> lowerIns ins gfds argcmap) inss
lowerIns :: Instruction -> GFDMap -> Map.Map BId Int -> [AsmInstr']
lowerIns (dest, instruction) gfds argcmap = case instruction of
IAssign src -> [Mv dest src]
IParam idx -> undefined
floodArgCount :: GFDMap -> [BB] -> Map.Map BId Int
floodArgCount gfds bbs = go Map.empty [(bid, n) | GlobFuncDef bid n _ <- Map.elems gfds]
where
bbMap :: Map.Map Int BB
bbMap = Map.fromList [(bid, bb) | bb@(BB bid _ _) <- bbs]
go :: Map.Map BId Int -> [(Int, Int)] -> Map.Map BId Int
go result frontier =
let result' = foldl' (\mp (bid, n) -> Map.insert bid n mp) result frontier
frontier' = concat [map (,n) (nexts bid \\ Map.keys result')
| (bid, n) <- frontier]
in go result' frontier'
nexts :: BId -> [BId]
nexts bid = case let BB _ _ term = bbMap Map.! bid in term of
IBr _ a b -> [a, b]
IJmp a -> [a]
IRet _ -> []
IExit -> []
IUnknown -> []
|