]> Joshua Wise's Git repositories - snipe.git/blame - codegen/codegen.sml
Initial import of l2c
[snipe.git] / codegen / codegen.sml
CommitLineData
0a24e44d
JW
1(* L2 Compiler
2 * Assembly code generator for fake x86 assembly
3 * Author: Joshua Wise <jwise@andrew.cmu.edu>
4 * Author: Chris Lu <czl@andrew.cmu.edu>
12aa4087
JW
5 *)
6
7signature CODEGEN =
8sig
9 val codegen : Tree.stm list -> x86.insn list
10end
11
12structure Codegen :> CODEGEN =
13struct
14 structure T = Tree
15 structure X = x86
16
17 (* munch_exp : prex86oper -> T.exp -> prex86insn list *)
18 (* munch_exp d e
19 * generates instructions to achieve d <- e
20 * d must be TEMP(t) or REG(r)
21 *)
22 fun munch_exp d (T.CONST(n)) = [X.MOVL(d, X.CONST n)]
23 | munch_exp d (T.TEMP(t)) = [X.MOVL(d, X.TEMP t)]
24 | munch_exp d (T.BINOP(T.ADD, e1, T.CONST n)) = (munch_exp d e1) @ [X.ADDL(d, X.CONST n)]
25 | munch_exp d (T.BINOP(T.ADD, T.CONST n, e1)) = (munch_exp d e1) @ [X.ADDL(d, X.CONST n)]
0a24e44d
JW
26 | munch_exp d (T.BINOP(T.ADD, e1, e2)) =
27 let
28 val t1 = Temp.new ()
29 in
30 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.ADDL(d, X.TEMP t1)]
31 end
12aa4087
JW
32 | munch_exp d (T.BINOP(T.SUB, T.CONST 0w0, e1)) = (munch_exp d e1) @ [X.NEG d]
33 | munch_exp d (T.BINOP(T.SUB, e1, T.CONST(n))) = (munch_exp d e1) @ [X.SUBL(d, X.CONST n)]
0a24e44d
JW
34 | munch_exp d (T.BINOP(T.SUB, e1, e2)) =
35 let val
36 t1 = Temp.new ()
37 in
38 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.SUBL(d, X.TEMP t1)]
39 end
12aa4087
JW
40 | munch_exp d (T.BINOP(T.MUL, T.TEMP t, T.CONST n)) = [X.IMUL3(d, X.TEMP t, n)]
41 | munch_exp d (T.BINOP(T.MUL, T.CONST n, T.TEMP t)) = [X.IMUL3(d, X.TEMP t, n)]
42 | munch_exp d (T.BINOP(T.MUL, e1, T.CONST n)) = (munch_exp d e1) @ [X.IMUL(d, X.CONST n)]
43 | munch_exp d (T.BINOP(T.MUL, T.CONST n, e1)) = (munch_exp d e1) @ [X.IMUL(d, X.CONST n)]
0a24e44d
JW
44 | munch_exp d (T.BINOP(T.MUL, e1, e2)) =
45 let
46 val t1 = Temp.new ()
47 in
48 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.IMUL(d, X.TEMP t1)]
49 end
50 | munch_exp d (T.BINOP(T.DIV, e1, e2)) =
51 let
52 val t1 = Temp.new ()
53 in
54 (munch_exp (X.TEMP t1) e1) @ (munch_exp d e2) @
55 [X.MOVL (X.REG X.EAX, X.TEMP t1), X.CLTD, X.IDIVL d, X.MOVL (d, X.REG X.EAX)]
56 end
57 | munch_exp d (T.BINOP(T.MOD, e1, e2)) =
58 let
59 val t1 = Temp.new ()
60 in
61 (munch_exp (X.TEMP t1) e1) @ (munch_exp d e2) @
62 [X.MOVL (X.REG X.EAX, X.TEMP t1), X.CLTD, X.IDIVL d, X.MOVL (d, X.REG X.EDX)]
63 end
64 | munch_exp d (T.BINOP(T.LSH, e1, T.CONST n)) = (munch_exp d e1) @ [X.SALL (d, X.CONST n)]
65 | munch_exp d (T.BINOP(T.LSH, e1, e2)) =
66 let
67 val t1 = Temp.new()
68 in
69 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
70 [X.MOVL (X.REG X.ECX, X.TEMP t1), X.SALL (d, X.REG X.ECX)]
71 end
72 | munch_exp d (T.BINOP(T.RSH, e1, T.CONST n)) = (munch_exp d e1) @ [X.SARL (d, X.CONST n)]
73 | munch_exp d (T.BINOP(T.RSH, e1, e2)) =
74 let
75 val t1 = Temp.new()
76 in
77 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
78 [X.MOVL (X.REG X.ECX, X.TEMP t1), X.SARL (d, X.REG X.ECX)]
79 end
80 | munch_exp d (T.BINOP(T.LOGOR, e1, e2)) =
81 let
82 val l1 = Label.new()
83 in
84 (munch_exp d e1) @ [X.CMPL (d, X.CONST(0w0)), X.JNE l1] @ (munch_exp d e2) @ [X.CMPL (d, X.CONST(0w0)), X.LABEL l1, X.SETNE d, X.MOVZBL(d,d)]
85 end
86 | munch_exp d (T.BINOP(T.LOGAND, e1, e2)) =
87 let
88 val l1 = Label.new()
89 in
90 (munch_exp d e1) @ [X.CMPL (d, X.CONST(0w0)), X.JE l1] @ (munch_exp d e2) @ [X.CMPL (d, X.CONST(0w0)), X.LABEL l1, X.SETNE d, X.MOVZBL(d,d)]
91 end
92 | munch_exp d (T.BINOP(T.BITAND, e1, e2)) =
93 let
94 val t1 = Temp.new ()
95 in
96 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.ANDL(d, X.TEMP t1)]
97 end
98 | munch_exp d (T.BINOP(T.BITOR, e1, e2)) =
99 let
100 val t1 = Temp.new ()
101 in
102 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.ORL(d, X.TEMP t1)]
103 end
104 | munch_exp d (T.BINOP(T.BITXOR, e1, e2)) =
105 let
106 val t1 = Temp.new ()
107 in
108 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.XORL(d, X.TEMP t1)]
109 end
110 | munch_exp d (T.BINOP(T.NEQ, e1, e2)) =
111 let
112 val t1 = Temp.new ()
113 in
114 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
115 [X.CMPL(d, X.TEMP t1), X.SETNE(d), X.MOVZBL(d, d)]
116 end
117 | munch_exp d (T.BINOP(T.EQ, e1, e2)) =
118 let
119 val t1 = Temp.new ()
120 in
121 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
122 [X.CMPL(d, X.TEMP t1), X.SETE(d), X.MOVZBL(d, d)]
123 end
124 | munch_exp d (T.BINOP(T.LE, e1, e2)) =
125 let
126 val t1 = Temp.new ()
127 in
128 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
129 [X.CMPL(d, X.TEMP t1), X.SETLE(d), X.MOVZBL(d, d)]
130 end
131 | munch_exp d (T.BINOP(T.LT, e1, e2)) =
132 let
133 val t1 = Temp.new ()
134 in
135 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
136 [X.CMPL(d, X.TEMP t1), X.SETL(d), X.MOVZBL(d, d)]
137 end
138 | munch_exp d (T.BINOP(T.GE, e1, e2)) =
139 let
140 val t1 = Temp.new ()
141 in
142 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
143 [X.CMPL(d, X.TEMP t1), X.SETGE(d), X.MOVZBL(d, d)]
144 end
145 | munch_exp d (T.BINOP(T.GT, e1, e2)) =
146 let
147 val t1 = Temp.new ()
148 in
149 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
150 [X.CMPL(d, X.TEMP t1), X.SETG(d), X.MOVZBL(d, d)]
151 end
152 | munch_exp d (T.UNOP(T.NEG, e1)) = (munch_exp d e1) @ [X.NEG d]
153 | munch_exp d (T.UNOP(T.BITNOT, e1)) = (munch_exp d e1) @ [X.NOTL d]
154 | munch_exp d (T.UNOP(T.BANG, e1)) = (munch_exp d e1) @
155 [X.TEST(d,d), X.SETE(d), X.MOVZBL(d, d)]
12aa4087 156
0a24e44d 157 (* munch_stm : T.stm -> X.insn list *)
12aa4087
JW
158 (* munch_stm stm generates code to execute stm *)
159 fun munch_stm (T.MOVE(T.TEMP(t1), e2)) =
0a24e44d
JW
160 let
161 val t = Temp.new ()
162 in
163 munch_exp (X.TEMP t) e2
164 @ [X.MOVL(X.TEMP t1, X.TEMP t)]
165 end
12aa4087
JW
166 | munch_stm (T.MOVE(_, _)) =
167 raise ErrorMsg.InternalError "Incorrect first operand for T.MOVE?"
168 | munch_stm (T.RETURN(e)) =
169 let
170 val t = Temp.new ()
171 in
172 munch_exp (X.TEMP t) e
173 @ [X.MOVL(X.REG X.EAX, X.TEMP t), X.RET]
174 end
0a24e44d
JW
175 | munch_stm (T.LABEL(l)) = [X.LABEL l]
176 | munch_stm (T.JUMP(l)) = [X.JMP l]
177 | munch_stm (T.JUMPIFN(e, l)) =
178 let
179 val t = Temp.new ()
180 in
181 munch_exp (X.TEMP t) e
182 @ [X.TEST(X.TEMP t, X.TEMP t), X.JE l]
183 end
12aa4087
JW
184
185 fun codegen nil = nil
186 | codegen (stm::stms) = munch_stm stm @ codegen stms
187end
This page took 0.04005 seconds and 4 git commands to generate.