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_STRUCTS = | |
11 | sig | |
12 | structure CFunction: C_FUNCTION | |
13 | structure CType: C_TYPE | |
14 | structure Label: ID | |
15 | structure ProfileLabel: PROFILE_LABEL | |
16 | structure RepType: REP_TYPE | |
17 | structure Runtime: RUNTIME | |
18 | structure WordSize: WORD_SIZE | |
19 | structure WordX: WORD_X | |
20 | sharing CFunction = RepType.CFunction | |
21 | sharing CType = RepType.CType | |
22 | sharing WordSize = CType.WordSize = WordX.WordSize | |
23 | end | |
24 | ||
25 | signature X86 = | |
26 | sig | |
27 | structure CFunction: C_FUNCTION | |
28 | structure CType: C_TYPE | |
29 | structure Label: ID | |
30 | structure RepType: REP_TYPE | |
31 | structure Runtime: RUNTIME | |
32 | structure WordSize: WORD_SIZE | |
33 | structure WordX: WORD_X | |
34 | sharing CFunction = RepType.CFunction | |
35 | sharing CType = RepType.CType | |
36 | sharing WordSize = CType.WordSize = WordX.WordSize | |
37 | ||
38 | val tracer : string -> ('a -> 'b) -> | |
39 | (('a -> 'b) * (unit -> unit)) | |
40 | val tracerTop : string -> ('a -> 'b) -> | |
41 | (('a -> 'b) * (unit -> unit)) | |
42 | ||
43 | structure Size : | |
44 | sig | |
45 | datatype class = INT | FLT | FPI | |
46 | ||
47 | datatype t | |
48 | = BYTE | WORD | LONG | |
49 | | SNGL | DBLE | EXTD | |
50 | | FPIS | FPIL | FPIQ | |
51 | ||
52 | val toString : t -> string | |
53 | val fromBytes : int -> t | |
54 | val toBytes : t -> int | |
55 | val fromCType : CType.t -> t vector | |
56 | val class : t -> class | |
57 | val toFPI : t -> t | |
58 | val eq : t * t -> bool | |
59 | val lt : t * t -> bool | |
60 | end | |
61 | ||
62 | structure Register : | |
63 | sig | |
64 | datatype reg | |
65 | = EAX | EBX | ECX | EDX | EDI | ESI | EBP | ESP | |
66 | val allReg : reg list | |
67 | ||
68 | datatype part | |
69 | = E | X | L | H | |
70 | ||
71 | datatype t = T of {reg: reg, part: part} | |
72 | val all : t list | |
73 | ||
74 | val toString : t -> string | |
75 | val size : t -> Size.t | |
76 | val eq : t * t -> bool | |
77 | val valid : t -> bool | |
78 | val coincide : t * t -> bool | |
79 | val coincident' : reg -> t list | |
80 | ||
81 | (* | |
82 | val return : Size.t -> t | |
83 | *) | |
84 | val eax : t | |
85 | val ebx : t | |
86 | val ecx : t | |
87 | val edx : t | |
88 | val al : t | |
89 | val bl : t | |
90 | val cl : t | |
91 | val dl : t | |
92 | val edi : t | |
93 | val esi : t | |
94 | val esp : t | |
95 | val ebp : t | |
96 | ||
97 | val registers : Size.t -> t list | |
98 | val baseRegisters : t list | |
99 | val indexRegisters : t list | |
100 | val callerSaveRegisters : t list | |
101 | val calleeSaveRegisters : t list | |
102 | ||
103 | val withLowPart : Size.t * Size.t -> t list | |
104 | val lowPartOf : t * Size.t -> t | |
105 | end | |
106 | ||
107 | structure FltRegister : | |
108 | sig | |
109 | datatype t = T of int | |
110 | val toString : t -> string | |
111 | val eq: t * t -> bool | |
112 | (* | |
113 | val return : t | |
114 | *) | |
115 | val top : t | |
116 | val one : t | |
117 | val total : int | |
118 | val push : t -> t | |
119 | val pop : t -> t | |
120 | val id : t -> t | |
121 | end | |
122 | ||
123 | structure Immediate : | |
124 | sig | |
125 | type t | |
126 | ||
127 | datatype u | |
128 | = Word of WordX.t | |
129 | | Label of Label.t | |
130 | | LabelPlusWord of Label.t * WordX.t | |
131 | ||
132 | val word : WordX.t -> t | |
133 | val int' : int * WordSize.t -> t | |
134 | val int : int -> t | |
135 | val zero : t | |
136 | val label : Label.t -> t | |
137 | val labelPlusWord : Label.t * WordX.t -> t | |
138 | val labelPlusInt : Label.t * int -> t | |
139 | ||
140 | val deLabel : t -> Label.t option | |
141 | val destruct : t -> u | |
142 | val clearAll : unit -> unit | |
143 | ||
144 | val eval : t -> WordX.t option | |
145 | val isZero : t -> bool | |
146 | val eq : t * t -> bool | |
147 | end | |
148 | ||
149 | structure Scale : | |
150 | sig | |
151 | datatype t | |
152 | = One | Two | Four | Eight | |
153 | val eq : t * t -> bool | |
154 | val toWordX : t -> WordX.t | |
155 | val toImmediate : t -> Immediate.t | |
156 | val fromBytes : int -> t | |
157 | val fromCType : CType.t -> t | |
158 | end | |
159 | ||
160 | structure Address : | |
161 | sig | |
162 | datatype t = T of {disp: Immediate.t option, | |
163 | base: Register.t option, | |
164 | index: Register.t option, | |
165 | scale: Scale.t option} | |
166 | end | |
167 | ||
168 | structure MemLoc : | |
169 | sig | |
170 | structure Class : | |
171 | sig | |
172 | type t | |
173 | ||
174 | val toString : t -> string | |
175 | ||
176 | val new : {name: string} -> t | |
177 | val Temp : t | |
178 | val StaticTemp : t | |
179 | val CStack : t | |
180 | val Code : t | |
181 | ||
182 | val eq : t * t -> bool | |
183 | val compare : t * t -> order | |
184 | end | |
185 | ||
186 | type t | |
187 | ||
188 | datatype u | |
189 | = U of {immBase: Immediate.t option, | |
190 | memBase: t option, | |
191 | immIndex: Immediate.t option, | |
192 | memIndex: t option, | |
193 | scale: Scale.t, | |
194 | size: Size.t, | |
195 | class: Class.t} | |
196 | ||
197 | val layout : t -> Layout.t | |
198 | val toString : t -> string | |
199 | ||
200 | val imm : {base: Immediate.t, | |
201 | index: Immediate.t, | |
202 | scale: Scale.t, | |
203 | size: Size.t, | |
204 | class: Class.t} -> t | |
205 | val basic : {base: Immediate.t, | |
206 | index: t, | |
207 | scale: Scale.t, | |
208 | size: Size.t, | |
209 | class: Class.t} -> t | |
210 | val simple : {base: t, | |
211 | index: Immediate.t, | |
212 | scale: Scale.t, | |
213 | size: Size.t, | |
214 | class: Class.t} -> t | |
215 | val complex : {base: t, | |
216 | index: t, | |
217 | scale: Scale.t, | |
218 | size: Size.t, | |
219 | class: Class.t} -> t | |
220 | val shift : {origin: t, | |
221 | disp: Immediate.t, | |
222 | scale: Scale.t, | |
223 | size: Size.t} -> t | |
224 | val destruct : t -> u | |
225 | val clearAll : unit -> unit | |
226 | ||
227 | val size : t -> Size.t | |
228 | val class : t -> Class.t | |
229 | val eq : t * t -> bool | |
230 | val compare : t * t -> order | |
231 | ||
232 | val utilized : t -> t list | |
233 | val mayAlias : t * t -> bool | |
234 | val mayAliasOrd : t * t -> order option | |
235 | ||
236 | val replace : (t -> t) -> t -> t | |
237 | ||
238 | (* | |
239 | * Static memory locations | |
240 | *) | |
241 | val makeContents : {base: Immediate.t, | |
242 | size: Size.t, | |
243 | class: Class.t} -> t | |
244 | (* CReturn locations *) | |
245 | (* | |
246 | val cReturnTempContent : Size.t -> t | |
247 | val cReturnTempContents : CFunction.CType.t -> t list | |
248 | *) | |
249 | end | |
250 | ||
251 | structure ClassSet : SET | |
252 | sharing type ClassSet.Element.t = MemLoc.Class.t | |
253 | structure MemLocSet : SET | |
254 | sharing type MemLocSet.Element.t = MemLoc.t | |
255 | ||
256 | structure Operand : | |
257 | sig | |
258 | datatype t | |
259 | = Register of Register.t | |
260 | | FltRegister of FltRegister.t | |
261 | | Immediate of Immediate.t | |
262 | | Label of Label.t | |
263 | | Address of Address.t | |
264 | | MemLoc of MemLoc.t | |
265 | ||
266 | val layout : t -> Layout.t | |
267 | val toString : t -> string | |
268 | ||
269 | val register : Register.t -> t | |
270 | val deRegister : t -> Register.t option | |
271 | val fltregister : FltRegister.t -> t | |
272 | val deFltregister : t -> FltRegister.t option | |
273 | val immediate : Immediate.t -> t | |
274 | val immediate_word : WordX.t -> t | |
275 | val immediate_int' : int * WordSize.t -> t | |
276 | val immediate_int : int -> t | |
277 | val immediate_zero : t | |
278 | val immediate_label : Label.t -> t | |
279 | val deImmediate : t -> Immediate.t option | |
280 | val label : Label.t -> t | |
281 | val deLabel : t -> Label.t option | |
282 | val address : Address.t -> t | |
283 | val memloc : MemLoc.t -> t | |
284 | val memloc_label : Label.t -> t | |
285 | val deMemloc : t -> MemLoc.t option | |
286 | ||
287 | val size : t -> Size.t option | |
288 | val eq : t * t -> bool | |
289 | val mayAlias : t * t -> bool | |
290 | ||
291 | val cReturnTemps: RepType.t -> {src: t, dst: MemLoc.t} list | |
292 | end | |
293 | ||
294 | structure Instruction : | |
295 | sig | |
296 | (* Integer binary arithmetic(w/o mult & div)/logic instructions. *) | |
297 | datatype binal | |
298 | = ADD (* signed/unsigned addition; p. 63 *) | |
299 | | ADC (* signed/unsigned addition with carry; p. 61 *) | |
300 | | SUB (* signed/unsigned subtraction; p. 713 *) | |
301 | | SBB (* signed/unsigned subtraction with borrow; p. 667 *) | |
302 | | AND (* logical and; p. 70 *) | |
303 | | OR (* logical or; p. 499 *) | |
304 | | XOR (* logical xor; p. 758 *) | |
305 | (* Integer multiplication and division. *) | |
306 | datatype md | |
307 | = IMUL (* signed multiplication (one operand form); p. 335 *) | |
308 | | MUL (* unsigned multiplication; p. 488 *) | |
309 | | IDIV (* signed division; p. 332 *) | |
310 | | DIV (* unsigned division; p. 188 *) | |
311 | | IMOD (* signed modulus; *) | |
312 | | MOD (* unsigned modulus; *) | |
313 | (* Integer unary arithmetic/logic instructions. *) | |
314 | datatype unal | |
315 | = INC (* increment by 1; p. 341 *) | |
316 | | DEC (* decrement by 1; p. 186 *) | |
317 | | NEG (* two's complement negation; p. 494 *) | |
318 | | NOT (* one's complement negation; p. 497 *) | |
319 | (* Integer shift/rotate arithmetic/logic instructions. *) | |
320 | datatype sral | |
321 | = SAL (* shift arithmetic left; p. 662 *) | |
322 | | SHL (* shift logical left; p. 662 *) | |
323 | | SAR (* shift arithmetic right; p. 662 *) | |
324 | | SHR (* shift logical right; p. 662 *) | |
325 | | ROL (* rotate left; p. 631 *) | |
326 | | RCL (* rotate through carry left; p. 631 *) | |
327 | | ROR (* rotate right; p. 631 *) | |
328 | | RCR (* rotate through carry right; p. 631 *) | |
329 | (* Move with extention instructions. *) | |
330 | datatype movx | |
331 | = MOVSX (* move with sign extention; p. 481 *) | |
332 | | MOVZX (* move with zero extention; p. 486 *) | |
333 | (* Condition test field; p. 795 *) | |
334 | datatype condition | |
335 | = O (* overflow *) | NO (* not overflow *) | |
336 | | B (* below *) | NB (* not below *) | |
337 | | AE (* above or equal *) | NAE (* not above or equal *) | |
338 | | C (* carry *) | NC (* not carry *) | |
339 | | E (* equal *) | NE (* not equal *) | |
340 | | Z (* zero *) | NZ (* not zero *) | |
341 | | BE (* below or equal *) | NBE (* not below or equal *) | |
342 | | A (* above *) | NA (* not above *) | |
343 | | S (* sign *) | NS (* not sign *) | |
344 | | P (* parity *) | NP (* not parity *) | |
345 | | PE (* parity even *) | PO (* parity odd *) | |
346 | | L (* less than *) | |
347 | | NL (* not less than *) | |
348 | | LE (* less than or equal *) | |
349 | | NLE (* not less than or equal *) | |
350 | | G (* greater than *) | |
351 | | NG (* not greater than *) | |
352 | | GE (* greater than or equal *) | |
353 | | NGE (* not greater than or equal *) | |
354 | val condition_negate : condition -> condition | |
355 | val condition_reverse : condition -> condition | |
356 | ||
357 | (* Floating-point binary arithmetic instructions. *) | |
358 | datatype fbina | |
359 | = FADD (* addition; p. 205 *) | |
360 | | FSUB (* subtraction; p. 297 *) | |
361 | | FSUBR (* reversed subtraction; p. 301 *) | |
362 | | FMUL (* multiplication; p. 256 *) | |
363 | | FDIV (* division; p. 229 *) | |
364 | | FDIVR (* reversed division; p. 233 *) | |
365 | val fbina_reverse : fbina -> fbina | |
366 | (* Floating-point unary arithmetic instructions. *) | |
367 | datatype funa | |
368 | = F2XM1 (* compute 2^x-1; p. 201 *) | |
369 | | FABS (* absolute value; p. 203 *) | |
370 | | FCHS (* change sign; p. 214 *) | |
371 | | FSQRT (* square root; p. 284 *) | |
372 | | FSIN (* sine; p. 280 *) | |
373 | | FCOS (* cosine; p. 226 *) | |
374 | | FRNDINT (* round to integer; p. 271 *) | |
375 | (* Floating-point binary arithmetic stack instructions. *) | |
376 | datatype fbinas | |
377 | = FSCALE (* scale; p. 278 *) | |
378 | | FPREM (* partial remainder; p. 263 *) | |
379 | | FPREM1 (* IEEE partial remainder; p. 266 *) | |
380 | (* floating point binary arithmetic stack pop instructions. *) | |
381 | datatype fbinasp | |
382 | = FYL2X (* compute y * log_2 x; p. 327 *) | |
383 | | FYL2XP1 (* compute y * log_2 (x + 1.0); p. 329 *) | |
384 | | FPATAN (* partial arctangent; p. 261 *) | |
385 | (* Floating-point constants. *) | |
386 | datatype fldc | |
387 | = ONE (* +1.0; p. 250 *) | |
388 | | ZERO (* +0.0; p. 250 *) | |
389 | | PI (* pi; p. 250 *) | |
390 | | L2E (* log_2 e; p. 250 *) | |
391 | | LN2 (* log_e 2; p. 250 *) | |
392 | | L2T (* log_2 10; p. 250 *) | |
393 | | LG2 (* log_10 2; p. 250 *) | |
394 | ||
395 | (* x86 Instructions. | |
396 | * src operands are not changed by the instruction. | |
397 | * dst operands are changed by the instruction. | |
398 | *) | |
399 | datatype t | |
400 | (* No operation *) | |
401 | = NOP | |
402 | (* Halt *) | |
403 | | HLT | |
404 | (* Integer binary arithmetic(w/o mult & div)/logic instructions. | |
405 | *) | |
406 | | BinAL of {oper: binal, | |
407 | src: Operand.t, | |
408 | dst: Operand.t, | |
409 | size: Size.t} | |
410 | (* Psuedo integer multiplication and division. | |
411 | *) | |
412 | | pMD of {oper: md, | |
413 | src: Operand.t, | |
414 | dst: Operand.t, | |
415 | size: Size.t} | |
416 | (* Integer multiplication and division. | |
417 | *) | |
418 | | MD of {oper: md, | |
419 | src: Operand.t, | |
420 | size: Size.t} | |
421 | (* Integer signed/unsiged multiplication (two operand form); p. 335 | |
422 | *) | |
423 | | IMUL2 of {src: Operand.t, | |
424 | dst: Operand.t, | |
425 | size: Size.t} | |
426 | (* Integer unary arithmetic/logic instructions. | |
427 | *) | |
428 | | UnAL of {oper: unal, | |
429 | dst: Operand.t, | |
430 | size: Size.t} | |
431 | (* Integer shift/rotate arithmetic/logic instructions. | |
432 | *) | |
433 | | SRAL of {oper: sral, | |
434 | count: Operand.t, | |
435 | dst: Operand.t, | |
436 | size: Size.t} | |
437 | (* Arithmetic compare. | |
438 | *) | |
439 | | CMP of {src1: Operand.t, | |
440 | src2: Operand.t, | |
441 | size: Size.t} | |
442 | (* Logical compare. | |
443 | *) | |
444 | | TEST of {src1: Operand.t, | |
445 | src2: Operand.t, | |
446 | size: Size.t} | |
447 | (* Set byte on condition. | |
448 | *) | |
449 | | SETcc of {condition: condition, | |
450 | dst: Operand.t, | |
451 | size: Size.t} | |
452 | (* Jump; p. 373 | |
453 | *) | |
454 | | JMP of {target: Operand.t, | |
455 | absolute: bool} | |
456 | (* Jump if condition is met. | |
457 | *) | |
458 | | Jcc of {condition: condition, | |
459 | target: Operand.t} | |
460 | (* Call procedure. | |
461 | *) | |
462 | | CALL of {target: Operand.t, | |
463 | absolute: bool} | |
464 | (* Return from procedure. | |
465 | *) | |
466 | | RET of {src: Operand.t option} | |
467 | (* Move. | |
468 | *) | |
469 | | MOV of {src: Operand.t, | |
470 | dst: Operand.t, | |
471 | size: Size.t} | |
472 | (* Conditional move. | |
473 | *) | |
474 | | CMOVcc of {condition: condition, | |
475 | src: Operand.t, | |
476 | dst: Operand.t, | |
477 | size: Size.t} | |
478 | (* Exchange register/memory with register. | |
479 | *) | |
480 | | XCHG of {src: Operand.t, | |
481 | dst: Operand.t, | |
482 | size: Size.t} | |
483 | (* Pseudo push a value onto a stack. | |
484 | *) | |
485 | | pPUSH of {src: Operand.t, | |
486 | base: Operand.t, | |
487 | size: Size.t} | |
488 | (* Pseudo pop a value from a stack. | |
489 | *) | |
490 | | pPOP of {dst: Operand.t, | |
491 | base: Operand.t, | |
492 | size: Size.t} | |
493 | (* Push a value onto the stack. | |
494 | *) | |
495 | | PUSH of {src: Operand.t, | |
496 | size: Size.t} | |
497 | (* Pop a value from the stack. | |
498 | *) | |
499 | | POP of {dst: Operand.t, | |
500 | size: Size.t} | |
501 | (* Convert X to 2X with sign extension. | |
502 | *) | |
503 | | CX of {size: Size.t} | |
504 | (* Move with extention. | |
505 | *) | |
506 | | MOVX of {oper: movx, | |
507 | src: Operand.t, | |
508 | srcsize: Size.t, | |
509 | dst: Operand.t, | |
510 | dstsize: Size.t} | |
511 | (* Move with contraction. | |
512 | *) | |
513 | | XVOM of {src: Operand.t, | |
514 | srcsize: Size.t, | |
515 | dst: Operand.t, | |
516 | dstsize: Size.t} | |
517 | (* Load effective address. | |
518 | *) | |
519 | | LEA of {src: Operand.t, | |
520 | dst: Operand.t, | |
521 | size: Size.t} | |
522 | (* Pseudo floating-point move. | |
523 | *) | |
524 | | pFMOV of {src: Operand.t, | |
525 | dst: Operand.t, | |
526 | size: Size.t} | |
527 | (* Pseudo floating-point move with extension. | |
528 | *) | |
529 | | pFMOVX of {src: Operand.t, | |
530 | dst: Operand.t, | |
531 | srcsize: Size.t, | |
532 | dstsize: Size.t} | |
533 | (* Pseudo floating-point move with contraction. | |
534 | *) | |
535 | | pFXVOM of {src: Operand.t, | |
536 | dst: Operand.t, | |
537 | srcsize: Size.t, | |
538 | dstsize: Size.t} | |
539 | (* Pseudo floating-point load constant. | |
540 | *) | |
541 | | pFLDC of {oper: fldc, | |
542 | dst: Operand.t, | |
543 | size: Size.t} | |
544 | (* Pseudo floating-point move from integer. | |
545 | *) | |
546 | | pFMOVFI of {src: Operand.t, | |
547 | dst: Operand.t, | |
548 | srcsize: Size.t, | |
549 | dstsize: Size.t} | |
550 | (* Pseudo floating-point move to integer. | |
551 | *) | |
552 | | pFMOVTI of {src: Operand.t, | |
553 | dst: Operand.t, | |
554 | srcsize: Size.t, | |
555 | dstsize: Size.t} | |
556 | (* Pseudo floating-point compare. | |
557 | *) | |
558 | | pFCOM of {src1: Operand.t, | |
559 | src2: Operand.t, | |
560 | size: Size.t} | |
561 | (* Pseudo floating-point unordered compare. | |
562 | *) | |
563 | | pFUCOM of {src1: Operand.t, | |
564 | src2: Operand.t, | |
565 | size: Size.t} | |
566 | (* Pseudo floating-point binary arithmetic instructions. | |
567 | *) | |
568 | | pFBinA of {oper: fbina, | |
569 | src: Operand.t, | |
570 | dst: Operand.t, | |
571 | size: Size.t} | |
572 | (* Pseudo floating-point unary arithmetic instructions. | |
573 | *) | |
574 | | pFUnA of {oper: funa, | |
575 | dst: Operand.t, | |
576 | size: Size.t} | |
577 | (* Pseudo floating-point partial tangetn instruction. | |
578 | *) | |
579 | | pFPTAN of {dst: Operand.t, | |
580 | size: Size.t} | |
581 | (* Pseudo floating-point binary arithmetic stack instructions. | |
582 | *) | |
583 | | pFBinAS of {oper: fbinas, | |
584 | src: Operand.t, | |
585 | dst: Operand.t, | |
586 | size: Size.t} | |
587 | (* Pseudo floating-point binary arithmetic stack pop instructions. | |
588 | *) | |
589 | | pFBinASP of {oper: fbinasp, | |
590 | src: Operand.t, | |
591 | dst: Operand.t, | |
592 | size: Size.t} | |
593 | (* Floating-point load real. | |
594 | *) | |
595 | | FLD of {src: Operand.t, | |
596 | size: Size.t} | |
597 | (* Floating-point store real. | |
598 | *) | |
599 | | FST of {dst: Operand.t, | |
600 | size: Size.t, | |
601 | pop: bool} | |
602 | (* Floating-point load integer. | |
603 | *) | |
604 | | FILD of {src: Operand.t, | |
605 | size: Size.t} | |
606 | (* Floating-point store integer. | |
607 | *) | |
608 | | FIST of {dst: Operand.t, | |
609 | size: Size.t, | |
610 | pop: bool} | |
611 | (* Floating-point exchange. | |
612 | *) | |
613 | | FXCH of {src: Operand.t} | |
614 | (* Floating-point load constant. | |
615 | *) | |
616 | | FLDC of {oper: fldc} | |
617 | (* Floating-point load control word. | |
618 | *) | |
619 | | FLDCW of {src: Operand.t} | |
620 | (* Floating-point store control word. | |
621 | *) | |
622 | | FSTCW of {dst: Operand.t, | |
623 | check: bool} | |
624 | (* Floating-point store status word. | |
625 | *) | |
626 | | FSTSW of {dst: Operand.t, | |
627 | check: bool} | |
628 | (* Floating-point compare. | |
629 | *) | |
630 | | FCOM of {src: Operand.t, | |
631 | size: Size.t, | |
632 | pop: bool, | |
633 | pop': bool} | |
634 | (* Floating-point unordered compare. | |
635 | *) | |
636 | | FUCOM of {src: Operand.t, | |
637 | pop: bool, | |
638 | pop': bool} | |
639 | (* Floating-point binary arithmetic instructions. | |
640 | *) | |
641 | | FBinA of {oper: fbina, | |
642 | src: Operand.t, | |
643 | dst: Operand.t, | |
644 | size: Size.t, | |
645 | pop: bool} | |
646 | (* Floating-point unary arithmetic instructions. | |
647 | *) | |
648 | | FUnA of {oper: funa} | |
649 | (* Floating-point partial tangent instruction. | |
650 | *) | |
651 | | FPTAN | |
652 | (* Floating-point binary arithmetic stack instructions. | |
653 | *) | |
654 | | FBinAS of {oper: fbinas} | |
655 | (* Floating-point binary arithmetic stack pop instructions. | |
656 | *) | |
657 | | FBinASP of {oper: fbinasp} | |
658 | ||
659 | val toString : t -> string | |
660 | val uses_defs_kills : t -> {uses: Operand.t list, | |
661 | defs: Operand.t list, | |
662 | kills: Operand.t list} | |
663 | val hints : t -> (MemLoc.t * Register.t) list | |
664 | val srcs_dsts : t -> {srcs: Operand.t list option, | |
665 | dsts: Operand.t list option} | |
666 | val replace : ({use: bool, def: bool} -> Operand.t -> Operand.t) -> | |
667 | t -> t | |
668 | end | |
669 | ||
670 | structure Directive : | |
671 | sig | |
672 | structure Id : | |
673 | sig | |
674 | type t | |
675 | val new : unit -> t | |
676 | val plist : t -> PropertyList.t | |
677 | end | |
678 | ||
679 | datatype t | |
680 | (* Transfers *) | |
681 | (* Assert that a memloc is in a register with properties; | |
682 | * used at top of basic blocks to establish passing convention. | |
683 | *) | |
684 | = Assume of {assumes: {register: Register.t, | |
685 | memloc: MemLoc.t, | |
686 | weight: int, | |
687 | sync: bool, | |
688 | reserve: bool} list} | |
689 | | FltAssume of {assumes: {memloc: MemLoc.t, | |
690 | weight: int, | |
691 | sync: bool} list} | |
692 | (* Ensure that memloc is in the register, possibly reserved; | |
693 | * used at bot of basic blocks to establish passing convention, | |
694 | * also used before C calls to set-up %esp. | |
695 | *) | |
696 | | Cache of {caches: {register: Register.t, | |
697 | memloc: MemLoc.t, | |
698 | reserve: bool} list} | |
699 | | FltCache of {caches: {memloc: MemLoc.t} list} | |
700 | (* Reset the register allocation; | |
701 | * used at bot of basic blocks that fall-thru | |
702 | * to a block with multiple incoming paths of control. | |
703 | *) | |
704 | | Reset | |
705 | (* Ensure that memlocs are commited to memory; | |
706 | * used at bot of basic blocks to establish passing conventions | |
707 | *) | |
708 | | Force of {commit_memlocs: MemLocSet.t, | |
709 | commit_classes: ClassSet.t, | |
710 | remove_memlocs: MemLocSet.t, | |
711 | remove_classes: ClassSet.t, | |
712 | dead_memlocs: MemLocSet.t, | |
713 | dead_classes: ClassSet.t} | |
714 | (* C calls *) | |
715 | (* Prepare for a C call; i.e., clear all caller save registers; | |
716 | * also, clear the flt. register stack; | |
717 | * used before C calls. | |
718 | *) | |
719 | | CCall | |
720 | (* Assert the return value; | |
721 | * used after C calls. | |
722 | *) | |
723 | | Return of {returns: {src:Operand.t, dst: MemLoc.t} list} | |
724 | (* Misc. *) | |
725 | (* Assert that the register is not free for the allocator; | |
726 | * used ??? | |
727 | *) | |
728 | | Reserve of {registers: Register.t list} | |
729 | (* Assert that the register is free for the allocator; | |
730 | * used to free registers at fall-thru; | |
731 | * also used after C calls to free %esp. | |
732 | *) | |
733 | | Unreserve of {registers: Register.t list} | |
734 | (* Clear the floating point stack; | |
735 | * used at bot of basic blocks to establish passing convention, | |
736 | *) | |
737 | | ClearFlt | |
738 | (* Save the register allocation in id and | |
739 | * assert that live are used at this point; | |
740 | * used at bot of basic blocks to delay establishment | |
741 | * of passing convention to compensation block | |
742 | *) | |
743 | | SaveRegAlloc of {live: MemLocSet.t, | |
744 | id: Id.t} | |
745 | (* Restore the register allocation from id and | |
746 | * remove anything tracked that is not live; | |
747 | * used at bot of basic blocks to delay establishment | |
748 | * of passing convention to compensation block | |
749 | *) | |
750 | | RestoreRegAlloc of {live: MemLocSet.t, | |
751 | id: Id.t} | |
752 | ||
753 | val toString : t -> string | |
754 | val uses_defs_kills : t -> {uses: Operand.t list, | |
755 | defs: Operand.t list, | |
756 | kills: Operand.t list} | |
757 | val hints : t -> (MemLoc.t * Register.t) list | |
758 | val replace : ({use: bool, def: bool} -> Operand.t -> Operand.t) -> | |
759 | t -> t | |
760 | val assume : {assumes: {register: Register.t, | |
761 | memloc: MemLoc.t, | |
762 | weight: int, | |
763 | sync: bool, | |
764 | reserve: bool} list} -> t | |
765 | val fltassume : {assumes: {memloc: MemLoc.t, | |
766 | weight: int, | |
767 | sync: bool} list} -> t | |
768 | val cache : {caches: {register: Register.t, | |
769 | memloc: MemLoc.t, | |
770 | reserve: bool} list} -> t | |
771 | val fltcache : {caches: {memloc: MemLoc.t} list} -> t | |
772 | val reset : unit -> t | |
773 | val force : {commit_memlocs: MemLocSet.t, | |
774 | commit_classes: ClassSet.t, | |
775 | remove_memlocs: MemLocSet.t, | |
776 | remove_classes: ClassSet.t, | |
777 | dead_memlocs: MemLocSet.t, | |
778 | dead_classes: ClassSet.t} -> t | |
779 | val ccall : unit -> t | |
780 | val return : {returns: {src: Operand.t, dst: MemLoc.t} list} -> t | |
781 | val reserve : {registers: Register.t list} -> t | |
782 | val unreserve : {registers: Register.t list} -> t | |
783 | val clearflt : unit -> t | |
784 | val saveregalloc : {live: MemLocSet.t, | |
785 | id: Id.t} -> t | |
786 | val restoreregalloc : {live: MemLocSet.t, | |
787 | id: Id.t} -> t | |
788 | end | |
789 | ||
790 | structure PseudoOp : | |
791 | sig | |
792 | datatype t | |
793 | = Data | |
794 | | Text | |
795 | | SymbolStub | |
796 | | NonLazySymbolPointer | |
797 | | Balign of Immediate.t * Immediate.t option * Immediate.t option | |
798 | | P2align of Immediate.t * Immediate.t option * Immediate.t option | |
799 | | Space of Immediate.t * Immediate.t | |
800 | | Byte of Immediate.t list | |
801 | | Word of Immediate.t list | |
802 | | Long of Immediate.t list | |
803 | | String of string list | |
804 | | Global of Label.t | |
805 | | Hidden of Label.t | |
806 | | IndirectSymbol of Label.t | |
807 | | Local of Label.t | |
808 | | Comm of Label.t * Immediate.t * Immediate.t option | |
809 | ||
810 | val toString : t -> string | |
811 | ||
812 | val data : unit -> t | |
813 | val text : unit -> t | |
814 | val symbol_stub : unit -> t | |
815 | val non_lazy_symbol_pointer : unit -> t | |
816 | val balign : Immediate.t * Immediate.t option * Immediate.t option -> t | |
817 | val p2align : Immediate.t * Immediate.t option * Immediate.t option -> t | |
818 | val space : Immediate.t * Immediate.t -> t | |
819 | val byte : Immediate.t list -> t | |
820 | val word : Immediate.t list -> t | |
821 | val long : Immediate.t list -> t | |
822 | val string : string list -> t | |
823 | val global : Label.t -> t | |
824 | val hidden : Label.t -> t | |
825 | val indirect_symbol : Label.t -> t | |
826 | val locall : Label.t -> t | |
827 | val comm : Label.t * Immediate.t * Immediate.t option -> t | |
828 | end | |
829 | ||
830 | structure Assembly : | |
831 | sig | |
832 | datatype t | |
833 | = Comment of string | |
834 | | Directive of Directive.t | |
835 | | PseudoOp of PseudoOp.t | |
836 | | Label of Label.t | |
837 | | Instruction of Instruction.t | |
838 | ||
839 | val layout : t -> Layout.t | |
840 | val toString : t -> string | |
841 | val uses_defs_kills : t -> {uses: Operand.t list, | |
842 | defs: Operand.t list, | |
843 | kills: Operand.t list} | |
844 | val hints : t -> (MemLoc.t * Register.t) list | |
845 | val replace : ({use: bool, def: bool} -> Operand.t -> Operand.t) -> | |
846 | t -> t | |
847 | ||
848 | val comment : string -> t | |
849 | val isComment : t -> bool | |
850 | val directive : Directive.t -> t | |
851 | val directive_assume : {assumes: {register: Register.t, | |
852 | memloc: MemLoc.t, | |
853 | weight: int, | |
854 | sync: bool, | |
855 | reserve: bool} list} -> t | |
856 | val directive_fltassume : {assumes: {memloc: MemLoc.t, | |
857 | weight: int, | |
858 | sync: bool} list} -> t | |
859 | val directive_cache : {caches: {register: Register.t, | |
860 | memloc: MemLoc.t, | |
861 | reserve: bool} list} -> t | |
862 | val directive_fltcache : {caches: {memloc: MemLoc.t} list} -> t | |
863 | val directive_reset : unit -> t | |
864 | val directive_force : {commit_memlocs: MemLocSet.t, | |
865 | commit_classes: ClassSet.t, | |
866 | remove_memlocs: MemLocSet.t, | |
867 | remove_classes: ClassSet.t, | |
868 | dead_memlocs: MemLocSet.t, | |
869 | dead_classes: ClassSet.t} -> t | |
870 | val directive_ccall : unit -> t | |
871 | val directive_return : {returns: {src: Operand.t, dst: MemLoc.t} list} -> t | |
872 | val directive_reserve : {registers: Register.t list} -> t | |
873 | val directive_unreserve : {registers: Register.t list} -> t | |
874 | val directive_saveregalloc : {live: MemLocSet.t, | |
875 | id: Directive.Id.t} -> t | |
876 | val directive_restoreregalloc : {live: MemLocSet.t, | |
877 | id: Directive.Id.t} -> t | |
878 | val directive_clearflt : unit -> t | |
879 | val pseudoop : PseudoOp.t -> t | |
880 | val pseudoop_data : unit -> t | |
881 | val pseudoop_text : unit -> t | |
882 | val pseudoop_symbol_stub : unit -> t | |
883 | val pseudoop_non_lazy_symbol_pointer : unit -> t | |
884 | val pseudoop_balign : Immediate.t * Immediate.t option * Immediate.t option ->t | |
885 | val pseudoop_p2align : Immediate.t * Immediate.t option * Immediate.t option -> t | |
886 | val pseudoop_space : Immediate.t * Immediate.t -> t | |
887 | val pseudoop_byte : Immediate.t list -> t | |
888 | val pseudoop_word : Immediate.t list -> t | |
889 | val pseudoop_long : Immediate.t list -> t | |
890 | val pseudoop_string : string list -> t | |
891 | val pseudoop_global : Label.t -> t | |
892 | val pseudoop_hidden : Label.t -> t | |
893 | val pseudoop_indirect_symbol : Label.t -> t | |
894 | val pseudoop_local : Label.t -> t | |
895 | val pseudoop_comm : Label.t * Immediate.t * Immediate.t option -> t | |
896 | val label : Label.t -> t | |
897 | val instruction : Instruction.t -> t | |
898 | val instruction_nop : unit -> t | |
899 | val instruction_hlt : unit -> t | |
900 | val instruction_binal : {oper: Instruction.binal, | |
901 | src: Operand.t, | |
902 | dst: Operand.t, | |
903 | size: Size.t} -> t | |
904 | val instruction_pmd : {oper: Instruction.md, | |
905 | src: Operand.t, | |
906 | dst: Operand.t, | |
907 | size: Size.t} -> t | |
908 | val instruction_md : {oper: Instruction.md, | |
909 | src: Operand.t, | |
910 | size: Size.t} -> t | |
911 | val instruction_imul2 : {src: Operand.t, | |
912 | dst: Operand.t, | |
913 | size: Size.t} -> t | |
914 | val instruction_unal : {oper: Instruction.unal, | |
915 | dst: Operand.t, | |
916 | size: Size.t} -> t | |
917 | val instruction_sral : {oper: Instruction.sral, | |
918 | count: Operand.t, | |
919 | dst: Operand.t, | |
920 | size: Size.t} -> t | |
921 | val instruction_cmp : {src1: Operand.t, | |
922 | src2: Operand.t, | |
923 | size: Size.t} -> t | |
924 | val instruction_test : {src1: Operand.t, | |
925 | src2: Operand.t, | |
926 | size: Size.t} -> t | |
927 | val instruction_setcc : {condition: Instruction.condition, | |
928 | dst: Operand.t, | |
929 | size: Size.t} -> t | |
930 | val instruction_jmp : {target: Operand.t, | |
931 | absolute: bool} -> t | |
932 | val instruction_jcc : {condition: Instruction.condition, | |
933 | target: Operand.t} -> t | |
934 | val instruction_call : {target: Operand.t, | |
935 | absolute: bool} -> t | |
936 | val instruction_ret : {src: Operand.t option} -> t | |
937 | val instruction_mov : {src: Operand.t, | |
938 | dst: Operand.t, | |
939 | size: Size.t} -> t | |
940 | val instruction_cmovcc : {condition: Instruction.condition, | |
941 | src: Operand.t, | |
942 | dst: Operand.t, | |
943 | size: Size.t} -> t | |
944 | val instruction_xchg : {src: Operand.t, | |
945 | dst: Operand.t, | |
946 | size: Size.t} -> t | |
947 | val instruction_ppush : {src: Operand.t, | |
948 | base: Operand.t, | |
949 | size: Size.t} -> t | |
950 | val instruction_ppop : {dst: Operand.t, | |
951 | base: Operand.t, | |
952 | size: Size.t} -> t | |
953 | val instruction_push : {src: Operand.t, | |
954 | size: Size.t} -> t | |
955 | val instruction_pop : {dst: Operand.t, | |
956 | size: Size.t} -> t | |
957 | val instruction_cx : {size: Size.t} -> t | |
958 | val instruction_movx : {oper: Instruction.movx, | |
959 | src: Operand.t, | |
960 | srcsize: Size.t, | |
961 | dst: Operand.t, | |
962 | dstsize: Size.t} -> t | |
963 | val instruction_xvom : {src: Operand.t, | |
964 | srcsize: Size.t, | |
965 | dst: Operand.t, | |
966 | dstsize: Size.t} -> t | |
967 | val instruction_lea : {src: Operand.t, | |
968 | dst: Operand.t, | |
969 | size: Size.t} -> t | |
970 | val instruction_pfmov : {src: Operand.t, | |
971 | dst: Operand.t, | |
972 | size: Size.t} -> t | |
973 | val instruction_pfmovx : {src: Operand.t, | |
974 | dst: Operand.t, | |
975 | srcsize: Size.t, | |
976 | dstsize: Size.t} -> t | |
977 | val instruction_pfxvom : {src: Operand.t, | |
978 | dst: Operand.t, | |
979 | srcsize: Size.t, | |
980 | dstsize: Size.t} -> t | |
981 | val instruction_pfldc : {oper: Instruction.fldc, | |
982 | dst: Operand.t, | |
983 | size: Size.t} -> t | |
984 | val instruction_pfmovfi : {src: Operand.t, | |
985 | srcsize: Size.t, | |
986 | dst: Operand.t, | |
987 | dstsize: Size.t} -> t | |
988 | val instruction_pfmovti : {src: Operand.t, | |
989 | srcsize: Size.t, | |
990 | dst: Operand.t, | |
991 | dstsize: Size.t} -> t | |
992 | val instruction_pfcom : {src1: Operand.t, | |
993 | src2: Operand.t, | |
994 | size: Size.t} -> t | |
995 | val instruction_pfucom : {src1: Operand.t, | |
996 | src2: Operand.t, | |
997 | size: Size.t} -> t | |
998 | val instruction_pfbina : {oper: Instruction.fbina, | |
999 | src: Operand.t, | |
1000 | dst: Operand.t, | |
1001 | size: Size.t} -> t | |
1002 | val instruction_pfuna : {oper: Instruction.funa, | |
1003 | dst: Operand.t, | |
1004 | size: Size.t} -> t | |
1005 | val instruction_pfptan : {dst: Operand.t, | |
1006 | size: Size.t} -> t | |
1007 | val instruction_pfbinas : {oper: Instruction.fbinas, | |
1008 | src: Operand.t, | |
1009 | dst: Operand.t, | |
1010 | size: Size.t} -> t | |
1011 | val instruction_pfbinasp : {oper: Instruction.fbinasp, | |
1012 | src: Operand.t, | |
1013 | dst: Operand.t, | |
1014 | size: Size.t} -> t | |
1015 | val instruction_fld : {src: Operand.t, | |
1016 | size: Size.t} -> t | |
1017 | val instruction_fst : {dst: Operand.t, | |
1018 | size: Size.t, | |
1019 | pop: bool} -> t | |
1020 | val instruction_fild : {src: Operand.t, | |
1021 | size: Size.t} -> t | |
1022 | val instruction_fist : {dst: Operand.t, | |
1023 | size: Size.t, | |
1024 | pop: bool} -> t | |
1025 | val instruction_fxch : {src: Operand.t} -> t | |
1026 | val instruction_fldc : {oper: Instruction.fldc} -> t | |
1027 | val instruction_fldcw : {src: Operand.t} -> t | |
1028 | val instruction_fstcw : {dst: Operand.t, | |
1029 | check: bool} -> t | |
1030 | val instruction_fstsw : {dst: Operand.t, | |
1031 | check: bool} -> t | |
1032 | val instruction_fcom : {src: Operand.t, | |
1033 | size: Size.t, | |
1034 | pop: bool, | |
1035 | pop': bool} -> t | |
1036 | val instruction_fucom : {src: Operand.t, | |
1037 | pop: bool, | |
1038 | pop': bool} -> t | |
1039 | val instruction_fbina : {oper: Instruction.fbina, | |
1040 | src: Operand.t, | |
1041 | dst: Operand.t, | |
1042 | size: Size.t, | |
1043 | pop: bool} -> t | |
1044 | val instruction_funa : {oper: Instruction.funa} -> t | |
1045 | val instruction_fptan : unit -> t | |
1046 | val instruction_fbinas : {oper: Instruction.fbinas} -> t | |
1047 | val instruction_fbinasp : {oper: Instruction.fbinasp} -> t | |
1048 | end | |
1049 | ||
1050 | structure FrameInfo: | |
1051 | sig | |
1052 | datatype t = T of {size: int, | |
1053 | frameLayoutsIndex: int} | |
1054 | end | |
1055 | ||
1056 | structure Entry: | |
1057 | sig | |
1058 | datatype t | |
1059 | = Jump of {label: Label.t} | |
1060 | | Func of {label: Label.t, | |
1061 | live: MemLocSet.t} | |
1062 | | Cont of {label: Label.t, | |
1063 | live: MemLocSet.t, | |
1064 | frameInfo: FrameInfo.t} | |
1065 | | Handler of {frameInfo: FrameInfo.t, | |
1066 | label: Label.t, | |
1067 | live: MemLocSet.t} | |
1068 | | CReturn of {dsts: (Operand.t * Size.t) vector, | |
1069 | frameInfo: FrameInfo.t option, | |
1070 | func: RepType.t CFunction.t, | |
1071 | label: Label.t} | |
1072 | ||
1073 | val cont : {label: Label.t, | |
1074 | live: MemLocSet.t, | |
1075 | frameInfo: FrameInfo.t} -> t | |
1076 | val creturn: {dsts: (Operand.t * Size.t) vector, | |
1077 | frameInfo: FrameInfo.t option, | |
1078 | func: RepType.t CFunction.t, | |
1079 | label: Label.t} -> t | |
1080 | val func : {label: Label.t, | |
1081 | live: MemLocSet.t} -> t | |
1082 | val handler : {frameInfo: FrameInfo.t, | |
1083 | label: Label.t, | |
1084 | live: MemLocSet.t} -> t | |
1085 | val isFunc : t -> bool | |
1086 | val jump : {label: Label.t} -> t | |
1087 | val label : t -> Label.t | |
1088 | val live : t -> MemLocSet.t | |
1089 | val toString : t -> string | |
1090 | val uses_defs_kills : t -> {uses: Operand.t list, | |
1091 | defs: Operand.t list, | |
1092 | kills: Operand.t list} | |
1093 | end | |
1094 | ||
1095 | structure Transfer : | |
1096 | sig | |
1097 | structure Cases : | |
1098 | sig | |
1099 | datatype 'a t = Word of (WordX.t * 'a) list | |
1100 | ||
1101 | val word : (WordX.t * 'a) list -> 'a t | |
1102 | ||
1103 | val isEmpty : 'a t -> bool | |
1104 | val isSingle : 'a t -> bool | |
1105 | val extract : 'a t * (WordX.t * 'a -> 'b) -> 'b | |
1106 | val count : 'a t * ('a -> bool) -> int | |
1107 | val keepAll : 'a t * (WordX.t * 'a -> bool) -> 'a t | |
1108 | val forall : 'a t * (WordX.t * 'a -> bool) -> bool | |
1109 | val foreach : 'a t * (WordX.t * 'a -> unit) -> unit | |
1110 | val map : 'a t * (WordX.t * 'a -> 'b) -> 'b t | |
1111 | val mapToList : 'a t * (WordX.t * 'a -> 'b) -> 'b list | |
1112 | end | |
1113 | ||
1114 | datatype t | |
1115 | = Goto of {target: Label.t} | |
1116 | | Iff of {condition: Instruction.condition, | |
1117 | truee: Label.t, | |
1118 | falsee: Label.t} | |
1119 | | Switch of {test: Operand.t, | |
1120 | cases: Label.t Cases.t, | |
1121 | default: Label.t} | |
1122 | | Tail of {target: Label.t, | |
1123 | live: MemLocSet.t} | |
1124 | | NonTail of {target: Label.t, | |
1125 | live: MemLocSet.t, | |
1126 | return: Label.t, | |
1127 | handler: Label.t option, | |
1128 | size: int} | |
1129 | | Return of {live: MemLocSet.t} | |
1130 | | Raise of {live: MemLocSet.t} | |
1131 | | CCall of {args: (Operand.t * Size.t) list, | |
1132 | frameInfo: FrameInfo.t option, | |
1133 | func: RepType.t CFunction.t, | |
1134 | return: Label.t option} | |
1135 | ||
1136 | val toString : t -> string | |
1137 | ||
1138 | val uses_defs_kills : t -> {uses: Operand.t list, | |
1139 | defs: Operand.t list, | |
1140 | kills: Operand.t list} | |
1141 | val nearTargets : t -> Label.t list | |
1142 | val live : t -> MemLocSet.t | |
1143 | val replace : ({use: bool, def: bool} -> Operand.t -> Operand.t) -> | |
1144 | t -> t | |
1145 | ||
1146 | val goto : {target: Label.t} -> t | |
1147 | val iff : {condition: Instruction.condition, | |
1148 | truee: Label.t, | |
1149 | falsee: Label.t} -> t | |
1150 | val switch : {test: Operand.t, | |
1151 | cases: Label.t Cases.t, | |
1152 | default: Label.t} -> t | |
1153 | val tail : {target: Label.t, | |
1154 | live: MemLocSet.t} -> t | |
1155 | val nontail : {target: Label.t, | |
1156 | live: MemLocSet.t, | |
1157 | return: Label.t, | |
1158 | handler: Label.t option, | |
1159 | size: int} -> t | |
1160 | val return : {live: MemLocSet.t} -> t | |
1161 | val raisee : {live: MemLocSet.t} -> t | |
1162 | val ccall: {args: (Operand.t * Size.t) list, | |
1163 | frameInfo: FrameInfo.t option, | |
1164 | func: RepType.t CFunction.t, | |
1165 | return: Label.t option} -> t | |
1166 | end | |
1167 | ||
1168 | structure ProfileLabel : | |
1169 | sig | |
1170 | include PROFILE_LABEL | |
1171 | val toAssembly : t -> Assembly.t list | |
1172 | val toAssemblyOpt : t option -> Assembly.t list | |
1173 | end | |
1174 | ||
1175 | structure Block : | |
1176 | sig | |
1177 | datatype t' = T' of {entry: Entry.t option, | |
1178 | profileLabel: ProfileLabel.t option, | |
1179 | statements: Assembly.t list, | |
1180 | transfer: Transfer.t option} | |
1181 | val mkBlock': {entry: Entry.t option, | |
1182 | statements: Assembly.t list, | |
1183 | transfer: Transfer.t option} -> t' | |
1184 | val mkProfileBlock': {profileLabel: ProfileLabel.t} -> t' | |
1185 | val printBlock' : t' -> unit | |
1186 | ||
1187 | datatype t = T of {entry: Entry.t, | |
1188 | profileLabel: ProfileLabel.t option, | |
1189 | statements: Assembly.t list, | |
1190 | transfer: Transfer.t} | |
1191 | val printBlock : t -> unit | |
1192 | ||
1193 | val compress : t' list -> t list | |
1194 | end | |
1195 | ||
1196 | structure Chunk : | |
1197 | sig | |
1198 | datatype t = T of {data: Assembly.t list, | |
1199 | blocks: Block.t list} | |
1200 | end | |
1201 | end |