]> Joshua Wise's Git repositories - snipe.git/blame - codegen/codegen.sml
Initial import of l1c
[snipe.git] / codegen / codegen.sml
CommitLineData
12aa4087
JW
1(* L1 Compiler
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>
6 *
7 * Implements a "convenient munch" algorithm
8 *)
9
10signature CODEGEN =
11sig
12 val codegen : Tree.stm list -> x86.insn list
13end
14
15structure Codegen :> CODEGEN =
16struct
17 structure T = Tree
18 structure X = x86
19
20 (* munch_exp : prex86oper -> T.exp -> prex86insn list *)
21 (* munch_exp d e
22 * generates instructions to achieve d <- e
23 * d must be TEMP(t) or REG(r)
24 *)
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
40
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)) =
48 let
49 val t = Temp.new ()
50 in
51 munch_exp (X.TEMP t) e
52 @ [X.MOVL(X.REG X.EAX, X.TEMP t), X.RET]
53 end
54
55 fun codegen nil = nil
56 | codegen (stm::stms) = munch_stm stm @ codegen stms
57end
This page took 0.027341 seconds and 4 git commands to generate.