]>
Commit | Line | Data |
---|---|---|
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 | ||
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)] | |
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 | |
187 | end |