-(* L1 Compiler
- * Assembly Code Generator for FAKE assembly
- * Author: Alex Vaynberg <alv@andrew.cmu.edu>
- * Based on code by: Kaustuv Chaudhuri <kaustuv+@cs.cmu.edu>
- * Modified: Frank Pfenning <fp@cs.cmu.edu>
- *
- * Implements a "convenient munch" algorithm
+(* L2 Compiler
+ * Assembly code generator for fake x86 assembly
+ * Author: Joshua Wise <jwise@andrew.cmu.edu>
+ * Author: Chris Lu <czl@andrew.cmu.edu>
*)
signature CODEGEN =
| munch_exp d (T.TEMP(t)) = [X.MOVL(d, X.TEMP t)]
| munch_exp d (T.BINOP(T.ADD, e1, T.CONST n)) = (munch_exp d e1) @ [X.ADDL(d, X.CONST n)]
| munch_exp d (T.BINOP(T.ADD, T.CONST n, e1)) = (munch_exp d e1) @ [X.ADDL(d, X.CONST n)]
- | 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
+ | 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
| munch_exp d (T.BINOP(T.SUB, T.CONST 0w0, e1)) = (munch_exp d e1) @ [X.NEG d]
| munch_exp d (T.BINOP(T.SUB, e1, T.CONST(n))) = (munch_exp d e1) @ [X.SUBL(d, X.CONST n)]
- | 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
+ | 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
| munch_exp d (T.BINOP(T.MUL, T.TEMP t, T.CONST n)) = [X.IMUL3(d, X.TEMP t, n)]
| munch_exp d (T.BINOP(T.MUL, T.CONST n, T.TEMP t)) = [X.IMUL3(d, X.TEMP t, n)]
| munch_exp d (T.BINOP(T.MUL, e1, T.CONST n)) = (munch_exp d e1) @ [X.IMUL(d, X.CONST n)]
| munch_exp d (T.BINOP(T.MUL, T.CONST n, e1)) = (munch_exp d e1) @ [X.IMUL(d, X.CONST n)]
- | 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
- | 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
- | 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
+ | 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
+ | 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
+ | 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
+ | munch_exp d (T.BINOP(T.LSH, e1, T.CONST n)) = (munch_exp d e1) @ [X.SALL (d, X.CONST n)]
+ | munch_exp d (T.BINOP(T.LSH, e1, e2)) =
+ let
+ val t1 = Temp.new()
+ in
+ (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
+ [X.MOVL (X.REG X.ECX, X.TEMP t1), X.SALL (d, X.REG X.ECX)]
+ end
+ | munch_exp d (T.BINOP(T.RSH, e1, T.CONST n)) = (munch_exp d e1) @ [X.SARL (d, X.CONST n)]
+ | munch_exp d (T.BINOP(T.RSH, e1, e2)) =
+ let
+ val t1 = Temp.new()
+ in
+ (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
+ [X.MOVL (X.REG X.ECX, X.TEMP t1), X.SARL (d, X.REG X.ECX)]
+ end
+ | munch_exp d (T.BINOP(T.LOGOR, e1, e2)) =
+ let
+ val l1 = Label.new()
+ in
+ (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)]
+ end
+ | munch_exp d (T.BINOP(T.LOGAND, e1, e2)) =
+ let
+ val l1 = Label.new()
+ in
+ (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)]
+ end
+ | munch_exp d (T.BINOP(T.BITAND, e1, e2)) =
+ let
+ val t1 = Temp.new ()
+ in
+ (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.ANDL(d, X.TEMP t1)]
+ end
+ | munch_exp d (T.BINOP(T.BITOR, e1, e2)) =
+ let
+ val t1 = Temp.new ()
+ in
+ (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.ORL(d, X.TEMP t1)]
+ end
+ | munch_exp d (T.BINOP(T.BITXOR, e1, e2)) =
+ let
+ val t1 = Temp.new ()
+ in
+ (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @ [X.XORL(d, X.TEMP t1)]
+ end
+ | munch_exp d (T.BINOP(T.NEQ, e1, e2)) =
+ let
+ val t1 = Temp.new ()
+ in
+ (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
+ [X.CMPL(d, X.TEMP t1), X.SETNE(d), X.MOVZBL(d, d)]
+ end
+ | munch_exp d (T.BINOP(T.EQ, e1, e2)) =
+ let
+ val t1 = Temp.new ()
+ in
+ (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
+ [X.CMPL(d, X.TEMP t1), X.SETE(d), X.MOVZBL(d, d)]
+ end
+ | munch_exp d (T.BINOP(T.LE, e1, e2)) =
+ let
+ val t1 = Temp.new ()
+ in
+ (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
+ [X.CMPL(d, X.TEMP t1), X.SETLE(d), X.MOVZBL(d, d)]
+ end
+ | munch_exp d (T.BINOP(T.LT, e1, e2)) =
+ let
+ val t1 = Temp.new ()
+ in
+ (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
+ [X.CMPL(d, X.TEMP t1), X.SETL(d), X.MOVZBL(d, d)]
+ end
+ | munch_exp d (T.BINOP(T.GE, e1, e2)) =
+ let
+ val t1 = Temp.new ()
+ in
+ (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
+ [X.CMPL(d, X.TEMP t1), X.SETGE(d), X.MOVZBL(d, d)]
+ end
+ | munch_exp d (T.BINOP(T.GT, e1, e2)) =
+ let
+ val t1 = Temp.new ()
+ in
+ (munch_exp d e1) @ (munch_exp (X.TEMP t1) e2) @
+ [X.CMPL(d, X.TEMP t1), X.SETG(d), X.MOVZBL(d, d)]
+ end
+ | munch_exp d (T.UNOP(T.NEG, e1)) = (munch_exp d e1) @ [X.NEG d]
+ | munch_exp d (T.UNOP(T.BITNOT, e1)) = (munch_exp d e1) @ [X.NOTL d]
+ | munch_exp d (T.UNOP(T.BANG, e1)) = (munch_exp d e1) @
+ [X.TEST(d,d), X.SETE(d), X.MOVZBL(d, d)]
- (* munch_stm : T.stm -> AS.instr list *)
+ (* munch_stm : T.stm -> X.insn list *)
(* munch_stm stm generates code to execute stm *)
fun munch_stm (T.MOVE(T.TEMP(t1), e2)) =
- munch_exp (X.TEMP t1) e2
+ let
+ val t = Temp.new ()
+ in
+ munch_exp (X.TEMP t) e2
+ @ [X.MOVL(X.TEMP t1, X.TEMP t)]
+ end
| munch_stm (T.MOVE(_, _)) =
raise ErrorMsg.InternalError "Incorrect first operand for T.MOVE?"
| munch_stm (T.RETURN(e)) =
munch_exp (X.TEMP t) e
@ [X.MOVL(X.REG X.EAX, X.TEMP t), X.RET]
end
+ | munch_stm (T.LABEL(l)) = [X.LABEL l]
+ | munch_stm (T.JUMP(l)) = [X.JMP l]
+ | munch_stm (T.JUMPIFN(e, l)) =
+ let
+ val t = Temp.new ()
+ in
+ munch_exp (X.TEMP t) e
+ @ [X.TEST(X.TEMP t, X.TEMP t), X.JE l]
+ end
fun codegen nil = nil
| codegen (stm::stms) = munch_stm stm @ codegen stms