X-Git-Url: http://git.joshuawise.com/snipe.git/blobdiff_plain/12aa4087bee3e70f170d7457794921de4e385227..0a24e44d4e9f82f8d3d83de8e58c83c8cf2868b6:/codegen/codegen.sml diff --git a/codegen/codegen.sml b/codegen/codegen.sml index 0297b9f..9b99ef7 100644 --- a/codegen/codegen.sml +++ b/codegen/codegen.sml @@ -1,10 +1,7 @@ -(* L1 Compiler - * Assembly Code Generator for FAKE assembly - * Author: Alex Vaynberg - * Based on code by: Kaustuv Chaudhuri - * Modified: Frank Pfenning - * - * Implements a "convenient munch" algorithm +(* L2 Compiler + * Assembly code generator for fake x86 assembly + * Author: Joshua Wise + * Author: Chris Lu *) signature CODEGEN = @@ -26,22 +23,146 @@ struct | 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)) = @@ -51,6 +172,15 @@ struct 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