]> Joshua Wise's Git repositories - snipe.git/blob - codegen/codegen.sml
Initial import of l2c
[snipe.git] / codegen / codegen.sml
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>
5  *)
6
7 signature CODEGEN =
8 sig
9   val codegen : Tree.stm list -> x86.insn list
10 end
11
12 structure Codegen :> CODEGEN = 
13 struct
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)]
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
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)]
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
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)]
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)]
156
157   (* munch_stm : T.stm -> X.insn list *)
158   (* munch_stm stm generates code to execute stm *)
159   fun munch_stm (T.MOVE(T.TEMP(t1), e2)) =
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
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
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
184
185   fun codegen nil = nil
186     | codegen (stm::stms) = munch_stm stm @ codegen stms
187 end
This page took 0.036379 seconds and 4 git commands to generate.