]>
Commit | Line | Data |
---|---|---|
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 | ||
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 |