Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | (* Copyright (C) 2009 Matthew Fluet. |
2 | * Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh | |
3 | * Jagannathan, and Stephen Weeks. | |
4 | * Copyright (C) 1997-2000 NEC Research Institute. | |
5 | * | |
6 | * MLton is released under a BSD-style license. | |
7 | * See the file MLton-LICENSE for details. | |
8 | *) | |
9 | ||
10 | signature X86_PSEUDO = | |
11 | sig | |
12 | structure CFunction: C_FUNCTION | |
13 | structure CType: C_TYPE | |
14 | structure Label: ID | |
15 | structure RepType: REP_TYPE | |
16 | structure Runtime: RUNTIME | |
17 | structure WordSize: WORD_SIZE | |
18 | structure WordX: WORD_X | |
19 | sharing CFunction = RepType.CFunction | |
20 | sharing CType = RepType.CType | |
21 | sharing WordSize = CType.WordSize = WordX.WordSize | |
22 | ||
23 | val tracer : string -> ('a -> 'b) -> | |
24 | (('a -> 'b) * (unit -> unit)) | |
25 | val tracerTop : string -> ('a -> 'b) -> | |
26 | (('a -> 'b) * (unit -> unit)) | |
27 | ||
28 | structure Size : | |
29 | sig | |
30 | datatype class = INT | FLT | FPI | |
31 | datatype t | |
32 | = BYTE | WORD | LONG | |
33 | | SNGL | DBLE | EXTD | |
34 | | FPIS | FPIL | FPIQ | |
35 | val fromBytes : int -> t | |
36 | val toBytes : t -> int | |
37 | val fromCType : CType.t -> t vector | |
38 | val class : t -> class | |
39 | val eq : t * t -> bool | |
40 | val lt : t * t -> bool | |
41 | end | |
42 | ||
43 | structure Immediate : | |
44 | sig | |
45 | type t | |
46 | ||
47 | val word : WordX.t -> t | |
48 | val int' : int * WordSize.t -> t | |
49 | val int : int -> t | |
50 | val zero : t | |
51 | val label : Label.t -> t | |
52 | val labelPlusWord : Label.t * WordX.t -> t | |
53 | val labelPlusInt : Label.t * int -> t | |
54 | end | |
55 | ||
56 | structure Scale : | |
57 | sig | |
58 | datatype t = One | Two | Four | Eight | |
59 | val fromBytes : int -> t | |
60 | val fromCType : CType.t -> t | |
61 | end | |
62 | ||
63 | structure MemLoc : | |
64 | sig | |
65 | structure Class : | |
66 | sig | |
67 | type t | |
68 | val new : {name: string} -> t | |
69 | val Temp : t | |
70 | val StaticTemp : t | |
71 | val CStack : t | |
72 | val Code : t | |
73 | ||
74 | val eq : t * t -> bool | |
75 | end | |
76 | ||
77 | type t | |
78 | val layout : t -> Layout.t | |
79 | ||
80 | val imm : {base: Immediate.t, | |
81 | index: Immediate.t, | |
82 | scale: Scale.t, | |
83 | size: Size.t, | |
84 | class: Class.t} -> t | |
85 | val basic : {base: Immediate.t, | |
86 | index: t, | |
87 | scale: Scale.t, | |
88 | size: Size.t, | |
89 | class: Class.t} -> t | |
90 | val simple : {base: t, | |
91 | index: Immediate.t, | |
92 | scale: Scale.t, | |
93 | size: Size.t, | |
94 | class: Class.t} -> t | |
95 | val complex : {base: t, | |
96 | index: t, | |
97 | scale: Scale.t, | |
98 | size: Size.t, | |
99 | class: Class.t} -> t | |
100 | val shift : {origin: t, | |
101 | disp: Immediate.t, | |
102 | scale: Scale.t, | |
103 | size: Size.t} -> t | |
104 | ||
105 | val class : t -> Class.t | |
106 | val compare : t * t -> order | |
107 | (* | |
108 | * Static memory locations | |
109 | *) | |
110 | val makeContents : {base: Immediate.t, | |
111 | size: Size.t, | |
112 | class: Class.t} -> t | |
113 | end | |
114 | ||
115 | structure ClassSet : SET | |
116 | sharing type ClassSet.Element.t = MemLoc.Class.t | |
117 | structure MemLocSet : SET | |
118 | sharing type MemLocSet.Element.t = MemLoc.t | |
119 | ||
120 | structure Operand : | |
121 | sig | |
122 | type t | |
123 | ||
124 | val layout : t -> Layout.t | |
125 | val toString : t -> string | |
126 | ||
127 | val immediate : Immediate.t -> t | |
128 | val immediate_word : WordX.t -> t | |
129 | val immediate_int' : int * WordSize.t -> t | |
130 | val immediate_int : int -> t | |
131 | val immediate_zero : t | |
132 | val immediate_label : Label.t -> t | |
133 | val deImmediate : t -> Immediate.t option | |
134 | val label : Label.t -> t | |
135 | val deLabel : t -> Label.t option | |
136 | val memloc : MemLoc.t -> t | |
137 | val memloc_label : Label.t -> t | |
138 | val deMemloc : t -> MemLoc.t option | |
139 | ||
140 | val size : t -> Size.t option | |
141 | val eq : t * t -> bool | |
142 | val mayAlias : t * t -> bool | |
143 | end | |
144 | ||
145 | structure Instruction : | |
146 | sig | |
147 | (* Integer binary arithmetic(w/o mult & div)/logic instructions. *) | |
148 | datatype binal | |
149 | = ADD (* signed/unsigned addition; p. 63 *) | |
150 | | ADC (* signed/unsigned addition with carry; p. 61 *) | |
151 | | SUB (* signed/unsigned subtraction; p. 713 *) | |
152 | | SBB (* signed/unsigned subtraction with borrow; p. 667 *) | |
153 | | AND (* logical and; p. 70 *) | |
154 | | OR (* logical or; p. 499 *) | |
155 | | XOR (* logical xor; p. 758 *) | |
156 | (* Integer multiplication and division. *) | |
157 | datatype md | |
158 | = IMUL (* signed multiplication (one operand form); p. 335 *) | |
159 | | MUL (* unsigned multiplication; p. 488 *) | |
160 | | IDIV (* signed division; p. 332 *) | |
161 | | DIV (* unsigned division; p. 188 *) | |
162 | | IMOD (* signed modulus; *) | |
163 | | MOD (* unsigned modulus; *) | |
164 | datatype unal | |
165 | = INC (* increment by 1; p. 341 *) | |
166 | | DEC (* decrement by 1; p. 186 *) | |
167 | | NEG (* two's complement negation; p. 494 *) | |
168 | | NOT (* one's complement negation; p. 497 *) | |
169 | (* Integer shift/rotate arithmetic/logic instructions. *) | |
170 | datatype sral | |
171 | = SAL (* shift arithmetic left; p. 662 *) | |
172 | | SHL (* shift logical left; p. 662 *) | |
173 | | SAR (* shift arithmetic right; p. 662 *) | |
174 | | SHR (* shift logical right; p. 662 *) | |
175 | | ROL (* rotate left; p. 631 *) | |
176 | | RCL (* rotate through carry left; p. 631 *) | |
177 | | ROR (* rotate right; p. 631 *) | |
178 | | RCR (* rotate through carry right; p. 631 *) | |
179 | (* Move with extention instructions. *) | |
180 | datatype movx | |
181 | = MOVSX (* move with sign extention; p. 481 *) | |
182 | | MOVZX (* move with zero extention; p. 486 *) | |
183 | (* Condition test field; p. 795 *) | |
184 | datatype condition | |
185 | = O (* overflow *) | NO (* not overflow *) | |
186 | | B (* below *) | NB (* not below *) | |
187 | | AE (* above or equal *) | NAE (* not above or equal *) | |
188 | | C (* carry *) | NC (* not carry *) | |
189 | | E (* equal *) | NE (* not equal *) | |
190 | | Z (* zero *) | NZ (* not zero *) | |
191 | | BE (* below or equal *) | NBE (* not below or equal *) | |
192 | | A (* above *) | NA (* not above *) | |
193 | | S (* sign *) | NS (* not sign *) | |
194 | | P (* parity *) | NP (* not parity *) | |
195 | | PE (* parity even *) | PO (* parity odd *) | |
196 | | L (* less than *) | |
197 | | NL (* not less than *) | |
198 | | LE (* less than or equal *) | |
199 | | NLE (* not less than or equal *) | |
200 | | G (* greater than *) | |
201 | | NG (* not greater than *) | |
202 | | GE (* greater than or equal *) | |
203 | | NGE (* not greater than or equal *) | |
204 | val condition_negate : condition -> condition | |
205 | val condition_reverse : condition -> condition | |
206 | (* Floating-point binary arithmetic instructions. *) | |
207 | datatype fbina | |
208 | = FADD (* addition; p. 205 *) | |
209 | | FSUB (* subtraction; p. 297 *) | |
210 | | FSUBR (* reversed subtraction; p. 301 *) | |
211 | | FMUL (* multiplication; p. 256 *) | |
212 | | FDIV (* division; p. 229 *) | |
213 | | FDIVR (* reversed division; p. 233 *) | |
214 | val fbina_reverse : fbina -> fbina | |
215 | (* Floating-point unary arithmetic instructions. *) | |
216 | datatype funa | |
217 | = F2XM1 (* compute 2^x-1; p. 201 *) | |
218 | | FABS (* absolute value; p. 203 *) | |
219 | | FCHS (* change sign; p. 214 *) | |
220 | | FSQRT (* square root; p. 284 *) | |
221 | | FSIN (* sine; p. 280 *) | |
222 | | FCOS (* cosine; p. 226 *) | |
223 | | FRNDINT (* round to integer; p. 271 *) | |
224 | (* Floating-point binary arithmetic stack instructions. *) | |
225 | datatype fbinas | |
226 | = FSCALE (* scale; p. 278 *) | |
227 | | FPREM (* partial remainder; p. 263 *) | |
228 | | FPREM1 (* IEEE partial remainder; p. 266 *) | |
229 | (* floating point binary arithmetic stack pop instructions. *) | |
230 | datatype fbinasp | |
231 | = FYL2X (* compute y * log_2 x; p. 327 *) | |
232 | | FYL2XP1 (* compute y * log_2 (x + 1.0); p. 329 *) | |
233 | | FPATAN (* partial arctangent; p. 261 *) | |
234 | (* Floating-point constants. *) | |
235 | datatype fldc | |
236 | = ONE (* +1.0; p. 250 *) | |
237 | | ZERO (* +0.0; p. 250 *) | |
238 | | PI (* pi; p. 250 *) | |
239 | | L2E (* log_2 e; p. 250 *) | |
240 | | LN2 (* log_e 2; p. 250 *) | |
241 | | L2T (* log_2 10; p. 250 *) | |
242 | | LG2 (* log_10 2; p. 250 *) | |
243 | ||
244 | type t | |
245 | end | |
246 | ||
247 | structure PseudoOp : | |
248 | sig | |
249 | type t | |
250 | ||
251 | val toString : t -> string | |
252 | ||
253 | val data : unit -> t | |
254 | val text : unit -> t | |
255 | val p2align : Immediate.t * Immediate.t option * Immediate.t option -> t | |
256 | val byte : Immediate.t list -> t | |
257 | val word : Immediate.t list -> t | |
258 | val long : Immediate.t list -> t | |
259 | end | |
260 | ||
261 | structure Assembly : | |
262 | sig | |
263 | type t | |
264 | ||
265 | val toString : t -> string | |
266 | ||
267 | val comment : string -> t | |
268 | val isComment : t -> bool | |
269 | val pseudoop : PseudoOp.t -> t | |
270 | val pseudoop_data : unit -> t | |
271 | val pseudoop_text : unit -> t | |
272 | val pseudoop_symbol_stub : unit -> t | |
273 | val pseudoop_non_lazy_symbol_pointer : unit -> t | |
274 | val pseudoop_p2align : Immediate.t * Immediate.t option * Immediate.t option -> t | |
275 | val pseudoop_byte : Immediate.t list -> t | |
276 | val pseudoop_global: Label.t -> t | |
277 | val pseudoop_hidden : Label.t -> t | |
278 | val pseudoop_indirect_symbol : Label.t -> t | |
279 | val pseudoop_word : Immediate.t list -> t | |
280 | val pseudoop_long : Immediate.t list -> t | |
281 | val label : Label.t -> t | |
282 | val instruction : Instruction.t -> t | |
283 | val instruction_nop : unit -> t | |
284 | val instruction_binal : {oper: Instruction.binal, | |
285 | src: Operand.t, | |
286 | dst: Operand.t, | |
287 | size: Size.t} -> t | |
288 | val instruction_pmd : {oper: Instruction.md, | |
289 | src: Operand.t, | |
290 | dst: Operand.t, | |
291 | size: Size.t} -> t | |
292 | val instruction_imul2 : {src: Operand.t, | |
293 | dst: Operand.t, | |
294 | size: Size.t} -> t | |
295 | val instruction_unal : {oper: Instruction.unal, | |
296 | dst: Operand.t, | |
297 | size: Size.t} -> t | |
298 | val instruction_sral : {oper: Instruction.sral, | |
299 | count: Operand.t, | |
300 | dst: Operand.t, | |
301 | size: Size.t} -> t | |
302 | val instruction_cmp : {src1: Operand.t, | |
303 | src2: Operand.t, | |
304 | size: Size.t} -> t | |
305 | val instruction_test : {src1: Operand.t, | |
306 | src2: Operand.t, | |
307 | size: Size.t} -> t | |
308 | val instruction_setcc : {condition: Instruction.condition, | |
309 | dst: Operand.t, | |
310 | size: Size.t} -> t | |
311 | val instruction_jmp : {target: Operand.t, | |
312 | absolute: bool} -> t | |
313 | val instruction_jcc : {condition: Instruction.condition, | |
314 | target: Operand.t} -> t | |
315 | val instruction_call : {target: Operand.t, | |
316 | absolute: bool} -> t | |
317 | val instruction_ret : {src: Operand.t option} -> t | |
318 | val instruction_mov : {src: Operand.t, | |
319 | dst: Operand.t, | |
320 | size: Size.t} -> t | |
321 | val instruction_cmovcc : {condition: Instruction.condition, | |
322 | src: Operand.t, | |
323 | dst: Operand.t, | |
324 | size: Size.t} -> t | |
325 | val instruction_xchg : {src: Operand.t, | |
326 | dst: Operand.t, | |
327 | size: Size.t} -> t | |
328 | val instruction_ppush : {src: Operand.t, | |
329 | base: Operand.t, | |
330 | size: Size.t} -> t | |
331 | val instruction_ppop : {dst: Operand.t, | |
332 | base: Operand.t, | |
333 | size: Size.t} -> t | |
334 | val instruction_movx : {oper: Instruction.movx, | |
335 | src: Operand.t, | |
336 | srcsize: Size.t, | |
337 | dst: Operand.t, | |
338 | dstsize: Size.t} -> t | |
339 | val instruction_xvom : {src: Operand.t, | |
340 | srcsize: Size.t, | |
341 | dst: Operand.t, | |
342 | dstsize: Size.t} -> t | |
343 | val instruction_lea : {src: Operand.t, | |
344 | dst: Operand.t, | |
345 | size: Size.t} -> t | |
346 | val instruction_pfmov : {src: Operand.t, | |
347 | dst: Operand.t, | |
348 | size: Size.t} -> t | |
349 | val instruction_pfmovx : {src: Operand.t, | |
350 | dst: Operand.t, | |
351 | srcsize: Size.t, | |
352 | dstsize: Size.t} -> t | |
353 | val instruction_pfxvom : {src: Operand.t, | |
354 | dst: Operand.t, | |
355 | srcsize: Size.t, | |
356 | dstsize: Size.t} -> t | |
357 | val instruction_pfldc : {oper: Instruction.fldc, | |
358 | dst: Operand.t, | |
359 | size: Size.t} -> t | |
360 | val instruction_pfmovfi : {src: Operand.t, | |
361 | srcsize: Size.t, | |
362 | dst: Operand.t, | |
363 | dstsize: Size.t} -> t | |
364 | val instruction_pfmovti : {src: Operand.t, | |
365 | srcsize: Size.t, | |
366 | dst: Operand.t, | |
367 | dstsize: Size.t} -> t | |
368 | val instruction_pfcom : {src1: Operand.t, | |
369 | src2: Operand.t, | |
370 | size: Size.t} -> t | |
371 | val instruction_pfucom : {src1: Operand.t, | |
372 | src2: Operand.t, | |
373 | size: Size.t} -> t | |
374 | val instruction_pfbina : {oper: Instruction.fbina, | |
375 | src: Operand.t, | |
376 | dst: Operand.t, | |
377 | size: Size.t} -> t | |
378 | val instruction_pfuna : {oper: Instruction.funa, | |
379 | dst: Operand.t, | |
380 | size: Size.t} -> t | |
381 | val instruction_pfptan : {dst: Operand.t, | |
382 | size: Size.t} -> t | |
383 | val instruction_pfbinas : {oper: Instruction.fbinas, | |
384 | src: Operand.t, | |
385 | dst: Operand.t, | |
386 | size: Size.t} -> t | |
387 | val instruction_pfbinasp : {oper: Instruction.fbinasp, | |
388 | src: Operand.t, | |
389 | dst: Operand.t, | |
390 | size: Size.t} -> t | |
391 | val instruction_fldcw : {src: Operand.t} -> t | |
392 | val instruction_fstcw : {dst: Operand.t, | |
393 | check: bool} -> t | |
394 | val instruction_fstsw : {dst: Operand.t, | |
395 | check: bool} -> t | |
396 | end | |
397 | ||
398 | structure FrameInfo: | |
399 | sig | |
400 | datatype t = T of {size: int, | |
401 | frameLayoutsIndex: int} | |
402 | end | |
403 | ||
404 | structure Entry: | |
405 | sig | |
406 | type t | |
407 | ||
408 | val cont: {label: Label.t, | |
409 | live: MemLocSet.t, | |
410 | frameInfo: FrameInfo.t} -> t | |
411 | val creturn: {dsts: (Operand.t * Size.t) vector, | |
412 | frameInfo: FrameInfo.t option, | |
413 | func: RepType.t CFunction.t, | |
414 | label: Label.t} -> t | |
415 | val func: {label: Label.t, | |
416 | live: MemLocSet.t} -> t | |
417 | val handler: {frameInfo: FrameInfo.t, | |
418 | label: Label.t, | |
419 | live: MemLocSet.t} -> t | |
420 | val jump: {label: Label.t} -> t | |
421 | val label: t -> Label.t | |
422 | end | |
423 | ||
424 | structure Transfer : | |
425 | sig | |
426 | structure Cases : | |
427 | sig | |
428 | type 'a t | |
429 | ||
430 | val word : (WordX.t * 'a) list -> 'a t | |
431 | end | |
432 | ||
433 | type t | |
434 | ||
435 | val goto : {target: Label.t} -> t | |
436 | val iff : {condition: Instruction.condition, | |
437 | truee: Label.t, | |
438 | falsee: Label.t} -> t | |
439 | val switch : {test: Operand.t, | |
440 | cases: Label.t Cases.t, | |
441 | default: Label.t} -> t | |
442 | val tail : {target: Label.t, | |
443 | live: MemLocSet.t} -> t | |
444 | val nontail : {target: Label.t, | |
445 | live: MemLocSet.t, | |
446 | return: Label.t, | |
447 | handler: Label.t option, | |
448 | size: int} -> t | |
449 | val return : {live: MemLocSet.t} -> t | |
450 | val raisee : {live: MemLocSet.t} -> t | |
451 | val ccall : {args: (Operand.t * Size.t) list, | |
452 | frameInfo: FrameInfo.t option, | |
453 | func: RepType.t CFunction.t, | |
454 | return: Label.t option} -> t | |
455 | end | |
456 | ||
457 | structure ProfileLabel : | |
458 | sig | |
459 | type t | |
460 | end | |
461 | ||
462 | structure Block : | |
463 | sig | |
464 | type t' | |
465 | val mkBlock': {entry: Entry.t option, | |
466 | statements: Assembly.t list, | |
467 | transfer: Transfer.t option} -> t' | |
468 | val mkProfileBlock': {profileLabel: ProfileLabel.t} -> t' | |
469 | val printBlock' : t' -> unit | |
470 | ||
471 | type t | |
472 | val printBlock : t -> unit | |
473 | ||
474 | val compress: t' list -> t list | |
475 | end | |
476 | ||
477 | structure Chunk : | |
478 | sig | |
479 | datatype t = T of {data: Assembly.t list, blocks: Block.t list} | |
480 | ||
481 | end | |
482 | end | |
483 | ||
484 | functor x86PseudoCheck(structure S : X86) : X86_PSEUDO = S |