2 * Assembly Code Generator for FAKE assembly
3 * Author: Alex Vaynberg <alv@andrew.cmu.edu>
4 * Based on code by: Kaustuv Chaudhuri <kaustuv+@cs.cmu.edu>
5 * Modified: Frank Pfenning <fp@cs.cmu.edu>
7 * Implements a "convenient munch" algorithm
12 val codegen : Tree.stm list -> x86.insn list
15 structure Codegen :> CODEGEN =
20 (* munch_exp : prex86oper -> T.exp -> prex86insn list *)
22 * generates instructions to achieve d <- e
23 * d must be TEMP(t) or REG(r)
25 fun munch_exp d (T.CONST(n)) = [X.MOVL(d, X.CONST n)]
26 | munch_exp d (T.TEMP(t)) = [X.MOVL(d, X.TEMP t)]
27 | munch_exp d (T.BINOP(T.ADD, e1, T.CONST n)) = (munch_exp d e1) @ [X.ADDL(d, X.CONST n)]
28 | munch_exp d (T.BINOP(T.ADD, T.CONST n, e1)) = (munch_exp d e1) @ [X.ADDL(d, X.CONST n)]
29 | munch_exp d (T.BINOP(T.ADD, e1, e2)) = let val t1 = Temp.new () in (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.ADDL(d, X.TEMP t1)] end
30 | munch_exp d (T.BINOP(T.SUB, T.CONST 0w0, e1)) = (munch_exp d e1) @ [X.NEG d]
31 | munch_exp d (T.BINOP(T.SUB, e1, T.CONST(n))) = (munch_exp d e1) @ [X.SUBL(d, X.CONST n)]
32 | munch_exp d (T.BINOP(T.SUB, e1, e2)) = let val t1 = Temp.new () in (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.SUBL(d, X.TEMP t1)] end
33 | munch_exp d (T.BINOP(T.MUL, T.TEMP t, T.CONST n)) = [X.IMUL3(d, X.TEMP t, n)]
34 | munch_exp d (T.BINOP(T.MUL, T.CONST n, T.TEMP t)) = [X.IMUL3(d, X.TEMP t, n)]
35 | munch_exp d (T.BINOP(T.MUL, e1, T.CONST n)) = (munch_exp d e1) @ [X.IMUL(d, X.CONST n)]
36 | munch_exp d (T.BINOP(T.MUL, T.CONST n, e1)) = (munch_exp d e1) @ [X.IMUL(d, X.CONST n)]
37 | munch_exp d (T.BINOP(T.MUL, e1, e2)) = let val t1 = Temp.new () in (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.IMUL(d, X.TEMP t1)] end
38 | munch_exp d (T.BINOP(T.DIV, e1, e2)) = let val t1 = Temp.new () in (munch_exp (X.TEMP t1) e1) @ (munch_exp d e2) @ [X.MOVL (X.REG X.EAX, X.TEMP t1), X.CLTD, X.IDIVL d, X.MOVL (d, X.REG X.EAX)] end
39 | munch_exp d (T.BINOP(T.MOD, e1, e2)) = let val t1 = Temp.new () in (munch_exp (X.TEMP t1) e1) @ (munch_exp d e2) @ [X.MOVL (X.REG X.EAX, X.TEMP t1), X.CLTD, X.IDIVL d, X.MOVL (d, X.REG X.EDX)] end
41 (* munch_stm : T.stm -> AS.instr list *)
42 (* munch_stm stm generates code to execute stm *)
43 fun munch_stm (T.MOVE(T.TEMP(t1), e2)) =
44 munch_exp (X.TEMP t1) e2
45 | munch_stm (T.MOVE(_, _)) =
46 raise ErrorMsg.InternalError "Incorrect first operand for T.MOVE?"
47 | munch_stm (T.RETURN(e)) =
51 munch_exp (X.TEMP t) e
52 @ [X.MOVL(X.REG X.EAX, X.TEMP t), X.RET]
56 | codegen (stm::stms) = munch_stm stm @ codegen stms