2 * Assembly code generator for fake x86 assembly
3 * Author: Joshua Wise <jwise@andrew.cmu.edu>
4 * Author: Chris Lu <czl@andrew.cmu.edu>
9 val codegen : Tree.stm list -> x86.insn list
12 structure Codegen :> CODEGEN =
17 (* munch_exp : prex86oper -> T.exp -> prex86insn list *)
19 * generates instructions to achieve d <- e
20 * d must be TEMP(t) or REG(r)
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)) =
30 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.ADDL(d, X.TEMP t1)]
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)) =
38 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.SUBL(d, X.TEMP t1)]
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)) =
48 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.IMUL(d, X.TEMP t1)]
50 | munch_exp d (T.BINOP(T.DIV, e1, e2)) =
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)]
57 | munch_exp d (T.BINOP(T.MOD, e1, e2)) =
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)]
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)) =
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)]
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)) =
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)]
80 | munch_exp d (T.BINOP(T.LOGOR, e1, e2)) =
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)]
86 | munch_exp d (T.BINOP(T.LOGAND, e1, e2)) =
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)]
92 | munch_exp d (T.BINOP(T.BITAND, e1, e2)) =
96 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.ANDL(d, X.TEMP t1)]
98 | munch_exp d (T.BINOP(T.BITOR, e1, e2)) =
102 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.ORL(d, X.TEMP t1)]
104 | munch_exp d (T.BINOP(T.BITXOR, e1, e2)) =
108 (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.XORL(d, X.TEMP t1)]
110 | munch_exp d (T.BINOP(T.NEQ, e1, e2)) =
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)]
117 | munch_exp d (T.BINOP(T.EQ, e1, e2)) =
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)]
124 | munch_exp d (T.BINOP(T.LE, e1, e2)) =
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)]
131 | munch_exp d (T.BINOP(T.LT, e1, e2)) =
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)]
138 | munch_exp d (T.BINOP(T.GE, e1, e2)) =
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)]
145 | munch_exp d (T.BINOP(T.GT, e1, e2)) =
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)]
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)]
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)) =
163 munch_exp (X.TEMP t) e2
164 @ [X.MOVL(X.TEMP t1, X.TEMP t)]
166 | munch_stm (T.MOVE(_, _)) =
167 raise ErrorMsg.InternalError "Incorrect first operand for T.MOVE?"
168 | munch_stm (T.RETURN(e)) =
172 munch_exp (X.TEMP t) e
173 @ [X.MOVL(X.REG X.EAX, X.TEMP t), X.RET]
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)) =
181 munch_exp (X.TEMP t) e
182 @ [X.TEST(X.TEMP t, X.TEMP t), X.JE l]
185 fun codegen nil = nil
186 | codegen (stm::stms) = munch_stm stm @ codegen stms