-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmipsframe.sml
108 lines (83 loc) · 3.01 KB
/
mipsframe.sml
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
structure MIPSFrame : FRAME =
struct
structure A = Assem
structure T = Tree
val unimplemented = ErrorMsg.unimplemented
(* frames *)
datatype access = InFrame of int
| InReg of Temp.temp
type frame = {name: Temp.label,
formals: access list,
nlocals: int ref}
fun newFrame {name, formals} = let
fun access(escape, (acc, offset)) =
if escape then
(InFrame offset :: acc, offset + 4)
else
(InReg(Temp.newtemp()) :: acc, offset)
val (formals, _) = foldl access ([], 0) formals
in {name = name,
formals = rev formals,
nlocals = ref 0}
end
fun name ({name,...}: frame) = name
fun formals ({formals,...}: frame) = formals
fun allocLocal ({nlocals,...}: frame) true =
(nlocals := !nlocals + 1;
InFrame(!nlocals * ~4))
| allocLocal frame false = InReg(Temp.newtemp())
(* registers *)
type register = string
local
val registers =
["$zero", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3",
"$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
"$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7",
"$t8", "$t9", "$k0", "$k1", "$gp", "$sp", "$fp", "$ra"]
fun mkReg (name, (map, regs)) = let
val r = Temp.newtemp()
in (Temp.Table.enter(map, r, name), r::regs)
end
val (tempMap,
[zero, at, v0, v1, a0, a1, a2, a3,
t0, t1, t2, t3, t4, t5, t6, t7,
s0, s1, s2, s3, s4, s5, s6, s7,
t8, t9, k0, k1, gp, sp, fp, ra]) =
foldr mkReg (Temp.Table.empty, []) registers
in
val registers = registers
val tempMap = tempMap
val SP = sp
val FP = fp
val RV = v0
val ZERO = zero
val specialregs = [zero, v0, gp, sp, fp, ra]
val argregs = [a0, a1, a2, a3]
val calleesaves = [t0, t1, t2, t3, t4, t5, t6, t7, t8, t9]
val callersaves = [s0, s1, s2, s3, s4, s5, s6, s7]
val calldefs = RV::ra::callersaves
end
val wordSize = 4
(* translation to IR trees *)
datatype frag = PROC of {frame: frame, body: T.stm}
| STRING of Temp.label * string
fun expOfAccess (InFrame off) exp = T.MEM(T.BINOP(T.PLUS, exp, T.CONST off))
| expOfAccess (InReg t) _ = T.TEMP t
fun externalCall (name, args) = T.CALL(T.NAME(Temp.namedlabel name), args)
fun argPos i =
if i < 4 then T.TEMP(List.nth(argregs, i))
else unimplemented()
fun procEntryExit1 (frame, body) = body
fun procEntryExit2 (frame, body) =
body @ [A.OPER{assem="",
src=specialregs @ calleesaves,
dst=[], jump=NONE}]
fun procEntryExit3 ({name,...}: frame, body) =
{prolog = "PROCEDURE " ^ Symbol.name name ^ "\n",
body = body,
epilog = "END " ^ Symbol.name name ^ "\n"}
fun string (lab, s) =
concat [Symbol.name lab, ":\n",
".word ", Int.toString(size s), "\n",
".ascii \"", String.toString s, "\"\n"]
end