]> Joshua Wise's Git repositories - snipe.git/blob - codegen/blarg.sml
Fix some stupid bugs in code generation.
[snipe.git] / codegen / blarg.sml
1 (* L3 compiler
2  * blargCPU instruction/operand internal representation and manipulation
3  * Author: Joshua Wise <jwise@andrew.cmu.edu>
4  * Author: Chris Lu <czl@andrew.cmu.edu>
5  *)
6
7 signature BLARG =
8 sig
9   (* register type *)
10   datatype reg =
11     R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7 | R8 | R9 | R10 | R11 | R12 | FR | SP | PC
12   (* operands to instructions *)
13   datatype oper = REG of reg |
14                      TEMP of Temp.temp |
15                      STACKARG of int
16   datatype pred = NV | NE | EQ | LT | GT | LE | GE | AL
17   (* instructions *)
18   datatype opc =
19     MOVLIT of oper * word |
20     MOVSYM of oper * Symbol.symbol |
21     MOVLBL of oper * Label.label |
22     LDR of oper * oper |
23     STO of oper * oper |
24     MOV of oper * oper |
25     MOVS of oper * oper |
26     ADD of oper * oper |
27     ADDS of oper * oper |
28     SUB of oper * oper |
29     SUBS of oper * oper |
30     AND of oper * oper |
31     ANDS of oper * oper |
32     NOT of oper * oper |
33     NOTS of oper * oper |
34     PUSH of oper * oper |
35     POP of oper * oper |
36     CALL of oper * oper * int |
37     SHR of oper * oper |
38     SHL of oper * oper
39
40   datatype insn =
41     DIRECTIVE of string |
42     COMMENT of string |
43     LABEL of Label.label |
44     INSN of pred * opc |
45     LIVEIGN of insn
46   
47   structure OperSet : ORD_SET
48     where type Key.ord_key = oper;
49   structure LiveMap : ORD_MAP
50     where type Key.ord_key = int;
51   
52   val regcmp : reg * reg -> order
53   val cmpoper : oper * oper -> order
54   val opereq : oper * oper -> bool
55   val regname : reg -> string
56   val regtonum : reg -> int
57   val numtoreg : int -> reg
58   val predname : pred -> string
59   val pp_oper : oper -> string
60   val print : insn -> string
61 end
62
63 structure Blarg :> BLARG =
64 struct
65
66 (* register type *)
67   datatype reg =
68     R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7 | R8 | R9 | R10 | R11 | R12 | FR | SP | PC
69   (* operands to instructions *)
70   datatype oper = REG of reg |
71                   TEMP of Temp.temp |
72                   STACKARG of int
73   datatype pred = NV | NE | EQ | LT | GT | LE | GE | AL
74   (* instructions *)
75   datatype opc =
76     MOVLIT of oper * word |
77     MOVSYM of oper * Symbol.symbol |
78     MOVLBL of oper * Label.label |
79     LDR of oper * oper |
80     STO of oper * oper |
81     MOV of oper * oper |
82     MOVS of oper * oper |
83     ADD of oper * oper |
84     ADDS of oper * oper |
85     SUB of oper * oper |
86     SUBS of oper * oper |
87     AND of oper * oper |
88     ANDS of oper * oper |
89     NOT of oper * oper |
90     NOTS of oper * oper |
91     PUSH of oper * oper |
92     POP of oper * oper |
93     CALL of oper * oper * int |
94     SHR of oper * oper |
95     SHL of oper * oper
96
97   datatype insn =
98     DIRECTIVE of string |
99     COMMENT of string |
100     LABEL of Label.label |
101     INSN of pred * opc |
102     LIVEIGN of insn
103     
104   type func = Ast.ident * insn list
105
106   (* gives name of reg *)
107   val regnames =
108     [ (R0, "r0"),
109       (R1, "r1"),
110       (R2, "r2"),
111       (R3, "r3"),
112       (R4, "r4"),
113       (R5, "r5"),
114       (R6, "r6"),
115       (R7, "r7"),
116       (R8, "r8"),
117       (R9, "r9"),
118       (R10, "r10"),
119       (R11, "r11"),
120       (R12, "r12"),
121       (FR, "fr"),
122       (SP, "sp"),
123       (PC, "pc") ];
124
125   fun regname reg =
126     let
127       val (r, n) = valOf (List.find (fn (r, _) => r = reg) regnames)
128     in
129       n
130     end
131
132   fun predname NV = "nv"
133     | predname NE = "ne"
134     | predname EQ = "eq"
135     | predname LT = "lt"
136     | predname GT = "gt"
137     | predname GE = "ge"
138     | predname LE = "le"
139     | predname AL = ""
140
141   (* gives number (color) associated with reg *)
142   fun regtonum R0 = 0
143     | regtonum R1 = 1
144     | regtonum R2 = 2
145     | regtonum R3 = 3
146     | regtonum R4 = 4
147     | regtonum R5 = 5
148     | regtonum R6 = 6
149     | regtonum R7 = 7
150     | regtonum R8 = 8
151     | regtonum R9 = 9
152     | regtonum R10 = 10
153     | regtonum R11 = 11
154     | regtonum R12 = 12
155     | regtonum SP = 4
156     | regtonum _ = raise ErrorMsg.InternalError ("regtonum: Invalid register")
157
158   (* gives reg associated with number (color) *)
159   fun numtoreg 0 = R0
160     | numtoreg 1 = R1
161     | numtoreg 2 = R2
162     | numtoreg 3 = R3
163     | numtoreg 4 = R4
164     | numtoreg 5 = R5
165     | numtoreg 6 = R6
166     | numtoreg 7 = R7
167     | numtoreg 8 = R8
168     | numtoreg 9 = R9
169     | numtoreg 10 = R10
170     | numtoreg 11 = R11
171     | numtoreg 12 = R12
172     | numtoreg n = raise ErrorMsg.InternalError ("numtoreg: Invalid register "^(Int.toString n))
173
174   (* register compare *)
175   fun regcmp (r1, r2) = Int.compare (regtonum r1, regtonum r2)
176
177   (* operand compare; arbitrary order imposed to make
178    * various things easier (e.g. liveness, for sorting)
179    *)
180   fun cmpoper (REG reg1, REG reg2) = regcmp (reg1, reg2)
181     | cmpoper (TEMP temp1, TEMP temp2) = Temp.compare (temp1,temp2)
182     | cmpoper (REG _, _) = LESS
183     | cmpoper (_, _) = GREATER
184
185   fun opereq (REG a, REG b) = a = b
186     | opereq (TEMP a, TEMP b) = Temp.eq (a, b)
187     | opereq (_, _) = false
188
189   structure OperSet = ListSetFn (
190     struct
191       type ord_key = oper
192       val compare = cmpoper
193     end)
194   
195   structure LiveMap = SplayMapFn(struct
196                                    type ord_key = int
197                                    val compare = Int.compare
198                                  end)
199   
200   fun pp_oper (REG r) = (regname r)
201     | pp_oper (TEMP t) = (Temp.name t)
202     | pp_oper (STACKARG i) = "arg#"^Int.toString i
203   
204   fun pp_insn pr (MOVLIT (d, w)) = "\tmov"^pr^" "^(pp_oper d)^", #0x"^(Word.toString w)^"\n"
205     | pp_insn pr (MOVSYM (d, s)) = "\tmov"^pr^" "^(pp_oper d)^", #"^(Symbol.name s)^"\n"
206     | pp_insn pr (MOVLBL (d, l)) = "\tmov"^pr^" "^(pp_oper d)^", #"^(Label.name l)^"\n"
207     | pp_insn pr (LDR (d, s)) = "\tldr"^pr^" "^(pp_oper d)^", ["^(pp_oper s)^"]\n"
208     | pp_insn pr (STO (d, s)) = "\tsto"^pr^" ["^(pp_oper d)^"], "^(pp_oper s)^"\n"
209     | pp_insn pr (MOV (d, s)) = "\tmov"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
210     | pp_insn pr (MOVS (d, s)) = "\tmovs"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
211     | pp_insn pr (ADD (d, s)) = "\tadd"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
212     | pp_insn pr (ADDS (d, s)) = "\tadds"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
213     | pp_insn pr (SUB (d, s)) = "\tsub"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
214     | pp_insn pr (SUBS (d, s)) = "\tsubs"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
215     | pp_insn pr (AND (d, s)) = "\tand"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
216     | pp_insn pr (ANDS (d, s)) = "\tands"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
217     | pp_insn pr (NOT (d, s)) = "\tnot"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
218     | pp_insn pr (NOTS (d, s)) = "\tnots"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
219     | pp_insn pr (PUSH (d, s)) = "\tpush"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
220     | pp_insn pr (POP (d, s)) = "\tpop"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
221     | pp_insn pr (CALL (d, s, n)) = "\tcall"^pr^" "^(pp_oper d)^", "^(pp_oper s)^" @ ("^(Int.toString n)^" args)\n"
222     | pp_insn pr (SHR (d, s)) = "\tshr"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
223     | pp_insn pr (SHL (d, s)) = "\tshl"^pr^" "^(pp_oper d)^", "^(pp_oper s)^"\n"
224     
225   (* pretty prints the asm *)
226   fun print (DIRECTIVE(str)) = str ^ "\n"
227     | print (COMMENT(str)) = "@ " ^ str ^ "\n"
228     | print (LABEL(l)) = Label.name l ^ ":\n"
229     | print (INSN (pred, insn)) = pp_insn (predname pred) insn
230     | print (LIVEIGN i) = print i
231 end
This page took 0.036175 seconds and 4 git commands to generate.