]> Joshua Wise's Git repositories - snipe.git/blame - codegen/x86.sml
Initial import of l2c
[snipe.git] / codegen / x86.sml
CommitLineData
0a24e44d
JW
1(* L2 compiler
2 * X86 instruction/operand internal representation and manipulation
3 * Author: Joshua Wise <jwise@andrew.cmu.edu>
4 * Author: Chris Lu <czl@andrew.cmu.edu>
5 *)
6
12aa4087
JW
7signature X86 =
8sig
0a24e44d 9 (* register type *)
12aa4087
JW
10 datatype reg =
11 EAX | EBX | ECX | EDX | ESI | EDI | EBP | RSP | R8D | R9D | R10D | R11D | R12D | R13D | R14D | R15D
0a24e44d 12 (* operands to instructions *)
12aa4087 13 datatype oper = REG of reg | TEMP of Temp.temp | CONST of Word32.word | REL of (reg * int)
0a24e44d
JW
14 (* instructions
15 * a better way to do SET would be SET of cc * oper,
16 * same with JMP
17 *)
12aa4087
JW
18 datatype insn =
19 DIRECTIVE of string |
20 COMMENT of string |
0a24e44d 21 LABEL of Label.label |
12aa4087
JW
22 MOVL of oper * oper |
23 SUBL of oper * oper |
24 IMUL of oper * oper |
25 IMUL3 of oper * oper * Word32.word |
26 ADDL of oper * oper |
12aa4087
JW
27 IDIVL of oper |
28 NEG of oper |
0a24e44d
JW
29 NOTL of oper |
30 SALL of oper * oper |
31 SARL of oper * oper |
32 ANDL of oper * oper |
33 ORL of oper * oper |
34 XORL of oper * oper |
35 CMPL of oper * oper |
36 TEST of oper * oper |
37 SETNE of oper |
38 SETE of oper |
39 SETLE of oper |
40 SETL of oper |
41 SETGE of oper |
42 SETG of oper |
43 JMP of Label.label |
44 JE of Label.label |
45 JNE of Label.label |
46 MOVZBL of oper * oper |
12aa4087
JW
47 CLTD |
48 RET
49
50 val cmpoper : oper * oper -> order
51 val opereq : oper * oper -> bool
52 val regname : reg -> string
0a24e44d 53 val regnameb : reg -> string
12aa4087
JW
54 val regtonum : reg -> int
55 val numtoreg : int -> reg
56 val prettyprint_oper : oper -> string
0a24e44d 57 val prettyprint_operb : oper -> string
12aa4087
JW
58 val prettyprint : insn -> string
59end
60
61structure x86 :> X86 =
62struct
63 datatype reg =
64 EAX | EBX | ECX | EDX | ESI | EDI | EBP | RSP | R8D | R9D | R10D | R11D | R12D | R13D | R14D | R15D
65 datatype oper = REG of reg | TEMP of Temp.temp | CONST of Word32.word | REL of (reg * int)
66 datatype insn =
67 DIRECTIVE of string |
68 COMMENT of string |
0a24e44d 69 LABEL of Label.label |
12aa4087
JW
70 MOVL of oper * oper |
71 SUBL of oper * oper |
72 IMUL of oper * oper |
73 IMUL3 of oper * oper * Word32.word |
74 ADDL of oper * oper |
12aa4087
JW
75 IDIVL of oper |
76 NEG of oper |
0a24e44d
JW
77 NOTL of oper |
78 SALL of oper * oper |
79 SARL of oper * oper |
80 ANDL of oper * oper |
81 ORL of oper * oper |
82 XORL of oper * oper |
83 CMPL of oper * oper |
84 TEST of oper * oper |
85 SETNE of oper |
86 SETE of oper |
87 SETLE of oper |
88 SETL of oper |
89 SETGE of oper |
90 SETG of oper |
91 JMP of Label.label |
92 JE of Label.label |
93 JNE of Label.label |
94 MOVZBL of oper * oper |
12aa4087
JW
95 CLTD |
96 RET
0a24e44d
JW
97
98 (* gives name of reg *)
12aa4087
JW
99 fun regname EAX = "eax"
100 | regname EBX = "ebx"
101 | regname ECX = "ecx"
102 | regname EDX = "edx"
103 | regname ESI = "esi"
104 | regname EDI = "edi"
105 | regname EBP = "ebp"
106 | regname RSP = "rsp"
107 | regname R8D = "r8d"
108 | regname R9D = "r9d"
109 | regname R10D = "r10d"
110 | regname R11D = "r11d"
111 | regname R12D = "r12d"
112 | regname R13D = "r13d"
113 | regname R14D = "r14d"
114 | regname R15D = "r15d"
0a24e44d
JW
115
116 (* like regname, but for the byte name *)
117 fun regnameb EAX = "al"
118 | regnameb EBX = "bl"
119 | regnameb ECX = "cl"
120 | regnameb EDX = "dl"
121 | regnameb ESI = "sil"
122 | regnameb EDI = "dil"
123 | regnameb EBP = "bpl"
124 | regnameb RSP = "spl"
125 | regnameb R8D = "r8b"
126 | regnameb R9D = "r9b"
127 | regnameb R10D = "r10b"
128 | regnameb R11D = "r11b"
129 | regnameb R12D = "r12b"
130 | regnameb R13D = "r13b"
131 | regnameb R14D = "r14b"
132 | regnameb R15D = "r15b"
133
134 (* gives number (color) associated with reg *)
12aa4087
JW
135 fun regtonum EAX = 0
136 | regtonum EBX = 1
137 | regtonum ECX = 2
138 | regtonum EDX = 3
139 | regtonum ESI = 4
140 | regtonum EDI = 5
141 | regtonum R8D = 6
142 | regtonum R9D = 7
143 | regtonum R10D = 8
144 | regtonum R11D = 9
145 | regtonum R12D = 10
146 | regtonum R13D = 11
147 | regtonum R14D = 12
148 | regtonum R15D = 13
149 | regtonum EBP = 14 (* Dummy numbers -- not permitted for allocation, but there so that we can compare *)
150 | regtonum RSP = 15
0a24e44d
JW
151
152 (* gives reg associated with number (color) *)
12aa4087
JW
153 fun numtoreg 0 = EAX
154 | numtoreg 1 = EBX
155 | numtoreg 2 = ECX
156 | numtoreg 3 = EDX
157 | numtoreg 4 = ESI
158 | numtoreg 5 = EDI
159 | numtoreg 6 = R8D
160 | numtoreg 7 = R9D
161 | numtoreg 8 = R10D
162 | numtoreg 9 = R11D
163 | numtoreg 10 = R12D
164 | numtoreg 11 = R13D
165 | numtoreg 12 = R14D
166 | numtoreg 13 = R15D
167 | numtoreg n = raise ErrorMsg.InternalError ("numtoreg: Unknown register "^(Int.toString n))
0a24e44d
JW
168
169 (* register compare *)
12aa4087
JW
170 fun regcmp (r1, r2) = Int.compare (regtonum r1, regtonum r2)
171
0a24e44d
JW
172 (* operand compare; arbitrary order imposed to make
173 * various things easier (e.g. liveness, for sorting)
174 *)
12aa4087
JW
175 fun cmpoper (REG(reg1), REG(reg2)) = regcmp (reg1, reg2)
176 | cmpoper (TEMP(temp1), TEMP(temp2)) = Temp.compare (temp1,temp2)
177 | cmpoper (CONST(const1), CONST(const2)) = Word32.compare (const1, const2)
178 | cmpoper (REL (r1, i1), REL (r2, i2)) =
179 let
180 val regorder = regcmp (r1, r2)
181 val intorder = Int.compare (i1, i2)
182 in
183 if (regorder = EQUAL) then intorder
184 else regorder
185 end
186 | cmpoper (CONST _, _) = LESS
187 | cmpoper (REG _, _) = LESS
188 | cmpoper (REL _, _) = LESS
189 | cmpoper (_, _) = GREATER
0a24e44d 190
12aa4087 191 fun opereq (a, b) = cmpoper (a, b) = EQUAL
0a24e44d
JW
192
193 (* integer tostring, except with more - and less ~ *)
12aa4087
JW
194 fun moreDifferentToString (i) =
195 if (i >= 0) then Int.toString i
196 else "-" ^ (Int.toString (~i))
0a24e44d
JW
197
198 (* pretty prints an operand *)
12aa4087
JW
199 fun prettyprint_oper (REG r) = "%" ^ (regname r)
200 | prettyprint_oper (TEMP t) = Temp.name t
201 | prettyprint_oper (CONST c) = "$0x" ^ (Word32.toString c)
202 | prettyprint_oper (REL (r, i)) = (moreDifferentToString i) ^ "(%" ^ (regname r) ^ ")"
203
0a24e44d
JW
204 (* pretty prints an operand as a byte *)
205 fun prettyprint_operb (REG r) = "%" ^ (regnameb r)
206 | prettyprint_operb (TEMP t) = Temp.name t ^ "b"
207 | prettyprint_operb (CONST c) = "$0x" ^ (Word32.toString (c mod 0w32))
208 | prettyprint_operb x = prettyprint_oper x
209
210 (* pretty prints (no...) *)
12aa4087
JW
211 fun prettyprint (DIRECTIVE(str)) = str ^ "\n"
212 | prettyprint (COMMENT(str)) = "// " ^ str ^ "\n"
0a24e44d 213 | prettyprint (LABEL(l)) = Label.name l ^ "\n"
12aa4087
JW
214 | prettyprint (MOVL(src, dst)) = "\tMOVL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
215 | prettyprint (SUBL(src, dst)) = "\tSUBL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
216 | prettyprint (IMUL(src, dst)) = "\tIMUL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
217 | prettyprint (IMUL3(dst, tmp, const)) = "\tIMUL\t" ^ (prettyprint_oper (CONST const)) ^ ", " ^ (prettyprint_oper tmp) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
218 | prettyprint (ADDL(src, dst)) = "\tADDL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
12aa4087
JW
219 | prettyprint (IDIVL(src)) = "\tIDIVL\t" ^ (prettyprint_oper src) ^ "\n"
220 | prettyprint (NEG (src)) = "\tNEG\t" ^ (prettyprint_oper src) ^ "\n"
0a24e44d
JW
221 | prettyprint (NOTL (src)) = "\tNOTL\t" ^ (prettyprint_oper src) ^ "\n"
222 | prettyprint (SALL (dst, shft)) = "\tSALL\t" ^ (prettyprint_oper dst) ^ ", " ^ (prettyprint_operb shft) ^ "\n"
223 | prettyprint (SARL (dst, shft)) = "\tSARL\t" ^ (prettyprint_oper dst) ^ ", " ^ (prettyprint_operb shft) ^ "\n"
224 | prettyprint (ANDL(src, dst)) = "\tANDL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
225 | prettyprint (ORL(src, dst)) = "\tORL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
226 | prettyprint (XORL(src, dst)) = "\tXORL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
227 | prettyprint (CMPL(src, dst)) = "\tCMPL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
228 | prettyprint (TEST(src, dst)) = "\tTEST\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
229 | prettyprint (SETNE(dst)) = "\tSETNE\t" ^ (prettyprint_operb dst) ^ "\n"
230 | prettyprint (SETE(dst)) = "\tSETE\t" ^ (prettyprint_operb dst) ^ "\n"
231 | prettyprint (SETLE(dst)) = "\tSETLE\t" ^ (prettyprint_operb dst) ^ "\n"
232 | prettyprint (SETL(dst)) = "\tSETL\t" ^ (prettyprint_operb dst) ^ "\n"
233 | prettyprint (SETGE(dst)) = "\tSETGE\t" ^ (prettyprint_operb dst) ^ "\n"
234 | prettyprint (SETG(dst)) = "\tSETG\t" ^ (prettyprint_operb dst) ^ "\n"
235 | prettyprint (JMP(label)) = "\tJMP\t" ^ (Label.name label) ^ "\n"
236 | prettyprint (JE(label)) = "\tJE\t" ^ (Label.name label) ^ "\n"
237 | prettyprint (JNE(label)) = "\tJNE\t" ^ (Label.name label) ^ "\n"
238 | prettyprint (MOVZBL(src, dst)) = "\tMOVZBL\t" ^ (prettyprint_operb src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
12aa4087
JW
239 | prettyprint (CLTD) = "\tCLTD\n"
240 | prettyprint (RET) = "\tRET\n"
241(* | prettyprint _ = raise ErrorMsg.InternalError ("prettyprint: unknown instruction")*)
242end
This page took 0.044629 seconds and 4 git commands to generate.