]> Joshua Wise's Git repositories - snipe.git/blob - codegen/codegen.sml
Initial import of l1c
[snipe.git] / codegen / codegen.sml
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
10 signature CODEGEN =
11 sig
12   val codegen : Tree.stm list -> x86.insn list
13 end
14
15 structure Codegen :> CODEGEN = 
16 struct
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
57 end
This page took 0.045922 seconds and 4 git commands to generate.