1 # The Mu computer's level-2 language, also called Mu.
2 # http://akkartik.name/post/mu-2019-2
5 # $ ./translate_subx init.linux [0-9]*.subx mu.subx
6 # $ ./a.elf < prog.mu > prog.elf
9 # 1. Be memory safe. It should be impossible to corrupt the heap, or to create
10 # a bad pointer. (Requires strong type safety.)
11 # 2. Do as little as possible to achieve goal 1. The translator should be
12 # implementable in machine code.
13 # - minimize impedance mismatch between source language and SubX target
14 # (e.g. programmer manages registers manually)
15 # - checks over syntax
16 # (e.g. programmer's register allocation is checked)
17 # - runtime checks to avoid complex static analysis
18 # (e.g. array indexing always checks bounds)
20 # == Language description
21 # A program is a sequence of function and type definitions.
24 # fn foo n: int -> _/eax: int {
28 # Functions consist of a name, optional inputs, optional outputs and a block.
30 # Function inputs and outputs are variables. All variables have a type and
31 # storage specifier. They can be placed either in memory (on the stack) or in
32 # one of 6 named registers.
33 # eax ecx edx ebx esi edi
34 # Variables in registers must be primitive 32-bit types.
35 # Variables not explicitly placed in a register are on the stack.
37 # Function inputs are always passed in memory (on the stack), while outputs
38 # are always returned in registers. Outputs can't be named; they use the
41 # Blocks mostly consist of statements.
43 # Statements mostly consist of a name, optional inputs and optional outputs.
45 # Statement inputs are variables or literals. Variables need to specify type
46 # (and storage) the first time they're mentioned but not later.
48 # Statement outputs, like function outputs, must be variables in registers.
50 # Statement names must be either primitives or user-defined functions.
52 # Primitives can write to any register.
53 # User-defined functions only write to hard-coded registers. Outputs of each
54 # call must have the same registers as in the function definition.
56 # There are some other statement types:
57 # - blocks. Multiple statements surrounded by '{...}' and optionally
58 # prefixed with a label name and ':'
66 # - variable definitions on the stack. E.g.:
68 # - var bar: (array int 3)
69 # There's no initializer; variables are automatically initialized.
70 # The type of a local variable is either word-length (4 bytes) or starts with 'ref'.
72 # - variables definitions in a register. E.g.:
73 # - var foo/eax: int <- add bar 1
74 # The initializer is mandatory and must be a valid instruction that writes
75 # a single output to the right register. In practice registers will
76 # usually be either initialized by primitives or copied from eax.
77 # - var eax: int <- foo bar quux
78 # var floo/ecx: int <- copy eax
85 # A program is a linked list of functions
86 # A function contains:
87 # name: (handle array byte)
88 # inouts: linked list of vars <-- 'inouts' is more precise than 'inputs'
91 # outputs: linked list of vars
94 # body: (handle block)
95 # A var-type contains:
96 # name: (handle array byte)
97 # type: (handle type-tree)
101 # tag 1: a simple statement (stmt1)
102 # tag 2: a variable defined on the stack
103 # tag 3: a variable defined in a register
107 # statements: (handle list stmt)
108 # name: (handle array byte) -- starting with '$'
110 # A regular statement contains:
112 # operation: (handle array byte)
113 # inouts: (handle list operand)
114 # outputs: (handle list var)
116 # A variable defined on the stack contains:
118 # name: (handle array byte)
119 # type: (handle type-tree)
121 # A variable defined in a register contains:
123 # name: (handle array byte)
124 # type: (handle type-tree)
125 # reg: (handle array byte)
127 # == Translation: managing the stack
128 # Now that we know what the language looks like in the large, let's think
129 # about how translation happens from the bottom up. One crucial piece of the
130 # puzzle is how Mu will clean up variables defined on the stack for you.
132 # Assume that we maintain a 'functions' list while parsing source code. And a
133 # 'primitives' list is a global constant. Both these contain enough information
134 # to perform type-checking on function calls or primitive statements, respectively.
136 # Defining variables pushes them on a stack with the current block depth and
137 # enough information about their location (stack offset or register).
138 # Starting a block increments the current block id.
139 # Each statement now has enough information to emit code for it.
140 # Ending a block is where the magic happens:
141 # pop all variables at the current block depth
142 # emit code to restore all register variables introduced at the current depth
143 # emit code to clean up all stack variables at the current depth (just increment esp)
144 # decrement the current block depth
147 # live-vars: stack of vars
149 # name: (handle array byte)
150 # type: (handle type-tree)
152 # stack-offset: int (added to ebp)
153 # register: (handle array byte)
154 # either usual register names
155 # or '*' to indicate any register
156 # At most one of stack-offset or register-index must be non-zero.
157 # A register of '*' designates a variable _template_. Only legal in formal
158 # parameters for primitives.
160 # == Translating a single function call
161 # This one's easy. Assuming we've already checked things, we just drop the
162 # outputs (which use hard-coded registers) and emit inputs in a standard format.
164 # out1, out2, out3, ... <- name inout1, inout2, inout3, ...
166 # (name inout1 inout2 inout3)
169 # functions: linked list of info
170 # name: (handle array byte)
171 # inouts: linked list of vars
172 # outputs: linked list of vars
173 # body: block (linked list of statements)
175 # == Translating a single primitive instruction
176 # A second crucial piece of the puzzle is how Mu converts fairly regular
177 # primitives with their uniform syntax to SubX instructions with their gnarly
180 # Mu instructions have inputs and outputs. Primitives can have up to 2 of
182 # SubX instructions have rm32 and r32 operands.
183 # The translation between them covers almost all the possibilities.
184 # Instructions with 1 inout may turn into ones with 1 rm32
185 # (e.g. incrementing a var on the stack)
186 # Instructions with 1 output may turn into ones with 1 rm32
187 # (e.g. incrementing a var in a register)
188 # 1 inout and 1 output may turn into 1 rm32 and 1 r32
189 # (e.g. adding a var to a reg)
190 # 2 inouts may turn into 1 rm32 and 1 r32
191 # (e.g. adding a reg to a var)
192 # 1 inout and 1 literal may turn into 1 rm32 and 1 imm32
193 # (e.g. adding a constant to a var)
194 # 1 output and 1 literal may turn into 1 rm32 and 1 imm32
195 # (e.g. adding a constant to a reg)
196 # 2 outputs to hardcoded registers and 1 inout may turn into 1 rm32
197 # (special-case: divide edx:eax by a var or reg)
199 # We always emit rm32. It may be the first inout or the first output.
200 # We may emit r32 or imm32 or neither.
201 # When we emit r32 it may come from first inout or second inout or first output.
203 # Accordingly, the formal data structure for a primitive looks like this:
204 # primitives: linked list of info
205 # name: (handle array byte)
206 # mu-inouts: linked list of vars to check
207 # mu-outputs: linked list of vars to check; at most a singleton
208 # subx-name: (handle array byte)
209 # subx-rm32: enum arg-location
210 # subx-r32: enum arg-location
211 # subx-imm32: enum arg-location
212 # subx-imm8: enum arg-location
213 # subx-disp32: enum arg-location
214 # subx-xm32: enum arg-location
215 # subx-x32: enum arg-location
218 # 1 means first inout
219 # 2 means second inout
220 # 3 means first output
222 # == Translating a block
223 # Emit block name if necessary
225 # When you encounter a statement, emit it as above
226 # When you encounter a variable declaration
227 # emit any code needed for it (bzeros)
228 # push it on the var stack
229 # update register dict if necessary
230 # When you encounter '}'
231 # While popping variables off the var stack until block id changes
232 # Emit code needed to clean up the stack
233 # either increment esp
234 # or pop into appropriate register
236 # The rest is straightforward.
241 _Program-functions: # (handle function)
243 _Program-functions->payload:
245 _Program-types: # (handle typeinfo)
247 _Program-types->payload:
249 _Program-signatures: # (handle function)
251 _Program-signatures->payload:
254 # Some constants for simulating the data structures described above.
255 # Many constants here come with a type in a comment.
257 # Sometimes the type is of the value at that offset for the given type. For
258 # example, if you start at a function record and move forward Function-inouts
259 # bytes, you'll find a (handle list var).
261 # At other times, the type is of the constant itself. For example, the type of
262 # the constant Function-size is (addr int). To get the size of a function,
263 # look in *Function-size.
265 Function-name: # (handle array byte)
267 Function-inouts: # (handle list var)
269 Function-outputs: # (handle list var)
271 Function-body: # (handle block)
273 Function-next: # (handle function)
275 Function-size: # (addr int)
278 Primitive-name: # (handle array byte)
280 Primitive-inouts: # (handle list var)
282 Primitive-outputs: # (handle list var)
284 Primitive-subx-name: # (handle array byte)
286 Primitive-subx-rm32: # enum arg-location
288 Primitive-subx-r32: # enum arg-location
290 Primitive-subx-imm32: # enum arg-location
292 Primitive-subx-imm8: # enum arg-location -- only for bit shifts
294 Primitive-subx-disp32: # enum arg-location -- only for branches
296 Primitive-subx-xm32: # enum arg-location
298 Primitive-subx-x32: # enum arg-location
300 Primitive-next: # (handle function)
302 Primitive-size: # (addr int)
308 Block-stmts: # (handle list stmt)
310 Block-var: # (handle var)
313 Stmt1-operation: # (handle array byte)
315 Stmt1-inouts: # (handle stmt-var)
317 Stmt1-outputs: # (handle stmt-var)
320 Vardef-var: # (handle var)
323 Regvardef-operation: # (handle array byte)
325 Regvardef-inouts: # (handle stmt-var)
327 Regvardef-outputs: # (handle stmt-var) # will have exactly one element
330 Stmt-size: # (addr int)
333 Var-name: # (handle array byte)
335 Var-type: # (handle type-tree)
337 Var-block-depth: # int -- not available until code-generation time
339 Var-offset: # int -- not available until code-generation time
341 Var-register: # (handle array byte) -- name of a register
343 Var-size: # (addr int)
346 List-value: # (handle _)
348 List-next: # (handle list _)
350 List-size: # (addr int)
353 # A stmt-var is like a list of vars with call-site specific metadata
354 Stmt-var-value: # (handle var)
356 Stmt-var-next: # (handle stmt-var)
358 Stmt-var-is-deref: # boolean
360 Stmt-var-size: # (addr int)
363 # A live-var is a var augmented with information needed for tracking live
365 Live-var-value: # (handle var)
367 Live-var-register-spilled: # boolean; only used if value is in a register, and only during code-gen
369 Live-var-size: # (addr int)
372 # Types are expressed as trees (s-expressions) of type-ids (ints).
374 Type-tree-is-atom: # boolean
377 Type-tree-value: # type-id
379 Type-tree-value-size: # int (for static data structure sizes)
381 Type-tree-parameter-name: # (handle array byte) for type parameters
384 Type-tree-left: # (addr type-tree)
386 Type-tree-right: # (addr type-tree)
389 Type-tree-size: # (addr int)
394 # TODO: Turn this data structure into valid Mu, with (fake) handles rather than addrs.
395 Type-id: # (stream (addr array byte))
396 0/imm32/write # initialized later from Primitive-type-ids
400 0/imm32 # 0 reserved for literals; value is just the name
401 # Not to be used directly, so we don't include a name here.
407 0/imm32 # 6 reserved for constants; they're like literals, but value is an int in Var-offset
408 # Not to be used directly, so we don't include a name here.
409 "offset"/imm32 # 7: (offset T) is guaranteed to be a 32-bit multiple of size-of(T)
412 0/imm32 # 9 reserved for array-capacity; value is in Type-tree-size.
413 # Not to be used directly, so we don't include a name here.
414 0/imm32 # 10 reserved for type parameters; value is (address array byte) in Type-tree-value2.
415 # Not to be used directly, so we don't include a name here.
418 "code-point"/imm32 # 13; smallest scannable unit from a text stream
419 "grapheme"/imm32 # 14; smallest printable unit; will eventually be composed of multiple code-points, but currently corresponds 1:1
420 # only 4-byte graphemes in utf-8 are currently supported;
421 # unclear how we should deal with larger clusters.
424 0/imm32 # 16 reserved for literal strings; value is just the name
425 # Not to be used directly, so we don't include a name here.
426 # TODO: move this up next to literal ints
427 # Keep Primitive-type-ids in sync if you add types here.
428 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
429 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
430 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
431 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
432 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
433 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
435 Primitive-type-ids: # (addr int)
438 # == Type definitions
439 # Program->types contains some typeinfo for each type definition.
440 # Types contain vars with types, but can't specify registers.
441 Typeinfo-id: # type-id
443 Typeinfo-fields: # (handle table (handle array byte) (handle typeinfo-entry))
445 # Total size must be >= 0
446 # During parsing it may take on two additional values:
447 # -2: not yet initialized
448 # -1: in process of being computed
449 # See populate-mu-type-sizes for details.
450 Typeinfo-total-size-in-bytes: # int
452 Typeinfo-next: # (handle typeinfo)
454 Typeinfo-size: # (addr int)
457 # Each entry in the typeinfo->fields table has a pointer to a string and a
458 # pointer to a typeinfo-entry.
459 Typeinfo-fields-row-size: # (addr int)
462 # typeinfo-entry objects have information about a field in a single record type
464 # each field of a type is represented using two var's:
465 # 1. the input var: expected type of the field; convenient for creating using parse-var-with-type
466 # 2. the output var: a constant containing the byte offset; convenient for code-generation
467 # computing the output happens after parsing; in the meantime we preserve the
468 # order of fields in the 'index' field.
469 Typeinfo-entry-input-var: # (handle var)
471 Typeinfo-entry-index: # int
473 Typeinfo-entry-output-var: # (handle var)
475 Typeinfo-entry-size: # (addr int)
483 (new-segment *Heap-size Heap)
484 #? (test-address-with-right-type-for-stream)
485 # if (argv[1] == "test') run-tests()
487 # if (argc <= 1) break
488 81 7/subop/compare *ebp 1/imm32
489 7e/jump-if-<= break/disp8
490 # if (argv[1] != "test") break
491 (kernel-string-equal? *(ebp+8) "test") # => eax
492 3d/compare-eax-and 0/imm32/false
493 74/jump-if-= break/disp8
496 # syscall_exit(*Num-test-failures)
497 8b/-> *Num-test-failures 3/r32/ebx
498 eb/jump $mu-main:end/disp8
500 # otherwise convert Stdin
501 (write-buffered Stdout "== code\n")
502 (convert-mu Stdin Stdout Stderr 0)
505 bb/copy-to-ebx 0/imm32
507 e8/call syscall_exit/disp32
509 convert-mu: # in: (addr buffered-file), out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor)
515 # initialize global data structures
516 c7 0/subop/copy *Next-block-index 1/imm32
517 8b/-> *Primitive-type-ids 0/r32/eax
518 89/<- *Type-id 0/r32/eax # stream-write
519 c7 0/subop/copy *_Program-functions 0/imm32
520 c7 0/subop/copy *_Program-functions->payload 0/imm32
521 c7 0/subop/copy *_Program-types 0/imm32
522 c7 0/subop/copy *_Program-types->payload 0/imm32
523 c7 0/subop/copy *_Program-signatures 0/imm32
524 c7 0/subop/copy *_Program-signatures->payload 0/imm32
526 (parse-mu *(ebp+8) *(ebp+0x10) *(ebp+0x14))
527 (populate-mu-type-sizes *(ebp+0x10) *(ebp+0x14))
528 #? (dump-typeinfos "=== typeinfos\n")
529 (check-mu-types *(ebp+0x10) *(ebp+0x14))
530 (emit-subx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
532 # . restore registers
539 test-convert-empty-input:
540 # empty input => empty output
545 (clear-stream _test-input-stream)
546 (clear-stream $_test-input-buffered-file->buffer)
547 (clear-stream _test-output-stream)
548 (clear-stream $_test-output-buffered-file->buffer)
550 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
551 (flush _test-output-buffered-file)
552 (check-stream-equal _test-output-stream "" "F - test-convert-empty-input")
558 test-convert-function-skeleton:
563 (clear-stream _test-input-stream)
564 (clear-stream $_test-input-buffered-file->buffer)
565 (clear-stream _test-output-stream)
566 (clear-stream $_test-output-buffered-file->buffer)
568 (write _test-input-stream "fn foo {\n")
569 (write _test-input-stream "}\n")
571 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
572 (flush _test-output-buffered-file)
573 #? # dump _test-output-stream {{{
575 #? (write-stream 2 _test-output-stream)
577 #? (rewind-stream _test-output-stream)
580 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0")
581 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-skeleton/1")
582 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-skeleton/2")
583 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3")
584 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-skeleton/4")
585 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5")
586 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-skeleton/6")
587 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-skeleton/7")
593 test-convert-multiple-function-skeletons:
598 (clear-stream _test-input-stream)
599 (clear-stream $_test-input-buffered-file->buffer)
600 (clear-stream _test-output-stream)
601 (clear-stream $_test-output-buffered-file->buffer)
603 (write _test-input-stream "fn foo {\n")
604 (write _test-input-stream "}\n")
605 (write _test-input-stream "fn bar {\n")
606 (write _test-input-stream "}\n")
608 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
609 (flush _test-output-buffered-file)
610 #? # dump _test-output-stream {{{
612 #? (write-stream 2 _test-output-stream)
614 #? (rewind-stream _test-output-stream)
616 # check first function
617 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-multiple-function-skeletons/0")
618 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/1")
619 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/2")
620 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/3")
621 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/4")
622 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/5")
623 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/6")
624 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/7")
625 # check second function
626 (check-next-stream-line-equal _test-output-stream "bar:" "F - test-convert-multiple-function-skeletons/10")
627 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/11")
628 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/12")
629 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/13")
630 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/14")
631 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/15")
632 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/16")
633 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/17")
639 test-convert-function-with-arg:
644 (clear-stream _test-input-stream)
645 (clear-stream $_test-input-buffered-file->buffer)
646 (clear-stream _test-output-stream)
647 (clear-stream $_test-output-buffered-file->buffer)
649 (write _test-input-stream "fn foo n: int {\n")
650 (write _test-input-stream "}\n")
652 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
653 (flush _test-output-buffered-file)
654 #? # dump _test-output-stream {{{
656 #? (write-stream 2 _test-output-stream)
658 #? (rewind-stream _test-output-stream)
661 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg/0")
662 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg/1")
663 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg/2")
664 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg/3")
665 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg/4")
666 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg/5")
667 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg/6")
668 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg/7")
674 test-function-with-redefined-name:
679 (clear-stream _test-input-stream)
680 (clear-stream $_test-input-buffered-file->buffer)
681 (clear-stream _test-output-stream)
682 (clear-stream $_test-output-buffered-file->buffer)
683 (clear-stream _test-error-stream)
684 (clear-stream $_test-error-buffered-file->buffer)
685 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
689 (tailor-exit-descriptor %edx 0x10)
691 (write _test-input-stream "fn foo {\n")
692 (write _test-input-stream "}\n")
693 (write _test-input-stream "fn foo {\n")
694 (write _test-input-stream "}\n")
696 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
697 # registers except esp clobbered at this point
700 (flush _test-output-buffered-file)
701 (flush _test-error-buffered-file)
702 #? # dump _test-error-stream {{{
704 #? (write-stream 2 _test-error-stream)
706 #? (rewind-stream _test-error-stream)
709 (check-stream-equal _test-output-stream "" "F - test-function-with-redefined-name: output should be empty")
710 (check-next-stream-line-equal _test-error-stream "fn foo defined more than once" "F - test-function-with-redefined-name: error message")
711 # check that stop(1) was called
712 (check-ints-equal *(edx+4) 2 "F - test-function-with-redefined-name: exit status")
713 # don't restore from ebp
714 81 0/subop/add %esp 8/imm32
719 test-function-with-redefined-name-2:
724 (clear-stream _test-input-stream)
725 (clear-stream $_test-input-buffered-file->buffer)
726 (clear-stream _test-output-stream)
727 (clear-stream $_test-output-buffered-file->buffer)
728 (clear-stream _test-error-stream)
729 (clear-stream $_test-error-buffered-file->buffer)
730 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
734 (tailor-exit-descriptor %edx 0x10)
736 (write _test-input-stream "fn foo {\n")
737 (write _test-input-stream "}\n")
738 (write _test-input-stream "sig foo\n")
740 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
741 # registers except esp clobbered at this point
744 (flush _test-output-buffered-file)
745 (flush _test-error-buffered-file)
746 #? # dump _test-error-stream {{{
748 #? (write-stream 2 _test-error-stream)
750 #? (rewind-stream _test-error-stream)
753 (check-stream-equal _test-output-stream "" "F - test-function-with-redefined-name-2: output should be empty")
754 (check-next-stream-line-equal _test-error-stream "fn foo defined more than once" "F - test-function-with-redefined-name-2: error message")
755 # check that stop(1) was called
756 (check-ints-equal *(edx+4) 2 "F - test-function-with-redefined-name-2: exit status")
757 # don't restore from ebp
758 81 0/subop/add %esp 8/imm32
763 test-function-with-redefined-name-3:
768 (clear-stream _test-input-stream)
769 (clear-stream $_test-input-buffered-file->buffer)
770 (clear-stream _test-output-stream)
771 (clear-stream $_test-output-buffered-file->buffer)
772 (clear-stream _test-error-stream)
773 (clear-stream $_test-error-buffered-file->buffer)
774 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
778 (tailor-exit-descriptor %edx 0x10)
780 (write _test-input-stream "sig foo\n")
781 (write _test-input-stream "fn foo {\n")
782 (write _test-input-stream "}\n")
784 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
785 # registers except esp clobbered at this point
788 (flush _test-output-buffered-file)
789 (flush _test-error-buffered-file)
790 #? # dump _test-error-stream {{{
792 #? (write-stream 2 _test-error-stream)
794 #? (rewind-stream _test-error-stream)
797 (check-stream-equal _test-output-stream "" "F - test-function-with-redefined-name-3: output should be empty")
798 (check-next-stream-line-equal _test-error-stream "fn foo defined more than once" "F - test-function-with-redefined-name-3: error message")
799 # check that stop(1) was called
800 (check-ints-equal *(edx+4) 2 "F - test-function-with-redefined-name-3: exit status")
801 # don't restore from ebp
802 81 0/subop/add %esp 8/imm32
807 test-function-with-inout-in-register:
812 (clear-stream _test-input-stream)
813 (clear-stream $_test-input-buffered-file->buffer)
814 (clear-stream _test-output-stream)
815 (clear-stream $_test-output-buffered-file->buffer)
816 (clear-stream _test-error-stream)
817 (clear-stream $_test-error-buffered-file->buffer)
818 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
822 (tailor-exit-descriptor %edx 0x10)
824 (write _test-input-stream "fn foo x/eax: int {\n")
825 (write _test-input-stream "}\n")
827 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
828 # registers except esp clobbered at this point
831 (flush _test-output-buffered-file)
832 (flush _test-error-buffered-file)
833 #? # dump _test-error-stream {{{
835 #? (write-stream 2 _test-error-stream)
837 #? (rewind-stream _test-error-stream)
840 (check-stream-equal _test-output-stream "" "F - test-function-with-inout-in-register: output should be empty")
841 (check-next-stream-line-equal _test-error-stream "fn foo: function inout 'x' cannot be in a register" "F - test-function-with-inout-in-register: error message")
842 # check that stop(1) was called
843 (check-ints-equal *(edx+4) 2 "F - test-function-with-inout-in-register: exit status")
844 # don't restore from ebp
845 81 0/subop/add %esp 8/imm32
850 test-function-with-addr-output:
855 (clear-stream _test-input-stream)
856 (clear-stream $_test-input-buffered-file->buffer)
857 (clear-stream _test-output-stream)
858 (clear-stream $_test-output-buffered-file->buffer)
859 (clear-stream _test-error-stream)
860 (clear-stream $_test-error-buffered-file->buffer)
861 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
865 (tailor-exit-descriptor %edx 0x10)
867 (write _test-input-stream "fn foo -> _/eax: (addr int) {\n")
868 (write _test-input-stream "}\n")
870 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
871 # registers except esp clobbered at this point
874 (flush _test-output-buffered-file)
875 (flush _test-error-buffered-file)
876 #? # dump _test-error-stream {{{
878 #? (write-stream 2 _test-error-stream)
880 #? (rewind-stream _test-error-stream)
883 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-output: output should be empty")
884 (check-next-stream-line-equal _test-error-stream "fn foo: output cannot have an addr type; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-output: error message")
885 # check that stop(1) was called
886 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-output: exit status")
887 # don't restore from ebp
888 81 0/subop/add %esp 8/imm32
893 test-function-with-addr-inout:
898 (clear-stream _test-input-stream)
899 (clear-stream $_test-input-buffered-file->buffer)
900 (clear-stream _test-output-stream)
901 (clear-stream $_test-output-buffered-file->buffer)
902 (clear-stream _test-error-stream)
903 (clear-stream $_test-error-buffered-file->buffer)
904 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
908 (tailor-exit-descriptor %edx 0x10)
910 (write _test-input-stream "fn foo a: (addr addr int) {\n")
911 (write _test-input-stream "}\n")
913 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
914 # registers except esp clobbered at this point
917 (flush _test-output-buffered-file)
918 (flush _test-error-buffered-file)
919 #? # dump _test-error-stream {{{
921 #? (write-stream 2 _test-error-stream)
923 #? (rewind-stream _test-error-stream)
926 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-inout: output should be empty")
927 (check-next-stream-line-equal _test-error-stream "fn foo: inout 'a' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-inout: error message")
928 # check that stop(1) was called
929 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-inout: exit status")
930 # don't restore from ebp
931 81 0/subop/add %esp 8/imm32
936 test-function-with-addr-inout-2:
941 (clear-stream _test-input-stream)
942 (clear-stream $_test-input-buffered-file->buffer)
943 (clear-stream _test-output-stream)
944 (clear-stream $_test-output-buffered-file->buffer)
945 (clear-stream _test-error-stream)
946 (clear-stream $_test-error-buffered-file->buffer)
947 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
951 (tailor-exit-descriptor %edx 0x10)
953 (write _test-input-stream "fn foo a: (addr array addr int) {\n")
954 (write _test-input-stream "}\n")
956 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
957 # registers except esp clobbered at this point
960 (flush _test-output-buffered-file)
961 (flush _test-error-buffered-file)
962 #? # dump _test-error-stream {{{
964 #? (write-stream 2 _test-error-stream)
966 #? (rewind-stream _test-error-stream)
969 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-inout-2: output should be empty")
970 (check-next-stream-line-equal _test-error-stream "fn foo: inout 'a' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-inout-2: error message")
971 # check that stop(1) was called
972 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-inout-2: exit status")
973 # don't restore from ebp
974 81 0/subop/add %esp 8/imm32
979 test-function-with-addr-inout-3:
984 (clear-stream _test-input-stream)
985 (clear-stream $_test-input-buffered-file->buffer)
986 (clear-stream _test-output-stream)
987 (clear-stream $_test-output-buffered-file->buffer)
988 (clear-stream _test-error-stream)
989 (clear-stream $_test-error-buffered-file->buffer)
990 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
994 (tailor-exit-descriptor %edx 0x10)
996 (write _test-input-stream "fn foo a: (addr array (addr int) 3) {\n")
997 (write _test-input-stream "}\n")
999 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1000 # registers except esp clobbered at this point
1002 89/<- %edx 4/r32/esp
1003 (flush _test-output-buffered-file)
1004 (flush _test-error-buffered-file)
1005 #? # dump _test-error-stream {{{
1007 #? (write-stream 2 _test-error-stream)
1009 #? (rewind-stream _test-error-stream)
1012 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-inout-3: output should be empty")
1013 (check-next-stream-line-equal _test-error-stream "fn foo: inout 'a' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-inout-3: error message")
1014 # check that stop(1) was called
1015 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-inout-3: exit status")
1016 # don't restore from ebp
1017 81 0/subop/add %esp 8/imm32
1022 test-function-with-addr-inout-4:
1025 89/<- %ebp 4/r32/esp
1027 (clear-stream _test-input-stream)
1028 (clear-stream $_test-input-buffered-file->buffer)
1029 (clear-stream _test-output-stream)
1030 (clear-stream $_test-output-buffered-file->buffer)
1031 (clear-stream _test-error-stream)
1032 (clear-stream $_test-error-buffered-file->buffer)
1033 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1036 89/<- %edx 4/r32/esp
1037 (tailor-exit-descriptor %edx 0x10)
1039 (write _test-input-stream "fn foo a: (array (addr int) 3) {\n")
1040 (write _test-input-stream "}\n")
1042 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1043 # registers except esp clobbered at this point
1045 89/<- %edx 4/r32/esp
1046 (flush _test-output-buffered-file)
1047 (flush _test-error-buffered-file)
1048 #? # dump _test-error-stream {{{
1050 #? (write-stream 2 _test-error-stream)
1052 #? (rewind-stream _test-error-stream)
1055 (check-stream-equal _test-output-stream "" "F - test-function-with-addr-inout-4: output should be empty")
1056 (check-next-stream-line-equal _test-error-stream "fn foo: inout 'a' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function" "F - test-function-with-addr-inout-4: error message")
1057 # check that stop(1) was called
1058 (check-ints-equal *(edx+4) 2 "F - test-function-with-addr-inout-4: exit status")
1059 # don't restore from ebp
1060 81 0/subop/add %esp 8/imm32
1065 # 'main' is an exception
1066 test-function-main-with-addr-inout:
1069 89/<- %ebp 4/r32/esp
1071 (clear-stream _test-input-stream)
1072 (clear-stream $_test-input-buffered-file->buffer)
1073 (clear-stream _test-output-stream)
1074 (clear-stream $_test-output-buffered-file->buffer)
1076 (write _test-input-stream "fn main a: (addr addr int) {\n")
1077 (write _test-input-stream "}\n")
1079 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
1080 (flush _test-output-buffered-file)
1083 89/<- %esp 5/r32/ebp
1087 # 'lookup' is an exception, but only in signatures
1088 test-signature-lookup-with-addr-inout:
1091 89/<- %ebp 4/r32/esp
1093 (clear-stream _test-input-stream)
1094 (clear-stream $_test-input-buffered-file->buffer)
1095 (clear-stream _test-output-stream)
1096 (clear-stream $_test-output-buffered-file->buffer)
1098 (write _test-input-stream "sig lookup h: (handle _T) -> _/eax: (addr _T)\n")
1100 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
1101 (flush _test-output-buffered-file)
1104 89/<- %esp 5/r32/ebp
1108 test-convert-function-with-arg-and-body:
1111 89/<- %ebp 4/r32/esp
1113 (clear-stream _test-input-stream)
1114 (clear-stream $_test-input-buffered-file->buffer)
1115 (clear-stream _test-output-stream)
1116 (clear-stream $_test-output-buffered-file->buffer)
1118 (write _test-input-stream "fn foo n: int {\n")
1119 (write _test-input-stream " increment n\n")
1120 (write _test-input-stream "}\n")
1122 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
1123 (flush _test-output-buffered-file)
1124 #? # dump _test-output-stream {{{
1126 #? (write-stream 2 _test-output-stream)
1128 #? (rewind-stream _test-output-stream)
1131 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg-and-body/0")
1132 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg-and-body/1")
1133 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg-and-body/2")
1134 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg-and-body/3")
1135 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-arg-and-body/4")
1136 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-arg-and-body/5")
1137 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-arg-and-body/6")
1138 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-arg-and-body/7")
1139 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-arg-and-body/8")
1140 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg-and-body/9")
1141 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg-and-body/10")
1142 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg-and-body/11")
1143 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg-and-body/12")
1145 89/<- %esp 5/r32/ebp
1149 test-convert-function-distinguishes-args:
1152 89/<- %ebp 4/r32/esp
1154 (clear-stream _test-input-stream)
1155 (clear-stream $_test-input-buffered-file->buffer)
1156 (clear-stream _test-output-stream)
1157 (clear-stream $_test-output-buffered-file->buffer)
1159 (write _test-input-stream "fn foo a: int, b: int {\n")
1160 (write _test-input-stream " increment b\n")
1161 (write _test-input-stream "}\n")
1163 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
1164 (flush _test-output-buffered-file)
1165 #? # dump _test-output-stream {{{
1167 #? (write-stream 2 _test-output-stream)
1169 #? (rewind-stream _test-output-stream)
1172 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-distinguishes-args/0")
1173 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-distinguishes-args/1")
1174 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-distinguishes-args/2")
1175 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-distinguishes-args/3")
1176 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-distinguishes-args/4")
1177 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-distinguishes-args/5")
1178 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x0000000c)" "F - test-convert-function-distinguishes-args/6")
1179 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-distinguishes-args/7")
1180 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-distinguishes-args/8")
1181 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-distinguishes-args/9")
1182 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-distinguishes-args/10")
1183 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-distinguishes-args/11")
1184 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-distinguishes-args/12")
1186 89/<- %esp 5/r32/ebp
1190 test-convert-function-with-return-literal:
1193 89/<- %ebp 4/r32/esp
1195 (clear-stream _test-input-stream)
1196 (clear-stream $_test-input-buffered-file->buffer)
1197 (clear-stream _test-output-stream)
1198 (clear-stream $_test-output-buffered-file->buffer)
1200 (write _test-input-stream "fn foo -> _/eax: int {\n")
1201 (write _test-input-stream " return 0\n")
1202 (write _test-input-stream "}\n")
1204 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
1205 (flush _test-output-buffered-file)
1206 #? # dump _test-output-stream {{{
1208 #? (write-stream 2 _test-output-stream)
1210 #? (rewind-stream _test-output-stream)
1213 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-literal/0")
1214 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-literal/1")
1215 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-literal/2")
1216 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-literal/3")
1217 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-literal/4")
1218 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-literal/5")
1219 (check-next-stream-line-equal _test-output-stream " c7 0/subop/copy %eax 0/imm32" "F - test-convert-function-with-return-literal/6")
1220 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-literal/7")
1221 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-literal/8")
1222 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-literal/9")
1223 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-literal/10")
1224 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-literal/11")
1225 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-literal/12")
1226 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-literal/13")
1228 89/<- %esp 5/r32/ebp
1232 test-convert-function-with-return:
1235 89/<- %ebp 4/r32/esp
1237 (clear-stream _test-input-stream)
1238 (clear-stream $_test-input-buffered-file->buffer)
1239 (clear-stream _test-output-stream)
1240 (clear-stream $_test-output-buffered-file->buffer)
1242 (write _test-input-stream "fn foo -> _/eax: int {\n")
1243 (write _test-input-stream " var y: int\n")
1244 (write _test-input-stream " return y\n")
1245 (write _test-input-stream "}\n")
1247 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
1248 (flush _test-output-buffered-file)
1249 #? # dump _test-output-stream {{{
1251 #? (write-stream 2 _test-output-stream)
1253 #? (rewind-stream _test-output-stream)
1256 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return/0")
1257 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return/1")
1258 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return/2")
1259 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return/3")
1260 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return/4")
1261 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return/5")
1262 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-return/6") # y
1263 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-function-with-return/7")
1264 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return/8")
1265 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return/9")
1266 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return/10")
1267 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return/11")
1268 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return/12")
1269 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return/13")
1270 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return/14")
1271 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return/15")
1273 89/<- %esp 5/r32/ebp
1277 test-convert-function-with-return-float:
1280 89/<- %ebp 4/r32/esp
1282 (clear-stream _test-input-stream)
1283 (clear-stream $_test-input-buffered-file->buffer)
1284 (clear-stream _test-output-stream)
1285 (clear-stream $_test-output-buffered-file->buffer)
1287 (write _test-input-stream "fn foo -> _/xmm0: float {\n")
1288 (write _test-input-stream " var y: float\n")
1289 (write _test-input-stream " return y\n")
1290 (write _test-input-stream "}\n")
1292 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
1293 (flush _test-output-buffered-file)
1294 #? # dump _test-output-stream {{{
1296 #? (write-stream 2 _test-output-stream)
1298 #? (rewind-stream _test-output-stream)
1301 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return/0")
1302 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return/1")
1303 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return/2")
1304 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return/3")
1305 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return/4")
1306 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return/5")
1307 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-return/6") # y
1308 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *(ebp+0xfffffffc) 0x00000000/x32" "F - test-convert-function-with-return/7")
1309 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return/8")
1310 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return/9")
1311 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return/10")
1312 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return/11")
1313 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return/12")
1314 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return/13")
1315 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return/14")
1316 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return/15")
1318 89/<- %esp 5/r32/ebp
1322 test-convert-function-with-return-register:
1325 89/<- %ebp 4/r32/esp
1327 (clear-stream _test-input-stream)
1328 (clear-stream $_test-input-buffered-file->buffer)
1329 (clear-stream _test-output-stream)
1330 (clear-stream $_test-output-buffered-file->buffer)
1332 (write _test-input-stream "fn foo -> _/eax: int {\n")
1333 (write _test-input-stream " var y/eax: int <- copy 3\n")
1334 (write _test-input-stream " return y\n")
1335 (write _test-input-stream "}\n")
1337 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
1338 (flush _test-output-buffered-file)
1339 #? # dump _test-output-stream {{{
1341 #? (write-stream 2 _test-output-stream)
1343 #? (rewind-stream _test-output-stream)
1346 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-register/0")
1347 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-register/1")
1348 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-register/2")
1349 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-register/3")
1350 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-register/4")
1351 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-register/5")
1352 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-return-register/6")
1353 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-convert-function-with-return-register/7")
1354 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-function-with-return-register/8")
1355 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-return-register/9")
1356 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-register/10")
1357 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-register/11")
1358 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-register/12")
1359 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-register/13")
1360 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-register/14")
1361 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-register/15")
1362 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-register/16")
1364 89/<- %esp 5/r32/ebp
1368 test-function-with-output-without-register:
1371 89/<- %ebp 4/r32/esp
1373 (clear-stream _test-input-stream)
1374 (clear-stream $_test-input-buffered-file->buffer)
1375 (clear-stream _test-output-stream)
1376 (clear-stream $_test-output-buffered-file->buffer)
1377 (clear-stream _test-error-stream)
1378 (clear-stream $_test-error-buffered-file->buffer)
1379 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1382 89/<- %edx 4/r32/esp
1383 (tailor-exit-descriptor %edx 0x10)
1385 (write _test-input-stream "fn foo -> _: int {\n")
1386 (write _test-input-stream "}\n")
1388 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1389 # registers except esp clobbered at this point
1391 89/<- %edx 4/r32/esp
1392 (flush _test-output-buffered-file)
1393 (flush _test-error-buffered-file)
1394 #? # dump _test-error-stream {{{
1396 #? (write-stream 2 _test-error-stream)
1398 #? (rewind-stream _test-error-stream)
1401 (check-stream-equal _test-output-stream "" "F - test-function-with-output-without-register: output should be empty")
1402 (check-next-stream-line-equal _test-error-stream "fn foo: function output '_' must be in a register, in instruction 'fn foo -> _: int {" "F - test-function-with-output-without-register: error message")
1403 # check that stop(1) was called
1404 (check-ints-equal *(edx+4) 2 "F - test-function-with-output-without-register: exit status")
1405 # don't restore from ebp
1406 81 0/subop/add %esp 8/imm32
1411 test-function-with-outputs-in-conflicting-registers:
1414 89/<- %ebp 4/r32/esp
1416 (clear-stream _test-input-stream)
1417 (clear-stream $_test-input-buffered-file->buffer)
1418 (clear-stream _test-output-stream)
1419 (clear-stream $_test-output-buffered-file->buffer)
1420 (clear-stream _test-error-stream)
1421 (clear-stream $_test-error-buffered-file->buffer)
1422 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1425 89/<- %edx 4/r32/esp
1426 (tailor-exit-descriptor %edx 0x10)
1428 (write _test-input-stream "fn foo -> _/eax: int, _/eax: int {\n")
1429 (write _test-input-stream "}\n")
1431 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1432 # registers except esp clobbered at this point
1434 89/<- %edx 4/r32/esp
1435 (flush _test-output-buffered-file)
1436 (flush _test-error-buffered-file)
1437 #? # dump _test-error-stream {{{
1439 #? (write-stream 2 _test-error-stream)
1441 #? (rewind-stream _test-error-stream)
1444 (check-stream-equal _test-output-stream "" "F - test-function-with-outputs-in-conflicting-registers: output should be empty")
1445 (check-next-stream-line-equal _test-error-stream "fn foo: outputs must be in unique registers" "F - test-function-with-outputs-in-conflicting-registers: error message")
1446 # check that stop(1) was called
1447 (check-ints-equal *(edx+4) 2 "F - test-function-with-outputs-in-conflicting-registers: exit status")
1448 # don't restore from ebp
1449 81 0/subop/add %esp 8/imm32
1454 test-function-with-named-output:
1457 89/<- %ebp 4/r32/esp
1459 (clear-stream _test-input-stream)
1460 (clear-stream $_test-input-buffered-file->buffer)
1461 (clear-stream _test-output-stream)
1462 (clear-stream $_test-output-buffered-file->buffer)
1463 (clear-stream _test-error-stream)
1464 (clear-stream $_test-error-buffered-file->buffer)
1465 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1468 89/<- %edx 4/r32/esp
1469 (tailor-exit-descriptor %edx 0x10)
1471 (write _test-input-stream "fn foo -> x/eax: int {\n")
1472 (write _test-input-stream " return 0\n")
1473 (write _test-input-stream "}\n")
1475 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1476 # registers except esp clobbered at this point
1478 89/<- %edx 4/r32/esp
1479 (flush _test-output-buffered-file)
1480 (flush _test-error-buffered-file)
1481 #? # dump _test-error-stream {{{
1483 #? (write-stream 2 _test-error-stream)
1485 #? (rewind-stream _test-error-stream)
1488 (check-stream-equal _test-output-stream "" "F - test-function-with-named-output: output should be empty")
1489 (check-next-stream-line-equal _test-error-stream "fn foo: function outputs cannot be named; rename 'x' in the header to '_'" "F - test-function-with-named-output: error message")
1490 # check that stop(1) was called
1491 (check-ints-equal *(edx+4) 2 "F - test-function-with-named-output: exit status")
1492 # don't restore from ebp
1493 81 0/subop/add %esp 8/imm32
1498 test-return-with-wrong-type:
1501 89/<- %ebp 4/r32/esp
1503 (clear-stream _test-input-stream)
1504 (clear-stream $_test-input-buffered-file->buffer)
1505 (clear-stream _test-output-stream)
1506 (clear-stream $_test-output-buffered-file->buffer)
1507 (clear-stream _test-error-stream)
1508 (clear-stream $_test-error-buffered-file->buffer)
1509 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1512 89/<- %edx 4/r32/esp
1513 (tailor-exit-descriptor %edx 0x10)
1515 (write _test-input-stream "fn foo -> _/eax: int {\n")
1516 (write _test-input-stream " var x/eax: boolean <- copy 0\n")
1517 (write _test-input-stream " return x\n")
1518 (write _test-input-stream "}\n")
1520 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1521 # registers except esp clobbered at this point
1523 89/<- %edx 4/r32/esp
1524 (flush _test-output-buffered-file)
1525 (flush _test-error-buffered-file)
1526 #? # dump _test-error-stream {{{
1528 #? (write-stream 2 _test-error-stream)
1530 #? (rewind-stream _test-error-stream)
1533 (check-stream-equal _test-output-stream "" "F - test-return-with-wrong-type: output should be empty")
1534 (check-next-stream-line-equal _test-error-stream "fn foo: return: 'x' has the wrong type" "F - test-return-with-wrong-type: error message")
1535 # check that stop(1) was called
1536 (check-ints-equal *(edx+4) 2 "F - test-return-with-wrong-type: exit status")
1537 # don't restore from ebp
1538 81 0/subop/add %esp 8/imm32
1543 test-missing-return:
1546 89/<- %ebp 4/r32/esp
1548 (clear-stream _test-input-stream)
1549 (clear-stream $_test-input-buffered-file->buffer)
1550 (clear-stream _test-output-stream)
1551 (clear-stream $_test-output-buffered-file->buffer)
1552 (clear-stream _test-error-stream)
1553 (clear-stream $_test-error-buffered-file->buffer)
1554 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1557 89/<- %edx 4/r32/esp
1558 (tailor-exit-descriptor %edx 0x10)
1560 (write _test-input-stream "fn foo -> _/eax: int {\n")
1561 (write _test-input-stream " var x/eax: boolean <- copy 0\n")
1562 (write _test-input-stream "}\n")
1564 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1565 # registers except esp clobbered at this point
1567 89/<- %edx 4/r32/esp
1568 (flush _test-output-buffered-file)
1569 (flush _test-error-buffered-file)
1570 #? # dump _test-error-stream {{{
1572 #? (write-stream 2 _test-error-stream)
1574 #? (rewind-stream _test-error-stream)
1577 (check-stream-equal _test-output-stream "" "F - test-missing-return: output should be empty")
1578 (check-next-stream-line-equal _test-error-stream "fn foo: final statement should be a 'return'" "F - test-missing-return: error message")
1579 # check that stop(1) was called
1580 (check-ints-equal *(edx+4) 2 "F - test-missing-return: exit status")
1581 # don't restore from ebp
1582 81 0/subop/add %esp 8/imm32
1587 test-missing-return-2:
1590 89/<- %ebp 4/r32/esp
1592 (clear-stream _test-input-stream)
1593 (clear-stream $_test-input-buffered-file->buffer)
1594 (clear-stream _test-output-stream)
1595 (clear-stream $_test-output-buffered-file->buffer)
1596 (clear-stream _test-error-stream)
1597 (clear-stream $_test-error-buffered-file->buffer)
1598 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1601 89/<- %edx 4/r32/esp
1602 (tailor-exit-descriptor %edx 0x10)
1604 (write _test-input-stream "fn foo -> _/eax: int {\n")
1605 (write _test-input-stream "}\n")
1607 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1608 # registers except esp clobbered at this point
1610 89/<- %edx 4/r32/esp
1611 (flush _test-output-buffered-file)
1612 (flush _test-error-buffered-file)
1613 #? # dump _test-error-stream {{{
1615 #? (write-stream 2 _test-error-stream)
1617 #? (rewind-stream _test-error-stream)
1620 (check-stream-equal _test-output-stream "" "F - test-missing-return-2: output should be empty")
1621 (check-next-stream-line-equal _test-error-stream "fn foo: final statement should be a 'return'" "F - test-missing-return-2: error message")
1622 # check that stop(1) was called
1623 (check-ints-equal *(edx+4) 2 "F - test-missing-return-2: exit status")
1624 # don't restore from ebp
1625 81 0/subop/add %esp 8/imm32
1630 test-early-exit-without-return:
1633 89/<- %ebp 4/r32/esp
1635 (clear-stream _test-input-stream)
1636 (clear-stream $_test-input-buffered-file->buffer)
1637 (clear-stream _test-output-stream)
1638 (clear-stream $_test-output-buffered-file->buffer)
1639 (clear-stream _test-error-stream)
1640 (clear-stream $_test-error-buffered-file->buffer)
1641 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1644 89/<- %edx 4/r32/esp
1645 (tailor-exit-descriptor %edx 0x10)
1647 (write _test-input-stream "fn foo -> _/eax: int {\n")
1648 (write _test-input-stream " break\n")
1649 (write _test-input-stream " return 0\n")
1650 (write _test-input-stream "}\n")
1652 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1653 # registers except esp clobbered at this point
1655 89/<- %edx 4/r32/esp
1656 (flush _test-output-buffered-file)
1657 (flush _test-error-buffered-file)
1658 #? # dump _test-error-stream {{{
1660 #? (write-stream 2 _test-error-stream)
1662 #? (rewind-stream _test-error-stream)
1665 (check-stream-equal _test-output-stream "" "F - test-early-exit-without-return: output should be empty")
1666 (check-next-stream-line-equal _test-error-stream "fn foo has outputs, so you cannot 'break' out of the outermost block. Use 'return'." "F - test-early-exit-without-return: error message")
1667 # check that stop(1) was called
1668 (check-ints-equal *(edx+4) 2 "F - test-early-exit-without-return: exit status")
1669 # don't restore from ebp
1670 81 0/subop/add %esp 8/imm32
1675 test-return-with-too-few-inouts:
1678 89/<- %ebp 4/r32/esp
1680 (clear-stream _test-input-stream)
1681 (clear-stream $_test-input-buffered-file->buffer)
1682 (clear-stream _test-output-stream)
1683 (clear-stream $_test-output-buffered-file->buffer)
1684 (clear-stream _test-error-stream)
1685 (clear-stream $_test-error-buffered-file->buffer)
1686 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1689 89/<- %edx 4/r32/esp
1690 (tailor-exit-descriptor %edx 0x10)
1692 (write _test-input-stream "fn foo -> _/eax: int {\n")
1693 (write _test-input-stream " return\n")
1694 (write _test-input-stream "}\n")
1696 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1697 # registers except esp clobbered at this point
1699 89/<- %edx 4/r32/esp
1700 (flush _test-output-buffered-file)
1701 (flush _test-error-buffered-file)
1702 #? # dump _test-error-stream {{{
1704 #? (write-stream 2 _test-error-stream)
1706 #? (rewind-stream _test-error-stream)
1709 (check-stream-equal _test-output-stream "" "F - test-return-with-too-few-inouts: output should be empty")
1710 (check-next-stream-line-equal _test-error-stream "fn foo: return: too few inouts" "F - test-return-with-too-few-inouts: error message")
1711 # check that stop(1) was called
1712 (check-ints-equal *(edx+4) 2 "F - test-return-with-too-few-inouts: exit status")
1713 # don't restore from ebp
1714 81 0/subop/add %esp 8/imm32
1719 test-return-with-too-many-inouts:
1722 89/<- %ebp 4/r32/esp
1724 (clear-stream _test-input-stream)
1725 (clear-stream $_test-input-buffered-file->buffer)
1726 (clear-stream _test-output-stream)
1727 (clear-stream $_test-output-buffered-file->buffer)
1728 (clear-stream _test-error-stream)
1729 (clear-stream $_test-error-buffered-file->buffer)
1730 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1733 89/<- %edx 4/r32/esp
1734 (tailor-exit-descriptor %edx 0x10)
1736 (write _test-input-stream "fn foo -> _/eax: int {\n")
1737 (write _test-input-stream " return 0, 0\n")
1738 (write _test-input-stream "}\n")
1740 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1741 # registers except esp clobbered at this point
1743 89/<- %edx 4/r32/esp
1744 (flush _test-output-buffered-file)
1745 (flush _test-error-buffered-file)
1746 #? # dump _test-error-stream {{{
1748 #? (write-stream 2 _test-error-stream)
1750 #? (rewind-stream _test-error-stream)
1753 (check-stream-equal _test-output-stream "" "F - test-return-with-too-many-inouts: output should be empty")
1754 (check-next-stream-line-equal _test-error-stream "fn foo: return: too many inouts" "F - test-return-with-too-many-inouts: error message")
1755 # check that stop(1) was called
1756 (check-ints-equal *(edx+4) 2 "F - test-return-with-too-many-inouts: exit status")
1757 # don't restore from ebp
1758 81 0/subop/add %esp 8/imm32
1763 test-return-unavailable-value:
1766 89/<- %ebp 4/r32/esp
1768 (clear-stream _test-input-stream)
1769 (clear-stream $_test-input-buffered-file->buffer)
1770 (clear-stream _test-output-stream)
1771 (clear-stream $_test-output-buffered-file->buffer)
1772 (clear-stream _test-error-stream)
1773 (clear-stream $_test-error-buffered-file->buffer)
1774 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1777 89/<- %edx 4/r32/esp
1778 (tailor-exit-descriptor %edx 0x10)
1780 (write _test-input-stream "fn foo -> _/eax: int, _/ecx: int {\n")
1781 (write _test-input-stream " var x/eax: int <- copy 0\n")
1782 (write _test-input-stream " var y/ecx: int <- copy 0\n")
1783 (write _test-input-stream " return y, x\n")
1784 (write _test-input-stream "}\n")
1786 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1787 # registers except esp clobbered at this point
1789 89/<- %edx 4/r32/esp
1790 (flush _test-output-buffered-file)
1791 (flush _test-error-buffered-file)
1792 #? # dump _test-error-stream {{{
1794 #? (write-stream 2 _test-error-stream)
1796 #? (rewind-stream _test-error-stream)
1799 (check-stream-equal _test-output-stream "" "F - test-return-unavailable-value: output should be empty")
1800 (check-next-stream-line-equal _test-error-stream "fn foo: return: 'x' is no longer available" "F - test-return-unavailable-value: error message")
1801 # check that stop(1) was called
1802 (check-ints-equal *(edx+4) 2 "F - test-return-unavailable-value: exit status")
1803 # don't restore from ebp
1804 81 0/subop/add %esp 8/imm32
1809 test-return-literal-to-float:
1812 89/<- %ebp 4/r32/esp
1814 (clear-stream _test-input-stream)
1815 (clear-stream $_test-input-buffered-file->buffer)
1816 (clear-stream _test-output-stream)
1817 (clear-stream $_test-output-buffered-file->buffer)
1818 (clear-stream _test-error-stream)
1819 (clear-stream $_test-error-buffered-file->buffer)
1820 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1823 89/<- %edx 4/r32/esp
1824 (tailor-exit-descriptor %edx 0x10)
1826 (write _test-input-stream "fn foo -> _/xmm0: float {\n")
1827 (write _test-input-stream " return 0\n")
1828 (write _test-input-stream "}\n")
1830 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1831 # registers except esp clobbered at this point
1833 89/<- %edx 4/r32/esp
1834 (flush _test-output-buffered-file)
1835 (flush _test-error-buffered-file)
1836 #? # dump _test-error-stream {{{
1838 #? (write-stream 2 _test-error-stream)
1840 #? (rewind-stream _test-error-stream)
1843 (check-stream-equal _test-output-stream "" "F - test-return-literal-to-float: output should be empty")
1844 (check-next-stream-line-equal _test-error-stream "fn foo: return: cannot copy literal '0' to float" "F - test-return-literal-to-float: error message")
1845 # check that stop(1) was called
1846 (check-ints-equal *(edx+4) 2 "F - test-return-literal-to-float: exit status")
1847 # don't restore from ebp
1848 81 0/subop/add %esp 8/imm32
1853 test-convert-return-with-duplicate-values:
1856 89/<- %ebp 4/r32/esp
1858 (clear-stream _test-input-stream)
1859 (clear-stream $_test-input-buffered-file->buffer)
1860 (clear-stream _test-output-stream)
1861 (clear-stream $_test-output-buffered-file->buffer)
1863 (write _test-input-stream "fn foo -> _/eax: int, _/ecx: int {\n")
1864 (write _test-input-stream " var x/eax: int <- copy 0x34\n")
1865 (write _test-input-stream " return x, x\n")
1866 (write _test-input-stream "}\n")
1868 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
1869 (flush _test-output-buffered-file)
1870 #? # dump _test-output-stream {{{
1872 #? (write-stream 2 _test-output-stream)
1874 #? (rewind-stream _test-output-stream)
1877 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-return-with-duplicate-values/0")
1878 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-return-with-duplicate-values/1")
1879 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-return-with-duplicate-values/2")
1880 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-return-with-duplicate-values/3")
1881 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-return-with-duplicate-values/4")
1882 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-return-with-duplicate-values/5")
1883 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-return-with-duplicate-values/6")
1884 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0x34/imm32" "F - test-convert-return-with-duplicate-values/7")
1885 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-return-with-duplicate-values/8")
1886 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000001/r32" "F - test-convert-return-with-duplicate-values/9")
1887 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-return-with-duplicate-values/10")
1888 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-return-with-duplicate-values/11")
1889 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-return-with-duplicate-values/12")
1890 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-return-with-duplicate-values/13")
1891 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-return-with-duplicate-values/14")
1892 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-return-with-duplicate-values/15")
1893 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-return-with-duplicate-values/16")
1894 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-return-with-duplicate-values/17")
1896 89/<- %esp 5/r32/ebp
1900 test-convert-return-with-duplicate-values-2:
1903 89/<- %ebp 4/r32/esp
1905 (clear-stream _test-input-stream)
1906 (clear-stream $_test-input-buffered-file->buffer)
1907 (clear-stream _test-output-stream)
1908 (clear-stream $_test-output-buffered-file->buffer)
1910 (write _test-input-stream "fn foo -> _/eax: int, _/ecx: int {\n")
1911 (write _test-input-stream " var x/ecx: int <- copy 0x34\n")
1912 (write _test-input-stream " return x, x\n")
1913 (write _test-input-stream "}\n")
1915 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
1916 (flush _test-output-buffered-file)
1917 #? # dump _test-output-stream {{{
1919 #? (write-stream 2 _test-output-stream)
1921 #? (rewind-stream _test-output-stream)
1924 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-return-with-duplicate-values-2/0")
1925 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-return-with-duplicate-values-2/1")
1926 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-return-with-duplicate-values-2/2")
1927 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-return-with-duplicate-values-2/3")
1928 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-return-with-duplicate-values-2/4")
1929 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-return-with-duplicate-values-2/5")
1930 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-return-with-duplicate-values-2/6")
1931 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x34/imm32" "F - test-convert-return-with-duplicate-values-2/7")
1932 (check-next-stream-line-equal _test-output-stream " 8b/-> %ecx 0x00000000/r32" "F - test-convert-return-with-duplicate-values-2/8")
1933 (check-next-stream-line-equal _test-output-stream " 8b/-> %ecx 0x00000001/r32" "F - test-convert-return-with-duplicate-values-2/9")
1934 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-return-with-duplicate-values-2/10")
1935 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-return-with-duplicate-values-2/11")
1936 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-return-with-duplicate-values-2/12")
1937 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-return-with-duplicate-values-2/13")
1938 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-return-with-duplicate-values-2/14")
1939 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-return-with-duplicate-values-2/15")
1940 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-return-with-duplicate-values-2/16")
1941 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-return-with-duplicate-values-2/17")
1943 89/<- %esp 5/r32/ebp
1947 test-stmt-with-unknown-var:
1950 89/<- %ebp 4/r32/esp
1952 (clear-stream _test-input-stream)
1953 (clear-stream $_test-input-buffered-file->buffer)
1954 (clear-stream _test-output-stream)
1955 (clear-stream $_test-output-buffered-file->buffer)
1956 (clear-stream _test-error-stream)
1957 (clear-stream $_test-error-buffered-file->buffer)
1958 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
1961 89/<- %edx 4/r32/esp
1962 (tailor-exit-descriptor %edx 0x10)
1964 (write _test-input-stream "fn foo {\n")
1965 (write _test-input-stream " x <- copy 0x34\n")
1966 (write _test-input-stream "}\n")
1968 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
1969 # registers except esp clobbered at this point
1971 89/<- %edx 4/r32/esp
1972 (flush _test-output-buffered-file)
1973 (flush _test-error-buffered-file)
1974 #? # dump _test-error-stream {{{
1976 #? (write-stream 2 _test-error-stream)
1978 #? (rewind-stream _test-error-stream)
1981 (check-stream-equal _test-output-stream "" "F - test-stmt-with-unknown-var: output should be empty")
1982 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-stmt-with-unknown-var: error message")
1983 # check that stop(1) was called
1984 (check-ints-equal *(edx+4) 2 "F - test-stmt-with-unknown-var: exit status")
1985 # don't restore from ebp
1986 81 0/subop/add %esp 8/imm32
1991 test-stmt-with-missing-var-keyword:
1994 89/<- %ebp 4/r32/esp
1996 (clear-stream _test-input-stream)
1997 (clear-stream $_test-input-buffered-file->buffer)
1998 (clear-stream _test-output-stream)
1999 (clear-stream $_test-output-buffered-file->buffer)
2000 (clear-stream _test-error-stream)
2001 (clear-stream $_test-error-buffered-file->buffer)
2002 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
2005 89/<- %edx 4/r32/esp
2006 (tailor-exit-descriptor %edx 0x10)
2008 (write _test-input-stream "fn foo {\n")
2009 (write _test-input-stream " x: int\n")
2010 (write _test-input-stream "}\n")
2012 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
2013 # registers except esp clobbered at this point
2015 89/<- %edx 4/r32/esp
2016 (flush _test-output-buffered-file)
2017 (flush _test-error-buffered-file)
2018 #? # dump _test-error-stream {{{
2020 #? (write-stream 2 _test-error-stream)
2022 #? (rewind-stream _test-error-stream)
2025 (check-stream-equal _test-output-stream "" "F - test-stmt-with-missing-var-keyword: output should be empty")
2026 (check-next-stream-line-equal _test-error-stream "fn foo: unexpected ':'; did you forget a 'var'?" "F - test-stmt-with-missing-var-keyword: error message")
2027 # check that stop(1) was called
2028 (check-ints-equal *(edx+4) 2 "F - test-stmt-with-missing-var-keyword: exit status")
2029 # don't restore from ebp
2030 81 0/subop/add %esp 8/imm32
2035 test-stmt-with-invalid-identifier:
2038 89/<- %ebp 4/r32/esp
2040 (clear-stream _test-input-stream)
2041 (clear-stream $_test-input-buffered-file->buffer)
2042 (clear-stream _test-output-stream)
2043 (clear-stream $_test-output-buffered-file->buffer)
2044 (clear-stream _test-error-stream)
2045 (clear-stream $_test-error-buffered-file->buffer)
2046 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
2049 89/<- %edx 4/r32/esp
2050 (tailor-exit-descriptor %edx 0x10)
2052 (write _test-input-stream "fn foo {\n")
2053 (write _test-input-stream " 1 <- copy 0x34\n")
2054 (write _test-input-stream "}\n")
2056 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
2057 # registers except esp clobbered at this point
2059 89/<- %edx 4/r32/esp
2060 (flush _test-output-buffered-file)
2061 (flush _test-error-buffered-file)
2062 #? # dump _test-error-stream {{{
2064 #? (write-stream 2 _test-error-stream)
2066 #? (rewind-stream _test-error-stream)
2069 (check-stream-equal _test-output-stream "" "F - test-stmt-with-invalid-identifier: output should be empty")
2070 (check-next-stream-line-equal _test-error-stream "fn foo: invalid identifier '1'" "F - test-stmt-with-invalid-identifier: error message")
2071 # check that stop(1) was called
2072 (check-ints-equal *(edx+4) 2 "F - test-stmt-with-invalid-identifier: exit status")
2073 # don't restore from ebp
2074 81 0/subop/add %esp 8/imm32
2079 test-stmt-with-deref-var:
2082 89/<- %ebp 4/r32/esp
2084 (clear-stream _test-input-stream)
2085 (clear-stream $_test-input-buffered-file->buffer)
2086 (clear-stream _test-output-stream)
2087 (clear-stream $_test-output-buffered-file->buffer)
2088 (clear-stream _test-error-stream)
2089 (clear-stream $_test-error-buffered-file->buffer)
2090 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
2093 89/<- %edx 4/r32/esp
2094 (tailor-exit-descriptor %edx 0x10)
2096 (write _test-input-stream "fn foo {\n")
2097 (write _test-input-stream " *x <- copy 0x34\n")
2098 (write _test-input-stream "}\n")
2100 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
2101 # registers except esp clobbered at this point
2103 89/<- %edx 4/r32/esp
2104 (flush _test-output-buffered-file)
2105 (flush _test-error-buffered-file)
2106 #? # dump _test-error-stream {{{
2108 #? (write-stream 2 _test-error-stream)
2110 #? (rewind-stream _test-error-stream)
2113 (check-stream-equal _test-output-stream "" "F - test-stmt-with-deref-var: output should be empty")
2114 (check-next-stream-line-equal _test-error-stream "fn foo: output '*x' should write to a register, and therefore cannot be dereferenced" "F - test-stmt-with-deref-var: error message")
2115 # check that stop(1) was called
2116 (check-ints-equal *(edx+4) 2 "F - test-stmt-with-deref-var: exit status")
2117 # don't restore from ebp
2118 81 0/subop/add %esp 8/imm32
2123 test-convert-function-with-literal-arg:
2126 89/<- %ebp 4/r32/esp
2128 (clear-stream _test-input-stream)
2129 (clear-stream $_test-input-buffered-file->buffer)
2130 (clear-stream _test-output-stream)
2131 (clear-stream $_test-output-buffered-file->buffer)
2133 (write _test-input-stream "fn foo a: int, b: int -> _/eax: int {\n")
2134 (write _test-input-stream " var result/eax: int <- copy a\n")
2135 (write _test-input-stream " result <- add 1\n")
2136 (write _test-input-stream " return result\n")
2137 (write _test-input-stream "}\n")
2139 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2140 (flush _test-output-buffered-file)
2141 #? # dump _test-output-stream {{{
2143 #? (write-stream 2 _test-output-stream)
2145 #? (rewind-stream _test-output-stream)
2148 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg/0")
2149 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg/1")
2150 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg/2")
2151 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg/3")
2152 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg/4")
2153 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg/5")
2154 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-literal-arg/6")
2155 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-with-literal-arg/7")
2156 (check-next-stream-line-equal _test-output-stream " 05/add-to-eax 1/imm32" "F - test-convert-function-with-literal-arg/8")
2157 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-function-with-literal-arg/9")
2158 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-literal-arg/10")
2159 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-literal-arg/11")
2160 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg/12")
2161 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg/13")
2162 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg/14")
2163 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg/15")
2164 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg/16")
2165 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg/17")
2167 89/<- %esp 5/r32/ebp
2171 test-convert-function-with-literal-arg-2:
2174 89/<- %ebp 4/r32/esp
2176 (clear-stream _test-input-stream)
2177 (clear-stream $_test-input-buffered-file->buffer)
2178 (clear-stream _test-output-stream)
2179 (clear-stream $_test-output-buffered-file->buffer)
2181 (write _test-input-stream "fn foo a: int, b: int -> _/ebx: int {\n")
2182 (write _test-input-stream " var result/ebx: int <- copy a\n")
2183 (write _test-input-stream " result <- add 1\n")
2184 (write _test-input-stream " return result\n")
2185 (write _test-input-stream "}\n")
2187 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2188 (flush _test-output-buffered-file)
2189 #? # dump _test-output-stream {{{
2191 #? (write-stream 2 _test-output-stream)
2193 #? (rewind-stream _test-output-stream)
2196 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg-2/0")
2197 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg-2/1")
2198 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg-2/2")
2199 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg-2/3")
2200 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg-2/4")
2201 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg-2/5")
2202 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-function-with-literal-arg-2/6")
2203 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/7")
2204 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %ebx 1/imm32" "F - test-convert-function-with-literal-arg-2/8")
2205 (check-next-stream-line-equal _test-output-stream " 8b/-> %ebx 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/9")
2206 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-literal-arg-2/10")
2207 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-literal-arg-2/11")
2208 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg-2/12")
2209 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg-2/13")
2210 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg-2/14")
2211 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg-2/15")
2212 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg-2/16")
2213 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg-2/17")
2215 89/<- %esp 5/r32/ebp
2219 test-convert-function-call-with-literal-arg:
2222 89/<- %ebp 4/r32/esp
2224 (clear-stream _test-input-stream)
2225 (clear-stream $_test-input-buffered-file->buffer)
2226 (clear-stream _test-output-stream)
2227 (clear-stream $_test-output-buffered-file->buffer)
2229 (write _test-input-stream "fn main -> _/ebx: int {\n")
2230 (write _test-input-stream " var result/eax: int <- do-add 3 4\n")
2231 (write _test-input-stream " return result\n")
2232 (write _test-input-stream "}\n")
2233 (write _test-input-stream "fn do-add a: int, b: int -> _/eax: int {\n")
2234 (write _test-input-stream " var result/eax: int <- copy a\n")
2235 (write _test-input-stream " result <- add b\n")
2236 (write _test-input-stream " return result\n")
2237 (write _test-input-stream "}\n")
2239 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2240 (flush _test-output-buffered-file)
2241 #? # dump _test-output-stream {{{
2243 #? (write-stream 2 _test-output-stream)
2245 #? (rewind-stream _test-output-stream)
2248 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-literal-arg/0")
2249 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/1")
2250 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/2")
2251 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/3")
2252 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/4")
2253 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-literal-arg/5")
2254 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-literal-arg/6")
2255 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-literal-arg/7")
2256 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/8")
2257 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-local-var-in-reg/9")
2258 (check-next-stream-line-equal _test-output-stream " e9/jump $main:0x00000001:break/disp32" "F - test-convert-function-call-with-literal-arg/10")
2259 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/11")
2260 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-literal-arg/12")
2261 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/13")
2262 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/14")
2263 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/15")
2264 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/16")
2265 (check-next-stream-line-equal _test-output-stream "do-add:" "F - test-convert-function-call-with-literal-arg/17")
2266 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/18")
2267 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/19")
2268 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/20")
2269 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/21")
2270 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:loop:" "F - test-convert-function-call-with-literal-arg/22")
2271 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-literal-arg/23")
2272 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-call-with-literal-arg/24")
2273 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0x0000000c) 0x00000000/r32" "F - test-convert-function-call-with-literal-arg/25")
2274 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-function-call-with-literal-arg/26")
2275 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-call-with-literal-arg/27")
2276 (check-next-stream-line-equal _test-output-stream " e9/jump $do-add:0x00000002:break/disp32" "F - test-convert-function-call-with-literal-arg/28")
2277 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/29")
2278 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:break:" "F - test-convert-function-call-with-literal-arg/30")
2279 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/31")
2280 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/32")
2281 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/33")
2282 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/34")
2284 89/<- %esp 5/r32/ebp
2288 test-convert-function-call-with-literal-string-arg:
2291 89/<- %ebp 4/r32/esp
2293 (clear-stream _test-input-stream)
2294 (clear-stream $_test-input-buffered-file->buffer)
2295 (clear-stream _test-output-stream)
2296 (clear-stream $_test-output-buffered-file->buffer)
2298 (write _test-input-stream "fn foo {\n")
2299 (write _test-input-stream " string-func \"abc\"\n")
2300 (write _test-input-stream "}\n")
2301 (write _test-input-stream "sig string-func in: (addr array byte)\n")
2303 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2305 # not bothering checking output
2307 89/<- %esp 5/r32/ebp
2311 test-convert-function-call-with-literal-string-arg-and-type-parameter-in-signature:
2314 89/<- %ebp 4/r32/esp
2316 (clear-stream _test-input-stream)
2317 (clear-stream $_test-input-buffered-file->buffer)
2318 (clear-stream _test-output-stream)
2319 (clear-stream $_test-output-buffered-file->buffer)
2321 (write _test-input-stream "fn foo {\n")
2322 (write _test-input-stream " string-func \"abc\"\n")
2323 (write _test-input-stream "}\n")
2324 (write _test-input-stream "sig string-func in: (addr array _)\n")
2326 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2328 # not bothering checking output
2330 89/<- %esp 5/r32/ebp
2334 test-convert-function-call-with-null-addr:
2337 89/<- %ebp 4/r32/esp
2339 (clear-stream _test-input-stream)
2340 (clear-stream $_test-input-buffered-file->buffer)
2341 (clear-stream _test-output-stream)
2342 (clear-stream $_test-output-buffered-file->buffer)
2344 (write _test-input-stream "fn foo {\n")
2345 (write _test-input-stream " bar 0\n")
2346 (write _test-input-stream "}\n")
2347 (write _test-input-stream "sig bar in: (addr int)\n")
2349 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2351 # not bothering checking output
2353 89/<- %esp 5/r32/ebp
2357 test-convert-function-call-with-signature:
2360 89/<- %ebp 4/r32/esp
2362 (clear-stream _test-input-stream)
2363 (clear-stream $_test-input-buffered-file->buffer)
2364 (clear-stream _test-output-stream)
2365 (clear-stream $_test-output-buffered-file->buffer)
2367 (write _test-input-stream "fn main -> _/ebx: int {\n")
2368 (write _test-input-stream " var result/eax: int <- do-add 3 4\n")
2369 (write _test-input-stream " return result\n")
2370 (write _test-input-stream "}\n")
2371 (write _test-input-stream "sig do-add a: int, b: int -> _/eax: int\n")
2373 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2374 (flush _test-output-buffered-file)
2375 #? # dump _test-output-stream {{{
2377 #? (write-stream 2 _test-output-stream)
2379 #? (rewind-stream _test-output-stream)
2382 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-signature/0")
2383 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-signature/1")
2384 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-signature/2")
2385 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-signature/3")
2386 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-signature/4")
2387 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-signature/5")
2388 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-literal-arg/6")
2389 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-signature/6")
2390 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/8")
2391 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-local-var-in-reg/9")
2392 (check-next-stream-line-equal _test-output-stream " e9/jump $main:0x00000001:break/disp32" "F - test-convert-function-call-with-literal-arg/10")
2393 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-signature/7")
2394 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-signature/8")
2395 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-signature/9")
2396 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-signature/10")
2397 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-signature/11")
2398 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-signature/12")
2400 89/<- %esp 5/r32/ebp
2404 test-convert-function-with-local-var-in-mem:
2407 89/<- %ebp 4/r32/esp
2409 (clear-stream _test-input-stream)
2410 (clear-stream $_test-input-buffered-file->buffer)
2411 (clear-stream _test-output-stream)
2412 (clear-stream $_test-output-buffered-file->buffer)
2414 (write _test-input-stream "fn foo {\n")
2415 (write _test-input-stream " var x: int\n")
2416 (write _test-input-stream " increment x\n")
2417 (write _test-input-stream "}\n")
2419 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2420 (flush _test-output-buffered-file)
2421 #? # dump _test-output-stream {{{
2423 #? (write-stream 2 _test-output-stream)
2425 #? (rewind-stream _test-output-stream)
2428 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-mem/0")
2429 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-mem/1")
2430 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-mem/2")
2431 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-mem/3")
2432 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem/4")
2433 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-mem/5")
2434 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem/6")
2435 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-mem/7")
2436 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-mem/8")
2437 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem/9")
2438 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-mem/10")
2439 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-mem/11")
2440 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-mem/12")
2441 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-mem/13")
2442 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-mem/14")
2444 89/<- %esp 5/r32/ebp
2448 test-convert-invalid-literal:
2451 89/<- %ebp 4/r32/esp
2453 (clear-stream _test-input-stream)
2454 (clear-stream $_test-input-buffered-file->buffer)
2455 (clear-stream _test-output-stream)
2456 (clear-stream $_test-output-buffered-file->buffer)
2457 (clear-stream _test-error-stream)
2458 (clear-stream $_test-error-buffered-file->buffer)
2459 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
2462 89/<- %edx 4/r32/esp
2463 (tailor-exit-descriptor %edx 0x10)
2465 (write _test-input-stream "fn foo {\n")
2466 (write _test-input-stream " increment 1n\n")
2467 (write _test-input-stream "}\n")
2469 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
2470 # registers except esp clobbered at this point
2472 89/<- %edx 4/r32/esp
2473 (flush _test-output-buffered-file)
2474 (flush _test-error-buffered-file)
2475 #? # dump _test-error-stream {{{
2477 #? (write-stream 2 _test-error-stream)
2479 #? (rewind-stream _test-error-stream)
2482 (check-stream-equal _test-output-stream "" "F - test-convert-invalid-literal: output should be empty")
2483 (check-next-stream-line-equal _test-error-stream "fn foo: variable '1n' cannot begin with a digit (or do you have a typo in a number?)" "F - test-convert-invalid-literal: error message")
2484 # check that stop(1) was called
2485 (check-ints-equal *(edx+4) 2 "F - test-convert-invalid-literal: exit status")
2486 # don't restore from ebp
2487 81 0/subop/add %esp 8/imm32
2492 test-convert-valid-literal-with-metadata:
2495 89/<- %ebp 4/r32/esp
2497 (clear-stream _test-input-stream)
2498 (clear-stream $_test-input-buffered-file->buffer)
2499 (clear-stream _test-output-stream)
2500 (clear-stream $_test-output-buffered-file->buffer)
2502 (write _test-input-stream "fn foo {\n")
2503 (write _test-input-stream " var x/eax: int <- copy 1/abc\n")
2504 (write _test-input-stream "}\n")
2506 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2507 (flush _test-output-buffered-file)
2508 #? # dump _test-output-stream {{{
2510 #? (write-stream 2 _test-output-stream)
2512 #? (rewind-stream _test-output-stream)
2516 89/<- %esp 5/r32/ebp
2520 test-local-var-in-mem-has-no-initializer:
2523 89/<- %ebp 4/r32/esp
2525 (clear-stream _test-input-stream)
2526 (clear-stream $_test-input-buffered-file->buffer)
2527 (clear-stream _test-output-stream)
2528 (clear-stream $_test-output-buffered-file->buffer)
2529 (clear-stream _test-error-stream)
2530 (clear-stream $_test-error-buffered-file->buffer)
2531 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
2534 89/<- %edx 4/r32/esp
2535 (tailor-exit-descriptor %edx 0x10)
2537 (write _test-input-stream "fn foo {\n")
2538 (write _test-input-stream " var x: int <- copy 0\n")
2539 (write _test-input-stream " increment x\n")
2540 (write _test-input-stream "}\n")
2542 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
2543 # registers except esp clobbered at this point
2545 89/<- %edx 4/r32/esp
2546 (flush _test-output-buffered-file)
2547 (flush _test-error-buffered-file)
2548 #? # dump _test-error-stream {{{
2550 #? (write-stream 2 _test-error-stream)
2552 #? (rewind-stream _test-error-stream)
2555 (check-stream-equal _test-output-stream "" "F - test-var-in-mem-has-no-initializer: output should be empty")
2556 (check-next-stream-line-equal _test-error-stream "fn foo: var x: variables on the stack can't take an initializer" "F - test-var-in-mem-has-no-initializer: error message")
2557 # check that stop(1) was called
2558 (check-ints-equal *(edx+4) 2 "F - test-var-in-mem-has-no-initializer: exit status")
2559 # don't restore from ebp
2560 81 0/subop/add %esp 8/imm32
2565 test-convert-function-with-local-var-with-compound-type-in-mem:
2568 89/<- %ebp 4/r32/esp
2570 (clear-stream _test-input-stream)
2571 (clear-stream $_test-input-buffered-file->buffer)
2572 (clear-stream _test-output-stream)
2573 (clear-stream $_test-output-buffered-file->buffer)
2575 (write _test-input-stream "fn foo {\n")
2576 (write _test-input-stream " var x: (addr int)\n")
2577 (write _test-input-stream " copy-to x, 0\n")
2578 (write _test-input-stream "}\n")
2580 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2581 (flush _test-output-buffered-file)
2582 #? # dump _test-output-stream {{{
2584 #? (write-stream 2 _test-output-stream)
2586 #? (rewind-stream _test-output-stream)
2589 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/0")
2590 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/1")
2591 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/2")
2592 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/3")
2593 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-compound-type-in-mem/4")
2594 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/5")
2595 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/6")
2596 (check-next-stream-line-equal _test-output-stream " c7 0/subop/copy *(ebp+0xfffffffc) 0/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/7")
2597 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-with-compound-type-in-mem/8")
2598 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-compound-type-in-mem/9")
2599 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/10")
2600 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/11")
2601 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/12")
2602 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/13")
2603 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-compound-type-in-mem/14")
2605 89/<- %esp 5/r32/ebp
2609 test-convert-function-with-local-var-in-reg:
2612 89/<- %ebp 4/r32/esp
2614 (clear-stream _test-input-stream)
2615 (clear-stream $_test-input-buffered-file->buffer)
2616 (clear-stream _test-output-stream)
2617 (clear-stream $_test-output-buffered-file->buffer)
2619 (write _test-input-stream "fn foo {\n")
2620 (write _test-input-stream " var x/ecx: int <- copy 3\n")
2621 (write _test-input-stream " x <- increment\n")
2622 (write _test-input-stream "}\n")
2624 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2625 (flush _test-output-buffered-file)
2626 #? # dump _test-output-stream {{{
2628 #? (write-stream 2 _test-output-stream)
2630 #? (rewind-stream _test-output-stream)
2633 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-reg/0")
2634 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-reg/1")
2635 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-reg/2")
2636 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-reg/3")
2637 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-reg/4")
2638 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-reg/5")
2639 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-reg/6")
2640 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-local-var-in-reg/7")
2641 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-local-var-in-reg/8")
2642 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-reg/9")
2643 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-reg/10")
2644 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-reg/11")
2645 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-reg/12")
2646 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-reg/13")
2647 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-reg/14")
2648 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-reg/15")
2650 89/<- %esp 5/r32/ebp
2654 test-convert-function-with-local-var-in-same-reg:
2657 89/<- %ebp 4/r32/esp
2659 (clear-stream _test-input-stream)
2660 (clear-stream $_test-input-buffered-file->buffer)
2661 (clear-stream _test-output-stream)
2662 (clear-stream $_test-output-buffered-file->buffer)
2664 (write _test-input-stream "fn foo {\n")
2665 (write _test-input-stream " var x/ecx: int <- copy 3\n")
2666 (write _test-input-stream " var y/ecx: int <- copy x\n")
2667 (write _test-input-stream "}\n")
2669 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2670 (flush _test-output-buffered-file)
2671 #? # dump _test-output-stream {{{
2673 #? (write-stream 2 _test-output-stream)
2675 #? (rewind-stream _test-output-stream)
2678 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-same-reg/0")
2679 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-same-reg/1")
2680 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-same-reg/2")
2681 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-same-reg/3")
2682 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-same-reg/4")
2683 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-same-reg/5")
2684 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-same-reg/6")
2685 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-local-var-in-same-reg/7")
2686 # optimization: skip the second copy
2687 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-same-reg/8")
2688 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-same-reg/9")
2689 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-same-reg/10")
2690 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-same-reg/11")
2691 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-same-reg/12")
2692 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-same-reg/13")
2693 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-same-reg/14")
2695 89/<- %esp 5/r32/ebp
2699 test-convert-function-with-local-var-in-same-reg-dereferenced:
2702 89/<- %ebp 4/r32/esp
2704 (clear-stream _test-input-stream)
2705 (clear-stream $_test-input-buffered-file->buffer)
2706 (clear-stream _test-output-stream)
2707 (clear-stream $_test-output-buffered-file->buffer)
2709 (write _test-input-stream "fn foo {\n")
2710 (write _test-input-stream " var x/ecx: (addr int) <- copy 0\n")
2711 (write _test-input-stream " var y/ecx: int <- copy *x\n")
2712 (write _test-input-stream "}\n")
2714 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2715 (flush _test-output-buffered-file)
2716 #? # dump _test-output-stream {{{
2718 #? (write-stream 2 _test-output-stream)
2720 #? (rewind-stream _test-output-stream)
2723 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/0")
2724 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/1")
2725 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/2")
2726 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/3")
2727 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/4")
2728 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/5")
2729 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/6")
2730 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/7")
2731 (check-next-stream-line-equal _test-output-stream " 8b/-> *ecx 0x00000001/r32" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/8") # don't optimize this away
2732 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/9")
2733 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/10")
2734 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/11")
2735 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/12")
2736 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/13")
2737 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/14")
2738 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-same-reg-dereferenced/15")
2740 89/<- %esp 5/r32/ebp
2744 test-float-var-in-wrong-register:
2747 89/<- %ebp 4/r32/esp
2749 (clear-stream _test-input-stream)
2750 (clear-stream $_test-input-buffered-file->buffer)
2751 (clear-stream _test-output-stream)
2752 (clear-stream $_test-output-buffered-file->buffer)
2753 (clear-stream _test-error-stream)
2754 (clear-stream $_test-error-buffered-file->buffer)
2755 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
2758 89/<- %edx 4/r32/esp
2759 (tailor-exit-descriptor %edx 0x10)
2761 (write _test-input-stream "fn foo {\n")
2762 (write _test-input-stream " var x/eax: int <- copy 0\n")
2763 (write _test-input-stream " var y/eax: float <- convert x\n")
2764 (write _test-input-stream "}\n")
2766 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
2767 # registers except esp clobbered at this point
2769 89/<- %edx 4/r32/esp
2770 (flush _test-output-buffered-file)
2771 (flush _test-error-buffered-file)
2772 #? # dump _test-error-stream {{{
2774 #? (write-stream 2 _test-error-stream)
2776 #? (rewind-stream _test-error-stream)
2779 (check-stream-equal _test-output-stream "" "F - test-float-var-in-wrong-register: output should be empty")
2780 (check-next-stream-line-equal _test-error-stream "fn foo: float var 'y' should be in a floating-point register" "F - test-float-var-in-wrong-register: error message")
2781 # check that stop(1) was called
2782 (check-ints-equal *(edx+4) 2 "F - test-float-var-in-wrong-register: exit status")
2783 # don't restore from ebp
2784 81 0/subop/add %esp 8/imm32
2789 test-non-float-var-in-wrong-register:
2792 89/<- %ebp 4/r32/esp
2794 (clear-stream _test-input-stream)
2795 (clear-stream $_test-input-buffered-file->buffer)
2796 (clear-stream _test-output-stream)
2797 (clear-stream $_test-output-buffered-file->buffer)
2798 (clear-stream _test-error-stream)
2799 (clear-stream $_test-error-buffered-file->buffer)
2800 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
2803 89/<- %edx 4/r32/esp
2804 (tailor-exit-descriptor %edx 0x10)
2806 (write _test-input-stream "fn foo {\n")
2807 (write _test-input-stream " var x/xmm5: int <- copy 0\n")
2808 (write _test-input-stream "}\n")
2810 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
2811 # registers except esp clobbered at this point
2813 89/<- %edx 4/r32/esp
2814 (flush _test-output-buffered-file)
2815 (flush _test-error-buffered-file)
2816 #? # dump _test-error-stream {{{
2818 #? (write-stream 2 _test-error-stream)
2820 #? (rewind-stream _test-error-stream)
2823 (check-stream-equal _test-output-stream "" "F - test-non-float-var-in-wrong-register: output should be empty")
2824 (check-next-stream-line-equal _test-error-stream "fn foo: non-float var 'x' should be in an integer register" "F - test-non-float-var-in-wrong-register: error message")
2825 # check that stop(1) was called
2826 (check-ints-equal *(edx+4) 2 "F - test-non-float-var-in-wrong-register: exit status")
2827 # don't restore from ebp
2828 81 0/subop/add %esp 8/imm32
2833 test-convert-function-with-allocate:
2836 89/<- %ebp 4/r32/esp
2838 (clear-stream _test-input-stream)
2839 (clear-stream $_test-input-buffered-file->buffer)
2840 (clear-stream _test-output-stream)
2841 (clear-stream $_test-output-buffered-file->buffer)
2843 (write _test-input-stream "fn foo {\n")
2844 (write _test-input-stream " var x/ecx: (addr handle int) <- copy 0\n")
2845 (write _test-input-stream " allocate x\n")
2846 (write _test-input-stream "}\n")
2848 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2849 (flush _test-output-buffered-file)
2850 #? # dump _test-output-stream {{{
2852 #? (write-stream 2 _test-output-stream)
2854 #? (rewind-stream _test-output-stream)
2857 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-allocate/0")
2858 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-allocate/1")
2859 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-allocate/2")
2860 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-allocate/3")
2861 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-allocate/4")
2862 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-allocate/5")
2863 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-allocate/6")
2864 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-allocate/7")
2865 (check-next-stream-line-equal _test-output-stream " (allocate Heap 0x00000004 %ecx)" "F - test-convert-function-with-allocate/8") # 4 = size-of(int)
2866 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-allocate/9")
2867 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-allocate/10")
2868 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-allocate/11")
2869 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-allocate/12")
2870 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-allocate/13")
2871 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-allocate/14")
2872 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-allocate/15")
2874 89/<- %esp 5/r32/ebp
2878 test-initializer-in-hex:
2881 89/<- %ebp 4/r32/esp
2883 (clear-stream _test-input-stream)
2884 (clear-stream $_test-input-buffered-file->buffer)
2885 (clear-stream _test-output-stream)
2886 (clear-stream $_test-output-buffered-file->buffer)
2887 (clear-stream _test-error-stream)
2888 (clear-stream $_test-error-buffered-file->buffer)
2889 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
2892 89/<- %edx 4/r32/esp
2893 (tailor-exit-descriptor %edx 0x10)
2895 (write _test-input-stream "fn foo {\n")
2896 (write _test-input-stream " var x/ecx: int <- copy 10\n")
2897 (write _test-input-stream "}\n")
2899 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
2900 # registers except esp clobbered at this point
2902 89/<- %edx 4/r32/esp
2903 (flush _test-output-buffered-file)
2904 (flush _test-error-buffered-file)
2905 #? # dump _test-error-stream {{{
2907 #? (write-stream 2 _test-error-stream)
2909 #? (rewind-stream _test-error-stream)
2912 (check-stream-equal _test-output-stream "" "F - test-initializer-in-hex: output should be empty")
2913 (check-next-stream-line-equal _test-error-stream "literal integers are always hex in Mu; start '10' with a '0x' to be unambiguous, converting it to hexadecimal as necessary." "F - test-initializer-in-hex: error message")
2914 # check that stop(1) was called
2915 (check-ints-equal *(edx+4) 2 "F - test-initializer-in-hex: exit status")
2916 # don't restore from ebp
2917 81 0/subop/add %esp 8/imm32
2922 test-convert-function-with-second-local-var-in-same-reg:
2925 89/<- %ebp 4/r32/esp
2927 (clear-stream _test-input-stream)
2928 (clear-stream $_test-input-buffered-file->buffer)
2929 (clear-stream _test-output-stream)
2930 (clear-stream $_test-output-buffered-file->buffer)
2932 (write _test-input-stream "fn foo {\n")
2933 (write _test-input-stream " var x/ecx: int <- copy 3\n")
2934 (write _test-input-stream " var y/ecx: int <- copy 4\n")
2935 (write _test-input-stream " y <- increment\n")
2936 (write _test-input-stream "}\n")
2938 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
2939 (flush _test-output-buffered-file)
2940 #? # dump _test-output-stream {{{
2942 #? (write-stream 2 _test-output-stream)
2944 #? (rewind-stream _test-output-stream)
2947 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-second-local-var-in-same-reg/0")
2948 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-second-local-var-in-same-reg/1")
2949 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/2")
2950 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-second-local-var-in-same-reg/3")
2951 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-second-local-var-in-same-reg/4")
2952 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-second-local-var-in-same-reg/5")
2953 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-second-local-var-in-same-reg/6")
2954 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-second-local-var-in-same-reg/7")
2955 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-convert-function-with-second-local-var-in-same-reg/8")
2956 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-second-local-var-in-same-reg/9")
2957 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-second-local-var-in-same-reg/10")
2958 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-second-local-var-in-same-reg/11")
2959 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-second-local-var-in-same-reg/12")
2960 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-second-local-var-in-same-reg/13")
2961 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-second-local-var-in-same-reg/14")
2962 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/15")
2963 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-second-local-var-in-same-reg/16")
2965 89/<- %esp 5/r32/ebp
2969 test-read-clobbered-reg-var:
2972 89/<- %ebp 4/r32/esp
2974 (clear-stream _test-input-stream)
2975 (clear-stream $_test-input-buffered-file->buffer)
2976 (clear-stream _test-output-stream)
2977 (clear-stream $_test-output-buffered-file->buffer)
2978 (clear-stream _test-error-stream)
2979 (clear-stream $_test-error-buffered-file->buffer)
2980 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu
2983 89/<- %edx 4/r32/esp
2984 (tailor-exit-descriptor %edx 0x10)
2986 (write _test-input-stream "fn foo {\n")
2987 (write _test-input-stream " var x/ecx: int <- copy 3\n")
2988 (write _test-input-stream " var y/ecx: int <- copy 4\n")
2989 (write _test-input-stream " x <- increment\n")
2990 (write _test-input-stream "}\n")
2992 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
2993 # registers except esp clobbered at this point
2995 89/<- %edx 4/r32/esp
2996 (flush _test-output-buffered-file)
2997 (flush _test-error-buffered-file)
2998 #? # dump _test-error-stream {{{
3000 #? (write-stream 2 _test-error-stream)
3002 #? (rewind-stream _test-error-stream)
3005 (check-stream-equal _test-output-stream "" "F - test-read-clobbered-reg-var: output should be empty")
3006 (check-next-stream-line-equal _test-error-stream "fn foo: register ecx reads var 'x' after writing var 'y'" "F - test-read-clobbered-reg-var: error message")
3007 # check that stop(1) was called
3008 (check-ints-equal *(edx+4) 2 "F - test-read-clobbered-reg-var: exit status")
3009 # don't restore from ebp
3010 81 0/subop/add %esp 8/imm32
3015 test-overlapping-int-fp-registers:
3018 89/<- %ebp 4/r32/esp
3020 (clear-stream _test-input-stream)
3021 (clear-stream $_test-input-buffered-file->buffer)
3022 (clear-stream _test-output-stream)
3023 (clear-stream $_test-output-buffered-file->buffer)
3024 (clear-stream _test-error-stream)
3025 (clear-stream $_test-error-buffered-file->buffer)
3026 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu
3029 89/<- %edx 4/r32/esp
3030 (tailor-exit-descriptor %edx 0x10)
3032 (write _test-input-stream "fn foo {\n")
3033 (write _test-input-stream " var x/eax: int <- copy 3\n")
3034 (write _test-input-stream " var y/xmm0: float <- convert x\n")
3035 (write _test-input-stream " x <- increment\n")
3036 (write _test-input-stream "}\n")
3038 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3039 # registers except esp clobbered at this point
3041 89/<- %edx 4/r32/esp
3042 (flush _test-output-buffered-file)
3043 (flush _test-error-buffered-file)
3044 #? # dump _test-error-stream {{{
3046 #? (write-stream 2 _test-error-stream)
3048 #? (rewind-stream _test-error-stream)
3051 (check-next-stream-line-equal _test-error-stream "" "F - test-overlapping-int-fp-registers: error message")
3052 # don't bother checking the generated code
3053 # don't restore from ebp
3054 81 0/subop/add %esp 8/imm32
3059 test-convert-function-call:
3062 89/<- %ebp 4/r32/esp
3064 (clear-stream _test-input-stream)
3065 (clear-stream $_test-input-buffered-file->buffer)
3066 (clear-stream _test-output-stream)
3067 (clear-stream $_test-output-buffered-file->buffer)
3069 (write _test-input-stream "fn main -> _/ebx: int {\n")
3070 (write _test-input-stream " var result/ebx: int <- foo\n")
3071 (write _test-input-stream " return result\n")
3072 (write _test-input-stream "}\n")
3073 (write _test-input-stream "fn foo -> _/ebx: int {\n")
3074 (write _test-input-stream " var result/ebx: int <- copy 3\n")
3075 (write _test-input-stream " return result\n")
3076 (write _test-input-stream "}\n")
3078 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
3079 (flush _test-output-buffered-file)
3080 #? # dump _test-output-stream {{{
3082 #? (write-stream 2 _test-output-stream)
3084 #? (rewind-stream _test-output-stream)
3087 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call/0")
3088 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/1")
3089 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/2")
3090 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/3")
3091 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/4")
3092 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call/5")
3093 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-function-call-with-literal-arg/6")
3094 (check-next-stream-line-equal _test-output-stream " (foo)" "F - test-convert-function-call/6")
3095 (check-next-stream-line-equal _test-output-stream " 8b/-> %ebx 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/8")
3096 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-call-with-literal-arg/27")
3097 (check-next-stream-line-equal _test-output-stream " e9/jump $main:0x00000001:break/disp32" "F - test-convert-function-call-with-literal-arg/10")
3098 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/7")
3099 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call/8")
3100 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/9")
3101 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/10")
3102 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/11")
3103 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/12")
3104 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call/13")
3105 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/14")
3106 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/15")
3107 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/16")
3108 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/17")
3109 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call/18")
3110 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-function-call-with-literal-arg/6")
3111 (check-next-stream-line-equal _test-output-stream " bb/copy-to-ebx 3/imm32" "F - test-convert-function-call/19")
3112 (check-next-stream-line-equal _test-output-stream " 8b/-> %ebx 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/8")
3113 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-call-with-literal-arg/27")
3114 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-call-with-literal-arg/10")
3115 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/20")
3116 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call/21")
3117 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/22")
3118 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/23")
3119 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/24")
3120 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/25")
3122 89/<- %esp 5/r32/ebp
3126 test-convert-function-call-with-inout-with-compound-type:
3129 89/<- %ebp 4/r32/esp
3131 (clear-stream _test-input-stream)
3132 (clear-stream $_test-input-buffered-file->buffer)
3133 (clear-stream _test-output-stream)
3134 (clear-stream $_test-output-buffered-file->buffer)
3136 (write _test-input-stream "fn f {\n")
3137 (write _test-input-stream " var x: (addr int)\n")
3138 (write _test-input-stream " g x\n")
3139 (write _test-input-stream "}\n")
3140 (write _test-input-stream "fn g a: (addr int) {\n")
3141 (write _test-input-stream "}\n")
3143 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
3144 (flush _test-output-buffered-file)
3145 #? # dump _test-output-stream {{{
3147 #? (write-stream 2 _test-output-stream)
3149 #? (rewind-stream _test-output-stream)
3152 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-inout-with-compound-type/0")
3153 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-inout-with-compound-type/1")
3154 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-inout-with-compound-type/2")
3155 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-inout-with-compound-type/3")
3156 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-inout-with-compound-type/4")
3157 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-inout-with-compound-type/5")
3158 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-inout-with-compound-type/6")
3159 (check-next-stream-line-equal _test-output-stream " (g *(ebp+0xfffffffc))" "F - test-convert-function-call-with-inout-with-compound-type/7")
3160 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-call-with-inout-with-compound-type/8")
3161 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-inout-with-compound-type/9")
3162 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-inout-with-compound-type/10")
3163 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-inout-with-compound-type/11")
3164 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-inout-with-compound-type/12")
3165 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-inout-with-compound-type/13")
3166 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-inout-with-compound-type/14")
3167 (check-next-stream-line-equal _test-output-stream "g:" "F - test-convert-function-call-with-inout-with-compound-type/15")
3168 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-inout-with-compound-type/16")
3169 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-inout-with-compound-type/17")
3170 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-inout-with-compound-type/18")
3171 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-inout-with-compound-type/19")
3172 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-inout-with-compound-type/20")
3173 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-inout-with-compound-type/21")
3174 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-inout-with-compound-type/22")
3176 89/<- %esp 5/r32/ebp
3180 test-convert-function-call-with-inout-with-type-parameter:
3183 89/<- %ebp 4/r32/esp
3185 (clear-stream _test-input-stream)
3186 (clear-stream $_test-input-buffered-file->buffer)
3187 (clear-stream _test-output-stream)
3188 (clear-stream $_test-output-buffered-file->buffer)
3189 (clear-stream _test-error-stream)
3190 (clear-stream $_test-error-buffered-file->buffer)
3191 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3194 89/<- %edx 4/r32/esp
3195 (tailor-exit-descriptor %edx 0x10)
3197 (write _test-input-stream "fn f {\n")
3198 (write _test-input-stream " var x: (addr int)\n")
3199 (write _test-input-stream " g x\n")
3200 (write _test-input-stream "}\n")
3201 (write _test-input-stream "fn g a: (addr _) {\n")
3202 (write _test-input-stream "}\n")
3204 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3205 # registers except esp clobbered at this point
3207 89/<- %edx 4/r32/esp
3208 (flush _test-output-buffered-file)
3209 (flush _test-error-buffered-file)
3210 #? # dump _test-error-stream {{{
3212 #? (write-stream 2 _test-error-stream)
3214 #? (rewind-stream _test-error-stream)
3216 # no error; types matched
3217 (check-stream-equal _test-error-stream "" "F - test-convert-function-call-with-inout-with-type-parameter: error stream should be empty")
3218 # don't bother checking the generated code; that's in the test 'test-local-clobbered-by-fn-output' below
3219 # don't restore from ebp
3220 81 0/subop/add %esp 8/imm32
3225 test-convert-function-call-with-incorrect-inout-type:
3228 89/<- %ebp 4/r32/esp
3230 (clear-stream _test-input-stream)
3231 (clear-stream $_test-input-buffered-file->buffer)
3232 (clear-stream _test-output-stream)
3233 (clear-stream $_test-output-buffered-file->buffer)
3234 (clear-stream _test-error-stream)
3235 (clear-stream $_test-error-buffered-file->buffer)
3236 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3239 89/<- %edx 4/r32/esp
3240 (tailor-exit-descriptor %edx 0x10)
3242 (write _test-input-stream "fn f {\n")
3243 (write _test-input-stream " var x: int\n")
3244 (write _test-input-stream " g x\n")
3245 (write _test-input-stream "}\n")
3246 (write _test-input-stream "fn g a: foo {\n")
3247 (write _test-input-stream "}\n")
3249 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3250 # registers except esp clobbered at this point
3252 89/<- %edx 4/r32/esp
3253 (flush _test-output-buffered-file)
3254 (flush _test-error-buffered-file)
3255 #? # dump _test-error-stream {{{
3257 #? (write-stream 2 _test-error-stream)
3259 #? (rewind-stream _test-error-stream)
3262 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-inout-type: output should be empty")
3263 (check-next-stream-line-equal _test-error-stream "fn f: call g: type for inout 'x' is not right" "F - test-convert-function-call-with-incorrect-inout-type: error message")
3264 # check that stop(1) was called
3265 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-inout-type: exit status")
3266 # don't restore from ebp
3267 81 0/subop/add %esp 8/imm32
3271 test-convert-function-call-with-inout-with-incorrect-compound-type:
3274 89/<- %ebp 4/r32/esp
3276 (clear-stream _test-input-stream)
3277 (clear-stream $_test-input-buffered-file->buffer)
3278 (clear-stream _test-output-stream)
3279 (clear-stream $_test-output-buffered-file->buffer)
3280 (clear-stream _test-error-stream)
3281 (clear-stream $_test-error-buffered-file->buffer)
3282 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3285 89/<- %edx 4/r32/esp
3286 (tailor-exit-descriptor %edx 0x10)
3288 (write _test-input-stream "fn f {\n")
3289 (write _test-input-stream " var x: (addr int)\n")
3290 (write _test-input-stream " g x\n")
3291 (write _test-input-stream "}\n")
3292 (write _test-input-stream "fn g a: (addr bool) {\n")
3293 (write _test-input-stream "}\n")
3295 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3296 # registers except esp clobbered at this point
3298 89/<- %edx 4/r32/esp
3299 (flush _test-output-buffered-file)
3300 (flush _test-error-buffered-file)
3301 #? # dump _test-error-stream {{{
3303 #? (write-stream 2 _test-error-stream)
3305 #? (rewind-stream _test-error-stream)
3308 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-inout-with-incorrect-compound-type: output should be empty")
3309 (check-next-stream-line-equal _test-error-stream "fn f: call g: type for inout 'x' is not right" "F - test-convert-function-call-with-inout-with-incorrect-compound-type: error message")
3310 # don't restore from ebp
3311 81 0/subop/add %esp 8/imm32
3316 test-convert-function-call-with-inout-with-multiple-type-parameters:
3319 89/<- %ebp 4/r32/esp
3321 (clear-stream _test-input-stream)
3322 (clear-stream $_test-input-buffered-file->buffer)
3323 (clear-stream _test-output-stream)
3324 (clear-stream $_test-output-buffered-file->buffer)
3325 (clear-stream _test-error-stream)
3326 (clear-stream $_test-error-buffered-file->buffer)
3327 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3330 89/<- %edx 4/r32/esp
3331 (tailor-exit-descriptor %edx 0x10)
3333 (write _test-input-stream "fn f {\n")
3334 (write _test-input-stream " var x: (addr int)\n")
3335 (write _test-input-stream " var y: (addr int)\n")
3336 (write _test-input-stream " g x, y\n")
3337 (write _test-input-stream "}\n")
3338 (write _test-input-stream "fn g a: (addr _), b: (addr _) {\n")
3339 (write _test-input-stream "}\n")
3341 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3342 # registers except esp clobbered at this point
3344 89/<- %edx 4/r32/esp
3345 (flush _test-output-buffered-file)
3346 (flush _test-error-buffered-file)
3347 #? # dump _test-error-stream {{{
3349 #? (write-stream 2 _test-error-stream)
3351 #? (rewind-stream _test-error-stream)
3354 (check-stream-equal _test-error-stream "" "F - test-convert-function-call-with-inout-with-multiple-type-parameters: error stream should be empty")
3355 # don't bother checking the generated code
3356 # don't restore from ebp
3357 81 0/subop/add %esp 8/imm32
3362 test-type-parameter-matches-rest-of-type:
3365 89/<- %ebp 4/r32/esp
3367 (clear-stream _test-input-stream)
3368 (clear-stream $_test-input-buffered-file->buffer)
3369 (clear-stream _test-output-stream)
3370 (clear-stream $_test-output-buffered-file->buffer)
3371 (clear-stream _test-error-stream)
3372 (clear-stream $_test-error-buffered-file->buffer)
3373 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3376 89/<- %edx 4/r32/esp
3377 (tailor-exit-descriptor %edx 0x10)
3379 (write _test-input-stream "fn f {\n")
3380 (write _test-input-stream " var x: (addr array int)\n")
3381 (write _test-input-stream " g x\n")
3382 (write _test-input-stream "}\n")
3383 (write _test-input-stream "fn g a: (addr _) {\n")
3384 (write _test-input-stream "}\n")
3386 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3387 # registers except esp clobbered at this point
3389 89/<- %edx 4/r32/esp
3390 (flush _test-output-buffered-file)
3391 (flush _test-error-buffered-file)
3392 #? # dump _test-error-stream {{{
3394 #? (write-stream 2 _test-error-stream)
3396 #? (rewind-stream _test-error-stream)
3399 (check-stream-equal _test-error-stream "" "F - test-type-parameter-matches-rest-of-type: error stream should be empty")
3400 # don't bother checking the generated code
3401 # don't restore from ebp
3402 81 0/subop/add %esp 8/imm32
3407 test-convert-function-call-with-inout-with-incompatible-type-parameters:
3410 89/<- %ebp 4/r32/esp
3412 (clear-stream _test-input-stream)
3413 (clear-stream $_test-input-buffered-file->buffer)
3414 (clear-stream _test-output-stream)
3415 (clear-stream $_test-output-buffered-file->buffer)
3416 (clear-stream _test-error-stream)
3417 (clear-stream $_test-error-buffered-file->buffer)
3418 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3421 89/<- %edx 4/r32/esp
3422 (tailor-exit-descriptor %edx 0x10)
3424 (write _test-input-stream "fn f {\n")
3425 (write _test-input-stream " var x: (addr int)\n")
3426 (write _test-input-stream " var y: (addr boolean)\n")
3427 (write _test-input-stream " g x, y\n")
3428 (write _test-input-stream "}\n")
3429 (write _test-input-stream "fn g a: (addr _T), b: (addr _T) {\n")
3430 (write _test-input-stream "}\n")
3432 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3433 # registers except esp clobbered at this point
3435 89/<- %edx 4/r32/esp
3436 (flush _test-output-buffered-file)
3437 (flush _test-error-buffered-file)
3438 #? # dump _test-error-stream {{{
3440 #? (write-stream 2 _test-error-stream)
3442 #? (rewind-stream _test-error-stream)
3445 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-inout-with-incompatible-type-parameters: output should be empty")
3446 (check-next-stream-line-equal _test-error-stream "fn f: call g: type for inout 'y' is not right" "F - test-convert-function-call-with-inout-with-incompatible-type-parameters: error message")
3447 # don't restore from ebp
3448 81 0/subop/add %esp 8/imm32
3453 test-convert-function-call-with-too-few-inouts:
3456 89/<- %ebp 4/r32/esp
3458 (clear-stream _test-input-stream)
3459 (clear-stream $_test-input-buffered-file->buffer)
3460 (clear-stream _test-output-stream)
3461 (clear-stream $_test-output-buffered-file->buffer)
3462 (clear-stream _test-error-stream)
3463 (clear-stream $_test-error-buffered-file->buffer)
3464 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3467 89/<- %edx 4/r32/esp
3468 (tailor-exit-descriptor %edx 0x10)
3470 (write _test-input-stream "fn f {\n")
3471 (write _test-input-stream " g\n")
3472 (write _test-input-stream "}\n")
3473 (write _test-input-stream "fn g a: int {\n")
3474 (write _test-input-stream "}\n")
3476 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3477 # registers except esp clobbered at this point
3479 89/<- %edx 4/r32/esp
3480 (flush _test-output-buffered-file)
3481 (flush _test-error-buffered-file)
3482 #? # dump _test-error-stream {{{
3484 #? (write-stream 2 _test-error-stream)
3486 #? (rewind-stream _test-error-stream)
3489 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-inouts: output should be empty")
3490 (check-next-stream-line-equal _test-error-stream "fn f: call g: too few inouts" "F - test-convert-function-call-with-too-few-inouts: error message")
3491 # check that stop(1) was called
3492 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-inouts: exit status")
3493 # don't restore from ebp
3494 81 0/subop/add %esp 8/imm32
3498 test-convert-function-call-with-too-many-inouts:
3501 89/<- %ebp 4/r32/esp
3503 (clear-stream _test-input-stream)
3504 (clear-stream $_test-input-buffered-file->buffer)
3505 (clear-stream _test-output-stream)
3506 (clear-stream $_test-output-buffered-file->buffer)
3507 (clear-stream _test-error-stream)
3508 (clear-stream $_test-error-buffered-file->buffer)
3509 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3512 89/<- %edx 4/r32/esp
3513 (tailor-exit-descriptor %edx 0x10)
3515 (write _test-input-stream "fn f {\n")
3516 (write _test-input-stream " var x: int\n")
3517 (write _test-input-stream " g x\n")
3518 (write _test-input-stream "}\n")
3519 (write _test-input-stream "fn g {\n")
3520 (write _test-input-stream "}\n")
3522 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3523 # registers except esp clobbered at this point
3525 89/<- %edx 4/r32/esp
3526 (flush _test-output-buffered-file)
3527 (flush _test-error-buffered-file)
3528 #? # dump _test-error-stream {{{
3530 #? (write-stream 2 _test-error-stream)
3532 #? (rewind-stream _test-error-stream)
3535 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-inouts: output should be empty")
3536 (check-next-stream-line-equal _test-error-stream "fn f: call g: too many inouts" "F - test-convert-function-call-with-too-many-inouts: error message")
3537 # check that stop(1) was called
3538 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-inouts: exit status")
3539 # don't restore from ebp
3540 81 0/subop/add %esp 8/imm32
3544 test-convert-function-call-with-incorrect-output-type:
3547 89/<- %ebp 4/r32/esp
3549 (clear-stream _test-input-stream)
3550 (clear-stream $_test-input-buffered-file->buffer)
3551 (clear-stream _test-output-stream)
3552 (clear-stream $_test-output-buffered-file->buffer)
3553 (clear-stream _test-error-stream)
3554 (clear-stream $_test-error-buffered-file->buffer)
3555 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3558 89/<- %edx 4/r32/esp
3559 (tailor-exit-descriptor %edx 0x10)
3561 (write _test-input-stream "fn f {\n")
3562 (write _test-input-stream " var x/eax: int <- g\n")
3563 (write _test-input-stream "}\n")
3564 (write _test-input-stream "fn g -> _/eax: foo {\n")
3565 (write _test-input-stream "}\n")
3567 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3568 # registers except esp clobbered at this point
3570 89/<- %edx 4/r32/esp
3571 (flush _test-output-buffered-file)
3572 (flush _test-error-buffered-file)
3573 #? # dump _test-error-stream {{{
3575 #? (write-stream 2 _test-error-stream)
3577 #? (rewind-stream _test-error-stream)
3580 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-type: output should be empty")
3581 (check-next-stream-line-equal _test-error-stream "fn f: call g: type for output 'x' is not right" "F - test-convert-function-call-with-incorrect-output-type: error message")
3582 # check that stop(1) was called
3583 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-type: exit status")
3584 # don't restore from ebp
3585 81 0/subop/add %esp 8/imm32
3589 test-convert-function-call-with-too-few-outputs:
3592 89/<- %ebp 4/r32/esp
3594 (clear-stream _test-input-stream)
3595 (clear-stream $_test-input-buffered-file->buffer)
3596 (clear-stream _test-output-stream)
3597 (clear-stream $_test-output-buffered-file->buffer)
3598 (clear-stream _test-error-stream)
3599 (clear-stream $_test-error-buffered-file->buffer)
3600 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3603 89/<- %edx 4/r32/esp
3604 (tailor-exit-descriptor %edx 0x10)
3606 (write _test-input-stream "fn f {\n")
3607 (write _test-input-stream " g\n")
3608 (write _test-input-stream "}\n")
3609 (write _test-input-stream "fn g -> _/eax: int {\n")
3610 (write _test-input-stream "}\n")
3612 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3613 # registers except esp clobbered at this point
3615 89/<- %edx 4/r32/esp
3616 (flush _test-output-buffered-file)
3617 (flush _test-error-buffered-file)
3618 #? # dump _test-error-stream {{{
3620 #? (write-stream 2 _test-error-stream)
3622 #? (rewind-stream _test-error-stream)
3625 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-outputs: output should be empty")
3626 (check-next-stream-line-equal _test-error-stream "fn f: call g: too few outputs" "F - test-convert-function-call-with-too-few-outputs: error message")
3627 # check that stop(1) was called
3628 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-outputs: exit status")
3629 # don't restore from ebp
3630 81 0/subop/add %esp 8/imm32
3634 test-convert-function-call-with-too-many-outputs:
3637 89/<- %ebp 4/r32/esp
3639 (clear-stream _test-input-stream)
3640 (clear-stream $_test-input-buffered-file->buffer)
3641 (clear-stream _test-output-stream)
3642 (clear-stream $_test-output-buffered-file->buffer)
3643 (clear-stream _test-error-stream)
3644 (clear-stream $_test-error-buffered-file->buffer)
3645 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3648 89/<- %edx 4/r32/esp
3649 (tailor-exit-descriptor %edx 0x10)
3651 (write _test-input-stream "fn f {\n")
3652 (write _test-input-stream " var x/eax: int <- g\n")
3653 (write _test-input-stream "}\n")
3654 (write _test-input-stream "fn g {\n")
3655 (write _test-input-stream "}\n")
3657 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3658 # registers except esp clobbered at this point
3660 89/<- %edx 4/r32/esp
3661 (flush _test-output-buffered-file)
3662 (flush _test-error-buffered-file)
3663 #? # dump _test-error-stream {{{
3665 #? (write-stream 2 _test-error-stream)
3667 #? (rewind-stream _test-error-stream)
3670 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-outputs: output should be empty")
3671 (check-next-stream-line-equal _test-error-stream "fn f: call g: too many outputs" "F - test-convert-function-call-with-too-many-outputs: error message")
3672 # check that stop(1) was called
3673 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-outputs: exit status")
3674 # don't restore from ebp
3675 81 0/subop/add %esp 8/imm32
3679 test-convert-function-call-with-missing-output-register:
3682 89/<- %ebp 4/r32/esp
3684 (clear-stream _test-input-stream)
3685 (clear-stream $_test-input-buffered-file->buffer)
3686 (clear-stream _test-output-stream)
3687 (clear-stream $_test-output-buffered-file->buffer)
3688 (clear-stream _test-error-stream)
3689 (clear-stream $_test-error-buffered-file->buffer)
3690 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3693 89/<- %edx 4/r32/esp
3694 (tailor-exit-descriptor %edx 0x10)
3696 (write _test-input-stream "fn f {\n")
3697 (write _test-input-stream " var x: int\n")
3698 (write _test-input-stream " x <- g\n")
3699 (write _test-input-stream "}\n")
3700 (write _test-input-stream "fn g -> _/eax: int {\n")
3701 (write _test-input-stream "}\n")
3703 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3704 # registers except esp clobbered at this point
3706 89/<- %edx 4/r32/esp
3707 (flush _test-output-buffered-file)
3708 (flush _test-error-buffered-file)
3709 #? # dump _test-error-stream {{{
3711 #? (write-stream 2 _test-error-stream)
3713 #? (rewind-stream _test-error-stream)
3716 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-missing-output-register: output should be empty")
3717 (check-next-stream-line-equal _test-error-stream "fn f: call g: output 'x' is not in a register" "F - test-convert-function-call-with-missing-output-register: error message")
3718 # check that stop(1) was called
3719 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-missing-output-register: exit status")
3720 # don't restore from ebp
3721 81 0/subop/add %esp 8/imm32
3725 test-convert-function-call-with-incorrect-output-register:
3728 89/<- %ebp 4/r32/esp
3730 (clear-stream _test-input-stream)
3731 (clear-stream $_test-input-buffered-file->buffer)
3732 (clear-stream _test-output-stream)
3733 (clear-stream $_test-output-buffered-file->buffer)
3734 (clear-stream _test-error-stream)
3735 (clear-stream $_test-error-buffered-file->buffer)
3736 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3739 89/<- %edx 4/r32/esp
3740 (tailor-exit-descriptor %edx 0x10)
3742 (write _test-input-stream "fn f {\n")
3743 (write _test-input-stream " var x/ecx: int <- g\n")
3744 (write _test-input-stream "}\n")
3745 (write _test-input-stream "fn g -> _/eax: int {\n")
3746 (write _test-input-stream "}\n")
3748 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3749 # registers except esp clobbered at this point
3751 89/<- %edx 4/r32/esp
3752 (flush _test-output-buffered-file)
3753 (flush _test-error-buffered-file)
3754 #? # dump _test-error-stream {{{
3756 #? (write-stream 2 _test-error-stream)
3758 #? (rewind-stream _test-error-stream)
3761 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-register: output should be empty")
3762 (check-next-stream-line-equal _test-error-stream "fn f: call g: register for output 'x' is not right" "F - test-convert-function-call-with-incorrect-output-register: error message")
3763 # check that stop(1) was called
3764 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-register: exit status")
3765 # don't restore from ebp
3766 81 0/subop/add %esp 8/imm32
3770 test-convert-function-with-local-var-dereferenced:
3773 89/<- %ebp 4/r32/esp
3775 (clear-stream _test-input-stream)
3776 (clear-stream $_test-input-buffered-file->buffer)
3777 (clear-stream _test-output-stream)
3778 (clear-stream $_test-output-buffered-file->buffer)
3780 (write _test-input-stream "fn foo {\n")
3781 (write _test-input-stream " var x/ecx: (addr int) <- copy 0\n")
3782 (write _test-input-stream " increment *x\n")
3783 (write _test-input-stream "}\n")
3785 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
3786 (flush _test-output-buffered-file)
3787 #? # dump _test-output-stream {{{
3789 #? (write-stream 2 _test-output-stream)
3791 #? (rewind-stream _test-output-stream)
3794 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-dereferenced/0")
3795 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-dereferenced/1")
3796 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-dereferenced/2")
3797 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-dereferenced/3")
3798 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-dereferenced/4")
3799 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-dereferenced/5")
3800 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-dereferenced/6")
3801 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-local-var-dereferenced/7")
3802 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-with-local-var-dereferenced/8")
3803 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-dereferenced/9")
3804 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-dereferenced/10")
3805 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-dereferenced/11")
3806 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-dereferenced/12")
3807 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-dereferenced/13")
3808 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-dereferenced/14")
3809 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-dereferenced/15")
3811 89/<- %esp 5/r32/ebp
3815 test-dereference-of-var-on-stack:
3818 89/<- %ebp 4/r32/esp
3820 (clear-stream _test-input-stream)
3821 (clear-stream $_test-input-buffered-file->buffer)
3822 (clear-stream _test-output-stream)
3823 (clear-stream $_test-output-buffered-file->buffer)
3824 (clear-stream _test-error-stream)
3825 (clear-stream $_test-error-buffered-file->buffer)
3826 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3829 89/<- %edx 4/r32/esp
3830 (tailor-exit-descriptor %edx 0x10)
3832 (write _test-input-stream "fn foo {\n")
3833 (write _test-input-stream " var x: (addr int)\n")
3834 (write _test-input-stream " increment *x\n")
3835 (write _test-input-stream "}\n")
3837 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3838 # registers except esp clobbered at this point
3840 89/<- %edx 4/r32/esp
3841 (flush _test-output-buffered-file)
3842 (flush _test-error-buffered-file)
3843 #? # dump _test-error-stream {{{
3845 #? (write-stream 2 _test-error-stream)
3847 #? (rewind-stream _test-error-stream)
3850 (check-stream-equal _test-output-stream "" "F - test-dereference-of-var-on-stack: output should be empty")
3851 (check-next-stream-line-equal _test-error-stream "fn foo: cannot dereference var 'x' on stack" "F - test-dereference-of-var-on-stack: error message")
3852 # check that stop(1) was called
3853 (check-ints-equal *(edx+4) 2 "F - test-dereference-of-var-on-stack: exit status")
3854 # don't restore from ebp
3855 81 0/subop/add %esp 8/imm32
3860 test-convert-function-with-byte-operations:
3863 89/<- %ebp 4/r32/esp
3865 (clear-stream _test-input-stream)
3866 (clear-stream $_test-input-buffered-file->buffer)
3867 (clear-stream _test-output-stream)
3868 (clear-stream $_test-output-buffered-file->buffer)
3870 (write _test-input-stream "fn foo {\n")
3871 (write _test-input-stream " var x/eax: byte <- copy 0\n")
3872 (write _test-input-stream " var y/ecx: byte <- copy 0\n")
3873 (write _test-input-stream " y <- copy-byte x\n")
3874 (write _test-input-stream " var z/edx: (addr byte) <- copy 0\n")
3875 (write _test-input-stream " y <- copy-byte *z\n")
3876 (write _test-input-stream " copy-byte-to *z, x\n")
3877 (write _test-input-stream "}\n")
3879 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
3880 (flush _test-output-buffered-file)
3881 #? # dump _test-output-stream {{{
3883 #? (write-stream 2 _test-output-stream)
3885 #? (rewind-stream _test-output-stream)
3888 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-byte-operations/0")
3889 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-byte-operations/1")
3890 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-byte-operations/2")
3891 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-byte-operations/3")
3892 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-byte-operations/4")
3893 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-byte-operations/5")
3894 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-byte-operations/6")
3895 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-with-byte-operations/7")
3896 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-byte-operations/8")
3897 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-byte-operations/9")
3898 (check-next-stream-line-equal _test-output-stream " 8a/byte-> %eax 0x00000001/r32" "F - test-convert-function-with-byte-operations/10")
3899 (check-next-stream-line-equal _test-output-stream " 81 4/subop/and %ecx 0xff/imm32" "F - test-convert-function-with-byte-operations/11")
3900 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-function-with-byte-operations/12")
3901 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 0/imm32" "F - test-convert-function-with-byte-operations/13")
3902 (check-next-stream-line-equal _test-output-stream " 8a/byte-> *edx 0x00000001/r32" "F - test-convert-function-with-byte-operations/14")
3903 (check-next-stream-line-equal _test-output-stream " 81 4/subop/and %ecx 0xff/imm32" "F - test-convert-function-with-byte-operations/15")
3904 (check-next-stream-line-equal _test-output-stream " 88/byte<- *edx 0x00000000/r32" "F - test-convert-function-with-byte-operations/16")
3905 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-function-with-byte-operations/17")
3906 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-byte-operations/18")
3907 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-byte-operations/19")
3908 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-byte-operations/20")
3909 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-byte-operations/21")
3910 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-byte-operations/22")
3911 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-byte-operations/23")
3912 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-byte-operations/24")
3913 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-byte-operations/25")
3915 89/<- %esp 5/r32/ebp
3919 # variables of type 'byte' are not allowed on the stack
3920 test-byte-values-on-stack:
3923 89/<- %ebp 4/r32/esp
3925 (clear-stream _test-input-stream)
3926 (clear-stream $_test-input-buffered-file->buffer)
3927 (clear-stream _test-output-stream)
3928 (clear-stream $_test-output-buffered-file->buffer)
3929 (clear-stream _test-error-stream)
3930 (clear-stream $_test-error-buffered-file->buffer)
3931 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3934 89/<- %edx 4/r32/esp
3935 (tailor-exit-descriptor %edx 0x10)
3937 (write _test-input-stream "fn foo {\n")
3938 (write _test-input-stream " var x: byte\n")
3939 (write _test-input-stream "}\n")
3941 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3942 # registers except esp clobbered at this point
3944 89/<- %edx 4/r32/esp
3945 (flush _test-output-buffered-file)
3946 (flush _test-error-buffered-file)
3947 #? # dump _test-error-stream {{{
3949 #? (write-stream 2 _test-error-stream)
3951 #? (rewind-stream _test-error-stream)
3954 (check-stream-equal _test-output-stream "" "F - test-byte-values-on-stack: output should be empty")
3955 (check-next-stream-line-equal _test-error-stream "fn foo: var 'x' of type 'byte' cannot be on the stack" "F - test-byte-values-on-stack: error message")
3956 # check that stop(1) was called
3957 (check-ints-equal *(edx+4) 2 "F - test-byte-values-on-stack: exit status")
3958 # don't restore from ebp
3959 81 0/subop/add %esp 8/imm32
3964 # variables of type 'byte' are not allowed in esi or edi
3965 test-byte-values-in-unsupported-registers:
3968 89/<- %ebp 4/r32/esp
3970 (clear-stream _test-input-stream)
3971 (clear-stream $_test-input-buffered-file->buffer)
3972 (clear-stream _test-output-stream)
3973 (clear-stream $_test-output-buffered-file->buffer)
3974 (clear-stream _test-error-stream)
3975 (clear-stream $_test-error-buffered-file->buffer)
3976 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
3979 89/<- %edx 4/r32/esp
3980 (tailor-exit-descriptor %edx 0x10)
3982 (write _test-input-stream "fn foo {\n")
3983 (write _test-input-stream " var x/esi: byte <- copy 0\n")
3984 (write _test-input-stream "}\n")
3986 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
3987 # registers except esp clobbered at this point
3989 89/<- %edx 4/r32/esp
3990 (flush _test-output-buffered-file)
3991 (flush _test-error-buffered-file)
3992 #? # dump _test-error-stream {{{
3994 #? (write-stream 2 _test-error-stream)
3996 #? (rewind-stream _test-error-stream)
3999 (check-stream-equal _test-output-stream "" "F - test-byte-values-in-unsupported-registers: output should be empty")
4000 (check-next-stream-line-equal _test-error-stream "fn foo: var 'x' of type 'byte' cannot be in esi or edi" "F - test-byte-values-in-unsupported-registers: error message")
4001 # check that stop(1) was called
4002 (check-ints-equal *(edx+4) 2 "F - test-byte-values-in-unsupported-registers: exit status")
4003 # don't restore from ebp
4004 81 0/subop/add %esp 8/imm32
4009 # variables of type 'byte' _can_ be function args. They then occupy 4 bytes.
4010 test-copy-byte-var-from-fn-arg:
4013 89/<- %ebp 4/r32/esp
4015 (clear-stream _test-input-stream)
4016 (clear-stream $_test-input-buffered-file->buffer)
4017 (clear-stream _test-output-stream)
4018 (clear-stream $_test-output-buffered-file->buffer)
4020 (write _test-input-stream "fn foo x: byte, y: int {\n")
4021 (write _test-input-stream " var a/eax: byte <- copy x\n")
4022 (write _test-input-stream " var b/eax: int <- copy y\n")
4023 (write _test-input-stream "}\n")
4025 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4026 (flush _test-output-buffered-file)
4027 #? # dump _test-output-stream {{{
4029 #? (write-stream 2 _test-output-stream)
4031 #? (rewind-stream _test-output-stream)
4034 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-copy-byte-from-fn-arg/0")
4035 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-copy-byte-from-fn-arg/1")
4036 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-copy-byte-from-fn-arg/2")
4037 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-copy-byte-from-fn-arg/3")
4038 (check-next-stream-line-equal _test-output-stream " {" "F - test-copy-byte-from-fn-arg/4")
4039 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-copy-byte-from-fn-arg/5")
4040 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-copy-byte-from-fn-arg/6")
4041 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/7")
4042 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x0000000c) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/8")
4043 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-copy-byte-from-fn-arg/9")
4044 (check-next-stream-line-equal _test-output-stream " }" "F - test-copy-byte-from-fn-arg/10")
4045 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-copy-byte-from-fn-arg/11")
4046 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-copy-byte-from-fn-arg/12")
4047 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-copy-byte-from-fn-arg/13")
4048 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-copy-byte-from-fn-arg/14")
4049 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-copy-byte-from-fn-arg/15")
4051 89/<- %esp 5/r32/ebp
4055 test-convert-compare-register-with-literal:
4058 89/<- %ebp 4/r32/esp
4060 (clear-stream _test-input-stream)
4061 (clear-stream $_test-input-buffered-file->buffer)
4062 (clear-stream _test-output-stream)
4063 (clear-stream $_test-output-buffered-file->buffer)
4065 (write _test-input-stream "fn foo {\n")
4066 (write _test-input-stream " var x/ecx: int <- copy 0\n")
4067 (write _test-input-stream " compare x, 0\n")
4068 (write _test-input-stream "}\n")
4070 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4071 (flush _test-output-buffered-file)
4072 #? # dump _test-output-stream {{{
4074 #? (write-stream 2 _test-output-stream)
4076 #? (rewind-stream _test-output-stream)
4079 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-compare-register-with-literal/0")
4080 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-compare-register-with-literal/1")
4081 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-compare-register-with-literal/2")
4082 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-compare-register-with-literal/3")
4083 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-compare-register-with-literal/4")
4084 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-compare-register-with-literal/5")
4085 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6")
4086 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-compare-register-with-literal/7")
4087 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0/imm32" "F - test-convert-compare-register-with-literal/8")
4088 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9")
4089 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-compare-register-with-literal/10")
4090 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-compare-register-with-literal/11")
4091 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-compare-register-with-literal/12")
4092 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-compare-register-with-literal/13")
4093 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-compare-register-with-literal/14")
4094 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-compare-register-with-literal/15")
4096 89/<- %esp 5/r32/ebp
4100 test-convert-compare-byte-with-literal:
4103 89/<- %ebp 4/r32/esp
4105 (clear-stream _test-input-stream)
4106 (clear-stream $_test-input-buffered-file->buffer)
4107 (clear-stream _test-output-stream)
4108 (clear-stream $_test-output-buffered-file->buffer)
4110 (write _test-input-stream "fn foo {\n")
4111 (write _test-input-stream " var x/ecx: byte <- copy 0\n")
4112 (write _test-input-stream " compare x, 0\n")
4113 (write _test-input-stream "}\n")
4115 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4116 (flush _test-output-buffered-file)
4117 #? # dump _test-output-stream {{{
4119 #? (write-stream 2 _test-output-stream)
4121 #? (rewind-stream _test-output-stream)
4123 # no errors; output is identical to test-convert-compare-register-with-literal
4125 89/<- %esp 5/r32/ebp
4129 test-unknown-variable:
4132 89/<- %ebp 4/r32/esp
4134 (clear-stream _test-input-stream)
4135 (clear-stream $_test-input-buffered-file->buffer)
4136 (clear-stream _test-output-stream)
4137 (clear-stream $_test-output-buffered-file->buffer)
4138 (clear-stream _test-error-stream)
4139 (clear-stream $_test-error-buffered-file->buffer)
4140 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
4143 89/<- %edx 4/r32/esp
4144 (tailor-exit-descriptor %edx 0x10)
4146 (write _test-input-stream "fn foo {\n")
4147 (write _test-input-stream " compare x, 0\n")
4148 (write _test-input-stream "}\n")
4150 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
4151 # registers except esp clobbered at this point
4153 89/<- %edx 4/r32/esp
4154 (flush _test-output-buffered-file)
4155 (flush _test-error-buffered-file)
4156 #? # dump _test-error-stream {{{
4158 #? (write-stream 2 _test-error-stream)
4160 #? (rewind-stream _test-error-stream)
4163 (check-stream-equal _test-output-stream "" "F - test-unknown-variable: output should be empty")
4164 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable: error message")
4165 # check that stop(1) was called
4166 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable: exit status")
4167 # don't restore from ebp
4168 81 0/subop/add %esp 8/imm32
4173 test-convert-function-with-local-var-in-block:
4176 89/<- %ebp 4/r32/esp
4178 (clear-stream _test-input-stream)
4179 (clear-stream $_test-input-buffered-file->buffer)
4180 (clear-stream _test-output-stream)
4181 (clear-stream $_test-output-buffered-file->buffer)
4183 (write _test-input-stream "fn foo {\n")
4184 (write _test-input-stream " {\n")
4185 (write _test-input-stream " var x: int\n")
4186 (write _test-input-stream " increment x\n")
4187 (write _test-input-stream " }\n")
4188 (write _test-input-stream "}\n")
4190 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4191 (flush _test-output-buffered-file)
4192 #? # dump _test-output-stream {{{
4194 #? (write-stream 2 _test-output-stream)
4196 #? (rewind-stream _test-output-stream)
4199 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-block/0")
4200 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-block/1")
4201 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-block/2")
4202 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-block/3")
4203 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/4")
4204 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-block/5")
4205 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/6")
4206 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-local-var-in-block/7")
4207 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-block/8")
4208 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-block/9")
4209 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-block/10")
4210 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/11")
4211 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-local-var-in-block/12")
4212 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/13")
4213 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-block/14")
4214 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-block/15")
4215 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-block/16")
4216 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-block/17")
4217 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-block/18")
4219 89/<- %esp 5/r32/ebp
4223 test-convert-function-with-local-var-in-mem-after-block:
4226 89/<- %ebp 4/r32/esp
4228 (clear-stream _test-input-stream)
4229 (clear-stream $_test-input-buffered-file->buffer)
4230 (clear-stream _test-output-stream)
4231 (clear-stream $_test-output-buffered-file->buffer)
4233 (write _test-input-stream "fn foo {\n")
4234 (write _test-input-stream " {\n")
4235 (write _test-input-stream " var y: int\n")
4236 (write _test-input-stream " }\n")
4237 (write _test-input-stream " var x: int\n")
4238 (write _test-input-stream " increment x\n")
4239 (write _test-input-stream "}\n")
4241 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4242 (flush _test-output-buffered-file)
4243 #? # dump _test-output-stream {{{
4245 #? (write-stream 2 _test-output-stream)
4247 #? (rewind-stream _test-output-stream)
4250 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-mem-after-block/0")
4251 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-mem-after-block/1")
4252 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-mem-after-block/2")
4253 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-mem-after-block/3")
4254 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem-after-block/4")
4255 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-mem-after-block/5")
4256 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem-after-block/6")
4257 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-local-var-in-mem-after-block/7")
4258 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem-after-block/8")
4259 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-mem-after-block/9")
4260 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem-after-block/10")
4261 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-local-var-in-mem-after-block/11")
4262 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem-after-block/12")
4263 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-mem-after-block/13")
4264 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-mem-after-block/14")
4265 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem-after-block/15")
4266 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-mem-after-block/16")
4267 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-mem-after-block/17")
4268 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-mem-after-block/18")
4269 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-mem-after-block/19")
4270 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-mem-after-block/20")
4272 89/<- %esp 5/r32/ebp
4276 test-convert-function-with-local-var-in-named-block:
4279 89/<- %ebp 4/r32/esp
4281 (clear-stream _test-input-stream)
4282 (clear-stream $_test-input-buffered-file->buffer)
4283 (clear-stream _test-output-stream)
4284 (clear-stream $_test-output-buffered-file->buffer)
4286 (write _test-input-stream "fn foo {\n")
4287 (write _test-input-stream " $bar: {\n")
4288 (write _test-input-stream " var x: int\n")
4289 (write _test-input-stream " increment x\n")
4290 (write _test-input-stream " }\n")
4291 (write _test-input-stream "}\n")
4293 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4294 (flush _test-output-buffered-file)
4295 #? # dump _test-output-stream {{{
4297 #? (write-stream 2 _test-output-stream)
4299 #? (rewind-stream _test-output-stream)
4302 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-named-block/0")
4303 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-named-block/1")
4304 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-named-block/2")
4305 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-named-block/3")
4306 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/4")
4307 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-named-block/5")
4308 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/6")
4309 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-local-var-in-named-block/7")
4310 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-named-block/8")
4311 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-named-block/9")
4312 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-in-named-block/10")
4313 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/11")
4314 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-local-var-in-named-block/12")
4315 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/13")
4316 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-named-block/14")
4317 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-named-block/15")
4318 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-named-block/16")
4319 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-named-block/17")
4320 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-named-block/18")
4322 89/<- %esp 5/r32/ebp
4326 test-unknown-variable-in-named-block:
4329 89/<- %ebp 4/r32/esp
4331 (clear-stream _test-input-stream)
4332 (clear-stream $_test-input-buffered-file->buffer)
4333 (clear-stream _test-output-stream)
4334 (clear-stream $_test-output-buffered-file->buffer)
4335 (clear-stream _test-error-stream)
4336 (clear-stream $_test-error-buffered-file->buffer)
4337 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
4340 89/<- %edx 4/r32/esp
4341 (tailor-exit-descriptor %edx 0x10)
4343 (write _test-input-stream "fn foo {\n")
4344 (write _test-input-stream " $a: {\n")
4345 (write _test-input-stream " compare x, 0\n")
4346 (write _test-input-stream " }\n")
4347 (write _test-input-stream "}\n")
4349 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
4350 # registers except esp clobbered at this point
4352 89/<- %edx 4/r32/esp
4353 (flush _test-output-buffered-file)
4354 (flush _test-error-buffered-file)
4355 #? # dump _test-error-stream {{{
4357 #? (write-stream 2 _test-error-stream)
4359 #? (rewind-stream _test-error-stream)
4362 (check-stream-equal _test-output-stream "" "F - test-unknown-variable-in-named-block: output should be empty")
4363 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable-in-named-block: error message")
4364 # check that stop(1) was called
4365 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable-in-named-block: exit status")
4366 # don't restore from ebp
4367 81 0/subop/add %esp 8/imm32
4372 test-always-shadow-outermost-reg-vars-in-function:
4375 89/<- %ebp 4/r32/esp
4377 (clear-stream _test-input-stream)
4378 (clear-stream $_test-input-buffered-file->buffer)
4379 (clear-stream _test-output-stream)
4380 (clear-stream $_test-output-buffered-file->buffer)
4382 (write _test-input-stream "fn foo {\n")
4383 (write _test-input-stream " var x/ecx: int <- copy 3\n")
4384 (write _test-input-stream "}\n")
4386 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4387 (flush _test-output-buffered-file)
4388 #? # dump _test-output-stream {{{
4390 #? (write-stream 2 _test-output-stream)
4392 #? (rewind-stream _test-output-stream)
4395 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-always-shadow-outermost-reg-vars-in-function/0")
4396 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-always-shadow-outermost-reg-vars-in-function/1")
4397 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/2")
4398 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-always-shadow-outermost-reg-vars-in-function/3")
4399 (check-next-stream-line-equal _test-output-stream " {" "F - test-always-shadow-outermost-reg-vars-in-function/4")
4400 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-always-shadow-outermost-reg-vars-in-function/5")
4401 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6")
4402 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-always-shadow-outermost-reg-vars-in-function/8")
4403 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9")
4404 (check-next-stream-line-equal _test-output-stream " }" "F - test-always-shadow-outermost-reg-vars-in-function/12")
4405 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-always-shadow-outermost-reg-vars-in-function/13")
4406 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-always-shadow-outermost-reg-vars-in-function/14")
4407 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-always-shadow-outermost-reg-vars-in-function/15")
4408 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/16")
4409 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-always-shadow-outermost-reg-vars-in-function/17")
4411 89/<- %esp 5/r32/ebp
4418 89/<- %ebp 4/r32/esp
4420 (clear-stream _test-input-stream)
4421 (clear-stream $_test-input-buffered-file->buffer)
4422 (clear-stream _test-output-stream)
4423 (clear-stream $_test-output-buffered-file->buffer)
4425 (write _test-input-stream "fn foo {\n")
4426 (write _test-input-stream " var x/ecx: int <- copy 3\n")
4427 (write _test-input-stream " {\n")
4428 (write _test-input-stream " var y/ecx: int <- copy 4\n")
4429 (write _test-input-stream " }\n")
4430 (write _test-input-stream " x <- increment\n")
4431 (write _test-input-stream "}\n")
4433 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4434 (flush _test-output-buffered-file)
4435 #? # dump _test-output-stream {{{
4437 #? (write-stream 2 _test-output-stream)
4439 #? (rewind-stream _test-output-stream)
4442 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-local/0")
4443 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-local/1")
4444 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-local/2")
4445 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-local/3")
4446 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-local/4")
4447 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-local/5")
4448 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-local/6")
4449 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-local/7")
4450 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-local/8")
4451 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-local/9")
4452 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-local/10")
4453 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-local/11")
4454 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-local/12")
4455 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-local/13")
4456 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-local/14")
4457 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-local/15")
4458 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-local/16")
4459 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-local/17")
4460 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-local/18")
4461 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-local/19")
4462 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-local/20")
4463 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-local/21")
4464 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-local/22")
4466 89/<- %esp 5/r32/ebp
4473 89/<- %ebp 4/r32/esp
4475 (clear-stream _test-input-stream)
4476 (clear-stream $_test-input-buffered-file->buffer)
4477 (clear-stream _test-output-stream)
4478 (clear-stream $_test-output-buffered-file->buffer)
4480 (write _test-input-stream "fn foo {\n")
4481 (write _test-input-stream " var x/ecx: int <- copy 3\n")
4482 (write _test-input-stream " {\n")
4483 (write _test-input-stream " var x/edx: int <- copy 4\n")
4484 (write _test-input-stream " }\n")
4485 (write _test-input-stream " x <- increment\n")
4486 (write _test-input-stream "}\n")
4488 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4489 (flush _test-output-buffered-file)
4490 #? # dump _test-output-stream {{{
4492 #? (write-stream 2 _test-output-stream)
4494 #? (rewind-stream _test-output-stream)
4497 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name/0")
4498 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name/1")
4499 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name/2")
4500 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name/3")
4501 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/4")
4502 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name/5")
4503 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name/6")
4504 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name/7")
4505 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/8")
4506 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name/9")
4507 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name/10")
4508 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name/11")
4509 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name/12")
4510 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/13")
4511 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name/14")
4512 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name/15")
4513 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name/16")
4514 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/17")
4515 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name/18")
4516 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name/19")
4517 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name/20")
4518 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name/21")
4519 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name/22")
4521 89/<- %esp 5/r32/ebp
4528 89/<- %ebp 4/r32/esp
4530 (clear-stream _test-input-stream)
4531 (clear-stream $_test-input-buffered-file->buffer)
4532 (clear-stream _test-output-stream)
4533 (clear-stream $_test-output-buffered-file->buffer)
4535 (write _test-input-stream "fn foo {\n")
4536 (write _test-input-stream " var x/ecx: int <- copy 3\n")
4537 (write _test-input-stream " {\n")
4538 (write _test-input-stream " var x/edx: int <- copy 4\n")
4539 (write _test-input-stream " var y/ecx: int <- copy 5\n")
4540 (write _test-input-stream " }\n")
4541 (write _test-input-stream " x <- increment\n")
4542 (write _test-input-stream "}\n")
4544 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4545 (flush _test-output-buffered-file)
4546 #? # dump _test-output-stream {{{
4548 #? (write-stream 2 _test-output-stream)
4550 #? (rewind-stream _test-output-stream)
4553 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name-2/0")
4554 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name-2/1")
4555 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name-2/2")
4556 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name-2/3")
4557 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/4")
4558 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name-2/5")
4559 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/6")
4560 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name-2/7")
4561 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/8")
4562 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name-2/9")
4563 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name-2/10")
4564 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name-2/11")
4565 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/12")
4566 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 5/imm32" "F - test-shadow-name-2/13")
4567 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/14")
4568 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name-2/15")
4569 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/16")
4570 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name-2/17")
4571 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name-2/18")
4572 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/19")
4573 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/20")
4574 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name-2/21")
4575 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name-2/22")
4576 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name-2/23")
4577 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name-2/24")
4578 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name-2/25")
4580 89/<- %esp 5/r32/ebp
4584 test-do-not-spill-same-register-in-block:
4587 89/<- %ebp 4/r32/esp
4589 (clear-stream _test-input-stream)
4590 (clear-stream $_test-input-buffered-file->buffer)
4591 (clear-stream _test-output-stream)
4592 (clear-stream $_test-output-buffered-file->buffer)
4594 (write _test-input-stream "fn foo {\n")
4595 (write _test-input-stream " var x/ecx: int <- copy 3\n")
4596 (write _test-input-stream " var y/ecx: int <- copy 4\n")
4597 (write _test-input-stream " y <- increment\n")
4598 (write _test-input-stream "}\n")
4600 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4601 (flush _test-output-buffered-file)
4602 #? # dump _test-output-stream {{{
4604 #? (write-stream 2 _test-output-stream)
4606 #? (rewind-stream _test-output-stream)
4609 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-do-not-spill-same-register-in-block/0")
4610 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-do-not-spill-same-register-in-block/1")
4611 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-do-not-spill-same-register-in-block/2")
4612 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-do-not-spill-same-register-in-block/3")
4613 (check-next-stream-line-equal _test-output-stream " {" "F - test-do-not-spill-same-register-in-block/4")
4614 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-do-not-spill-same-register-in-block/5")
4615 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-do-not-spill-same-register-in-block/6")
4616 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-do-not-spill-same-register-in-block/7")
4617 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-do-not-spill-same-register-in-block/8")
4618 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-do-not-spill-same-register-in-block/9")
4619 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-do-not-spill-same-register-in-block/10")
4620 (check-next-stream-line-equal _test-output-stream " }" "F - test-do-not-spill-same-register-in-block/11")
4621 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-do-not-spill-same-register-in-block/12")
4622 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-do-not-spill-same-register-in-block/13")
4623 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-do-not-spill-same-register-in-block/14")
4624 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-do-not-spill-same-register-in-block/15")
4625 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-do-not-spill-same-register-in-block/16")
4627 89/<- %esp 5/r32/ebp
4631 test-spill-different-register-in-block:
4634 89/<- %ebp 4/r32/esp
4636 (clear-stream _test-input-stream)
4637 (clear-stream $_test-input-buffered-file->buffer)
4638 (clear-stream _test-output-stream)
4639 (clear-stream $_test-output-buffered-file->buffer)
4641 (write _test-input-stream "fn foo {\n")
4642 (write _test-input-stream " var x/eax: int <- copy 3\n")
4643 (write _test-input-stream " var y/ecx: int <- copy 4\n")
4644 (write _test-input-stream " y <- increment\n")
4645 (write _test-input-stream "}\n")
4647 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4648 (flush _test-output-buffered-file)
4649 #? # dump _test-output-stream {{{
4651 #? (write-stream 2 _test-output-stream)
4653 #? (rewind-stream _test-output-stream)
4656 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-spill-different-register-in-block/0")
4657 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-spill-different-register-in-block/1")
4658 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-spill-different-register-in-block/2")
4659 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-spill-different-register-in-block/3")
4660 (check-next-stream-line-equal _test-output-stream " {" "F - test-spill-different-register-in-block/4")
4661 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-spill-different-register-in-block/5")
4662 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-spill-different-register-in-block/6")
4663 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-spill-different-register-in-block/7")
4664 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-spill-different-register-in-block/8")
4665 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-spill-different-register-in-block/9")
4666 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-spill-different-register-in-block/10")
4667 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-spill-different-register-in-block/11")
4668 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-spill-different-register-in-block/12")
4669 (check-next-stream-line-equal _test-output-stream " }" "F - test-spill-different-register-in-block/13")
4670 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-spill-different-register-in-block/14")
4671 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-spill-different-register-in-block/15")
4672 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-spill-different-register-in-block/16")
4673 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-spill-different-register-in-block/17")
4674 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-spill-different-register-in-block/18")
4676 89/<- %esp 5/r32/ebp
4680 test-convert-function-with-branches-in-block:
4683 89/<- %ebp 4/r32/esp
4685 (clear-stream _test-input-stream)
4686 (clear-stream $_test-input-buffered-file->buffer)
4687 (clear-stream _test-output-stream)
4688 (clear-stream $_test-output-buffered-file->buffer)
4690 (write _test-input-stream "fn foo x: int {\n")
4691 (write _test-input-stream " {\n")
4692 (write _test-input-stream " break-if->=\n")
4693 (write _test-input-stream " loop-if-addr<\n")
4694 (write _test-input-stream " increment x\n")
4695 (write _test-input-stream " loop\n")
4696 (write _test-input-stream " }\n")
4697 (write _test-input-stream "}\n")
4699 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4700 (flush _test-output-buffered-file)
4701 #? # dump _test-output-stream {{{
4703 #? (write-stream 2 _test-output-stream)
4705 #? (rewind-stream _test-output-stream)
4708 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-block/0")
4709 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1")
4710 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2")
4711 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3")
4712 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4")
4713 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5")
4714 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6")
4715 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7")
4716 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/8")
4717 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-block/9")
4718 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-in-block/10")
4719 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/11")
4720 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/12")
4721 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-block/13")
4722 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-branches-in-block/14")
4723 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/15")
4724 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/16")
4725 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/17")
4726 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/18")
4727 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/19")
4728 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/20")
4729 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/21")
4730 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/22")
4731 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/23")
4732 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/24")
4733 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/25")
4735 89/<- %esp 5/r32/ebp
4739 test-convert-function-with-branches-in-block-2:
4742 89/<- %ebp 4/r32/esp
4744 (clear-stream _test-input-stream)
4745 (clear-stream $_test-input-buffered-file->buffer)
4746 (clear-stream _test-output-stream)
4747 (clear-stream $_test-output-buffered-file->buffer)
4749 (write _test-input-stream "fn foo x: int {\n")
4750 (write _test-input-stream " {\n")
4751 (write _test-input-stream " break-if->=\n")
4752 (write _test-input-stream " loop-if-float<\n")
4753 (write _test-input-stream " increment x\n")
4754 (write _test-input-stream " loop\n")
4755 (write _test-input-stream " }\n")
4756 (write _test-input-stream "}\n")
4758 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4759 (flush _test-output-buffered-file)
4760 #? # dump _test-output-stream {{{
4762 #? (write-stream 2 _test-output-stream)
4764 #? (rewind-stream _test-output-stream)
4767 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-block/0")
4768 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1")
4769 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2")
4770 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3")
4771 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4")
4772 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5")
4773 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6")
4774 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7")
4775 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/8")
4776 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-block/9")
4777 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-in-block/10")
4778 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/11")
4779 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/12")
4780 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-block/13")
4781 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-branches-in-block/14")
4782 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/15")
4783 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/16")
4784 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/17")
4785 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/18")
4786 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/19")
4787 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/20")
4788 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/21")
4789 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/22")
4790 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/23")
4791 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/24")
4792 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/25")
4794 89/<- %esp 5/r32/ebp
4798 test-convert-function-with-branches-in-named-block:
4801 89/<- %ebp 4/r32/esp
4803 (clear-stream _test-input-stream)
4804 (clear-stream $_test-input-buffered-file->buffer)
4805 (clear-stream _test-output-stream)
4806 (clear-stream $_test-output-buffered-file->buffer)
4808 (write _test-input-stream "fn foo x: int {\n")
4809 (write _test-input-stream " $bar: {\n")
4810 (write _test-input-stream " break-if->= $bar\n")
4811 (write _test-input-stream " loop-if-addr< $bar\n")
4812 (write _test-input-stream " increment x\n")
4813 (write _test-input-stream " loop\n")
4814 (write _test-input-stream " }\n")
4815 (write _test-input-stream "}\n")
4817 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4818 (flush _test-output-buffered-file)
4819 #? # dump _test-output-stream {{{
4821 #? (write-stream 2 _test-output-stream)
4823 #? (rewind-stream _test-output-stream)
4826 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-named-block/0")
4827 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-named-block/1")
4828 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-named-block/2")
4829 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-named-block/3")
4830 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/4")
4831 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-named-block/5")
4832 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/6")
4833 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-branches-in-named-block/7")
4834 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/8")
4835 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-named-block/9")
4836 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:break/disp32" "F - test-convert-function-with-branches-in-named-block/10")
4837 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/11")
4838 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/12")
4839 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-named-block/13")
4840 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:loop/disp32" "F - test-convert-function-with-branches-in-named-block/14")
4841 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/15")
4842 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-named-block/16")
4843 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-named-block/17")
4844 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/18")
4845 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-branches-in-named-block/19")
4846 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/20")
4847 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-named-block/21")
4848 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-named-block/22")
4849 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-named-block/23")
4850 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-named-block/24")
4851 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-named-block/25")
4853 89/<- %esp 5/r32/ebp
4857 test-convert-function-with-var-in-nested-block:
4860 89/<- %ebp 4/r32/esp
4862 (clear-stream _test-input-stream)
4863 (clear-stream $_test-input-buffered-file->buffer)
4864 (clear-stream _test-output-stream)
4865 (clear-stream $_test-output-buffered-file->buffer)
4867 (write _test-input-stream "fn foo x: int {\n")
4868 (write _test-input-stream " {\n")
4869 (write _test-input-stream " {\n")
4870 (write _test-input-stream " var x: int\n")
4871 (write _test-input-stream " increment x\n")
4872 (write _test-input-stream " }\n")
4873 (write _test-input-stream " }\n")
4874 (write _test-input-stream "}\n")
4876 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4877 (flush _test-output-buffered-file)
4878 #? # dump _test-output-stream {{{
4880 #? (write-stream 2 _test-output-stream)
4882 #? (rewind-stream _test-output-stream)
4885 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-var-in-nested-block/0")
4886 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-var-in-nested-block/1")
4887 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-var-in-nested-block/2")
4888 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-var-in-nested-block/3")
4889 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/4")
4890 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-var-in-nested-block/5")
4891 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/6")
4892 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-var-in-nested-block/7")
4893 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/8")
4894 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-var-in-nested-block/9")
4895 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-var-in-nested-block/10")
4896 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-var-in-nested-block/11")
4897 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-var-in-nested-block/12")
4898 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/13")
4899 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-var-in-nested-block/14")
4900 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/15")
4901 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-var-in-nested-block/16")
4902 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/17")
4903 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-var-in-nested-block/18")
4904 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-var-in-nested-block/19")
4905 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-var-in-nested-block/20")
4906 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-var-in-nested-block/21")
4907 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-var-in-nested-block/22")
4909 89/<- %esp 5/r32/ebp
4913 test-convert-function-with-multiple-vars-in-nested-blocks:
4916 89/<- %ebp 4/r32/esp
4918 (clear-stream _test-input-stream)
4919 (clear-stream $_test-input-buffered-file->buffer)
4920 (clear-stream _test-output-stream)
4921 (clear-stream $_test-output-buffered-file->buffer)
4923 (write _test-input-stream "fn foo x: int {\n")
4924 (write _test-input-stream " {\n")
4925 (write _test-input-stream " var x/eax: int <- copy 0\n")
4926 (write _test-input-stream " {\n")
4927 (write _test-input-stream " var y: int\n")
4928 (write _test-input-stream " x <- add y\n")
4929 (write _test-input-stream " }\n")
4930 (write _test-input-stream " }\n")
4931 (write _test-input-stream "}\n")
4933 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4934 (flush _test-output-buffered-file)
4935 #? # dump _test-output-stream {{{
4937 #? (write-stream 2 _test-output-stream)
4939 #? (rewind-stream _test-output-stream)
4942 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/0")
4943 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/1")
4944 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/2")
4945 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/3")
4946 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/4")
4947 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/5")
4948 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/6")
4949 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/7")
4950 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/8")
4951 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/9")
4952 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/10")
4953 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/11")
4954 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/12")
4955 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/13")
4956 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/14")
4957 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/15")
4958 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/16")
4959 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/17")
4960 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/18")
4961 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/19")
4962 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/20")
4963 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/21")
4964 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/22")
4965 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/23")
4966 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/24")
4967 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-multiple-vars-in-nested-blocks/25")
4969 89/<- %esp 5/r32/ebp
4973 test-convert-function-with-branches-and-local-vars:
4974 # A conditional 'break' after a 'var' in a block is converted into a
4975 # nested block that performs all necessary cleanup before jumping. This
4976 # results in some ugly code duplication.
4979 89/<- %ebp 4/r32/esp
4981 (clear-stream _test-input-stream)
4982 (clear-stream $_test-input-buffered-file->buffer)
4983 (clear-stream _test-output-stream)
4984 (clear-stream $_test-output-buffered-file->buffer)
4986 (write _test-input-stream "fn foo {\n")
4987 (write _test-input-stream " {\n")
4988 (write _test-input-stream " var x: int\n")
4989 (write _test-input-stream " break-if->=\n")
4990 (write _test-input-stream " increment x\n")
4991 (write _test-input-stream " }\n")
4992 (write _test-input-stream "}\n")
4994 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
4995 (flush _test-output-buffered-file)
4996 #? # dump _test-output-stream {{{
4998 #? (write-stream 2 _test-output-stream)
5000 #? (rewind-stream _test-output-stream)
5003 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-local-vars/0")
5004 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-local-vars/1")
5005 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-local-vars/2")
5006 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-local-vars/3")
5007 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/4")
5008 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-local-vars/5")
5009 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/6")
5010 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-local-vars/7")
5011 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-local-vars/8")
5012 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/9")
5013 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-local-vars/10")
5014 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-local-vars/11")
5015 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-local-vars/12")
5016 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/13")
5017 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-local-vars/14")
5018 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-local-vars/15")
5019 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/16")
5020 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-local-vars/17")
5021 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/18")
5022 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-local-vars/19")
5023 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-local-vars/20")
5024 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-local-vars/21")
5025 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-local-vars/22")
5026 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-local-vars/23")
5028 89/<- %esp 5/r32/ebp
5032 test-convert-function-with-conditional-loops-and-local-vars:
5033 # A conditional 'loop' after a 'var' in a block is converted into a nested
5034 # block that performs all necessary cleanup before jumping. This results
5035 # in some ugly code duplication.
5038 89/<- %ebp 4/r32/esp
5040 (clear-stream _test-input-stream)
5041 (clear-stream $_test-input-buffered-file->buffer)
5042 (clear-stream _test-output-stream)
5043 (clear-stream $_test-output-buffered-file->buffer)
5045 (write _test-input-stream "fn foo {\n")
5046 (write _test-input-stream " {\n")
5047 (write _test-input-stream " var x: int\n")
5048 (write _test-input-stream " loop-if->=\n")
5049 (write _test-input-stream " increment x\n")
5050 (write _test-input-stream " }\n")
5051 (write _test-input-stream "}\n")
5053 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5054 (flush _test-output-buffered-file)
5055 #? # dump _test-output-stream {{{
5057 #? (write-stream 2 _test-output-stream)
5059 #? (rewind-stream _test-output-stream)
5062 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-conditional-loops-and-local-vars/0")
5063 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-conditional-loops-and-local-vars/1")
5064 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/2")
5065 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-conditional-loops-and-local-vars/3")
5066 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/4")
5067 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/5")
5068 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/6")
5069 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/7")
5070 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/8")
5071 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/9")
5072 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-conditional-loops-and-local-vars/10")
5073 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/11")
5074 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-conditional-loops-and-local-vars/12")
5075 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/13")
5076 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-conditional-loops-and-local-vars/14")
5077 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/15")
5078 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/16")
5079 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/17")
5080 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/18")
5081 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/19")
5082 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-conditional-loops-and-local-vars/20")
5083 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/21")
5084 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/22")
5085 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-conditional-loops-and-local-vars/23")
5087 89/<- %esp 5/r32/ebp
5091 test-convert-function-with-unconditional-loops-and-local-vars:
5092 # An unconditional 'loop' after a 'var' in a block is emitted _after_ the
5093 # regular block cleanup. Any instructions after 'loop' are dead and
5094 # therefore skipped.
5097 89/<- %ebp 4/r32/esp
5099 (clear-stream _test-input-stream)
5100 (clear-stream $_test-input-buffered-file->buffer)
5101 (clear-stream _test-output-stream)
5102 (clear-stream $_test-output-buffered-file->buffer)
5104 (write _test-input-stream "fn foo {\n")
5105 (write _test-input-stream " {\n")
5106 (write _test-input-stream " var x: int\n")
5107 (write _test-input-stream " loop\n")
5108 (write _test-input-stream " increment x\n")
5109 (write _test-input-stream " }\n")
5110 (write _test-input-stream "}\n")
5112 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5113 (flush _test-output-buffered-file)
5114 #? # dump _test-output-stream {{{
5116 #? (write-stream 2 _test-output-stream)
5118 #? (rewind-stream _test-output-stream)
5121 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-loops-and-local-vars/0")
5122 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-loops-and-local-vars/1")
5123 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/2")
5124 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-loops-and-local-vars/3")
5125 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/4")
5126 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/5")
5127 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/6")
5128 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/7")
5129 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/8")
5130 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/9")
5131 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-unconditional-loops-and-local-vars/10")
5132 # not emitted: ff 0/subop/increment *(ebp+0xfffffffc)
5133 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/11")
5134 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/12")
5135 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/13")
5136 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/14")
5137 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-loops-and-local-vars/15")
5138 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/16")
5139 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/17")
5140 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-loops-and-local-vars/18")
5142 89/<- %esp 5/r32/ebp
5146 test-convert-function-with-branches-and-loops-and-local-vars:
5149 89/<- %ebp 4/r32/esp
5151 (clear-stream _test-input-stream)
5152 (clear-stream $_test-input-buffered-file->buffer)
5153 (clear-stream _test-output-stream)
5154 (clear-stream $_test-output-buffered-file->buffer)
5156 (write _test-input-stream "fn foo {\n")
5157 (write _test-input-stream " {\n")
5158 (write _test-input-stream " var x: int\n")
5159 (write _test-input-stream " break-if->=\n")
5160 (write _test-input-stream " increment x\n")
5161 (write _test-input-stream " loop\n")
5162 (write _test-input-stream " }\n")
5163 (write _test-input-stream "}\n")
5165 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5166 (flush _test-output-buffered-file)
5167 #? # dump _test-output-stream {{{
5169 #? (write-stream 2 _test-output-stream)
5171 #? (rewind-stream _test-output-stream)
5174 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-loops-and-local-vars/0")
5175 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-loops-and-local-vars/1")
5176 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/2")
5177 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-loops-and-local-vars/3")
5178 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/4")
5179 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/5")
5180 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/6")
5181 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/7")
5182 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/8")
5183 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/9")
5184 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/10")
5185 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/11")
5186 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/12")
5187 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/13")
5188 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-loops-and-local-vars/14")
5189 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/15")
5190 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/16")
5191 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/17")
5192 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/18")
5193 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/19")
5194 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/20")
5195 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-loops-and-local-vars/21")
5196 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/22")
5197 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/23")
5198 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-loops-and-local-vars/24")
5200 89/<- %esp 5/r32/ebp
5204 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars:
5207 89/<- %ebp 4/r32/esp
5209 (clear-stream _test-input-stream)
5210 (clear-stream $_test-input-buffered-file->buffer)
5211 (clear-stream _test-output-stream)
5212 (clear-stream $_test-output-buffered-file->buffer)
5214 (write _test-input-stream "fn foo {\n")
5215 (write _test-input-stream " a: {\n")
5216 (write _test-input-stream " var x: int\n")
5217 (write _test-input-stream " {\n")
5218 (write _test-input-stream " var y: int\n")
5219 (write _test-input-stream " break-if->= a\n")
5220 (write _test-input-stream " increment x\n")
5221 (write _test-input-stream " loop\n")
5222 (write _test-input-stream " }\n")
5223 (write _test-input-stream " }\n")
5224 (write _test-input-stream "}\n")
5226 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5227 (flush _test-output-buffered-file)
5228 #? # dump _test-output-stream {{{
5230 #? (write-stream 2 _test-output-stream)
5232 #? (rewind-stream _test-output-stream)
5235 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/0")
5236 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/1")
5237 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/2")
5238 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/3")
5239 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/4")
5240 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/5")
5241 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/6")
5242 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/7")
5243 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/8")
5244 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/9")
5245 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/10")
5246 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/11")
5247 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/12")
5248 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/13")
5249 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/14")
5250 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/15")
5251 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/16")
5252 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/17")
5253 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/18")
5254 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/19")
5255 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/20")
5256 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/21")
5257 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/22")
5258 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/23")
5259 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/24")
5260 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/25")
5261 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/26")
5262 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/27")
5263 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/28")
5264 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/29")
5265 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/30")
5266 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/31")
5268 89/<- %esp 5/r32/ebp
5272 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2:
5275 89/<- %ebp 4/r32/esp
5277 (clear-stream _test-input-stream)
5278 (clear-stream $_test-input-buffered-file->buffer)
5279 (clear-stream _test-output-stream)
5280 (clear-stream $_test-output-buffered-file->buffer)
5281 # non-local conditional branch from a block without a local variable,
5282 # unwinding a local on the stack
5283 (write _test-input-stream "fn foo {\n")
5284 (write _test-input-stream " a: {\n")
5285 (write _test-input-stream " var x: int\n")
5286 (write _test-input-stream " {\n")
5287 (write _test-input-stream " break-if->= a\n")
5288 (write _test-input-stream " }\n")
5289 (write _test-input-stream " }\n")
5290 (write _test-input-stream "}\n")
5292 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5293 (flush _test-output-buffered-file)
5294 #? # dump _test-output-stream {{{
5296 #? (write-stream 2 _test-output-stream)
5298 #? (rewind-stream _test-output-stream)
5301 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/0")
5302 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/1")
5303 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/2")
5304 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/3")
5305 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/4")
5306 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/5")
5307 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/6")
5308 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/7")
5309 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/8")
5310 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/9")
5311 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/10")
5312 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/11")
5313 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/12")
5314 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/13")
5315 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/14")
5316 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/15")
5317 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/16")
5318 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/17")
5319 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/18")
5320 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/19")
5321 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/20")
5322 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/21")
5323 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/22")
5324 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/23")
5325 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/24")
5326 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/25")
5327 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/26")
5329 89/<- %esp 5/r32/ebp
5333 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3:
5336 89/<- %ebp 4/r32/esp
5338 (clear-stream _test-input-stream)
5339 (clear-stream $_test-input-buffered-file->buffer)
5340 (clear-stream _test-output-stream)
5341 (clear-stream $_test-output-buffered-file->buffer)
5342 # non-local unconditional branch from a block without a local variable,
5343 # unwinding a local on the stack
5344 (write _test-input-stream "fn foo {\n")
5345 (write _test-input-stream " a: {\n")
5346 (write _test-input-stream " var x: int\n")
5347 (write _test-input-stream " {\n")
5348 (write _test-input-stream " break a\n")
5349 (write _test-input-stream " }\n")
5350 (write _test-input-stream " }\n")
5351 (write _test-input-stream "}\n")
5353 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5354 (flush _test-output-buffered-file)
5355 #? # dump _test-output-stream {{{
5357 #? (write-stream 2 _test-output-stream)
5359 #? (rewind-stream _test-output-stream)
5362 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/0")
5363 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/1")
5364 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/2")
5365 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/3")
5366 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/4")
5367 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/5")
5368 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/6")
5369 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/7")
5370 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/8")
5371 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/9")
5372 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/10")
5373 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/11")
5374 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/12")
5375 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/14")
5376 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/15")
5377 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/16")
5378 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/17")
5379 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/18")
5380 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/19")
5381 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/20")
5382 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/21")
5383 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/22")
5384 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/23")
5385 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/24")
5387 89/<- %esp 5/r32/ebp
5391 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4:
5394 89/<- %ebp 4/r32/esp
5396 (clear-stream _test-input-stream)
5397 (clear-stream $_test-input-buffered-file->buffer)
5398 (clear-stream _test-output-stream)
5399 (clear-stream $_test-output-buffered-file->buffer)
5401 (write _test-input-stream "fn foo {\n")
5402 (write _test-input-stream " a: {\n")
5403 (write _test-input-stream " var x/esi: int <- copy 0\n")
5404 (write _test-input-stream " {\n")
5405 (write _test-input-stream " break a\n")
5406 (write _test-input-stream " }\n")
5407 (write _test-input-stream " }\n")
5408 (write _test-input-stream "}\n")
5410 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5411 (flush _test-output-buffered-file)
5412 #? # dump _test-output-stream {{{
5414 #? (write-stream 2 _test-output-stream)
5416 #? (rewind-stream _test-output-stream)
5419 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/0")
5420 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/1")
5421 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/2")
5422 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/3")
5423 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/4")
5424 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/5")
5425 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/6")
5426 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/7")
5427 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/8")
5428 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/9")
5429 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/10")
5430 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/11")
5431 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/12")
5432 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/13")
5433 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/14")
5434 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/15")
5435 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/16")
5436 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/17")
5437 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/18")
5438 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/19")
5439 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/20")
5440 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/21")
5441 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/22")
5442 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/23")
5443 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/24")
5445 89/<- %esp 5/r32/ebp
5449 test-convert-function-with-nonlocal-unconditional-break-and-local-vars:
5452 89/<- %ebp 4/r32/esp
5454 (clear-stream _test-input-stream)
5455 (clear-stream $_test-input-buffered-file->buffer)
5456 (clear-stream _test-output-stream)
5457 (clear-stream $_test-output-buffered-file->buffer)
5459 (write _test-input-stream "fn foo {\n")
5460 (write _test-input-stream " a: {\n")
5461 (write _test-input-stream " var x: int\n")
5462 (write _test-input-stream " {\n")
5463 (write _test-input-stream " var y: int\n")
5464 (write _test-input-stream " break a\n")
5465 (write _test-input-stream " increment x\n")
5466 (write _test-input-stream " }\n")
5467 (write _test-input-stream " }\n")
5468 (write _test-input-stream "}\n")
5470 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5471 (flush _test-output-buffered-file)
5472 #? # dump _test-output-stream {{{
5474 #? (write-stream 2 _test-output-stream)
5476 #? (rewind-stream _test-output-stream)
5479 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/0")
5480 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/1")
5481 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/2")
5482 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/3")
5483 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/4")
5484 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/5")
5485 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/6")
5486 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/7")
5487 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/8")
5488 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/9")
5489 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/10")
5490 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/11")
5491 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/12")
5492 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/13")
5493 (check-next-stream-line-equal _test-output-stream " e9/jump a:break/disp32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/14")
5494 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/15")
5495 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/16")
5496 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/17")
5497 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/18")
5498 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/19")
5499 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/20")
5500 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/21")
5501 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/22")
5502 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/23")
5503 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/24")
5504 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/25")
5506 89/<- %esp 5/r32/ebp
5510 test-convert-function-with-unconditional-break-and-local-vars:
5513 89/<- %ebp 4/r32/esp
5515 (clear-stream _test-input-stream)
5516 (clear-stream $_test-input-buffered-file->buffer)
5517 (clear-stream _test-output-stream)
5518 (clear-stream $_test-output-buffered-file->buffer)
5520 (write _test-input-stream "fn foo {\n")
5521 (write _test-input-stream " {\n")
5522 (write _test-input-stream " var x: int\n")
5523 (write _test-input-stream " {\n")
5524 (write _test-input-stream " var y: int\n")
5525 (write _test-input-stream " break\n")
5526 (write _test-input-stream " increment x\n")
5527 (write _test-input-stream " }\n")
5528 (write _test-input-stream " }\n")
5529 (write _test-input-stream "}\n")
5531 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5532 (flush _test-output-buffered-file)
5533 #? # dump _test-output-stream {{{
5535 #? (write-stream 2 _test-output-stream)
5537 #? (rewind-stream _test-output-stream)
5540 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-break-and-local-vars/0")
5541 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-break-and-local-vars/1")
5542 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/2")
5543 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-break-and-local-vars/3")
5544 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/4")
5545 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/5")
5546 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/6")
5547 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/7")
5548 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/8")
5549 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/9")
5550 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/10")
5551 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/11")
5552 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/12")
5553 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/13")
5554 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/14")
5555 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/15")
5556 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/16")
5557 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/17")
5558 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/18")
5559 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/19")
5560 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-break-and-local-vars/20")
5561 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/21")
5562 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/22")
5563 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-break-and-local-vars/23")
5565 89/<- %esp 5/r32/ebp
5569 test-convert-function-with-nonlocal-unconditional-loop-and-local-vars:
5572 89/<- %ebp 4/r32/esp
5574 (clear-stream _test-input-stream)
5575 (clear-stream $_test-input-buffered-file->buffer)
5576 (clear-stream _test-output-stream)
5577 (clear-stream $_test-output-buffered-file->buffer)
5579 (write _test-input-stream "fn foo {\n")
5580 (write _test-input-stream " a: {\n")
5581 (write _test-input-stream " var x: int\n")
5582 (write _test-input-stream " {\n")
5583 (write _test-input-stream " var y: int\n")
5584 (write _test-input-stream " loop a\n")
5585 (write _test-input-stream " increment x\n")
5586 (write _test-input-stream " }\n")
5587 (write _test-input-stream " }\n")
5588 (write _test-input-stream "}\n")
5590 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5591 (flush _test-output-buffered-file)
5592 #? # dump _test-output-stream {{{
5594 #? (write-stream 2 _test-output-stream)
5596 #? (rewind-stream _test-output-stream)
5599 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/0")
5600 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/1")
5601 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/2")
5602 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/3")
5603 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/4")
5604 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/5")
5605 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/6")
5606 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/7")
5607 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/8")
5608 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/9")
5609 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/10")
5610 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/11")
5611 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/12")
5612 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/13")
5613 (check-next-stream-line-equal _test-output-stream " e9/jump a:loop/disp32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/14")
5614 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/15")
5615 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/16")
5616 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/17")
5617 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/18")
5618 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/19")
5619 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/20")
5620 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/21")
5621 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/22")
5622 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/23")
5623 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/24")
5624 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/25")
5626 89/<- %esp 5/r32/ebp
5630 test-convert-function-with-local-array-var-in-mem:
5633 89/<- %ebp 4/r32/esp
5635 (clear-stream _test-input-stream)
5636 (clear-stream $_test-input-buffered-file->buffer)
5637 (clear-stream _test-output-stream)
5638 (clear-stream $_test-output-buffered-file->buffer)
5640 (write _test-input-stream "fn foo {\n")
5641 (write _test-input-stream " var x: (array int 3)\n")
5642 (write _test-input-stream "}\n")
5644 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5645 (flush _test-output-buffered-file)
5646 #? # dump _test-output-stream {{{
5648 #? (write-stream 2 _test-output-stream)
5650 #? (rewind-stream _test-output-stream)
5653 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-var-in-mem/0")
5654 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-var-in-mem/1")
5655 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-var-in-mem/2")
5656 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-array-var-in-mem/3")
5657 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-var-in-mem/4")
5658 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-var-in-mem/5")
5660 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-function-with-local-array-var-in-mem/7")
5661 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-function-with-local-array-var-in-mem/8")
5663 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-function-with-local-array-var-in-mem/9")
5665 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-var-in-mem/10")
5666 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-var-in-mem/11")
5667 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-var-in-mem/12")
5668 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-array-var-in-mem/13")
5669 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-var-in-mem/14")
5670 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-var-in-mem/15")
5672 89/<- %esp 5/r32/ebp
5676 test-array-size-in-hex:
5679 89/<- %ebp 4/r32/esp
5681 (clear-stream _test-input-stream)
5682 (clear-stream $_test-input-buffered-file->buffer)
5683 (clear-stream _test-output-stream)
5684 (clear-stream $_test-output-buffered-file->buffer)
5685 (clear-stream _test-error-stream)
5686 (clear-stream $_test-error-buffered-file->buffer)
5687 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
5690 89/<- %edx 4/r32/esp
5691 (tailor-exit-descriptor %edx 0x10)
5693 (write _test-input-stream "fn foo {\n")
5694 (write _test-input-stream " var x: (array int 10)\n")
5695 (write _test-input-stream "}\n")
5697 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
5698 # registers except esp clobbered at this point
5700 89/<- %edx 4/r32/esp
5701 (flush _test-output-buffered-file)
5702 (flush _test-error-buffered-file)
5703 #? # dump _test-error-stream {{{
5705 #? (write-stream 2 _test-error-stream)
5707 #? (rewind-stream _test-error-stream)
5710 (check-stream-equal _test-output-stream "" "F - test-array-size-in-hex: output should be empty")
5711 (check-next-stream-line-equal _test-error-stream "literal integers are always hex in Mu; start '10' with a '0x' to be unambiguous, converting it to hexadecimal as necessary." "F - test-array-size-in-hex: error message")
5712 # check that stop(1) was called
5713 (check-ints-equal *(edx+4) 2 "F - test-array-size-in-hex: exit status")
5714 # don't restore from ebp
5715 81 0/subop/add %esp 8/imm32
5720 test-array-size-with-metadata:
5723 89/<- %ebp 4/r32/esp
5725 (clear-stream _test-input-stream)
5726 (clear-stream $_test-input-buffered-file->buffer)
5727 (clear-stream _test-output-stream)
5728 (clear-stream $_test-output-buffered-file->buffer)
5730 (write _test-input-stream "fn foo {\n")
5731 (write _test-input-stream " var x: (array int 3/bar)\n")
5732 (write _test-input-stream "}\n")
5734 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5735 (flush _test-output-buffered-file)
5736 #? # dump _test-output-stream {{{
5738 #? (write-stream 2 _test-output-stream)
5740 #? (rewind-stream _test-output-stream)
5744 89/<- %esp 5/r32/ebp
5748 test-convert-function-with-populate:
5751 89/<- %ebp 4/r32/esp
5753 (clear-stream _test-input-stream)
5754 (clear-stream $_test-input-buffered-file->buffer)
5755 (clear-stream _test-output-stream)
5756 (clear-stream $_test-output-buffered-file->buffer)
5758 (write _test-input-stream "fn foo {\n")
5759 (write _test-input-stream " var x/ecx: (addr handle array int) <- copy 0\n")
5760 (write _test-input-stream " populate x, 7\n")
5761 (write _test-input-stream "}\n")
5763 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5764 (flush _test-output-buffered-file)
5765 #? # dump _test-output-stream {{{
5767 #? (write-stream 2 _test-output-stream)
5769 #? (rewind-stream _test-output-stream)
5772 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-populate/0")
5773 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-populate/1")
5774 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-populate/2")
5775 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-populate/3")
5776 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-populate/4")
5777 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-populate/5")
5778 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-populate/6")
5779 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-populate/7")
5780 (check-next-stream-line-equal _test-output-stream " (allocate-array2 Heap 0x00000004 7 %ecx)" "F - test-convert-function-with-populate/8") # 4 = size-of(int)
5781 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-populate/9")
5782 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-populate/10")
5783 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-populate/11")
5784 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-populate/12")
5785 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-populate/13")
5786 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-populate/14")
5787 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-populate/15")
5789 89/<- %esp 5/r32/ebp
5793 # special-case for size(byte) when allocating array
5794 test-convert-function-with-local-array-of-bytes-in-mem:
5797 89/<- %ebp 4/r32/esp
5799 (clear-stream _test-input-stream)
5800 (clear-stream $_test-input-buffered-file->buffer)
5801 (clear-stream _test-output-stream)
5802 (clear-stream $_test-output-buffered-file->buffer)
5804 (write _test-input-stream "fn foo {\n")
5805 (write _test-input-stream " var x: (array byte 3)\n")
5806 (write _test-input-stream "}\n")
5808 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5809 (flush _test-output-buffered-file)
5810 #? # dump _test-output-stream {{{
5812 #? (write-stream 2 _test-output-stream)
5814 #? (rewind-stream _test-output-stream)
5817 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-of-bytes-in-mem/0")
5818 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-of-bytes-in-mem/1")
5819 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/2")
5820 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-array-of-bytes-in-mem/3")
5821 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-of-bytes-in-mem/4")
5822 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-of-bytes-in-mem/5")
5824 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x00000003)" "F - test-convert-function-with-local-array-of-bytes-in-mem/7")
5825 (check-next-stream-line-equal _test-output-stream " 68/push 0x00000003/imm32" "F - test-convert-function-with-local-array-of-bytes-in-mem/8")
5827 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000007/imm32" "F - test-convert-function-with-local-array-of-bytes-in-mem/9")
5829 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-of-bytes-in-mem/10")
5830 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-of-bytes-in-mem/11")
5831 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-of-bytes-in-mem/12")
5832 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/13")
5833 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/14")
5834 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-of-bytes-in-mem/15")
5836 89/<- %esp 5/r32/ebp
5840 test-convert-address:
5843 89/<- %ebp 4/r32/esp
5845 (clear-stream _test-input-stream)
5846 (clear-stream $_test-input-buffered-file->buffer)
5847 (clear-stream _test-output-stream)
5848 (clear-stream $_test-output-buffered-file->buffer)
5850 (write _test-input-stream "fn foo {\n")
5851 (write _test-input-stream " var a: int\n")
5852 (write _test-input-stream " var b/eax: (addr int) <- address a\n")
5853 (write _test-input-stream "}\n")
5855 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5856 (flush _test-output-buffered-file)
5857 #? # dump _test-output-stream {{{
5859 #? (write-stream 2 _test-output-stream)
5861 #? (rewind-stream _test-output-stream)
5864 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-address/0")
5865 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-address/1")
5866 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-address/2")
5867 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-address/3")
5868 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-address/4")
5869 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-address/5")
5870 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-address/6")
5871 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-address/7")
5872 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-address/8")
5873 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-address/9")
5874 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-address/10")
5875 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-address/11")
5876 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-address/12")
5877 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-address/13")
5878 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-address/14")
5879 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-address/15")
5880 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-address/16")
5882 89/<- %esp 5/r32/ebp
5886 test-convert-floating-point-convert:
5889 89/<- %ebp 4/r32/esp
5891 (clear-stream _test-input-stream)
5892 (clear-stream $_test-input-buffered-file->buffer)
5893 (clear-stream _test-output-stream)
5894 (clear-stream $_test-output-buffered-file->buffer)
5896 (write _test-input-stream "fn foo {\n")
5897 (write _test-input-stream " var a/eax: int <- copy 0\n")
5898 (write _test-input-stream " var b/xmm1: float <- convert a\n")
5899 (write _test-input-stream "}\n")
5901 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5902 (flush _test-output-buffered-file)
5903 #? # dump _test-output-stream {{{
5905 #? (write-stream 2 _test-output-stream)
5907 #? (rewind-stream _test-output-stream)
5910 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-floating-point-convert/0")
5911 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-floating-point-convert/1")
5912 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-floating-point-convert/2")
5913 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-floating-point-convert/3")
5914 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-floating-point-convert/4")
5915 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-floating-point-convert/5")
5916 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-floating-point-convert/6")
5917 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-floating-point-convert/7")
5918 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-convert/8")
5919 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-floating-point-convert/9")
5920 (check-next-stream-line-equal _test-output-stream " f3 0f 2a/convert-to-float %eax 0x00000001/x32" "F - test-convert-floating-point-convert/10")
5921 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 1/x32" "F - test-convert-floating-point-convert/11")
5922 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-floating-point-convert/12")
5923 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-floating-point-convert/13")
5924 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-floating-point-convert/14")
5925 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-floating-point-convert/15")
5926 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-floating-point-convert/16")
5927 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-floating-point-convert/17")
5928 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-floating-point-convert/18")
5929 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-floating-point-convert/19")
5931 89/<- %esp 5/r32/ebp
5935 test-convert-floating-point-convert-2:
5938 89/<- %ebp 4/r32/esp
5940 (clear-stream _test-input-stream)
5941 (clear-stream $_test-input-buffered-file->buffer)
5942 (clear-stream _test-output-stream)
5943 (clear-stream $_test-output-buffered-file->buffer)
5945 (write _test-input-stream "fn foo {\n")
5946 (write _test-input-stream " var a/eax: int <- copy 0\n")
5947 (write _test-input-stream " var b/xmm1: float <- convert a\n")
5948 (write _test-input-stream " a <- convert b\n")
5949 (write _test-input-stream "}\n")
5951 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
5952 (flush _test-output-buffered-file)
5953 #? # dump _test-output-stream {{{
5955 #? (write-stream 2 _test-output-stream)
5957 #? (rewind-stream _test-output-stream)
5960 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-floating-point-convert-2/0")
5961 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-floating-point-convert-2/1")
5962 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-floating-point-convert-2/2")
5963 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-floating-point-convert-2/3")
5964 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-floating-point-convert-2/4")
5965 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-floating-point-convert-2/5")
5966 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-floating-point-convert-2/6")
5967 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-floating-point-convert-2/7")
5968 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-convert-2/8")
5969 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-floating-point-convert-2/9")
5970 (check-next-stream-line-equal _test-output-stream " f3 0f 2a/convert-to-float %eax 0x00000001/x32" "F - test-convert-floating-point-convert-2/10")
5971 (check-next-stream-line-equal _test-output-stream " f3 0f 2d/convert-to-int %xmm1 0x00000000/r32" "F - test-convert-floating-point-convert-2/11")
5972 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 1/x32" "F - test-convert-floating-point-convert-2/12")
5973 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-floating-point-convert-2/13")
5974 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-floating-point-convert-2/14")
5975 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-floating-point-convert-2/15")
5976 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-floating-point-convert-2/16")
5977 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-floating-point-convert-2/17")
5978 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-floating-point-convert-2/18")
5979 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-floating-point-convert-2/19")
5980 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-floating-point-convert-2/20")
5982 89/<- %esp 5/r32/ebp
5986 test-convert-floating-point-operation:
5989 89/<- %ebp 4/r32/esp
5991 (clear-stream _test-input-stream)
5992 (clear-stream $_test-input-buffered-file->buffer)
5993 (clear-stream _test-output-stream)
5994 (clear-stream $_test-output-buffered-file->buffer)
5996 (write _test-input-stream "fn f {\n")
5997 (write _test-input-stream " var m: float\n")
5998 (write _test-input-stream " var x/xmm1: float <- copy m\n")
5999 (write _test-input-stream " var y/xmm5: float <- copy m\n")
6000 (write _test-input-stream " x <- copy y\n")
6001 (write _test-input-stream " copy-to m, y\n")
6002 (write _test-input-stream " x <- add y\n")
6003 (write _test-input-stream " x <- add m\n")
6004 (write _test-input-stream " x <- subtract y\n")
6005 (write _test-input-stream " x <- subtract m\n")
6006 (write _test-input-stream " x <- multiply y\n")
6007 (write _test-input-stream " x <- multiply m\n")
6008 (write _test-input-stream " x <- divide y\n")
6009 (write _test-input-stream " x <- divide m\n")
6010 (write _test-input-stream " x <- reciprocal y\n")
6011 (write _test-input-stream " x <- reciprocal m\n")
6012 (write _test-input-stream " x <- square-root y\n")
6013 (write _test-input-stream " x <- square-root m\n")
6014 (write _test-input-stream " x <- inverse-square-root y\n")
6015 (write _test-input-stream " x <- inverse-square-root m\n")
6016 (write _test-input-stream " x <- max y\n")
6017 (write _test-input-stream " x <- max m\n")
6018 (write _test-input-stream " x <- min y\n")
6019 (write _test-input-stream " x <- min m\n")
6020 (write _test-input-stream " compare x, y\n")
6021 (write _test-input-stream " compare x, m\n")
6022 (write _test-input-stream "}\n")
6024 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6025 (flush _test-output-buffered-file)
6026 #? # dump _test-output-stream {{{
6028 #? (write-stream 2 _test-output-stream)
6030 #? (rewind-stream _test-output-stream)
6033 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-floating-point-operation/0")
6034 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-floating-point-operation/1")
6035 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-floating-point-operation/2")
6036 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-floating-point-operation/3")
6037 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-floating-point-operation/4")
6038 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-floating-point-operation/5")
6039 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-floating-point-operation/6")
6040 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-operation/7")
6041 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-floating-point-operation/8")
6042 (check-next-stream-line-equal _test-output-stream " f3 0f 10/copy *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/9")
6043 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-operation/10")
6044 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 5/x32" "F - test-convert-floating-point-operation/11")
6045 (check-next-stream-line-equal _test-output-stream " f3 0f 10/copy *(ebp+0xfffffffc) 0x00000005/x32" "F - test-convert-floating-point-operation/12")
6046 (check-next-stream-line-equal _test-output-stream " f3 0f 11/copy %xmm1 0x00000005/x32" "F - test-convert-floating-point-operation/13")
6047 (check-next-stream-line-equal _test-output-stream " f3 0f 11/copy *(ebp+0xfffffffc) 0x00000005/x32" "F - test-convert-floating-point-operation/14")
6048 (check-next-stream-line-equal _test-output-stream " f3 0f 58/add %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/15")
6049 (check-next-stream-line-equal _test-output-stream " f3 0f 58/add *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/16")
6050 (check-next-stream-line-equal _test-output-stream " f3 0f 5c/subtract %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/17")
6051 (check-next-stream-line-equal _test-output-stream " f3 0f 5c/subtract *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/18")
6052 (check-next-stream-line-equal _test-output-stream " f3 0f 59/multiply %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/19")
6053 (check-next-stream-line-equal _test-output-stream " f3 0f 59/multiply *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/20")
6054 (check-next-stream-line-equal _test-output-stream " f3 0f 5e/divide %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/21")
6055 (check-next-stream-line-equal _test-output-stream " f3 0f 5e/divide *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/22")
6056 (check-next-stream-line-equal _test-output-stream " f3 0f 53/reciprocal %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/23")
6057 (check-next-stream-line-equal _test-output-stream " f3 0f 53/reciprocal *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/24")
6058 (check-next-stream-line-equal _test-output-stream " f3 0f 51/square-root %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/25")
6059 (check-next-stream-line-equal _test-output-stream " f3 0f 51/square-root *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/26")
6060 (check-next-stream-line-equal _test-output-stream " f3 0f 52/inverse-square-root %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/27")
6061 (check-next-stream-line-equal _test-output-stream " f3 0f 52/inverse-square-root *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/28")
6062 (check-next-stream-line-equal _test-output-stream " f3 0f 5f/max %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/29")
6063 (check-next-stream-line-equal _test-output-stream " f3 0f 5f/max *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/30")
6064 (check-next-stream-line-equal _test-output-stream " f3 0f 5d/min %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/31")
6065 (check-next-stream-line-equal _test-output-stream " f3 0f 5d/min *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/32")
6066 (check-next-stream-line-equal _test-output-stream " 0f 2f/compare %xmm5 0x00000001/x32" "F - test-convert-floating-point-operation/33")
6067 (check-next-stream-line-equal _test-output-stream " 0f 2f/compare *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-operation/34")
6068 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 5/x32" "F - test-convert-floating-point-operation/35")
6069 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-operation/36")
6070 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 1/x32" "F - test-convert-floating-point-operation/37")
6071 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-operation/38")
6072 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-floating-point-operation/39")
6073 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-floating-point-operation/40")
6074 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-floating-point-operation/41")
6075 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-floating-point-operation/42")
6076 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-floating-point-operation/43")
6077 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-floating-point-operation/44")
6078 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-floating-point-operation/45")
6080 89/<- %esp 5/r32/ebp
6084 test-convert-floating-point-dereferenced:
6087 89/<- %ebp 4/r32/esp
6089 (clear-stream _test-input-stream)
6090 (clear-stream $_test-input-buffered-file->buffer)
6091 (clear-stream _test-output-stream)
6092 (clear-stream $_test-output-buffered-file->buffer)
6094 (write _test-input-stream "fn f {\n")
6095 (write _test-input-stream " var m: float\n")
6096 (write _test-input-stream " var x/xmm1: float <- copy m\n")
6097 (write _test-input-stream " var y/eax: (addr float) <- copy 0\n")
6098 (write _test-input-stream " x <- multiply *y\n")
6099 (write _test-input-stream "}\n")
6101 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6102 (flush _test-output-buffered-file)
6103 #? # dump _test-output-stream {{{
6105 #? (write-stream 2 _test-output-stream)
6107 #? (rewind-stream _test-output-stream)
6110 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-floating-point-dereferenced/0")
6111 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-floating-point-dereferenced/1")
6112 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-floating-point-dereferenced/2")
6113 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-floating-point-dereferenced/3")
6114 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-floating-point-dereferenced/4")
6115 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-floating-point-dereferenced/5")
6116 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-floating-point-dereferenced/6")
6117 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-floating-point-dereferenced/7")
6118 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-floating-point-dereferenced/8")
6119 (check-next-stream-line-equal _test-output-stream " f3 0f 10/copy *(ebp+0xfffffffc) 0x00000001/x32" "F - test-convert-floating-point-dereferenced/9")
6120 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-floating-point-dereferenced/10")
6121 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-floating-point-dereferenced/11")
6122 (check-next-stream-line-equal _test-output-stream " f3 0f 59/multiply *eax 0x00000001/x32" "F - test-convert-floating-point-dereferenced/12")
6123 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-floating-point-dereferenced/13")
6124 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 1/x32" "F - test-convert-floating-point-dereferenced/14")
6125 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-dereferenced/15")
6126 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-floating-point-dereferenced/16")
6127 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-floating-point-dereferenced/17")
6128 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-floating-point-dereferenced/18")
6129 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-floating-point-dereferenced/19")
6130 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-floating-point-dereferenced/20")
6131 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-floating-point-dereferenced/21")
6132 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-floating-point-dereferenced/22")
6134 89/<- %esp 5/r32/ebp
6138 test-convert-length-of-array:
6141 89/<- %ebp 4/r32/esp
6143 (clear-stream _test-input-stream)
6144 (clear-stream $_test-input-buffered-file->buffer)
6145 (clear-stream _test-output-stream)
6146 (clear-stream $_test-output-buffered-file->buffer)
6148 (write _test-input-stream "fn foo a: (addr array int) {\n")
6149 (write _test-input-stream " var b/eax: (addr array int) <- copy a\n")
6150 (write _test-input-stream " var c/eax: int <- length b\n")
6151 (write _test-input-stream "}\n")
6153 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6154 (flush _test-output-buffered-file)
6155 #? # dump _test-output-stream {{{
6157 #? (write-stream 2 _test-output-stream)
6159 #? (rewind-stream _test-output-stream)
6162 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array/0")
6163 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array/1")
6164 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array/2")
6165 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array/3")
6166 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array/4")
6167 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array/5")
6168 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array/6")
6169 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array/7")
6170 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array/8")
6171 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array/9")
6172 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array/10")
6173 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array/11")
6174 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array/12")
6175 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array/13")
6176 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array/14")
6177 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array/15")
6178 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array/16")
6180 89/<- %esp 5/r32/ebp
6184 # special-case for size(byte) when computing array length
6185 test-convert-length-of-array-of-bytes:
6188 89/<- %ebp 4/r32/esp
6190 (clear-stream _test-input-stream)
6191 (clear-stream $_test-input-buffered-file->buffer)
6192 (clear-stream _test-output-stream)
6193 (clear-stream $_test-output-buffered-file->buffer)
6195 (write _test-input-stream "fn foo a: (addr array byte) {\n")
6196 (write _test-input-stream " var b/eax: (addr array byte) <- copy a\n")
6197 (write _test-input-stream " var c/eax: int <- length b\n")
6198 (write _test-input-stream "}\n")
6200 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6201 (flush _test-output-buffered-file)
6202 #? # dump _test-output-stream {{{
6204 #? (write-stream 2 _test-output-stream)
6206 #? (rewind-stream _test-output-stream)
6209 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-bytes/0")
6210 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-bytes/1")
6211 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-bytes/2")
6212 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-bytes/3")
6213 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-bytes/4")
6214 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-bytes/5")
6215 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-bytes/6")
6216 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/7")
6217 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/8")
6218 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-bytes/9")
6219 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-bytes/10")
6220 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-bytes/11")
6221 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-bytes/12")
6222 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-bytes/13")
6223 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-bytes/14")
6224 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-bytes/15")
6226 89/<- %esp 5/r32/ebp
6230 test-convert-length-of-array-on-stack:
6233 89/<- %ebp 4/r32/esp
6235 (clear-stream _test-input-stream)
6236 (clear-stream $_test-input-buffered-file->buffer)
6237 (clear-stream _test-output-stream)
6238 (clear-stream $_test-output-buffered-file->buffer)
6240 (write _test-input-stream "fn foo {\n")
6241 (write _test-input-stream " var a: (array int 3)\n")
6242 (write _test-input-stream " var b/eax: int <- length a\n")
6243 (write _test-input-stream "}\n")
6245 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6246 (flush _test-output-buffered-file)
6247 #? # dump _test-output-stream {{{
6249 #? (write-stream 2 _test-output-stream)
6251 #? (rewind-stream _test-output-stream)
6254 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-on-stack/0")
6255 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-on-stack/1")
6256 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-on-stack/2")
6257 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-on-stack/3")
6258 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-on-stack/4")
6259 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-on-stack/5")
6261 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-length-of-array-on-stack/6")
6262 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-length-of-array-on-stack/7")
6263 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-on-stack/8")
6264 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff0) 0x00000000/r32" "F - test-convert-length-of-array-on-stack/9")
6265 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array-on-stack/10")
6266 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-on-stack/11")
6267 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-length-of-array-on-stack/12")
6268 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-on-stack/13")
6269 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-on-stack/14")
6270 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-on-stack/15")
6271 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-on-stack/16")
6272 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-on-stack/17")
6273 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-on-stack/18")
6275 89/<- %esp 5/r32/ebp
6279 test-reg-var-def-with-read-of-same-register:
6282 89/<- %ebp 4/r32/esp
6284 (clear-stream _test-input-stream)
6285 (clear-stream $_test-input-buffered-file->buffer)
6286 (clear-stream _test-output-stream)
6287 (clear-stream $_test-output-buffered-file->buffer)
6288 (clear-stream _test-error-stream)
6289 (clear-stream $_test-error-buffered-file->buffer)
6290 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu
6293 89/<- %edx 4/r32/esp
6294 (tailor-exit-descriptor %edx 0x10)
6296 (write _test-input-stream "fn foo {\n")
6297 (write _test-input-stream " var x/eax: int <- copy 3\n")
6298 (write _test-input-stream " var y/eax: int <- add x\n")
6299 (write _test-input-stream "}\n")
6301 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
6302 # registers except esp could be clobbered at this point (though they shouldn't be)
6304 89/<- %edx 4/r32/esp
6305 (flush _test-output-buffered-file)
6306 (flush _test-error-buffered-file)
6307 #? # dump _test-output-stream {{{
6309 #? (write-stream 2 _test-output-stream)
6311 #? (rewind-stream _test-output-stream)
6313 #? # dump _test-error-stream {{{
6315 #? (write-stream 2 _test-error-stream)
6317 #? (rewind-stream _test-error-stream)
6319 (check-stream-equal _test-error-stream "" "F - test-reg-var-def-with-read-of-same-register: error stream should be empty")
6321 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-reg-var-def-with-read-of-same-register/0")
6322 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-reg-var-def-with-read-of-same-register/1")
6323 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-reg-var-def-with-read-of-same-register/2")
6324 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-reg-var-def-with-read-of-same-register/3")
6325 (check-next-stream-line-equal _test-output-stream " {" "F - test-reg-var-def-with-read-of-same-register/4")
6326 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-reg-var-def-with-read-of-same-register/5")
6327 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-reg-var-def-with-read-of-same-register/6")
6328 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-reg-var-def-with-read-of-same-register/7")
6329 (check-next-stream-line-equal _test-output-stream " 01/add-to %eax 0x00000000/r32" "F - test-reg-var-def-with-read-of-same-register/8")
6330 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-reg-var-def-with-read-of-same-register/9")
6331 (check-next-stream-line-equal _test-output-stream " }" "F - test-reg-var-def-with-read-of-same-register/10")
6332 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-reg-var-def-with-read-of-same-register/11")
6333 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-reg-var-def-with-read-of-same-register/12")
6334 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-reg-var-def-with-read-of-same-register/13")
6335 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-reg-var-def-with-read-of-same-register/14")
6336 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-reg-var-def-with-read-of-same-register/15")
6337 # don't restore from ebp
6338 81 0/subop/add %esp 8/imm32
6343 test-convert-index-into-array:
6346 89/<- %ebp 4/r32/esp
6348 (clear-stream _test-input-stream)
6349 (clear-stream $_test-input-buffered-file->buffer)
6350 (clear-stream _test-output-stream)
6351 (clear-stream $_test-output-buffered-file->buffer)
6353 (write _test-input-stream "fn foo {\n")
6354 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n")
6355 (write _test-input-stream " var idx/ecx: int <- copy 3\n")
6356 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n")
6357 (write _test-input-stream "}\n")
6359 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6360 (flush _test-output-buffered-file)
6361 #? # dump _test-output-stream {{{
6363 #? (write-stream 2 _test-output-stream)
6365 #? (rewind-stream _test-output-stream)
6368 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array/0")
6369 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array/1")
6370 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array/2")
6371 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array/3")
6372 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array/4")
6373 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array/5")
6374 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array/6")
6375 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array/7")
6376 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array/8")
6377 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array/9")
6378 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 0x00000004 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array/10")
6379 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array/11")
6380 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array/12")
6381 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-convert-index-into-array/13")
6382 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array/14")
6383 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array/15")
6384 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array/16")
6385 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array/17")
6386 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array/18")
6387 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array/19")
6388 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array/20")
6389 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array/21")
6391 89/<- %esp 5/r32/ebp
6395 test-convert-index-into-array-of-bytes:
6398 89/<- %ebp 4/r32/esp
6400 (clear-stream _test-input-stream)
6401 (clear-stream $_test-input-buffered-file->buffer)
6402 (clear-stream _test-output-stream)
6403 (clear-stream $_test-output-buffered-file->buffer)
6405 (write _test-input-stream "fn foo {\n")
6406 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n")
6407 (write _test-input-stream " var idx/ecx: int <- copy 3\n")
6408 (write _test-input-stream " var x/eax: (addr byte) <- index arr, idx\n")
6409 (write _test-input-stream "}\n")
6411 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6412 (flush _test-output-buffered-file)
6413 #? # dump _test-output-stream {{{
6415 #? (write-stream 2 _test-output-stream)
6417 #? (rewind-stream _test-output-stream)
6420 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes/0")
6421 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes/1")
6422 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes/2")
6423 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes/3")
6424 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes/4")
6425 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes/5")
6426 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes/6")
6427 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes/7")
6428 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes/8")
6429 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes/9")
6430 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 0x00000001 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes/10")
6431 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-of-bytes/11")
6432 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-of-bytes/12")
6433 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000000 + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes/13")
6434 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes/14")
6435 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes/15")
6436 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes/16")
6437 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes/17")
6438 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes/18")
6439 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes/19")
6440 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes/20")
6441 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes/21")
6443 89/<- %esp 5/r32/ebp
6447 test-convert-index-into-array-with-literal:
6450 89/<- %ebp 4/r32/esp
6452 (clear-stream _test-input-stream)
6453 (clear-stream $_test-input-buffered-file->buffer)
6454 (clear-stream _test-output-stream)
6455 (clear-stream $_test-output-buffered-file->buffer)
6457 (write _test-input-stream "fn foo {\n")
6458 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n")
6459 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n")
6460 (write _test-input-stream "}\n")
6462 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6463 (flush _test-output-buffered-file)
6464 #? # dump _test-output-stream {{{
6466 #? (write-stream 2 _test-output-stream)
6468 #? (rewind-stream _test-output-stream)
6471 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-with-literal/0")
6472 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-with-literal/1")
6473 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-with-literal/2")
6474 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-with-literal/3")
6475 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-with-literal/4")
6476 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5")
6477 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6")
6478 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7")
6479 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds 2 0x00000004 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-with-literal/8")
6480 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-with-literal/9")
6481 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-with-literal/10")
6482 # 2 * 4 bytes/elem + 4 bytes for size = offset 12
6483 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/11")
6484 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/12")
6485 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/13")
6486 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-with-literal/14")
6487 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-with-literal/15")
6488 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-with-literal/16")
6489 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-with-literal/17")
6490 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-with-literal/18")
6492 89/<- %esp 5/r32/ebp
6496 test-convert-index-into-array-of-bytes-with-literal:
6499 89/<- %ebp 4/r32/esp
6501 (clear-stream _test-input-stream)
6502 (clear-stream $_test-input-buffered-file->buffer)
6503 (clear-stream _test-output-stream)
6504 (clear-stream $_test-output-buffered-file->buffer)
6506 (write _test-input-stream "fn foo {\n")
6507 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n")
6508 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n")
6509 (write _test-input-stream "}\n")
6511 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6512 (flush _test-output-buffered-file)
6513 #? # dump _test-output-stream {{{
6515 #? (write-stream 2 _test-output-stream)
6517 #? (rewind-stream _test-output-stream)
6520 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-with-literal/0")
6521 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-with-literal/1")
6522 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/2")
6523 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-with-literal/3")
6524 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-with-literal/4")
6525 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-with-literal/5")
6526 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-with-literal/6")
6527 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-with-literal/7")
6528 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds 2 0x00000001 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes-with-literal/8")
6529 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-of-bytes-with-literal/9")
6530 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-of-bytes-with-literal/10")
6531 # 2 * 1 byte/elem + 4 bytes for size = offset 6
6532 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000006) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-with-literal/11")
6533 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-with-literal/12")
6534 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-with-literal/13")
6535 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-with-literal/14")
6536 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-with-literal/15")
6537 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-with-literal/16")
6538 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/17")
6539 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-with-literal/18")
6541 89/<- %esp 5/r32/ebp
6545 test-convert-index-into-array-on-stack:
6548 89/<- %ebp 4/r32/esp
6550 (clear-stream _test-input-stream)
6551 (clear-stream $_test-input-buffered-file->buffer)
6552 (clear-stream _test-output-stream)
6553 (clear-stream $_test-output-buffered-file->buffer)
6555 (write _test-input-stream "fn foo {\n")
6556 (write _test-input-stream " var arr: (array int 3)\n")
6557 (write _test-input-stream " var idx/eax: int <- copy 2\n")
6558 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n")
6559 (write _test-input-stream "}\n")
6561 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6562 (flush _test-output-buffered-file)
6563 #? # dump _test-output-stream {{{
6565 #? (write-stream 2 _test-output-stream)
6567 #? (rewind-stream _test-output-stream)
6570 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack/0")
6571 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack/1")
6572 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack/2")
6573 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack/3")
6574 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack/4")
6575 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack/5")
6577 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack/6")
6578 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack/7")
6580 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack/8")
6581 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 2/imm32" "F - test-convert-index-into-array-on-stack/9")
6582 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %eax 0x00000004 *(ebp+0xfffffff0) \"foo\" \"arr\")" "F - test-convert-index-into-array-on-stack/10")
6583 # var x is at (ebp-0x10) + idx<<2 + 4 = ebp + idx<<2 - 0xc
6584 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + eax<<0x00000002 + 0xfffffff4) 0x00000000/r32" "F - test-convert-index-into-array-on-stack/11")
6586 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack/12")
6588 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack/13")
6590 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack/14")
6591 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack/15")
6592 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack/16")
6593 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack/17")
6594 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack/18")
6595 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack/19")
6597 89/<- %esp 5/r32/ebp
6601 test-convert-index-into-array-on-stack-with-literal:
6604 89/<- %ebp 4/r32/esp
6606 (clear-stream _test-input-stream)
6607 (clear-stream $_test-input-buffered-file->buffer)
6608 (clear-stream _test-output-stream)
6609 (clear-stream $_test-output-buffered-file->buffer)
6611 (write _test-input-stream "fn foo {\n")
6612 (write _test-input-stream " var arr: (array int 3)\n")
6613 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n")
6614 (write _test-input-stream "}\n")
6616 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6617 (flush _test-output-buffered-file)
6618 #? # dump _test-output-stream {{{
6620 #? (write-stream 2 _test-output-stream)
6622 #? (rewind-stream _test-output-stream)
6625 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack-with-literal/0")
6626 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack-with-literal/1")
6627 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack-with-literal/2")
6628 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack-with-literal/3")
6629 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack-with-literal/4")
6630 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack-with-literal/5")
6632 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack-with-literal/6")
6633 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack-with-literal/7")
6635 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack-with-literal/8")
6636 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds 2 0x00000004 *(ebp+0xfffffff0) \"foo\" \"arr\")" "F - test-convert-index-into-array-on-stack-with-literal/9")
6637 # x is at (ebp-0x10) + 4 + 2*4 = ebp-4
6638 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + 0xfffffffc) 0x00000000/r32" "F - test-convert-index-into-array-on-stack-with-literal/10")
6640 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack-with-literal/11")
6642 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack-with-literal/12")
6644 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack-with-literal/13")
6645 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack-with-literal/14")
6646 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack-with-literal/15")
6647 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack-with-literal/16")
6648 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack-with-literal/17")
6649 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack-with-literal/18")
6651 89/<- %esp 5/r32/ebp
6655 test-convert-index-into-array-of-bytes-on-stack-with-literal:
6658 89/<- %ebp 4/r32/esp
6660 (clear-stream _test-input-stream)
6661 (clear-stream $_test-input-buffered-file->buffer)
6662 (clear-stream _test-output-stream)
6663 (clear-stream $_test-output-buffered-file->buffer)
6665 (write _test-input-stream "fn foo {\n")
6666 (write _test-input-stream " var arr: (array byte 3)\n")
6667 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n")
6668 (write _test-input-stream "}\n")
6670 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6671 (flush _test-output-buffered-file)
6672 #? # dump _test-output-stream {{{
6674 #? (write-stream 2 _test-output-stream)
6676 #? (rewind-stream _test-output-stream)
6679 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/0")
6680 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/1")
6681 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/2")
6682 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/3")
6683 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/4")
6684 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/5")
6686 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x00000003)" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/6")
6687 (check-next-stream-line-equal _test-output-stream " 68/push 0x00000003/imm32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/7")
6689 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/8")
6690 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds 2 0x00000001 *(ebp+0xfffffff9) \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/9")
6691 # x is at (ebp-7) + 4 + 2 = ebp-1
6692 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp + 0xffffffff) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/10")
6694 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/11")
6696 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000007/imm32" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/12")
6698 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/13")
6699 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/14")
6700 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/15")
6701 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/16")
6702 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/17")
6703 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/18")
6705 89/<- %esp 5/r32/ebp
6709 test-convert-index-into-array-using-offset:
6712 89/<- %ebp 4/r32/esp
6714 (clear-stream _test-input-stream)
6715 (clear-stream $_test-input-buffered-file->buffer)
6716 (clear-stream _test-output-stream)
6717 (clear-stream $_test-output-buffered-file->buffer)
6719 (write _test-input-stream "fn foo {\n")
6720 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n")
6721 (write _test-input-stream " var idx/ecx: int <- copy 3\n")
6722 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n")
6723 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n")
6724 (write _test-input-stream "}\n")
6726 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6727 (flush _test-output-buffered-file)
6728 #? # dump _test-output-stream {{{
6730 #? (write-stream 2 _test-output-stream)
6732 #? (rewind-stream _test-output-stream)
6735 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset/0")
6736 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset/1")
6737 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset/2")
6738 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset/3")
6739 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset/4")
6740 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset/5")
6741 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset/6")
6742 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset/7")
6743 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset/8")
6744 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-using-offset/9")
6745 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10")
6746 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 1 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-using-offset/11")
6747 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-using-offset/12")
6748 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-using-offset/13")
6749 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset/15")
6750 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset/16")
6751 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset/17")
6752 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset/18")
6753 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset/19")
6754 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset/20")
6755 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset/21")
6756 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset/22")
6757 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset/23")
6759 89/<- %esp 5/r32/ebp
6763 test-convert-compute-offset-using-literal-index:
6766 89/<- %ebp 4/r32/esp
6768 (clear-stream _test-input-stream)
6769 (clear-stream $_test-input-buffered-file->buffer)
6770 (clear-stream _test-output-stream)
6771 (clear-stream $_test-output-buffered-file->buffer)
6773 (write _test-input-stream "fn foo {\n")
6774 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n")
6775 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, 3\n")
6776 (write _test-input-stream "}\n")
6778 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6779 (flush _test-output-buffered-file)
6780 #? # dump _test-output-stream {{{
6782 #? (write-stream 2 _test-output-stream)
6784 #? (rewind-stream _test-output-stream)
6787 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-compute-offset-using-literal-index/0")
6788 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-compute-offset-using-literal-index/1")
6789 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-compute-offset-using-literal-index/2")
6790 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-compute-offset-using-literal-index/3")
6791 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-compute-offset-using-literal-index/4")
6792 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-compute-offset-using-literal-index/5")
6793 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-compute-offset-using-literal-index/6")
6794 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-compute-offset-using-literal-index/7")
6795 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compute-offset-using-literal-index/8")
6796 (check-next-stream-line-equal _test-output-stream " c7/copy %ecx 0x0000000c/imm32" "F - test-convert-compute-offset-using-literal-index/9")
6797 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compute-offset-using-literal-index/10")
6798 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-compute-offset-using-literal-index/11")
6799 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-compute-offset-using-literal-index/12")
6800 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-compute-offset-using-literal-index/13")
6801 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-compute-offset-using-literal-index/14")
6802 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-compute-offset-using-literal-index/15")
6803 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-compute-offset-using-literal-index/16")
6804 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-compute-offset-using-literal-index/17")
6806 89/<- %esp 5/r32/ebp
6810 test-convert-index-into-array-of-bytes-using-offset:
6813 89/<- %ebp 4/r32/esp
6815 (clear-stream _test-input-stream)
6816 (clear-stream $_test-input-buffered-file->buffer)
6817 (clear-stream _test-output-stream)
6818 (clear-stream $_test-output-buffered-file->buffer)
6820 (write _test-input-stream "fn foo {\n")
6821 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n")
6822 (write _test-input-stream " var idx/ecx: int <- copy 3\n")
6823 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n")
6824 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n")
6825 (write _test-input-stream "}\n")
6827 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6828 (flush _test-output-buffered-file)
6829 #? # dump _test-output-stream {{{
6831 #? (write-stream 2 _test-output-stream)
6833 #? (rewind-stream _test-output-stream)
6836 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset/0")
6837 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset/1")
6838 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/2")
6839 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset/3")
6840 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset/4")
6841 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset/5")
6842 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset/6")
6843 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/7")
6844 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/8")
6845 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/9")
6846 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000001/imm32 0x00000001/r32" "F - test-convert-index-into-array-of-bytes-using-offset/10")
6847 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 1 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes-using-offset/11")
6848 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset/12")
6849 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-of-bytes-using-offset/13")
6850 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-using-offset/14")
6851 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/15")
6852 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset/16")
6853 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset/17")
6854 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset/18")
6855 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset/19")
6856 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset/20")
6857 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/21")
6858 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset/22")
6860 89/<- %esp 5/r32/ebp
6864 test-convert-index-into-array-using-offset-on-stack:
6867 89/<- %ebp 4/r32/esp
6869 (clear-stream _test-input-stream)
6870 (clear-stream $_test-input-buffered-file->buffer)
6871 (clear-stream _test-output-stream)
6872 (clear-stream $_test-output-buffered-file->buffer)
6874 (write _test-input-stream "fn foo {\n")
6875 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n")
6876 (write _test-input-stream " var idx: int\n")
6877 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n")
6878 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n")
6879 (write _test-input-stream "}\n")
6881 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6882 (flush _test-output-buffered-file)
6883 #? # dump _test-output-stream {{{
6885 #? (write-stream 2 _test-output-stream)
6887 #? (rewind-stream _test-output-stream)
6890 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset-on-stack/0")
6891 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset-on-stack/1")
6892 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset-on-stack/2")
6893 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset-on-stack/3")
6894 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset-on-stack/4")
6895 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset-on-stack/5")
6896 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset-on-stack/6")
6897 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/7")
6898 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/8")
6899 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset-on-stack/9")
6900 (check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset-on-stack/10")
6901 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 1 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-using-offset-on-stack/11")
6902 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/12")
6903 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-using-offset-on-stack/13")
6904 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset-on-stack/14")
6905 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset-on-stack/15")
6906 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-using-offset-on-stack/16")
6907 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset-on-stack/17")
6908 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset-on-stack/18")
6909 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset-on-stack/19")
6910 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset-on-stack/20")
6911 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset-on-stack/21")
6912 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset-on-stack/22")
6913 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset-on-stack/23")
6915 89/<- %esp 5/r32/ebp
6919 test-convert-index-into-array-of-bytes-using-offset-on-stack:
6922 89/<- %ebp 4/r32/esp
6924 (clear-stream _test-input-stream)
6925 (clear-stream $_test-input-buffered-file->buffer)
6926 (clear-stream _test-output-stream)
6927 (clear-stream $_test-output-buffered-file->buffer)
6929 (write _test-input-stream "fn foo {\n")
6930 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n")
6931 (write _test-input-stream " var idx: int\n")
6932 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n")
6933 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n")
6934 (write _test-input-stream "}\n")
6936 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6937 (flush _test-output-buffered-file)
6938 #? # dump _test-output-stream {{{
6940 #? (write-stream 2 _test-output-stream)
6942 #? (rewind-stream _test-output-stream)
6945 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/0")
6946 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/1")
6947 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/2")
6948 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/3")
6949 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/4")
6950 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/5")
6951 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/6")
6952 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/7")
6953 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/8")
6954 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/9")
6955 (check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000001/imm32 0x00000001/r32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/10")
6956 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 1 *eax \"foo\" \"arr\")" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/11")
6957 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/12")
6958 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/13")
6959 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/14")
6960 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/15")
6961 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/16")
6962 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/17")
6963 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/18")
6964 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/19")
6965 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/20")
6966 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/21")
6967 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/22")
6968 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/23")
6970 89/<- %esp 5/r32/ebp
6974 test-convert-function-and-type-definition:
6977 89/<- %ebp 4/r32/esp
6979 (clear-stream _test-input-stream)
6980 (clear-stream $_test-input-buffered-file->buffer)
6981 (clear-stream _test-output-stream)
6982 (clear-stream $_test-output-buffered-file->buffer)
6984 (write _test-input-stream "fn foo a: (addr t) {\n")
6985 (write _test-input-stream " var _a/eax: (addr t) <- copy a\n")
6986 (write _test-input-stream " var b/ecx: (addr int) <- get _a, x\n")
6987 (write _test-input-stream " var c/ecx: (addr int) <- get _a, y\n")
6988 (write _test-input-stream "}\n")
6989 (write _test-input-stream "type t {\n")
6990 (write _test-input-stream " x: int\n")
6991 (write _test-input-stream " y: int\n")
6992 (write _test-input-stream "}\n")
6994 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
6995 (flush _test-output-buffered-file)
6996 #? # dump _test-output-stream {{{
6998 #? (write-stream 2 _test-output-stream)
7000 #? (rewind-stream _test-output-stream)
7003 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-and-type-definition/0")
7004 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-and-type-definition/1")
7005 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-and-type-definition/2")
7006 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-and-type-definition/3")
7007 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-and-type-definition/4")
7008 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-and-type-definition/5")
7009 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-and-type-definition/6")
7010 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7")
7011 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-and-type-definition/8")
7012 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-function-and-type-definition/9")
7013 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-get-base-address/disp32" "F - test-convert-function-and-type-definition/10")
7014 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000000) 0x00000001/r32" "F - test-convert-function-and-type-definition/11")
7015 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-function-and-type-definition/12")
7016 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-get-base-address/disp32" "F - test-convert-function-and-type-definition/13")
7017 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000004) 0x00000001/r32" "F - test-convert-function-and-type-definition/14")
7018 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/15")
7019 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/16")
7020 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-and-type-definition/17")
7021 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-and-type-definition/18")
7022 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-and-type-definition/19")
7023 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-and-type-definition/20")
7024 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-and-type-definition/21")
7025 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-and-type-definition/22")
7027 89/<- %esp 5/r32/ebp
7031 test-type-definition-with-array:
7034 89/<- %ebp 4/r32/esp
7036 (clear-stream _test-input-stream)
7037 (clear-stream $_test-input-buffered-file->buffer)
7038 (clear-stream _test-output-stream)
7039 (clear-stream $_test-output-buffered-file->buffer)
7040 (clear-stream _test-error-stream)
7041 (clear-stream $_test-error-buffered-file->buffer)
7042 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
7045 89/<- %edx 4/r32/esp
7046 (tailor-exit-descriptor %edx 0x10)
7048 (write _test-input-stream "type t {\n")
7049 (write _test-input-stream " a: (array int 3)\n")
7050 (write _test-input-stream "}\n")
7052 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
7053 # registers except esp clobbered at this point
7055 89/<- %edx 4/r32/esp
7056 (flush _test-output-buffered-file)
7057 (flush _test-error-buffered-file)
7058 #? # dump _test-error-stream {{{
7060 #? (write-stream 2 _test-error-stream)
7062 #? (rewind-stream _test-error-stream)
7065 (check-stream-equal _test-output-stream "" "F - test-type-definition-with-array: output should be empty")
7066 (check-next-stream-line-equal _test-error-stream "type t: 'array' elements not allowed for now" "F - test-type-definition-with-array: error message")
7067 # check that stop(1) was called
7068 (check-ints-equal *(edx+4) 2 "F - test-type-definition-with-array: exit status")
7069 # don't restore from ebp
7070 81 0/subop/add %esp 8/imm32
7075 test-type-definition-with-addr:
7078 89/<- %ebp 4/r32/esp
7080 (clear-stream _test-input-stream)
7081 (clear-stream $_test-input-buffered-file->buffer)
7082 (clear-stream _test-output-stream)
7083 (clear-stream $_test-output-buffered-file->buffer)
7084 (clear-stream _test-error-stream)
7085 (clear-stream $_test-error-buffered-file->buffer)
7086 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
7089 89/<- %edx 4/r32/esp
7090 (tailor-exit-descriptor %edx 0x10)
7092 (write _test-input-stream "type t {\n")
7093 (write _test-input-stream " a: (addr int)\n")
7094 (write _test-input-stream "}\n")
7096 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
7097 # registers except esp clobbered at this point
7099 89/<- %edx 4/r32/esp
7100 (flush _test-output-buffered-file)
7101 (flush _test-error-buffered-file)
7102 #? # dump _test-error-stream {{{
7104 #? (write-stream 2 _test-error-stream)
7106 #? (rewind-stream _test-error-stream)
7109 (check-stream-equal _test-output-stream "" "F - test-type-definition-with-addr: output should be empty")
7110 (check-next-stream-line-equal _test-error-stream "type t: 'addr' elements not allowed" "F - test-type-definition-with-addr: error message")
7111 # check that stop(1) was called
7112 (check-ints-equal *(edx+4) 2 "F - test-type-definition-with-addr: exit status")
7113 # don't restore from ebp
7114 81 0/subop/add %esp 8/imm32
7119 test-convert-function-with-local-var-with-user-defined-type:
7122 89/<- %ebp 4/r32/esp
7124 (clear-stream _test-input-stream)
7125 (clear-stream $_test-input-buffered-file->buffer)
7126 (clear-stream _test-output-stream)
7127 (clear-stream $_test-output-buffered-file->buffer)
7129 (write _test-input-stream "fn foo {\n")
7130 (write _test-input-stream " var a: t\n")
7131 (write _test-input-stream "}\n")
7132 (write _test-input-stream "type t {\n")
7133 (write _test-input-stream " x: int\n")
7134 (write _test-input-stream " y: int\n")
7135 (write _test-input-stream "}\n")
7137 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
7138 (flush _test-output-buffered-file)
7139 #? # dump _test-output-stream {{{
7141 #? (write-stream 2 _test-output-stream)
7143 #? (rewind-stream _test-output-stream)
7146 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type/0")
7147 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type/1")
7148 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/2")
7149 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type/3")
7150 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type/4")
7151 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type/5")
7152 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/6")
7153 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/7")
7154 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/8")
7155 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type/9")
7156 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type/10")
7157 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type/11")
7158 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type/12")
7159 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/13")
7160 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type/14")
7162 89/<- %esp 5/r32/ebp
7166 test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type:
7169 89/<- %ebp 4/r32/esp
7171 (clear-stream _test-input-stream)
7172 (clear-stream $_test-input-buffered-file->buffer)
7173 (clear-stream _test-output-stream)
7174 (clear-stream $_test-output-buffered-file->buffer)
7176 (write _test-input-stream "fn foo {\n")
7177 (write _test-input-stream " var a: t\n")
7178 (write _test-input-stream "}\n")
7179 (write _test-input-stream "type t {\n")
7180 (write _test-input-stream " x: s\n")
7181 (write _test-input-stream "}\n")
7182 (write _test-input-stream "type s {\n")
7183 (write _test-input-stream " z: int\n")
7184 (write _test-input-stream "}\n")
7186 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
7187 (flush _test-output-buffered-file)
7188 #? # dump _test-output-stream {{{
7190 #? (write-stream 2 _test-output-stream)
7192 #? (rewind-stream _test-output-stream)
7195 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/0")
7196 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/1")
7197 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/2")
7198 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/3")
7199 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/4")
7200 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/5")
7201 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/7")
7202 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/8")
7203 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/9")
7204 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/10")
7205 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/11")
7206 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/12")
7207 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/13")
7208 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type-containing-user-defined-type/14")
7210 89/<- %esp 5/r32/ebp
7214 test-convert-function-call-with-arg-of-user-defined-type:
7217 89/<- %ebp 4/r32/esp
7219 (clear-stream _test-input-stream)
7220 (clear-stream $_test-input-buffered-file->buffer)
7221 (clear-stream _test-output-stream)
7222 (clear-stream $_test-output-buffered-file->buffer)
7224 (write _test-input-stream "fn f {\n")
7225 (write _test-input-stream " var a: t\n")
7226 (write _test-input-stream " foo a\n")
7227 (write _test-input-stream "}\n")
7228 (write _test-input-stream "fn foo x: t {\n")
7229 (write _test-input-stream "}\n")
7230 (write _test-input-stream "type t {\n")
7231 (write _test-input-stream " x: int\n")
7232 (write _test-input-stream " y: int\n")
7233 (write _test-input-stream "}\n")
7235 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
7236 (flush _test-output-buffered-file)
7237 #? # dump _test-output-stream {{{
7239 #? (write-stream 2 _test-output-stream)
7241 #? (rewind-stream _test-output-stream)
7244 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0")
7245 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1")
7246 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2")
7247 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3")
7248 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4")
7249 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5")
7251 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/6")
7252 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7")
7254 (check-next-stream-line-equal _test-output-stream " (foo *(ebp+0xfffffff8) *(ebp+0xfffffffc))" "F - test-convert-function-call-with-arg-of-user-defined-type/8")
7256 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/9")
7257 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10")
7258 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11")
7259 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12")
7260 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13")
7261 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14")
7262 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15")
7263 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16")
7264 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17")
7265 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18")
7266 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19")
7267 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20")
7268 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21")
7269 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22")
7270 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23")
7272 89/<- %esp 5/r32/ebp
7276 test-convert-function-call-with-arg-of-user-defined-type-register-indirect:
7279 89/<- %ebp 4/r32/esp
7281 (clear-stream _test-input-stream)
7282 (clear-stream $_test-input-buffered-file->buffer)
7283 (clear-stream _test-output-stream)
7284 (clear-stream $_test-output-buffered-file->buffer)
7286 (write _test-input-stream "fn f {\n")
7287 (write _test-input-stream " var a/eax: (addr t) <- copy 0\n")
7288 (write _test-input-stream " foo *a\n")
7289 (write _test-input-stream "}\n")
7290 (write _test-input-stream "fn foo x: t {\n")
7291 (write _test-input-stream "}\n")
7292 (write _test-input-stream "type t {\n")
7293 (write _test-input-stream " x: int\n")
7294 (write _test-input-stream " y: int\n")
7295 (write _test-input-stream "}\n")
7297 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
7298 (flush _test-output-buffered-file)
7299 #? # dump _test-output-stream {{{
7301 #? (write-stream 2 _test-output-stream)
7303 #? (rewind-stream _test-output-stream)
7306 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0")
7307 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1")
7308 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2")
7309 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/3")
7310 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4")
7311 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5")
7313 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/6")
7314 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7")
7316 (check-next-stream-line-equal _test-output-stream " (foo *(eax+0x00000000) *(eax+0x00000004))" "F - test-convert-function-call-with-arg-of-user-defined-type/8")
7318 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/9")
7319 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10")
7320 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11")
7321 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12")
7322 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/13")
7323 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14")
7324 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15")
7325 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16")
7326 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17")
7327 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18")
7328 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type/19")
7329 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20")
7330 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/21")
7331 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22")
7332 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23")
7334 89/<- %esp 5/r32/ebp
7338 # we don't have special support for call-by-reference; just explicitly create
7339 # a new variable with the address of the arg
7340 test-convert-function-call-with-arg-of-user-defined-type-by-reference:
7343 89/<- %ebp 4/r32/esp
7345 (clear-stream _test-input-stream)
7346 (clear-stream $_test-input-buffered-file->buffer)
7347 (clear-stream _test-output-stream)
7348 (clear-stream $_test-output-buffered-file->buffer)
7350 (write _test-input-stream "fn f {\n")
7351 (write _test-input-stream " var a: t\n")
7352 (write _test-input-stream " var b/eax: (addr t) <- address a\n")
7353 (write _test-input-stream " foo b\n")
7354 (write _test-input-stream "}\n")
7355 (write _test-input-stream "fn foo x: (addr t) {\n")
7356 (write _test-input-stream " var x/ecx: (addr t) <- copy x\n")
7357 (write _test-input-stream "}\n")
7358 (write _test-input-stream "type t {\n")
7359 (write _test-input-stream " x: int\n")
7360 (write _test-input-stream " y: int\n")
7361 (write _test-input-stream "}\n")
7363 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
7364 (flush _test-output-buffered-file)
7365 #? # dump _test-output-stream {{{
7367 #? (write-stream 2 _test-output-stream)
7369 #? (rewind-stream _test-output-stream)
7372 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/0")
7373 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/1")
7374 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/2")
7375 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/3")
7376 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/4")
7377 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/5")
7379 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/6")
7380 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/7")
7381 # var b/eax: (addr t)
7382 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/8")
7383 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/9")
7385 (check-next-stream-line-equal _test-output-stream " (foo %eax)" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/10")
7387 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/11")
7388 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/12")
7389 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/13")
7390 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/14")
7391 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/15")
7392 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/16")
7393 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/17")
7394 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/18")
7395 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/19")
7396 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/20")
7397 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/21")
7398 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/22")
7399 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23")
7400 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/24")
7401 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/25")
7402 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000001/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/26")
7403 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/27")
7404 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/28")
7405 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29")
7406 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/30")
7407 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/31")
7408 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/32")
7409 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/33")
7411 89/<- %esp 5/r32/ebp
7415 test-convert-get-on-local-variable:
7418 89/<- %ebp 4/r32/esp
7420 (clear-stream _test-input-stream)
7421 (clear-stream $_test-input-buffered-file->buffer)
7422 (clear-stream _test-output-stream)
7423 (clear-stream $_test-output-buffered-file->buffer)
7425 (write _test-input-stream "fn foo {\n")
7426 (write _test-input-stream " var a: t\n")
7427 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n")
7428 (write _test-input-stream "}\n")
7429 (write _test-input-stream "type t {\n")
7430 (write _test-input-stream " x: int\n")
7431 (write _test-input-stream " y: int\n")
7432 (write _test-input-stream "}\n")
7434 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
7435 (flush _test-output-buffered-file)
7436 #? # dump _test-output-stream {{{
7438 #? (write-stream 2 _test-output-stream)
7440 #? (rewind-stream _test-output-stream)
7443 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-local-variable/0")
7444 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-local-variable/1")
7445 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-local-variable/2")
7446 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-local-variable/3")
7447 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-local-variable/4")
7448 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-local-variable/5")
7450 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/6")
7451 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/7")
7453 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-local-variable/8")
7455 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000001/r32" "F - test-convert-get-on-local-variable/9")
7457 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-local-variable/10")
7459 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-get-on-local-variable/11")
7460 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-local-variable/12")
7461 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-local-variable/13")
7462 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-local-variable/14")
7463 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-local-variable/15")
7464 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-local-variable/16")
7465 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-local-variable/17")
7467 89/<- %esp 5/r32/ebp
7471 test-convert-get-on-function-argument:
7474 89/<- %ebp 4/r32/esp
7476 (clear-stream _test-input-stream)
7477 (clear-stream $_test-input-buffered-file->buffer)
7478 (clear-stream _test-output-stream)
7479 (clear-stream $_test-output-buffered-file->buffer)
7481 (write _test-input-stream "fn foo a: t {\n")
7482 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n")
7483 (write _test-input-stream "}\n")
7484 (write _test-input-stream "type t {\n")
7485 (write _test-input-stream " x: int\n")
7486 (write _test-input-stream " y: int\n")
7487 (write _test-input-stream "}\n")
7489 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
7490 (flush _test-output-buffered-file)
7491 #? # dump _test-output-stream {{{
7493 #? (write-stream 2 _test-output-stream)
7495 #? (rewind-stream _test-output-stream)
7498 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument/0")
7499 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument/1")
7500 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument/2")
7501 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument/3")
7502 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument/4")
7503 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument/5")
7505 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument/6")
7507 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument/7")
7509 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument/8")
7510 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument/9")
7511 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument/10")
7512 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument/11")
7513 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument/12")
7514 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument/13")
7515 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument/14")
7517 89/<- %esp 5/r32/ebp
7521 test-convert-get-on-function-argument-with-known-type:
7524 89/<- %ebp 4/r32/esp
7526 (clear-stream _test-input-stream)
7527 (clear-stream $_test-input-buffered-file->buffer)
7528 (clear-stream _test-output-stream)
7529 (clear-stream $_test-output-buffered-file->buffer)
7531 (write _test-input-stream "type t {\n")
7532 (write _test-input-stream " x: int\n")
7533 (write _test-input-stream " y: int\n")
7534 (write _test-input-stream "}\n")
7535 (write _test-input-stream "fn foo a: t {\n")
7536 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n")
7537 (write _test-input-stream "}\n")
7539 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
7540 (flush _test-output-buffered-file)
7541 #? # dump _test-output-stream {{{
7543 #? (write-stream 2 _test-output-stream)
7545 #? (rewind-stream _test-output-stream)
7548 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument-with-known-type/0")
7549 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument-with-known-type/1")
7550 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument-with-known-type/2")
7551 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument-with-known-type/3")
7552 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument-with-known-type/4")
7553 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument-with-known-type/5")
7555 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument-with-known-type/6")
7557 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument-with-known-type/7")
7559 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument-with-known-type/8")
7560 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument-with-known-type/9")
7561 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument-with-known-type/10")
7562 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument-with-known-type/11")
7563 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument-with-known-type/12")
7564 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument-with-known-type/13")
7565 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument-with-known-type/14")
7567 89/<- %esp 5/r32/ebp
7571 test-add-with-too-many-inouts:
7574 89/<- %ebp 4/r32/esp
7576 (clear-stream _test-input-stream)
7577 (clear-stream $_test-input-buffered-file->buffer)
7578 (clear-stream _test-output-stream)
7579 (clear-stream $_test-output-buffered-file->buffer)
7580 (clear-stream _test-error-stream)
7581 (clear-stream $_test-error-buffered-file->buffer)
7582 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
7585 89/<- %edx 4/r32/esp
7586 (tailor-exit-descriptor %edx 0x10)
7588 (write _test-input-stream "fn foo {\n")
7589 (write _test-input-stream " var a: int\n")
7590 (write _test-input-stream " var b/ecx: int <- add a, 0\n")
7591 (write _test-input-stream "}\n")
7593 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
7594 # registers except esp clobbered at this point
7596 89/<- %edx 4/r32/esp
7597 (flush _test-output-buffered-file)
7598 (flush _test-error-buffered-file)
7599 #? # dump _test-error-stream {{{
7601 #? (write-stream 2 _test-error-stream)
7603 #? (rewind-stream _test-error-stream)
7606 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts: output should be empty")
7607 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: too many inouts; most primitives support at most two arguments, across inouts and outputs" "F - test-add-with-too-many-inouts: error message")
7608 # check that stop(1) was called
7609 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts: exit status")
7610 # don't restore from ebp
7611 81 0/subop/add %esp 8/imm32
7616 test-add-with-too-many-inouts-2:
7619 89/<- %ebp 4/r32/esp
7621 (clear-stream _test-input-stream)
7622 (clear-stream $_test-input-buffered-file->buffer)
7623 (clear-stream _test-output-stream)
7624 (clear-stream $_test-output-buffered-file->buffer)
7625 (clear-stream _test-error-stream)
7626 (clear-stream $_test-error-buffered-file->buffer)
7627 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
7630 89/<- %edx 4/r32/esp
7631 (tailor-exit-descriptor %edx 0x10)
7633 (write _test-input-stream "fn foo {\n")
7634 (write _test-input-stream " var a: int\n")
7635 (write _test-input-stream " add-to a, 0, 1\n")
7636 (write _test-input-stream "}\n")
7638 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
7639 # registers except esp clobbered at this point
7641 89/<- %edx 4/r32/esp
7642 (flush _test-output-buffered-file)
7643 (flush _test-error-buffered-file)
7644 #? # dump _test-error-stream {{{
7646 #? (write-stream 2 _test-error-stream)
7648 #? (rewind-stream _test-error-stream)
7651 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts-2: output should be empty")
7652 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add-to: too many inouts; most primitives support at most two arguments, across inouts and outputs" "F - test-add-with-too-many-inouts-2: error message")
7653 # check that stop(1) was called
7654 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts-2: exit status")
7655 # don't restore from ebp
7656 81 0/subop/add %esp 8/imm32
7661 test-add-with-too-many-outputs:
7664 89/<- %ebp 4/r32/esp
7666 (clear-stream _test-input-stream)
7667 (clear-stream $_test-input-buffered-file->buffer)
7668 (clear-stream _test-output-stream)
7669 (clear-stream $_test-output-buffered-file->buffer)
7670 (clear-stream _test-error-stream)
7671 (clear-stream $_test-error-buffered-file->buffer)
7672 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
7675 89/<- %edx 4/r32/esp
7676 (tailor-exit-descriptor %edx 0x10)
7678 (write _test-input-stream "fn foo {\n")
7679 (write _test-input-stream " var a/eax: int <- copy 0\n")
7680 (write _test-input-stream " var b/ebx: int <- copy 0\n")
7681 (write _test-input-stream " var c/ecx: int <- copy 0\n")
7682 (write _test-input-stream " c, b <- add a\n")
7683 (write _test-input-stream "}\n")
7685 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
7686 # registers except esp clobbered at this point
7688 89/<- %edx 4/r32/esp
7689 (flush _test-output-buffered-file)
7690 (flush _test-error-buffered-file)
7691 #? # dump _test-error-stream {{{
7693 #? (write-stream 2 _test-error-stream)
7695 #? (rewind-stream _test-error-stream)
7698 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-outputs: output should be empty")
7699 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: too many outputs; most primitives support at most one output" "F - test-add-with-too-many-outputs: error message")
7700 # check that stop(1) was called
7701 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-outputs: exit status")
7702 # don't restore from ebp
7703 81 0/subop/add %esp 8/imm32
7708 test-add-with-non-number:
7711 89/<- %ebp 4/r32/esp
7713 (clear-stream _test-input-stream)
7714 (clear-stream $_test-input-buffered-file->buffer)
7715 (clear-stream _test-output-stream)
7716 (clear-stream $_test-output-buffered-file->buffer)
7717 (clear-stream _test-error-stream)
7718 (clear-stream $_test-error-buffered-file->buffer)
7719 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
7722 89/<- %edx 4/r32/esp
7723 (tailor-exit-descriptor %edx 0x10)
7725 (write _test-input-stream "fn foo {\n")
7726 (write _test-input-stream " var a: int\n")
7727 (write _test-input-stream " var b/ecx: (addr int) <- add a\n")
7728 (write _test-input-stream "}\n")
7730 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
7731 # registers except esp clobbered at this point
7733 89/<- %edx 4/r32/esp
7734 (flush _test-output-buffered-file)
7735 (flush _test-error-buffered-file)
7736 #? # dump _test-error-stream {{{
7738 #? (write-stream 2 _test-error-stream)
7740 #? (rewind-stream _test-error-stream)
7743 (check-stream-equal _test-output-stream "" "F - test-add-with-non-number: output should be empty")
7744 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: 'b' must be a non-addr non-offset scalar" "F - test-add-with-non-number: error message")
7745 # check that stop(1) was called
7746 (check-ints-equal *(edx+4) 2 "F - test-add-with-non-number: exit status")
7747 # don't restore from ebp
7748 81 0/subop/add %esp 8/imm32
7753 test-add-with-addr-dereferenced:
7756 89/<- %ebp 4/r32/esp
7758 (clear-stream _test-input-stream)
7759 (clear-stream $_test-input-buffered-file->buffer)
7760 (clear-stream _test-output-stream)
7761 (clear-stream $_test-output-buffered-file->buffer)
7763 (write _test-input-stream "fn foo {\n")
7764 (write _test-input-stream " var a/eax: (addr int) <- copy 0\n")
7765 (write _test-input-stream " add-to *a, 1\n")
7766 (write _test-input-stream "}\n")
7768 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
7769 (flush _test-output-buffered-file)
7772 89/<- %esp 5/r32/ebp
7776 test-copy-with-no-inout:
7779 89/<- %ebp 4/r32/esp
7781 (clear-stream _test-input-stream)
7782 (clear-stream $_test-input-buffered-file->buffer)
7783 (clear-stream _test-output-stream)
7784 (clear-stream $_test-output-buffered-file->buffer)
7785 (clear-stream _test-error-stream)
7786 (clear-stream $_test-error-buffered-file->buffer)
7787 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
7790 89/<- %edx 4/r32/esp
7791 (tailor-exit-descriptor %edx 0x10)
7793 (write _test-input-stream "fn foo {\n")
7794 (write _test-input-stream " var x/eax: boolean <- copy\n")
7795 (write _test-input-stream "}\n")
7797 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
7798 # registers except esp clobbered at this point
7800 89/<- %edx 4/r32/esp
7801 (flush _test-output-buffered-file)
7802 (flush _test-error-buffered-file)
7803 #? # dump _test-error-stream {{{
7805 #? (write-stream 2 _test-error-stream)
7807 #? (rewind-stream _test-error-stream)
7810 (check-stream-equal _test-output-stream "" "F - test-copy-with-no-inout: output should be empty")
7811 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy' expects an inout" "F - test-copy-with-no-inout: error message")
7812 # check that stop(1) was called
7813 (check-ints-equal *(edx+4) 2 "F - test-copy-with-no-inout: exit status")
7814 # don't restore from ebp
7815 81 0/subop/add %esp 8/imm32
7820 test-copy-with-multiple-inouts:
7823 89/<- %ebp 4/r32/esp
7825 (clear-stream _test-input-stream)
7826 (clear-stream $_test-input-buffered-file->buffer)
7827 (clear-stream _test-output-stream)
7828 (clear-stream $_test-output-buffered-file->buffer)
7829 (clear-stream _test-error-stream)
7830 (clear-stream $_test-error-buffered-file->buffer)
7831 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
7834 89/<- %edx 4/r32/esp
7835 (tailor-exit-descriptor %edx 0x10)
7837 (write _test-input-stream "fn foo {\n")
7838 (write _test-input-stream " var x/eax: boolean <- copy 0, 0\n")
7839 (write _test-input-stream "}\n")
7841 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
7842 # registers except esp clobbered at this point
7844 89/<- %edx 4/r32/esp
7845 (flush _test-output-buffered-file)
7846 (flush _test-error-buffered-file)
7847 #? # dump _test-error-stream {{{
7849 #? (write-stream 2 _test-error-stream)
7851 #? (rewind-stream _test-error-stream)
7854 (check-stream-equal _test-output-stream "" "F - test-copy-with-multiple-inouts: output should be empty")
7855 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy' must have just one inout" "F - test-copy-with-multiple-inouts: error message")
7856 # check that stop(1) was called
7857 (check-ints-equal *(edx+4) 2 "F - test-copy-with-multiple-inouts: exit status")
7858 # don't restore from ebp
7859 81 0/subop/add %esp 8/imm32
7864 test-copy-with-no-output:
7867 89/<- %ebp 4/r32/esp
7869 (clear-stream _test-input-stream)
7870 (clear-stream $_test-input-buffered-file->buffer)
7871 (clear-stream _test-output-stream)
7872 (clear-stream $_test-output-buffered-file->buffer)
7873 (clear-stream _test-error-stream)
7874 (clear-stream $_test-error-buffered-file->buffer)
7875 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
7878 89/<- %edx 4/r32/esp
7879 (tailor-exit-descriptor %edx 0x10)
7881 (write _test-input-stream "fn foo {\n")
7882 (write _test-input-stream " copy 0\n")
7883 (write _test-input-stream "}\n")
7885 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
7886 # registers except esp clobbered at this point
7888 89/<- %edx 4/r32/esp
7889 (flush _test-output-buffered-file)
7890 (flush _test-error-buffered-file)
7891 #? # dump _test-error-stream {{{
7893 #? (write-stream 2 _test-error-stream)
7895 #? (rewind-stream _test-error-stream)
7898 (check-stream-equal _test-output-stream "" "F - test-copy-with-no-output: output should be empty")
7899 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy' expects an output" "F - test-copy-with-no-output: error message")
7900 # check that stop(1) was called
7901 (check-ints-equal *(edx+4) 2 "F - test-copy-with-no-output: exit status")
7902 # don't restore from ebp
7903 81 0/subop/add %esp 8/imm32
7908 test-copy-with-multiple-outputs:
7911 89/<- %ebp 4/r32/esp
7913 (clear-stream _test-input-stream)
7914 (clear-stream $_test-input-buffered-file->buffer)
7915 (clear-stream _test-output-stream)
7916 (clear-stream $_test-output-buffered-file->buffer)
7917 (clear-stream _test-error-stream)
7918 (clear-stream $_test-error-buffered-file->buffer)
7919 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
7922 89/<- %edx 4/r32/esp
7923 (tailor-exit-descriptor %edx 0x10)
7925 (write _test-input-stream "fn foo {\n")
7926 (write _test-input-stream " var x/eax: boolean <- copy 0\n")
7927 (write _test-input-stream " var y/ecx: boolean <- copy 0\n")
7928 (write _test-input-stream " x, y <- copy 0\n")
7929 (write _test-input-stream "}\n")
7931 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
7932 # registers except esp clobbered at this point
7934 89/<- %edx 4/r32/esp
7935 (flush _test-output-buffered-file)
7936 (flush _test-error-buffered-file)
7937 #? # dump _test-error-stream {{{
7939 #? (write-stream 2 _test-error-stream)
7941 #? (rewind-stream _test-error-stream)
7944 (check-stream-equal _test-output-stream "" "F - test-copy-with-multiple-outputs: output should be empty")
7945 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy' must have just one output" "F - test-copy-with-multiple-outputs: error message")
7946 # check that stop(1) was called
7947 (check-ints-equal *(edx+4) 2 "F - test-copy-with-multiple-outputs: exit status")
7948 # don't restore from ebp
7949 81 0/subop/add %esp 8/imm32
7954 test-copy-invalid-value-to-address:
7957 89/<- %ebp 4/r32/esp
7959 (clear-stream _test-input-stream)
7960 (clear-stream $_test-input-buffered-file->buffer)
7961 (clear-stream _test-output-stream)
7962 (clear-stream $_test-output-buffered-file->buffer)
7963 (clear-stream _test-error-stream)
7964 (clear-stream $_test-error-buffered-file->buffer)
7965 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
7968 89/<- %edx 4/r32/esp
7969 (tailor-exit-descriptor %edx 0x10)
7971 (write _test-input-stream "fn foo {\n")
7972 (write _test-input-stream " var x/eax: int <- copy 0\n")
7973 (write _test-input-stream " var y/ecx: (addr int) <- copy x\n")
7974 (write _test-input-stream "}\n")
7976 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
7977 # registers except esp clobbered at this point
7979 89/<- %edx 4/r32/esp
7980 (flush _test-output-buffered-file)
7981 (flush _test-error-buffered-file)
7982 #? # dump _test-error-stream {{{
7984 #? (write-stream 2 _test-error-stream)
7986 #? (rewind-stream _test-error-stream)
7989 (check-stream-equal _test-output-stream "" "F - test-copy-invalid-value-to-address: output should be empty")
7990 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: 'y' must be a non-addr non-offset scalar" "F - test-copy-invalid-value-to-address: error message")
7991 # check that stop(1) was called
7992 (check-ints-equal *(edx+4) 2 "F - test-copy-invalid-value-to-address: exit status")
7993 # don't restore from ebp
7994 81 0/subop/add %esp 8/imm32
7999 test-copy-null-value-to-address:
8002 89/<- %ebp 4/r32/esp
8004 (clear-stream _test-input-stream)
8005 (clear-stream $_test-input-buffered-file->buffer)
8006 (clear-stream _test-output-stream)
8007 (clear-stream $_test-output-buffered-file->buffer)
8009 (write _test-input-stream "fn foo {\n")
8010 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n")
8011 (write _test-input-stream "}\n")
8013 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
8014 (flush _test-output-buffered-file)
8017 89/<- %esp 5/r32/ebp
8021 test-copy-string-literal:
8024 89/<- %ebp 4/r32/esp
8026 (clear-stream _test-input-stream)
8027 (clear-stream $_test-input-buffered-file->buffer)
8028 (clear-stream _test-output-stream)
8029 (clear-stream $_test-output-buffered-file->buffer)
8031 (write _test-input-stream "fn foo {\n")
8032 (write _test-input-stream " var y/ecx: (addr array byte) <- copy \"a\"\n")
8033 (write _test-input-stream "}\n")
8035 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
8036 (flush _test-output-buffered-file)
8038 #? # dump _test-output-stream {{{
8040 #? (write-stream 2 _test-output-stream)
8042 #? (rewind-stream _test-output-stream)
8045 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-copy-string-literal/0")
8046 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-copy-string-literal/1")
8047 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-copy-string-literal/2")
8048 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-copy-string-literal/3")
8049 (check-next-stream-line-equal _test-output-stream " {" "F - test-copy-string-literal/4")
8050 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-copy-string-literal/5")
8051 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-copy-string-literal/6")
8052 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx \"a\"/imm32" "F - test-copy-string-literal/7")
8053 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-copy-string-literal/8")
8054 (check-next-stream-line-equal _test-output-stream " }" "F - test-copy-string-literal/9")
8055 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-copy-string-literal/10")
8056 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-copy-string-literal/11")
8057 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-copy-string-literal/12")
8058 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-copy-string-literal/13")
8059 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-copy-string-literal/14")
8061 89/<- %esp 5/r32/ebp
8065 test-copy-invalid-value-to-offset:
8068 89/<- %ebp 4/r32/esp
8070 (clear-stream _test-input-stream)
8071 (clear-stream $_test-input-buffered-file->buffer)
8072 (clear-stream _test-output-stream)
8073 (clear-stream $_test-output-buffered-file->buffer)
8074 (clear-stream _test-error-stream)
8075 (clear-stream $_test-error-buffered-file->buffer)
8076 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8079 89/<- %edx 4/r32/esp
8080 (tailor-exit-descriptor %edx 0x10)
8082 (write _test-input-stream "fn foo {\n")
8083 (write _test-input-stream " var x/eax: int <- copy 0\n")
8084 (write _test-input-stream " var y/ecx: (offset int) <- copy x\n")
8085 (write _test-input-stream "}\n")
8087 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8088 # registers except esp clobbered at this point
8090 89/<- %edx 4/r32/esp
8091 (flush _test-output-buffered-file)
8092 (flush _test-error-buffered-file)
8093 #? # dump _test-error-stream {{{
8095 #? (write-stream 2 _test-error-stream)
8097 #? (rewind-stream _test-error-stream)
8100 (check-stream-equal _test-output-stream "" "F - test-copy-invalid-value-to-address: output should be empty")
8101 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: 'y' must be a non-addr non-offset scalar" "F - test-copy-invalid-value-to-address: error message")
8102 # check that stop(1) was called
8103 (check-ints-equal *(edx+4) 2 "F - test-copy-invalid-value-to-offset: exit status")
8104 # don't restore from ebp
8105 81 0/subop/add %esp 8/imm32
8110 test-copy-null-value-to-offset:
8113 89/<- %ebp 4/r32/esp
8115 (clear-stream _test-input-stream)
8116 (clear-stream $_test-input-buffered-file->buffer)
8117 (clear-stream _test-output-stream)
8118 (clear-stream $_test-output-buffered-file->buffer)
8120 (write _test-input-stream "fn foo {\n")
8121 (write _test-input-stream " var y/ecx: (offset int) <- copy 0\n")
8122 (write _test-input-stream "}\n")
8124 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
8125 (flush _test-output-buffered-file)
8126 #? # dump _test-error-stream {{{
8128 #? (write-stream 2 _test-error-stream)
8130 #? (rewind-stream _test-error-stream)
8134 89/<- %esp 5/r32/ebp
8138 test-copy-non-literal-to-byte:
8141 89/<- %ebp 4/r32/esp
8143 (clear-stream _test-input-stream)
8144 (clear-stream $_test-input-buffered-file->buffer)
8145 (clear-stream _test-output-stream)
8146 (clear-stream $_test-output-buffered-file->buffer)
8147 (clear-stream _test-error-stream)
8148 (clear-stream $_test-error-buffered-file->buffer)
8149 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8152 89/<- %edx 4/r32/esp
8153 (tailor-exit-descriptor %edx 0x10)
8155 (write _test-input-stream "fn foo {\n")
8156 (write _test-input-stream " var x/ecx: int <- copy 3\n")
8157 (write _test-input-stream " var y/ecx: byte <- copy x\n")
8158 (write _test-input-stream "}\n")
8160 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8161 # registers except esp clobbered at this point
8163 89/<- %edx 4/r32/esp
8164 (flush _test-output-buffered-file)
8165 (flush _test-error-buffered-file)
8166 #? # dump _test-error-stream {{{
8168 #? (write-stream 2 _test-error-stream)
8170 #? (rewind-stream _test-error-stream)
8173 (check-stream-equal _test-output-stream "" "F - test-copy-non-literal-to-byte: output should be empty")
8174 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: cannot copy non-literal to 'y' of type byte; use copy-byte" "F - test-copy-non-literal-to-byte: error message")
8175 # check that stop(1) was called
8176 (check-ints-equal *(edx+4) 2 "F - test-copy-non-literal-to-byte: exit status")
8177 # don't restore from ebp
8178 81 0/subop/add %esp 8/imm32
8183 test-copy-deref-address:
8186 89/<- %ebp 4/r32/esp
8188 (clear-stream _test-input-stream)
8189 (clear-stream $_test-input-buffered-file->buffer)
8190 (clear-stream _test-output-stream)
8191 (clear-stream $_test-output-buffered-file->buffer)
8193 (write _test-input-stream "fn foo {\n")
8194 (write _test-input-stream " var x/eax: (addr addr int) <- copy 0\n")
8195 (write _test-input-stream " var y/ecx: (addr int) <- copy *x\n")
8196 (write _test-input-stream "}\n")
8198 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
8199 (flush _test-output-buffered-file)
8205 test-copy-to-non-register:
8208 89/<- %ebp 4/r32/esp
8210 (clear-stream _test-input-stream)
8211 (clear-stream $_test-input-buffered-file->buffer)
8212 (clear-stream _test-output-stream)
8213 (clear-stream $_test-output-buffered-file->buffer)
8214 (clear-stream _test-error-stream)
8215 (clear-stream $_test-error-buffered-file->buffer)
8216 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8219 89/<- %edx 4/r32/esp
8220 (tailor-exit-descriptor %edx 0x10)
8222 (write _test-input-stream "fn foo {\n")
8223 (write _test-input-stream " var x: int\n")
8224 (write _test-input-stream " x <- copy 0\n")
8225 (write _test-input-stream "}\n")
8227 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8228 # registers except esp clobbered at this point
8230 89/<- %edx 4/r32/esp
8231 (flush _test-output-buffered-file)
8232 (flush _test-error-buffered-file)
8233 #? # dump _test-error-stream {{{
8235 #? (write-stream 2 _test-error-stream)
8237 #? (rewind-stream _test-error-stream)
8240 (check-stream-equal _test-output-stream "" "F - test-copy-to-non-register: output should be empty")
8241 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: output 'x' not in a register" "F - test-copy-to-non-register: error message")
8242 # check that stop(1) was called
8243 (check-ints-equal *(edx+4) 2 "F - test-copy-to-non-register: exit status")
8244 # don't restore from ebp
8245 81 0/subop/add %esp 8/imm32
8250 test-copy-from-non-scalar-inout:
8253 89/<- %ebp 4/r32/esp
8255 (clear-stream _test-input-stream)
8256 (clear-stream $_test-input-buffered-file->buffer)
8257 (clear-stream _test-output-stream)
8258 (clear-stream $_test-output-buffered-file->buffer)
8259 (clear-stream _test-error-stream)
8260 (clear-stream $_test-error-buffered-file->buffer)
8261 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8264 89/<- %edx 4/r32/esp
8265 (tailor-exit-descriptor %edx 0x10)
8267 (write _test-input-stream "fn foo {\n")
8268 (write _test-input-stream " var x: (handle int)\n")
8269 (write _test-input-stream " var y/eax: int <- copy x\n")
8270 (write _test-input-stream "}\n")
8272 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8273 # registers except esp clobbered at this point
8275 89/<- %edx 4/r32/esp
8276 (flush _test-output-buffered-file)
8277 (flush _test-error-buffered-file)
8278 #? # dump _test-error-stream {{{
8280 #? (write-stream 2 _test-error-stream)
8282 #? (rewind-stream _test-error-stream)
8285 (check-stream-equal _test-output-stream "" "F - test-copy-from-non-scalar-inout: output should be empty")
8286 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy: 'x' is too large to fit in a register" "F - test-copy-from-non-scalar-inout: error message")
8287 # check that stop(1) was called
8288 (check-ints-equal *(edx+4) 2 "F - test-copy-from-non-scalar-inout: exit status")
8289 # don't restore from ebp
8290 81 0/subop/add %esp 8/imm32
8295 test-copy-to-with-no-inout:
8298 89/<- %ebp 4/r32/esp
8300 (clear-stream _test-input-stream)
8301 (clear-stream $_test-input-buffered-file->buffer)
8302 (clear-stream _test-output-stream)
8303 (clear-stream $_test-output-buffered-file->buffer)
8304 (clear-stream _test-error-stream)
8305 (clear-stream $_test-error-buffered-file->buffer)
8306 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8309 89/<- %edx 4/r32/esp
8310 (tailor-exit-descriptor %edx 0x10)
8312 (write _test-input-stream "fn foo {\n")
8313 (write _test-input-stream " copy-to\n")
8314 (write _test-input-stream "}\n")
8316 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8317 # registers except esp clobbered at this point
8319 89/<- %edx 4/r32/esp
8320 (flush _test-output-buffered-file)
8321 (flush _test-error-buffered-file)
8322 #? # dump _test-error-stream {{{
8324 #? (write-stream 2 _test-error-stream)
8326 #? (rewind-stream _test-error-stream)
8329 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-no-inout: output should be empty")
8330 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-to' must have two inouts" "F - test-copy-to-with-no-inout: error message")
8331 # check that stop(1) was called
8332 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-no-inout: exit status")
8333 # don't restore from ebp
8334 81 0/subop/add %esp 8/imm32
8339 test-copy-to-with-no-source:
8342 89/<- %ebp 4/r32/esp
8344 (clear-stream _test-input-stream)
8345 (clear-stream $_test-input-buffered-file->buffer)
8346 (clear-stream _test-output-stream)
8347 (clear-stream $_test-output-buffered-file->buffer)
8348 (clear-stream _test-error-stream)
8349 (clear-stream $_test-error-buffered-file->buffer)
8350 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8353 89/<- %edx 4/r32/esp
8354 (tailor-exit-descriptor %edx 0x10)
8356 (write _test-input-stream "fn foo {\n")
8357 (write _test-input-stream " var x: boolean\n")
8358 (write _test-input-stream " copy-to x\n")
8359 (write _test-input-stream "}\n")
8361 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8362 # registers except esp clobbered at this point
8364 89/<- %edx 4/r32/esp
8365 (flush _test-output-buffered-file)
8366 (flush _test-error-buffered-file)
8367 #? # dump _test-error-stream {{{
8369 #? (write-stream 2 _test-error-stream)
8371 #? (rewind-stream _test-error-stream)
8374 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-no-source: output should be empty")
8375 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-to' must have two inouts" "F - test-copy-to-with-no-source: error message")
8376 # check that stop(1) was called
8377 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-no-source: exit status")
8378 # don't restore from ebp
8379 81 0/subop/add %esp 8/imm32
8384 test-copy-to-with-no-register:
8387 89/<- %ebp 4/r32/esp
8389 (clear-stream _test-input-stream)
8390 (clear-stream $_test-input-buffered-file->buffer)
8391 (clear-stream _test-output-stream)
8392 (clear-stream $_test-output-buffered-file->buffer)
8393 (clear-stream _test-error-stream)
8394 (clear-stream $_test-error-buffered-file->buffer)
8395 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8398 89/<- %edx 4/r32/esp
8399 (tailor-exit-descriptor %edx 0x10)
8401 (write _test-input-stream "fn foo {\n")
8402 (write _test-input-stream " var x: boolean\n")
8403 (write _test-input-stream " copy-to x, x\n")
8404 (write _test-input-stream "}\n")
8406 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8407 # registers except esp clobbered at this point
8409 89/<- %edx 4/r32/esp
8410 (flush _test-output-buffered-file)
8411 (flush _test-error-buffered-file)
8412 #? # dump _test-error-stream {{{
8414 #? (write-stream 2 _test-error-stream)
8416 #? (rewind-stream _test-error-stream)
8419 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-no-register: output should be empty")
8420 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: source (second inout) is in memory" "F - test-copy-to-with-no-register: error message")
8421 # check that stop(1) was called
8422 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-no-register: exit status")
8423 # don't restore from ebp
8424 81 0/subop/add %esp 8/imm32
8429 test-copy-to-with-too-many-inouts:
8432 89/<- %ebp 4/r32/esp
8434 (clear-stream _test-input-stream)
8435 (clear-stream $_test-input-buffered-file->buffer)
8436 (clear-stream _test-output-stream)
8437 (clear-stream $_test-output-buffered-file->buffer)
8438 (clear-stream _test-error-stream)
8439 (clear-stream $_test-error-buffered-file->buffer)
8440 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8443 89/<- %edx 4/r32/esp
8444 (tailor-exit-descriptor %edx 0x10)
8446 (write _test-input-stream "fn foo {\n")
8447 (write _test-input-stream " var x: boolean\n")
8448 (write _test-input-stream " copy-to x, 0, 0\n")
8449 (write _test-input-stream "}\n")
8451 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8452 # registers except esp clobbered at this point
8454 89/<- %edx 4/r32/esp
8455 (flush _test-output-buffered-file)
8456 (flush _test-error-buffered-file)
8457 #? # dump _test-error-stream {{{
8459 #? (write-stream 2 _test-error-stream)
8461 #? (rewind-stream _test-error-stream)
8464 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-too-many-inouts: output should be empty")
8465 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-to' must have two inouts" "F - test-copy-to-with-too-many-inouts: error message")
8466 # check that stop(1) was called
8467 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-too-many-inouts: exit status")
8468 # don't restore from ebp
8469 81 0/subop/add %esp 8/imm32
8474 test-copy-to-with-output:
8477 89/<- %ebp 4/r32/esp
8479 (clear-stream _test-input-stream)
8480 (clear-stream $_test-input-buffered-file->buffer)
8481 (clear-stream _test-output-stream)
8482 (clear-stream $_test-output-buffered-file->buffer)
8483 (clear-stream _test-error-stream)
8484 (clear-stream $_test-error-buffered-file->buffer)
8485 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8488 89/<- %edx 4/r32/esp
8489 (tailor-exit-descriptor %edx 0x10)
8491 (write _test-input-stream "fn foo {\n")
8492 (write _test-input-stream " var x/eax: boolean <- copy 0\n")
8493 (write _test-input-stream " var y/ecx: boolean <- copy 0\n")
8494 (write _test-input-stream " x <- copy-to y, 0\n")
8495 (write _test-input-stream "}\n")
8497 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8498 # registers except esp clobbered at this point
8500 89/<- %edx 4/r32/esp
8501 (flush _test-output-buffered-file)
8502 (flush _test-error-buffered-file)
8503 #? # dump _test-error-stream {{{
8505 #? (write-stream 2 _test-error-stream)
8507 #? (rewind-stream _test-error-stream)
8510 (check-stream-equal _test-output-stream "" "F - test-copy-to-with-output: output should be empty")
8511 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-to' must not have any outputs" "F - test-copy-to-with-output: error message")
8512 # check that stop(1) was called
8513 (check-ints-equal *(edx+4) 2 "F - test-copy-to-with-output: exit status")
8514 # don't restore from ebp
8515 81 0/subop/add %esp 8/imm32
8520 test-copy-to-invalid-value-to-address:
8523 89/<- %ebp 4/r32/esp
8525 (clear-stream _test-input-stream)
8526 (clear-stream $_test-input-buffered-file->buffer)
8527 (clear-stream _test-output-stream)
8528 (clear-stream $_test-output-buffered-file->buffer)
8529 (clear-stream _test-error-stream)
8530 (clear-stream $_test-error-buffered-file->buffer)
8531 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8534 89/<- %edx 4/r32/esp
8535 (tailor-exit-descriptor %edx 0x10)
8537 (write _test-input-stream "fn foo {\n")
8538 (write _test-input-stream " var x/eax: int <- copy 0\n")
8539 (write _test-input-stream " var y: (addr int)\n")
8540 (write _test-input-stream " copy-to y, x\n")
8541 (write _test-input-stream "}\n")
8543 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8544 # registers except esp clobbered at this point
8546 89/<- %edx 4/r32/esp
8547 (flush _test-output-buffered-file)
8548 (flush _test-error-buffered-file)
8549 #? # dump _test-error-stream {{{
8551 #? (write-stream 2 _test-error-stream)
8553 #? (rewind-stream _test-error-stream)
8556 (check-stream-equal _test-output-stream "" "F - test-copy-to-invalid-value-to-address: output should be empty")
8557 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: 'y' must be a non-addr non-offset scalar" "F - test-copy-to-invalid-value-to-address: error message")
8558 # check that stop(1) was called
8559 (check-ints-equal *(edx+4) 2 "F - test-copy-to-invalid-value-to-address: exit status")
8560 # don't restore from ebp
8561 81 0/subop/add %esp 8/imm32
8566 test-copy-to-null-value-to-address:
8569 89/<- %ebp 4/r32/esp
8571 (clear-stream _test-input-stream)
8572 (clear-stream $_test-input-buffered-file->buffer)
8573 (clear-stream _test-output-stream)
8574 (clear-stream $_test-output-buffered-file->buffer)
8576 (write _test-input-stream "fn foo {\n")
8577 (write _test-input-stream " var y: (addr int)\n")
8578 (write _test-input-stream " copy-to y, 0\n")
8579 (write _test-input-stream "}\n")
8581 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
8582 (flush _test-output-buffered-file)
8585 89/<- %esp 5/r32/ebp
8589 test-copy-to-invalid-value-to-offset:
8592 89/<- %ebp 4/r32/esp
8594 (clear-stream _test-input-stream)
8595 (clear-stream $_test-input-buffered-file->buffer)
8596 (clear-stream _test-output-stream)
8597 (clear-stream $_test-output-buffered-file->buffer)
8598 (clear-stream _test-error-stream)
8599 (clear-stream $_test-error-buffered-file->buffer)
8600 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8603 89/<- %edx 4/r32/esp
8604 (tailor-exit-descriptor %edx 0x10)
8606 (write _test-input-stream "fn foo {\n")
8607 (write _test-input-stream " var x/eax: int <- copy 0\n")
8608 (write _test-input-stream " var y: (offset int)\n")
8609 (write _test-input-stream " copy-to y, x\n")
8610 (write _test-input-stream "}\n")
8612 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8613 # registers except esp clobbered at this point
8615 89/<- %edx 4/r32/esp
8616 (flush _test-output-buffered-file)
8617 (flush _test-error-buffered-file)
8618 #? # dump _test-error-stream {{{
8620 #? (write-stream 2 _test-error-stream)
8622 #? (rewind-stream _test-error-stream)
8625 (check-stream-equal _test-output-stream "" "F - test-copy-to-invalid-value-to-offset: output should be empty")
8626 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: 'y' must be a non-addr non-offset scalar" "F - test-copy-to-invalid-value-to-offset: error message")
8627 # check that stop(1) was called
8628 (check-ints-equal *(edx+4) 2 "F - test-copy-to-invalid-value-to-offset: exit status")
8629 # don't restore from ebp
8630 81 0/subop/add %esp 8/imm32
8635 test-copy-to-null-value-to-offset:
8638 89/<- %ebp 4/r32/esp
8640 (clear-stream _test-input-stream)
8641 (clear-stream $_test-input-buffered-file->buffer)
8642 (clear-stream _test-output-stream)
8643 (clear-stream $_test-output-buffered-file->buffer)
8645 (write _test-input-stream "fn foo {\n")
8646 (write _test-input-stream " var y: (offset int)\n")
8647 (write _test-input-stream " copy-to y, 0\n")
8648 (write _test-input-stream "}\n")
8650 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
8651 (flush _test-output-buffered-file)
8654 89/<- %esp 5/r32/ebp
8658 test-copy-to-non-literal-to-byte:
8661 89/<- %ebp 4/r32/esp
8663 (clear-stream _test-input-stream)
8664 (clear-stream $_test-input-buffered-file->buffer)
8665 (clear-stream _test-output-stream)
8666 (clear-stream $_test-output-buffered-file->buffer)
8667 (clear-stream _test-error-stream)
8668 (clear-stream $_test-error-buffered-file->buffer)
8669 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8672 89/<- %edx 4/r32/esp
8673 (tailor-exit-descriptor %edx 0x10)
8675 (write _test-input-stream "fn foo {\n")
8676 (write _test-input-stream " var x/ecx: byte <- copy 3\n")
8677 (write _test-input-stream " var y/eax: (addr byte) <- copy 0\n")
8678 (write _test-input-stream " copy-to *y, x\n")
8679 (write _test-input-stream "}\n")
8681 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8682 # registers except esp clobbered at this point
8684 89/<- %edx 4/r32/esp
8685 (flush _test-output-buffered-file)
8686 (flush _test-error-buffered-file)
8687 #? # dump _test-error-stream {{{
8689 #? (write-stream 2 _test-error-stream)
8691 #? (rewind-stream _test-error-stream)
8694 (check-stream-equal _test-output-stream "" "F - test-copy-to-non-literal-to-byte: output should be empty")
8695 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: cannot copy non-literal to type byte; use copy-byte-to" "F - test-copy-to-non-literal-to-byte: error message")
8696 # check that stop(1) was called
8697 (check-ints-equal *(edx+4) 2 "F - test-copy-to-non-literal-to-byte: exit status")
8698 # don't restore from ebp
8699 81 0/subop/add %esp 8/imm32
8704 test-copy-to-deref-address:
8707 89/<- %ebp 4/r32/esp
8709 (clear-stream _test-input-stream)
8710 (clear-stream $_test-input-buffered-file->buffer)
8711 (clear-stream _test-output-stream)
8712 (clear-stream $_test-output-buffered-file->buffer)
8714 (write _test-input-stream "fn foo {\n")
8715 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n")
8716 (write _test-input-stream " var y/ecx: (addr addr int) <- copy 0\n")
8717 (write _test-input-stream " copy-to *y, x\n")
8718 (write _test-input-stream "}\n")
8720 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
8721 (flush _test-output-buffered-file)
8727 test-copy-to-from-non-scalar-inout:
8730 89/<- %ebp 4/r32/esp
8732 (clear-stream _test-input-stream)
8733 (clear-stream $_test-input-buffered-file->buffer)
8734 (clear-stream _test-output-stream)
8735 (clear-stream $_test-output-buffered-file->buffer)
8736 (clear-stream _test-error-stream)
8737 (clear-stream $_test-error-buffered-file->buffer)
8738 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8741 89/<- %edx 4/r32/esp
8742 (tailor-exit-descriptor %edx 0x10)
8744 (write _test-input-stream "fn foo {\n")
8745 (write _test-input-stream " var x: (handle int)\n")
8746 (write _test-input-stream " var y: int\n")
8747 (write _test-input-stream " copy-to y, x\n")
8748 (write _test-input-stream "}\n")
8750 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8751 # registers except esp clobbered at this point
8753 89/<- %edx 4/r32/esp
8754 (flush _test-output-buffered-file)
8755 (flush _test-error-buffered-file)
8756 #? # dump _test-error-stream {{{
8758 #? (write-stream 2 _test-error-stream)
8760 #? (rewind-stream _test-error-stream)
8763 (check-stream-equal _test-output-stream "" "F - test-copy-to-from-non-scalar-inout: output should be empty")
8764 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-to: 'x' is too large to copy" "F - test-copy-to-from-non-scalar-inout: error message")
8765 # check that stop(1) was called
8766 (check-ints-equal *(edx+4) 2 "F - test-copy-to-from-non-scalar-inout: exit status")
8767 # don't restore from ebp
8768 81 0/subop/add %esp 8/imm32
8773 test-copy-byte-with-no-inout:
8776 89/<- %ebp 4/r32/esp
8778 (clear-stream _test-input-stream)
8779 (clear-stream $_test-input-buffered-file->buffer)
8780 (clear-stream _test-output-stream)
8781 (clear-stream $_test-output-buffered-file->buffer)
8782 (clear-stream _test-error-stream)
8783 (clear-stream $_test-error-buffered-file->buffer)
8784 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8787 89/<- %edx 4/r32/esp
8788 (tailor-exit-descriptor %edx 0x10)
8790 (write _test-input-stream "fn foo {\n")
8791 (write _test-input-stream " var x/eax: byte <- copy-byte\n")
8792 (write _test-input-stream "}\n")
8794 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8795 # registers except esp clobbered at this point
8797 89/<- %edx 4/r32/esp
8798 (flush _test-output-buffered-file)
8799 (flush _test-error-buffered-file)
8800 #? # dump _test-error-stream {{{
8802 #? (write-stream 2 _test-error-stream)
8804 #? (rewind-stream _test-error-stream)
8807 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-no-inout: output should be empty")
8808 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' expects an inout" "F - test-copy-byte-with-no-inout: error message")
8809 # check that stop(1) was called
8810 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-no-inout: exit status")
8811 # don't restore from ebp
8812 81 0/subop/add %esp 8/imm32
8817 test-copy-byte-with-multiple-inouts:
8820 89/<- %ebp 4/r32/esp
8822 (clear-stream _test-input-stream)
8823 (clear-stream $_test-input-buffered-file->buffer)
8824 (clear-stream _test-output-stream)
8825 (clear-stream $_test-output-buffered-file->buffer)
8826 (clear-stream _test-error-stream)
8827 (clear-stream $_test-error-buffered-file->buffer)
8828 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8831 89/<- %edx 4/r32/esp
8832 (tailor-exit-descriptor %edx 0x10)
8834 (write _test-input-stream "fn foo {\n")
8835 (write _test-input-stream " var x/eax: byte <- copy-byte 0, 0\n")
8836 (write _test-input-stream "}\n")
8838 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8839 # registers except esp clobbered at this point
8841 89/<- %edx 4/r32/esp
8842 (flush _test-output-buffered-file)
8843 (flush _test-error-buffered-file)
8844 #? # dump _test-error-stream {{{
8846 #? (write-stream 2 _test-error-stream)
8848 #? (rewind-stream _test-error-stream)
8851 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-multiple-inouts: output should be empty")
8852 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' must have just one inout" "F - test-copy-byte-with-multiple-inouts: error message")
8853 # check that stop(1) was called
8854 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-multiple-inouts: exit status")
8855 # don't restore from ebp
8856 81 0/subop/add %esp 8/imm32
8861 test-copy-byte-with-no-output:
8864 89/<- %ebp 4/r32/esp
8866 (clear-stream _test-input-stream)
8867 (clear-stream $_test-input-buffered-file->buffer)
8868 (clear-stream _test-output-stream)
8869 (clear-stream $_test-output-buffered-file->buffer)
8870 (clear-stream _test-error-stream)
8871 (clear-stream $_test-error-buffered-file->buffer)
8872 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8875 89/<- %edx 4/r32/esp
8876 (tailor-exit-descriptor %edx 0x10)
8878 (write _test-input-stream "fn foo {\n")
8879 (write _test-input-stream " copy-byte 0\n")
8880 (write _test-input-stream "}\n")
8882 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8883 # registers except esp clobbered at this point
8885 89/<- %edx 4/r32/esp
8886 (flush _test-output-buffered-file)
8887 (flush _test-error-buffered-file)
8888 #? # dump _test-error-stream {{{
8890 #? (write-stream 2 _test-error-stream)
8892 #? (rewind-stream _test-error-stream)
8895 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-no-output: output should be empty")
8896 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' expects an output" "F - test-copy-byte-with-no-output: error message")
8897 # check that stop(1) was called
8898 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-no-output: exit status")
8899 # don't restore from ebp
8900 81 0/subop/add %esp 8/imm32
8905 test-copy-byte-with-multiple-outputs:
8908 89/<- %ebp 4/r32/esp
8910 (clear-stream _test-input-stream)
8911 (clear-stream $_test-input-buffered-file->buffer)
8912 (clear-stream _test-output-stream)
8913 (clear-stream $_test-output-buffered-file->buffer)
8914 (clear-stream _test-error-stream)
8915 (clear-stream $_test-error-buffered-file->buffer)
8916 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8919 89/<- %edx 4/r32/esp
8920 (tailor-exit-descriptor %edx 0x10)
8922 (write _test-input-stream "fn foo {\n")
8923 (write _test-input-stream " var x/eax: byte <- copy 0\n")
8924 (write _test-input-stream " var y/ecx: byte <- copy 0\n")
8925 (write _test-input-stream " x, y <- copy-byte 0\n")
8926 (write _test-input-stream "}\n")
8928 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
8929 # registers except esp clobbered at this point
8931 89/<- %edx 4/r32/esp
8932 (flush _test-output-buffered-file)
8933 (flush _test-error-buffered-file)
8934 #? # dump _test-error-stream {{{
8936 #? (write-stream 2 _test-error-stream)
8938 #? (rewind-stream _test-error-stream)
8941 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-multiple-outputs: output should be empty")
8942 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' must have just one output" "F - test-copy-byte-with-multiple-outputs: error message")
8943 # check that stop(1) was called
8944 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-multiple-outputs: exit status")
8945 # don't restore from ebp
8946 81 0/subop/add %esp 8/imm32
8951 test-copy-byte-deref-address:
8954 89/<- %ebp 4/r32/esp
8956 (clear-stream _test-input-stream)
8957 (clear-stream $_test-input-buffered-file->buffer)
8958 (clear-stream _test-output-stream)
8959 (clear-stream $_test-output-buffered-file->buffer)
8961 (write _test-input-stream "fn foo {\n")
8962 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n")
8963 (write _test-input-stream " var y/ecx: byte <- copy-byte *x\n")
8964 (write _test-input-stream "}\n")
8966 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
8967 (flush _test-output-buffered-file)
8968 #? # dump _test-error-stream {{{
8970 #? (write-stream 2 _test-error-stream)
8972 #? (rewind-stream _test-error-stream)
8974 # not bothering checking output
8975 (check-next-stream-line-equal _test-error-stream "" "F - test-copy-byte-deref-address: error message")
8980 test-copy-byte-with-invalid-output-type:
8983 89/<- %ebp 4/r32/esp
8985 (clear-stream _test-input-stream)
8986 (clear-stream $_test-input-buffered-file->buffer)
8987 (clear-stream _test-output-stream)
8988 (clear-stream $_test-output-buffered-file->buffer)
8989 (clear-stream _test-error-stream)
8990 (clear-stream $_test-error-buffered-file->buffer)
8991 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
8994 89/<- %edx 4/r32/esp
8995 (tailor-exit-descriptor %edx 0x10)
8997 (write _test-input-stream "fn foo {\n")
8998 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n")
8999 (write _test-input-stream " var y/eax: int <- copy-byte *x\n")
9000 (write _test-input-stream "}\n")
9002 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9003 # registers except esp clobbered at this point
9005 89/<- %edx 4/r32/esp
9006 (flush _test-output-buffered-file)
9007 (flush _test-error-buffered-file)
9008 #? # dump _test-error-stream {{{
9010 #? (write-stream 2 _test-error-stream)
9012 #? (rewind-stream _test-error-stream)
9015 (check-stream-equal _test-output-stream "" "F - test-copy-byte-with-invalid-output-type: output should be empty")
9016 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte' must write to output of type byte" "F - test-copy-byte-with-invalid-output-type: error message")
9017 # check that stop(1) was called
9018 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-with-invalid-output-type: exit status")
9019 # don't restore from ebp
9020 81 0/subop/add %esp 8/imm32
9025 test-copy-byte-from-non-scalar-inout:
9028 89/<- %ebp 4/r32/esp
9030 (clear-stream _test-input-stream)
9031 (clear-stream $_test-input-buffered-file->buffer)
9032 (clear-stream _test-output-stream)
9033 (clear-stream $_test-output-buffered-file->buffer)
9034 (clear-stream _test-error-stream)
9035 (clear-stream $_test-error-buffered-file->buffer)
9036 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9039 89/<- %edx 4/r32/esp
9040 (tailor-exit-descriptor %edx 0x10)
9042 (write _test-input-stream "fn foo {\n")
9043 (write _test-input-stream " var x: (handle int)\n")
9044 (write _test-input-stream " var y/eax: byte <- copy-byte x\n")
9045 (write _test-input-stream "}\n")
9047 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9048 # registers except esp clobbered at this point
9050 89/<- %edx 4/r32/esp
9051 (flush _test-output-buffered-file)
9052 (flush _test-error-buffered-file)
9053 #? # dump _test-error-stream {{{
9055 #? (write-stream 2 _test-error-stream)
9057 #? (rewind-stream _test-error-stream)
9060 (check-stream-equal _test-output-stream "" "F - test-copy-byte-from-non-scalar-inout: output should be empty")
9061 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-byte: 'x' is too large to fit in a register" "F - test-copy-byte-from-non-scalar-inout: error message")
9062 # check that stop(1) was called
9063 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-from-non-scalar-inout: exit status")
9064 # don't restore from ebp
9065 81 0/subop/add %esp 8/imm32
9070 test-copy-byte-to-with-no-inout:
9073 89/<- %ebp 4/r32/esp
9075 (clear-stream _test-input-stream)
9076 (clear-stream $_test-input-buffered-file->buffer)
9077 (clear-stream _test-output-stream)
9078 (clear-stream $_test-output-buffered-file->buffer)
9079 (clear-stream _test-error-stream)
9080 (clear-stream $_test-error-buffered-file->buffer)
9081 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9084 89/<- %edx 4/r32/esp
9085 (tailor-exit-descriptor %edx 0x10)
9087 (write _test-input-stream "fn foo {\n")
9088 (write _test-input-stream " copy-byte-to\n")
9089 (write _test-input-stream "}\n")
9091 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9092 # registers except esp clobbered at this point
9094 89/<- %edx 4/r32/esp
9095 (flush _test-output-buffered-file)
9096 (flush _test-error-buffered-file)
9097 #? # dump _test-error-stream {{{
9099 #? (write-stream 2 _test-error-stream)
9101 #? (rewind-stream _test-error-stream)
9104 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-no-inout: output should be empty")
9105 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte-to' must have two inouts" "F - test-copy-byte-to-with-no-inout: error message")
9106 # check that stop(1) was called
9107 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-no-inout: exit status")
9108 # don't restore from ebp
9109 81 0/subop/add %esp 8/imm32
9114 test-copy-byte-to-with-no-source:
9117 89/<- %ebp 4/r32/esp
9119 (clear-stream _test-input-stream)
9120 (clear-stream $_test-input-buffered-file->buffer)
9121 (clear-stream _test-output-stream)
9122 (clear-stream $_test-output-buffered-file->buffer)
9123 (clear-stream _test-error-stream)
9124 (clear-stream $_test-error-buffered-file->buffer)
9125 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9128 89/<- %edx 4/r32/esp
9129 (tailor-exit-descriptor %edx 0x10)
9131 (write _test-input-stream "fn foo {\n")
9132 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n")
9133 (write _test-input-stream " copy-byte-to *x\n")
9134 (write _test-input-stream "}\n")
9136 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9137 # registers except esp clobbered at this point
9139 89/<- %edx 4/r32/esp
9140 (flush _test-output-buffered-file)
9141 (flush _test-error-buffered-file)
9142 #? # dump _test-error-stream {{{
9144 #? (write-stream 2 _test-error-stream)
9146 #? (rewind-stream _test-error-stream)
9149 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-no-source: output should be empty")
9150 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte-to' must have two inouts" "F - test-copy-byte-to-with-no-source: error message")
9151 # check that stop(1) was called
9152 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-no-source: exit status")
9153 # don't restore from ebp
9154 81 0/subop/add %esp 8/imm32
9159 test-copy-byte-to-with-too-many-inouts:
9162 89/<- %ebp 4/r32/esp
9164 (clear-stream _test-input-stream)
9165 (clear-stream $_test-input-buffered-file->buffer)
9166 (clear-stream _test-output-stream)
9167 (clear-stream $_test-output-buffered-file->buffer)
9168 (clear-stream _test-error-stream)
9169 (clear-stream $_test-error-buffered-file->buffer)
9170 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9173 89/<- %edx 4/r32/esp
9174 (tailor-exit-descriptor %edx 0x10)
9176 (write _test-input-stream "fn foo {\n")
9177 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n")
9178 (write _test-input-stream " copy-byte-to *x, 0, 0\n")
9179 (write _test-input-stream "}\n")
9181 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9182 # registers except esp clobbered at this point
9184 89/<- %edx 4/r32/esp
9185 (flush _test-output-buffered-file)
9186 (flush _test-error-buffered-file)
9187 #? # dump _test-error-stream {{{
9189 #? (write-stream 2 _test-error-stream)
9191 #? (rewind-stream _test-error-stream)
9194 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-too-many-inouts: output should be empty")
9195 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte-to' must have two inouts" "F - test-copy-byte-to-with-too-many-inouts: error message")
9196 # check that stop(1) was called
9197 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-too-many-inouts: exit status")
9198 # don't restore from ebp
9199 81 0/subop/add %esp 8/imm32
9204 test-copy-byte-to-with-output:
9207 89/<- %ebp 4/r32/esp
9209 (clear-stream _test-input-stream)
9210 (clear-stream $_test-input-buffered-file->buffer)
9211 (clear-stream _test-output-stream)
9212 (clear-stream $_test-output-buffered-file->buffer)
9213 (clear-stream _test-error-stream)
9214 (clear-stream $_test-error-buffered-file->buffer)
9215 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9218 89/<- %edx 4/r32/esp
9219 (tailor-exit-descriptor %edx 0x10)
9221 (write _test-input-stream "fn foo {\n")
9222 (write _test-input-stream " var x/eax: byte <- copy 0\n")
9223 (write _test-input-stream " var y/ecx: (addr byte) <- copy 0\n")
9224 (write _test-input-stream " x <- copy-byte-to *y, 0\n")
9225 (write _test-input-stream "}\n")
9227 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9228 # registers except esp clobbered at this point
9230 89/<- %edx 4/r32/esp
9231 (flush _test-output-buffered-file)
9232 (flush _test-error-buffered-file)
9233 #? # dump _test-error-stream {{{
9235 #? (write-stream 2 _test-error-stream)
9237 #? (rewind-stream _test-error-stream)
9240 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-output: output should be empty")
9241 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-byte-to' must not have any outputs" "F - test-copy-byte-to-with-output: error message")
9242 # check that stop(1) was called
9243 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-output: exit status")
9244 # don't restore from ebp
9245 81 0/subop/add %esp 8/imm32
9250 test-copy-byte-to-with-invalid-output-type:
9253 89/<- %ebp 4/r32/esp
9255 (clear-stream _test-input-stream)
9256 (clear-stream $_test-input-buffered-file->buffer)
9257 (clear-stream _test-output-stream)
9258 (clear-stream $_test-output-buffered-file->buffer)
9259 (clear-stream _test-error-stream)
9260 (clear-stream $_test-error-buffered-file->buffer)
9261 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9264 89/<- %edx 4/r32/esp
9265 (tailor-exit-descriptor %edx 0x10)
9267 (write _test-input-stream "fn foo {\n")
9268 (write _test-input-stream " var x/eax: byte <- copy 0\n")
9269 (write _test-input-stream " var y: int\n")
9270 (write _test-input-stream " copy-byte-to y, x\n")
9271 (write _test-input-stream "}\n")
9273 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9274 # registers except esp clobbered at this point
9276 89/<- %edx 4/r32/esp
9277 (flush _test-output-buffered-file)
9278 (flush _test-error-buffered-file)
9279 #? # dump _test-error-stream {{{
9281 #? (write-stream 2 _test-error-stream)
9283 #? (rewind-stream _test-error-stream)
9286 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-invalid-output-type: output should be empty")
9287 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-byte-to: 'y' must be a byte" "F - test-copy-byte-to-with-invalid-output-type: error message")
9288 # check that stop(1) was called
9289 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-invalid-output-type: exit status")
9290 # don't restore from ebp
9291 81 0/subop/add %esp 8/imm32
9296 test-copy-byte-to-with-literal-inout:
9299 89/<- %ebp 4/r32/esp
9301 (clear-stream _test-input-stream)
9302 (clear-stream $_test-input-buffered-file->buffer)
9303 (clear-stream _test-output-stream)
9304 (clear-stream $_test-output-buffered-file->buffer)
9305 (clear-stream _test-error-stream)
9306 (clear-stream $_test-error-buffered-file->buffer)
9307 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9310 89/<- %edx 4/r32/esp
9311 (tailor-exit-descriptor %edx 0x10)
9313 (write _test-input-stream "fn foo {\n")
9314 (write _test-input-stream " var x/eax: (addr byte) <- copy 0\n")
9315 (write _test-input-stream " copy-byte-to *x, 0\n")
9316 (write _test-input-stream "}\n")
9318 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9319 # registers except esp clobbered at this point
9321 89/<- %edx 4/r32/esp
9322 (flush _test-output-buffered-file)
9323 (flush _test-error-buffered-file)
9324 #? # dump _test-error-stream {{{
9326 #? (write-stream 2 _test-error-stream)
9328 #? (rewind-stream _test-error-stream)
9331 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-with-literal-inout: output should be empty")
9332 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-byte-to: source (second inout) must be in a register" "F - test-copy-byte-to-with-literal-inout: error message")
9333 # check that stop(1) was called
9334 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-with-literal-inout: exit status")
9335 # don't restore from ebp
9336 81 0/subop/add %esp 8/imm32
9341 test-copy-byte-to-deref-address:
9344 89/<- %ebp 4/r32/esp
9346 (clear-stream _test-input-stream)
9347 (clear-stream $_test-input-buffered-file->buffer)
9348 (clear-stream _test-output-stream)
9349 (clear-stream $_test-output-buffered-file->buffer)
9351 (write _test-input-stream "fn foo {\n")
9352 (write _test-input-stream " var x/eax: byte <- copy 0\n")
9353 (write _test-input-stream " var y/ecx: (addr byte) <- copy 0\n")
9354 (write _test-input-stream " copy-byte-to *y, x\n")
9355 (write _test-input-stream "}\n")
9357 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
9358 (flush _test-output-buffered-file)
9364 test-copy-byte-to-from-non-scalar-inout:
9367 89/<- %ebp 4/r32/esp
9369 (clear-stream _test-input-stream)
9370 (clear-stream $_test-input-buffered-file->buffer)
9371 (clear-stream _test-output-stream)
9372 (clear-stream $_test-output-buffered-file->buffer)
9373 (clear-stream _test-error-stream)
9374 (clear-stream $_test-error-buffered-file->buffer)
9375 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9378 89/<- %edx 4/r32/esp
9379 (tailor-exit-descriptor %edx 0x10)
9381 (write _test-input-stream "fn foo {\n")
9382 (write _test-input-stream " var x: (handle int)\n")
9383 (write _test-input-stream " var y/eax: (addr byte) <- copy 0\n")
9384 (write _test-input-stream " copy-byte-to *y, x\n")
9385 (write _test-input-stream "}\n")
9387 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9388 # registers except esp clobbered at this point
9390 89/<- %edx 4/r32/esp
9391 (flush _test-output-buffered-file)
9392 (flush _test-error-buffered-file)
9393 #? # dump _test-error-stream {{{
9395 #? (write-stream 2 _test-error-stream)
9397 #? (rewind-stream _test-error-stream)
9400 (check-stream-equal _test-output-stream "" "F - test-copy-byte-to-from-non-scalar-inout: output should be empty")
9401 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-byte-to: 'x' is too large to copy" "F - test-copy-byte-to-from-non-scalar-inout: error message")
9402 # check that stop(1) was called
9403 (check-ints-equal *(edx+4) 2 "F - test-copy-byte-to-from-non-scalar-inout: exit status")
9404 # don't restore from ebp
9405 81 0/subop/add %esp 8/imm32
9410 test-compare-with-no-inout:
9413 89/<- %ebp 4/r32/esp
9415 (clear-stream _test-input-stream)
9416 (clear-stream $_test-input-buffered-file->buffer)
9417 (clear-stream _test-output-stream)
9418 (clear-stream $_test-output-buffered-file->buffer)
9419 (clear-stream _test-error-stream)
9420 (clear-stream $_test-error-buffered-file->buffer)
9421 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9424 89/<- %edx 4/r32/esp
9425 (tailor-exit-descriptor %edx 0x10)
9427 (write _test-input-stream "fn foo {\n")
9428 (write _test-input-stream " var x: boolean\n")
9429 (write _test-input-stream " compare\n")
9430 (write _test-input-stream "}\n")
9432 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9433 # registers except esp clobbered at this point
9435 89/<- %edx 4/r32/esp
9436 (flush _test-output-buffered-file)
9437 (flush _test-error-buffered-file)
9438 #? # dump _test-error-stream {{{
9440 #? (write-stream 2 _test-error-stream)
9442 #? (rewind-stream _test-error-stream)
9445 (check-stream-equal _test-output-stream "" "F - test-compare-with-no-inout: output should be empty")
9446 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'compare' must have two inouts" "F - test-compare-with-no-inout: error message")
9447 # check that stop(1) was called
9448 (check-ints-equal *(edx+4) 2 "F - test-compare-with-no-inout: exit status")
9449 # don't restore from ebp
9450 81 0/subop/add %esp 8/imm32
9455 test-compare-with-just-one-inout:
9458 89/<- %ebp 4/r32/esp
9460 (clear-stream _test-input-stream)
9461 (clear-stream $_test-input-buffered-file->buffer)
9462 (clear-stream _test-output-stream)
9463 (clear-stream $_test-output-buffered-file->buffer)
9464 (clear-stream _test-error-stream)
9465 (clear-stream $_test-error-buffered-file->buffer)
9466 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9469 89/<- %edx 4/r32/esp
9470 (tailor-exit-descriptor %edx 0x10)
9472 (write _test-input-stream "fn foo {\n")
9473 (write _test-input-stream " var x: boolean\n")
9474 (write _test-input-stream " compare x\n")
9475 (write _test-input-stream "}\n")
9477 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9478 # registers except esp clobbered at this point
9480 89/<- %edx 4/r32/esp
9481 (flush _test-output-buffered-file)
9482 (flush _test-error-buffered-file)
9483 #? # dump _test-error-stream {{{
9485 #? (write-stream 2 _test-error-stream)
9487 #? (rewind-stream _test-error-stream)
9490 (check-stream-equal _test-output-stream "" "F - test-compare-with-just-one-inout: output should be empty")
9491 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'compare' must have two inouts" "F - test-compare-with-just-one-inout: error message")
9492 # check that stop(1) was called
9493 (check-ints-equal *(edx+4) 2 "F - test-compare-with-just-one-inout: exit status")
9494 # don't restore from ebp
9495 81 0/subop/add %esp 8/imm32
9500 test-compare-with-too-many-inouts:
9503 89/<- %ebp 4/r32/esp
9505 (clear-stream _test-input-stream)
9506 (clear-stream $_test-input-buffered-file->buffer)
9507 (clear-stream _test-output-stream)
9508 (clear-stream $_test-output-buffered-file->buffer)
9509 (clear-stream _test-error-stream)
9510 (clear-stream $_test-error-buffered-file->buffer)
9511 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9514 89/<- %edx 4/r32/esp
9515 (tailor-exit-descriptor %edx 0x10)
9517 (write _test-input-stream "fn foo {\n")
9518 (write _test-input-stream " var x: boolean\n")
9519 (write _test-input-stream " compare x, 0, 0\n")
9520 (write _test-input-stream "}\n")
9522 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9523 # registers except esp clobbered at this point
9525 89/<- %edx 4/r32/esp
9526 (flush _test-output-buffered-file)
9527 (flush _test-error-buffered-file)
9528 #? # dump _test-error-stream {{{
9530 #? (write-stream 2 _test-error-stream)
9532 #? (rewind-stream _test-error-stream)
9535 (check-stream-equal _test-output-stream "" "F - test-compare-with-too-many-inouts: output should be empty")
9536 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'compare' must have two inouts" "F - test-compare-with-too-many-inouts: error message")
9537 # check that stop(1) was called
9538 (check-ints-equal *(edx+4) 2 "F - test-compare-with-too-many-inouts: exit status")
9539 # don't restore from ebp
9540 81 0/subop/add %esp 8/imm32
9545 test-compare-with-output:
9548 89/<- %ebp 4/r32/esp
9550 (clear-stream _test-input-stream)
9551 (clear-stream $_test-input-buffered-file->buffer)
9552 (clear-stream _test-output-stream)
9553 (clear-stream $_test-output-buffered-file->buffer)
9554 (clear-stream _test-error-stream)
9555 (clear-stream $_test-error-buffered-file->buffer)
9556 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9559 89/<- %edx 4/r32/esp
9560 (tailor-exit-descriptor %edx 0x10)
9562 (write _test-input-stream "fn foo {\n")
9563 (write _test-input-stream " var x/eax: boolean <- copy 0\n")
9564 (write _test-input-stream " var y/ecx: boolean <- copy 0\n")
9565 (write _test-input-stream " x <- compare y, 0\n")
9566 (write _test-input-stream "}\n")
9568 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9569 # registers except esp clobbered at this point
9571 89/<- %edx 4/r32/esp
9572 (flush _test-output-buffered-file)
9573 (flush _test-error-buffered-file)
9574 #? # dump _test-error-stream {{{
9576 #? (write-stream 2 _test-error-stream)
9578 #? (rewind-stream _test-error-stream)
9581 (check-stream-equal _test-output-stream "" "F - test-compare-with-output: output should be empty")
9582 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'compare' must not have any outputs" "F - test-compare-with-output: error message")
9583 # check that stop(1) was called
9584 (check-ints-equal *(edx+4) 2 "F - test-compare-with-output: exit status")
9585 # don't restore from ebp
9586 81 0/subop/add %esp 8/imm32
9591 test-compare-invalid-value-to-address:
9594 89/<- %ebp 4/r32/esp
9596 (clear-stream _test-input-stream)
9597 (clear-stream $_test-input-buffered-file->buffer)
9598 (clear-stream _test-output-stream)
9599 (clear-stream $_test-output-buffered-file->buffer)
9600 (clear-stream _test-error-stream)
9601 (clear-stream $_test-error-buffered-file->buffer)
9602 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9605 89/<- %edx 4/r32/esp
9606 (tailor-exit-descriptor %edx 0x10)
9608 (write _test-input-stream "fn foo {\n")
9609 (write _test-input-stream " var x/eax: int <- copy 0\n")
9610 (write _test-input-stream " var y: (addr int)\n")
9611 (write _test-input-stream " compare y, x\n")
9612 (write _test-input-stream "}\n")
9614 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9615 # registers except esp clobbered at this point
9617 89/<- %edx 4/r32/esp
9618 (flush _test-output-buffered-file)
9619 (flush _test-error-buffered-file)
9620 #? # dump _test-error-stream {{{
9622 #? (write-stream 2 _test-error-stream)
9624 #? (rewind-stream _test-error-stream)
9627 (check-stream-equal _test-output-stream "" "F - test-compare-invalid-value-to-address: output should be empty")
9628 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: 'y' must be a non-addr non-offset scalar" "F - test-compare-invalid-value-to-address: error message")
9629 # check that stop(1) was called
9630 (check-ints-equal *(edx+4) 2 "F - test-compare-invalid-value-to-address: exit status")
9631 # don't restore from ebp
9632 81 0/subop/add %esp 8/imm32
9637 test-compare-address:
9640 89/<- %ebp 4/r32/esp
9642 (clear-stream _test-input-stream)
9643 (clear-stream $_test-input-buffered-file->buffer)
9644 (clear-stream _test-output-stream)
9645 (clear-stream $_test-output-buffered-file->buffer)
9647 (write _test-input-stream "fn foo {\n")
9648 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n")
9649 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n")
9650 (write _test-input-stream " compare y, x\n")
9651 (write _test-input-stream "}\n")
9653 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
9654 (flush _test-output-buffered-file)
9660 test-compare-deref-address:
9663 89/<- %ebp 4/r32/esp
9665 (clear-stream _test-input-stream)
9666 (clear-stream $_test-input-buffered-file->buffer)
9667 (clear-stream _test-output-stream)
9668 (clear-stream $_test-output-buffered-file->buffer)
9670 (write _test-input-stream "fn foo {\n")
9671 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n")
9672 (write _test-input-stream " var y/ecx: (addr addr int) <- copy 0\n")
9673 (write _test-input-stream " compare *y, x\n")
9674 (write _test-input-stream "}\n")
9676 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
9677 (flush _test-output-buffered-file)
9683 test-compare-two-vars-in-memory:
9686 89/<- %ebp 4/r32/esp
9688 (clear-stream _test-input-stream)
9689 (clear-stream $_test-input-buffered-file->buffer)
9690 (clear-stream _test-output-stream)
9691 (clear-stream $_test-output-buffered-file->buffer)
9692 (clear-stream _test-error-stream)
9693 (clear-stream $_test-error-buffered-file->buffer)
9694 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9697 89/<- %edx 4/r32/esp
9698 (tailor-exit-descriptor %edx 0x10)
9700 (write _test-input-stream "fn foo {\n")
9701 (write _test-input-stream " var x: boolean\n")
9702 (write _test-input-stream " compare x, x\n")
9703 (write _test-input-stream "}\n")
9705 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9706 # registers except esp clobbered at this point
9708 89/<- %edx 4/r32/esp
9709 (flush _test-output-buffered-file)
9710 (flush _test-error-buffered-file)
9711 #? # dump _test-error-stream {{{
9713 #? (write-stream 2 _test-error-stream)
9715 #? (rewind-stream _test-error-stream)
9718 (check-stream-equal _test-output-stream "" "F - test-compare-two-vars-in-memory: output should be empty")
9719 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: both inouts are in memory" "F - test-compare-two-vars-in-memory: error message")
9720 # check that stop(1) was called
9721 (check-ints-equal *(edx+4) 2 "F - test-compare-two-vars-in-memory: exit status")
9722 # don't restore from ebp
9723 81 0/subop/add %esp 8/imm32
9728 test-compare-non-scalar:
9731 89/<- %ebp 4/r32/esp
9733 (clear-stream _test-input-stream)
9734 (clear-stream $_test-input-buffered-file->buffer)
9735 (clear-stream _test-output-stream)
9736 (clear-stream $_test-output-buffered-file->buffer)
9737 (clear-stream _test-error-stream)
9738 (clear-stream $_test-error-buffered-file->buffer)
9739 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9742 89/<- %edx 4/r32/esp
9743 (tailor-exit-descriptor %edx 0x10)
9745 (write _test-input-stream "fn foo {\n")
9746 (write _test-input-stream " var x: (handle int)\n")
9747 (write _test-input-stream " var y: int\n")
9748 (write _test-input-stream " compare y, x\n")
9749 (write _test-input-stream "}\n")
9751 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9752 # registers except esp clobbered at this point
9754 89/<- %edx 4/r32/esp
9755 (flush _test-output-buffered-file)
9756 (flush _test-error-buffered-file)
9757 #? # dump _test-error-stream {{{
9759 #? (write-stream 2 _test-error-stream)
9761 #? (rewind-stream _test-error-stream)
9764 (check-stream-equal _test-output-stream "" "F - test-compare-non-scalar: output should be empty")
9765 #? (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: 'x' is too large to compare" "F - test-compare-non-scalar: error message")
9766 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: both inouts are in memory" "F - test-compare-non-scalar: error message")
9767 # check that stop(1) was called
9768 (check-ints-equal *(edx+4) 2 "F - test-compare-non-scalar: exit status")
9769 # don't restore from ebp
9770 81 0/subop/add %esp 8/imm32
9775 test-compare-with-string-literal:
9778 89/<- %ebp 4/r32/esp
9780 (clear-stream _test-input-stream)
9781 (clear-stream $_test-input-buffered-file->buffer)
9782 (clear-stream _test-output-stream)
9783 (clear-stream $_test-output-buffered-file->buffer)
9784 (clear-stream _test-error-stream)
9785 (clear-stream $_test-error-buffered-file->buffer)
9786 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9789 89/<- %edx 4/r32/esp
9790 (tailor-exit-descriptor %edx 0x10)
9792 (write _test-input-stream "fn foo {\n")
9793 (write _test-input-stream " var x/eax: (addr array byte) <- copy 0\n")
9794 (write _test-input-stream " compare x, \"abc\"\n")
9795 (write _test-input-stream "}\n")
9797 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9798 # registers except esp clobbered at this point
9800 89/<- %edx 4/r32/esp
9801 (flush _test-output-buffered-file)
9802 (flush _test-error-buffered-file)
9803 #? # dump _test-error-stream {{{
9805 #? (write-stream 2 _test-error-stream)
9807 #? (rewind-stream _test-error-stream)
9810 (check-stream-equal _test-output-stream "" "F - test-compare-with-string-literal: output should be empty")
9811 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compare: string literal \"abc\" is not supported; use the string-equal? function" "F - test-compare-with-string-literal: error message")
9812 # check that stop(1) was called
9813 (check-ints-equal *(edx+4) 2 "F - test-compare-with-string-literal: exit status")
9814 # don't restore from ebp
9815 81 0/subop/add %esp 8/imm32
9820 test-address-with-no-inout:
9823 89/<- %ebp 4/r32/esp
9825 (clear-stream _test-input-stream)
9826 (clear-stream $_test-input-buffered-file->buffer)
9827 (clear-stream _test-output-stream)
9828 (clear-stream $_test-output-buffered-file->buffer)
9829 (clear-stream _test-error-stream)
9830 (clear-stream $_test-error-buffered-file->buffer)
9831 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9834 89/<- %edx 4/r32/esp
9835 (tailor-exit-descriptor %edx 0x10)
9837 (write _test-input-stream "fn foo {\n")
9838 (write _test-input-stream " var x/eax: boolean <- address\n")
9839 (write _test-input-stream "}\n")
9841 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9842 # registers except esp clobbered at this point
9844 89/<- %edx 4/r32/esp
9845 (flush _test-output-buffered-file)
9846 (flush _test-error-buffered-file)
9847 #? # dump _test-error-stream {{{
9849 #? (write-stream 2 _test-error-stream)
9851 #? (rewind-stream _test-error-stream)
9854 (check-stream-equal _test-output-stream "" "F - test-address-with-no-inout: output should be empty")
9855 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'address' expects an inout" "F - test-address-with-no-inout: error message")
9856 # check that stop(1) was called
9857 (check-ints-equal *(edx+4) 2 "F - test-address-with-no-inout: exit status")
9858 # don't restore from ebp
9859 81 0/subop/add %esp 8/imm32
9864 test-address-with-multiple-inouts:
9867 89/<- %ebp 4/r32/esp
9869 (clear-stream _test-input-stream)
9870 (clear-stream $_test-input-buffered-file->buffer)
9871 (clear-stream _test-output-stream)
9872 (clear-stream $_test-output-buffered-file->buffer)
9873 (clear-stream _test-error-stream)
9874 (clear-stream $_test-error-buffered-file->buffer)
9875 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9878 89/<- %edx 4/r32/esp
9879 (tailor-exit-descriptor %edx 0x10)
9881 (write _test-input-stream "fn foo {\n")
9882 (write _test-input-stream " var x/eax: boolean <- address 0, 0\n")
9883 (write _test-input-stream "}\n")
9885 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9886 # registers except esp clobbered at this point
9888 89/<- %edx 4/r32/esp
9889 (flush _test-output-buffered-file)
9890 (flush _test-error-buffered-file)
9891 #? # dump _test-error-stream {{{
9893 #? (write-stream 2 _test-error-stream)
9895 #? (rewind-stream _test-error-stream)
9898 (check-stream-equal _test-output-stream "" "F - test-address-with-multiple-inouts: output should be empty")
9899 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'address' must have just one inout" "F - test-address-with-multiple-inouts: error message")
9900 # check that stop(1) was called
9901 (check-ints-equal *(edx+4) 2 "F - test-address-with-multiple-inouts: exit status")
9902 # don't restore from ebp
9903 81 0/subop/add %esp 8/imm32
9908 test-address-with-no-output:
9911 89/<- %ebp 4/r32/esp
9913 (clear-stream _test-input-stream)
9914 (clear-stream $_test-input-buffered-file->buffer)
9915 (clear-stream _test-output-stream)
9916 (clear-stream $_test-output-buffered-file->buffer)
9917 (clear-stream _test-error-stream)
9918 (clear-stream $_test-error-buffered-file->buffer)
9919 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9922 89/<- %edx 4/r32/esp
9923 (tailor-exit-descriptor %edx 0x10)
9925 (write _test-input-stream "fn foo {\n")
9926 (write _test-input-stream " address 0\n")
9927 (write _test-input-stream "}\n")
9929 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9930 # registers except esp clobbered at this point
9932 89/<- %edx 4/r32/esp
9933 (flush _test-output-buffered-file)
9934 (flush _test-error-buffered-file)
9935 #? # dump _test-error-stream {{{
9937 #? (write-stream 2 _test-error-stream)
9939 #? (rewind-stream _test-error-stream)
9942 (check-stream-equal _test-output-stream "" "F - test-address-with-no-output: output should be empty")
9943 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'address' expects an output" "F - test-address-with-no-output: error message")
9944 # check that stop(1) was called
9945 (check-ints-equal *(edx+4) 2 "F - test-address-with-no-output: exit status")
9946 # don't restore from ebp
9947 81 0/subop/add %esp 8/imm32
9952 test-address-with-multiple-outputs:
9955 89/<- %ebp 4/r32/esp
9957 (clear-stream _test-input-stream)
9958 (clear-stream $_test-input-buffered-file->buffer)
9959 (clear-stream _test-output-stream)
9960 (clear-stream $_test-output-buffered-file->buffer)
9961 (clear-stream _test-error-stream)
9962 (clear-stream $_test-error-buffered-file->buffer)
9963 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
9966 89/<- %edx 4/r32/esp
9967 (tailor-exit-descriptor %edx 0x10)
9969 (write _test-input-stream "fn foo {\n")
9970 (write _test-input-stream " var x/eax: boolean <- copy 0\n")
9971 (write _test-input-stream " var y/ecx: boolean <- copy 0\n")
9972 (write _test-input-stream " x, y <- address 0\n")
9973 (write _test-input-stream "}\n")
9975 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
9976 # registers except esp clobbered at this point
9978 89/<- %edx 4/r32/esp
9979 (flush _test-output-buffered-file)
9980 (flush _test-error-buffered-file)
9981 #? # dump _test-error-stream {{{
9983 #? (write-stream 2 _test-error-stream)
9985 #? (rewind-stream _test-error-stream)
9988 (check-stream-equal _test-output-stream "" "F - test-address-with-multiple-outputs: output should be empty")
9989 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'address' must have just one output" "F - test-address-with-multiple-outputs: error message")
9990 # check that stop(1) was called
9991 (check-ints-equal *(edx+4) 2 "F - test-address-with-multiple-outputs: exit status")
9992 # don't restore from ebp
9993 81 0/subop/add %esp 8/imm32
9998 # silly but it works
9999 test-address-of-deref:
10002 89/<- %ebp 4/r32/esp
10004 (clear-stream _test-input-stream)
10005 (clear-stream $_test-input-buffered-file->buffer)
10006 (clear-stream _test-output-stream)
10007 (clear-stream $_test-output-buffered-file->buffer)
10009 (write _test-input-stream "fn foo {\n")
10010 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n")
10011 (write _test-input-stream " var y/ecx: (addr int) <- address *x\n")
10012 (write _test-input-stream "}\n")
10014 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
10015 (flush _test-output-buffered-file)
10021 test-address-to-non-register:
10024 89/<- %ebp 4/r32/esp
10026 (clear-stream _test-input-stream)
10027 (clear-stream $_test-input-buffered-file->buffer)
10028 (clear-stream _test-output-stream)
10029 (clear-stream $_test-output-buffered-file->buffer)
10030 (clear-stream _test-error-stream)
10031 (clear-stream $_test-error-buffered-file->buffer)
10032 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10035 89/<- %edx 4/r32/esp
10036 (tailor-exit-descriptor %edx 0x10)
10038 (write _test-input-stream "fn foo {\n")
10039 (write _test-input-stream " var x: (addr int)\n")
10040 (write _test-input-stream " x <- address 0\n")
10041 (write _test-input-stream "}\n")
10043 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10044 # registers except esp clobbered at this point
10046 89/<- %edx 4/r32/esp
10047 (flush _test-output-buffered-file)
10048 (flush _test-error-buffered-file)
10049 #? # dump _test-error-stream {{{
10051 #? (write-stream 2 _test-error-stream)
10053 #? (rewind-stream _test-error-stream)
10056 (check-stream-equal _test-output-stream "" "F - test-address-to-non-register: output should be empty")
10057 (check-next-stream-line-equal _test-error-stream "fn foo: stmt address: output 'x' not in a register" "F - test-address-to-non-register: error message")
10058 # check that stop(1) was called
10059 (check-ints-equal *(edx+4) 2 "F - test-address-to-non-register: exit status")
10060 # don't restore from ebp
10061 81 0/subop/add %esp 8/imm32
10066 test-address-with-wrong-type:
10069 89/<- %ebp 4/r32/esp
10071 (clear-stream _test-input-stream)
10072 (clear-stream $_test-input-buffered-file->buffer)
10073 (clear-stream _test-output-stream)
10074 (clear-stream $_test-output-buffered-file->buffer)
10075 (clear-stream _test-error-stream)
10076 (clear-stream $_test-error-buffered-file->buffer)
10077 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10080 89/<- %edx 4/r32/esp
10081 (tailor-exit-descriptor %edx 0x10)
10083 (write _test-input-stream "fn foo {\n")
10084 (write _test-input-stream " var x: int\n")
10085 (write _test-input-stream " var y/eax: (addr boolean) <- address x\n")
10086 (write _test-input-stream "}\n")
10088 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10089 # registers except esp clobbered at this point
10091 89/<- %edx 4/r32/esp
10092 (flush _test-output-buffered-file)
10093 (flush _test-error-buffered-file)
10094 #? # dump _test-error-stream {{{
10096 #? (write-stream 2 _test-error-stream)
10098 #? (rewind-stream _test-error-stream)
10101 (check-stream-equal _test-output-stream "" "F - test-address-with-wrong-type: output should be empty")
10102 (check-next-stream-line-equal _test-error-stream "fn foo: stmt address: output 'y' cannot hold address of 'x'" "F - test-address-with-wrong-type: error message")
10103 # check that stop(1) was called
10104 (check-ints-equal *(edx+4) 2 "F - test-address-with-wrong-type: exit status")
10105 # don't restore from ebp
10106 81 0/subop/add %esp 8/imm32
10111 test-address-with-right-type-for-array:
10114 89/<- %ebp 4/r32/esp
10116 (clear-stream _test-input-stream)
10117 (clear-stream $_test-input-buffered-file->buffer)
10118 (clear-stream _test-output-stream)
10119 (clear-stream $_test-output-buffered-file->buffer)
10121 (write _test-input-stream "fn foo {\n")
10122 (write _test-input-stream " var x: (array int 3)\n")
10123 (write _test-input-stream " var y/eax: (addr array int) <- address x\n")
10124 (write _test-input-stream "}\n")
10126 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
10127 (flush _test-output-buffered-file)
10130 89/<- %esp 5/r32/ebp
10134 test-address-with-right-type-for-stream:
10137 89/<- %ebp 4/r32/esp
10139 (clear-stream _test-input-stream)
10140 (clear-stream $_test-input-buffered-file->buffer)
10141 (clear-stream _test-output-stream)
10142 (clear-stream $_test-output-buffered-file->buffer)
10144 (write _test-input-stream "fn foo {\n")
10145 (write _test-input-stream " var x: (stream int 3)\n")
10146 (write _test-input-stream " var y/eax: (addr stream int) <- address x\n")
10147 (write _test-input-stream "}\n")
10149 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
10150 (flush _test-output-buffered-file)
10153 89/<- %esp 5/r32/ebp
10157 test-get-with-wrong-field:
10160 89/<- %ebp 4/r32/esp
10162 (clear-stream _test-input-stream)
10163 (clear-stream $_test-input-buffered-file->buffer)
10164 (clear-stream _test-output-stream)
10165 (clear-stream $_test-output-buffered-file->buffer)
10166 (clear-stream _test-error-stream)
10167 (clear-stream $_test-error-buffered-file->buffer)
10168 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10171 89/<- %edx 4/r32/esp
10172 (tailor-exit-descriptor %edx 0x10)
10174 (write _test-input-stream "fn foo {\n")
10175 (write _test-input-stream " var a: t\n")
10176 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n")
10177 (write _test-input-stream "}\n")
10178 (write _test-input-stream "type t {\n")
10179 (write _test-input-stream " x: int\n")
10180 (write _test-input-stream "}\n")
10182 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10183 # registers except esp clobbered at this point
10185 89/<- %edx 4/r32/esp
10186 (flush _test-output-buffered-file)
10187 (flush _test-error-buffered-file)
10188 #? # dump _test-error-stream {{{
10190 #? (write-stream 2 _test-error-stream)
10192 #? (rewind-stream _test-error-stream)
10195 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-field: output should be empty")
10196 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: type 't' has no member called 'y'" "F - test-get-with-wrong-field: error message")
10197 # check that stop(1) was called
10198 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-field: exit status")
10199 # don't restore from ebp
10200 81 0/subop/add %esp 8/imm32
10205 test-get-with-wrong-base-type:
10208 89/<- %ebp 4/r32/esp
10210 (clear-stream _test-input-stream)
10211 (clear-stream $_test-input-buffered-file->buffer)
10212 (clear-stream _test-output-stream)
10213 (clear-stream $_test-output-buffered-file->buffer)
10214 (clear-stream _test-error-stream)
10215 (clear-stream $_test-error-buffered-file->buffer)
10216 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10219 89/<- %edx 4/r32/esp
10220 (tailor-exit-descriptor %edx 0x10)
10222 (write _test-input-stream "fn foo {\n")
10223 (write _test-input-stream " var a: int\n")
10224 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n")
10225 (write _test-input-stream "}\n")
10227 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10228 # registers except esp clobbered at this point
10230 89/<- %edx 4/r32/esp
10231 (flush _test-output-buffered-file)
10232 (flush _test-error-buffered-file)
10233 #? # dump _test-error-stream {{{
10235 #? (write-stream 2 _test-error-stream)
10237 #? (rewind-stream _test-error-stream)
10240 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type: output should be empty")
10241 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' must have a 'type' definition" "F - test-get-with-wrong-base-type: error message")
10242 # check that stop(1) was called
10243 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type: exit status")
10244 # don't restore from ebp
10245 81 0/subop/add %esp 8/imm32
10250 test-get-with-wrong-base-type-2:
10253 89/<- %ebp 4/r32/esp
10255 (clear-stream _test-input-stream)
10256 (clear-stream $_test-input-buffered-file->buffer)
10257 (clear-stream _test-output-stream)
10258 (clear-stream $_test-output-buffered-file->buffer)
10259 (clear-stream _test-error-stream)
10260 (clear-stream $_test-error-buffered-file->buffer)
10261 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10264 89/<- %edx 4/r32/esp
10265 (tailor-exit-descriptor %edx 0x10)
10267 (write _test-input-stream "fn foo {\n")
10268 (write _test-input-stream " var a: (addr t)\n")
10269 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n")
10270 (write _test-input-stream "}\n")
10271 (write _test-input-stream "type t {\n")
10272 (write _test-input-stream " x: int\n")
10273 (write _test-input-stream "}\n")
10275 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10276 # registers except esp clobbered at this point
10278 89/<- %edx 4/r32/esp
10279 (flush _test-output-buffered-file)
10280 (flush _test-error-buffered-file)
10281 #? # dump _test-error-stream {{{
10283 #? (write-stream 2 _test-error-stream)
10285 #? (rewind-stream _test-error-stream)
10288 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type-2: output should be empty")
10289 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' is an 'addr' type, and so must live in a register" "F - test-get-with-wrong-base-type-2: error message")
10290 # check that stop(1) was called
10291 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type-2: exit status")
10292 # don't restore from ebp
10293 81 0/subop/add %esp 8/imm32
10298 test-get-with-wrong-base-type-3:
10301 89/<- %ebp 4/r32/esp
10303 (clear-stream _test-input-stream)
10304 (clear-stream $_test-input-buffered-file->buffer)
10305 (clear-stream _test-output-stream)
10306 (clear-stream $_test-output-buffered-file->buffer)
10307 (clear-stream _test-error-stream)
10308 (clear-stream $_test-error-buffered-file->buffer)
10309 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10312 89/<- %edx 4/r32/esp
10313 (tailor-exit-descriptor %edx 0x10)
10315 (write _test-input-stream "fn foo {\n")
10316 (write _test-input-stream " var a: (handle int)\n")
10317 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n")
10318 (write _test-input-stream "}\n")
10320 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10321 # registers except esp clobbered at this point
10323 89/<- %edx 4/r32/esp
10324 (flush _test-output-buffered-file)
10325 (flush _test-error-buffered-file)
10326 #? # dump _test-error-stream {{{
10328 #? (write-stream 2 _test-error-stream)
10330 #? (rewind-stream _test-error-stream)
10333 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type-3: output should be empty")
10334 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: var 'a' must have a 'type' definition" "F - test-get-with-wrong-base-type-3: error message")
10335 # check that stop(1) was called
10336 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type-3: exit status")
10337 # don't restore from ebp
10338 81 0/subop/add %esp 8/imm32
10343 test-get-with-wrong-offset-type:
10346 89/<- %ebp 4/r32/esp
10348 (clear-stream _test-input-stream)
10349 (clear-stream $_test-input-buffered-file->buffer)
10350 (clear-stream _test-output-stream)
10351 (clear-stream $_test-output-buffered-file->buffer)
10352 (clear-stream _test-error-stream)
10353 (clear-stream $_test-error-buffered-file->buffer)
10354 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10357 89/<- %edx 4/r32/esp
10358 (tailor-exit-descriptor %edx 0x10)
10360 (write _test-input-stream "fn foo {\n")
10361 (write _test-input-stream " var a: t\n")
10362 (write _test-input-stream " var b: int\n")
10363 (write _test-input-stream " var c/ecx: (addr int) <- get a, b\n")
10364 (write _test-input-stream "}\n")
10365 (write _test-input-stream "type t {\n")
10366 (write _test-input-stream " x: int\n")
10367 (write _test-input-stream "}\n")
10369 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10370 # registers except esp clobbered at this point
10372 89/<- %edx 4/r32/esp
10373 (flush _test-output-buffered-file)
10374 (flush _test-error-buffered-file)
10375 #? # dump _test-error-stream {{{
10377 #? (write-stream 2 _test-error-stream)
10379 #? (rewind-stream _test-error-stream)
10382 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-offset-type: output should be empty")
10383 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: type 't' has no member called 'b'" "F - test-get-with-wrong-offset-type: error message")
10384 # check that stop(1) was called
10385 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-offset-type: exit status")
10386 # don't restore from ebp
10387 81 0/subop/add %esp 8/imm32
10392 test-get-with-wrong-output-type:
10395 89/<- %ebp 4/r32/esp
10397 (clear-stream _test-input-stream)
10398 (clear-stream $_test-input-buffered-file->buffer)
10399 (clear-stream _test-output-stream)
10400 (clear-stream $_test-output-buffered-file->buffer)
10401 (clear-stream _test-error-stream)
10402 (clear-stream $_test-error-buffered-file->buffer)
10403 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10406 89/<- %edx 4/r32/esp
10407 (tailor-exit-descriptor %edx 0x10)
10409 (write _test-input-stream "fn foo {\n")
10410 (write _test-input-stream " var a: t\n")
10411 (write _test-input-stream " var c: (addr int)\n")
10412 (write _test-input-stream " c <- get a, x\n")
10413 (write _test-input-stream "}\n")
10414 (write _test-input-stream "type t {\n")
10415 (write _test-input-stream " x: int\n")
10416 (write _test-input-stream "}\n")
10418 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10419 # registers except esp clobbered at this point
10421 89/<- %edx 4/r32/esp
10422 (flush _test-output-buffered-file)
10423 (flush _test-error-buffered-file)
10424 #? # dump _test-error-stream {{{
10426 #? (write-stream 2 _test-error-stream)
10428 #? (rewind-stream _test-error-stream)
10431 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type: output should be empty")
10432 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output 'c' is not in a register" "F - test-get-with-wrong-output-type: error message")
10433 # check that stop(1) was called
10434 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type: exit status")
10435 # don't restore from ebp
10436 81 0/subop/add %esp 8/imm32
10441 test-get-with-wrong-output-type-2:
10444 89/<- %ebp 4/r32/esp
10446 (clear-stream _test-input-stream)
10447 (clear-stream $_test-input-buffered-file->buffer)
10448 (clear-stream _test-output-stream)
10449 (clear-stream $_test-output-buffered-file->buffer)
10450 (clear-stream _test-error-stream)
10451 (clear-stream $_test-error-buffered-file->buffer)
10452 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10455 89/<- %edx 4/r32/esp
10456 (tailor-exit-descriptor %edx 0x10)
10458 (write _test-input-stream "fn foo {\n")
10459 (write _test-input-stream " var a: t\n")
10460 (write _test-input-stream " var c/ecx: int <- get a, x\n")
10461 (write _test-input-stream "}\n")
10462 (write _test-input-stream "type t {\n")
10463 (write _test-input-stream " x: int\n")
10464 (write _test-input-stream "}\n")
10466 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10467 # registers except esp clobbered at this point
10469 89/<- %edx 4/r32/esp
10470 (flush _test-output-buffered-file)
10471 (flush _test-error-buffered-file)
10472 #? # dump _test-error-stream {{{
10474 #? (write-stream 2 _test-error-stream)
10476 #? (rewind-stream _test-error-stream)
10479 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-2: output should be empty")
10480 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an addr" "F - test-get-with-wrong-output-type-2: error message")
10481 # check that stop(1) was called
10482 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-2: exit status")
10483 # don't restore from ebp
10484 81 0/subop/add %esp 8/imm32
10489 test-get-with-wrong-output-type-3:
10492 89/<- %ebp 4/r32/esp
10494 (clear-stream _test-input-stream)
10495 (clear-stream $_test-input-buffered-file->buffer)
10496 (clear-stream _test-output-stream)
10497 (clear-stream $_test-output-buffered-file->buffer)
10498 (clear-stream _test-error-stream)
10499 (clear-stream $_test-error-buffered-file->buffer)
10500 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10503 89/<- %edx 4/r32/esp
10504 (tailor-exit-descriptor %edx 0x10)
10506 (write _test-input-stream "fn foo {\n")
10507 (write _test-input-stream " var a: t\n")
10508 (write _test-input-stream " var c/ecx: (array int) <- get a, x\n")
10509 (write _test-input-stream "}\n")
10510 (write _test-input-stream "type t {\n")
10511 (write _test-input-stream " x: int\n")
10512 (write _test-input-stream "}\n")
10514 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10515 # registers except esp clobbered at this point
10517 89/<- %edx 4/r32/esp
10518 (flush _test-output-buffered-file)
10519 (flush _test-error-buffered-file)
10520 #? # dump _test-error-stream {{{
10522 #? (write-stream 2 _test-error-stream)
10524 #? (rewind-stream _test-error-stream)
10527 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-3: output should be empty")
10528 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an addr" "F - test-get-with-wrong-output-type-3: error message")
10529 # check that stop(1) was called
10530 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-3: exit status")
10531 # don't restore from ebp
10532 81 0/subop/add %esp 8/imm32
10537 test-get-with-wrong-output-type-4:
10540 89/<- %ebp 4/r32/esp
10542 (clear-stream _test-input-stream)
10543 (clear-stream $_test-input-buffered-file->buffer)
10544 (clear-stream _test-output-stream)
10545 (clear-stream $_test-output-buffered-file->buffer)
10546 (clear-stream _test-error-stream)
10547 (clear-stream $_test-error-buffered-file->buffer)
10548 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10551 89/<- %edx 4/r32/esp
10552 (tailor-exit-descriptor %edx 0x10)
10554 (write _test-input-stream "fn foo {\n")
10555 (write _test-input-stream " var a: t\n")
10556 (write _test-input-stream " var c/ecx: (addr boolean) <- get a, x\n")
10557 (write _test-input-stream "}\n")
10558 (write _test-input-stream "type t {\n")
10559 (write _test-input-stream " x: int\n")
10560 (write _test-input-stream "}\n")
10562 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10563 # registers except esp clobbered at this point
10565 89/<- %edx 4/r32/esp
10566 (flush _test-output-buffered-file)
10567 (flush _test-error-buffered-file)
10568 #? # dump _test-error-stream {{{
10570 #? (write-stream 2 _test-error-stream)
10572 #? (rewind-stream _test-error-stream)
10575 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-4: output should be empty")
10576 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: wrong output type for member 'x' of type 't'" "F - test-get-with-wrong-output-type-4: error message")
10577 # check that stop(1) was called
10578 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-4: exit status")
10579 # don't restore from ebp
10580 81 0/subop/add %esp 8/imm32
10585 test-get-with-wrong-output-type-5:
10588 89/<- %ebp 4/r32/esp
10590 (clear-stream _test-input-stream)
10591 (clear-stream $_test-input-buffered-file->buffer)
10592 (clear-stream _test-output-stream)
10593 (clear-stream $_test-output-buffered-file->buffer)
10595 (write _test-input-stream "fn foo {\n")
10596 (write _test-input-stream " var a: t\n")
10597 (write _test-input-stream " var c/ecx: (addr handle int) <- get a, x\n")
10598 (write _test-input-stream "}\n")
10599 (write _test-input-stream "type t {\n")
10600 (write _test-input-stream " x: (handle int)\n")
10601 (write _test-input-stream "}\n")
10603 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
10604 (flush _test-output-buffered-file)
10607 89/<- %esp 5/r32/ebp
10611 test-get-with-too-few-inouts:
10614 89/<- %ebp 4/r32/esp
10616 (clear-stream _test-input-stream)
10617 (clear-stream $_test-input-buffered-file->buffer)
10618 (clear-stream _test-output-stream)
10619 (clear-stream $_test-output-buffered-file->buffer)
10620 (clear-stream _test-error-stream)
10621 (clear-stream $_test-error-buffered-file->buffer)
10622 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10625 89/<- %edx 4/r32/esp
10626 (tailor-exit-descriptor %edx 0x10)
10628 (write _test-input-stream "fn foo {\n")
10629 (write _test-input-stream " var a: t\n")
10630 (write _test-input-stream " var c/ecx: (addr int) <- get a\n")
10631 (write _test-input-stream "}\n")
10632 (write _test-input-stream "type t {\n")
10633 (write _test-input-stream " x: int\n")
10634 (write _test-input-stream "}\n")
10636 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10637 # registers except esp clobbered at this point
10639 89/<- %edx 4/r32/esp
10640 (flush _test-output-buffered-file)
10641 (flush _test-error-buffered-file)
10642 #? # dump _test-error-stream {{{
10644 #? (write-stream 2 _test-error-stream)
10646 #? (rewind-stream _test-error-stream)
10649 (check-stream-equal _test-output-stream "" "F - test-get-with-too-few-inouts: output should be empty")
10650 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too few inouts (2 required)" "F - test-get-with-too-few-inouts: error message")
10651 # check that stop(1) was called
10652 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-few-inouts: exit status")
10653 # don't restore from ebp
10654 81 0/subop/add %esp 8/imm32
10659 test-get-with-too-many-inouts:
10662 89/<- %ebp 4/r32/esp
10664 (clear-stream _test-input-stream)
10665 (clear-stream $_test-input-buffered-file->buffer)
10666 (clear-stream _test-output-stream)
10667 (clear-stream $_test-output-buffered-file->buffer)
10668 (clear-stream _test-error-stream)
10669 (clear-stream $_test-error-buffered-file->buffer)
10670 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10673 89/<- %edx 4/r32/esp
10674 (tailor-exit-descriptor %edx 0x10)
10676 (write _test-input-stream "fn foo {\n")
10677 (write _test-input-stream " var a: t\n")
10678 (write _test-input-stream " var c/ecx: (addr int) <- get a, x, 0\n")
10679 (write _test-input-stream "}\n")
10680 (write _test-input-stream "type t {\n")
10681 (write _test-input-stream " x: int\n")
10682 (write _test-input-stream "}\n")
10684 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10685 # registers except esp clobbered at this point
10687 89/<- %edx 4/r32/esp
10688 (flush _test-output-buffered-file)
10689 (flush _test-error-buffered-file)
10690 #? # dump _test-error-stream {{{
10692 #? (write-stream 2 _test-error-stream)
10694 #? (rewind-stream _test-error-stream)
10697 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-inouts: output should be empty")
10698 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too many inouts (2 required)" "F - test-get-with-too-many-inouts: error message")
10699 # check that stop(1) was called
10700 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-inouts: exit status")
10701 # don't restore from ebp
10702 81 0/subop/add %esp 8/imm32
10707 test-get-with-no-output:
10710 89/<- %ebp 4/r32/esp
10712 (clear-stream _test-input-stream)
10713 (clear-stream $_test-input-buffered-file->buffer)
10714 (clear-stream _test-output-stream)
10715 (clear-stream $_test-output-buffered-file->buffer)
10716 (clear-stream _test-error-stream)
10717 (clear-stream $_test-error-buffered-file->buffer)
10718 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10721 89/<- %edx 4/r32/esp
10722 (tailor-exit-descriptor %edx 0x10)
10724 (write _test-input-stream "fn foo {\n")
10725 (write _test-input-stream " var a: t\n")
10726 (write _test-input-stream " get a, x\n")
10727 (write _test-input-stream "}\n")
10728 (write _test-input-stream "type t {\n")
10729 (write _test-input-stream " x: int\n")
10730 (write _test-input-stream "}\n")
10732 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10733 # registers except esp clobbered at this point
10735 89/<- %edx 4/r32/esp
10736 (flush _test-output-buffered-file)
10737 (flush _test-error-buffered-file)
10738 #? # dump _test-error-stream {{{
10740 #? (write-stream 2 _test-error-stream)
10742 #? (rewind-stream _test-error-stream)
10745 (check-stream-equal _test-output-stream "" "F - test-get-with-no-output: output should be empty")
10746 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: must have an output" "F - test-get-with-no-output: error message")
10747 # check that stop(1) was called
10748 (check-ints-equal *(edx+4) 2 "F - test-get-with-no-output: exit status")
10749 # don't restore from ebp
10750 81 0/subop/add %esp 8/imm32
10755 test-get-with-too-many-outputs:
10758 89/<- %ebp 4/r32/esp
10760 (clear-stream _test-input-stream)
10761 (clear-stream $_test-input-buffered-file->buffer)
10762 (clear-stream _test-output-stream)
10763 (clear-stream $_test-output-buffered-file->buffer)
10764 (clear-stream _test-error-stream)
10765 (clear-stream $_test-error-buffered-file->buffer)
10766 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
10769 89/<- %edx 4/r32/esp
10770 (tailor-exit-descriptor %edx 0x10)
10772 (write _test-input-stream "fn foo {\n")
10773 (write _test-input-stream " var a: t\n")
10774 (write _test-input-stream " var b: int\n")
10775 (write _test-input-stream " var c/eax: (addr int) <- copy 0\n")
10776 (write _test-input-stream " c, b <- get a, x\n")
10777 (write _test-input-stream "}\n")
10778 (write _test-input-stream "type t {\n")
10779 (write _test-input-stream " x: int\n")
10780 (write _test-input-stream "}\n")
10782 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
10783 # registers except esp clobbered at this point
10785 89/<- %edx 4/r32/esp
10786 (flush _test-output-buffered-file)
10787 (flush _test-error-buffered-file)
10788 #? # dump _test-error-stream {{{
10790 #? (write-stream 2 _test-error-stream)
10792 #? (rewind-stream _test-error-stream)
10795 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-outputs: output should be empty")
10796 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: too many outputs (1 required)" "F - test-get-with-too-many-outputs: error message")
10797 # check that stop(1) was called
10798 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-outputs: exit status")
10799 # don't restore from ebp
10800 81 0/subop/add %esp 8/imm32
10805 test-convert-array-of-user-defined-types:
10808 89/<- %ebp 4/r32/esp
10810 (clear-stream _test-input-stream)
10811 (clear-stream $_test-input-buffered-file->buffer)
10812 (clear-stream _test-output-stream)
10813 (clear-stream $_test-output-buffered-file->buffer)
10815 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2
10816 (write _test-input-stream " x: int\n")
10817 (write _test-input-stream " y: int\n")
10818 (write _test-input-stream "}\n")
10819 (write _test-input-stream "fn foo {\n")
10820 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n")
10821 (write _test-input-stream " var idx/ecx: int <- copy 3\n")
10822 (write _test-input-stream " var x/eax: (addr t) <- index arr, idx\n")
10823 (write _test-input-stream "}\n")
10825 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
10826 (flush _test-output-buffered-file)
10827 #? # dump _test-output-stream {{{
10829 #? (write-stream 2 _test-output-stream)
10831 #? (rewind-stream _test-output-stream)
10834 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-array-of-user-defined-types/0")
10835 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-array-of-user-defined-types/1")
10836 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-array-of-user-defined-types/2")
10837 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-array-of-user-defined-types/3")
10838 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-array-of-user-defined-types/4")
10839 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-array-of-user-defined-types/5")
10840 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-array-of-user-defined-types/6")
10841 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-array-of-user-defined-types/7")
10842 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-array-of-user-defined-types/8")
10843 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-array-of-user-defined-types/9")
10844 (check-next-stream-line-equal _test-output-stream " (__check-mu-array-bounds %ecx 0x00000008 *eax \"foo\" \"arr\")" "F - test-convert-array-of-user-defined-types/10")
10845 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %eax 0/imm32" "F - test-convert-array-of-user-defined-types/12")
10846 (check-next-stream-line-equal _test-output-stream " 0f 84/jump-if-= __mu-abort-null-index-base-address/disp32" "F - test-convert-array-of-user-defined-types/13")
10847 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000003 + 4) 0x00000000/r32" "F - test-convert-array-of-user-defined-types/14")
10848 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-array-of-user-defined-types/15")
10849 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-array-of-user-defined-types/16")
10850 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-array-of-user-defined-types/17")
10851 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-array-of-user-defined-types/18")
10852 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-array-of-user-defined-types/19")
10853 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-array-of-user-defined-types/20")
10854 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-array-of-user-defined-types/21")
10855 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-array-of-user-defined-types/22")
10857 89/<- %esp 5/r32/ebp
10861 test-convert-length-of-array-of-user-defined-types-to-eax:
10864 89/<- %ebp 4/r32/esp
10866 (clear-stream _test-input-stream)
10867 (clear-stream $_test-input-buffered-file->buffer)
10868 (clear-stream _test-output-stream)
10869 (clear-stream $_test-output-buffered-file->buffer)
10871 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2
10872 (write _test-input-stream " x: int\n")
10873 (write _test-input-stream " y: int\n")
10874 (write _test-input-stream " z: int\n")
10875 (write _test-input-stream "}\n")
10876 (write _test-input-stream "fn foo {\n")
10877 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n")
10878 (write _test-input-stream " var x/eax: int <- length arr\n")
10879 (write _test-input-stream "}\n")
10881 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
10882 (flush _test-output-buffered-file)
10883 #? # dump _test-output-stream {{{
10885 #? (write-stream 2 _test-output-stream)
10887 #? (rewind-stream _test-output-stream)
10890 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/0")
10891 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/1")
10892 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/2")
10893 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/3")
10894 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-eax/4")
10895 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/5")
10897 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/6")
10898 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/7")
10899 # length instruction
10900 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/8")
10901 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/9")
10902 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/10")
10903 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/11")
10904 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-eax/12")
10905 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/13")
10906 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/14")
10907 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/15")
10909 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-eax/16")
10911 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-eax/17")
10912 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/18")
10913 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/19")
10914 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/20")
10915 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/21")
10916 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-eax/22")
10918 89/<- %esp 5/r32/ebp
10922 test-convert-length-of-array-of-user-defined-types-to-ecx:
10925 89/<- %ebp 4/r32/esp
10927 (clear-stream _test-input-stream)
10928 (clear-stream $_test-input-buffered-file->buffer)
10929 (clear-stream _test-output-stream)
10930 (clear-stream $_test-output-buffered-file->buffer)
10932 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2
10933 (write _test-input-stream " x: int\n")
10934 (write _test-input-stream " y: int\n")
10935 (write _test-input-stream " z: int\n")
10936 (write _test-input-stream "}\n")
10937 (write _test-input-stream "fn foo {\n")
10938 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n")
10939 (write _test-input-stream " var x/ecx: int <- length arr\n")
10940 (write _test-input-stream "}\n")
10942 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
10943 (flush _test-output-buffered-file)
10944 #? # dump _test-output-stream {{{
10946 #? (write-stream 2 _test-output-stream)
10948 #? (rewind-stream _test-output-stream)
10951 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/0")
10952 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/1")
10953 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/2")
10954 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/3")
10955 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/4")
10956 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/5")
10958 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/6")
10959 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/7")
10961 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/8")
10962 # length instruction
10963 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/9")
10964 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/10")
10965 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/11")
10966 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/12")
10967 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/13")
10968 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/14")
10969 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/15")
10970 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/16")
10971 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/17")
10973 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/18")
10975 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/19")
10977 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/20")
10978 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/21")
10979 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/22")
10980 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/23")
10981 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/24")
10982 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/25")
10984 89/<- %esp 5/r32/ebp
10988 test-convert-length-of-array-of-user-defined-types-to-edx:
10991 89/<- %ebp 4/r32/esp
10993 (clear-stream _test-input-stream)
10994 (clear-stream $_test-input-buffered-file->buffer)
10995 (clear-stream _test-output-stream)
10996 (clear-stream $_test-output-buffered-file->buffer)
10998 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2
10999 (write _test-input-stream " x: int\n")
11000 (write _test-input-stream " y: int\n")
11001 (write _test-input-stream " z: int\n")
11002 (write _test-input-stream "}\n")
11003 (write _test-input-stream "fn foo {\n")
11004 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n")
11005 (write _test-input-stream " var x/edx: int <- length arr\n")
11006 (write _test-input-stream "}\n")
11008 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
11009 (flush _test-output-buffered-file)
11010 #? # dump _test-output-stream {{{
11012 #? (write-stream 2 _test-output-stream)
11014 #? (rewind-stream _test-output-stream)
11017 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/0")
11018 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/1")
11019 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/2")
11020 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/3")
11021 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-edx/4")
11022 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/5")
11024 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/6")
11025 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/7")
11027 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/8")
11028 # length instruction
11029 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/9")
11030 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/10")
11031 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/11")
11032 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/12")
11033 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types-to-edx/13")
11034 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/14")
11035 (check-next-stream-line-equal _test-output-stream " 89/<- %edx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/15")
11036 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/16")
11037 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/17")
11039 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/18")
11041 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/19")
11043 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-edx/20")
11044 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/21")
11045 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/22")
11046 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/23")
11047 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/24")
11048 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-edx/25")
11050 89/<- %esp 5/r32/ebp
11054 test-convert-length-of-array-of-user-defined-types:
11057 89/<- %ebp 4/r32/esp
11059 (clear-stream _test-input-stream)
11060 (clear-stream $_test-input-buffered-file->buffer)
11061 (clear-stream _test-output-stream)
11062 (clear-stream $_test-output-buffered-file->buffer)
11064 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2
11065 (write _test-input-stream " x: int\n")
11066 (write _test-input-stream " y: int\n")
11067 (write _test-input-stream " z: int\n")
11068 (write _test-input-stream "}\n")
11069 (write _test-input-stream "fn foo {\n")
11070 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n")
11071 (write _test-input-stream " var x/ebx: int <- length arr\n")
11072 (write _test-input-stream "}\n")
11074 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
11075 (flush _test-output-buffered-file)
11076 #? # dump _test-output-stream {{{
11078 #? (write-stream 2 _test-output-stream)
11080 #? (rewind-stream _test-output-stream)
11083 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types/0")
11084 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types/1")
11085 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types/2")
11086 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types/3")
11087 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types/4")
11088 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types/5")
11089 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types/6")
11090 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-length-of-array-of-user-defined-types/7")
11091 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-length-of-array-of-user-defined-types/8")
11092 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types/9")
11093 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types/10")
11094 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types/11")
11095 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types/12")
11096 (check-next-stream-line-equal _test-output-stream " 31/xor %edx 2/r32/edx" "F - test-convert-length-of-array-of-user-defined-types/13")
11097 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x0000000c/imm32" "F - test-convert-length-of-array-of-user-defined-types/14")
11098 (check-next-stream-line-equal _test-output-stream " f7 7/subop/idiv-eax-edx-by %ecx" "F - test-convert-length-of-array-of-user-defined-types/15")
11099 (check-next-stream-line-equal _test-output-stream " 89/<- %ebx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types/16")
11100 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types/17")
11101 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types/18")
11102 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types/19")
11103 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ebx" "F - test-convert-length-of-array-of-user-defined-types/20")
11104 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types/21")
11105 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types/22")
11106 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types/23")
11107 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types/24")
11108 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types/25")
11109 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types/26")
11110 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types/27")
11112 89/<- %esp 5/r32/ebp
11116 test-index-with-non-array-atom-base-type:
11119 89/<- %ebp 4/r32/esp
11121 (clear-stream _test-input-stream)
11122 (clear-stream $_test-input-buffered-file->buffer)
11123 (clear-stream _test-output-stream)
11124 (clear-stream $_test-output-buffered-file->buffer)
11125 (clear-stream _test-error-stream)
11126 (clear-stream $_test-error-buffered-file->buffer)
11127 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11130 89/<- %edx 4/r32/esp
11131 (tailor-exit-descriptor %edx 0x10)
11133 (write _test-input-stream "fn foo {\n")
11134 (write _test-input-stream " var a: int\n")
11135 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n")
11136 (write _test-input-stream "}\n")
11138 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11139 # registers except esp clobbered at this point
11141 89/<- %edx 4/r32/esp
11142 (flush _test-output-buffered-file)
11143 (flush _test-error-buffered-file)
11144 #? # dump _test-error-stream {{{
11146 #? (write-stream 2 _test-error-stream)
11148 #? (rewind-stream _test-error-stream)
11151 (check-stream-equal _test-output-stream "" "F - test-index-with-non-array-atom-base-type: output should be empty")
11152 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is not an array" "F - test-index-with-non-array-atom-base-type: error message")
11153 # check that stop(1) was called
11154 (check-ints-equal *(edx+4) 2 "F - test-index-with-non-array-atom-base-type: exit status")
11155 # don't restore from ebp
11156 81 0/subop/add %esp 8/imm32
11161 test-index-with-non-array-compound-base-type:
11164 89/<- %ebp 4/r32/esp
11166 (clear-stream _test-input-stream)
11167 (clear-stream $_test-input-buffered-file->buffer)
11168 (clear-stream _test-output-stream)
11169 (clear-stream $_test-output-buffered-file->buffer)
11170 (clear-stream _test-error-stream)
11171 (clear-stream $_test-error-buffered-file->buffer)
11172 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11175 89/<- %edx 4/r32/esp
11176 (tailor-exit-descriptor %edx 0x10)
11178 (write _test-input-stream "fn foo {\n")
11179 (write _test-input-stream " var a: (handle int)\n")
11180 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n")
11181 (write _test-input-stream "}\n")
11183 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11184 # registers except esp clobbered at this point
11186 89/<- %edx 4/r32/esp
11187 (flush _test-output-buffered-file)
11188 (flush _test-error-buffered-file)
11189 #? # dump _test-error-stream {{{
11191 #? (write-stream 2 _test-error-stream)
11193 #? (rewind-stream _test-error-stream)
11196 (check-stream-equal _test-output-stream "" "F - test-index-with-non-array-compound-base-type: output should be empty")
11197 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is not an array" "F - test-index-with-non-array-compound-base-type: error message")
11198 # check that stop(1) was called
11199 (check-ints-equal *(edx+4) 2 "F - test-index-with-non-array-compound-base-type: exit status")
11200 # don't restore from ebp
11201 81 0/subop/add %esp 8/imm32
11206 test-index-with-non-array-compound-base-type-2:
11209 89/<- %ebp 4/r32/esp
11211 (clear-stream _test-input-stream)
11212 (clear-stream $_test-input-buffered-file->buffer)
11213 (clear-stream _test-output-stream)
11214 (clear-stream $_test-output-buffered-file->buffer)
11215 (clear-stream _test-error-stream)
11216 (clear-stream $_test-error-buffered-file->buffer)
11217 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11220 89/<- %edx 4/r32/esp
11221 (tailor-exit-descriptor %edx 0x10)
11223 (write _test-input-stream "fn foo {\n")
11224 (write _test-input-stream " var a: (addr int)\n")
11225 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n")
11226 (write _test-input-stream "}\n")
11228 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11229 # registers except esp clobbered at this point
11231 89/<- %edx 4/r32/esp
11232 (flush _test-output-buffered-file)
11233 (flush _test-error-buffered-file)
11234 #? # dump _test-error-stream {{{
11236 #? (write-stream 2 _test-error-stream)
11238 #? (rewind-stream _test-error-stream)
11241 (check-stream-equal _test-output-stream "" "F - test-index-with-non-array-compound-base-type-2: output should be empty")
11242 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is not an array" "F - test-index-with-non-array-compound-base-type-2: error message")
11243 # check that stop(1) was called
11244 (check-ints-equal *(edx+4) 2 "F - test-index-with-non-array-compound-base-type-2: exit status")
11245 # don't restore from ebp
11246 81 0/subop/add %esp 8/imm32
11251 test-index-with-array-atom-base-type:
11254 89/<- %ebp 4/r32/esp
11256 (clear-stream _test-input-stream)
11257 (clear-stream $_test-input-buffered-file->buffer)
11258 (clear-stream _test-output-stream)
11259 (clear-stream $_test-output-buffered-file->buffer)
11260 (clear-stream _test-error-stream)
11261 (clear-stream $_test-error-buffered-file->buffer)
11262 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11265 89/<- %edx 4/r32/esp
11266 (tailor-exit-descriptor %edx 0x10)
11268 (write _test-input-stream "fn foo {\n")
11269 (write _test-input-stream " var a: array\n")
11270 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n")
11271 (write _test-input-stream "}\n")
11273 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11274 # registers except esp clobbered at this point
11276 89/<- %edx 4/r32/esp
11277 (flush _test-output-buffered-file)
11278 (flush _test-error-buffered-file)
11279 #? # dump _test-error-stream {{{
11281 #? (write-stream 2 _test-error-stream)
11283 #? (rewind-stream _test-error-stream)
11286 (check-stream-equal _test-output-stream "" "F - test-index-with-array-atom-base-type: output should be empty")
11287 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: array 'a' must specify the type of its elements" "F - test-index-with-array-atom-base-type: error message")
11288 # check that stop(1) was called
11289 (check-ints-equal *(edx+4) 2 "F - test-index-with-array-atom-base-type: exit status")
11290 # don't restore from ebp
11291 81 0/subop/add %esp 8/imm32
11296 test-index-with-addr-base-on-stack:
11299 89/<- %ebp 4/r32/esp
11301 (clear-stream _test-input-stream)
11302 (clear-stream $_test-input-buffered-file->buffer)
11303 (clear-stream _test-output-stream)
11304 (clear-stream $_test-output-buffered-file->buffer)
11305 (clear-stream _test-error-stream)
11306 (clear-stream $_test-error-buffered-file->buffer)
11307 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11310 89/<- %edx 4/r32/esp
11311 (tailor-exit-descriptor %edx 0x10)
11313 (write _test-input-stream "fn foo {\n")
11314 (write _test-input-stream " var a: (addr array int)\n")
11315 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0\n")
11316 (write _test-input-stream "}\n")
11318 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11319 # registers except esp clobbered at this point
11321 89/<- %edx 4/r32/esp
11322 (flush _test-output-buffered-file)
11323 (flush _test-error-buffered-file)
11324 #? # dump _test-error-stream {{{
11326 #? (write-stream 2 _test-error-stream)
11328 #? (rewind-stream _test-error-stream)
11331 (check-stream-equal _test-output-stream "" "F - test-index-with-addr-base-on-stack: output should be empty")
11332 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: var 'a' is an addr to an array, and so must live in a register" "F - test-index-with-addr-base-on-stack: error message")
11333 # check that stop(1) was called
11334 (check-ints-equal *(edx+4) 2 "F - test-index-with-addr-base-on-stack: exit status")
11335 # don't restore from ebp
11336 81 0/subop/add %esp 8/imm32
11341 test-index-with-wrong-index-type:
11344 89/<- %ebp 4/r32/esp
11346 (clear-stream _test-input-stream)
11347 (clear-stream $_test-input-buffered-file->buffer)
11348 (clear-stream _test-output-stream)
11349 (clear-stream $_test-output-buffered-file->buffer)
11350 (clear-stream _test-error-stream)
11351 (clear-stream $_test-error-buffered-file->buffer)
11352 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11355 89/<- %edx 4/r32/esp
11356 (tailor-exit-descriptor %edx 0x10)
11358 (write _test-input-stream "fn foo {\n")
11359 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n")
11360 (write _test-input-stream " var b: boolean\n")
11361 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n")
11362 (write _test-input-stream "}\n")
11364 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11365 # registers except esp clobbered at this point
11367 89/<- %edx 4/r32/esp
11368 (flush _test-output-buffered-file)
11369 (flush _test-error-buffered-file)
11370 #? # dump _test-error-stream {{{
11372 #? (write-stream 2 _test-error-stream)
11374 #? (rewind-stream _test-error-stream)
11377 (check-stream-equal _test-output-stream "" "F - test-index-with-wrong-index-type: output should be empty")
11378 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: second argument 'b' must be an int or offset" "F - test-index-with-wrong-index-type: error message")
11379 # check that stop(1) was called
11380 (check-ints-equal *(edx+4) 2 "F - test-index-with-wrong-index-type: exit status")
11381 # don't restore from ebp
11382 81 0/subop/add %esp 8/imm32
11387 test-index-with-offset-atom-index-type:
11390 89/<- %ebp 4/r32/esp
11392 (clear-stream _test-input-stream)
11393 (clear-stream $_test-input-buffered-file->buffer)
11394 (clear-stream _test-output-stream)
11395 (clear-stream $_test-output-buffered-file->buffer)
11396 (clear-stream _test-error-stream)
11397 (clear-stream $_test-error-buffered-file->buffer)
11398 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11401 89/<- %edx 4/r32/esp
11402 (tailor-exit-descriptor %edx 0x10)
11404 (write _test-input-stream "fn foo {\n")
11405 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n")
11406 (write _test-input-stream " var b: offset\n")
11407 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n")
11408 (write _test-input-stream "}\n")
11410 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11411 # registers except esp clobbered at this point
11413 89/<- %edx 4/r32/esp
11414 (flush _test-output-buffered-file)
11415 (flush _test-error-buffered-file)
11416 #? # dump _test-error-stream {{{
11418 #? (write-stream 2 _test-error-stream)
11420 #? (rewind-stream _test-error-stream)
11423 (check-stream-equal _test-output-stream "" "F - test-index-with-offset-atom-index-type: output should be empty")
11424 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: offset 'b' must specify the type of array elements" "F - test-index-with-offset-atom-index-type: error message")
11425 # check that stop(1) was called
11426 (check-ints-equal *(edx+4) 2 "F - test-index-with-offset-atom-index-type: exit status")
11427 # don't restore from ebp
11428 81 0/subop/add %esp 8/imm32
11433 test-index-with-offset-on-stack:
11436 89/<- %ebp 4/r32/esp
11438 (clear-stream _test-input-stream)
11439 (clear-stream $_test-input-buffered-file->buffer)
11440 (clear-stream _test-output-stream)
11441 (clear-stream $_test-output-buffered-file->buffer)
11442 (clear-stream _test-error-stream)
11443 (clear-stream $_test-error-buffered-file->buffer)
11444 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11447 89/<- %edx 4/r32/esp
11448 (tailor-exit-descriptor %edx 0x10)
11450 (write _test-input-stream "fn foo {\n")
11451 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n")
11452 (write _test-input-stream " var b: int\n")
11453 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n")
11454 (write _test-input-stream "}\n")
11456 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11457 # registers except esp clobbered at this point
11459 89/<- %edx 4/r32/esp
11460 (flush _test-output-buffered-file)
11461 (flush _test-error-buffered-file)
11462 #? # dump _test-error-stream {{{
11464 #? (write-stream 2 _test-error-stream)
11466 #? (rewind-stream _test-error-stream)
11469 (check-stream-equal _test-output-stream "" "F - test-index-with-offset-on-stack: output should be empty")
11470 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: second argument 'b' must be in a register" "F - test-index-with-offset-on-stack: error message")
11471 # check that stop(1) was called
11472 (check-ints-equal *(edx+4) 2 "F - test-index-with-offset-on-stack: exit status")
11473 # don't restore from ebp
11474 81 0/subop/add %esp 8/imm32
11479 test-index-needs-offset-type:
11482 89/<- %ebp 4/r32/esp
11484 (clear-stream _test-input-stream)
11485 (clear-stream $_test-input-buffered-file->buffer)
11486 (clear-stream _test-output-stream)
11487 (clear-stream $_test-output-buffered-file->buffer)
11488 (clear-stream _test-error-stream)
11489 (clear-stream $_test-error-buffered-file->buffer)
11490 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11493 89/<- %edx 4/r32/esp
11494 (tailor-exit-descriptor %edx 0x10)
11496 (write _test-input-stream "fn foo {\n")
11497 (write _test-input-stream " var a/eax: (addr array t) <- copy 0\n")
11498 (write _test-input-stream " var b/ebx: int <- copy 0\n")
11499 (write _test-input-stream " var c/ecx: (addr int) <- index a, b\n")
11500 (write _test-input-stream "}\n")
11501 (write _test-input-stream "type t {\n") # size 12 is not a power of two
11502 (write _test-input-stream " x: int\n")
11503 (write _test-input-stream " y: int\n")
11504 (write _test-input-stream " z: int\n")
11505 (write _test-input-stream "}\n")
11507 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11508 # registers except esp clobbered at this point
11510 89/<- %edx 4/r32/esp
11511 (flush _test-output-buffered-file)
11512 (flush _test-error-buffered-file)
11513 #? # dump _test-error-stream {{{
11515 #? (write-stream 2 _test-error-stream)
11517 #? (rewind-stream _test-error-stream)
11520 (check-stream-equal _test-output-stream "" "F - test-index-needs-offset-type: output should be empty")
11521 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: cannot take an int for array 'a'; create an offset instead. See mu.md for details." "F - test-index-needs-offset-type: error message")
11522 # check that stop(1) was called
11523 (check-ints-equal *(edx+4) 2 "F - test-index-needs-offset-type: exit status")
11524 # don't restore from ebp
11525 81 0/subop/add %esp 8/imm32
11530 test-index-with-output-not-address:
11533 89/<- %ebp 4/r32/esp
11535 (clear-stream _test-input-stream)
11536 (clear-stream $_test-input-buffered-file->buffer)
11537 (clear-stream _test-output-stream)
11538 (clear-stream $_test-output-buffered-file->buffer)
11539 (clear-stream _test-error-stream)
11540 (clear-stream $_test-error-buffered-file->buffer)
11541 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11544 89/<- %edx 4/r32/esp
11545 (tailor-exit-descriptor %edx 0x10)
11547 (write _test-input-stream "fn foo {\n")
11548 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n")
11549 (write _test-input-stream " var o/edi: int <- index a, 0\n")
11550 (write _test-input-stream "}\n")
11552 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11553 # registers except esp clobbered at this point
11555 89/<- %edx 4/r32/esp
11556 (flush _test-output-buffered-file)
11557 (flush _test-error-buffered-file)
11558 #? # dump _test-error-stream {{{
11560 #? (write-stream 2 _test-error-stream)
11562 #? (rewind-stream _test-error-stream)
11565 (check-stream-equal _test-output-stream "" "F - test-index-with-output-not-address: output should be empty")
11566 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' must be an addr" "F - test-index-with-output-not-address: error message")
11567 # check that stop(1) was called
11568 (check-ints-equal *(edx+4) 2 "F - test-index-with-output-not-address: exit status")
11569 # don't restore from ebp
11570 81 0/subop/add %esp 8/imm32
11575 test-index-with-output-not-address-2:
11578 89/<- %ebp 4/r32/esp
11580 (clear-stream _test-input-stream)
11581 (clear-stream $_test-input-buffered-file->buffer)
11582 (clear-stream _test-output-stream)
11583 (clear-stream $_test-output-buffered-file->buffer)
11584 (clear-stream _test-error-stream)
11585 (clear-stream $_test-error-buffered-file->buffer)
11586 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11589 89/<- %edx 4/r32/esp
11590 (tailor-exit-descriptor %edx 0x10)
11592 (write _test-input-stream "fn foo {\n")
11593 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n")
11594 (write _test-input-stream " var o/edi: (int) <- index a, 0\n")
11595 (write _test-input-stream "}\n")
11597 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11598 # registers except esp clobbered at this point
11600 89/<- %edx 4/r32/esp
11601 (flush _test-output-buffered-file)
11602 (flush _test-error-buffered-file)
11603 #? # dump _test-error-stream {{{
11605 #? (write-stream 2 _test-error-stream)
11607 #? (rewind-stream _test-error-stream)
11610 (check-stream-equal _test-output-stream "" "F - test-index-with-output-not-address-2: output should be empty")
11611 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' must be an addr" "F - test-index-with-output-not-address-2: error message")
11612 # check that stop(1) was called
11613 (check-ints-equal *(edx+4) 2 "F - test-index-with-output-not-address-2: exit status")
11614 # don't restore from ebp
11615 81 0/subop/add %esp 8/imm32
11620 test-index-with-wrong-output-type:
11623 89/<- %ebp 4/r32/esp
11625 (clear-stream _test-input-stream)
11626 (clear-stream $_test-input-buffered-file->buffer)
11627 (clear-stream _test-output-stream)
11628 (clear-stream $_test-output-buffered-file->buffer)
11629 (clear-stream _test-error-stream)
11630 (clear-stream $_test-error-buffered-file->buffer)
11631 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11634 89/<- %edx 4/r32/esp
11635 (tailor-exit-descriptor %edx 0x10)
11637 (write _test-input-stream "fn foo {\n")
11638 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n")
11639 (write _test-input-stream " var o/edi: (addr int) <- index a, 0\n")
11640 (write _test-input-stream "}\n")
11642 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11643 # registers except esp clobbered at this point
11645 89/<- %edx 4/r32/esp
11646 (flush _test-output-buffered-file)
11647 (flush _test-error-buffered-file)
11648 #? # dump _test-error-stream {{{
11650 #? (write-stream 2 _test-error-stream)
11652 #? (rewind-stream _test-error-stream)
11655 (check-stream-equal _test-output-stream "" "F - test-index-with-wrong-output-type: output should be empty")
11656 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' does not have the right type" "F - test-index-with-wrong-output-type: error message")
11657 # check that stop(1) was called
11658 (check-ints-equal *(edx+4) 2 "F - test-index-with-wrong-output-type: exit status")
11659 # don't restore from ebp
11660 81 0/subop/add %esp 8/imm32
11665 test-index-with-wrong-output-compound-type:
11668 89/<- %ebp 4/r32/esp
11670 (clear-stream _test-input-stream)
11671 (clear-stream $_test-input-buffered-file->buffer)
11672 (clear-stream _test-output-stream)
11673 (clear-stream $_test-output-buffered-file->buffer)
11674 (clear-stream _test-error-stream)
11675 (clear-stream $_test-error-buffered-file->buffer)
11676 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11679 89/<- %edx 4/r32/esp
11680 (tailor-exit-descriptor %edx 0x10)
11682 (write _test-input-stream "fn foo {\n")
11683 (write _test-input-stream " var a/ebx: (addr array handle boolean) <- copy 0\n")
11684 (write _test-input-stream " var o/edi: (addr handle int) <- index a, 0\n")
11685 (write _test-input-stream "}\n")
11687 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11688 # registers except esp clobbered at this point
11690 89/<- %edx 4/r32/esp
11691 (flush _test-output-buffered-file)
11692 (flush _test-error-buffered-file)
11693 #? # dump _test-error-stream {{{
11695 #? (write-stream 2 _test-error-stream)
11697 #? (rewind-stream _test-error-stream)
11700 (check-stream-equal _test-output-stream "" "F - test-index-with-wrong-output-compound-type: output should be empty")
11701 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: output 'o' does not have the right type" "F - test-index-with-wrong-output-compound-type: error message")
11702 # check that stop(1) was called
11703 (check-ints-equal *(edx+4) 2 "F - test-index-with-wrong-output-compound-type: exit status")
11704 # don't restore from ebp
11705 81 0/subop/add %esp 8/imm32
11710 test-index-with-no-inouts:
11713 89/<- %ebp 4/r32/esp
11715 (clear-stream _test-input-stream)
11716 (clear-stream $_test-input-buffered-file->buffer)
11717 (clear-stream _test-output-stream)
11718 (clear-stream $_test-output-buffered-file->buffer)
11719 (clear-stream _test-error-stream)
11720 (clear-stream $_test-error-buffered-file->buffer)
11721 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11724 89/<- %edx 4/r32/esp
11725 (tailor-exit-descriptor %edx 0x10)
11727 (write _test-input-stream "fn foo {\n")
11728 (write _test-input-stream " var c/ecx: (addr int) <- index\n")
11729 (write _test-input-stream "}\n")
11731 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11732 # registers except esp clobbered at this point
11734 89/<- %edx 4/r32/esp
11735 (flush _test-output-buffered-file)
11736 (flush _test-error-buffered-file)
11737 #? # dump _test-error-stream {{{
11739 #? (write-stream 2 _test-error-stream)
11741 #? (rewind-stream _test-error-stream)
11744 (check-stream-equal _test-output-stream "" "F - test-index-with-no-inouts: output should be empty")
11745 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too few inouts (2 required)" "F - test-index-with-no-inouts: error message")
11746 # check that stop(1) was called
11747 (check-ints-equal *(edx+4) 2 "F - test-index-with-no-inouts: exit status")
11748 # don't restore from ebp
11749 81 0/subop/add %esp 8/imm32
11754 test-index-with-too-few-inouts:
11757 89/<- %ebp 4/r32/esp
11759 (clear-stream _test-input-stream)
11760 (clear-stream $_test-input-buffered-file->buffer)
11761 (clear-stream _test-output-stream)
11762 (clear-stream $_test-output-buffered-file->buffer)
11763 (clear-stream _test-error-stream)
11764 (clear-stream $_test-error-buffered-file->buffer)
11765 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11768 89/<- %edx 4/r32/esp
11769 (tailor-exit-descriptor %edx 0x10)
11771 (write _test-input-stream "fn foo {\n")
11772 (write _test-input-stream " var a: (array int 3)\n")
11773 (write _test-input-stream " var c/ecx: (addr int) <- index a\n")
11774 (write _test-input-stream "}\n")
11776 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11777 # registers except esp clobbered at this point
11779 89/<- %edx 4/r32/esp
11780 (flush _test-output-buffered-file)
11781 (flush _test-error-buffered-file)
11782 #? # dump _test-error-stream {{{
11784 #? (write-stream 2 _test-error-stream)
11786 #? (rewind-stream _test-error-stream)
11789 (check-stream-equal _test-output-stream "" "F - test-index-with-too-few-inouts: output should be empty")
11790 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too few inouts (2 required)" "F - test-index-with-too-few-inouts: error message")
11791 # check that stop(1) was called
11792 (check-ints-equal *(edx+4) 2 "F - test-index-with-too-few-inouts: exit status")
11793 # don't restore from ebp
11794 81 0/subop/add %esp 8/imm32
11799 test-index-with-too-many-inouts:
11802 89/<- %ebp 4/r32/esp
11804 (clear-stream _test-input-stream)
11805 (clear-stream $_test-input-buffered-file->buffer)
11806 (clear-stream _test-output-stream)
11807 (clear-stream $_test-output-buffered-file->buffer)
11808 (clear-stream _test-error-stream)
11809 (clear-stream $_test-error-buffered-file->buffer)
11810 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11813 89/<- %edx 4/r32/esp
11814 (tailor-exit-descriptor %edx 0x10)
11816 (write _test-input-stream "fn foo {\n")
11817 (write _test-input-stream " var a: (array int 3)\n")
11818 (write _test-input-stream " var c/ecx: (addr int) <- index a, 0, 0\n")
11819 (write _test-input-stream "}\n")
11821 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11822 # registers except esp clobbered at this point
11824 89/<- %edx 4/r32/esp
11825 (flush _test-output-buffered-file)
11826 (flush _test-error-buffered-file)
11827 #? # dump _test-error-stream {{{
11829 #? (write-stream 2 _test-error-stream)
11831 #? (rewind-stream _test-error-stream)
11834 (check-stream-equal _test-output-stream "" "F - test-index-with-too-many-inouts: output should be empty")
11835 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too many inouts (2 required)" "F - test-index-with-too-many-inouts: error message")
11836 # check that stop(1) was called
11837 (check-ints-equal *(edx+4) 2 "F - test-index-with-too-many-inouts: exit status")
11838 # don't restore from ebp
11839 81 0/subop/add %esp 8/imm32
11844 test-index-with-no-output:
11847 89/<- %ebp 4/r32/esp
11849 (clear-stream _test-input-stream)
11850 (clear-stream $_test-input-buffered-file->buffer)
11851 (clear-stream _test-output-stream)
11852 (clear-stream $_test-output-buffered-file->buffer)
11853 (clear-stream _test-error-stream)
11854 (clear-stream $_test-error-buffered-file->buffer)
11855 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11858 89/<- %edx 4/r32/esp
11859 (tailor-exit-descriptor %edx 0x10)
11861 (write _test-input-stream "fn foo {\n")
11862 (write _test-input-stream " var a: (array int 3)\n")
11863 (write _test-input-stream " index a, 0\n")
11864 (write _test-input-stream "}\n")
11866 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11867 # registers except esp clobbered at this point
11869 89/<- %edx 4/r32/esp
11870 (flush _test-output-buffered-file)
11871 (flush _test-error-buffered-file)
11872 #? # dump _test-error-stream {{{
11874 #? (write-stream 2 _test-error-stream)
11876 #? (rewind-stream _test-error-stream)
11879 (check-stream-equal _test-output-stream "" "F - test-index-with-no-output: output should be empty")
11880 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: must have an output" "F - test-index-with-no-output: error message")
11881 # check that stop(1) was called
11882 (check-ints-equal *(edx+4) 2 "F - test-index-with-no-output: exit status")
11883 # don't restore from ebp
11884 81 0/subop/add %esp 8/imm32
11889 test-index-with-too-many-outputs:
11892 89/<- %ebp 4/r32/esp
11894 (clear-stream _test-input-stream)
11895 (clear-stream $_test-input-buffered-file->buffer)
11896 (clear-stream _test-output-stream)
11897 (clear-stream $_test-output-buffered-file->buffer)
11898 (clear-stream _test-error-stream)
11899 (clear-stream $_test-error-buffered-file->buffer)
11900 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11903 89/<- %edx 4/r32/esp
11904 (tailor-exit-descriptor %edx 0x10)
11906 (write _test-input-stream "fn foo {\n")
11907 (write _test-input-stream " var a: (array int 3)\n")
11908 (write _test-input-stream " var b/eax: (addr int) <- copy 0\n")
11909 (write _test-input-stream " var c/ecx: (addr int) <- copy 0\n")
11910 (write _test-input-stream " b, c <- index a, 0\n")
11911 (write _test-input-stream "}\n")
11913 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11914 # registers except esp clobbered at this point
11916 89/<- %edx 4/r32/esp
11917 (flush _test-output-buffered-file)
11918 (flush _test-error-buffered-file)
11919 #? # dump _test-error-stream {{{
11921 #? (write-stream 2 _test-error-stream)
11923 #? (rewind-stream _test-error-stream)
11926 (check-stream-equal _test-output-stream "" "F - test-index-with-too-many-outputs: output should be empty")
11927 (check-next-stream-line-equal _test-error-stream "fn foo: stmt index: too many outputs (1 required)" "F - test-index-with-too-many-outputs: error message")
11928 # check that stop(1) was called
11929 (check-ints-equal *(edx+4) 2 "F - test-index-with-too-many-outputs: exit status")
11930 # don't restore from ebp
11931 81 0/subop/add %esp 8/imm32
11936 test-compute-offset-with-non-array-atom-base-type:
11939 89/<- %ebp 4/r32/esp
11941 (clear-stream _test-input-stream)
11942 (clear-stream $_test-input-buffered-file->buffer)
11943 (clear-stream _test-output-stream)
11944 (clear-stream $_test-output-buffered-file->buffer)
11945 (clear-stream _test-error-stream)
11946 (clear-stream $_test-error-buffered-file->buffer)
11947 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11950 89/<- %edx 4/r32/esp
11951 (tailor-exit-descriptor %edx 0x10)
11953 (write _test-input-stream "fn foo {\n")
11954 (write _test-input-stream " var a: int\n")
11955 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0\n")
11956 (write _test-input-stream "}\n")
11958 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
11959 # registers except esp clobbered at this point
11961 89/<- %edx 4/r32/esp
11962 (flush _test-output-buffered-file)
11963 (flush _test-error-buffered-file)
11964 #? # dump _test-error-stream {{{
11966 #? (write-stream 2 _test-error-stream)
11968 #? (rewind-stream _test-error-stream)
11971 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-non-array-atom-base-type: output should be empty")
11972 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: var 'a' is not an array" "F - test-compute-offset-with-non-array-atom-base-type: error message")
11973 # check that stop(1) was called
11974 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-non-array-atom-base-type: exit status")
11975 # don't restore from ebp
11976 81 0/subop/add %esp 8/imm32
11981 test-compute-offset-with-non-array-compound-base-type:
11984 89/<- %ebp 4/r32/esp
11986 (clear-stream _test-input-stream)
11987 (clear-stream $_test-input-buffered-file->buffer)
11988 (clear-stream _test-output-stream)
11989 (clear-stream $_test-output-buffered-file->buffer)
11990 (clear-stream _test-error-stream)
11991 (clear-stream $_test-error-buffered-file->buffer)
11992 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
11995 89/<- %edx 4/r32/esp
11996 (tailor-exit-descriptor %edx 0x10)
11998 (write _test-input-stream "fn foo {\n")
11999 (write _test-input-stream " var a: (handle int)\n")
12000 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0\n")
12001 (write _test-input-stream "}\n")
12003 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12004 # registers except esp clobbered at this point
12006 89/<- %edx 4/r32/esp
12007 (flush _test-output-buffered-file)
12008 (flush _test-error-buffered-file)
12009 #? # dump _test-error-stream {{{
12011 #? (write-stream 2 _test-error-stream)
12013 #? (rewind-stream _test-error-stream)
12016 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-non-array-compound-base-type: output should be empty")
12017 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: var 'a' is not an array" "F - test-compute-offset-with-non-array-compound-base-type: error message")
12018 # check that stop(1) was called
12019 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-non-array-compound-base-type: exit status")
12020 # don't restore from ebp
12021 81 0/subop/add %esp 8/imm32
12026 test-compute-offset-with-non-array-compound-base-type-2:
12029 89/<- %ebp 4/r32/esp
12031 (clear-stream _test-input-stream)
12032 (clear-stream $_test-input-buffered-file->buffer)
12033 (clear-stream _test-output-stream)
12034 (clear-stream $_test-output-buffered-file->buffer)
12035 (clear-stream _test-error-stream)
12036 (clear-stream $_test-error-buffered-file->buffer)
12037 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12040 89/<- %edx 4/r32/esp
12041 (tailor-exit-descriptor %edx 0x10)
12043 (write _test-input-stream "fn foo {\n")
12044 (write _test-input-stream " var a: (addr int)\n")
12045 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0\n")
12046 (write _test-input-stream "}\n")
12048 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12049 # registers except esp clobbered at this point
12051 89/<- %edx 4/r32/esp
12052 (flush _test-output-buffered-file)
12053 (flush _test-error-buffered-file)
12054 #? # dump _test-error-stream {{{
12056 #? (write-stream 2 _test-error-stream)
12058 #? (rewind-stream _test-error-stream)
12061 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-non-array-compound-base-type-2: output should be empty")
12062 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: var 'a' is not an array" "F - test-compute-offset-with-non-array-compound-base-type-2: error message")
12063 # check that stop(1) was called
12064 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-non-array-compound-base-type-2: exit status")
12065 # don't restore from ebp
12066 81 0/subop/add %esp 8/imm32
12071 test-compute-offset-with-array-atom-base-type:
12074 89/<- %ebp 4/r32/esp
12076 (clear-stream _test-input-stream)
12077 (clear-stream $_test-input-buffered-file->buffer)
12078 (clear-stream _test-output-stream)
12079 (clear-stream $_test-output-buffered-file->buffer)
12080 (clear-stream _test-error-stream)
12081 (clear-stream $_test-error-buffered-file->buffer)
12082 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12085 89/<- %edx 4/r32/esp
12086 (tailor-exit-descriptor %edx 0x10)
12088 (write _test-input-stream "fn foo {\n")
12089 (write _test-input-stream " var a: array\n")
12090 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0\n")
12091 (write _test-input-stream "}\n")
12093 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12094 # registers except esp clobbered at this point
12096 89/<- %edx 4/r32/esp
12097 (flush _test-output-buffered-file)
12098 (flush _test-error-buffered-file)
12099 #? # dump _test-error-stream {{{
12101 #? (write-stream 2 _test-error-stream)
12103 #? (rewind-stream _test-error-stream)
12106 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-array-atom-base-type: output should be empty")
12107 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: array 'a' must specify the type of its elements" "F - test-compute-offset-with-array-atom-base-type: error message")
12108 # check that stop(1) was called
12109 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-array-atom-base-type: exit status")
12110 # don't restore from ebp
12111 81 0/subop/add %esp 8/imm32
12116 test-compute-offset-with-wrong-index-type:
12119 89/<- %ebp 4/r32/esp
12121 (clear-stream _test-input-stream)
12122 (clear-stream $_test-input-buffered-file->buffer)
12123 (clear-stream _test-output-stream)
12124 (clear-stream $_test-output-buffered-file->buffer)
12125 (clear-stream _test-error-stream)
12126 (clear-stream $_test-error-buffered-file->buffer)
12127 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12130 89/<- %edx 4/r32/esp
12131 (tailor-exit-descriptor %edx 0x10)
12133 (write _test-input-stream "fn foo {\n")
12134 (write _test-input-stream " var a/eax: (addr array int) <- copy 0\n")
12135 (write _test-input-stream " var b: boolean\n")
12136 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, b\n")
12137 (write _test-input-stream "}\n")
12139 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12140 # registers except esp clobbered at this point
12142 89/<- %edx 4/r32/esp
12143 (flush _test-output-buffered-file)
12144 (flush _test-error-buffered-file)
12145 #? # dump _test-error-stream {{{
12147 #? (write-stream 2 _test-error-stream)
12149 #? (rewind-stream _test-error-stream)
12152 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-wrong-index-type: output should be empty")
12153 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: second argument 'b' must be an int" "F - test-compute-offset-with-wrong-index-type: error message")
12154 # check that stop(1) was called
12155 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-wrong-index-type: exit status")
12156 # don't restore from ebp
12157 81 0/subop/add %esp 8/imm32
12162 test-compute-offset-with-output-not-offset:
12165 89/<- %ebp 4/r32/esp
12167 (clear-stream _test-input-stream)
12168 (clear-stream $_test-input-buffered-file->buffer)
12169 (clear-stream _test-output-stream)
12170 (clear-stream $_test-output-buffered-file->buffer)
12171 (clear-stream _test-error-stream)
12172 (clear-stream $_test-error-buffered-file->buffer)
12173 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12176 89/<- %edx 4/r32/esp
12177 (tailor-exit-descriptor %edx 0x10)
12179 (write _test-input-stream "fn foo {\n")
12180 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n")
12181 (write _test-input-stream " var o/edi: int <- compute-offset a, 0\n")
12182 (write _test-input-stream "}\n")
12184 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12185 # registers except esp clobbered at this point
12187 89/<- %edx 4/r32/esp
12188 (flush _test-output-buffered-file)
12189 (flush _test-error-buffered-file)
12190 #? # dump _test-error-stream {{{
12192 #? (write-stream 2 _test-error-stream)
12194 #? (rewind-stream _test-error-stream)
12197 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-output-not-offset: output should be empty")
12198 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: output 'o' must be an offset" "F - test-compute-offset-with-output-not-offset: error message")
12199 # check that stop(1) was called
12200 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-output-not-offset: exit status")
12201 # don't restore from ebp
12202 81 0/subop/add %esp 8/imm32
12207 test-compute-offset-with-output-not-address-2:
12210 89/<- %ebp 4/r32/esp
12212 (clear-stream _test-input-stream)
12213 (clear-stream $_test-input-buffered-file->buffer)
12214 (clear-stream _test-output-stream)
12215 (clear-stream $_test-output-buffered-file->buffer)
12216 (clear-stream _test-error-stream)
12217 (clear-stream $_test-error-buffered-file->buffer)
12218 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12221 89/<- %edx 4/r32/esp
12222 (tailor-exit-descriptor %edx 0x10)
12224 (write _test-input-stream "fn foo {\n")
12225 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n")
12226 (write _test-input-stream " var o/edi: (int) <- compute-offset a, 0\n")
12227 (write _test-input-stream "}\n")
12229 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12230 # registers except esp clobbered at this point
12232 89/<- %edx 4/r32/esp
12233 (flush _test-output-buffered-file)
12234 (flush _test-error-buffered-file)
12235 #? # dump _test-error-stream {{{
12237 #? (write-stream 2 _test-error-stream)
12239 #? (rewind-stream _test-error-stream)
12242 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-output-not-address-2: output should be empty")
12243 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: output 'o' must be an offset" "F - test-compute-offset-with-output-not-address-2: error message")
12244 # check that stop(1) was called
12245 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-output-not-address-2: exit status")
12246 # don't restore from ebp
12247 81 0/subop/add %esp 8/imm32
12252 test-compute-offset-with-wrong-output-type:
12255 89/<- %ebp 4/r32/esp
12257 (clear-stream _test-input-stream)
12258 (clear-stream $_test-input-buffered-file->buffer)
12259 (clear-stream _test-output-stream)
12260 (clear-stream $_test-output-buffered-file->buffer)
12261 (clear-stream _test-error-stream)
12262 (clear-stream $_test-error-buffered-file->buffer)
12263 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12266 89/<- %edx 4/r32/esp
12267 (tailor-exit-descriptor %edx 0x10)
12269 (write _test-input-stream "fn foo {\n")
12270 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n")
12271 (write _test-input-stream " var o/edi: (offset int) <- compute-offset a, 0\n")
12272 (write _test-input-stream "}\n")
12274 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12275 # registers except esp clobbered at this point
12277 89/<- %edx 4/r32/esp
12278 (flush _test-output-buffered-file)
12279 (flush _test-error-buffered-file)
12280 #? # dump _test-error-stream {{{
12282 #? (write-stream 2 _test-error-stream)
12284 #? (rewind-stream _test-error-stream)
12287 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-wrong-output-type: output should be empty")
12288 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: output 'o' does not have the right type" "F - test-compute-offset-with-wrong-output-type: error message")
12289 # check that stop(1) was called
12290 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-wrong-output-type: exit status")
12291 # don't restore from ebp
12292 81 0/subop/add %esp 8/imm32
12297 test-compute-offset-with-wrong-output-compound-type:
12300 89/<- %ebp 4/r32/esp
12302 (clear-stream _test-input-stream)
12303 (clear-stream $_test-input-buffered-file->buffer)
12304 (clear-stream _test-output-stream)
12305 (clear-stream $_test-output-buffered-file->buffer)
12306 (clear-stream _test-error-stream)
12307 (clear-stream $_test-error-buffered-file->buffer)
12308 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12311 89/<- %edx 4/r32/esp
12312 (tailor-exit-descriptor %edx 0x10)
12314 (write _test-input-stream "fn foo {\n")
12315 (write _test-input-stream " var a/ebx: (addr array handle boolean) <- copy 0\n")
12316 (write _test-input-stream " var o/edi: (offset handle int) <- compute-offset a, 0\n")
12317 (write _test-input-stream "}\n")
12319 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12320 # registers except esp clobbered at this point
12322 89/<- %edx 4/r32/esp
12323 (flush _test-output-buffered-file)
12324 (flush _test-error-buffered-file)
12325 #? # dump _test-error-stream {{{
12327 #? (write-stream 2 _test-error-stream)
12329 #? (rewind-stream _test-error-stream)
12332 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-wrong-output-compound-type: output should be empty")
12333 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: output 'o' does not have the right type" "F - test-compute-offset-with-wrong-output-compound-type: error message")
12334 # check that stop(1) was called
12335 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-wrong-output-compound-type: exit status")
12336 # don't restore from ebp
12337 81 0/subop/add %esp 8/imm32
12342 test-compute-offset-with-no-inouts:
12345 89/<- %ebp 4/r32/esp
12347 (clear-stream _test-input-stream)
12348 (clear-stream $_test-input-buffered-file->buffer)
12349 (clear-stream _test-output-stream)
12350 (clear-stream $_test-output-buffered-file->buffer)
12351 (clear-stream _test-error-stream)
12352 (clear-stream $_test-error-buffered-file->buffer)
12353 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12356 89/<- %edx 4/r32/esp
12357 (tailor-exit-descriptor %edx 0x10)
12359 (write _test-input-stream "fn foo {\n")
12360 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset\n")
12361 (write _test-input-stream "}\n")
12363 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12364 # registers except esp clobbered at this point
12366 89/<- %edx 4/r32/esp
12367 (flush _test-output-buffered-file)
12368 (flush _test-error-buffered-file)
12369 #? # dump _test-error-stream {{{
12371 #? (write-stream 2 _test-error-stream)
12373 #? (rewind-stream _test-error-stream)
12376 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-no-inouts: output should be empty")
12377 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: too few inouts (2 required)" "F - test-compute-offset-with-no-inouts: error message")
12378 # check that stop(1) was called
12379 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-no-inouts: exit status")
12380 # don't restore from ebp
12381 81 0/subop/add %esp 8/imm32
12386 test-compute-offset-with-too-few-inouts:
12389 89/<- %ebp 4/r32/esp
12391 (clear-stream _test-input-stream)
12392 (clear-stream $_test-input-buffered-file->buffer)
12393 (clear-stream _test-output-stream)
12394 (clear-stream $_test-output-buffered-file->buffer)
12395 (clear-stream _test-error-stream)
12396 (clear-stream $_test-error-buffered-file->buffer)
12397 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12400 89/<- %edx 4/r32/esp
12401 (tailor-exit-descriptor %edx 0x10)
12403 (write _test-input-stream "fn foo {\n")
12404 (write _test-input-stream " var a: (array int 3)\n")
12405 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a\n")
12406 (write _test-input-stream "}\n")
12408 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12409 # registers except esp clobbered at this point
12411 89/<- %edx 4/r32/esp
12412 (flush _test-output-buffered-file)
12413 (flush _test-error-buffered-file)
12414 #? # dump _test-error-stream {{{
12416 #? (write-stream 2 _test-error-stream)
12418 #? (rewind-stream _test-error-stream)
12421 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-too-few-inouts: output should be empty")
12422 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: too few inouts (2 required)" "F - test-compute-offset-with-too-few-inouts: error message")
12423 # check that stop(1) was called
12424 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-too-few-inouts: exit status")
12425 # don't restore from ebp
12426 81 0/subop/add %esp 8/imm32
12431 test-compute-offset-with-too-many-inouts:
12434 89/<- %ebp 4/r32/esp
12436 (clear-stream _test-input-stream)
12437 (clear-stream $_test-input-buffered-file->buffer)
12438 (clear-stream _test-output-stream)
12439 (clear-stream $_test-output-buffered-file->buffer)
12440 (clear-stream _test-error-stream)
12441 (clear-stream $_test-error-buffered-file->buffer)
12442 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12445 89/<- %edx 4/r32/esp
12446 (tailor-exit-descriptor %edx 0x10)
12448 (write _test-input-stream "fn foo {\n")
12449 (write _test-input-stream " var a: (array int 3)\n")
12450 (write _test-input-stream " var c/ecx: (offset int) <- compute-offset a, 0, 0\n")
12451 (write _test-input-stream "}\n")
12453 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12454 # registers except esp clobbered at this point
12456 89/<- %edx 4/r32/esp
12457 (flush _test-output-buffered-file)
12458 (flush _test-error-buffered-file)
12459 #? # dump _test-error-stream {{{
12461 #? (write-stream 2 _test-error-stream)
12463 #? (rewind-stream _test-error-stream)
12466 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-too-many-inouts: output should be empty")
12467 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: too many inouts (2 required)" "F - test-compute-offset-with-too-many-inouts: error message")
12468 # check that stop(1) was called
12469 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-too-many-inouts: exit status")
12470 # don't restore from ebp
12471 81 0/subop/add %esp 8/imm32
12476 test-compute-offset-with-no-output:
12479 89/<- %ebp 4/r32/esp
12481 (clear-stream _test-input-stream)
12482 (clear-stream $_test-input-buffered-file->buffer)
12483 (clear-stream _test-output-stream)
12484 (clear-stream $_test-output-buffered-file->buffer)
12485 (clear-stream _test-error-stream)
12486 (clear-stream $_test-error-buffered-file->buffer)
12487 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12490 89/<- %edx 4/r32/esp
12491 (tailor-exit-descriptor %edx 0x10)
12493 (write _test-input-stream "fn foo {\n")
12494 (write _test-input-stream " var a: (array int 3)\n")
12495 (write _test-input-stream " compute-offset a, 0\n")
12496 (write _test-input-stream "}\n")
12498 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12499 # registers except esp clobbered at this point
12501 89/<- %edx 4/r32/esp
12502 (flush _test-output-buffered-file)
12503 (flush _test-error-buffered-file)
12504 #? # dump _test-error-stream {{{
12506 #? (write-stream 2 _test-error-stream)
12508 #? (rewind-stream _test-error-stream)
12511 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-no-output: output should be empty")
12512 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: must have an output" "F - test-compute-offset-with-no-output: error message")
12513 # check that stop(1) was called
12514 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-no-output: exit status")
12515 # don't restore from ebp
12516 81 0/subop/add %esp 8/imm32
12521 test-compute-offset-with-too-many-outputs:
12524 89/<- %ebp 4/r32/esp
12526 (clear-stream _test-input-stream)
12527 (clear-stream $_test-input-buffered-file->buffer)
12528 (clear-stream _test-output-stream)
12529 (clear-stream $_test-output-buffered-file->buffer)
12530 (clear-stream _test-error-stream)
12531 (clear-stream $_test-error-buffered-file->buffer)
12532 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12535 89/<- %edx 4/r32/esp
12536 (tailor-exit-descriptor %edx 0x10)
12538 (write _test-input-stream "fn foo {\n")
12539 (write _test-input-stream " var a: (array int 3)\n")
12540 (write _test-input-stream " var b/eax: (offset int) <- compute-offset a, 0\n")
12541 (write _test-input-stream " var c/ecx: (addr int) <- copy 0\n")
12542 (write _test-input-stream " b, c <- compute-offset a, 0\n")
12543 (write _test-input-stream "}\n")
12545 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12546 # registers except esp clobbered at this point
12548 89/<- %edx 4/r32/esp
12549 (flush _test-output-buffered-file)
12550 (flush _test-error-buffered-file)
12551 #? # dump _test-error-stream {{{
12553 #? (write-stream 2 _test-error-stream)
12555 #? (rewind-stream _test-error-stream)
12558 (check-stream-equal _test-output-stream "" "F - test-compute-offset-with-too-many-outputs: output should be empty")
12559 (check-next-stream-line-equal _test-error-stream "fn foo: stmt compute-offset: too many outputs (1 required)" "F - test-compute-offset-with-too-many-outputs: error message")
12560 # check that stop(1) was called
12561 (check-ints-equal *(edx+4) 2 "F - test-compute-offset-with-too-many-outputs: exit status")
12562 # don't restore from ebp
12563 81 0/subop/add %esp 8/imm32
12568 test-convert-read-from-stream:
12571 89/<- %ebp 4/r32/esp
12573 (clear-stream _test-input-stream)
12574 (clear-stream $_test-input-buffered-file->buffer)
12575 (clear-stream _test-output-stream)
12576 (clear-stream $_test-output-buffered-file->buffer)
12578 (write _test-input-stream "fn foo {\n")
12579 (write _test-input-stream " var s/esi: (addr stream int) <- copy 0\n")
12580 (write _test-input-stream " var o/ecx: (addr int) <- copy 0\n")
12581 (write _test-input-stream " read-from-stream s, o\n")
12582 (write _test-input-stream "}\n")
12584 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
12585 # registers except esp clobbered at this point
12587 89/<- %edx 4/r32/esp
12588 (flush _test-output-buffered-file)
12589 (flush _test-error-buffered-file)
12590 #? # dump _test-output-stream {{{
12592 #? (write-stream 2 _test-output-stream)
12594 #? (rewind-stream _test-output-stream)
12597 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-read-from-stream/0")
12598 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-read-from-stream/1")
12599 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-read-from-stream/2")
12600 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-read-from-stream/3")
12601 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-read-from-stream/4")
12602 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-read-from-stream/5")
12603 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-read-from-stream/6")
12604 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-read-from-stream/7")
12605 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-read-from-stream/8")
12606 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-read-from-stream/9")
12607 (check-next-stream-line-equal _test-output-stream " (read-from-stream %esi %ecx 0x00000004)" "F - test-convert-read-from-stream/10")
12608 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-read-from-stream/11")
12609 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-read-from-stream/12")
12610 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-read-from-stream/13")
12611 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-read-from-stream/14")
12612 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-read-from-stream/15")
12613 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-read-from-stream/16")
12614 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-read-from-stream/17")
12615 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-read-from-stream/18")
12617 89/<- %esp 5/r32/ebp
12621 test-convert-read-from-stream-with-correct-payload-size:
12624 89/<- %ebp 4/r32/esp
12626 (clear-stream _test-input-stream)
12627 (clear-stream $_test-input-buffered-file->buffer)
12628 (clear-stream _test-output-stream)
12629 (clear-stream $_test-output-buffered-file->buffer)
12631 (write _test-input-stream "fn foo {\n")
12632 (write _test-input-stream " var s/esi: (addr stream handle int) <- copy 0\n")
12633 (write _test-input-stream " var o/ecx: (addr handle int) <- copy 0\n")
12634 (write _test-input-stream " read-from-stream s, o\n")
12635 (write _test-input-stream "}\n")
12637 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
12638 # registers except esp clobbered at this point
12640 89/<- %edx 4/r32/esp
12641 (flush _test-output-buffered-file)
12642 (flush _test-error-buffered-file)
12643 #? # dump _test-output-stream {{{
12645 #? (write-stream 2 _test-output-stream)
12647 #? (rewind-stream _test-output-stream)
12650 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-read-from-stream-with-correct-payload-size/0")
12651 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-read-from-stream-with-correct-payload-size/1")
12652 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-read-from-stream-with-correct-payload-size/2")
12653 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-read-from-stream-with-correct-payload-size/3")
12654 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-read-from-stream-with-correct-payload-size/4")
12655 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-read-from-stream-with-correct-payload-size/5")
12656 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-read-from-stream-with-correct-payload-size/6")
12657 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-read-from-stream-with-correct-payload-size/7")
12658 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-read-from-stream-with-correct-payload-size/8")
12659 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-read-from-stream-with-correct-payload-size/9")
12660 (check-next-stream-line-equal _test-output-stream " (read-from-stream %esi %ecx 0x00000008)" "F - test-convert-read-from-stream-with-correct-payload-size/10")
12661 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-read-from-stream-with-correct-payload-size/11")
12662 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-read-from-stream-with-correct-payload-size/12")
12663 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-read-from-stream-with-correct-payload-size/13")
12664 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-read-from-stream-with-correct-payload-size/14")
12665 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-read-from-stream-with-correct-payload-size/15")
12666 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-read-from-stream-with-correct-payload-size/16")
12667 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-read-from-stream-with-correct-payload-size/17")
12668 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-read-from-stream-with-correct-payload-size/18")
12670 89/<- %esp 5/r32/ebp
12674 test-read-from-stream-with-non-stream-atom-base-type:
12677 89/<- %ebp 4/r32/esp
12679 (clear-stream _test-input-stream)
12680 (clear-stream $_test-input-buffered-file->buffer)
12681 (clear-stream _test-output-stream)
12682 (clear-stream $_test-output-buffered-file->buffer)
12683 (clear-stream _test-error-stream)
12684 (clear-stream $_test-error-buffered-file->buffer)
12685 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12688 89/<- %edx 4/r32/esp
12689 (tailor-exit-descriptor %edx 0x10)
12691 (write _test-input-stream "fn foo {\n")
12692 (write _test-input-stream " var a: int\n")
12693 (write _test-input-stream " read-from-stream a, 0\n")
12694 (write _test-input-stream "}\n")
12696 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12697 # registers except esp clobbered at this point
12699 89/<- %edx 4/r32/esp
12700 (flush _test-output-buffered-file)
12701 (flush _test-error-buffered-file)
12702 #? # dump _test-error-stream {{{
12704 #? (write-stream 2 _test-error-stream)
12706 #? (rewind-stream _test-error-stream)
12709 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-non-stream-atom-base-type: output should be empty")
12710 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: var 'a' must be an addr to a stream" "F - test-read-from-stream-with-non-stream-atom-base-type: error message")
12711 # check that stop(1) was called
12712 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-non-stream-atom-base-type: exit status")
12713 # don't restore from ebp
12714 81 0/subop/add %esp 8/imm32
12719 test-read-from-stream-with-non-stream-compound-base-type:
12722 89/<- %ebp 4/r32/esp
12724 (clear-stream _test-input-stream)
12725 (clear-stream $_test-input-buffered-file->buffer)
12726 (clear-stream _test-output-stream)
12727 (clear-stream $_test-output-buffered-file->buffer)
12728 (clear-stream _test-error-stream)
12729 (clear-stream $_test-error-buffered-file->buffer)
12730 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12733 89/<- %edx 4/r32/esp
12734 (tailor-exit-descriptor %edx 0x10)
12736 (write _test-input-stream "fn foo {\n")
12737 (write _test-input-stream " var a: (handle int)\n")
12738 (write _test-input-stream " read-from-stream a, 0\n")
12739 (write _test-input-stream "}\n")
12741 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12742 # registers except esp clobbered at this point
12744 89/<- %edx 4/r32/esp
12745 (flush _test-output-buffered-file)
12746 (flush _test-error-buffered-file)
12747 #? # dump _test-error-stream {{{
12749 #? (write-stream 2 _test-error-stream)
12751 #? (rewind-stream _test-error-stream)
12754 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-non-stream-compound-base-type: output should be empty")
12755 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: var 'a' must be an addr to a stream" "F - test-read-from-stream-with-non-stream-compound-base-type: error message")
12756 # check that stop(1) was called
12757 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-non-stream-compound-base-type: exit status")
12758 # don't restore from ebp
12759 81 0/subop/add %esp 8/imm32
12764 test-read-from-stream-with-non-stream-compound-base-type-2:
12767 89/<- %ebp 4/r32/esp
12769 (clear-stream _test-input-stream)
12770 (clear-stream $_test-input-buffered-file->buffer)
12771 (clear-stream _test-output-stream)
12772 (clear-stream $_test-output-buffered-file->buffer)
12773 (clear-stream _test-error-stream)
12774 (clear-stream $_test-error-buffered-file->buffer)
12775 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12778 89/<- %edx 4/r32/esp
12779 (tailor-exit-descriptor %edx 0x10)
12781 (write _test-input-stream "fn foo {\n")
12782 (write _test-input-stream " var a: (addr int)\n")
12783 (write _test-input-stream " read-from-stream a, 0\n")
12784 (write _test-input-stream "}\n")
12786 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12787 # registers except esp clobbered at this point
12789 89/<- %edx 4/r32/esp
12790 (flush _test-output-buffered-file)
12791 (flush _test-error-buffered-file)
12792 #? # dump _test-error-stream {{{
12794 #? (write-stream 2 _test-error-stream)
12796 #? (rewind-stream _test-error-stream)
12799 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-non-stream-compound-base-type-2: output should be empty")
12800 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: var 'a' must be an addr to a stream" "F - test-read-from-stream-with-non-stream-compound-base-type-2: error message")
12801 # check that stop(1) was called
12802 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-non-stream-compound-base-type-2: exit status")
12803 # don't restore from ebp
12804 81 0/subop/add %esp 8/imm32
12809 test-read-from-stream-with-stream-atom-base-type:
12812 89/<- %ebp 4/r32/esp
12814 (clear-stream _test-input-stream)
12815 (clear-stream $_test-input-buffered-file->buffer)
12816 (clear-stream _test-output-stream)
12817 (clear-stream $_test-output-buffered-file->buffer)
12818 (clear-stream _test-error-stream)
12819 (clear-stream $_test-error-buffered-file->buffer)
12820 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12823 89/<- %edx 4/r32/esp
12824 (tailor-exit-descriptor %edx 0x10)
12826 (write _test-input-stream "fn foo {\n")
12827 (write _test-input-stream " var a: stream\n")
12828 (write _test-input-stream " read-from-stream a, 0\n")
12829 (write _test-input-stream "}\n")
12831 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12832 # registers except esp clobbered at this point
12834 89/<- %edx 4/r32/esp
12835 (flush _test-output-buffered-file)
12836 (flush _test-error-buffered-file)
12837 #? # dump _test-error-stream {{{
12839 #? (write-stream 2 _test-error-stream)
12841 #? (rewind-stream _test-error-stream)
12844 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-stream-atom-base-type: output should be empty")
12845 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: var 'a' must be an addr to a stream" "F - test-read-from-stream-with-stream-atom-base-type: error message")
12846 # check that stop(1) was called
12847 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-stream-atom-base-type: exit status")
12848 # don't restore from ebp
12849 81 0/subop/add %esp 8/imm32
12854 test-read-from-stream-with-wrong-index-type:
12857 89/<- %ebp 4/r32/esp
12859 (clear-stream _test-input-stream)
12860 (clear-stream $_test-input-buffered-file->buffer)
12861 (clear-stream _test-output-stream)
12862 (clear-stream $_test-output-buffered-file->buffer)
12863 (clear-stream _test-error-stream)
12864 (clear-stream $_test-error-buffered-file->buffer)
12865 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12868 89/<- %edx 4/r32/esp
12869 (tailor-exit-descriptor %edx 0x10)
12871 (write _test-input-stream "fn foo {\n")
12872 (write _test-input-stream " var a/eax: (addr stream int) <- copy 0\n")
12873 (write _test-input-stream " var b: boolean\n")
12874 (write _test-input-stream " read-from-stream a, b\n")
12875 (write _test-input-stream "}\n")
12877 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12878 # registers except esp clobbered at this point
12880 89/<- %edx 4/r32/esp
12881 (flush _test-output-buffered-file)
12882 (flush _test-error-buffered-file)
12883 #? # dump _test-error-stream {{{
12885 #? (write-stream 2 _test-error-stream)
12887 #? (rewind-stream _test-error-stream)
12890 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-wrong-index-type: output should be empty")
12891 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: target 'b' must be an addr" "F - test-read-from-stream-with-wrong-index-type: error message")
12892 # check that stop(1) was called
12893 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-wrong-index-type: exit status")
12894 # don't restore from ebp
12895 81 0/subop/add %esp 8/imm32
12900 test-read-from-stream-with-no-inouts:
12903 89/<- %ebp 4/r32/esp
12905 (clear-stream _test-input-stream)
12906 (clear-stream $_test-input-buffered-file->buffer)
12907 (clear-stream _test-output-stream)
12908 (clear-stream $_test-output-buffered-file->buffer)
12909 (clear-stream _test-error-stream)
12910 (clear-stream $_test-error-buffered-file->buffer)
12911 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12914 89/<- %edx 4/r32/esp
12915 (tailor-exit-descriptor %edx 0x10)
12917 (write _test-input-stream "fn foo {\n")
12918 (write _test-input-stream " read-from-stream\n")
12919 (write _test-input-stream "}\n")
12921 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12922 # registers except esp clobbered at this point
12924 89/<- %edx 4/r32/esp
12925 (flush _test-output-buffered-file)
12926 (flush _test-error-buffered-file)
12927 #? # dump _test-error-stream {{{
12929 #? (write-stream 2 _test-error-stream)
12931 #? (rewind-stream _test-error-stream)
12934 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-no-inouts: output should be empty")
12935 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: too few inouts (2 required)" "F - test-read-from-stream-with-no-inouts: error message")
12936 # check that stop(1) was called
12937 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-no-inouts: exit status")
12938 # don't restore from ebp
12939 81 0/subop/add %esp 8/imm32
12944 test-read-from-stream-with-too-few-inouts:
12947 89/<- %ebp 4/r32/esp
12949 (clear-stream _test-input-stream)
12950 (clear-stream $_test-input-buffered-file->buffer)
12951 (clear-stream _test-output-stream)
12952 (clear-stream $_test-output-buffered-file->buffer)
12953 (clear-stream _test-error-stream)
12954 (clear-stream $_test-error-buffered-file->buffer)
12955 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
12958 89/<- %edx 4/r32/esp
12959 (tailor-exit-descriptor %edx 0x10)
12961 (write _test-input-stream "fn foo {\n")
12962 (write _test-input-stream " var a: (addr stream int)\n")
12963 (write _test-input-stream " read-from-stream a\n")
12964 (write _test-input-stream "}\n")
12966 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
12967 # registers except esp clobbered at this point
12969 89/<- %edx 4/r32/esp
12970 (flush _test-output-buffered-file)
12971 (flush _test-error-buffered-file)
12972 #? # dump _test-error-stream {{{
12974 #? (write-stream 2 _test-error-stream)
12976 #? (rewind-stream _test-error-stream)
12979 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-too-few-inouts: output should be empty")
12980 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: too few inouts (2 required)" "F - test-read-from-stream-with-too-few-inouts: error message")
12981 # check that stop(1) was called
12982 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-too-few-inouts: exit status")
12983 # don't restore from ebp
12984 81 0/subop/add %esp 8/imm32
12989 test-read-from-stream-with-too-many-inouts:
12992 89/<- %ebp 4/r32/esp
12994 (clear-stream _test-input-stream)
12995 (clear-stream $_test-input-buffered-file->buffer)
12996 (clear-stream _test-output-stream)
12997 (clear-stream $_test-output-buffered-file->buffer)
12998 (clear-stream _test-error-stream)
12999 (clear-stream $_test-error-buffered-file->buffer)
13000 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13003 89/<- %edx 4/r32/esp
13004 (tailor-exit-descriptor %edx 0x10)
13006 (write _test-input-stream "fn foo {\n")
13007 (write _test-input-stream " var a: (addr stream int)\n")
13008 (write _test-input-stream " var b: (addr int)\n")
13009 (write _test-input-stream " read-from-stream a, b, 0\n")
13010 (write _test-input-stream "}\n")
13012 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13013 # registers except esp clobbered at this point
13015 89/<- %edx 4/r32/esp
13016 (flush _test-output-buffered-file)
13017 (flush _test-error-buffered-file)
13018 #? # dump _test-error-stream {{{
13020 #? (write-stream 2 _test-error-stream)
13022 #? (rewind-stream _test-error-stream)
13025 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-too-many-inouts: output should be empty")
13026 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: too many inouts (2 required)" "F - test-read-from-stream-with-too-many-inouts: error message")
13027 # check that stop(1) was called
13028 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-too-many-inouts: exit status")
13029 # don't restore from ebp
13030 81 0/subop/add %esp 8/imm32
13035 test-read-from-stream-with-output:
13038 89/<- %ebp 4/r32/esp
13040 (clear-stream _test-input-stream)
13041 (clear-stream $_test-input-buffered-file->buffer)
13042 (clear-stream _test-output-stream)
13043 (clear-stream $_test-output-buffered-file->buffer)
13044 (clear-stream _test-error-stream)
13045 (clear-stream $_test-error-buffered-file->buffer)
13046 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13049 89/<- %edx 4/r32/esp
13050 (tailor-exit-descriptor %edx 0x10)
13052 (write _test-input-stream "fn foo {\n")
13053 (write _test-input-stream " var a: (addr stream int)\n")
13054 (write _test-input-stream " var b/eax: (addr int) <- copy 0\n")
13055 (write _test-input-stream " b <- read-from-stream a, b\n")
13056 (write _test-input-stream "}\n")
13058 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13059 # registers except esp clobbered at this point
13061 89/<- %edx 4/r32/esp
13062 (flush _test-output-buffered-file)
13063 (flush _test-error-buffered-file)
13064 #? # dump _test-error-stream {{{
13066 #? (write-stream 2 _test-error-stream)
13068 #? (rewind-stream _test-error-stream)
13071 (check-stream-equal _test-output-stream "" "F - test-read-from-stream-with-output: output should be empty")
13072 (check-next-stream-line-equal _test-error-stream "fn foo: stmt read-from-stream: unexpected output" "F - test-read-from-stream-with-output: error message")
13073 # check that stop(1) was called
13074 (check-ints-equal *(edx+4) 2 "F - test-read-from-stream-with-output: exit status")
13075 # don't restore from ebp
13076 81 0/subop/add %esp 8/imm32
13081 test-convert-write-to-stream:
13084 89/<- %ebp 4/r32/esp
13086 (clear-stream _test-input-stream)
13087 (clear-stream $_test-input-buffered-file->buffer)
13088 (clear-stream _test-output-stream)
13089 (clear-stream $_test-output-buffered-file->buffer)
13091 (write _test-input-stream "fn foo {\n")
13092 (write _test-input-stream " var s/esi: (addr stream int) <- copy 0\n")
13093 (write _test-input-stream " var o/ecx: (addr int) <- copy 0\n")
13094 (write _test-input-stream " write-to-stream s, o\n")
13095 (write _test-input-stream "}\n")
13097 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
13098 # registers except esp clobbered at this point
13100 89/<- %edx 4/r32/esp
13101 (flush _test-output-buffered-file)
13102 (flush _test-error-buffered-file)
13103 #? # dump _test-output-stream {{{
13105 #? (write-stream 2 _test-output-stream)
13107 #? (rewind-stream _test-output-stream)
13110 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-write-to-stream/0")
13111 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-write-to-stream/1")
13112 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-write-to-stream/2")
13113 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-write-to-stream/3")
13114 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-write-to-stream/4")
13115 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-write-to-stream/5")
13116 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-write-to-stream/6")
13117 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-write-to-stream/7")
13118 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-write-to-stream/8")
13119 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-write-to-stream/9")
13120 (check-next-stream-line-equal _test-output-stream " (write-to-stream %esi %ecx 0x00000004)" "F - test-convert-write-to-stream/10")
13121 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-write-to-stream/11")
13122 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-write-to-stream/12")
13123 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-write-to-stream/13")
13124 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-write-to-stream/14")
13125 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-write-to-stream/15")
13126 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-write-to-stream/16")
13127 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-write-to-stream/17")
13128 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-write-to-stream/18")
13130 89/<- %esp 5/r32/ebp
13134 test-convert-write-to-stream-with-correct-payload-size:
13137 89/<- %ebp 4/r32/esp
13139 (clear-stream _test-input-stream)
13140 (clear-stream $_test-input-buffered-file->buffer)
13141 (clear-stream _test-output-stream)
13142 (clear-stream $_test-output-buffered-file->buffer)
13144 (write _test-input-stream "fn foo {\n")
13145 (write _test-input-stream " var s/esi: (addr stream handle int) <- copy 0\n")
13146 (write _test-input-stream " var o/ecx: (addr handle int) <- copy 0\n")
13147 (write _test-input-stream " write-to-stream s, o\n")
13148 (write _test-input-stream "}\n")
13150 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
13151 # registers except esp clobbered at this point
13153 89/<- %edx 4/r32/esp
13154 (flush _test-output-buffered-file)
13155 (flush _test-error-buffered-file)
13156 #? # dump _test-output-stream {{{
13158 #? (write-stream 2 _test-output-stream)
13160 #? (rewind-stream _test-output-stream)
13163 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-write-to-stream-with-correct-payload-size/0")
13164 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-write-to-stream-with-correct-payload-size/1")
13165 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-write-to-stream-with-correct-payload-size/2")
13166 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-write-to-stream-with-correct-payload-size/3")
13167 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-write-to-stream-with-correct-payload-size/4")
13168 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-write-to-stream-with-correct-payload-size/5")
13169 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %esi" "F - test-convert-write-to-stream-with-correct-payload-size/6")
13170 (check-next-stream-line-equal _test-output-stream " be/copy-to-esi 0/imm32" "F - test-convert-write-to-stream-with-correct-payload-size/7")
13171 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-write-to-stream-with-correct-payload-size/8")
13172 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-write-to-stream-with-correct-payload-size/9")
13173 (check-next-stream-line-equal _test-output-stream " (write-to-stream %esi %ecx 0x00000008)" "F - test-convert-write-to-stream-with-correct-payload-size/10")
13174 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-write-to-stream-with-correct-payload-size/11")
13175 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %esi" "F - test-convert-write-to-stream-with-correct-payload-size/12")
13176 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-write-to-stream-with-correct-payload-size/13")
13177 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-write-to-stream-with-correct-payload-size/14")
13178 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-write-to-stream-with-correct-payload-size/15")
13179 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-write-to-stream-with-correct-payload-size/16")
13180 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-write-to-stream-with-correct-payload-size/17")
13181 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-write-to-stream-with-correct-payload-size/18")
13183 89/<- %esp 5/r32/ebp
13187 test-write-to-stream-with-non-stream-atom-base-type:
13190 89/<- %ebp 4/r32/esp
13192 (clear-stream _test-input-stream)
13193 (clear-stream $_test-input-buffered-file->buffer)
13194 (clear-stream _test-output-stream)
13195 (clear-stream $_test-output-buffered-file->buffer)
13196 (clear-stream _test-error-stream)
13197 (clear-stream $_test-error-buffered-file->buffer)
13198 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13201 89/<- %edx 4/r32/esp
13202 (tailor-exit-descriptor %edx 0x10)
13204 (write _test-input-stream "fn foo {\n")
13205 (write _test-input-stream " var a: int\n")
13206 (write _test-input-stream " write-to-stream a, 0\n")
13207 (write _test-input-stream "}\n")
13209 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13210 # registers except esp clobbered at this point
13212 89/<- %edx 4/r32/esp
13213 (flush _test-output-buffered-file)
13214 (flush _test-error-buffered-file)
13215 #? # dump _test-error-stream {{{
13217 #? (write-stream 2 _test-error-stream)
13219 #? (rewind-stream _test-error-stream)
13222 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-non-stream-atom-base-type: output should be empty")
13223 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: var 'a' must be an addr to a stream" "F - test-write-to-stream-with-non-stream-atom-base-type: error message")
13224 # check that stop(1) was called
13225 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-non-stream-atom-base-type: exit status")
13226 # don't restore from ebp
13227 81 0/subop/add %esp 8/imm32
13232 test-write-to-stream-with-non-stream-compound-base-type:
13235 89/<- %ebp 4/r32/esp
13237 (clear-stream _test-input-stream)
13238 (clear-stream $_test-input-buffered-file->buffer)
13239 (clear-stream _test-output-stream)
13240 (clear-stream $_test-output-buffered-file->buffer)
13241 (clear-stream _test-error-stream)
13242 (clear-stream $_test-error-buffered-file->buffer)
13243 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13246 89/<- %edx 4/r32/esp
13247 (tailor-exit-descriptor %edx 0x10)
13249 (write _test-input-stream "fn foo {\n")
13250 (write _test-input-stream " var a: (handle int)\n")
13251 (write _test-input-stream " write-to-stream a, 0\n")
13252 (write _test-input-stream "}\n")
13254 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13255 # registers except esp clobbered at this point
13257 89/<- %edx 4/r32/esp
13258 (flush _test-output-buffered-file)
13259 (flush _test-error-buffered-file)
13260 #? # dump _test-error-stream {{{
13262 #? (write-stream 2 _test-error-stream)
13264 #? (rewind-stream _test-error-stream)
13267 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-non-stream-compound-base-type: output should be empty")
13268 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: var 'a' must be an addr to a stream" "F - test-write-to-stream-with-non-stream-compound-base-type: error message")
13269 # check that stop(1) was called
13270 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-non-stream-compound-base-type: exit status")
13271 # don't restore from ebp
13272 81 0/subop/add %esp 8/imm32
13277 test-write-to-stream-with-non-stream-compound-base-type-2:
13280 89/<- %ebp 4/r32/esp
13282 (clear-stream _test-input-stream)
13283 (clear-stream $_test-input-buffered-file->buffer)
13284 (clear-stream _test-output-stream)
13285 (clear-stream $_test-output-buffered-file->buffer)
13286 (clear-stream _test-error-stream)
13287 (clear-stream $_test-error-buffered-file->buffer)
13288 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13291 89/<- %edx 4/r32/esp
13292 (tailor-exit-descriptor %edx 0x10)
13294 (write _test-input-stream "fn foo {\n")
13295 (write _test-input-stream " var a: (addr int)\n")
13296 (write _test-input-stream " write-to-stream a, 0\n")
13297 (write _test-input-stream "}\n")
13299 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13300 # registers except esp clobbered at this point
13302 89/<- %edx 4/r32/esp
13303 (flush _test-output-buffered-file)
13304 (flush _test-error-buffered-file)
13305 #? # dump _test-error-stream {{{
13307 #? (write-stream 2 _test-error-stream)
13309 #? (rewind-stream _test-error-stream)
13312 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-non-stream-compound-base-type-2: output should be empty")
13313 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: var 'a' must be an addr to a stream" "F - test-write-to-stream-with-non-stream-compound-base-type-2: error message")
13314 # check that stop(1) was called
13315 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-non-stream-compound-base-type-2: exit status")
13316 # don't restore from ebp
13317 81 0/subop/add %esp 8/imm32
13322 test-write-to-stream-with-stream-atom-base-type:
13325 89/<- %ebp 4/r32/esp
13327 (clear-stream _test-input-stream)
13328 (clear-stream $_test-input-buffered-file->buffer)
13329 (clear-stream _test-output-stream)
13330 (clear-stream $_test-output-buffered-file->buffer)
13331 (clear-stream _test-error-stream)
13332 (clear-stream $_test-error-buffered-file->buffer)
13333 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13336 89/<- %edx 4/r32/esp
13337 (tailor-exit-descriptor %edx 0x10)
13339 (write _test-input-stream "fn foo {\n")
13340 (write _test-input-stream " var a: stream\n")
13341 (write _test-input-stream " write-to-stream a, 0\n")
13342 (write _test-input-stream "}\n")
13344 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13345 # registers except esp clobbered at this point
13347 89/<- %edx 4/r32/esp
13348 (flush _test-output-buffered-file)
13349 (flush _test-error-buffered-file)
13350 #? # dump _test-error-stream {{{
13352 #? (write-stream 2 _test-error-stream)
13354 #? (rewind-stream _test-error-stream)
13357 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-stream-atom-base-type: output should be empty")
13358 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: var 'a' must be an addr to a stream" "F - test-write-to-stream-with-stream-atom-base-type: error message")
13359 # check that stop(1) was called
13360 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-stream-atom-base-type: exit status")
13361 # don't restore from ebp
13362 81 0/subop/add %esp 8/imm32
13367 test-write-to-stream-with-wrong-index-type:
13370 89/<- %ebp 4/r32/esp
13372 (clear-stream _test-input-stream)
13373 (clear-stream $_test-input-buffered-file->buffer)
13374 (clear-stream _test-output-stream)
13375 (clear-stream $_test-output-buffered-file->buffer)
13376 (clear-stream _test-error-stream)
13377 (clear-stream $_test-error-buffered-file->buffer)
13378 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13381 89/<- %edx 4/r32/esp
13382 (tailor-exit-descriptor %edx 0x10)
13384 (write _test-input-stream "fn foo {\n")
13385 (write _test-input-stream " var a/eax: (addr stream int) <- copy 0\n")
13386 (write _test-input-stream " var b: boolean\n")
13387 (write _test-input-stream " write-to-stream a, b\n")
13388 (write _test-input-stream "}\n")
13390 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13391 # registers except esp clobbered at this point
13393 89/<- %edx 4/r32/esp
13394 (flush _test-output-buffered-file)
13395 (flush _test-error-buffered-file)
13396 #? # dump _test-error-stream {{{
13398 #? (write-stream 2 _test-error-stream)
13400 #? (rewind-stream _test-error-stream)
13403 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-wrong-index-type: output should be empty")
13404 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: target 'b' must be an addr" "F - test-write-to-stream-with-wrong-index-type: error message")
13405 # check that stop(1) was called
13406 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-wrong-index-type: exit status")
13407 # don't restore from ebp
13408 81 0/subop/add %esp 8/imm32
13413 test-write-to-stream-with-no-inouts:
13416 89/<- %ebp 4/r32/esp
13418 (clear-stream _test-input-stream)
13419 (clear-stream $_test-input-buffered-file->buffer)
13420 (clear-stream _test-output-stream)
13421 (clear-stream $_test-output-buffered-file->buffer)
13422 (clear-stream _test-error-stream)
13423 (clear-stream $_test-error-buffered-file->buffer)
13424 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13427 89/<- %edx 4/r32/esp
13428 (tailor-exit-descriptor %edx 0x10)
13430 (write _test-input-stream "fn foo {\n")
13431 (write _test-input-stream " write-to-stream\n")
13432 (write _test-input-stream "}\n")
13434 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13435 # registers except esp clobbered at this point
13437 89/<- %edx 4/r32/esp
13438 (flush _test-output-buffered-file)
13439 (flush _test-error-buffered-file)
13440 #? # dump _test-error-stream {{{
13442 #? (write-stream 2 _test-error-stream)
13444 #? (rewind-stream _test-error-stream)
13447 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-no-inouts: output should be empty")
13448 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: too few inouts (2 required)" "F - test-write-to-stream-with-no-inouts: error message")
13449 # check that stop(1) was called
13450 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-no-inouts: exit status")
13451 # don't restore from ebp
13452 81 0/subop/add %esp 8/imm32
13457 test-write-to-stream-with-too-few-inouts:
13460 89/<- %ebp 4/r32/esp
13462 (clear-stream _test-input-stream)
13463 (clear-stream $_test-input-buffered-file->buffer)
13464 (clear-stream _test-output-stream)
13465 (clear-stream $_test-output-buffered-file->buffer)
13466 (clear-stream _test-error-stream)
13467 (clear-stream $_test-error-buffered-file->buffer)
13468 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13471 89/<- %edx 4/r32/esp
13472 (tailor-exit-descriptor %edx 0x10)
13474 (write _test-input-stream "fn foo {\n")
13475 (write _test-input-stream " var a: (addr stream int)\n")
13476 (write _test-input-stream " write-to-stream a\n")
13477 (write _test-input-stream "}\n")
13479 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13480 # registers except esp clobbered at this point
13482 89/<- %edx 4/r32/esp
13483 (flush _test-output-buffered-file)
13484 (flush _test-error-buffered-file)
13485 #? # dump _test-error-stream {{{
13487 #? (write-stream 2 _test-error-stream)
13489 #? (rewind-stream _test-error-stream)
13492 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-too-few-inouts: output should be empty")
13493 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: too few inouts (2 required)" "F - test-write-to-stream-with-too-few-inouts: error message")
13494 # check that stop(1) was called
13495 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-too-few-inouts: exit status")
13496 # don't restore from ebp
13497 81 0/subop/add %esp 8/imm32
13502 test-write-to-stream-with-too-many-inouts:
13505 89/<- %ebp 4/r32/esp
13507 (clear-stream _test-input-stream)
13508 (clear-stream $_test-input-buffered-file->buffer)
13509 (clear-stream _test-output-stream)
13510 (clear-stream $_test-output-buffered-file->buffer)
13511 (clear-stream _test-error-stream)
13512 (clear-stream $_test-error-buffered-file->buffer)
13513 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13516 89/<- %edx 4/r32/esp
13517 (tailor-exit-descriptor %edx 0x10)
13519 (write _test-input-stream "fn foo {\n")
13520 (write _test-input-stream " var a: (addr stream int)\n")
13521 (write _test-input-stream " var b: (addr int)\n")
13522 (write _test-input-stream " write-to-stream a, b, 0\n")
13523 (write _test-input-stream "}\n")
13525 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13526 # registers except esp clobbered at this point
13528 89/<- %edx 4/r32/esp
13529 (flush _test-output-buffered-file)
13530 (flush _test-error-buffered-file)
13531 #? # dump _test-error-stream {{{
13533 #? (write-stream 2 _test-error-stream)
13535 #? (rewind-stream _test-error-stream)
13538 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-too-many-inouts: output should be empty")
13539 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: too many inouts (2 required)" "F - test-write-to-stream-with-too-many-inouts: error message")
13540 # check that stop(1) was called
13541 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-too-many-inouts: exit status")
13542 # don't restore from ebp
13543 81 0/subop/add %esp 8/imm32
13548 test-write-to-stream-with-output:
13551 89/<- %ebp 4/r32/esp
13553 (clear-stream _test-input-stream)
13554 (clear-stream $_test-input-buffered-file->buffer)
13555 (clear-stream _test-output-stream)
13556 (clear-stream $_test-output-buffered-file->buffer)
13557 (clear-stream _test-error-stream)
13558 (clear-stream $_test-error-buffered-file->buffer)
13559 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13562 89/<- %edx 4/r32/esp
13563 (tailor-exit-descriptor %edx 0x10)
13565 (write _test-input-stream "fn foo {\n")
13566 (write _test-input-stream " var a: (addr stream int)\n")
13567 (write _test-input-stream " var b/eax: (addr int) <- copy 0\n")
13568 (write _test-input-stream " b <- write-to-stream a, b\n")
13569 (write _test-input-stream "}\n")
13571 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13572 # registers except esp clobbered at this point
13574 89/<- %edx 4/r32/esp
13575 (flush _test-output-buffered-file)
13576 (flush _test-error-buffered-file)
13577 #? # dump _test-error-stream {{{
13579 #? (write-stream 2 _test-error-stream)
13581 #? (rewind-stream _test-error-stream)
13584 (check-stream-equal _test-output-stream "" "F - test-write-to-stream-with-output: output should be empty")
13585 (check-next-stream-line-equal _test-error-stream "fn foo: stmt write-to-stream: unexpected output" "F - test-write-to-stream-with-output: error message")
13586 # check that stop(1) was called
13587 (check-ints-equal *(edx+4) 2 "F - test-write-to-stream-with-output: exit status")
13588 # don't restore from ebp
13589 81 0/subop/add %esp 8/imm32
13594 test-length-with-non-array-atom-base-type:
13597 89/<- %ebp 4/r32/esp
13599 (clear-stream _test-input-stream)
13600 (clear-stream $_test-input-buffered-file->buffer)
13601 (clear-stream _test-output-stream)
13602 (clear-stream $_test-output-buffered-file->buffer)
13603 (clear-stream _test-error-stream)
13604 (clear-stream $_test-error-buffered-file->buffer)
13605 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13608 89/<- %edx 4/r32/esp
13609 (tailor-exit-descriptor %edx 0x10)
13611 (write _test-input-stream "fn foo {\n")
13612 (write _test-input-stream " var a: int\n")
13613 (write _test-input-stream " var c/ecx: int <- length a\n")
13614 (write _test-input-stream "}\n")
13616 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13617 # registers except esp clobbered at this point
13619 89/<- %edx 4/r32/esp
13620 (flush _test-output-buffered-file)
13621 (flush _test-error-buffered-file)
13622 #? # dump _test-error-stream {{{
13624 #? (write-stream 2 _test-error-stream)
13626 #? (rewind-stream _test-error-stream)
13629 (check-stream-equal _test-output-stream "" "F - test-length-with-non-array-atom-base-type: output should be empty")
13630 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: var 'a' is not an array" "F - test-length-with-non-array-atom-base-type: error message")
13631 # check that stop(1) was called
13632 (check-ints-equal *(edx+4) 2 "F - test-length-with-non-array-atom-base-type: exit status")
13633 # don't restore from ebp
13634 81 0/subop/add %esp 8/imm32
13639 test-length-with-non-array-compound-base-type:
13642 89/<- %ebp 4/r32/esp
13644 (clear-stream _test-input-stream)
13645 (clear-stream $_test-input-buffered-file->buffer)
13646 (clear-stream _test-output-stream)
13647 (clear-stream $_test-output-buffered-file->buffer)
13648 (clear-stream _test-error-stream)
13649 (clear-stream $_test-error-buffered-file->buffer)
13650 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13653 89/<- %edx 4/r32/esp
13654 (tailor-exit-descriptor %edx 0x10)
13656 (write _test-input-stream "fn foo {\n")
13657 (write _test-input-stream " var a: (handle int)\n")
13658 (write _test-input-stream " var c/ecx: (addr int) <- length a, 0\n")
13659 (write _test-input-stream "}\n")
13661 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13662 # registers except esp clobbered at this point
13664 89/<- %edx 4/r32/esp
13665 (flush _test-output-buffered-file)
13666 (flush _test-error-buffered-file)
13667 #? # dump _test-error-stream {{{
13669 #? (write-stream 2 _test-error-stream)
13671 #? (rewind-stream _test-error-stream)
13674 (check-stream-equal _test-output-stream "" "F - test-length-with-non-array-compound-base-type: output should be empty")
13675 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: var 'a' is not an array" "F - test-length-with-non-array-compound-base-type: error message")
13676 # check that stop(1) was called
13677 (check-ints-equal *(edx+4) 2 "F - test-length-with-non-array-compound-base-type: exit status")
13678 # don't restore from ebp
13679 81 0/subop/add %esp 8/imm32
13684 test-length-with-non-array-compound-base-type-2:
13687 89/<- %ebp 4/r32/esp
13689 (clear-stream _test-input-stream)
13690 (clear-stream $_test-input-buffered-file->buffer)
13691 (clear-stream _test-output-stream)
13692 (clear-stream $_test-output-buffered-file->buffer)
13693 (clear-stream _test-error-stream)
13694 (clear-stream $_test-error-buffered-file->buffer)
13695 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13698 89/<- %edx 4/r32/esp
13699 (tailor-exit-descriptor %edx 0x10)
13701 (write _test-input-stream "fn foo {\n")
13702 (write _test-input-stream " var a: (addr int)\n")
13703 (write _test-input-stream " var c/ecx: (addr int) <- length a, 0\n")
13704 (write _test-input-stream "}\n")
13706 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13707 # registers except esp clobbered at this point
13709 89/<- %edx 4/r32/esp
13710 (flush _test-output-buffered-file)
13711 (flush _test-error-buffered-file)
13712 #? # dump _test-error-stream {{{
13714 #? (write-stream 2 _test-error-stream)
13716 #? (rewind-stream _test-error-stream)
13719 (check-stream-equal _test-output-stream "" "F - test-length-with-non-array-compound-base-type-2: output should be empty")
13720 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: var 'a' is not an array" "F - test-length-with-non-array-compound-base-type-2: error message")
13721 # check that stop(1) was called
13722 (check-ints-equal *(edx+4) 2 "F - test-length-with-non-array-compound-base-type-2: exit status")
13723 # don't restore from ebp
13724 81 0/subop/add %esp 8/imm32
13729 test-length-with-array-atom-base-type:
13732 89/<- %ebp 4/r32/esp
13734 (clear-stream _test-input-stream)
13735 (clear-stream $_test-input-buffered-file->buffer)
13736 (clear-stream _test-output-stream)
13737 (clear-stream $_test-output-buffered-file->buffer)
13738 (clear-stream _test-error-stream)
13739 (clear-stream $_test-error-buffered-file->buffer)
13740 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13743 89/<- %edx 4/r32/esp
13744 (tailor-exit-descriptor %edx 0x10)
13746 (write _test-input-stream "fn foo {\n")
13747 (write _test-input-stream " var a: array\n")
13748 (write _test-input-stream " var c/ecx: (addr int) <- length a\n")
13749 (write _test-input-stream "}\n")
13751 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13752 # registers except esp clobbered at this point
13754 89/<- %edx 4/r32/esp
13755 (flush _test-output-buffered-file)
13756 (flush _test-error-buffered-file)
13757 #? # dump _test-error-stream {{{
13759 #? (write-stream 2 _test-error-stream)
13761 #? (rewind-stream _test-error-stream)
13764 (check-stream-equal _test-output-stream "" "F - test-length-with-array-atom-base-type: output should be empty")
13765 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: array 'a' must specify the type of its elements" "F - test-length-with-array-atom-base-type: error message")
13766 # check that stop(1) was called
13767 (check-ints-equal *(edx+4) 2 "F - test-length-with-array-atom-base-type: exit status")
13768 # don't restore from ebp
13769 81 0/subop/add %esp 8/imm32
13774 test-length-with-addr-base-on-stack:
13777 89/<- %ebp 4/r32/esp
13779 (clear-stream _test-input-stream)
13780 (clear-stream $_test-input-buffered-file->buffer)
13781 (clear-stream _test-output-stream)
13782 (clear-stream $_test-output-buffered-file->buffer)
13783 (clear-stream _test-error-stream)
13784 (clear-stream $_test-error-buffered-file->buffer)
13785 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13788 89/<- %edx 4/r32/esp
13789 (tailor-exit-descriptor %edx 0x10)
13791 (write _test-input-stream "fn foo {\n")
13792 (write _test-input-stream " var a: (addr array int)\n")
13793 (write _test-input-stream " var c/ecx: (addr int) <- length a\n")
13794 (write _test-input-stream "}\n")
13796 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13797 # registers except esp clobbered at this point
13799 89/<- %edx 4/r32/esp
13800 (flush _test-output-buffered-file)
13801 (flush _test-error-buffered-file)
13802 #? # dump _test-error-stream {{{
13804 #? (write-stream 2 _test-error-stream)
13806 #? (rewind-stream _test-error-stream)
13809 (check-stream-equal _test-output-stream "" "F - test-length-with-addr-base-on-stack: output should be empty")
13810 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: var 'a' is an addr to an array, and so must live in a register" "F - test-length-with-addr-base-on-stack: error message")
13811 # check that stop(1) was called
13812 (check-ints-equal *(edx+4) 2 "F - test-length-with-addr-base-on-stack: exit status")
13813 # don't restore from ebp
13814 81 0/subop/add %esp 8/imm32
13819 test-length-with-wrong-output-type:
13822 89/<- %ebp 4/r32/esp
13824 (clear-stream _test-input-stream)
13825 (clear-stream $_test-input-buffered-file->buffer)
13826 (clear-stream _test-output-stream)
13827 (clear-stream $_test-output-buffered-file->buffer)
13828 (clear-stream _test-error-stream)
13829 (clear-stream $_test-error-buffered-file->buffer)
13830 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13833 89/<- %edx 4/r32/esp
13834 (tailor-exit-descriptor %edx 0x10)
13836 (write _test-input-stream "fn foo {\n")
13837 (write _test-input-stream " var a/ebx: (addr array boolean) <- copy 0\n")
13838 (write _test-input-stream " var o/edi: (addr int) <- length a\n")
13839 (write _test-input-stream "}\n")
13841 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13842 # registers except esp clobbered at this point
13844 89/<- %edx 4/r32/esp
13845 (flush _test-output-buffered-file)
13846 (flush _test-error-buffered-file)
13847 #? # dump _test-error-stream {{{
13849 #? (write-stream 2 _test-error-stream)
13851 #? (rewind-stream _test-error-stream)
13854 (check-stream-equal _test-output-stream "" "F - test-length-with-wrong-output-type: output should be empty")
13855 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: output 'o' does not have the right type" "F - test-length-with-wrong-output-type: error message")
13856 # check that stop(1) was called
13857 (check-ints-equal *(edx+4) 2 "F - test-length-with-wrong-output-type: exit status")
13858 # don't restore from ebp
13859 81 0/subop/add %esp 8/imm32
13864 test-length-with-wrong-output-compound-type:
13867 89/<- %ebp 4/r32/esp
13869 (clear-stream _test-input-stream)
13870 (clear-stream $_test-input-buffered-file->buffer)
13871 (clear-stream _test-output-stream)
13872 (clear-stream $_test-output-buffered-file->buffer)
13873 (clear-stream _test-error-stream)
13874 (clear-stream $_test-error-buffered-file->buffer)
13875 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13878 89/<- %edx 4/r32/esp
13879 (tailor-exit-descriptor %edx 0x10)
13881 (write _test-input-stream "fn foo {\n")
13882 (write _test-input-stream " var a/ebx: (addr array handle boolean) <- copy 0\n")
13883 (write _test-input-stream " var o/edi: (addr handle int) <- length a\n")
13884 (write _test-input-stream "}\n")
13886 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13887 # registers except esp clobbered at this point
13889 89/<- %edx 4/r32/esp
13890 (flush _test-output-buffered-file)
13891 (flush _test-error-buffered-file)
13892 #? # dump _test-error-stream {{{
13894 #? (write-stream 2 _test-error-stream)
13896 #? (rewind-stream _test-error-stream)
13899 (check-stream-equal _test-output-stream "" "F - test-length-with-wrong-output-compound-type: output should be empty")
13900 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: output 'o' does not have the right type" "F - test-length-with-wrong-output-compound-type: error message")
13901 # check that stop(1) was called
13902 (check-ints-equal *(edx+4) 2 "F - test-length-with-wrong-output-compound-type: exit status")
13903 # don't restore from ebp
13904 81 0/subop/add %esp 8/imm32
13909 test-length-with-no-inouts:
13912 89/<- %ebp 4/r32/esp
13914 (clear-stream _test-input-stream)
13915 (clear-stream $_test-input-buffered-file->buffer)
13916 (clear-stream _test-output-stream)
13917 (clear-stream $_test-output-buffered-file->buffer)
13918 (clear-stream _test-error-stream)
13919 (clear-stream $_test-error-buffered-file->buffer)
13920 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13923 89/<- %edx 4/r32/esp
13924 (tailor-exit-descriptor %edx 0x10)
13926 (write _test-input-stream "fn foo {\n")
13927 (write _test-input-stream " var c/ecx: int <- length\n")
13928 (write _test-input-stream "}\n")
13930 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13931 # registers except esp clobbered at this point
13933 89/<- %edx 4/r32/esp
13934 (flush _test-output-buffered-file)
13935 (flush _test-error-buffered-file)
13936 #? # dump _test-error-stream {{{
13938 #? (write-stream 2 _test-error-stream)
13940 #? (rewind-stream _test-error-stream)
13943 (check-stream-equal _test-output-stream "" "F - test-length-with-no-inouts: output should be empty")
13944 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: too few inouts (1 required)" "F - test-length-with-no-inouts: error message")
13945 # check that stop(1) was called
13946 (check-ints-equal *(edx+4) 2 "F - test-length-with-no-inouts: exit status")
13947 # don't restore from ebp
13948 81 0/subop/add %esp 8/imm32
13953 test-length-with-too-many-inouts:
13956 89/<- %ebp 4/r32/esp
13958 (clear-stream _test-input-stream)
13959 (clear-stream $_test-input-buffered-file->buffer)
13960 (clear-stream _test-output-stream)
13961 (clear-stream $_test-output-buffered-file->buffer)
13962 (clear-stream _test-error-stream)
13963 (clear-stream $_test-error-buffered-file->buffer)
13964 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
13967 89/<- %edx 4/r32/esp
13968 (tailor-exit-descriptor %edx 0x10)
13970 (write _test-input-stream "fn foo {\n")
13971 (write _test-input-stream " var a: (array int 3)\n")
13972 (write _test-input-stream " var c/ecx: int <- length a, 0, 0\n")
13973 (write _test-input-stream "}\n")
13975 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
13976 # registers except esp clobbered at this point
13978 89/<- %edx 4/r32/esp
13979 (flush _test-output-buffered-file)
13980 (flush _test-error-buffered-file)
13981 #? # dump _test-error-stream {{{
13983 #? (write-stream 2 _test-error-stream)
13985 #? (rewind-stream _test-error-stream)
13988 (check-stream-equal _test-output-stream "" "F - test-length-with-too-many-inouts: output should be empty")
13989 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: too many inouts (1 required)" "F - test-length-with-too-many-inouts: error message")
13990 # check that stop(1) was called
13991 (check-ints-equal *(edx+4) 2 "F - test-length-with-too-many-inouts: exit status")
13992 # don't restore from ebp
13993 81 0/subop/add %esp 8/imm32
13998 test-length-with-no-output:
14001 89/<- %ebp 4/r32/esp
14003 (clear-stream _test-input-stream)
14004 (clear-stream $_test-input-buffered-file->buffer)
14005 (clear-stream _test-output-stream)
14006 (clear-stream $_test-output-buffered-file->buffer)
14007 (clear-stream _test-error-stream)
14008 (clear-stream $_test-error-buffered-file->buffer)
14009 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14012 89/<- %edx 4/r32/esp
14013 (tailor-exit-descriptor %edx 0x10)
14015 (write _test-input-stream "fn foo {\n")
14016 (write _test-input-stream " var a: (array int 3)\n")
14017 (write _test-input-stream " length a\n")
14018 (write _test-input-stream "}\n")
14020 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14021 # registers except esp clobbered at this point
14023 89/<- %edx 4/r32/esp
14024 (flush _test-output-buffered-file)
14025 (flush _test-error-buffered-file)
14026 #? # dump _test-error-stream {{{
14028 #? (write-stream 2 _test-error-stream)
14030 #? (rewind-stream _test-error-stream)
14033 (check-stream-equal _test-output-stream "" "F - test-length-with-no-output: output should be empty")
14034 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: must have an output" "F - test-length-with-no-output: error message")
14035 # check that stop(1) was called
14036 (check-ints-equal *(edx+4) 2 "F - test-length-with-no-output: exit status")
14037 # don't restore from ebp
14038 81 0/subop/add %esp 8/imm32
14043 test-length-with-too-many-outputs:
14046 89/<- %ebp 4/r32/esp
14048 (clear-stream _test-input-stream)
14049 (clear-stream $_test-input-buffered-file->buffer)
14050 (clear-stream _test-output-stream)
14051 (clear-stream $_test-output-buffered-file->buffer)
14052 (clear-stream _test-error-stream)
14053 (clear-stream $_test-error-buffered-file->buffer)
14054 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14057 89/<- %edx 4/r32/esp
14058 (tailor-exit-descriptor %edx 0x10)
14060 (write _test-input-stream "fn foo {\n")
14061 (write _test-input-stream " var a: (array int 3)\n")
14062 (write _test-input-stream " var b/eax: int <- copy 0\n")
14063 (write _test-input-stream " var c/ecx: int <- copy 0\n")
14064 (write _test-input-stream " b, c <- length a\n")
14065 (write _test-input-stream "}\n")
14067 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14068 # registers except esp clobbered at this point
14070 89/<- %edx 4/r32/esp
14071 (flush _test-output-buffered-file)
14072 (flush _test-error-buffered-file)
14073 #? # dump _test-error-stream {{{
14075 #? (write-stream 2 _test-error-stream)
14077 #? (rewind-stream _test-error-stream)
14080 (check-stream-equal _test-output-stream "" "F - test-length-with-too-many-outputs: output should be empty")
14081 (check-next-stream-line-equal _test-error-stream "fn foo: stmt length: too many outputs (1 required)" "F - test-length-with-too-many-outputs: error message")
14082 # check that stop(1) was called
14083 (check-ints-equal *(edx+4) 2 "F - test-length-with-too-many-outputs: exit status")
14084 # don't restore from ebp
14085 81 0/subop/add %esp 8/imm32
14090 test-convert-function-with-return-register-and-local:
14093 89/<- %ebp 4/r32/esp
14095 (clear-stream _test-input-stream)
14096 (clear-stream $_test-input-buffered-file->buffer)
14097 (clear-stream _test-output-stream)
14098 (clear-stream $_test-output-buffered-file->buffer)
14100 (write _test-input-stream "fn foo -> _/eax: int {\n")
14101 (write _test-input-stream " var y/eax: int <- copy 3\n")
14102 (write _test-input-stream " var z/ecx: int <- copy 4\n")
14103 (write _test-input-stream " return y\n")
14104 (write _test-input-stream "}\n")
14106 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
14107 (flush _test-output-buffered-file)
14108 #? # dump _test-output-stream {{{
14110 #? (write-stream 2 _test-output-stream)
14112 #? (rewind-stream _test-output-stream)
14115 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-register-and-local/0")
14116 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-register-and-local/1")
14117 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-register-and-local/2")
14118 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-register-and-local/3")
14119 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-register-and-local/4")
14120 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-register-and-local/5")
14121 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-return-register-and-local/6")
14122 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-convert-function-with-return-register-and-local/7")
14123 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-return-register-and-local/8")
14124 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-convert-function-with-return-register-and-local/9")
14125 (check-next-stream-line-equal _test-output-stream " 8b/-> %eax 0x00000000/r32" "F - test-convert-function-with-return-register-and-local/10")
14126 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-return-register-and-local/11")
14127 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-return-register-and-local/12")
14128 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-register-and-local/13")
14129 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-register-and-local/14")
14130 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-register-and-local/15")
14131 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-register-and-local/16")
14132 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-register-and-local/17")
14133 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-register-and-local/18")
14134 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-register-and-local/19")
14136 89/<- %esp 5/r32/ebp
14140 test-convert-function-with-return-register-and-local-2:
14143 89/<- %ebp 4/r32/esp
14145 (clear-stream _test-input-stream)
14146 (clear-stream $_test-input-buffered-file->buffer)
14147 (clear-stream _test-output-stream)
14148 (clear-stream $_test-output-buffered-file->buffer)
14150 (write _test-input-stream "fn foo -> _/eax: int {\n")
14151 (write _test-input-stream " var y/eax: int <- copy 3\n")
14152 (write _test-input-stream " var z/ecx: int <- copy 4\n")
14153 (write _test-input-stream " return z\n")
14154 (write _test-input-stream "}\n")
14156 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
14157 (flush _test-output-buffered-file)
14158 #? # dump _test-output-stream {{{
14160 #? (write-stream 2 _test-output-stream)
14162 #? (rewind-stream _test-output-stream)
14165 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-register-and-local-2/0")
14166 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-register-and-local-2/1")
14167 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-register-and-local-2/2")
14168 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-register-and-local-2/3")
14169 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-register-and-local-2/4")
14170 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-register-and-local-2/5")
14171 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-return-register-and-local-2/6")
14172 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-convert-function-with-return-register-and-local-2/7")
14173 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-return-register-and-local-2/8")
14174 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-convert-function-with-return-register-and-local-2/9")
14175 (check-next-stream-line-equal _test-output-stream " 8b/-> %ecx 0x00000000/r32" "F - test-convert-function-with-return-register-and-local-2/10")
14176 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-return-register-and-local-2/11")
14177 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-function-with-return-register-and-local-2/12")
14178 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-register-and-local-2/13")
14179 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-register-and-local-2/14")
14180 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-register-and-local-2/15")
14181 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-register-and-local-2/16")
14182 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-register-and-local-2/17")
14183 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-register-and-local-2/18")
14184 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-register-and-local-2/19")
14186 89/<- %esp 5/r32/ebp
14190 test-convert-function-with-return-float-register-and-local:
14193 89/<- %ebp 4/r32/esp
14195 (clear-stream _test-input-stream)
14196 (clear-stream $_test-input-buffered-file->buffer)
14197 (clear-stream _test-output-stream)
14198 (clear-stream $_test-output-buffered-file->buffer)
14200 (write _test-input-stream "fn foo -> _/xmm1: float {\n")
14201 (write _test-input-stream " var y/eax: int <- copy 3\n")
14202 (write _test-input-stream " var g/xmm0: float <- convert y\n")
14203 (write _test-input-stream " var h/xmm1: float <- convert y\n")
14204 (write _test-input-stream " return g\n")
14205 (write _test-input-stream "}\n")
14207 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
14208 (flush _test-output-buffered-file)
14209 #? # dump _test-output-stream {{{
14211 #? (write-stream 2 _test-output-stream)
14213 #? (rewind-stream _test-output-stream)
14216 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-float-register-and-local/0")
14217 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-float-register-and-local/1")
14218 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-float-register-and-local/2")
14219 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-float-register-and-local/3")
14220 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-float-register-and-local/4")
14221 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-float-register-and-local/5")
14222 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-return-float-register-and-local/6") # var y
14223 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-convert-function-with-return-float-register-and-local/7")
14224 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-function-with-return-float-register-and-local/8") # var g
14225 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 0/x32" "F - test-convert-function-with-return-float-register-and-local/9")
14226 (check-next-stream-line-equal _test-output-stream " f3 0f 2a/convert-to-float %eax 0x00000000/x32" "F - test-convert-function-with-return-float-register-and-local/10")
14227 (check-next-stream-line-equal _test-output-stream " 81 5/subop/subtract %esp 4/imm32" "F - test-convert-function-with-return-float-register-and-local/11") # var h
14228 (check-next-stream-line-equal _test-output-stream " f3 0f 11/<- *esp 1/x32" "F - test-convert-function-with-return-float-register-and-local/12")
14229 (check-next-stream-line-equal _test-output-stream " f3 0f 2a/convert-to-float %eax 0x00000001/x32" "F - test-convert-function-with-return-float-register-and-local/13")
14230 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> %xmm0 0x00000001/x32" "F - test-convert-function-with-return-float-register-and-local/14") # return g
14231 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-dereferenced/15") # reclaim h
14232 (check-next-stream-line-equal _test-output-stream " f3 0f 10/-> *esp 0/x32" "F - test-convert-floating-point-dereferenced/16") # reclaim g
14233 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 4/imm32" "F - test-convert-floating-point-dereferenced/17")
14234 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-return-float-register-and-local/18") # reclaim y
14235 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-float-register-and-local/19")
14236 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-float-register-and-local/20")
14237 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-float-register-and-local/21")
14238 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-float-register-and-local/22")
14239 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-float-register-and-local/23")
14240 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-float-register-and-local/24")
14241 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-float-register-and-local/25")
14243 89/<- %esp 5/r32/ebp
14247 test-convert-function-with-return-and-local-vars:
14250 89/<- %ebp 4/r32/esp
14252 (clear-stream _test-input-stream)
14253 (clear-stream $_test-input-buffered-file->buffer)
14254 (clear-stream _test-output-stream)
14255 (clear-stream $_test-output-buffered-file->buffer)
14257 (write _test-input-stream "fn foo -> _/eax: int {\n")
14258 (write _test-input-stream " {\n")
14259 (write _test-input-stream " var x: int\n")
14260 (write _test-input-stream " {\n")
14261 (write _test-input-stream " var y: int\n")
14262 (write _test-input-stream " return y\n")
14263 (write _test-input-stream " increment x\n")
14264 (write _test-input-stream " }\n")
14265 (write _test-input-stream " }\n")
14266 (write _test-input-stream " return 0\n")
14267 (write _test-input-stream "}\n")
14269 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
14270 (flush _test-output-buffered-file)
14271 #? # dump _test-output-stream {{{
14273 #? (write-stream 2 _test-output-stream)
14275 #? (rewind-stream _test-output-stream)
14278 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-return-and-local-vars/0")
14279 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-return-and-local-vars/1")
14280 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-return-and-local-vars/2")
14281 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-return-and-local-vars/3")
14282 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-and-local-vars/4")
14283 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-return-and-local-vars/5")
14284 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-and-local-vars/6")
14285 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-return-and-local-vars/7")
14286 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-return-and-local-vars/8") # var x
14287 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-return-and-local-vars/9")
14288 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-return-and-local-vars/10")
14289 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-return-and-local-vars/11") # var y
14290 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff8) 0x00000000/r32" "F - test-convert-function-with-return-and-local-vars/12")
14291 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return-and-local-vars/13")
14292 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return-and-local-vars/14")
14293 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-and-local-vars/15")
14294 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-and-local-vars/16")
14295 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-return-and-local-vars/17")
14296 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-function-with-return-and-local-vars/18")
14297 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-and-local-vars/19")
14298 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-return-and-local-vars/20")
14299 (check-next-stream-line-equal _test-output-stream " c7 0/subop/copy %eax 0/imm32" "F - test-convert-function-with-return-and-local-vars/21")
14300 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000001:break/disp32" "F - test-convert-function-with-return-and-local-vars/21")
14301 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-return-and-local-vars/21")
14302 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-return-and-local-vars/22")
14303 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-return-and-local-vars/23")
14304 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-return-and-local-vars/24")
14305 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-return-and-local-vars/25")
14306 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-return-and-local-vars/26")
14308 89/<- %esp 5/r32/ebp
14312 test-copy-object-with-no-inout:
14315 89/<- %ebp 4/r32/esp
14317 (clear-stream _test-input-stream)
14318 (clear-stream $_test-input-buffered-file->buffer)
14319 (clear-stream _test-output-stream)
14320 (clear-stream $_test-output-buffered-file->buffer)
14321 (clear-stream _test-error-stream)
14322 (clear-stream $_test-error-buffered-file->buffer)
14323 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14326 89/<- %edx 4/r32/esp
14327 (tailor-exit-descriptor %edx 0x10)
14329 (write _test-input-stream "fn foo {\n")
14330 (write _test-input-stream " copy-object\n")
14331 (write _test-input-stream "}\n")
14333 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14334 # registers except esp clobbered at this point
14336 89/<- %edx 4/r32/esp
14337 (flush _test-output-buffered-file)
14338 (flush _test-error-buffered-file)
14339 #? # dump _test-error-stream {{{
14341 #? (write-stream 2 _test-error-stream)
14343 #? (rewind-stream _test-error-stream)
14346 (check-stream-equal _test-output-stream "" "F - test-copy-object-with-no-inout: output should be empty")
14347 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-object' must have two inouts" "F - test-copy-object-with-no-inout: error message")
14348 # check that stop(1) was called
14349 (check-ints-equal *(edx+4) 2 "F - test-copy-object-with-no-inout: exit status")
14350 # don't restore from ebp
14351 81 0/subop/add %esp 8/imm32
14356 test-copy-object-with-no-source:
14359 89/<- %ebp 4/r32/esp
14361 (clear-stream _test-input-stream)
14362 (clear-stream $_test-input-buffered-file->buffer)
14363 (clear-stream _test-output-stream)
14364 (clear-stream $_test-output-buffered-file->buffer)
14365 (clear-stream _test-error-stream)
14366 (clear-stream $_test-error-buffered-file->buffer)
14367 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14370 89/<- %edx 4/r32/esp
14371 (tailor-exit-descriptor %edx 0x10)
14373 (write _test-input-stream "fn foo {\n")
14374 (write _test-input-stream " var x: (addr int)\n")
14375 (write _test-input-stream " copy-object x\n")
14376 (write _test-input-stream "}\n")
14378 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14379 # registers except esp clobbered at this point
14381 89/<- %edx 4/r32/esp
14382 (flush _test-output-buffered-file)
14383 (flush _test-error-buffered-file)
14384 #? # dump _test-error-stream {{{
14386 #? (write-stream 2 _test-error-stream)
14388 #? (rewind-stream _test-error-stream)
14391 (check-stream-equal _test-output-stream "" "F - test-copy-object-with-no-source: output should be empty")
14392 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-object' must have two inouts" "F - test-copy-object-with-no-source: error message")
14393 # check that stop(1) was called
14394 (check-ints-equal *(edx+4) 2 "F - test-copy-object-with-no-source: exit status")
14395 # don't restore from ebp
14396 81 0/subop/add %esp 8/imm32
14401 test-copy-object-with-too-many-inouts:
14404 89/<- %ebp 4/r32/esp
14406 (clear-stream _test-input-stream)
14407 (clear-stream $_test-input-buffered-file->buffer)
14408 (clear-stream _test-output-stream)
14409 (clear-stream $_test-output-buffered-file->buffer)
14410 (clear-stream _test-error-stream)
14411 (clear-stream $_test-error-buffered-file->buffer)
14412 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14415 89/<- %edx 4/r32/esp
14416 (tailor-exit-descriptor %edx 0x10)
14418 (write _test-input-stream "fn foo {\n")
14419 (write _test-input-stream " var x: (addr boolean)\n")
14420 (write _test-input-stream " copy-object x, x, x\n")
14421 (write _test-input-stream "}\n")
14423 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14424 # registers except esp clobbered at this point
14426 89/<- %edx 4/r32/esp
14427 (flush _test-output-buffered-file)
14428 (flush _test-error-buffered-file)
14429 #? # dump _test-error-stream {{{
14431 #? (write-stream 2 _test-error-stream)
14433 #? (rewind-stream _test-error-stream)
14436 (check-stream-equal _test-output-stream "" "F - test-copy-object-with-too-many-inouts: output should be empty")
14437 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-object' must have two inouts" "F - test-copy-object-with-too-many-inouts: error message")
14438 # check that stop(1) was called
14439 (check-ints-equal *(edx+4) 2 "F - test-copy-object-with-too-many-inouts: exit status")
14440 # don't restore from ebp
14441 81 0/subop/add %esp 8/imm32
14446 test-copy-object-with-output:
14449 89/<- %ebp 4/r32/esp
14451 (clear-stream _test-input-stream)
14452 (clear-stream $_test-input-buffered-file->buffer)
14453 (clear-stream _test-output-stream)
14454 (clear-stream $_test-output-buffered-file->buffer)
14455 (clear-stream _test-error-stream)
14456 (clear-stream $_test-error-buffered-file->buffer)
14457 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14460 89/<- %edx 4/r32/esp
14461 (tailor-exit-descriptor %edx 0x10)
14463 (write _test-input-stream "fn foo {\n")
14464 (write _test-input-stream " var x/eax: (addr boolean) <- copy 0\n")
14465 (write _test-input-stream " var y/ecx: (addr boolean) <- copy 0\n")
14466 (write _test-input-stream " x <- copy-object x, y\n")
14467 (write _test-input-stream "}\n")
14469 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14470 # registers except esp clobbered at this point
14472 89/<- %edx 4/r32/esp
14473 (flush _test-output-buffered-file)
14474 (flush _test-error-buffered-file)
14475 #? # dump _test-error-stream {{{
14477 #? (write-stream 2 _test-error-stream)
14479 #? (rewind-stream _test-error-stream)
14482 (check-stream-equal _test-output-stream "" "F - test-copy-object-with-output: output should be empty")
14483 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'copy-object' must not have any outputs" "F - test-copy-object-with-output: error message")
14484 # check that stop(1) was called
14485 (check-ints-equal *(edx+4) 2 "F - test-copy-object-with-output: exit status")
14486 # don't restore from ebp
14487 81 0/subop/add %esp 8/imm32
14492 test-copy-object-deref-address:
14495 89/<- %ebp 4/r32/esp
14497 (clear-stream _test-input-stream)
14498 (clear-stream $_test-input-buffered-file->buffer)
14499 (clear-stream _test-output-stream)
14500 (clear-stream $_test-output-buffered-file->buffer)
14502 (write _test-input-stream "fn foo {\n")
14503 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n")
14504 (write _test-input-stream " var y/ecx: (addr addr int) <- copy 0\n")
14505 (write _test-input-stream " copy-object *y, x\n")
14506 (write _test-input-stream "}\n")
14508 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
14509 (flush _test-output-buffered-file)
14515 test-copy-object-non-addr:
14518 89/<- %ebp 4/r32/esp
14520 (clear-stream _test-input-stream)
14521 (clear-stream $_test-input-buffered-file->buffer)
14522 (clear-stream _test-output-stream)
14523 (clear-stream $_test-output-buffered-file->buffer)
14524 (clear-stream _test-error-stream)
14525 (clear-stream $_test-error-buffered-file->buffer)
14526 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14529 89/<- %edx 4/r32/esp
14530 (tailor-exit-descriptor %edx 0x10)
14532 (write _test-input-stream "fn foo {\n")
14533 (write _test-input-stream " var x: int\n")
14534 (write _test-input-stream " var y: int\n")
14535 (write _test-input-stream " copy-object y, x\n")
14536 (write _test-input-stream "}\n")
14538 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14539 # registers except esp clobbered at this point
14541 89/<- %edx 4/r32/esp
14542 (flush _test-output-buffered-file)
14543 (flush _test-error-buffered-file)
14544 #? # dump _test-error-stream {{{
14546 #? (write-stream 2 _test-error-stream)
14548 #? (rewind-stream _test-error-stream)
14551 (check-stream-equal _test-output-stream "" "F - test-copy-object-non-addr: output should be empty")
14552 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-object: two inouts with identical addr types expected" "F - test-copy-object-non-addr: error message")
14553 # check that stop(1) was called
14554 (check-ints-equal *(edx+4) 2 "F - test-copy-object-non-addr: exit status")
14555 # don't restore from ebp
14556 81 0/subop/add %esp 8/imm32
14561 test-copy-object-non-equal:
14564 89/<- %ebp 4/r32/esp
14566 (clear-stream _test-input-stream)
14567 (clear-stream $_test-input-buffered-file->buffer)
14568 (clear-stream _test-output-stream)
14569 (clear-stream $_test-output-buffered-file->buffer)
14570 (clear-stream _test-error-stream)
14571 (clear-stream $_test-error-buffered-file->buffer)
14572 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14575 89/<- %edx 4/r32/esp
14576 (tailor-exit-descriptor %edx 0x10)
14578 (write _test-input-stream "fn foo {\n")
14579 (write _test-input-stream " var x: (addr int)\n")
14580 (write _test-input-stream " var y: (addr boolean)\n")
14581 (write _test-input-stream " copy-object y, x\n")
14582 (write _test-input-stream "}\n")
14584 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14585 # registers except esp clobbered at this point
14587 89/<- %edx 4/r32/esp
14588 (flush _test-output-buffered-file)
14589 (flush _test-error-buffered-file)
14590 #? # dump _test-error-stream {{{
14592 #? (write-stream 2 _test-error-stream)
14594 #? (rewind-stream _test-error-stream)
14597 (check-stream-equal _test-output-stream "" "F - test-copy-object-non-equal: output should be empty")
14598 (check-next-stream-line-equal _test-error-stream "fn foo: stmt copy-object: two inouts with identical addr types expected" "F - test-copy-object-non-equal: error message")
14599 # check that stop(1) was called
14600 (check-ints-equal *(edx+4) 2 "F - test-copy-object-non-equal: exit status")
14601 # don't restore from ebp
14602 81 0/subop/add %esp 8/imm32
14607 test-allocate-with-no-inout:
14610 89/<- %ebp 4/r32/esp
14612 (clear-stream _test-input-stream)
14613 (clear-stream $_test-input-buffered-file->buffer)
14614 (clear-stream _test-output-stream)
14615 (clear-stream $_test-output-buffered-file->buffer)
14616 (clear-stream _test-error-stream)
14617 (clear-stream $_test-error-buffered-file->buffer)
14618 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14621 89/<- %edx 4/r32/esp
14622 (tailor-exit-descriptor %edx 0x10)
14624 (write _test-input-stream "fn foo {\n")
14625 (write _test-input-stream " allocate\n")
14626 (write _test-input-stream "}\n")
14628 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14629 # registers except esp clobbered at this point
14631 89/<- %edx 4/r32/esp
14632 (flush _test-output-buffered-file)
14633 (flush _test-error-buffered-file)
14634 #? # dump _test-error-stream {{{
14636 #? (write-stream 2 _test-error-stream)
14638 #? (rewind-stream _test-error-stream)
14641 (check-stream-equal _test-output-stream "" "F - test-allocate-with-no-inout: output should be empty")
14642 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'allocate' must have a single inout" "F - test-allocate-with-no-inout: error message")
14643 # check that stop(1) was called
14644 (check-ints-equal *(edx+4) 2 "F - test-allocate-with-no-inout: exit status")
14645 # don't restore from ebp
14646 81 0/subop/add %esp 8/imm32
14651 test-allocate-with-too-many-inouts:
14654 89/<- %ebp 4/r32/esp
14656 (clear-stream _test-input-stream)
14657 (clear-stream $_test-input-buffered-file->buffer)
14658 (clear-stream _test-output-stream)
14659 (clear-stream $_test-output-buffered-file->buffer)
14660 (clear-stream _test-error-stream)
14661 (clear-stream $_test-error-buffered-file->buffer)
14662 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14665 89/<- %edx 4/r32/esp
14666 (tailor-exit-descriptor %edx 0x10)
14668 (write _test-input-stream "fn foo {\n")
14669 (write _test-input-stream " var x: (addr handle int)\n")
14670 (write _test-input-stream " allocate x, 0\n")
14671 (write _test-input-stream "}\n")
14673 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14674 # registers except esp clobbered at this point
14676 89/<- %edx 4/r32/esp
14677 (flush _test-output-buffered-file)
14678 (flush _test-error-buffered-file)
14679 #? # dump _test-error-stream {{{
14681 #? (write-stream 2 _test-error-stream)
14683 #? (rewind-stream _test-error-stream)
14686 (check-stream-equal _test-output-stream "" "F - test-allocate-with-too-many-inouts: output should be empty")
14687 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'allocate' must have a single inout" "F - test-allocate-with-too-many-inouts: error message")
14688 # check that stop(1) was called
14689 (check-ints-equal *(edx+4) 2 "F - test-allocate-with-too-many-inouts: exit status")
14690 # don't restore from ebp
14691 81 0/subop/add %esp 8/imm32
14696 test-allocate-with-output:
14699 89/<- %ebp 4/r32/esp
14701 (clear-stream _test-input-stream)
14702 (clear-stream $_test-input-buffered-file->buffer)
14703 (clear-stream _test-output-stream)
14704 (clear-stream $_test-output-buffered-file->buffer)
14705 (clear-stream _test-error-stream)
14706 (clear-stream $_test-error-buffered-file->buffer)
14707 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14710 89/<- %edx 4/r32/esp
14711 (tailor-exit-descriptor %edx 0x10)
14713 (write _test-input-stream "fn foo {\n")
14714 (write _test-input-stream " var x/eax: boolean <- copy 0\n")
14715 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n")
14716 (write _test-input-stream " x <- allocate y\n")
14717 (write _test-input-stream "}\n")
14719 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14720 # registers except esp clobbered at this point
14722 89/<- %edx 4/r32/esp
14723 (flush _test-output-buffered-file)
14724 (flush _test-error-buffered-file)
14725 #? # dump _test-error-stream {{{
14727 #? (write-stream 2 _test-error-stream)
14729 #? (rewind-stream _test-error-stream)
14732 (check-stream-equal _test-output-stream "" "F - test-allocate-with-output: output should be empty")
14733 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'allocate' must not have any outputs" "F - test-allocate-with-output: error message")
14734 # check that stop(1) was called
14735 (check-ints-equal *(edx+4) 2 "F - test-allocate-with-output: exit status")
14736 # don't restore from ebp
14737 81 0/subop/add %esp 8/imm32
14742 test-allocate-non-addr:
14745 89/<- %ebp 4/r32/esp
14747 (clear-stream _test-input-stream)
14748 (clear-stream $_test-input-buffered-file->buffer)
14749 (clear-stream _test-output-stream)
14750 (clear-stream $_test-output-buffered-file->buffer)
14751 (clear-stream _test-error-stream)
14752 (clear-stream $_test-error-buffered-file->buffer)
14753 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14756 89/<- %edx 4/r32/esp
14757 (tailor-exit-descriptor %edx 0x10)
14759 (write _test-input-stream "fn foo {\n")
14760 (write _test-input-stream " var y: (handle int)\n")
14761 (write _test-input-stream " allocate y\n")
14762 (write _test-input-stream "}\n")
14764 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14765 # registers except esp clobbered at this point
14767 89/<- %edx 4/r32/esp
14768 (flush _test-output-buffered-file)
14769 (flush _test-error-buffered-file)
14770 #? # dump _test-error-stream {{{
14772 #? (write-stream 2 _test-error-stream)
14774 #? (rewind-stream _test-error-stream)
14777 (check-stream-equal _test-output-stream "" "F - test-allocate-non-addr: output must be empty")
14778 (check-next-stream-line-equal _test-error-stream "fn foo: stmt allocate: inout 'y' must have type (addr handle ...)" "F - test-allocate-non-addr: error message")
14779 # check that stop(1) was called
14780 (check-ints-equal *(edx+4) 2 "F - test-allocate-non-addr: exit status")
14781 # don't restore from ebp
14782 81 0/subop/add %esp 8/imm32
14787 test-allocate-non-addr-handle:
14790 89/<- %ebp 4/r32/esp
14792 (clear-stream _test-input-stream)
14793 (clear-stream $_test-input-buffered-file->buffer)
14794 (clear-stream _test-output-stream)
14795 (clear-stream $_test-output-buffered-file->buffer)
14796 (clear-stream _test-error-stream)
14797 (clear-stream $_test-error-buffered-file->buffer)
14798 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14801 89/<- %edx 4/r32/esp
14802 (tailor-exit-descriptor %edx 0x10)
14804 (write _test-input-stream "fn foo {\n")
14805 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n")
14806 (write _test-input-stream " allocate y\n")
14807 (write _test-input-stream "}\n")
14809 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14810 # registers except esp clobbered at this point
14812 89/<- %edx 4/r32/esp
14813 (flush _test-output-buffered-file)
14814 (flush _test-error-buffered-file)
14815 #? # dump _test-error-stream {{{
14817 #? (write-stream 2 _test-error-stream)
14819 #? (rewind-stream _test-error-stream)
14822 (check-stream-equal _test-output-stream "" "F - test-allocate-non-addr-handle: output should be empty")
14823 (check-next-stream-line-equal _test-error-stream "fn foo: stmt allocate: inout 'y' must have type (addr handle ...)" "F - test-allocate-non-addr-handle: error message")
14824 # check that stop(1) was called
14825 (check-ints-equal *(edx+4) 2 "F - test-allocate-non-addr-handle: exit status")
14826 # don't restore from ebp
14827 81 0/subop/add %esp 8/imm32
14832 test-allocate-deref-address:
14835 89/<- %ebp 4/r32/esp
14837 (clear-stream _test-input-stream)
14838 (clear-stream $_test-input-buffered-file->buffer)
14839 (clear-stream _test-output-stream)
14840 (clear-stream $_test-output-buffered-file->buffer)
14842 (write _test-input-stream "fn foo {\n")
14843 (write _test-input-stream " var y/ecx: (addr addr handle int) <- copy 0\n")
14844 (write _test-input-stream " allocate *y\n")
14845 (write _test-input-stream "}\n")
14847 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
14848 (flush _test-output-buffered-file)
14854 test-populate-with-no-inout:
14857 89/<- %ebp 4/r32/esp
14859 (clear-stream _test-input-stream)
14860 (clear-stream $_test-input-buffered-file->buffer)
14861 (clear-stream _test-output-stream)
14862 (clear-stream $_test-output-buffered-file->buffer)
14863 (clear-stream _test-error-stream)
14864 (clear-stream $_test-error-buffered-file->buffer)
14865 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14868 89/<- %edx 4/r32/esp
14869 (tailor-exit-descriptor %edx 0x10)
14871 (write _test-input-stream "fn foo {\n")
14872 (write _test-input-stream " populate\n")
14873 (write _test-input-stream "}\n")
14875 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14876 # registers except esp clobbered at this point
14878 89/<- %edx 4/r32/esp
14879 (flush _test-output-buffered-file)
14880 (flush _test-error-buffered-file)
14881 #? # dump _test-error-stream {{{
14883 #? (write-stream 2 _test-error-stream)
14885 #? (rewind-stream _test-error-stream)
14888 (check-stream-equal _test-output-stream "" "F - test-populate-with-no-inout: output should be empty")
14889 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate' must have two inouts" "F - test-populate-with-no-inout: error message")
14890 # check that stop(1) was called
14891 (check-ints-equal *(edx+4) 2 "F - test-populate-with-no-inout: exit status")
14892 # don't restore from ebp
14893 81 0/subop/add %esp 8/imm32
14898 test-populate-with-too-many-inouts:
14901 89/<- %ebp 4/r32/esp
14903 (clear-stream _test-input-stream)
14904 (clear-stream $_test-input-buffered-file->buffer)
14905 (clear-stream _test-output-stream)
14906 (clear-stream $_test-output-buffered-file->buffer)
14907 (clear-stream _test-error-stream)
14908 (clear-stream $_test-error-buffered-file->buffer)
14909 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14912 89/<- %edx 4/r32/esp
14913 (tailor-exit-descriptor %edx 0x10)
14915 (write _test-input-stream "fn foo {\n")
14916 (write _test-input-stream " var x: (addr handle int)\n")
14917 (write _test-input-stream " populate x, 3, 0\n")
14918 (write _test-input-stream "}\n")
14920 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14921 # registers except esp clobbered at this point
14923 89/<- %edx 4/r32/esp
14924 (flush _test-output-buffered-file)
14925 (flush _test-error-buffered-file)
14926 #? # dump _test-error-stream {{{
14928 #? (write-stream 2 _test-error-stream)
14930 #? (rewind-stream _test-error-stream)
14933 (check-stream-equal _test-output-stream "" "F - test-populate-with-too-many-inouts: output should be empty")
14934 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate' must have two inouts" "F - test-populate-with-too-many-inouts: error message")
14935 # check that stop(1) was called
14936 (check-ints-equal *(edx+4) 2 "F - test-populate-with-too-many-inouts: exit status")
14937 # don't restore from ebp
14938 81 0/subop/add %esp 8/imm32
14943 test-populate-with-output:
14946 89/<- %ebp 4/r32/esp
14948 (clear-stream _test-input-stream)
14949 (clear-stream $_test-input-buffered-file->buffer)
14950 (clear-stream _test-output-stream)
14951 (clear-stream $_test-output-buffered-file->buffer)
14952 (clear-stream _test-error-stream)
14953 (clear-stream $_test-error-buffered-file->buffer)
14954 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
14957 89/<- %edx 4/r32/esp
14958 (tailor-exit-descriptor %edx 0x10)
14960 (write _test-input-stream "fn foo {\n")
14961 (write _test-input-stream " var x/eax: boolean <- copy 0\n")
14962 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n")
14963 (write _test-input-stream " x <- populate y\n")
14964 (write _test-input-stream "}\n")
14966 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
14967 # registers except esp clobbered at this point
14969 89/<- %edx 4/r32/esp
14970 (flush _test-output-buffered-file)
14971 (flush _test-error-buffered-file)
14972 #? # dump _test-error-stream {{{
14974 #? (write-stream 2 _test-error-stream)
14976 #? (rewind-stream _test-error-stream)
14979 (check-stream-equal _test-output-stream "" "F - test-populate-with-output: output should be empty")
14980 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate' must not have any outputs" "F - test-populate-with-output: error message")
14981 # check that stop(1) was called
14982 (check-ints-equal *(edx+4) 2 "F - test-populate-with-output: exit status")
14983 # don't restore from ebp
14984 81 0/subop/add %esp 8/imm32
14989 test-populate-non-addr:
14992 89/<- %ebp 4/r32/esp
14994 (clear-stream _test-input-stream)
14995 (clear-stream $_test-input-buffered-file->buffer)
14996 (clear-stream _test-output-stream)
14997 (clear-stream $_test-output-buffered-file->buffer)
14998 (clear-stream _test-error-stream)
14999 (clear-stream $_test-error-buffered-file->buffer)
15000 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15003 89/<- %edx 4/r32/esp
15004 (tailor-exit-descriptor %edx 0x10)
15006 (write _test-input-stream "fn foo {\n")
15007 (write _test-input-stream " var y: (handle int)\n")
15008 (write _test-input-stream " populate y, 3\n")
15009 (write _test-input-stream "}\n")
15011 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15012 # registers except esp clobbered at this point
15014 89/<- %edx 4/r32/esp
15015 (flush _test-output-buffered-file)
15016 (flush _test-error-buffered-file)
15017 #? # dump _test-error-stream {{{
15019 #? (write-stream 2 _test-error-stream)
15021 #? (rewind-stream _test-error-stream)
15024 (check-stream-equal _test-output-stream "" "F - test-populate-non-addr: output must be empty")
15025 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate: first inout 'y' must have type (addr handle array ...)" "F - test-populate-non-addr: error message")
15026 # check that stop(1) was called
15027 (check-ints-equal *(edx+4) 2 "F - test-populate-non-addr: exit status")
15028 # don't restore from ebp
15029 81 0/subop/add %esp 8/imm32
15034 test-populate-non-addr-handle:
15037 89/<- %ebp 4/r32/esp
15039 (clear-stream _test-input-stream)
15040 (clear-stream $_test-input-buffered-file->buffer)
15041 (clear-stream _test-output-stream)
15042 (clear-stream $_test-output-buffered-file->buffer)
15043 (clear-stream _test-error-stream)
15044 (clear-stream $_test-error-buffered-file->buffer)
15045 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15048 89/<- %edx 4/r32/esp
15049 (tailor-exit-descriptor %edx 0x10)
15051 (write _test-input-stream "fn foo {\n")
15052 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n")
15053 (write _test-input-stream " populate y, 3\n")
15054 (write _test-input-stream "}\n")
15056 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15057 # registers except esp clobbered at this point
15059 89/<- %edx 4/r32/esp
15060 (flush _test-output-buffered-file)
15061 (flush _test-error-buffered-file)
15062 #? # dump _test-error-stream {{{
15064 #? (write-stream 2 _test-error-stream)
15066 #? (rewind-stream _test-error-stream)
15069 (check-stream-equal _test-output-stream "" "F - test-populate-non-addr-handle: output should be empty")
15070 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate: first inout 'y' must have type (addr handle array ...)" "F - test-populate-non-addr-handle: error message")
15071 # check that stop(1) was called
15072 (check-ints-equal *(edx+4) 2 "F - test-populate-non-addr-handle: exit status")
15073 # don't restore from ebp
15074 81 0/subop/add %esp 8/imm32
15079 test-populate-non-addr-handle-array:
15082 89/<- %ebp 4/r32/esp
15084 (clear-stream _test-input-stream)
15085 (clear-stream $_test-input-buffered-file->buffer)
15086 (clear-stream _test-output-stream)
15087 (clear-stream $_test-output-buffered-file->buffer)
15088 (clear-stream _test-error-stream)
15089 (clear-stream $_test-error-buffered-file->buffer)
15090 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15093 89/<- %edx 4/r32/esp
15094 (tailor-exit-descriptor %edx 0x10)
15096 (write _test-input-stream "fn foo {\n")
15097 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n")
15098 (write _test-input-stream " populate y, 3\n")
15099 (write _test-input-stream "}\n")
15101 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15102 # registers except esp clobbered at this point
15104 89/<- %edx 4/r32/esp
15105 (flush _test-output-buffered-file)
15106 (flush _test-error-buffered-file)
15107 #? # dump _test-error-stream {{{
15109 #? (write-stream 2 _test-error-stream)
15111 #? (rewind-stream _test-error-stream)
15114 (check-stream-equal _test-output-stream "" "F - test-populate-non-addr-handle-array: output should be empty")
15115 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate: first inout 'y' must have type (addr handle array ...)" "F - test-populate-non-addr-handle-array: error message")
15116 # check that stop(1) was called
15117 (check-ints-equal *(edx+4) 2 "F - test-populate-non-addr-handle-array: exit status")
15118 # don't restore from ebp
15119 81 0/subop/add %esp 8/imm32
15124 test-populate-deref-address:
15127 89/<- %ebp 4/r32/esp
15129 (clear-stream _test-input-stream)
15130 (clear-stream $_test-input-buffered-file->buffer)
15131 (clear-stream _test-output-stream)
15132 (clear-stream $_test-output-buffered-file->buffer)
15134 (write _test-input-stream "fn foo {\n")
15135 (write _test-input-stream " var y/ecx: (addr addr handle array int) <- copy 0\n")
15136 (write _test-input-stream " populate *y, 3\n")
15137 (write _test-input-stream "}\n")
15139 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
15140 (flush _test-output-buffered-file)
15146 test-populate-stream-with-no-inout:
15149 89/<- %ebp 4/r32/esp
15151 (clear-stream _test-input-stream)
15152 (clear-stream $_test-input-buffered-file->buffer)
15153 (clear-stream _test-output-stream)
15154 (clear-stream $_test-output-buffered-file->buffer)
15155 (clear-stream _test-error-stream)
15156 (clear-stream $_test-error-buffered-file->buffer)
15157 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15160 89/<- %edx 4/r32/esp
15161 (tailor-exit-descriptor %edx 0x10)
15163 (write _test-input-stream "fn foo {\n")
15164 (write _test-input-stream " populate-stream\n")
15165 (write _test-input-stream "}\n")
15167 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15168 # registers except esp clobbered at this point
15170 89/<- %edx 4/r32/esp
15171 (flush _test-output-buffered-file)
15172 (flush _test-error-buffered-file)
15173 #? # dump _test-error-stream {{{
15175 #? (write-stream 2 _test-error-stream)
15177 #? (rewind-stream _test-error-stream)
15180 (check-stream-equal _test-output-stream "" "F - test-populate-stream-with-no-inout: output should be empty")
15181 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate-stream' must have two inouts" "F - test-populate-stream-with-no-inout: error message")
15182 # check that stop(1) was called
15183 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-with-no-inout: exit status")
15184 # don't restore from ebp
15185 81 0/subop/add %esp 8/imm32
15190 test-populate-stream-with-too-many-inouts:
15193 89/<- %ebp 4/r32/esp
15195 (clear-stream _test-input-stream)
15196 (clear-stream $_test-input-buffered-file->buffer)
15197 (clear-stream _test-output-stream)
15198 (clear-stream $_test-output-buffered-file->buffer)
15199 (clear-stream _test-error-stream)
15200 (clear-stream $_test-error-buffered-file->buffer)
15201 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15204 89/<- %edx 4/r32/esp
15205 (tailor-exit-descriptor %edx 0x10)
15207 (write _test-input-stream "fn foo {\n")
15208 (write _test-input-stream " var x: (addr handle int)\n")
15209 (write _test-input-stream " populate-stream x, 3, 0\n")
15210 (write _test-input-stream "}\n")
15212 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15213 # registers except esp clobbered at this point
15215 89/<- %edx 4/r32/esp
15216 (flush _test-output-buffered-file)
15217 (flush _test-error-buffered-file)
15218 #? # dump _test-error-stream {{{
15220 #? (write-stream 2 _test-error-stream)
15222 #? (rewind-stream _test-error-stream)
15225 (check-stream-equal _test-output-stream "" "F - test-populate-stream-with-too-many-inouts: output should be empty")
15226 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate-stream' must have two inouts" "F - test-populate-stream-with-too-many-inouts: error message")
15227 # check that stop(1) was called
15228 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-with-too-many-inouts: exit status")
15229 # don't restore from ebp
15230 81 0/subop/add %esp 8/imm32
15235 test-populate-stream-with-output:
15238 89/<- %ebp 4/r32/esp
15240 (clear-stream _test-input-stream)
15241 (clear-stream $_test-input-buffered-file->buffer)
15242 (clear-stream _test-output-stream)
15243 (clear-stream $_test-output-buffered-file->buffer)
15244 (clear-stream _test-error-stream)
15245 (clear-stream $_test-error-buffered-file->buffer)
15246 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15249 89/<- %edx 4/r32/esp
15250 (tailor-exit-descriptor %edx 0x10)
15252 (write _test-input-stream "fn foo {\n")
15253 (write _test-input-stream " var x/eax: boolean <- copy 0\n")
15254 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n")
15255 (write _test-input-stream " x <- populate-stream y\n")
15256 (write _test-input-stream "}\n")
15258 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15259 # registers except esp clobbered at this point
15261 89/<- %edx 4/r32/esp
15262 (flush _test-output-buffered-file)
15263 (flush _test-error-buffered-file)
15264 #? # dump _test-error-stream {{{
15266 #? (write-stream 2 _test-error-stream)
15268 #? (rewind-stream _test-error-stream)
15271 (check-stream-equal _test-output-stream "" "F - test-populate-stream-with-output: output should be empty")
15272 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'populate-stream' must not have any outputs" "F - test-populate-stream-with-output: error message")
15273 # check that stop(1) was called
15274 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-with-output: exit status")
15275 # don't restore from ebp
15276 81 0/subop/add %esp 8/imm32
15281 test-populate-stream-non-addr:
15284 89/<- %ebp 4/r32/esp
15286 (clear-stream _test-input-stream)
15287 (clear-stream $_test-input-buffered-file->buffer)
15288 (clear-stream _test-output-stream)
15289 (clear-stream $_test-output-buffered-file->buffer)
15290 (clear-stream _test-error-stream)
15291 (clear-stream $_test-error-buffered-file->buffer)
15292 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15295 89/<- %edx 4/r32/esp
15296 (tailor-exit-descriptor %edx 0x10)
15298 (write _test-input-stream "fn foo {\n")
15299 (write _test-input-stream " var y: (handle int)\n")
15300 (write _test-input-stream " populate-stream y, 3\n")
15301 (write _test-input-stream "}\n")
15303 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15304 # registers except esp clobbered at this point
15306 89/<- %edx 4/r32/esp
15307 (flush _test-output-buffered-file)
15308 (flush _test-error-buffered-file)
15309 #? # dump _test-error-stream {{{
15311 #? (write-stream 2 _test-error-stream)
15313 #? (rewind-stream _test-error-stream)
15316 (check-stream-equal _test-output-stream "" "F - test-populate-stream-non-addr: output must be empty")
15317 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate-stream: first inout 'y' must have type (addr handle stream ...)" "F - test-populate-stream-non-addr: error message")
15318 # check that stop(1) was called
15319 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-non-addr: exit status")
15320 # don't restore from ebp
15321 81 0/subop/add %esp 8/imm32
15326 test-populate-stream-non-addr-handle:
15329 89/<- %ebp 4/r32/esp
15331 (clear-stream _test-input-stream)
15332 (clear-stream $_test-input-buffered-file->buffer)
15333 (clear-stream _test-output-stream)
15334 (clear-stream $_test-output-buffered-file->buffer)
15335 (clear-stream _test-error-stream)
15336 (clear-stream $_test-error-buffered-file->buffer)
15337 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15340 89/<- %edx 4/r32/esp
15341 (tailor-exit-descriptor %edx 0x10)
15343 (write _test-input-stream "fn foo {\n")
15344 (write _test-input-stream " var y/ecx: (addr int) <- copy 0\n")
15345 (write _test-input-stream " populate-stream y, 3\n")
15346 (write _test-input-stream "}\n")
15348 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15349 # registers except esp clobbered at this point
15351 89/<- %edx 4/r32/esp
15352 (flush _test-output-buffered-file)
15353 (flush _test-error-buffered-file)
15354 #? # dump _test-error-stream {{{
15356 #? (write-stream 2 _test-error-stream)
15358 #? (rewind-stream _test-error-stream)
15361 (check-stream-equal _test-output-stream "" "F - test-populate-stream-non-addr-handle: output should be empty")
15362 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate-stream: first inout 'y' must have type (addr handle stream ...)" "F - test-populate-stream-non-addr-handle: error message")
15363 # check that stop(1) was called
15364 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-non-addr-handle: exit status")
15365 # don't restore from ebp
15366 81 0/subop/add %esp 8/imm32
15371 test-populate-stream-non-addr-handle-stream:
15374 89/<- %ebp 4/r32/esp
15376 (clear-stream _test-input-stream)
15377 (clear-stream $_test-input-buffered-file->buffer)
15378 (clear-stream _test-output-stream)
15379 (clear-stream $_test-output-buffered-file->buffer)
15380 (clear-stream _test-error-stream)
15381 (clear-stream $_test-error-buffered-file->buffer)
15382 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15385 89/<- %edx 4/r32/esp
15386 (tailor-exit-descriptor %edx 0x10)
15388 (write _test-input-stream "fn foo {\n")
15389 (write _test-input-stream " var y/ecx: (addr handle int) <- copy 0\n")
15390 (write _test-input-stream " populate-stream y, 3\n")
15391 (write _test-input-stream "}\n")
15393 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15394 # registers except esp clobbered at this point
15396 89/<- %edx 4/r32/esp
15397 (flush _test-output-buffered-file)
15398 (flush _test-error-buffered-file)
15399 #? # dump _test-error-stream {{{
15401 #? (write-stream 2 _test-error-stream)
15403 #? (rewind-stream _test-error-stream)
15406 (check-stream-equal _test-output-stream "" "F - test-populate-stream-non-addr-handle-stream: output should be empty")
15407 (check-next-stream-line-equal _test-error-stream "fn foo: stmt populate-stream: first inout 'y' must have type (addr handle stream ...)" "F - test-populate-stream-non-addr-handle-stream: error message")
15408 # check that stop(1) was called
15409 (check-ints-equal *(edx+4) 2 "F - test-populate-stream-non-addr-handle-stream: exit status")
15410 # don't restore from ebp
15411 81 0/subop/add %esp 8/imm32
15416 test-populate-stream-deref-address:
15419 89/<- %ebp 4/r32/esp
15421 (clear-stream _test-input-stream)
15422 (clear-stream $_test-input-buffered-file->buffer)
15423 (clear-stream _test-output-stream)
15424 (clear-stream $_test-output-buffered-file->buffer)
15426 (write _test-input-stream "fn foo {\n")
15427 (write _test-input-stream " var y/ecx: (addr addr handle stream int) <- copy 0\n")
15428 (write _test-input-stream " populate-stream *y, 3\n")
15429 (write _test-input-stream "}\n")
15431 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
15432 (flush _test-output-buffered-file)
15438 test-convert-with-no-inout:
15441 89/<- %ebp 4/r32/esp
15443 (clear-stream _test-input-stream)
15444 (clear-stream $_test-input-buffered-file->buffer)
15445 (clear-stream _test-output-stream)
15446 (clear-stream $_test-output-buffered-file->buffer)
15447 (clear-stream _test-error-stream)
15448 (clear-stream $_test-error-buffered-file->buffer)
15449 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15452 89/<- %edx 4/r32/esp
15453 (tailor-exit-descriptor %edx 0x10)
15455 (write _test-input-stream "fn foo {\n")
15456 (write _test-input-stream " var x/eax: int <- convert\n")
15457 (write _test-input-stream "}\n")
15459 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15460 # registers except esp clobbered at this point
15462 89/<- %edx 4/r32/esp
15463 (flush _test-output-buffered-file)
15464 (flush _test-error-buffered-file)
15465 #? # dump _test-error-stream {{{
15467 #? (write-stream 2 _test-error-stream)
15469 #? (rewind-stream _test-error-stream)
15472 (check-stream-equal _test-output-stream "" "F - test-convert-with-no-inout: output should be empty")
15473 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'convert' expects an inout" "F - test-convert-with-no-inout: error message")
15474 # check that stop(1) was called
15475 (check-ints-equal *(edx+4) 2 "F - test-convert-with-no-inout: exit status")
15476 # don't restore from ebp
15477 81 0/subop/add %esp 8/imm32
15482 test-convert-with-multiple-inouts:
15485 89/<- %ebp 4/r32/esp
15487 (clear-stream _test-input-stream)
15488 (clear-stream $_test-input-buffered-file->buffer)
15489 (clear-stream _test-output-stream)
15490 (clear-stream $_test-output-buffered-file->buffer)
15491 (clear-stream _test-error-stream)
15492 (clear-stream $_test-error-buffered-file->buffer)
15493 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15496 89/<- %edx 4/r32/esp
15497 (tailor-exit-descriptor %edx 0x10)
15499 (write _test-input-stream "fn foo {\n")
15500 (write _test-input-stream " var x/eax: int <- convert 0, 0\n")
15501 (write _test-input-stream "}\n")
15503 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15504 # registers except esp clobbered at this point
15506 89/<- %edx 4/r32/esp
15507 (flush _test-output-buffered-file)
15508 (flush _test-error-buffered-file)
15509 #? # dump _test-error-stream {{{
15511 #? (write-stream 2 _test-error-stream)
15513 #? (rewind-stream _test-error-stream)
15516 (check-stream-equal _test-output-stream "" "F - test-convert-with-multiple-inouts: output should be empty")
15517 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'convert' must have just one inout" "F - test-convert-with-multiple-inouts: error message")
15518 # check that stop(1) was called
15519 (check-ints-equal *(edx+4) 2 "F - test-convert-with-multiple-inouts: exit status")
15520 # don't restore from ebp
15521 81 0/subop/add %esp 8/imm32
15526 test-convert-with-no-output:
15529 89/<- %ebp 4/r32/esp
15531 (clear-stream _test-input-stream)
15532 (clear-stream $_test-input-buffered-file->buffer)
15533 (clear-stream _test-output-stream)
15534 (clear-stream $_test-output-buffered-file->buffer)
15535 (clear-stream _test-error-stream)
15536 (clear-stream $_test-error-buffered-file->buffer)
15537 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15540 89/<- %edx 4/r32/esp
15541 (tailor-exit-descriptor %edx 0x10)
15543 (write _test-input-stream "fn foo {\n")
15544 (write _test-input-stream " convert 0\n")
15545 (write _test-input-stream "}\n")
15547 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15548 # registers except esp clobbered at this point
15550 89/<- %edx 4/r32/esp
15551 (flush _test-output-buffered-file)
15552 (flush _test-error-buffered-file)
15553 #? # dump _test-error-stream {{{
15555 #? (write-stream 2 _test-error-stream)
15557 #? (rewind-stream _test-error-stream)
15560 (check-stream-equal _test-output-stream "" "F - test-convert-with-no-output: output should be empty")
15561 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'convert' expects an output" "F - test-convert-with-no-output: error message")
15562 # check that stop(1) was called
15563 (check-ints-equal *(edx+4) 2 "F - test-convert-with-no-output: exit status")
15564 # don't restore from ebp
15565 81 0/subop/add %esp 8/imm32
15570 test-convert-with-multiple-outputs:
15573 89/<- %ebp 4/r32/esp
15575 (clear-stream _test-input-stream)
15576 (clear-stream $_test-input-buffered-file->buffer)
15577 (clear-stream _test-output-stream)
15578 (clear-stream $_test-output-buffered-file->buffer)
15579 (clear-stream _test-error-stream)
15580 (clear-stream $_test-error-buffered-file->buffer)
15581 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15584 89/<- %edx 4/r32/esp
15585 (tailor-exit-descriptor %edx 0x10)
15587 (write _test-input-stream "fn foo {\n")
15588 (write _test-input-stream " var x/eax: int <- copy 0\n")
15589 (write _test-input-stream " var y/ecx: int <- copy 0\n")
15590 (write _test-input-stream " x, y <- convert 0\n")
15591 (write _test-input-stream "}\n")
15593 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15594 # registers except esp clobbered at this point
15596 89/<- %edx 4/r32/esp
15597 (flush _test-output-buffered-file)
15598 (flush _test-error-buffered-file)
15599 #? # dump _test-error-stream {{{
15601 #? (write-stream 2 _test-error-stream)
15603 #? (rewind-stream _test-error-stream)
15606 (check-stream-equal _test-output-stream "" "F - test-convert-with-multiple-outputs: output should be empty")
15607 (check-next-stream-line-equal _test-error-stream "fn foo: stmt 'convert' must have just one output" "F - test-convert-with-multiple-outputs: error message")
15608 # check that stop(1) was called
15609 (check-ints-equal *(edx+4) 2 "F - test-convert-with-multiple-outputs: exit status")
15610 # don't restore from ebp
15611 81 0/subop/add %esp 8/imm32
15616 test-convert-deref-address:
15619 89/<- %ebp 4/r32/esp
15621 (clear-stream _test-input-stream)
15622 (clear-stream $_test-input-buffered-file->buffer)
15623 (clear-stream _test-output-stream)
15624 (clear-stream $_test-output-buffered-file->buffer)
15626 (write _test-input-stream "fn foo {\n")
15627 (write _test-input-stream " var x/eax: (addr int) <- copy 0\n")
15628 (write _test-input-stream " var y/xmm4: float <- convert *x\n")
15629 (write _test-input-stream "}\n")
15631 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
15632 (flush _test-output-buffered-file)
15638 test-convert-to-non-register:
15641 89/<- %ebp 4/r32/esp
15643 (clear-stream _test-input-stream)
15644 (clear-stream $_test-input-buffered-file->buffer)
15645 (clear-stream _test-output-stream)
15646 (clear-stream $_test-output-buffered-file->buffer)
15647 (clear-stream _test-error-stream)
15648 (clear-stream $_test-error-buffered-file->buffer)
15649 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15652 89/<- %edx 4/r32/esp
15653 (tailor-exit-descriptor %edx 0x10)
15655 (write _test-input-stream "fn foo {\n")
15656 (write _test-input-stream " var x: float\n")
15657 (write _test-input-stream " var y: int\n")
15658 (write _test-input-stream " x <- convert y\n")
15659 (write _test-input-stream "}\n")
15661 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15662 # registers except esp clobbered at this point
15664 89/<- %edx 4/r32/esp
15665 (flush _test-output-buffered-file)
15666 (flush _test-error-buffered-file)
15667 #? # dump _test-error-stream {{{
15669 #? (write-stream 2 _test-error-stream)
15671 #? (rewind-stream _test-error-stream)
15674 (check-stream-equal _test-output-stream "" "F - test-convert-to-non-register: output should be empty")
15675 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: output 'x' not in a register" "F - test-convert-to-non-register: error message")
15676 # check that stop(1) was called
15677 (check-ints-equal *(edx+4) 2 "F - test-convert-to-non-register: exit status")
15678 # don't restore from ebp
15679 81 0/subop/add %esp 8/imm32
15684 test-convert-invalid-inout-type:
15687 89/<- %ebp 4/r32/esp
15689 (clear-stream _test-input-stream)
15690 (clear-stream $_test-input-buffered-file->buffer)
15691 (clear-stream _test-output-stream)
15692 (clear-stream $_test-output-buffered-file->buffer)
15693 (clear-stream _test-error-stream)
15694 (clear-stream $_test-error-buffered-file->buffer)
15695 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15698 89/<- %edx 4/r32/esp
15699 (tailor-exit-descriptor %edx 0x10)
15701 (write _test-input-stream "fn foo {\n")
15702 (write _test-input-stream " var x: boolean\n")
15703 (write _test-input-stream " var y/xmm1: float <- convert x\n")
15704 (write _test-input-stream "}\n")
15706 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15707 # registers except esp clobbered at this point
15709 89/<- %edx 4/r32/esp
15710 (flush _test-output-buffered-file)
15711 (flush _test-error-buffered-file)
15712 #? # dump _test-error-stream {{{
15714 #? (write-stream 2 _test-error-stream)
15716 #? (rewind-stream _test-error-stream)
15719 (check-stream-equal _test-output-stream "" "F - test-convert-invalid-inout-type: output should be empty")
15720 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: inout 'x' must be an int or float" "F - test-convert-invalid-inout-type: error message")
15721 # check that stop(1) was called
15722 (check-ints-equal *(edx+4) 2 "F - test-convert-invalid-inout-type: exit status")
15723 # don't restore from ebp
15724 81 0/subop/add %esp 8/imm32
15729 test-convert-invalid-output-type:
15732 89/<- %ebp 4/r32/esp
15734 (clear-stream _test-input-stream)
15735 (clear-stream $_test-input-buffered-file->buffer)
15736 (clear-stream _test-output-stream)
15737 (clear-stream $_test-output-buffered-file->buffer)
15738 (clear-stream _test-error-stream)
15739 (clear-stream $_test-error-buffered-file->buffer)
15740 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15743 89/<- %edx 4/r32/esp
15744 (tailor-exit-descriptor %edx 0x10)
15746 (write _test-input-stream "fn foo {\n")
15747 (write _test-input-stream " var x: float\n")
15748 (write _test-input-stream " var y/eax: boolean <- convert x\n")
15749 (write _test-input-stream "}\n")
15751 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15752 # registers except esp clobbered at this point
15754 89/<- %edx 4/r32/esp
15755 (flush _test-output-buffered-file)
15756 (flush _test-error-buffered-file)
15757 #? # dump _test-error-stream {{{
15759 #? (write-stream 2 _test-error-stream)
15761 #? (rewind-stream _test-error-stream)
15764 (check-stream-equal _test-output-stream "" "F - test-convert-invalid-output-type: output should be empty")
15765 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: output 'y' must be an int or float" "F - test-convert-invalid-output-type: error message")
15766 # check that stop(1) was called
15767 (check-ints-equal *(edx+4) 2 "F - test-convert-invalid-output-type: exit status")
15768 # don't restore from ebp
15769 81 0/subop/add %esp 8/imm32
15774 test-convert-int-to-int:
15777 89/<- %ebp 4/r32/esp
15779 (clear-stream _test-input-stream)
15780 (clear-stream $_test-input-buffered-file->buffer)
15781 (clear-stream _test-output-stream)
15782 (clear-stream $_test-output-buffered-file->buffer)
15783 (clear-stream _test-error-stream)
15784 (clear-stream $_test-error-buffered-file->buffer)
15785 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15788 89/<- %edx 4/r32/esp
15789 (tailor-exit-descriptor %edx 0x10)
15791 (write _test-input-stream "fn foo {\n")
15792 (write _test-input-stream " var x: int\n")
15793 (write _test-input-stream " var y/eax: int <- convert x\n")
15794 (write _test-input-stream "}\n")
15796 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15797 # registers except esp clobbered at this point
15799 89/<- %edx 4/r32/esp
15800 (flush _test-output-buffered-file)
15801 (flush _test-error-buffered-file)
15802 #? # dump _test-error-stream {{{
15804 #? (write-stream 2 _test-error-stream)
15806 #? (rewind-stream _test-error-stream)
15809 (check-stream-equal _test-output-stream "" "F - test-convert-int-to-int: output should be empty")
15810 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: no need to convert int to int" "F - test-convert-int-to-int: error message")
15811 # check that stop(1) was called
15812 (check-ints-equal *(edx+4) 2 "F - test-convert-int-to-int: exit status")
15813 # don't restore from ebp
15814 81 0/subop/add %esp 8/imm32
15819 test-convert-float-to-float:
15822 89/<- %ebp 4/r32/esp
15824 (clear-stream _test-input-stream)
15825 (clear-stream $_test-input-buffered-file->buffer)
15826 (clear-stream _test-output-stream)
15827 (clear-stream $_test-output-buffered-file->buffer)
15828 (clear-stream _test-error-stream)
15829 (clear-stream $_test-error-buffered-file->buffer)
15830 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
15833 89/<- %edx 4/r32/esp
15834 (tailor-exit-descriptor %edx 0x10)
15836 (write _test-input-stream "fn foo {\n")
15837 (write _test-input-stream " var x: float\n")
15838 (write _test-input-stream " var y/xmm6: float <- convert x\n")
15839 (write _test-input-stream "}\n")
15841 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
15842 # registers except esp clobbered at this point
15844 89/<- %edx 4/r32/esp
15845 (flush _test-output-buffered-file)
15846 (flush _test-error-buffered-file)
15847 #? # dump _test-error-stream {{{
15849 #? (write-stream 2 _test-error-stream)
15851 #? (rewind-stream _test-error-stream)
15854 (check-stream-equal _test-output-stream "" "F - test-convert-float-to-float: output should be empty")
15855 (check-next-stream-line-equal _test-error-stream "fn foo: stmt convert: no need to convert float to float" "F - test-convert-float-to-float: error message")
15856 # check that stop(1) was called
15857 (check-ints-equal *(edx+4) 2 "F - test-convert-float-to-float: exit status")
15858 # don't restore from ebp
15859 81 0/subop/add %esp 8/imm32
15864 #######################################################
15866 #######################################################
15870 # Global state added to each var record when parsing a function
15871 Next-block-index: # (addr int)
15874 Curr-block-depth: # (addr int)
15879 parse-mu: # in: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor)
15881 # var curr-function: (addr handle function) = Program->functions
15882 # var curr-signature: (addr handle function) = Program->signatures
15883 # var curr-type: (addr handle typeinfo) = Program->types
15884 # var line: (stream byte 512)
15885 # var word-slice: slice
15886 # while true # line loop
15887 # clear-stream(line)
15888 # read-line-buffered(in, line)
15889 # if (line->write == 0) break # end of file
15890 # word-slice = next-mu-token(line)
15891 # if slice-empty?(word-slice) # end of line
15893 # else if slice-starts-with?(word-slice, "#") # comment
15894 # continue # end of line
15895 # else if slice-equal?(word-slice, "fn")
15896 # var new-function: (handle function) = allocate(function)
15897 # var vars: (stack live-var 256)
15898 # populate-mu-function-header(line, new-function, vars)
15899 # populate-mu-function-body(in, new-function, vars)
15900 # assert(vars->top == 0)
15901 # *curr-function = new-function
15902 # curr-function = &new-function->next
15903 # else if slice-equal?(word-slice, "sig")
15904 # var new-function: (handle function) = allocate(function)
15905 # populate-mu-function-signature(line, new-function)
15906 # *curr-signature = new-function
15907 # curr-signature = &new-function->next
15908 # else if slice-equal?(word-slice, "type")
15909 # word-slice = next-mu-token(line)
15910 # type-id = pos-or-insert-slice(Type-id, word-slice)
15911 # var new-type: (handle typeinfo) = find-or-create-typeinfo(type-id)
15912 # assert(next-word(line) == "{")
15913 # populate-mu-type(in, new-type)
15919 89/<- %ebp 4/r32/esp
15920 # var curr-signature: (addr handle function) at *(ebp-4)
15921 68/push _Program-signatures/imm32
15929 # var line/ecx: (stream byte 512)
15930 81 5/subop/subtract %esp 0x200/imm32
15931 68/push 0x200/imm32/size
15932 68/push 0/imm32/read
15933 68/push 0/imm32/write
15934 89/<- %ecx 4/r32/esp
15935 # var word-slice/edx: slice
15936 68/push 0/imm32/end
15937 68/push 0/imm32/start
15938 89/<- %edx 4/r32/esp
15939 # var curr-function/edi: (addr handle function)
15940 bf/copy-to-edi _Program-functions/imm32
15941 # var vars/ebx: (stack live-var 256)
15942 81 5/subop/subtract %esp 0xc00/imm32
15943 68/push 0xc00/imm32/size
15944 68/push 0/imm32/top
15945 89/<- %ebx 4/r32/esp
15947 $parse-mu:line-loop:
15948 (clear-stream %ecx)
15949 (read-line-buffered *(ebp+8) %ecx)
15950 # if (line->write == 0) break
15951 81 7/subop/compare *ecx 0/imm32
15952 0f 84/jump-if-= break/disp32
15954 #? (write 2 "parse-mu: ^")
15955 #? (write-stream 2 %ecx)
15957 #? (rewind-stream %ecx)
15959 (next-mu-token %ecx %edx)
15960 # if slice-empty?(word-slice) continue
15961 (slice-empty? %edx) # => eax
15962 3d/compare-eax-and 0/imm32/false
15963 0f 85/jump-if-!= loop/disp32
15964 # if (*word-slice->start == "#") continue
15965 # . eax = *word-slice->start
15966 8b/-> *edx 0/r32/eax
15967 8a/copy-byte *eax 0/r32/AL
15968 25/and-eax-with 0xff/imm32
15969 # . if (eax == '#') continue
15970 3d/compare-eax-and 0x23/imm32/hash
15971 0f 84/jump-if-= loop/disp32
15972 # if (slice-equal?(word-slice, "fn")) parse a function
15975 (slice-equal? %edx "fn") # => eax
15976 3d/compare-eax-and 0/imm32/false
15977 0f 84/jump-if-= break/disp32
15978 # var new-function/esi: (handle function)
15981 89/<- %esi 4/r32/esp
15982 # populate-mu-function(line, in, vars, new-function)
15983 (allocate Heap *Function-size %esi)
15984 # var new-function-addr/eax: (addr function)
15985 (lookup *esi *(esi+4)) # => eax
15989 (populate-mu-function-header %ecx %eax %ebx *(ebp+0xc) *(ebp+0x10))
15990 (populate-mu-function-body *(ebp+8) %eax %ebx *(ebp+0xc) *(ebp+0x10))
15991 # *curr-function = new-function
15992 8b/-> *esi 0/r32/eax
15993 89/<- *edi 0/r32/eax
15994 8b/-> *(esi+4) 0/r32/eax
15995 89/<- *(edi+4) 0/r32/eax
15996 # curr-function = &new-function->next
15997 # . var tmp/eax: (addr function) = lookup(new-function)
15998 (lookup *esi *(esi+4)) # => eax
15999 # . curr-function = &tmp->next
16000 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next
16001 # reclaim new-function
16002 81 0/subop/add %esp 8/imm32
16004 e9/jump $parse-mu:line-loop/disp32
16006 # if (slice-equal?(word-slice, "sig")) parse a function signature
16007 # Function signatures are for providing types to SubX functions.
16010 (slice-equal? %edx "sig") # => eax
16011 3d/compare-eax-and 0/imm32/false
16012 0f 84/jump-if-= break/disp32
16013 # edi = curr-function
16015 8b/-> *(ebp-4) 7/r32/edi
16016 # var new-function/esi: (handle function)
16019 89/<- %esi 4/r32/esp
16020 # populate-mu-function(line, in, vars, new-function)
16021 (allocate Heap *Function-size %esi)
16022 # var new-function-addr/eax: (addr function)
16023 (lookup *esi *(esi+4)) # => eax
16025 (populate-mu-function-signature %ecx %eax *(ebp+0xc) *(ebp+0x10))
16026 # *curr-signature = new-function
16027 8b/-> *esi 0/r32/eax
16028 89/<- *edi 0/r32/eax
16029 8b/-> *(esi+4) 0/r32/eax
16030 89/<- *(edi+4) 0/r32/eax
16031 # curr-signature = &new-function->next
16032 # . var tmp/eax: (addr function) = lookup(new-function)
16033 (lookup *esi *(esi+4)) # => eax
16034 # . curr-function = &tmp->next
16035 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next
16036 # reclaim new-function
16037 81 0/subop/add %esp 8/imm32
16038 # save curr-function
16039 89/<- *(ebp-4) 7/r32/edi
16043 e9/jump $parse-mu:line-loop/disp32
16045 # if (slice-equal?(word-slice, "type")) parse a type (struct/record) definition
16048 (slice-equal? %edx "type") # => eax
16049 3d/compare-eax-and 0/imm32
16050 0f 84/jump-if-= break/disp32
16051 (next-mu-token %ecx %edx)
16052 # var type-id/eax: int
16053 (pos-or-insert-slice Type-id %edx) # => eax
16056 # var new-type/ecx: (handle typeinfo)
16059 89/<- %ecx 4/r32/esp
16060 (find-or-create-typeinfo %eax %ecx)
16062 (lookup *ecx *(ecx+4)) # => eax
16063 # TODO: ensure that 'line' has nothing else but '{'
16064 #? (dump-typeinfos "=== aaa\n")
16065 (populate-mu-type *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) # => eax
16066 #? (dump-typeinfos "=== zzz\n")
16068 81 0/subop/add %esp 8/imm32
16071 e9/jump $parse-mu:line-loop/disp32
16074 e9/jump $parse-mu:error1/disp32
16078 81 0/subop/add %esp 0x20c/imm32 # line
16079 81 0/subop/add %esp 0xc08/imm32 # vars
16080 81 0/subop/add %esp 8/imm32
16081 # . restore registers
16089 81 0/subop/add %esp 4/imm32
16091 89/<- %esp 5/r32/ebp
16096 # error("unexpected top-level command: " word-slice "\n")
16097 (write-buffered *(ebp+0xc) "unexpected top-level command: ")
16098 (write-slice-buffered *(ebp+0xc) %edx)
16099 (write-buffered *(ebp+0xc) "\n")
16101 (stop *(ebp+0x10) 1)
16105 # error(vars->top " vars not reclaimed after fn '" new-function->name "'\n")
16106 (write-int32-hex-buffered *(ebp+0xc) *ebx)
16107 (write-buffered *(ebp+0xc) " vars not reclaimed after fn '")
16108 (write-slice-buffered *(ebp+0xc) *eax) # Function-name
16109 (write-buffered *(ebp+0xc) "'\n")
16111 (stop *(ebp+0x10) 1)
16114 # scenarios considered:
16115 # ✗ fn foo # no block
16122 # ✓ fn foo x: int {
16123 # ✓ fn foo x: int {
16124 # ✓ fn foo x: int -> _/eax: int {
16126 # disallow outputs of type `(... addr ...)`
16127 # disallow inputs of type `(... addr ... addr ...)`
16128 populate-mu-function-header: # first-line: (addr stream byte), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor)
16130 # var word-slice: slice
16131 # next-mu-token(first-line, word-slice)
16132 # if slice-empty?(word-slice) abort
16133 # assert(word-slice not in '{' '}' '->')
16134 # out->name = slice-to-string(word-slice)
16137 # word-slice = next-mu-token(first-line)
16138 # if slice-empty?(word-slice) abort
16139 # if (word-slice == '{') goto done
16140 # if (word-slice == '->') break
16141 # assert(word-slice != '}')
16142 # var v: (handle var) = parse-var-with-type(word-slice, first-line)
16143 # assert(v->register == null)
16144 # # v->block-depth is implicitly 0
16145 # out->inouts = append(v, out->inouts)
16146 # push(vars, {v, false})
16149 # word-slice = next-mu-token(first-line)
16150 # if slice-empty?(word-slice) abort
16151 # if (word-slice == '{') break
16152 # assert(word-slice not in '}' '->')
16153 # var v: (handle var) = parse-var-with-type(word-slice, first-line)
16154 # assert(v->register != null)
16155 # assert(v->name == "_")
16156 # out->outputs = append(v, out->outputs)
16161 89/<- %ebp 4/r32/esp
16169 8b/-> *(ebp+0xc) 7/r32/edi
16170 # var word-slice/ecx: slice
16171 68/push 0/imm32/end
16172 68/push 0/imm32/start
16173 89/<- %ecx 4/r32/esp
16174 # var v/ebx: (handle var)
16177 89/<- %ebx 4/r32/esp
16178 # read function name
16179 (next-mu-token *(ebp+8) %ecx)
16181 # if slice-empty?(word-slice) abort
16182 (slice-empty? %ecx) # => eax
16183 3d/compare-eax-and 0/imm32/false
16184 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32
16185 # if (word-slice == '{') abort
16186 (slice-equal? %ecx "{") # => eax
16187 3d/compare-eax-and 0/imm32/false
16188 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32
16189 # if (word-slice == '->') abort
16190 (slice-equal? %ecx "->") # => eax
16191 3d/compare-eax-and 0/imm32/false
16192 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32
16193 # if (word-slice == '}') abort
16194 (slice-equal? %ecx "}") # => eax
16195 3d/compare-eax-and 0/imm32/false
16196 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32
16197 # if word-slice already defined, abort
16198 (function-exists? %ecx) # => eax
16199 3d/compare-eax-and 0/imm32/false
16200 0f 85/jump-if-!= $populate-mu-function-header:error-duplicate/disp32
16202 (slice-starts-with? %ecx "break") # => eax
16203 3d/compare-eax-and 0/imm32/false
16204 0f 85/jump-if-!= $populate-mu-function-header:error-break/disp32
16205 (slice-starts-with? %ecx "loop") # => eax
16206 3d/compare-eax-and 0/imm32/false
16207 0f 85/jump-if-!= $populate-mu-function-header:error-loop/disp32
16208 (slice-equal? %ecx "lookup") # => eax
16209 3d/compare-eax-and 0/imm32/false
16210 0f 85/jump-if-!= $populate-mu-function-header:error-lookup/disp32
16211 # save function name
16212 (slice-to-string Heap %ecx %edi) # Function-name
16213 # save function inouts
16215 $populate-mu-function-header:check-for-inout:
16216 (next-mu-token *(ebp+8) %ecx)
16217 # if slice-empty?(word-slice) abort
16218 (slice-empty? %ecx) # => eax
16219 3d/compare-eax-and 0/imm32/false
16220 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32
16221 # if (word-slice == '{') goto done
16222 (slice-equal? %ecx "{") # => eax
16223 3d/compare-eax-and 0/imm32/false
16224 0f 85/jump-if-!= $populate-mu-function-header:done/disp32
16225 # if (word-slice == '->') break
16226 (slice-equal? %ecx "->") # => eax
16227 3d/compare-eax-and 0/imm32/false
16228 0f 85/jump-if-!= break/disp32
16229 # if (word-slice == '}') abort
16230 (slice-equal? %ecx "}") # => eax
16231 3d/compare-eax-and 0/imm32/false
16232 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32
16233 # v = parse-var-with-type(word-slice, first-line)
16234 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16235 (parse-var-with-type %ecx *(ebp+8) %ebx %eax *(ebp+0x14) *(ebp+0x18))
16236 # if (v->register != null) abort
16237 # . eax: (addr var) = lookup(v)
16238 (lookup *ebx *(ebx+4)) # => eax
16239 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register
16240 0f 85/jump-if-!= $populate-mu-function-header:error2/disp32
16241 # if function name is not "main"
16242 # and v->type contains an 'addr' anywhere except the start, abort
16244 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16245 (string-equal? %eax "main") # => eax
16246 3d/compare-eax-and 0/imm32/false
16247 75/jump-if-!= break/disp8
16248 (lookup *ebx *(ebx+4)) # => eax
16249 (addr-payload-contains-addr? %eax) # => eax
16250 3d/compare-eax-and 0/imm32/false
16251 0f 85/jump-if-!= $populate-mu-function-header:error-nested-addr-inout/disp32
16253 # v->block-depth is implicitly 0
16255 # out->inouts = append(v, out->inouts)
16256 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts
16257 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts
16258 # push(vars, {v, false})
16259 (push *(ebp+0x10) *ebx)
16260 (push *(ebp+0x10) *(ebx+4))
16261 (push *(ebp+0x10) 0) # false
16263 e9/jump loop/disp32
16265 # save function outputs
16267 $populate-mu-function-header:check-for-out:
16268 (next-mu-token *(ebp+8) %ecx)
16269 # if slice-empty?(word-slice) abort
16270 (slice-empty? %ecx) # => eax
16271 3d/compare-eax-and 0/imm32/false
16272 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32
16273 # if (word-slice == '{') break
16274 (slice-equal? %ecx "{") # => eax
16275 3d/compare-eax-and 0/imm32/false
16276 0f 85/jump-if-!= break/disp32
16277 # if (word-slice == '->') abort
16278 (slice-equal? %ecx "->") # => eax
16279 3d/compare-eax-and 0/imm32/false
16280 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32
16281 # if (word-slice == '}') abort
16282 (slice-equal? %ecx "}") # => eax
16283 3d/compare-eax-and 0/imm32/false
16284 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32
16285 # v = parse-var-with-type(word-slice, first-line)
16286 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16287 (parse-var-with-type %ecx *(ebp+8) %ebx %eax *(ebp+0x14) *(ebp+0x18))
16288 # assert(var->register != null)
16289 # . eax: (addr var) = lookup(v)
16290 (lookup *ebx *(ebx+4)) # => eax
16291 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register
16292 0f 84/jump-if-= $populate-mu-function-header:error3/disp32
16293 # if (var->name != "_") abort
16294 (lookup *eax *(eax+4)) # Var-name Var-name => eax
16295 (string-equal? %eax "_") # => eax
16296 3d/compare-eax-and 0/imm32/false
16297 0f 84/jump-if-= $populate-mu-function-header:error4/disp32
16298 # if v->type is an addr, abort
16299 (lookup *ebx *(ebx+4)) # => eax
16300 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
16301 (mu-addr-type? %eax) # => eax
16302 3d/compare-eax-and 0/imm32/false
16303 0f 85/jump-if-!= $populate-mu-function-header:error-addr-output/disp32
16304 # out->outputs = append(v, out->outputs)
16305 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs
16306 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs
16308 e9/jump loop/disp32
16310 $populate-mu-function-header:done:
16311 (check-no-tokens-left *(ebp+8))
16312 $populate-mu-function-header:end:
16314 81 0/subop/add %esp 0x10/imm32
16315 # . restore registers
16322 89/<- %esp 5/r32/ebp
16326 $populate-mu-function-header:error1:
16327 # error("function header not in form 'fn <name> {'")
16328 (write-buffered *(ebp+0x14) "function header not in form 'fn <name> [inouts] [-> outputs] {' -- '")
16329 (flush *(ebp+0x14))
16330 (rewind-stream *(ebp+8))
16331 (write-stream-data *(ebp+0x14) *(ebp+8))
16332 (write-buffered *(ebp+0x14) "'\n")
16333 (flush *(ebp+0x14))
16334 (stop *(ebp+0x18) 1)
16337 $populate-mu-function-header:error2:
16338 # error("fn " fn ": function inout '" var "' cannot be in a register")
16339 (write-buffered *(ebp+0x14) "fn ")
16341 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16342 (write-buffered *(ebp+0x14) %eax)
16344 (write-buffered *(ebp+0x14) ": function inout '")
16345 (lookup *eax *(eax+4)) # Var-name Var-name => eax
16346 (write-buffered *(ebp+0x14) %eax)
16347 (write-buffered *(ebp+0x14) "' cannot be in a register")
16348 (flush *(ebp+0x14))
16349 (stop *(ebp+0x18) 1)
16352 $populate-mu-function-header:error3:
16353 # error("fn " fn ": function output '" var "' must be in a register")
16354 (write-buffered *(ebp+0x14) "fn ")
16356 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16357 (write-buffered *(ebp+0x14) %eax)
16359 (write-buffered *(ebp+0x14) ": function output '")
16360 (lookup *ebx *(ebx+4)) # => eax
16361 (lookup *eax *(eax+4)) # Var-name Var-name => eax
16362 (write-buffered *(ebp+0x14) %eax)
16363 (write-buffered *(ebp+0x14) "' must be in a register, in instruction '")
16364 (rewind-stream *(ebp+8))
16365 (write-stream-data *(ebp+0x14) *(ebp+8))
16366 (write-buffered *(ebp+0x14) "'\n")
16367 (flush *(ebp+0x14))
16368 (stop *(ebp+0x18) 1)
16371 $populate-mu-function-header:error4:
16372 # error("fn " fn ": function outputs cannot be named; rename '" var "' in the header to '_'")
16373 (write-buffered *(ebp+0x14) "fn ")
16375 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16376 (write-buffered *(ebp+0x14) %eax)
16378 (write-buffered *(ebp+0x14) ": function outputs cannot be named; rename '")
16379 (lookup *ebx *(ebx+4)) # => eax
16380 (lookup *eax *(eax+4)) # Var-name Var-name => eax
16381 (write-buffered *(ebp+0x14) %eax)
16382 (write-buffered *(ebp+0x14) "' in the header to '_'\n")
16383 (flush *(ebp+0x14))
16384 (stop *(ebp+0x18) 1)
16387 $populate-mu-function-header:error-duplicate:
16388 (write-buffered *(ebp+0x14) "fn ")
16389 (write-slice-buffered *(ebp+0x14) %ecx)
16390 (write-buffered *(ebp+0x14) " defined more than once\n")
16391 (flush *(ebp+0x14))
16392 (stop *(ebp+0x18) 1)
16395 $populate-mu-function-header:error-break:
16396 (write-buffered *(ebp+0x14) "Sorry, I've reserved all function names starting with 'break' for now. Please contact mu@akkartik.com.\n")
16397 (flush *(ebp+0x14))
16398 (stop *(ebp+0x18) 1)
16401 $populate-mu-function-header:error-loop:
16402 (write-buffered *(ebp+0x14) "Sorry, I've reserved all function names starting with 'loop' for now. Please contact mu@akkartik.com.\n")
16403 (flush *(ebp+0x14))
16404 (stop *(ebp+0x18) 1)
16407 $populate-mu-function-header:error-lookup:
16408 (write-buffered *(ebp+0x14) "cannot define a function called 'lookup'\n")
16409 (flush *(ebp+0x14))
16410 (stop *(ebp+0x18) 1)
16413 $populate-mu-function-header:error-addr-output:
16414 # error("fn " fn ": output cannot have an addr type; that could allow unsafe addresses to escape the function")
16415 (write-buffered *(ebp+0x14) "fn ")
16417 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16418 (write-buffered *(ebp+0x14) %eax)
16420 (write-buffered *(ebp+0x14) ": output cannot have an addr type; that could allow unsafe addresses to escape the function\n")
16421 (flush *(ebp+0x14))
16422 (stop *(ebp+0x18) 1)
16425 $populate-mu-function-header:error-nested-addr-inout:
16426 # error("fn " fn ": inout '" var "' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function")
16427 (write-buffered *(ebp+0x14) "fn ")
16428 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16429 (write-buffered *(ebp+0x14) %eax)
16430 (write-buffered *(ebp+0x14) ": inout '")
16431 (lookup *ebx *(ebx+4)) # => eax
16432 (lookup *eax *(eax+4)) # Var-name Var-name => eax
16433 (write-buffered *(ebp+0x14) %eax)
16434 (write-buffered *(ebp+0x14) "' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function\n")
16435 (flush *(ebp+0x14))
16436 (stop *(ebp+0x18) 1)
16439 # scenarios considered:
16444 # ✓ fn foo x: int -> _/eax: int
16446 # disallow outputs of type `(... addr ...)`
16447 # disallow inputs of type `(... addr ... addr ...)`
16448 populate-mu-function-signature: # first-line: (addr stream byte), out: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
16450 # var word-slice: slice
16451 # next-mu-token(first-line, word-slice)
16452 # assert(word-slice not in '{' '}' '->')
16453 # out->name = slice-to-string(word-slice)
16456 # word-slice = next-mu-token(first-line)
16457 # if slice-empty?(word-slice) break
16458 # if (word-slice == '->') break
16459 # assert(word-slice not in '{' '}')
16460 # var v: (handle var) = parse-var-with-type(word-slice, first-line)
16461 # assert(v->register == null)
16462 # # v->block-depth is implicitly 0
16463 # out->inouts = append(v, out->inouts)
16466 # word-slice = next-mu-token(first-line)
16467 # if slice-empty?(word-slice) break
16468 # assert(word-slice not in '{' '}' '->')
16469 # var v: (handle var) = parse-var-with-type(word-slice, first-line)
16470 # assert(v->register != null)
16471 # out->outputs = append(v, out->outputs)
16475 89/<- %ebp 4/r32/esp
16483 8b/-> *(ebp+0xc) 7/r32/edi
16484 # var word-slice/ecx: slice
16485 68/push 0/imm32/end
16486 68/push 0/imm32/start
16487 89/<- %ecx 4/r32/esp
16488 # var v/ebx: (handle var)
16491 89/<- %ebx 4/r32/esp
16492 # read function name
16493 (next-mu-token *(ebp+8) %ecx)
16495 # if (word-slice == '{') abort
16496 (slice-equal? %ecx "{") # => eax
16497 3d/compare-eax-and 0/imm32/false
16498 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32
16499 # if (word-slice == '->') abort
16500 (slice-equal? %ecx "->") # => eax
16501 3d/compare-eax-and 0/imm32/false
16502 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32
16503 # if (word-slice == '}') abort
16504 (slice-equal? %ecx "}") # => eax
16505 3d/compare-eax-and 0/imm32/false
16506 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32
16507 # if word-slice already defined, abort
16508 (function-exists? %ecx) # => eax
16509 3d/compare-eax-and 0/imm32/false
16510 0f 85/jump-if-!= $populate-mu-function-signature:error-duplicate/disp32
16512 (slice-starts-with? %ecx "break") # => eax
16513 3d/compare-eax-and 0/imm32/false
16514 0f 85/jump-if-!= $populate-mu-function-signature:error-break/disp32
16515 (slice-starts-with? %ecx "loop") # => eax
16516 3d/compare-eax-and 0/imm32/false
16517 0f 85/jump-if-!= $populate-mu-function-signature:error-loop/disp32
16518 # save function name
16519 (slice-to-string Heap %ecx %edi) # Function-name
16520 # save function inouts
16522 $populate-mu-function-signature:check-for-inout:
16523 (next-mu-token *(ebp+8) %ecx)
16524 (slice-empty? %ecx) # => eax
16525 3d/compare-eax-and 0/imm32/false
16526 0f 85/jump-if-!= break/disp32
16527 # if (word-slice == '->') break
16528 (slice-equal? %ecx "->") # => eax
16529 3d/compare-eax-and 0/imm32/false
16530 0f 85/jump-if-!= break/disp32
16531 # if (word-slice == '{') abort
16532 (slice-equal? %ecx "{") # => eax
16533 3d/compare-eax-and 0/imm32/false
16534 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32
16535 # if (word-slice == '}') abort
16536 (slice-equal? %ecx "}") # => eax
16537 3d/compare-eax-and 0/imm32/false
16538 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32
16539 # v = parse-var-with-type(word-slice, first-line)
16540 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16541 (parse-var-with-type %ecx *(ebp+8) %ebx %eax *(ebp+0x10) *(ebp+0x14))
16542 # if (v->register != null) abort
16543 # . eax: (addr var) = lookup(v)
16544 (lookup *ebx *(ebx+4)) # => eax
16545 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register
16546 0f 85/jump-if-!= $populate-mu-function-signature:error2/disp32
16547 # if function name is not "main"
16548 # and v->type contains an 'addr' anywhere except the start, abort
16550 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16551 (string-equal? %eax "main") # => eax
16552 3d/compare-eax-and 0/imm32/false
16553 75/jump-if-!= break/disp8
16554 (lookup *ebx *(ebx+4)) # => eax
16555 (addr-payload-contains-addr? %eax) # => eax
16556 3d/compare-eax-and 0/imm32/false
16557 0f 85/jump-if-!= $populate-mu-function-signature:error-nested-addr-inout/disp32
16559 # assert(v->register == null)
16560 # . eax: (addr var) = lookup(v)
16561 (lookup *ebx *(ebx+4)) # => eax
16562 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register
16563 0f 85/jump-if-!= $populate-mu-function-signature:error2/disp32
16564 # v->block-depth is implicitly 0
16566 # out->inouts = append(v, out->inouts)
16567 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts
16568 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts
16570 e9/jump loop/disp32
16572 # save function outputs
16574 $populate-mu-function-signature:check-for-out:
16575 (next-mu-token *(ebp+8) %ecx)
16576 (slice-empty? %ecx) # => eax
16577 3d/compare-eax-and 0/imm32/false
16578 0f 85/jump-if-!= break/disp32
16579 # if (word-slice == '{') abort
16580 (slice-equal? %ecx "{") # => eax
16581 3d/compare-eax-and 0/imm32/false
16582 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32
16583 # if (word-slice == '->') abort
16584 (slice-equal? %ecx "->") # => eax
16585 3d/compare-eax-and 0/imm32/false
16586 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32
16587 # if (word-slice == '}') abort
16588 (slice-equal? %ecx "}") # => eax
16589 3d/compare-eax-and 0/imm32/false
16590 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32
16591 # v = parse-var-with-type(word-slice, first-line)
16592 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16593 (parse-var-with-type %ecx *(ebp+8) %ebx %eax *(ebp+0x10) *(ebp+0x14))
16594 # assert(var->register != null)
16595 # . eax: (addr var) = lookup(v)
16596 (lookup *ebx *(ebx+4)) # => eax
16597 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register
16598 0f 84/jump-if-= $populate-mu-function-signature:error3/disp32
16599 # if (var->name != "_") abort
16600 (lookup *eax *(eax+4)) # Var-name Var-name => eax
16601 (string-equal? %eax "_") # => eax
16602 3d/compare-eax-and 0/imm32/false
16603 0f 84/jump-if-= $populate-mu-function-signature:error4/disp32
16604 # if function name is not "lookup"
16605 # and v->type is an addr, abort
16607 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16608 (string-equal? %eax "lookup") # => eax
16609 3d/compare-eax-and 0/imm32/false
16610 75/jump-if-!= break/disp8
16611 (lookup *ebx *(ebx+4)) # => eax
16612 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
16613 (mu-addr-type? %eax) # => eax
16614 3d/compare-eax-and 0/imm32/false
16615 0f 85/jump-if-!= $populate-mu-function-signature:error-addr-output/disp32
16617 # out->outputs = append(v, out->outputs)
16618 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs
16619 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs
16621 e9/jump loop/disp32
16623 $populate-mu-function-signature:done:
16624 (check-no-tokens-left *(ebp+8))
16625 $populate-mu-function-signature:end:
16627 81 0/subop/add %esp 0x10/imm32
16628 # . restore registers
16635 89/<- %esp 5/r32/ebp
16639 $populate-mu-function-signature:error1:
16640 # error("function signature not in form 'fn <name> {'")
16641 (write-buffered *(ebp+0x10) "function signature not in form 'fn <name> [inouts] [-> outputs] {' -- '")
16642 (flush *(ebp+0x10))
16643 (rewind-stream *(ebp+8))
16644 (write-stream-data *(ebp+0x10) *(ebp+8))
16645 (write-buffered *(ebp+0x10) "'\n")
16646 (flush *(ebp+0x10))
16647 (stop *(ebp+0x14) 1)
16650 $populate-mu-function-signature:error2:
16651 # error("fn " fn ": function inout '" var "' cannot be in a register")
16652 (write-buffered *(ebp+0x10) "fn ")
16654 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16655 (write-buffered *(ebp+0x10) %eax)
16657 (write-buffered *(ebp+0x10) ": function inout '")
16658 (lookup *eax *(eax+4)) # Var-name Var-name => eax
16659 (write-buffered *(ebp+0x10) %eax)
16660 (write-buffered *(ebp+0x10) "' cannot be in a register")
16661 (flush *(ebp+0x10))
16662 (stop *(ebp+0x14) 1)
16665 $populate-mu-function-signature:error3:
16666 # error("fn " fn ": function output '" var "' must be in a register")
16667 (write-buffered *(ebp+0x10) "fn ")
16669 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16670 (write-buffered *(ebp+0x10) %eax)
16672 (write-buffered *(ebp+0x10) ": function output '")
16673 (lookup *ebx *(ebx+4)) # => eax
16674 (lookup *eax *(eax+4)) # Var-name Var-name => eax
16675 (write-buffered *(ebp+0x10) %eax)
16676 (write-buffered *(ebp+0x10) "' must be in a register, in instruction '")
16677 (rewind-stream *(ebp+8))
16678 (write-stream-data *(ebp+0x10) *(ebp+8))
16679 (write-buffered *(ebp+0x10) "'\n")
16680 (flush *(ebp+0x10))
16681 (stop *(ebp+0x14) 1)
16684 $populate-mu-function-signature:error4:
16685 # error("fn " fn ": function outputs cannot be named; rename '" var "' in the header to '_'")
16686 (write-buffered *(ebp+0x10) "fn ")
16688 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16689 (write-buffered *(ebp+0x10) %eax)
16691 (write-buffered *(ebp+0x10) ": function outputs cannot be named; rename '")
16692 (lookup *ebx *(ebx+4)) # => eax
16693 (lookup *eax *(eax+4)) # Var-name Var-name => eax
16694 (write-buffered *(ebp+0x10) %eax)
16695 (write-buffered *(ebp+0x10) "' in the header to '_'\n")
16696 (flush *(ebp+0x10))
16697 (stop *(ebp+0x14) 1)
16700 $populate-mu-function-signature:error-duplicate:
16701 (write-buffered *(ebp+0x10) "fn ")
16702 (write-slice-buffered *(ebp+0x10) %ecx)
16703 (write-buffered *(ebp+0x10) " defined more than once\n")
16704 (flush *(ebp+0x10))
16705 (stop *(ebp+0x14) 1)
16708 $populate-mu-function-signature:error-break:
16709 (write-buffered *(ebp+0x10) "Sorry, I've reserved all function names starting with 'break' for now. Please contact mu@akkartik.com.\n")
16710 (flush *(ebp+0x10))
16711 (stop *(ebp+0x14) 1)
16714 $populate-mu-function-signature:error-loop:
16715 (write-buffered *(ebp+0x10) "Sorry, I've reserved all function names starting with 'loop' for now. Please contact mu@akkartik.com.\n")
16716 (flush *(ebp+0x10))
16717 (stop *(ebp+0x14) 1)
16720 $populate-mu-function-signature:error-addr-output:
16721 # error("fn " fn ": output cannot have an addr type; that could allow unsafe addresses to escape the function")
16722 (write-buffered *(ebp+0x10) "fn ")
16724 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16725 (write-buffered *(ebp+0x10) %eax)
16727 (write-buffered *(ebp+0x10) ": output cannot have an addr type; that could allow unsafe addresses to escape the function\n")
16728 (flush *(ebp+0x10))
16729 (stop *(ebp+0x14) 1)
16732 $populate-mu-function-signature:error-nested-addr-inout:
16733 # error("fn " fn ": inout '" var "' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function")
16734 (write-buffered *(ebp+0x10) "fn ")
16735 (lookup *edi *(edi+4)) # Function-name Function-name => eax
16736 (write-buffered *(ebp+0x10) %eax)
16737 (write-buffered *(ebp+0x10) ": inout '")
16738 (lookup *ebx *(ebx+4)) # => eax
16739 (lookup *eax *(eax+4)) # Var-name Var-name => eax
16740 (write-buffered *(ebp+0x10) %eax)
16741 (write-buffered *(ebp+0x10) "' cannot contain 'addr' anywhere in the type except the first word; that could allow unsafe addresses to escape the function\n")
16742 (flush *(ebp+0x10))
16743 (stop *(ebp+0x14) 1)
16746 addr-payload-contains-addr?: # v: (addr var) -> result/eax: boolean
16749 89/<- %ebp 4/r32/esp
16750 # var t/eax: (addr type-tree) = v->type
16751 8b/-> *(ebp+8) 0/r32/eax
16752 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
16753 # if t->right contains addr, return true
16754 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
16755 (type-tree-contains? %eax 2) # addr => eax
16756 # we don't have to look at t->left as long as it's guaranteed to be an atom
16757 $addr-payload-contains-addr?:end:
16759 89/<- %esp 5/r32/ebp
16763 type-tree-contains?: # t: (addr type-tree), n: type-id -> result/eax: boolean
16766 89/<- %ebp 4/r32/esp
16769 # if t is null, return false
16770 8b/-> *(ebp+8) 0/r32/eax
16771 3d/compare-eax-and 0/imm32
16772 0f 84/jump-if-= $type-tree-contains?:end/disp32 # eax changes type
16773 # if t is an atom, return (t->value == n)
16774 81 7/subop/compare *eax 0/imm32/false
16776 74/jump-if-= break/disp8
16777 8b/-> *(ebp+0xc) 1/r32/ecx
16778 39/compare *(eax+4) 1/r32/ecx # Type-tree-value
16780 25/and-eax-with 0xff/imm32
16781 eb/jump $type-tree-contains?:end/disp8
16783 # if t->left contains n, return true
16784 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
16785 (type-tree-contains? %eax *(ebp+0xc)) # => eax
16786 3d/compare-eax-and 0/imm32/false
16787 75/jump-if-!= $type-tree-contains?:end/disp8
16788 # otherwise return whether t->right contains n
16789 8b/-> *(ebp+8) 0/r32/eax
16790 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
16791 (type-tree-contains? %eax *(ebp+0xc)) # => eax
16792 $type-tree-contains?:end:
16793 # . restore registers
16796 89/<- %esp 5/r32/ebp
16800 function-exists?: # s: (addr slice) -> result/eax: boolean
16803 89/<- %ebp 4/r32/esp
16806 # var curr/ecx: (addr function) = functions
16807 (lookup *_Program-functions *_Program-functions->payload) # => eax
16808 89/<- %ecx 0/r32/eax
16810 # if (curr == null) break
16811 81 7/subop/compare %ecx 0/imm32
16812 74/jump-if-= break/disp8
16813 # if (curr->name == s) return true
16815 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax
16816 (slice-equal? *(ebp+8) %eax) # => eax
16817 3d/compare-eax-and 0/imm32/false
16818 74/jump-if-= break/disp8
16819 b8/copy-to-eax 1/imm32/true
16820 e9/jump $function-exists?:end/disp32
16822 # curr = curr->next
16823 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax
16824 89/<- %ecx 0/r32/eax
16828 # var curr/ecx: (addr function) = signatures
16829 (lookup *_Program-signatures *_Program-signatures->payload) # => eax
16830 89/<- %ecx 0/r32/eax
16832 # if (curr == null) break
16833 81 7/subop/compare %ecx 0/imm32
16834 74/jump-if-= break/disp8
16835 # if (curr->name == s) return true
16837 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax
16838 (slice-equal? *(ebp+8) %eax) # => eax
16839 3d/compare-eax-and 0/imm32/false
16840 74/jump-if-= break/disp8
16841 b8/copy-to-eax 1/imm32/true
16842 eb/jump $function-exists?:end/disp8
16844 # curr = curr->next
16845 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax
16846 89/<- %ecx 0/r32/eax
16851 b8/copy-to-eax 0/imm32/false
16852 $function-exists?:end:
16853 # . restore registers
16856 89/<- %esp 5/r32/ebp
16860 test-function-header-with-arg:
16863 89/<- %ebp 4/r32/esp
16865 8b/-> *Primitive-type-ids 0/r32/eax
16866 89/<- *Type-id 0/r32/eax # stream-write
16867 c7 0/subop/copy *_Program-functions 0/imm32
16868 c7 0/subop/copy *_Program-functions->payload 0/imm32
16869 c7 0/subop/copy *_Program-types 0/imm32
16870 c7 0/subop/copy *_Program-types->payload 0/imm32
16871 c7 0/subop/copy *_Program-signatures 0/imm32
16872 c7 0/subop/copy *_Program-signatures->payload 0/imm32
16873 (clear-stream _test-input-stream)
16874 (write _test-input-stream "foo n: int {\n")
16875 # var result/ecx: function
16876 2b/subtract *Function-size 4/r32/esp
16877 89/<- %ecx 4/r32/esp
16878 (zero-out %ecx *Function-size)
16879 # var vars/ebx: (stack live-var 16)
16880 81 5/subop/subtract %esp 0xc0/imm32
16881 68/push 0xc0/imm32/size
16882 68/push 0/imm32/top
16883 89/<- %ebx 4/r32/esp
16885 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0)
16886 # check result->name
16887 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax
16888 (check-strings-equal %eax "foo" "F - test-function-header-with-arg/name")
16889 # var v/edx: (addr var) = result->inouts->value
16890 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax
16891 (lookup *eax *(eax+4)) # List-value List-value => eax
16892 89/<- %edx 0/r32/eax
16894 (lookup *edx *(edx+4)) # Var-name Var-name => eax
16895 (check-strings-equal %eax "n" "F - test-function-header-with-arg/inout:0")
16897 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
16898 (check-ints-equal *eax 1 "F - test-function-header-with-arg/inout:0/type:0") # Type-tree-is-atom
16899 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-arg/inout:0/type:1") # Type-tree-value
16900 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-arg/inout:0/type:2") # Type-tree-right
16902 89/<- %esp 5/r32/ebp
16906 test-function-header-with-multiple-args:
16909 89/<- %ebp 4/r32/esp
16911 8b/-> *Primitive-type-ids 0/r32/eax
16912 89/<- *Type-id 0/r32/eax # stream-write
16913 c7 0/subop/copy *_Program-functions 0/imm32
16914 c7 0/subop/copy *_Program-functions->payload 0/imm32
16915 c7 0/subop/copy *_Program-types 0/imm32
16916 c7 0/subop/copy *_Program-types->payload 0/imm32
16917 c7 0/subop/copy *_Program-signatures 0/imm32
16918 c7 0/subop/copy *_Program-signatures->payload 0/imm32
16919 (clear-stream _test-input-stream)
16920 (write _test-input-stream "foo a: int, b: int c: int {\n")
16921 # result/ecx: function
16922 2b/subtract *Function-size 4/r32/esp
16923 89/<- %ecx 4/r32/esp
16924 (zero-out %ecx *Function-size)
16925 # var vars/ebx: (stack live-var 16)
16926 81 5/subop/subtract %esp 0xc0/imm32
16927 68/push 0xc0/imm32/size
16928 68/push 0/imm32/top
16929 89/<- %ebx 4/r32/esp
16931 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0)
16932 # check result->name
16933 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax
16934 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args/name")
16935 # var inouts/edx: (addr list var) = lookup(result->inouts)
16936 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax
16937 89/<- %edx 0/r32/eax
16938 $test-function-header-with-multiple-args:inout0:
16939 # var v/ebx: (addr var) = lookup(inouts->value)
16940 (lookup *edx *(edx+4)) # List-value List-value => eax
16941 89/<- %ebx 0/r32/eax
16943 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax
16944 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name
16946 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax
16947 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:0/type:0") # Type-tree-is-atom
16948 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:0/type:1") # Type-tree-value
16949 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:0/type:2") # Type-tree-right
16950 $test-function-header-with-multiple-args:inout1:
16951 # inouts = lookup(inouts->next)
16952 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax
16953 89/<- %edx 0/r32/eax
16954 # v = lookup(inouts->value)
16955 (lookup *edx *(edx+4)) # List-value List-value => eax
16956 89/<- %ebx 0/r32/eax
16958 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax
16959 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name
16961 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax
16962 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:1/type:0") # Type-tree-is-atom
16963 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:1/type:1") # Type-tree-value
16964 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:1/type:2") # Type-tree-right
16965 $test-function-header-with-multiple-args:inout2:
16966 # inouts = lookup(inouts->next)
16967 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax
16968 89/<- %edx 0/r32/eax
16969 # v = lookup(inouts->value)
16970 (lookup *edx *(edx+4)) # List-value List-value => eax
16971 89/<- %ebx 0/r32/eax
16973 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax
16974 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name
16976 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax
16977 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:2/type:0") # Type-tree-is-atom
16978 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:2/type:1") # Type-tree-value
16979 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:2/type:2") # Type-tree-right
16981 89/<- %esp 5/r32/ebp
16985 test-function-header-with-multiple-args-and-outputs:
16988 89/<- %ebp 4/r32/esp
16990 8b/-> *Primitive-type-ids 0/r32/eax
16991 89/<- *Type-id 0/r32/eax # stream-write
16992 c7 0/subop/copy *_Program-functions 0/imm32
16993 c7 0/subop/copy *_Program-functions->payload 0/imm32
16994 c7 0/subop/copy *_Program-types 0/imm32
16995 c7 0/subop/copy *_Program-types->payload 0/imm32
16996 c7 0/subop/copy *_Program-signatures 0/imm32
16997 c7 0/subop/copy *_Program-signatures->payload 0/imm32
16998 (clear-stream _test-input-stream)
16999 (write _test-input-stream "foo a: int, b: int, c: int -> _/ecx: int _/edx: int {\n")
17000 # result/ecx: function
17001 2b/subtract *Function-size 4/r32/esp
17002 89/<- %ecx 4/r32/esp
17003 (zero-out %ecx *Function-size)
17004 # var vars/ebx: (stack live-var 16)
17005 81 5/subop/subtract %esp 0xc0/imm32
17006 68/push 0xc0/imm32/size
17007 68/push 0/imm32/top
17008 89/<- %ebx 4/r32/esp
17010 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0)
17011 # check result->name
17012 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax
17013 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args-and-outputs/name")
17014 # var inouts/edx: (addr list var) = lookup(result->inouts)
17015 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax
17016 89/<- %edx 0/r32/eax
17017 $test-function-header-with-multiple-args-and-outputs:inout0:
17018 # var v/ebx: (addr var) = lookup(inouts->value)
17019 (lookup *edx *(edx+4)) # List-value List-value => eax
17020 89/<- %ebx 0/r32/eax
17022 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax
17023 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args-and-outputs/inout:0")
17025 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax
17026 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:0") # Type-tree-is-atom
17027 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:1") # Type-tree-value
17028 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:2") # Type-tree-right
17029 $test-function-header-with-multiple-args-and-outputs:inout1:
17030 # inouts = lookup(inouts->next)
17031 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax
17032 89/<- %edx 0/r32/eax
17033 # v = lookup(inouts->value)
17034 (lookup *edx *(edx+4)) # List-value List-value => eax
17035 89/<- %ebx 0/r32/eax
17037 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax
17038 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args-and-outputs/inout:1")
17040 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax
17041 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:0") # Type-tree-is-atom
17042 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:1") # Type-tree-value
17043 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:2") # Type-tree-right
17044 $test-function-header-with-multiple-args-and-outputs:inout2:
17045 # inouts = lookup(inouts->next)
17046 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax
17047 89/<- %edx 0/r32/eax
17048 # v = lookup(inouts->value)
17049 (lookup *edx *(edx+4)) # List-value List-value => eax
17050 89/<- %ebx 0/r32/eax
17052 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax
17053 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args-and-outputs/inout:2")
17055 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax
17056 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:0") # Type-tree-is-atom
17057 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:1") # Type-tree-value
17058 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:2") # Type-tree-right
17059 $test-function-header-with-multiple-args-and-outputs:out0:
17060 # var outputs/edx: (addr list var) = lookup(result->outputs)
17061 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax
17062 89/<- %edx 0/r32/eax
17063 # v = lookup(outputs->value)
17064 (lookup *edx *(edx+4)) # List-value List-value => eax
17065 89/<- %ebx 0/r32/eax
17067 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax
17068 (check-strings-equal %eax "_" "F - test-function-header-with-multiple-args-and-outputs/output:0")
17069 # check v->register
17070 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax
17071 (check-strings-equal %eax "ecx" "F - test-function-header-with-multiple-args-and-outputs/output:0/register")
17073 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax
17074 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:0") # Type-tree-is-atom
17075 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:1") # Type-tree-value
17076 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:2") # Type-tree-right
17077 $test-function-header-with-multiple-args-and-outputs:out1:
17078 # outputs = lookup(outputs->next)
17079 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax
17080 89/<- %edx 0/r32/eax
17081 # v = lookup(inouts->value)
17082 (lookup *edx *(edx+4)) # List-value List-value => eax
17083 89/<- %ebx 0/r32/eax
17085 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax
17086 (check-strings-equal %eax "_" "F - test-function-header-with-multiple-args-and-outputs/output:1")
17087 # check v->register
17088 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax
17089 (check-strings-equal %eax "edx" "F - test-function-header-with-multiple-args-and-outputs/output:1/register")
17091 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax
17092 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:0") # Type-tree-is-atom
17093 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:1") # Type-tree-value
17094 (check-ints-equal *(eax+0c) 0 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:2") # Type-tree-right
17096 89/<- %esp 5/r32/ebp
17100 # format for variables with types
17105 # ignores at most one trailing comma
17106 # does not support other, non-register metadata
17107 # WARNING: modifies name
17108 parse-var-with-type: # name: (addr slice), first-line: (addr stream byte), out: (addr handle var), fn-name: (addr array byte), err: (addr buffered-file), ed: (addr exit-descriptor)
17111 # if (!slice-ends-with(name, ":"))
17113 # --name->end to skip ':'
17114 # next-token-from-slice(name->start, name->end, '/', s)
17115 # new-var-from-slice(s, out)
17117 # next-token-from-slice(s->end, name->end, '/', s)
17118 # if (!slice-empty?(s))
17119 # out->register = slice-to-string(s)
17121 # var type: (handle type-tree) = parse-type(first-line)
17126 89/<- %ebp 4/r32/esp
17135 8b/-> *(ebp+8) 6/r32/esi
17136 # if (!slice-ends-with?(name, ":")) abort
17137 8b/-> *(esi+4) 1/r32/ecx # Slice-end
17139 8a/copy-byte *ecx 1/r32/CL
17140 81 4/subop/and %ecx 0xff/imm32
17141 81 7/subop/compare %ecx 0x3a/imm32/colon
17142 0f 85/jump-if-!= $parse-var-with-type:abort/disp32
17143 # --name->end to skip ':'
17144 ff 1/subop/decrement *(esi+4)
17146 68/push 0/imm32/end
17147 68/push 0/imm32/start
17148 89/<- %ecx 4/r32/esp
17149 $parse-var-with-type:parse-name:
17150 (next-token-from-slice *esi *(esi+4) 0x2f %ecx) # Slice-start, Slice-end, '/'
17151 $parse-var-with-type:create-var:
17152 # new-var-from-slice(s, out)
17153 (new-var-from-slice Heap %ecx *(ebp+0x10))
17154 # save out->register
17155 $parse-var-with-type:save-register:
17156 # . var out-addr/edi: (addr var) = lookup(*out)
17157 8b/-> *(ebp+0x10) 7/r32/edi
17158 (lookup *edi *(edi+4)) # => eax
17159 89/<- %edi 0/r32/eax
17160 # . s = next-token(...)
17161 (next-token-from-slice *(ecx+4) *(esi+4) 0x2f %ecx) # s->end, name->end, '/'
17162 # . if (!slice-empty?(s)) out->register = slice-to-string(s)
17164 $parse-var-with-type:write-register:
17165 (slice-empty? %ecx) # => eax
17166 3d/compare-eax-and 0/imm32/false
17167 75/jump-if-!= break/disp8
17168 # out->register = slice-to-string(s)
17169 8d/copy-address *(edi+0x18) 0/r32/eax # Var-register
17170 (slice-to-string Heap %ecx %eax)
17172 $parse-var-with-type:save-type:
17173 8d/copy-address *(edi+8) 0/r32/eax # Var-type
17174 (parse-type Heap *(ebp+0xc) %eax *(ebp+0x18) *(ebp+0x1c))
17175 $parse-var-with-type:check-register:
17176 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax
17177 3d/compare-eax-and 0/imm32
17178 74/jump-if-= $parse-var-with-type:end/disp8
17179 (float-register? %eax) # => eax
17181 3d/compare-eax-and 0/imm32/false
17182 74/jump-if-= break/disp8
17183 # var is in a float register; ensure type is float
17184 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax
17185 (simple-mu-type? %eax 0xf) # float => eax
17186 3d/compare-eax-and 0/imm32/false
17187 0f 84/jump-if-= $parse-var-with-type:error-non-float-in-floating-point-register/disp32
17188 eb/jump $parse-var-with-type:end/disp8
17190 # var is not in a float register; ensure type is not float
17191 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax
17192 (simple-mu-type? %eax 0xf) # float => eax
17193 3d/compare-eax-and 0/imm32/false
17194 0f 85/jump-if-!= $parse-var-with-type:error-float-in-integer-register/disp32
17195 $parse-var-with-type:end:
17197 81 0/subop/add %esp 8/imm32
17198 # . restore registers
17206 89/<- %esp 5/r32/ebp
17210 $parse-var-with-type:abort:
17211 # error("fn " fn ": var should have form 'name: type' in '" line "'\n")
17212 (write-buffered *(ebp+0x18) "fn ")
17213 (write-buffered *(ebp+0x18) *(ebp+0x14))
17214 (write-buffered *(ebp+0x18) ": var should have form 'name: type' in '")
17215 (flush *(ebp+0x18))
17216 (rewind-stream *(ebp+0xc))
17217 (write-stream-data *(ebp+0x18) *(ebp+0xc))
17218 (write-buffered *(ebp+0x18) "'\n")
17219 (flush *(ebp+0x18))
17220 (stop *(ebp+0x1c) 1)
17223 $parse-var-with-type:error-float-in-integer-register:
17224 # error("fn " fn ": float var '" var "' should be in a floating-point register\n")
17225 (write-buffered *(ebp+0x18) "fn ")
17226 (write-buffered *(ebp+0x18) *(ebp+0x14))
17227 (write-buffered *(ebp+0x18) ": float var '")
17228 (lookup *edi *(edi+4)) # Var-name Var-name => eax
17229 (write-buffered *(ebp+0x18) %eax)
17230 (write-buffered *(ebp+0x18) "' should be in a floating-point register\n")
17231 (flush *(ebp+0x18))
17232 (stop *(ebp+0x1c) 1)
17235 $parse-var-with-type:error-non-float-in-floating-point-register:
17236 # error("fn " fn ": non-float var '" var "' should be in an integer register\n")
17237 (write-buffered *(ebp+0x18) "fn ")
17238 (write-buffered *(ebp+0x18) *(ebp+0x14))
17239 (write-buffered *(ebp+0x18) ": non-float var '")
17240 (lookup *edi *(edi+4)) # Var-name Var-name => eax
17241 (write-buffered *(ebp+0x18) %eax)
17242 (write-buffered *(ebp+0x18) "' should be in an integer register\n")
17243 (flush *(ebp+0x18))
17244 (stop *(ebp+0x1c) 1)
17247 float-register?: # r: (addr array byte) -> result/eax: boolean
17250 89/<- %ebp 4/r32/esp
17252 (get Mu-registers-unique *(ebp+8) 0xc "Mu-registers-unique") # => eax
17253 81 7/subop/compare *eax 8/imm32/start-of-floating-point-registers
17254 0f 9d/set-if->= %al
17255 25/and-eax-with 0xff/imm32
17256 $float-register?:end:
17258 89/<- %esp 5/r32/ebp
17262 parse-type: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor)
17264 # var s: slice = next-mu-token(in)
17271 # out = allocate(Type-tree)
17273 # HACK: if s is an int, parse and return it
17274 # out->is-atom? = true
17276 # out->value = type-parameter
17277 # out->parameter-name = slice-to-string(ad, s)
17279 # out->value = pos-or-insert-slice(Type-id, s)
17281 # out->left = parse-type(ad, in)
17282 # out->right = parse-type-tree(ad, in)
17286 89/<- %ebp 4/r32/esp
17292 (zero-out *(ebp+0x10) *Handle-size)
17296 89/<- %ecx 4/r32/esp
17297 # s = next-mu-token(in)
17298 (next-mu-token *(ebp+0xc) %ecx)
17299 #? (write-buffered Stderr "tok: ")
17300 #? (write-slice-buffered Stderr %ecx)
17301 #? (write-buffered Stderr "$\n")
17304 (slice-equal? %ecx "") # => eax
17305 3d/compare-eax-and 0/imm32/false
17306 0f 85/jump-if-!= $parse-type:abort/disp32
17308 (slice-equal? %ecx "{") # => eax
17309 3d/compare-eax-and 0/imm32/false
17310 0f 85/jump-if-!= $parse-type:abort/disp32
17312 (slice-equal? %ecx "}") # => eax
17313 3d/compare-eax-and 0/imm32/false
17314 0f 85/jump-if-!= $parse-type:abort/disp32
17316 (slice-equal? %ecx "->") # => eax
17317 3d/compare-eax-and 0/imm32/false
17318 0f 85/jump-if-!= $parse-type:abort/disp32
17319 # if (s == ")") return
17320 (slice-equal? %ecx ")") # => eax
17321 3d/compare-eax-and 0/imm32/false
17322 0f 85/jump-if-!= $parse-type:end/disp32
17324 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10))
17325 # var out-addr/edx: (addr type-tree) = lookup(*out)
17326 8b/-> *(ebp+0x10) 2/r32/edx
17327 (lookup *edx *(edx+4)) # => eax
17328 89/<- %edx 0/r32/eax
17330 # if (s != "(") break
17331 (slice-equal? %ecx "(") # => eax
17332 3d/compare-eax-and 0/imm32/false
17333 0f 85/jump-if-!= break/disp32
17334 # if s is a number, store it in the type's size field
17336 $parse-type:check-for-int:
17337 # var tmp/eax: byte = *s->slice
17338 8b/-> *ecx 0/r32/eax
17339 8a/copy-byte *eax 0/r32/AL
17340 25/and-eax-with 0xff/imm32
17341 # TODO: raise an error on `var x: (array int a)`
17342 (decimal-digit? %eax) # => eax
17343 3d/compare-eax-and 0/imm32/false
17344 74/jump-if-= break/disp8
17346 # strip out metadata
17347 (next-token-from-slice *ecx *(ecx+4) 0x2f %ecx)
17349 (check-mu-hex-int %ecx *(ebp+0x14) *(ebp+0x18))
17350 (parse-hex-int-from-slice %ecx) # => eax
17351 c7 0/subop/copy *(edx+4) 9/imm32/type-id-array-capacity # Type-tree-value
17352 89/<- *(edx+8) 0/r32/eax # Type-tree-value-size
17353 e9/jump $parse-type:end/disp32
17356 # out->is-atom? = true
17357 c7 0/subop/copy *edx 1/imm32/true # Type-tree-is-atom
17359 $parse-type:check-for-type-parameter:
17360 # var tmp/eax: byte = *s->slice
17361 8b/-> *ecx 0/r32/eax
17362 8a/copy-byte *eax 0/r32/AL
17363 25/and-eax-with 0xff/imm32
17364 # if (tmp != '_') break
17365 3d/compare-eax-and 0x5f/imm32/_
17366 75/jump-if-!= break/disp8
17367 $parse-type:type-parameter:
17368 # out->value = type-parameter
17369 c7 0/subop/copy *(edx+4) 0xa/imm32/type-parameter # Type-tree-value
17370 # out->parameter-name = slice-to-string(ad, s)
17371 8d/copy-address *(edx+8) 0/r32/eax # Type-tree-parameter-name
17372 (slice-to-string *(ebp+8) %ecx %eax)
17373 e9/jump $parse-type:end/disp32
17375 $parse-type:non-type-parameter:
17376 # out->value = pos-or-insert-slice(Type-id, s)
17377 (pos-or-insert-slice Type-id %ecx) # => eax
17378 89/<- *(edx+4) 0/r32/eax # Type-tree-value
17379 e9/jump $parse-type:end/disp32
17381 $parse-type:non-atom:
17382 # otherwise s == "("
17383 # out->left = parse-type(ad, in)
17384 8d/copy-address *(edx+4) 0/r32/eax # Type-tree-left
17385 (parse-type *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18))
17386 # out->right = parse-type-tree(ad, in)
17387 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right
17388 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18))
17391 81 0/subop/add %esp 8/imm32
17392 # . restore registers
17397 89/<- %esp 5/r32/ebp
17402 # error("unexpected token when parsing type: '" s "'\n")
17403 (write-buffered *(ebp+0x14) "unexpected token when parsing type: '")
17404 (write-slice-buffered *(ebp+0x14) %ecx)
17405 (write-buffered *(ebp+0x14) "'\n")
17406 (flush *(ebp+0x14))
17407 (stop *(ebp+0x18) 1)
17410 parse-type-tree: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor)
17412 # var tmp: (handle type-tree) = parse-type(ad, in)
17415 # out = allocate(Type-tree)
17417 # out->right = parse-type-tree(ad, in)
17421 89/<- %ebp 4/r32/esp
17427 (zero-out *(ebp+0x10) *Handle-size)
17428 # var tmp/ecx: (handle type-tree)
17431 89/<- %ecx 4/r32/esp
17432 # tmp = parse-type(ad, in)
17433 (parse-type *(ebp+8) *(ebp+0xc) %ecx *(ebp+0x14) *(ebp+0x18))
17434 # if (tmp == 0) return
17435 81 7/subop/compare *ecx 0/imm32
17436 74/jump-if-= $parse-type-tree:end/disp8
17438 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10))
17439 # var out-addr/edx: (addr tree) = lookup(*out)
17440 8b/-> *(ebp+0x10) 2/r32/edx
17441 (lookup *edx *(edx+4)) # => eax
17442 89/<- %edx 0/r32/eax
17444 8b/-> *ecx 0/r32/eax
17445 89/<- *(edx+4) 0/r32/eax # Type-tree-left
17446 8b/-> *(ecx+4) 0/r32/eax
17447 89/<- *(edx+8) 0/r32/eax # Type-tree-left
17448 # out->right = parse-type-tree(ad, in)
17449 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right
17450 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18))
17451 $parse-type-tree:end:
17453 81 0/subop/add %esp 8/imm32
17454 # . restore registers
17459 89/<- %esp 5/r32/ebp
17463 next-mu-token: # in: (addr stream byte), out: (addr slice)
17466 # skip-chars-matching-whitespace(in)
17467 # if in->read >= in->write # end of in
17470 # out->start = &in->data[in->read]
17471 # var curr-byte/eax: byte = in->data[in->read]
17472 # if curr->byte == ',' # comment token
17475 # if curr-byte == '#' # comment
17476 # goto done # treat as eof
17477 # if curr-byte == '"' # string literal
17479 # goto done # no metadata
17480 # if curr-byte == '('
17483 # if curr-byte == ')'
17488 # if in->read >= in->write
17490 # curr-byte = in->data[in->read]
17491 # if curr-byte == ' '
17493 # if curr-byte == '\r'
17495 # if curr-byte == '\n'
17497 # if curr-byte == '('
17499 # if curr-byte == ')'
17501 # if curr-byte == ','
17505 # out->end = &in->data[in->read]
17509 89/<- %ebp 4/r32/esp
17516 8b/-> *(ebp+8) 6/r32/esi
17518 8b/-> *(ebp+0xc) 7/r32/edi
17519 $next-mu-token:start:
17520 (skip-chars-matching-whitespace %esi)
17521 $next-mu-token:check0:
17522 # if (in->read >= in->write) return out = {0, 0}
17524 8b/-> *(esi+4) 1/r32/ecx
17525 # . if (ecx >= in->write) return out = {0, 0}
17526 3b/compare<- *esi 1/r32/ecx
17527 c7 0/subop/copy *edi 0/imm32
17528 c7 0/subop/copy *(edi+4) 0/imm32
17529 0f 8d/jump-if->= $next-mu-token:end/disp32
17530 # out->start = &in->data[in->read]
17531 8d/copy-address *(esi+ecx+0xc) 0/r32/eax
17532 89/<- *edi 0/r32/eax
17533 # var curr-byte/eax: byte = in->data[in->read]
17534 31/xor-with %eax 0/r32/eax
17535 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL
17537 $next-mu-token:check-for-comma:
17538 # if (curr-byte != ',') break
17539 3d/compare-eax-and 0x2c/imm32/comma
17540 75/jump-if-!= break/disp8
17542 ff 0/subop/increment *(esi+4)
17544 e9/jump $next-mu-token:start/disp32
17547 $next-mu-token:check-for-comment:
17548 # if (curr-byte != '#') break
17549 3d/compare-eax-and 0x23/imm32/pound
17550 75/jump-if-!= break/disp8
17552 e9/jump $next-mu-token:done/disp32
17555 $next-mu-token:check-for-string-literal:
17556 # if (curr-byte != '"') break
17557 3d/compare-eax-and 0x22/imm32/dquote
17558 75/jump-if-!= break/disp8
17561 e9/jump $next-mu-token:done/disp32
17564 $next-mu-token:check-for-open-paren:
17565 # if (curr-byte != '(') break
17566 3d/compare-eax-and 0x28/imm32/open-paren
17567 75/jump-if-!= break/disp8
17569 ff 0/subop/increment *(esi+4)
17571 e9/jump $next-mu-token:done/disp32
17574 $next-mu-token:check-for-close-paren:
17575 # if (curr-byte != ')') break
17576 3d/compare-eax-and 0x29/imm32/close-paren
17577 75/jump-if-!= break/disp8
17579 ff 0/subop/increment *(esi+4)
17581 e9/jump $next-mu-token:done/disp32
17584 $next-mu-token:regular-word-without-metadata:
17585 # if (in->read >= in->write) break
17587 8b/-> *(esi+4) 1/r32/ecx
17588 # . if (ecx >= in->write) break
17589 3b/compare<- *esi 1/r32/ecx
17590 7d/jump-if->= break/disp8
17591 # var c/eax: byte = in->data[in->read]
17592 31/xor-with %eax 0/r32/eax
17593 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL
17594 # if (c == ' ') break
17595 3d/compare-eax-and 0x20/imm32/space
17596 74/jump-if-= break/disp8
17597 # if (c == '\r') break
17598 3d/compare-eax-and 0xd/imm32/carriage-return
17599 74/jump-if-= break/disp8
17600 # if (c == '\n') break
17601 3d/compare-eax-and 0xa/imm32/newline
17602 74/jump-if-= break/disp8
17603 # if (c == '(') break
17604 3d/compare-eax-and 0x28/imm32/open-paren
17605 0f 84/jump-if-= break/disp32
17606 # if (c == ')') break
17607 3d/compare-eax-and 0x29/imm32/close-paren
17608 0f 84/jump-if-= break/disp32
17609 # if (c == ',') break
17610 3d/compare-eax-and 0x2c/imm32/comma
17611 0f 84/jump-if-= break/disp32
17613 ff 0/subop/increment *(esi+4)
17615 e9/jump loop/disp32
17617 $next-mu-token:done:
17618 # out->end = &in->data[in->read]
17619 8b/-> *(esi+4) 1/r32/ecx
17620 8d/copy-address *(esi+ecx+0xc) 0/r32/eax
17621 89/<- *(edi+4) 0/r32/eax
17622 $next-mu-token:end:
17623 # . restore registers
17629 89/<- %esp 5/r32/ebp
17633 pos-or-insert-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int
17636 89/<- %ebp 4/r32/esp
17637 # if (pos-slice(arr, s) != -1) return it
17638 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax
17639 3d/compare-eax-and -1/imm32
17640 75/jump-if-!= $pos-or-insert-slice:end/disp8
17641 $pos-or-insert-slice:insert:
17642 # var s2/eax: (handle array byte)
17645 89/<- %eax 4/r32/esp
17646 (slice-to-string Heap *(ebp+0xc) %eax)
17647 # throw away alloc-id
17648 (lookup *eax *(eax+4)) # => eax
17649 (write-int *(ebp+8) %eax)
17650 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax
17651 $pos-or-insert-slice:end:
17653 81 0/subop/add %esp 8/imm32
17655 89/<- %esp 5/r32/ebp
17659 # return the index in an array of strings matching 's', -1 if not found
17660 # index is denominated in elements, not bytes
17661 pos-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int
17664 89/<- %ebp 4/r32/esp
17670 #? (write-buffered Stderr "pos-slice: ")
17671 #? (write-slice-buffered Stderr *(ebp+0xc))
17672 #? (write-buffered Stderr "\n")
17675 8b/-> *(ebp+8) 6/r32/esi
17676 # var index/ecx: int = 0
17677 b9/copy-to-ecx 0/imm32
17678 # var curr/edx: (addr (addr array byte)) = arr->data
17679 8d/copy-address *(esi+0xc) 2/r32/edx
17680 # var max/ebx: (addr (addr array byte)) = &arr->data[arr->write]
17681 8b/-> *esi 3/r32/ebx
17682 8d/copy-address *(esi+ebx+0xc) 3/r32/ebx
17684 #? (write-buffered Stderr " ")
17685 #? (write-int32-hex-buffered Stderr %ecx)
17686 #? (write-buffered Stderr "\n")
17688 # if (curr >= max) return -1
17689 39/compare %edx 3/r32/ebx
17690 b8/copy-to-eax -1/imm32
17691 73/jump-if-addr>= $pos-slice:end/disp8
17692 # if (slice-equal?(s, *curr)) break
17693 (slice-equal? *(ebp+0xc) *edx) # => eax
17694 3d/compare-eax-and 0/imm32/false
17695 75/jump-if-!= break/disp8
17699 81 0/subop/add %edx 4/imm32
17704 89/<- %eax 1/r32/ecx
17706 #? (write-buffered Stderr "=> ")
17707 #? (write-int32-hex-buffered Stderr %eax)
17708 #? (write-buffered Stderr "\n")
17709 # . restore registers
17715 89/<- %esp 5/r32/ebp
17719 test-parse-var-with-type:
17722 89/<- %ebp 4/r32/esp
17724 8b/-> *Primitive-type-ids 0/r32/eax
17725 89/<- *Type-id 0/r32/eax # stream-write
17726 # (eax..ecx) = "x:"
17727 b8/copy-to-eax "x:"/imm32
17728 8b/-> *eax 1/r32/ecx
17729 8d/copy-address *(eax+ecx+4) 1/r32/ecx
17730 05/add-to-eax 4/imm32
17731 # var slice/ecx: slice = {eax, ecx}
17734 89/<- %ecx 4/r32/esp
17735 # _test-input-stream contains "int"
17736 (clear-stream _test-input-stream)
17737 (write _test-input-stream "int")
17738 # var v/edx: (handle var)
17741 89/<- %edx 4/r32/esp
17743 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0)
17744 # var v-addr/edx: (addr var) = lookup(v)
17745 (lookup *edx *(edx+4)) # => eax
17746 89/<- %edx 0/r32/eax
17747 # check v-addr->name
17748 (lookup *edx *(edx+4)) # Var-name Var-name => eax
17749 (check-strings-equal %eax "x" "F - test-parse-var-with-type/name")
17750 # check v-addr->type
17751 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
17752 (check-ints-equal *eax 1 "F - test-parse-var-with-type/type:0") # Type-tree-is-atom
17753 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type/type:1") # Type-tree-value
17754 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type/type:2") # Type-tree-right
17756 89/<- %esp 5/r32/ebp
17760 test-parse-var-with-type-and-register:
17763 89/<- %ebp 4/r32/esp
17765 8b/-> *Primitive-type-ids 0/r32/eax
17766 89/<- *Type-id 0/r32/eax # stream-write
17767 # (eax..ecx) = "x/eax:"
17768 b8/copy-to-eax "x/eax:"/imm32
17769 8b/-> *eax 1/r32/ecx
17770 8d/copy-address *(eax+ecx+4) 1/r32/ecx
17771 05/add-to-eax 4/imm32
17772 # var slice/ecx: slice = {eax, ecx}
17775 89/<- %ecx 4/r32/esp
17776 # _test-input-stream contains "int"
17777 (clear-stream _test-input-stream)
17778 (write _test-input-stream "int")
17779 # var v/edx: (handle var)
17782 89/<- %edx 4/r32/esp
17784 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0)
17785 # var v-addr/edx: (addr var) = lookup(v)
17786 (lookup *edx *(edx+4)) # => eax
17787 89/<- %edx 0/r32/eax
17788 # check v-addr->name
17789 (lookup *edx *(edx+4)) # Var-name Var-name => eax
17790 (check-strings-equal %eax "x" "F - test-parse-var-with-type-and-register/name")
17791 # check v-addr->register
17792 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax
17793 (check-strings-equal %eax "eax" "F - test-parse-var-with-type-and-register/register")
17794 # check v-addr->type
17795 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
17796 (check-ints-equal *eax 1 "F - test-parse-var-with-type-and-register/type:0") # Type-tree-is-atom
17797 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type-and-register/type:1") # Type-tree-left
17798 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type-and-register/type:2") # Type-tree-right
17800 89/<- %esp 5/r32/ebp
17804 test-parse-var-with-trailing-characters:
17807 89/<- %ebp 4/r32/esp
17809 8b/-> *Primitive-type-ids 0/r32/eax
17810 89/<- *Type-id 0/r32/eax # stream-write
17811 # (eax..ecx) = "x:"
17812 b8/copy-to-eax "x:"/imm32
17813 8b/-> *eax 1/r32/ecx
17814 8d/copy-address *(eax+ecx+4) 1/r32/ecx
17815 05/add-to-eax 4/imm32
17816 # var slice/ecx: slice = {eax, ecx}
17819 89/<- %ecx 4/r32/esp
17820 # _test-input-stream contains "int,"
17821 (clear-stream _test-input-stream)
17822 (write _test-input-stream "int,")
17823 # var v/edx: (handle var)
17826 89/<- %edx 4/r32/esp
17828 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0)
17829 # var v-addr/edx: (addr var) = lookup(v)
17830 (lookup *edx *(edx+4)) # => eax
17831 89/<- %edx 0/r32/eax
17832 # check v-addr->name
17833 (lookup *edx *(edx+4)) # Var-name Var-name => eax
17834 (check-strings-equal %eax "x" "F - test-parse-var-with-trailing-characters/name")
17835 # check v-addr->register
17836 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-trailing-characters/register") # Var-register
17837 # check v-addr->type
17838 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
17839 (check-ints-equal *eax 1 "F - test-parse-var-with-trailing-characters/type:0") # Type-tree-is-atom
17840 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-left
17841 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-right
17843 89/<- %esp 5/r32/ebp
17847 test-parse-var-with-register-and-trailing-characters:
17850 89/<- %ebp 4/r32/esp
17852 8b/-> *Primitive-type-ids 0/r32/eax
17853 89/<- *Type-id 0/r32/eax # stream-write
17854 # (eax..ecx) = "x/eax:"
17855 b8/copy-to-eax "x/eax:"/imm32
17856 8b/-> *eax 1/r32/ecx
17857 8d/copy-address *(eax+ecx+4) 1/r32/ecx
17858 05/add-to-eax 4/imm32
17859 # var slice/ecx: slice = {eax, ecx}
17862 89/<- %ecx 4/r32/esp
17863 # _test-input-stream contains "int,"
17864 (clear-stream _test-input-stream)
17865 (write _test-input-stream "int,")
17866 # var v/edx: (handle var)
17869 89/<- %edx 4/r32/esp
17871 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0)
17872 # var v-addr/edx: (addr var) = lookup(v)
17873 (lookup *edx *(edx+4)) # => eax
17874 89/<- %edx 0/r32/eax
17875 # check v-addr->name
17876 (lookup *edx *(edx+4)) # Var-name Var-name => eax
17877 (check-strings-equal %eax "x" "F - test-parse-var-with-register-and-trailing-characters/name")
17878 # check v-addr->register
17879 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax
17880 (check-strings-equal %eax "eax" "F - test-parse-var-with-register-and-trailing-characters/register")
17881 # check v-addr->type
17882 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
17883 (check-ints-equal *eax 1 "F - test-parse-var-with-register-and-trailing-characters/type:0") # Type-tree-is-atom
17884 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-register-and-trailing-characters/type:1") # Type-tree-left
17885 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-register-and-trailing-characters/type:2") # Type-tree-right
17887 89/<- %esp 5/r32/ebp
17891 test-parse-var-with-compound-type:
17894 89/<- %ebp 4/r32/esp
17896 8b/-> *Primitive-type-ids 0/r32/eax
17897 89/<- *Type-id 0/r32/eax # stream-write
17898 # (eax..ecx) = "x:"
17899 b8/copy-to-eax "x:"/imm32
17900 8b/-> *eax 1/r32/ecx
17901 8d/copy-address *(eax+ecx+4) 1/r32/ecx
17902 05/add-to-eax 4/imm32
17903 # var slice/ecx: slice = {eax, ecx}
17906 89/<- %ecx 4/r32/esp
17907 # _test-input-stream contains "(addr int)"
17908 (clear-stream _test-input-stream)
17909 (write _test-input-stream "(addr int)")
17910 # var v/edx: (handle var)
17913 89/<- %edx 4/r32/esp
17915 (parse-var-with-type %ecx _test-input-stream %edx 0 Stderr 0)
17916 # var v-addr/edx: (addr var) = lookup(v)
17917 (lookup *edx *(edx+4)) # => eax
17918 89/<- %edx 0/r32/eax
17919 # check v-addr->name
17920 (lookup *edx *(edx+4)) # Var-name Var-name => eax
17921 (check-strings-equal %eax "x" "F - test-parse-var-with-compound-type/name")
17922 # check v-addr->register
17923 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-compound-type/register") # Var-register
17924 # - check v-addr->type
17925 # var type/edx: (addr type-tree) = var->type
17926 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
17927 89/<- %edx 0/r32/eax
17928 # type is a non-atom
17929 (check-ints-equal *edx 0 "F - test-parse-var-with-compound-type/type:0") # Type-tree-is-atom
17930 # type->left == atom(addr)
17931 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax
17932 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:1") # Type-tree-is-atom
17933 (check-ints-equal *(eax+4) 2 "F - test-parse-var-with-compound-type/type:2") # Type-tree-value
17934 # type->right->left == atom(int)
17935 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax
17936 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
17937 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:3") # Type-tree-is-atom
17938 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-compound-type/type:4") # Type-tree-value
17939 # type->right->right == null
17940 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-compound-type/type:5") # Type-tree-right
17942 89/<- %esp 5/r32/ebp
17946 # identifier starts with a letter or '$' or '_'
17947 # no constraints at the moment on later letters
17948 # all we really want to do so far is exclude '{', '}' and '->'
17949 identifier?: # in: (addr slice) -> result/eax: boolean
17952 89/<- %ebp 4/r32/esp
17953 # if (slice-empty?(in)) return false
17954 (slice-empty? *(ebp+8)) # => eax
17955 3d/compare-eax-and 0/imm32/false
17956 75/jump-if-!= $identifier?:false/disp8
17957 # var c/eax: byte = *in->start
17958 8b/-> *(ebp+8) 0/r32/eax
17959 8b/-> *eax 0/r32/eax
17960 8a/copy-byte *eax 0/r32/AL
17961 25/and-eax-with 0xff/imm32
17962 # if (c == '$') return true
17963 3d/compare-eax-and 0x24/imm32/$
17964 74/jump-if-= $identifier?:true/disp8
17965 # if (c == '_') return true
17966 3d/compare-eax-and 0x5f/imm32/_
17967 74/jump-if-= $identifier?:true/disp8
17969 25/and-eax-with 0x5f/imm32
17970 # if (c < 'A') return false
17971 3d/compare-eax-and 0x41/imm32/A
17972 7c/jump-if-< $identifier?:false/disp8
17973 # if (c > 'Z') return false
17974 3d/compare-eax-and 0x5a/imm32/Z
17975 7f/jump-if-> $identifier?:false/disp8
17976 # otherwise return true
17978 b8/copy-to-eax 1/imm32/true
17979 eb/jump $identifier?:end/disp8
17980 $identifier?:false:
17981 b8/copy-to-eax 0/imm32/false
17984 89/<- %esp 5/r32/ebp
17988 test-is-identifier-dollar:
17991 89/<- %ebp 4/r32/esp
17992 # (eax..ecx) = "$a"
17993 b8/copy-to-eax "$a"/imm32
17994 8b/-> *eax 1/r32/ecx
17995 8d/copy-address *(eax+ecx+4) 1/r32/ecx
17996 05/add-to-eax 4/imm32
17997 # var slice/ecx: slice = {eax, ecx}
18000 89/<- %ecx 4/r32/esp
18003 (check-ints-equal %eax 1 "F - test-is-identifier-dollar")
18005 89/<- %esp 5/r32/ebp
18009 test-is-identifier-underscore:
18012 89/<- %ebp 4/r32/esp
18013 # (eax..ecx) = "_a"
18014 b8/copy-to-eax "_a"/imm32
18015 8b/-> *eax 1/r32/ecx
18016 8d/copy-address *(eax+ecx+4) 1/r32/ecx
18017 05/add-to-eax 4/imm32
18018 # var slice/ecx: slice = {eax, ecx}
18021 89/<- %ecx 4/r32/esp
18024 (check-ints-equal %eax 1 "F - test-is-identifier-underscore")
18026 89/<- %esp 5/r32/ebp
18030 test-is-identifier-a:
18033 89/<- %ebp 4/r32/esp
18034 # (eax..ecx) = "a$"
18035 b8/copy-to-eax "a$"/imm32
18036 8b/-> *eax 1/r32/ecx
18037 8d/copy-address *(eax+ecx+4) 1/r32/ecx
18038 05/add-to-eax 4/imm32
18039 # var slice/ecx: slice = {eax, ecx}
18042 89/<- %ecx 4/r32/esp
18045 (check-ints-equal %eax 1 "F - test-is-identifier-a")
18047 89/<- %esp 5/r32/ebp
18051 test-is-identifier-z:
18054 89/<- %ebp 4/r32/esp
18055 # (eax..ecx) = "z$"
18056 b8/copy-to-eax "z$"/imm32
18057 8b/-> *eax 1/r32/ecx
18058 8d/copy-address *(eax+ecx+4) 1/r32/ecx
18059 05/add-to-eax 4/imm32
18060 # var slice/ecx: slice = {eax, ecx}
18063 89/<- %ecx 4/r32/esp
18066 (check-ints-equal %eax 1 "F - test-is-identifier-z")
18068 89/<- %esp 5/r32/ebp
18072 test-is-identifier-A:
18075 89/<- %ebp 4/r32/esp
18076 # (eax..ecx) = "A$"
18077 b8/copy-to-eax "A$"/imm32
18078 8b/-> *eax 1/r32/ecx
18079 8d/copy-address *(eax+ecx+4) 1/r32/ecx
18080 05/add-to-eax 4/imm32
18081 # var slice/ecx: slice = {eax, ecx}
18084 89/<- %ecx 4/r32/esp
18087 (check-ints-equal %eax 1 "F - test-is-identifier-A")
18089 89/<- %esp 5/r32/ebp
18093 test-is-identifier-Z:
18096 89/<- %ebp 4/r32/esp
18097 # (eax..ecx) = "Z$"
18098 b8/copy-to-eax "Z$"/imm32
18099 8b/-> *eax 1/r32/ecx
18100 8d/copy-address *(eax+ecx+4) 1/r32/ecx
18101 05/add-to-eax 4/imm32
18102 # var slice/ecx: slice = {eax, ecx}
18105 89/<- %ecx 4/r32/esp
18108 (check-ints-equal %eax 1 "F - test-is-identifier-Z")
18110 89/<- %esp 5/r32/ebp
18114 test-is-identifier-at:
18115 # character before 'A' is invalid
18118 89/<- %ebp 4/r32/esp
18119 # (eax..ecx) = "@a"
18120 b8/copy-to-eax "@a"/imm32
18121 8b/-> *eax 1/r32/ecx
18122 8d/copy-address *(eax+ecx+4) 1/r32/ecx
18123 05/add-to-eax 4/imm32
18124 # var slice/ecx: slice = {eax, ecx}
18127 89/<- %ecx 4/r32/esp
18130 (check-ints-equal %eax 0 "F - test-is-identifier-@")
18132 89/<- %esp 5/r32/ebp
18136 test-is-identifier-square-bracket:
18137 # character after 'Z' is invalid
18140 89/<- %ebp 4/r32/esp
18141 # (eax..ecx) = "[a"
18142 b8/copy-to-eax "[a"/imm32
18143 8b/-> *eax 1/r32/ecx
18144 8d/copy-address *(eax+ecx+4) 1/r32/ecx
18145 05/add-to-eax 4/imm32
18146 # var slice/ecx: slice = {eax, ecx}
18149 89/<- %ecx 4/r32/esp
18152 (check-ints-equal %eax 0 "F - test-is-identifier-@")
18154 89/<- %esp 5/r32/ebp
18158 test-is-identifier-backtick:
18159 # character before 'a' is invalid
18162 89/<- %ebp 4/r32/esp
18163 # (eax..ecx) = "`a"
18164 b8/copy-to-eax "`a"/imm32
18165 8b/-> *eax 1/r32/ecx
18166 8d/copy-address *(eax+ecx+4) 1/r32/ecx
18167 05/add-to-eax 4/imm32
18168 # var slice/ecx: slice = {eax, ecx}
18171 89/<- %ecx 4/r32/esp
18174 (check-ints-equal %eax 0 "F - test-is-identifier-backtick")
18176 89/<- %esp 5/r32/ebp
18180 test-is-identifier-curly-brace-open:
18181 # character after 'z' is invalid; also used for blocks
18184 89/<- %ebp 4/r32/esp
18185 # (eax..ecx) = "{a"
18186 b8/copy-to-eax "{a"/imm32
18187 8b/-> *eax 1/r32/ecx
18188 8d/copy-address *(eax+ecx+4) 1/r32/ecx
18189 05/add-to-eax 4/imm32
18190 # var slice/ecx: slice = {eax, ecx}
18193 89/<- %ecx 4/r32/esp
18196 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-open")
18198 89/<- %esp 5/r32/ebp
18202 test-is-identifier-curly-brace-close:
18205 89/<- %ebp 4/r32/esp
18206 # (eax..ecx) = "}a"
18207 b8/copy-to-eax "}a"/imm32
18208 8b/-> *eax 1/r32/ecx
18209 8d/copy-address *(eax+ecx+4) 1/r32/ecx
18210 05/add-to-eax 4/imm32
18211 # var slice/ecx: slice = {eax, ecx}
18214 89/<- %ecx 4/r32/esp
18217 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-close")
18219 89/<- %esp 5/r32/ebp
18223 test-is-identifier-hyphen:
18224 # disallow leading '-' since '->' has special meaning
18227 89/<- %ebp 4/r32/esp
18228 # (eax..ecx) = "-a"
18229 b8/copy-to-eax "-a"/imm32
18230 8b/-> *eax 1/r32/ecx
18231 8d/copy-address *(eax+ecx+4) 1/r32/ecx
18232 05/add-to-eax 4/imm32
18233 # var slice/ecx: slice = {eax, ecx}
18236 89/<- %ecx 4/r32/esp
18239 (check-ints-equal %eax 0 "F - test-is-identifier-hyphen")
18241 89/<- %esp 5/r32/ebp
18245 populate-mu-function-body: # in: (addr buffered-file), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor)
18248 89/<- %ebp 4/r32/esp
18254 8b/-> *(ebp+8) 6/r32/esi
18256 8b/-> *(ebp+0xc) 7/r32/edi
18257 # initialize some global state
18258 c7 0/subop/copy *Curr-block-depth 1/imm32
18259 # parse-mu-block(in, vars, out, out->body)
18260 8d/copy-address *(edi+0x18) 0/r32/eax # Function-body
18261 (parse-mu-block %esi *(ebp+0x10) %edi %eax *(ebp+0x14) *(ebp+0x18))
18262 $populate-mu-function-body:end:
18263 # . restore registers
18268 89/<- %esp 5/r32/ebp
18272 # parses a block, assuming that the leading '{' has already been read by the caller
18273 parse-mu-block: # in: (addr buffered-file), vars: (addr stack live-var), fn: (addr function), out: (addr handle block), err: (addr buffered-file), ed: (addr exit-descriptor)
18275 # var line: (stream byte 512)
18276 # var word-slice: slice
18277 # allocate(Heap, Stmt-size, out)
18278 # var out-addr: (addr block) = lookup(*out)
18279 # out-addr->tag = 0/block
18280 # out-addr->var = some unique name
18281 # push(vars, {out-addr->var, false})
18282 # while true # line loop
18283 # clear-stream(line)
18284 # read-line-buffered(in, line)
18285 # if (line->write == 0) break # end of file
18286 # word-slice = next-mu-token(line)
18287 # if slice-empty?(word-slice) # end of line
18289 # else if slice-starts-with?(word-slice, "#")
18291 # else if slice-equal?(word-slice, "{")
18292 # assert(no-tokens-in(line))
18293 # block = parse-mu-block(in, vars, fn)
18294 # append-to-block(out-addr, block)
18295 # else if slice-equal?(word-slice, "}")
18297 # else if slice-ends-with?(word-slice, ":")
18298 # if !slice-equal?(next-mu-token(line), "{")
18300 # --word-slice->end to skip ':'
18301 # named-block = parse-mu-named-block(word-slice, in, vars, fn)
18302 # append-to-block(out-addr, named-block)
18303 # else if slice-equal?(word-slice, "var")
18304 # var-def = parse-mu-var-def(line, vars, fn)
18305 # append-to-block(out-addr, var-def)
18307 # stmt = parse-mu-stmt(line, vars, fn)
18308 # append-to-block(out-addr, stmt)
18313 89/<- %ebp 4/r32/esp
18320 # var line/ecx: (stream byte 512)
18321 81 5/subop/subtract %esp 0x200/imm32
18322 68/push 0x200/imm32/size
18323 68/push 0/imm32/read
18324 68/push 0/imm32/write
18325 89/<- %ecx 4/r32/esp
18326 # var word-slice/edx: slice
18327 68/push 0/imm32/end
18328 68/push 0/imm32/start
18329 89/<- %edx 4/r32/esp
18330 # allocate into out
18331 (allocate Heap *Stmt-size *(ebp+0x14))
18332 # var out-addr/edi: (addr block) = lookup(*out)
18333 8b/-> *(ebp+0x14) 7/r32/edi
18334 (lookup *edi *(edi+4)) # => eax
18335 89/<- %edi 0/r32/eax
18336 # out-addr->tag is 0 (block) by default
18337 # set out-addr->var
18338 8d/copy-address *(edi+0xc) 0/r32/eax # Block-var
18339 (new-block-name *(ebp+0x10) %eax)
18340 # push(vars, out-addr->var)
18341 (push *(ebp+0xc) *(edi+0xc)) # Block-var
18342 (push *(ebp+0xc) *(edi+0x10)) # Block-var
18343 (push *(ebp+0xc) 0) # false
18344 # increment *Curr-block-depth
18345 ff 0/subop/increment *Curr-block-depth
18347 $parse-mu-block:line-loop:
18348 # line = read-line-buffered(in)
18349 (clear-stream %ecx)
18350 (read-line-buffered *(ebp+8) %ecx)
18351 #? (write-buffered Stderr "line: ")
18352 #? (write-stream-data Stderr %ecx)
18353 #? #? (write-buffered Stderr Newline) # line has its own newline
18355 #? (rewind-stream %ecx)
18356 # if (line->write == 0) break
18357 81 7/subop/compare *ecx 0/imm32
18358 0f 84/jump-if-= break/disp32
18359 #? (write-buffered Stderr "vars:\n")
18360 #? (dump-vars *(ebp+0xc))
18361 # word-slice = next-mu-token(line)
18362 (next-mu-token %ecx %edx)
18363 #? (write-buffered Stderr "word: ")
18364 #? (write-slice-buffered Stderr %edx)
18365 #? (write-buffered Stderr Newline)
18367 # if slice-empty?(word-slice) continue
18368 (slice-empty? %edx)
18369 3d/compare-eax-and 0/imm32/false
18370 0f 85/jump-if-!= loop/disp32
18371 # if (slice-starts-with?(word-slice, '#') continue
18372 # . eax = *word-slice->start
18373 8b/-> *edx 0/r32/eax
18374 8a/copy-byte *eax 0/r32/AL
18375 25/and-eax-with 0xff/imm32
18376 # . if (eax == '#') continue
18377 3d/compare-eax-and 0x23/imm32/hash
18378 0f 84/jump-if-= loop/disp32
18379 # if slice-equal?(word-slice, "{")
18381 $parse-mu-block:check-for-block:
18382 (slice-equal? %edx "{")
18383 3d/compare-eax-and 0/imm32/false
18384 74/jump-if-= break/disp8
18385 (check-no-tokens-left %ecx)
18386 # parse new block and append
18387 # . var tmp/eax: (handle block)
18390 89/<- %eax 4/r32/esp
18392 (parse-mu-block *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c))
18393 (append-to-block Heap %edi *eax *(eax+4))
18395 81 0/subop/add %esp 8/imm32
18397 e9/jump $parse-mu-block:line-loop/disp32
18399 # if slice-equal?(word-slice, "}") break
18400 $parse-mu-block:check-for-end:
18401 (slice-equal? %edx "}")
18402 3d/compare-eax-and 0/imm32/false
18403 0f 85/jump-if-!= break/disp32
18404 # if slice-ends-with?(word-slice, ":") parse named block and append
18406 $parse-mu-block:check-for-named-block:
18407 # . eax = *(word-slice->end-1)
18408 8b/-> *(edx+4) 0/r32/eax
18410 8a/copy-byte *eax 0/r32/AL
18411 25/and-eax-with 0xff/imm32
18412 # . if (eax != ':') break
18413 3d/compare-eax-and 0x3a/imm32/colon
18414 0f 85/jump-if-!= break/disp32
18415 # if next-mu-token(line) != "{", abort
18416 (check-next-token-is-open-curly %ecx *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c))
18418 ff 1/subop/decrement *(edx+4) # Slice-end
18419 # var tmp/eax: (handle block)
18422 89/<- %eax 4/r32/esp
18424 (parse-mu-named-block %edx *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c))
18425 (append-to-block Heap %edi *eax *(eax+4))
18427 81 0/subop/add %esp 8/imm32
18429 e9/jump $parse-mu-block:line-loop/disp32
18431 # if slice-equal?(word-slice, "var")
18433 $parse-mu-block:check-for-var:
18434 (slice-equal? %edx "var")
18435 3d/compare-eax-and 0/imm32/false
18436 74/jump-if-= break/disp8
18437 # var tmp/eax: (handle block)
18440 89/<- %eax 4/r32/esp
18442 (parse-mu-var-def %ecx *(ebp+0xc) %eax *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c))
18443 (append-to-block Heap %edi *eax *(eax+4))
18445 81 0/subop/add %esp 8/imm32
18447 e9/jump $parse-mu-block:line-loop/disp32
18449 $parse-mu-block:regular-stmt:
18451 # var tmp/eax: (handle block)
18454 89/<- %eax 4/r32/esp
18456 (parse-mu-stmt %ecx *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c))
18457 (append-to-block Heap %edi *eax *(eax+4))
18459 81 0/subop/add %esp 8/imm32
18461 e9/jump loop/disp32
18463 (clean-up-blocks *(ebp+0xc) *Curr-block-depth *(ebp+0x10))
18464 # decrement *Curr-block-depth
18465 ff 1/subop/decrement *Curr-block-depth
18467 (pop *(ebp+0xc)) # => eax
18468 (pop *(ebp+0xc)) # => eax
18469 (pop *(ebp+0xc)) # => eax
18470 $parse-mu-block:end:
18472 81 0/subop/add %esp 0x214/imm32
18473 # . restore registers
18480 89/<- %esp 5/r32/ebp
18484 $parse-mu-block:abort:
18485 # error("'{' or '}' should be on its own line, but got '")
18486 (write-buffered *(ebp+0x18) "'{' or '}' should be on its own line, but got '")
18487 (rewind-stream %ecx)
18488 (write-stream-data *(ebp+0x18) %ecx)
18489 (write-buffered *(ebp+0x18) "'\n")
18490 (flush *(ebp+0x18))
18491 (stop *(ebp+0x1c) 1)
18494 check-next-token-is-open-curly: # line: (addr stream byte), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
18497 89/<- %ebp 4/r32/esp
18501 # var word-slice/edx: slice
18502 68/push 0/imm32/end
18503 68/push 0/imm32/start
18504 89/<- %edx 4/r32/esp
18505 # word-slice = next-mu-token(line)
18506 (next-mu-token *(ebp+8) %edx)
18507 # if !slice-equal?(word-slice, "{") abort
18508 (slice-equal? %edx "{") # => eax
18509 3d/compare-eax-and 0/imm32/false
18510 0f 84/jump-if-= $check-next-token-is-open-curly:abort/disp32
18511 $check-next-token-is-open-curly:end:
18513 81 0/subop/add %esp 8/imm32
18514 # . restore registers
18518 89/<- %esp 5/r32/ebp
18522 $check-next-token-is-open-curly:abort:
18523 # error("fn " fn ": unexpected ':'; did you forget a 'var'?")
18524 (write-buffered *(ebp+0x10) "fn ")
18525 8b/-> *(ebp+0xc) 0/r32/eax
18526 (lookup *eax *(eax+4)) # Function-name Function-name => eax
18527 (write-buffered *(ebp+0x10) %eax)
18528 (write-buffered *(ebp+0x10) ": unexpected ':'; did you forget a 'var'?\n")
18529 (flush *(ebp+0x10))
18530 (stop *(ebp+0x14) 1)
18533 new-block-name: # fn: (addr function), out: (addr handle var)
18536 89/<- %ebp 4/r32/esp
18541 # var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:'
18542 8b/-> *(ebp+8) 0/r32/eax
18543 (lookup *eax *(eax+4)) # Function-name Function-name => eax
18544 8b/-> *eax 0/r32/eax # String-size
18545 05/add-to-eax 0xd/imm32 # 10 + 2 for '$:'
18546 89/<- %ecx 0/r32/eax
18547 # var name/edx: (stream byte n)
18548 29/subtract-from %esp 1/r32/ecx
18549 ff 6/subop/push %ecx
18550 68/push 0/imm32/read
18551 68/push 0/imm32/write
18552 89/<- %edx 4/r32/esp
18553 (clear-stream %edx)
18555 8b/-> *(ebp+8) 0/r32/eax
18556 (lookup *eax *(eax+4)) # Function-name Function-name => eax
18557 # construct result using Next-block-index (and increment it)
18561 (write-int32-hex %edx *Next-block-index)
18562 ff 0/subop/increment *Next-block-index
18563 # var s/eax: slice = {name->data, name->data + name->write} (clobbering edx)
18564 # . eax = name->write
18565 8b/-> *edx 0/r32/eax
18566 # . edx = name->data
18567 8d/copy-address *(edx+0xc) 2/r32/edx
18568 # . eax = name->write + name->data
18569 01/add-to %eax 2/r32/edx
18570 # . push {edx, eax}
18571 ff 6/subop/push %eax
18572 ff 6/subop/push %edx
18573 89/<- %eax 4/r32/esp
18574 # out = new literal(s)
18575 (new-literal Heap %eax *(ebp+0xc))
18576 #? 8b/-> *(ebp+0xc) 0/r32/eax
18577 #? (write-buffered Stderr "type allocid in caller after new-literal: ")
18578 #? (write-int32-hex-buffered Stderr *(eax+8))
18579 #? (write-buffered Stderr " for var ")
18580 #? (write-int32-hex-buffered Stderr %eax)
18581 #? (write-buffered Stderr Newline)
18583 $new-block-name:end:
18585 81 0/subop/add %ecx 0xc/imm32 # name.{read/write/len}
18586 81 0/subop/add %ecx 8/imm32 # slice
18587 01/add-to %esp 1/r32/ecx
18588 # . restore registers
18593 89/<- %esp 5/r32/ebp
18597 check-no-tokens-left: # line: (addr stream byte)
18600 89/<- %ebp 4/r32/esp
18605 68/push 0/imm32/end
18606 68/push 0/imm32/start
18607 89/<- %ecx 4/r32/esp
18609 (next-mu-token *(ebp+8) %ecx)
18610 # if slice-empty?(s) return
18611 (slice-empty? %ecx)
18612 3d/compare-eax-and 0/imm32/false
18613 75/jump-if-!= $check-no-tokens-left:end/disp8
18614 # if (slice-starts-with?(s, '#') return
18615 # . eax = *s->start
18616 8b/-> *edx 0/r32/eax
18617 8a/copy-byte *eax 0/r32/AL
18618 25/and-eax-with 0xff/imm32
18619 # . if (eax == '#') continue
18620 3d/compare-eax-and 0x23/imm32/hash
18621 74/jump-if-= $check-no-tokens-left:end/disp8
18623 (write-buffered Stderr "'{' or '}' should be on its own line, but got '")
18624 (rewind-stream %ecx)
18625 (write-stream 2 %ecx)
18626 (write-buffered Stderr "'\n")
18628 # . syscall_exit(1)
18629 bb/copy-to-ebx 1/imm32
18630 e8/call syscall_exit/disp32
18632 $check-no-tokens-left:end:
18634 81 0/subop/add %esp 8/imm32
18635 # . restore registers
18639 89/<- %esp 5/r32/ebp
18643 parse-mu-named-block: # name: (addr slice), in: (addr buffered-file), vars: (addr stack live-var), fn: (addr function), out: (addr handle stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
18645 # var v: (handle var)
18646 # new-literal(name, v)
18647 # push(vars, {v, false})
18648 # parse-mu-block(in, vars, fn, out)
18655 89/<- %ebp 4/r32/esp
18660 # var v/ecx: (handle var)
18663 89/<- %ecx 4/r32/esp
18665 (new-literal Heap *(ebp+8) %ecx)
18667 (push *(ebp+0x10) *ecx)
18668 (push *(ebp+0x10) *(ecx+4))
18669 (push *(ebp+0x10) 0) # false
18671 (parse-mu-block *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20))
18673 (pop *(ebp+0x10)) # => eax
18674 (pop *(ebp+0x10)) # => eax
18675 (pop *(ebp+0x10)) # => eax
18676 # var out-addr/edi: (addr stmt) = lookup(*out)
18677 8b/-> *(ebp+0x18) 7/r32/edi
18678 (lookup *edi *(edi+4)) # => eax
18679 89/<- %edi 0/r32/eax
18680 # out-addr->tag = named-block
18681 c7 0/subop/copy *edi 0/imm32/block # Stmt-tag
18682 # out-addr->var = v
18683 8b/-> *ecx 0/r32/eax
18684 89/<- *(edi+0xc) 0/r32/eax # Block-var
18685 8b/-> *(ecx+4) 0/r32/eax
18686 89/<- *(edi+0x10) 0/r32/eax # Block-var
18687 $parse-mu-named-block:end:
18689 81 0/subop/add %esp 8/imm32
18690 # . restore registers
18695 89/<- %esp 5/r32/ebp
18699 parse-mu-var-def: # line: (addr stream byte), vars: (addr stack live-var), out: (addr handle stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
18702 89/<- %ebp 4/r32/esp
18710 8b/-> *(ebp+0x10) 7/r32/edi
18711 # var word-slice/ecx: slice
18712 68/push 0/imm32/end
18713 68/push 0/imm32/start
18714 89/<- %ecx 4/r32/esp
18715 # var v/edx: (handle var)
18718 89/<- %edx 4/r32/esp
18719 # v = parse-var-with-type(next-mu-token(line))
18720 (next-mu-token *(ebp+8) %ecx)
18722 # just for tests, support null fn
18723 8b/-> *(ebp+0x14) 0/r32/eax
18724 3d/compare-eax-and 0/imm32
18725 74/jump-if-= break/disp8
18726 (lookup *eax *(eax+4)) # Var-name Var-name => eax
18728 (parse-var-with-type %ecx *(ebp+8) %edx %eax *(ebp+0x18) *(ebp+0x1c))
18729 # var v-addr/esi: (addr var)
18730 (lookup *edx *(edx+4)) # => eax
18731 89/<- %esi 0/r32/eax
18732 # v->block-depth = *Curr-block-depth
18733 8b/-> *Curr-block-depth 0/r32/eax
18734 89/<- *(esi+0x10) 0/r32/eax # Var-block-depth
18735 # either v has no register and there's no more to this line
18736 81 7/subop/compare *(esi+0x18) 0/imm32
18738 75/jump-if-!= break/disp8
18739 # if v-addr->type == byte, abort
18740 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax
18741 (simple-mu-type? %eax 8) # byte => eax
18742 3d/compare-eax-and 0/imm32/false
18743 0f 85/jump-if-!= $parse-mu-var-def:error-byte-on-stack/disp32
18744 # ensure that there's nothing else on this line
18745 (next-mu-token *(ebp+8) %ecx)
18746 (slice-empty? %ecx) # => eax
18747 3d/compare-eax-and 0/imm32/false
18748 0f 84/jump-if-= $parse-mu-var-def:error2/disp32
18750 (new-var-def Heap *edx *(edx+4) %edi)
18751 e9/jump $parse-mu-var-def:update-vars/disp32
18753 # or v has a register and there's more to this line
18755 0f 84/jump-if-= break/disp32
18756 # if v-addr->type == byte, check for unsupported registers
18758 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax
18759 (simple-mu-type? %eax 8) # byte => eax
18760 3d/compare-eax-and 0/imm32/false
18761 74/jump-if-= break/disp8
18762 (lookup *(esi+0x18) *(esi+0x1c)) # => eax
18763 (string-equal? %eax "esi") # => eax
18764 3d/compare-eax-and 0/imm32/false
18765 0f 85/jump-if-!= $parse-mu-var-def:error-byte-registers/disp32
18766 (lookup *(esi+0x18) *(esi+0x1c)) # => eax
18767 (string-equal? %eax "edi") # => eax
18768 3d/compare-eax-and 0/imm32/false
18769 0f 85/jump-if-!= $parse-mu-var-def:error-byte-registers/disp32
18771 # TODO: vars of type 'byte' should only be initialized by clearing to 0
18772 # ensure that the next word is '<-'
18773 (next-mu-token *(ebp+8) %ecx)
18774 (slice-equal? %ecx "<-") # => eax
18775 3d/compare-eax-and 0/imm32/false
18776 0f 84/jump-if-= $parse-mu-var-def:error1/disp32
18778 (new-reg-var-def Heap *edx *(edx+4) %edi)
18779 (lookup *edi *(edi+4)) # => eax
18780 (add-operation-and-inputs-to-stmt %eax *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c))
18782 $parse-mu-var-def:update-vars:
18783 # push 'v' at end of function
18784 (push *(ebp+0xc) *edx)
18785 (push *(ebp+0xc) *(edx+4))
18786 (push *(ebp+0xc) 0) # Live-var-register-spilled is unused during parsing
18787 $parse-mu-var-def:end:
18789 81 0/subop/add %esp 0x10/imm32
18790 # . restore registers
18797 89/<- %esp 5/r32/ebp
18801 $parse-mu-var-def:error1:
18802 (rewind-stream *(ebp+8))
18803 # error("register variable requires a valid instruction to initialize but got '" line "'\n")
18804 (write-buffered *(ebp+0x18) "register variable requires a valid instruction to initialize but got '")
18805 (flush *(ebp+0x18))
18806 (write-stream-data *(ebp+0x18) *(ebp+8))
18807 (write-buffered *(ebp+0x18) "'\n")
18808 (flush *(ebp+0x18))
18809 (stop *(ebp+0x1c) 1)
18812 $parse-mu-var-def:error2:
18813 # error("fn " fn ": var " var ": variables on the stack can't take an initializer\n")
18814 (write-buffered *(ebp+0x18) "fn ")
18815 8b/-> *(ebp+0x14) 0/r32/eax
18816 (lookup *eax *(eax+4)) # Function-name Function-name => eax
18817 (write-buffered *(ebp+0x18) %eax)
18818 (write-buffered *(ebp+0x18) ": var ")
18819 # var v-addr/eax: (addr var) = lookup(v)
18820 (lookup *edx *(edx+4)) # => eax
18821 (lookup *eax *(eax+4)) # Var-name Var-name => eax
18822 (write-buffered *(ebp+0x18) %eax)
18823 (write-buffered *(ebp+0x18) ": variables on the stack can't take an initializer\n")
18824 (flush *(ebp+0x18))
18825 (stop *(ebp+0x1c) 1)
18828 $parse-mu-var-def:error-byte-on-stack:
18829 # error("fn " fn ": var '" var "' of type 'byte' cannot be on the stack\n")
18830 (write-buffered *(ebp+0x18) "fn ")
18831 8b/-> *(ebp+0x14) 0/r32/eax
18832 (lookup *eax *(eax+4)) # Function-name Function-name => eax
18833 (write-buffered *(ebp+0x18) %eax)
18834 (write-buffered *(ebp+0x18) ": var '")
18835 # var v-addr/eax: (addr var) = lookup(v)
18836 (lookup *edx *(edx+4)) # => eax
18837 (lookup *eax *(eax+4)) # Var-name Var-name => eax
18838 (write-buffered *(ebp+0x18) %eax)
18839 (write-buffered *(ebp+0x18) "' of type 'byte' cannot be on the stack\n")
18840 (flush *(ebp+0x18))
18841 (stop *(ebp+0x1c) 1)
18844 $parse-mu-var-def:error-byte-registers:
18845 # error("fn " fn ": var '" var "' of type 'byte' cannot be in esi or edi\n")
18846 (write-buffered *(ebp+0x18) "fn ")
18847 8b/-> *(ebp+0x14) 0/r32/eax
18848 (lookup *eax *(eax+4)) # Function-name Function-name => eax
18849 (write-buffered *(ebp+0x18) %eax)
18850 (write-buffered *(ebp+0x18) ": var '")
18851 # var v-addr/eax: (addr var) = lookup(v)
18852 (lookup *edx *(edx+4)) # => eax
18853 (lookup *eax *(eax+4)) # Var-name Var-name => eax
18854 (write-buffered *(ebp+0x18) %eax)
18855 (write-buffered *(ebp+0x18) "' of type 'byte' cannot be in esi or edi\n")
18856 (flush *(ebp+0x18))
18857 (stop *(ebp+0x1c) 1)
18860 test-parse-mu-var-def:
18864 89/<- %ebp 4/r32/esp
18866 8b/-> *Primitive-type-ids 0/r32/eax
18867 89/<- *Type-id 0/r32/eax # stream-write
18868 (clear-stream _test-input-stream)
18869 (write _test-input-stream "n: int\n") # caller has consumed the 'var'
18870 c7 0/subop/copy *Curr-block-depth 1/imm32
18871 # var out/esi: (handle stmt)
18874 89/<- %esi 4/r32/esp
18875 # var vars/ecx: (stack (addr var) 16)
18876 81 5/subop/subtract %esp 0xc0/imm32
18877 68/push 0xc0/imm32/size
18878 68/push 0/imm32/top
18879 89/<- %ecx 4/r32/esp
18882 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0)
18883 # var out-addr/esi: (addr stmt)
18884 (lookup *esi *(esi+4)) # => eax
18885 89/<- %esi 0/r32/eax
18887 (check-ints-equal *esi 2 "F - test-parse-mu-var-def/tag") # Stmt-tag is var-def
18888 # var v/ecx: (addr var) = lookup(out->var)
18889 (lookup *(esi+4) *(esi+8)) # Vardef-var Vardef-var => eax
18890 89/<- %ecx 0/r32/eax
18892 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
18893 (check-strings-equal %eax "n" "F - test-parse-mu-var-def/var-name")
18895 (check-ints-equal *(ecx+0x18) 0 "F - test-parse-mu-var-def/var-register") # Var-register
18897 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-var-def/output-block-depth") # Var-block-depth
18899 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
18900 (check-ints-equal *eax 1 "F - test-parse-mu-var-def/var-type:0") # Type-tree-is-atom
18901 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-var-def/var-type:1") # Type-tree-value
18902 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-var-def/var-type:2") # Type-tree-right
18904 89/<- %esp 5/r32/ebp
18908 test-parse-mu-reg-var-def:
18909 # 'var n/eax: int <- copy 0'
18912 89/<- %ebp 4/r32/esp
18914 8b/-> *Primitive-type-ids 0/r32/eax
18915 89/<- *Type-id 0/r32/eax # stream-write
18916 (clear-stream _test-input-stream)
18917 (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var'
18918 c7 0/subop/copy *Curr-block-depth 1/imm32
18919 # var out/esi: (handle stmt)
18922 89/<- %esi 4/r32/esp
18923 # var vars/ecx: (stack (addr var) 16)
18924 81 5/subop/subtract %esp 0xc0/imm32
18925 68/push 0xc0/imm32/size
18926 68/push 0/imm32/top
18927 89/<- %ecx 4/r32/esp
18930 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0)
18931 # var out-addr/esi: (addr stmt)
18932 (lookup *esi *(esi+4)) # => eax
18933 89/<- %esi 0/r32/eax
18935 (check-ints-equal *esi 3 "F - test-parse-mu-reg-var-def/tag") # Stmt-tag is reg-var-def
18936 # var v/ecx: (addr var) = lookup(out->outputs->value)
18937 # . eax: (addr stmt-var) = lookup(out->outputs)
18938 (lookup *(esi+0x14) *(esi+0x18)) # Regvardef-outputs Regvardef-outputs => eax
18940 (check-ints-equal *(eax+8) 0 "F - test-parse-mu-reg-var-def/single-output") # Stmt-var-next
18941 # . eax: (addr var) = lookup(eax->value)
18942 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
18944 89/<- %ecx 0/r32/eax
18946 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
18947 (check-strings-equal %eax "n" "F - test-parse-mu-reg-var-def/output-name") # Var-name
18949 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax
18950 (check-strings-equal %eax "eax" "F - test-parse-mu-reg-var-def/output-register")
18952 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-reg-var-def/output-block-depth") # Var-block-depth
18954 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
18955 (check-ints-equal *eax 1 "F - test-parse-mu-reg-var-def/output-type:0") # Type-tree-is-atom
18956 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-reg-var-def/output-type:1") # Type-tree-value
18957 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-reg-var-def/output-type:2") # Type-tree-right
18959 89/<- %esp 5/r32/ebp
18963 parse-mu-stmt: # line: (addr stream byte), vars: (addr stack live-var), fn: (addr function), out: (addr handle stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
18966 # allocate(Heap, Stmt-size, out)
18967 # var out-addr: (addr stmt) = lookup(*out)
18968 # out-addr->tag = stmt
18969 # if stmt-has-outputs?(line)
18971 # name = next-mu-token(line)
18972 # if (name == '<-') break
18973 # assert(identifier?(name))
18974 # var v: (handle var) = lookup-var(name, vars)
18975 # out-addr->outputs = append(v, out-addr->outputs)
18976 # add-operation-and-inputs-to-stmt(out-addr, line, vars)
18980 89/<- %ebp 4/r32/esp
18987 # var name/ecx: slice
18988 68/push 0/imm32/end
18989 68/push 0/imm32/start
18990 89/<- %ecx 4/r32/esp
18991 # var is-deref?/edx: boolean = false
18992 ba/copy-to-edx 0/imm32/false
18993 # var v: (handle var)
18996 89/<- %ebx 4/r32/esp
18998 (allocate Heap *Stmt-size *(ebp+0x14))
18999 # var out-addr/edi: (addr stmt) = lookup(*out)
19000 8b/-> *(ebp+0x14) 7/r32/edi
19001 (lookup *edi *(edi+4)) # => eax
19002 89/<- %edi 0/r32/eax
19003 # out-addr->tag = 1/stmt
19004 c7 0/subop/copy *edi 1/imm32/stmt1 # Stmt-tag
19006 (stmt-has-outputs? *(ebp+8))
19007 3d/compare-eax-and 0/imm32/false
19008 0f 84/jump-if-= break/disp32
19010 $parse-mu-stmt:read-outputs:
19011 # name = next-mu-token(line)
19012 (next-mu-token *(ebp+8) %ecx)
19013 # if slice-empty?(word-slice) break
19014 (slice-empty? %ecx) # => eax
19015 3d/compare-eax-and 0/imm32/false
19016 0f 85/jump-if-!= break/disp32
19017 # if (name == "<-") break
19018 (slice-equal? %ecx "<-") # => eax
19019 3d/compare-eax-and 0/imm32/false
19020 0f 85/jump-if-!= break/disp32
19021 # if slice-starts-with?(name, "*") abort
19022 8b/-> *ecx 0/r32/eax # Slice-start
19023 8a/copy-byte *eax 0/r32/AL
19024 25/and-eax-with 0xff/imm32
19025 3d/compare-eax-and 0x2a/imm32/asterisk
19026 0f 84/jump-if-= $parse-mu-stmt:error-output-dereferenced/disp32
19027 # assert(identifier?(name))
19028 (identifier? %ecx) # => eax
19029 3d/compare-eax-and 0/imm32/false
19030 0f 84/jump-if-= $parse-mu-stmt:abort/disp32
19032 (lookup-var %ecx *(ebp+0xc) %ebx *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c))
19033 8d/copy-address *(edi+0x14) 0/r32/eax # Stmt1-outputs
19034 (append-stmt-var Heap *ebx *(ebx+4) *(edi+0x14) *(edi+0x18) 0 %eax) # Stmt1-outputs
19036 e9/jump loop/disp32
19039 (add-operation-and-inputs-to-stmt %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c))
19040 $parse-mu-stmt:end:
19042 81 0/subop/add %esp 0x10/imm32
19043 # . restore registers
19050 89/<- %esp 5/r32/ebp
19054 $parse-mu-stmt:abort:
19055 # error("invalid identifier '" name "'\n")
19056 (write-buffered *(ebp+0x18) "fn ")
19057 8b/-> *(ebp+0x10) 0/r32/eax
19058 (lookup *eax *(eax+4)) # Function-name Function-name => eax
19059 (write-buffered *(ebp+0x18) %eax)
19060 (write-buffered *(ebp+0x18) ": invalid identifier '")
19061 (write-slice-buffered *(ebp+0x18) %ecx)
19062 (write-buffered *(ebp+0x18) "'\n")
19063 (flush *(ebp+0x18))
19064 (stop *(ebp+0x1c) 1)
19067 $parse-mu-stmt:error-output-dereferenced:
19068 # error("invalid identifier '" name "'\n")
19069 (write-buffered *(ebp+0x18) "fn ")
19070 8b/-> *(ebp+0x10) 0/r32/eax
19071 (lookup *eax *(eax+4)) # Function-name Function-name => eax
19072 (write-buffered *(ebp+0x18) %eax)
19073 (write-buffered *(ebp+0x18) ": output '")
19074 (write-slice-buffered *(ebp+0x18) %ecx)
19075 (write-buffered *(ebp+0x18) "' should write to a register, and therefore cannot be dereferenced\n")
19076 (flush *(ebp+0x18))
19077 (stop *(ebp+0x1c) 1)
19080 add-operation-and-inputs-to-stmt: # stmt: (addr stmt), line: (addr stream byte), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
19082 # stmt->name = slice-to-string(next-mu-token(line))
19084 # name = next-mu-token(line)
19085 # v = lookup-var-or-literal(name)
19086 # stmt->inouts = append(v, stmt->inouts)
19090 89/<- %ebp 4/r32/esp
19099 8b/-> *(ebp+8) 7/r32/edi
19100 # var name/ecx: slice
19101 68/push 0/imm32/end
19102 68/push 0/imm32/start
19103 89/<- %ecx 4/r32/esp
19104 # var is-deref?/edx: boolean = false
19105 ba/copy-to-edx 0/imm32/false
19106 # var v/esi: (handle var)
19109 89/<- %esi 4/r32/esp
19110 $add-operation-and-inputs-to-stmt:read-operation:
19111 (next-mu-token *(ebp+0xc) %ecx)
19112 8d/copy-address *(edi+4) 0/r32/eax # Stmt1-operation or Regvardef-operationStmt1-operation or Regvardef-operation
19113 (slice-to-string Heap %ecx %eax)
19114 # var is-get?/ebx: boolean = (name == "get")
19115 (slice-equal? %ecx "get") # => eax
19116 89/<- %ebx 0/r32/eax
19118 $add-operation-and-inputs-to-stmt:read-inouts:
19119 # name = next-mu-token(line)
19120 (next-mu-token *(ebp+0xc) %ecx)
19121 # if slice-empty?(word-slice) break
19122 (slice-empty? %ecx) # => eax
19123 3d/compare-eax-and 0/imm32/false
19124 0f 85/jump-if-!= break/disp32
19125 # if (name == "<-") abort
19126 (slice-equal? %ecx "<-")
19127 3d/compare-eax-and 0/imm32/false
19128 0f 85/jump-if-!= $add-operation-and-inputs-to-stmt:abort/disp32
19129 # if (get? && second operand) lookup or create offset
19131 81 7/subop/compare %ebx 0/imm32/false
19132 74/jump-if-= break/disp8
19133 (lookup *(edi+0xc) *(edi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
19134 3d/compare-eax-and 0/imm32
19135 74/jump-if-= break/disp8
19136 (lookup-or-create-constant %eax %ecx %esi)
19137 #? (lookup *esi *(esi+4))
19138 #? (write-buffered Stderr "creating new output var ")
19139 #? (write-int32-hex-buffered Stderr %eax)
19140 #? (write-buffered Stderr " for field called ")
19141 #? (write-slice-buffered Stderr %ecx)
19142 #? (write-buffered Stderr "; var name ")
19143 #? (lookup *eax *(eax+4)) # Var-name
19144 #? (write-buffered Stderr %eax)
19145 #? (write-buffered Stderr Newline)
19147 e9/jump $add-operation-and-inputs-to-stmt:save-var/disp32
19149 # is-deref? = false
19150 ba/copy-to-edx 0/imm32/false
19151 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref?
19152 8b/-> *ecx 0/r32/eax # Slice-start
19153 8a/copy-byte *eax 0/r32/AL
19154 25/and-eax-with 0xff/imm32
19155 3d/compare-eax-and 0x2a/imm32/asterisk
19157 75/jump-if-!= break/disp8
19158 $add-operation-and-inputs-to-stmt:inout-is-deref:
19159 ff 0/subop/increment *ecx
19160 ba/copy-to-edx 1/imm32/true
19162 (lookup-var-or-literal %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c))
19163 # if (deref?) some additional checks
19164 81 7/subop/compare %edx 0/imm32/false
19166 74/jump-if-= break/disp8
19167 # if var is not in register, abort
19168 (lookup *esi *(esi+4)) # => eax
19169 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register
19170 0f 84/jump-if-= $add-operation-and-inputs-to-stmt:error-deref-on-stack/disp32
19171 # if var is not an address, abort
19172 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
19173 (mu-addr-type? %eax) # => eax
19174 3d/compare-eax-and 0/imm32/false
19175 0f 84/jump-if-= $add-operation-and-inputs-to-stmt:error-deref-non-addr/disp32
19177 $add-operation-and-inputs-to-stmt:save-var:
19178 8d/copy-address *(edi+0xc) 0/r32/eax
19179 (append-stmt-var Heap *esi *(esi+4) *(edi+0xc) *(edi+0x10) %edx %eax) # Stmt1-inouts or Regvardef-inouts
19181 e9/jump loop/disp32
19183 $add-operation-and-inputs-to-stmt:end:
19185 81 0/subop/add %esp 0x10/imm32
19186 # . restore registers
19194 89/<- %esp 5/r32/ebp
19198 $add-operation-and-inputs-to-stmt:abort:
19199 # error("fn ___: invalid identifier in '" line "'\n")
19200 (write-buffered *(ebp+0x18) "fn ")
19201 8b/-> *(ebp+0x14) 0/r32/eax
19202 (lookup *eax *(eax+4)) # Function-name Function-name => eax
19203 (write-buffered *(ebp+0x18) %eax)
19204 (rewind-stream *(ebp+0xc))
19205 (write-buffered *(ebp+0x18) ": invalid identifier in '")
19206 (write-stream-data *(ebp+0x18) *(ebp+0xc))
19207 (write-buffered *(ebp+0x18) "'\n")
19208 (flush *(ebp+0x18))
19209 (stop *(ebp+0x1c) 1)
19212 $add-operation-and-inputs-to-stmt:error-deref-on-stack:
19213 # error("fn ___: cannot dereference var ___ on stack\n")
19214 (write-buffered *(ebp+0x18) "fn ")
19215 8b/-> *(ebp+0x14) 0/r32/eax
19216 (lookup *eax *(eax+4)) # Function-name Function-name => eax
19217 (write-buffered *(ebp+0x18) %eax)
19218 (rewind-stream *(ebp+0xc))
19219 (write-buffered *(ebp+0x18) ": cannot dereference var '")
19220 (lookup *esi *(esi+4)) # => eax
19221 (lookup *eax *(eax+4)) # Var-name Var-name => eax
19222 (write-buffered *(ebp+0x18) %eax)
19223 (write-buffered *(ebp+0x18) "' on stack\n")
19224 (flush *(ebp+0x18))
19225 (stop *(ebp+0x1c) 1)
19228 $add-operation-and-inputs-to-stmt:error-deref-non-addr:
19229 # error("fn ___: cannot dereference non-addr var ___\n")
19230 (write-buffered *(ebp+0x18) "fn ")
19231 8b/-> *(ebp+0x14) 0/r32/eax
19232 (lookup *eax *(eax+4)) # Function-name Function-name => eax
19233 (write-buffered *(ebp+0x18) %eax)
19234 (rewind-stream *(ebp+0xc))
19235 (write-buffered *(ebp+0x18) ": cannot dereference non-addr var '")
19236 (lookup *esi *(esi+4)) # => eax
19237 (lookup *eax *(eax+4)) # Var-name Var-name => eax
19238 (write-buffered *(ebp+0x18) %eax)
19239 (write-buffered *(ebp+0x18) "'\n")
19240 (flush *(ebp+0x18))
19241 (stop *(ebp+0x1c) 1)
19244 stmt-has-outputs?: # line: (addr stream byte) -> result/eax: boolean
19247 89/<- %ebp 4/r32/esp
19250 # var word-slice/ecx: slice
19251 68/push 0/imm32/end
19252 68/push 0/imm32/start
19253 89/<- %ecx 4/r32/esp
19255 b8/copy-to-eax 0/imm32/false
19256 (rewind-stream *(ebp+8))
19258 (next-mu-token *(ebp+8) %ecx)
19259 # if slice-empty?(word-slice) break
19260 (slice-empty? %ecx)
19261 3d/compare-eax-and 0/imm32/false
19262 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false)
19263 0f 85/jump-if-!= break/disp32
19264 # if slice-starts-with?(word-slice, '#') break
19265 # . eax = *word-slice->start
19266 8b/-> *ecx 0/r32/eax
19267 8a/copy-byte *eax 0/r32/AL
19268 25/and-eax-with 0xff/imm32
19269 # . if (eax == '#') break
19270 3d/compare-eax-and 0x23/imm32/hash
19271 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false)
19272 0f 84/jump-if-= break/disp32
19273 # if slice-equal?(word-slice, '<-') return true
19274 (slice-equal? %ecx "<-")
19275 3d/compare-eax-and 0/imm32/false
19276 74/jump-if-= loop/disp8
19277 b8/copy-to-eax 1/imm32/true
19279 $stmt-has-outputs:end:
19280 (rewind-stream *(ebp+8))
19282 81 0/subop/add %esp 8/imm32
19283 # . restore registers
19286 89/<- %esp 5/r32/ebp
19290 # if 'name' starts with a digit, create a new literal var for it
19291 # otherwise return first 'name' from the top (back) of 'vars' and abort if not found
19292 lookup-var-or-literal: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
19295 89/<- %ebp 4/r32/esp
19301 8b/-> *(ebp+8) 6/r32/esi
19302 # if slice-empty?(name) abort
19303 (slice-empty? %esi) # => eax
19304 3d/compare-eax-and 0/imm32/false
19305 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32
19306 # var c/ecx: byte = *name->start
19307 8b/-> *esi 1/r32/ecx
19308 8a/copy-byte *ecx 1/r32/CL
19309 81 4/subop/and %ecx 0xff/imm32
19310 # if (decimal-digit?(c) || c == '-') return new var(name)
19312 81 7/subop/compare %ecx 0x2d/imm32/dash
19313 74/jump-if-= $lookup-var-or-literal:literal/disp8
19314 (decimal-digit? %ecx) # => eax
19315 3d/compare-eax-and 0/imm32/false
19316 74/jump-if-= break/disp8
19317 $lookup-var-or-literal:literal:
19318 (new-literal-integer Heap %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c))
19319 eb/jump $lookup-var-or-literal:end/disp8
19321 # else if (c == '"') return new var(name)
19323 81 7/subop/compare %ecx 0x22/imm32/dquote
19324 75/jump-if-!= break/disp8
19325 $lookup-var-or-literal:literal-string:
19326 (new-literal-string Heap %esi *(ebp+0x10))
19327 eb/jump $lookup-var-or-literal:end/disp8
19329 # otherwise return lookup-var(name, vars)
19331 $lookup-var-or-literal:var:
19332 (lookup-var %esi *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c))
19334 $lookup-var-or-literal:end:
19335 # . restore registers
19340 89/<- %esp 5/r32/ebp
19344 $lookup-var-or-literal:abort:
19345 (write-buffered *(ebp+0x18) "fn ")
19346 8b/-> *(ebp+0x14) 0/r32/eax
19347 (lookup *eax *(eax+4)) # Function-name Function-name => eax
19348 (write-buffered *(ebp+0x18) %eax)
19349 (write-buffered *(ebp+0x18) ": empty variable!")
19350 (flush *(ebp+0x18))
19351 (stop *(ebp+0x1c) 1)
19354 # return first 'name' from the top (back) of 'vars' and abort if not found
19355 lookup-var: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
19358 89/<- %ebp 4/r32/esp
19362 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c))
19363 # if (*out == 0) abort
19364 8b/-> *(ebp+0x10) 0/r32/eax
19365 81 7/subop/compare *eax 0/imm32
19366 74/jump-if-= $lookup-var:abort/disp8
19368 # . restore registers
19371 89/<- %esp 5/r32/ebp
19376 (write-buffered *(ebp+0x18) "fn ")
19377 8b/-> *(ebp+0x14) 0/r32/eax
19378 (lookup *eax *(eax+4)) # Function-name Function-name => eax
19379 (write-buffered *(ebp+0x18) %eax)
19380 (write-buffered *(ebp+0x18) ": unknown variable '")
19381 (write-slice-buffered *(ebp+0x18) *(ebp+8))
19382 (write-buffered *(ebp+0x18) "'\n")
19383 (flush *(ebp+0x18))
19384 (stop *(ebp+0x1c) 1)
19387 # return first 'name' from the top (back) of 'vars', and 0/null if not found
19388 # ensure that 'name' if in a register is the topmost variable in that register
19389 lookup-var-helper: # name: (addr slice), vars: (addr stack live-var), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
19391 # var curr: (addr handle var) = &vars->data[vars->top - 12]
19392 # var min = vars->data
19393 # while curr >= min
19394 # var v: (handle var) = *curr
19395 # if v->name == name
19401 89/<- %ebp 4/r32/esp
19410 (zero-out *(ebp+0x10) *Handle-size)
19412 8b/-> *(ebp+0xc) 6/r32/esi
19414 8b/-> *esi 3/r32/ebx
19415 # if (vars->top > vars->size) abort
19416 3b/compare<- *(esi+4) 0/r32/eax
19417 0f 8f/jump-if-> $lookup-var-helper:error1/disp32
19418 # var min/edx: (addr handle var) = vars->data
19419 8d/copy-address *(esi+8) 2/r32/edx
19420 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12]
19421 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12
19422 # var var-in-reg/edi: 16 addrs
19439 89/<- %edi 4/r32/esp
19441 $lookup-var-helper:loop:
19442 # if (curr < min) return
19443 39/compare %ebx 2/r32/edx
19444 0f 82/jump-if-addr< break/disp32
19445 # var v/ecx: (addr var) = lookup(*curr)
19446 (lookup *ebx *(ebx+4)) # => eax
19447 89/<- %ecx 0/r32/eax
19448 # var vn/eax: (addr array byte) = lookup(v->name)
19449 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
19450 # if (vn == name) return curr
19451 (slice-equal? *(ebp+8) %eax) # => eax
19452 3d/compare-eax-and 0/imm32/false
19454 74/jump-if-= break/disp8
19455 $lookup-var-helper:found:
19456 # var vr/eax: (addr array byte) = lookup(v->register)
19457 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax
19458 3d/compare-eax-and 0/imm32
19460 74/jump-if-= break/disp8
19461 $lookup-var-helper:found-register:
19462 # var reg/eax: int = get(Registers, vr)
19463 (get Mu-registers-unique %eax 0xc "Mu-registers-unique") # => eax
19464 8b/-> *eax 0/r32/eax
19465 # if (var-in-reg[reg]) error
19466 8b/-> *(edi+eax<<2) 0/r32/eax
19467 3d/compare-eax-and 0/imm32
19468 0f 85/jump-if-!= $lookup-var-helper:error2/disp32
19470 $lookup-var-helper:return:
19472 8b/-> *(ebp+0x10) 6/r32/esi
19474 8b/-> *ebx 0/r32/eax
19475 89/<- *esi 0/r32/eax
19476 8b/-> *(ebx+4) 0/r32/eax
19477 89/<- *(esi+4) 0/r32/eax
19479 eb/jump $lookup-var-helper:end/disp8
19481 # 'name' not yet found; update var-in-reg if v in register
19482 # . var vr/eax: (addr array byte) = lookup(v->register)
19483 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax
19484 # . if (vr == 0) continue
19485 3d/compare-eax-and 0/imm32
19486 74/jump-if-= $lookup-var-helper:continue/disp8
19487 # . var reg/eax: int = get(Registers, vr)
19488 (get Mu-registers-unique %eax 0xc "Mu-registers-unique") # => eax
19489 8b/-> *eax 0/r32/eax
19490 # . var-in-reg[reg] = v
19491 89/<- *(edi+eax<<2) 1/r32/ecx
19492 $lookup-var-helper:continue:
19494 81 5/subop/subtract %ebx 0xc/imm32
19495 e9/jump loop/disp32
19497 $lookup-var-helper:end:
19499 81 0/subop/add %esp 0x40/imm32
19500 # . restore registers
19508 89/<- %esp 5/r32/ebp
19512 $lookup-var-helper:error1:
19513 (write-buffered *(ebp+0x18) "fn ")
19514 8b/-> *(ebp+0x14) 0/r32/eax
19515 (lookup *eax *(eax+4)) # Function-name Function-name => eax
19516 (write-buffered *(ebp+0x18) %eax)
19517 (write-buffered *(ebp+0x18) ": malformed stack when looking up '")
19518 (write-slice-buffered *(ebp+0x18) *(ebp+8))
19519 (write-buffered *(ebp+0x18) "'\n")
19520 (flush *(ebp+0x18))
19521 (stop *(ebp+0x1c) 1)
19524 $lookup-var-helper:error2:
19525 # eax contains the conflicting var at this point
19526 (write-buffered *(ebp+0x18) "fn ")
19528 8b/-> *(ebp+0x14) 0/r32/eax
19529 (lookup *eax *(eax+4)) # Function-name Function-name => eax
19530 (write-buffered *(ebp+0x18) %eax)
19532 (write-buffered *(ebp+0x18) ": register ")
19534 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
19535 (write-buffered *(ebp+0x18) %eax)
19537 (write-buffered *(ebp+0x18) " reads var '")
19538 (write-slice-buffered *(ebp+0x18) *(ebp+8))
19539 (write-buffered *(ebp+0x18) "' after writing var '")
19540 (lookup *eax *(eax+4)) # Var-name Var-name => eax
19541 (write-buffered *(ebp+0x18) %eax)
19542 (write-buffered *(ebp+0x18) "'\n")
19543 (flush *(ebp+0x18))
19544 (stop *(ebp+0x1c) 1)
19547 dump-vars: # vars: (addr stack live-var)
19549 # var curr: (addr handle var) = &vars->data[vars->top - 12]
19550 # var min = vars->data
19551 # while curr >= min
19552 # var v: (handle var) = *curr
19558 89/<- %ebp 4/r32/esp
19564 8b/-> *(ebp+8) 6/r32/esi
19566 8b/-> *esi 3/r32/ebx
19567 # var min/edx: (addr handle var) = vars->data
19568 8d/copy-address *(esi+8) 2/r32/edx
19569 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12]
19570 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12
19573 # if (curr < min) return
19574 39/compare %ebx 2/r32/edx
19575 0f 82/jump-if-addr< break/disp32
19577 (write-buffered Stderr " var@")
19580 81 5/subop/subtract %ebx 0xc/imm32
19581 e9/jump loop/disp32
19584 # . restore registers
19589 89/<- %esp 5/r32/ebp
19594 # Like Registers, but no esp or ebp
19595 Mu-registers: # (addr stream {(handle array byte), int})
19596 # a table is a stream
19601 # general-purpose registers
19602 # it is perfectly ok to use fake alloc-ids -- as long as you never try to reclaim them
19603 0x11/imm32/alloc-id $Mu-register-eax/imm32 0/imm32
19604 0x11/imm32/alloc-id $Mu-register-ecx/imm32 1/imm32
19605 0x11/imm32/alloc-id $Mu-register-edx/imm32 2/imm32
19606 0x11/imm32/alloc-id $Mu-register-ebx/imm32 3/imm32
19607 0x11/imm32/alloc-id $Mu-register-esi/imm32 6/imm32
19608 0x11/imm32/alloc-id $Mu-register-edi/imm32 7/imm32
19609 # floating-point registers
19610 0x11/imm32/alloc-id $Mu-register-xmm0/imm32 0/imm32
19611 0x11/imm32/alloc-id $Mu-register-xmm1/imm32 1/imm32
19612 0x11/imm32/alloc-id $Mu-register-xmm2/imm32 2/imm32
19613 0x11/imm32/alloc-id $Mu-register-xmm3/imm32 3/imm32
19614 0x11/imm32/alloc-id $Mu-register-xmm4/imm32 4/imm32
19615 0x11/imm32/alloc-id $Mu-register-xmm5/imm32 5/imm32
19616 0x11/imm32/alloc-id $Mu-register-xmm6/imm32 6/imm32
19617 0x11/imm32/alloc-id $Mu-register-xmm7/imm32 7/imm32
19619 # Like Mu-registers, but with unique codes for integer and floating-point
19621 # Don't use this for code-generation, only for checking.
19622 Mu-registers-unique: # (addr stream {(handle array byte), int})
19623 # a table is a stream
19628 # general-purpose registers
19629 0x11/imm32/alloc-id $Mu-register-eax/imm32 0/imm32
19630 0x11/imm32/alloc-id $Mu-register-ecx/imm32 1/imm32
19631 0x11/imm32/alloc-id $Mu-register-edx/imm32 2/imm32
19632 0x11/imm32/alloc-id $Mu-register-ebx/imm32 3/imm32
19633 0x11/imm32/alloc-id $Mu-register-esi/imm32 6/imm32
19634 0x11/imm32/alloc-id $Mu-register-edi/imm32 7/imm32
19635 # floating-point registers
19636 0x11/imm32/alloc-id $Mu-register-xmm0/imm32 8/imm32
19637 0x11/imm32/alloc-id $Mu-register-xmm1/imm32 9/imm32
19638 0x11/imm32/alloc-id $Mu-register-xmm2/imm32 0xa/imm32
19639 0x11/imm32/alloc-id $Mu-register-xmm3/imm32 0xb/imm32
19640 0x11/imm32/alloc-id $Mu-register-xmm4/imm32 0xc/imm32
19641 0x11/imm32/alloc-id $Mu-register-xmm5/imm32 0xd/imm32
19642 0x11/imm32/alloc-id $Mu-register-xmm6/imm32 0xe/imm32
19643 0x11/imm32/alloc-id $Mu-register-xmm7/imm32 0xf/imm32
19646 0x11/imm32/alloc-id
19648 0x65/e 0x61/a 0x78/x
19651 0x11/imm32/alloc-id
19653 0x65/e 0x63/c 0x78/x
19656 0x11/imm32/alloc-id
19658 0x65/e 0x64/d 0x78/x
19661 0x11/imm32/alloc-id
19663 0x65/e 0x62/b 0x78/x
19666 0x11/imm32/alloc-id
19668 0x65/e 0x73/s 0x69/i
19671 0x11/imm32/alloc-id
19673 0x65/e 0x64/d 0x69/i
19676 0x11/imm32/alloc-id:fake:payload
19679 0x78/x 0x6d/m 0x6d/m 0x30/0
19682 0x11/imm32/alloc-id:fake:payload
19685 0x78/x 0x6d/m 0x6d/m 0x31/1
19688 0x11/imm32/alloc-id:fake:payload
19691 0x78/x 0x6d/m 0x6d/m 0x32/2
19694 0x11/imm32/alloc-id:fake:payload
19697 0x78/x 0x6d/m 0x6d/m 0x33/3
19700 0x11/imm32/alloc-id:fake:payload
19703 0x78/x 0x6d/m 0x6d/m 0x34/4
19706 0x11/imm32/alloc-id:fake:payload
19709 0x78/x 0x6d/m 0x6d/m 0x35/5
19712 0x11/imm32/alloc-id:fake:payload
19715 0x78/x 0x6d/m 0x6d/m 0x36/6
19718 0x11/imm32/alloc-id:fake:payload
19721 0x78/x 0x6d/m 0x6d/m 0x37/7
19725 # push 'out' to 'vars' if not already there; it's assumed to be a fn output
19726 maybe-define-var: # out: (handle var), vars: (addr stack live-var)
19729 89/<- %ebp 4/r32/esp
19732 # var out-addr/eax: (addr var)
19733 (lookup *(ebp+8) *(ebp+0xc)) # => eax
19735 (binding-exists? %eax *(ebp+0x10)) # => eax
19736 3d/compare-eax-and 0/imm32/false
19737 75/jump-if-!= $maybe-define-var:end/disp8
19738 # otherwise update vars
19739 (push *(ebp+0x10) *(ebp+8))
19740 (push *(ebp+0x10) *(ebp+0xc))
19741 (push *(ebp+0x10) 0) # 'out' is always a fn output; never spill it
19742 $maybe-define-var:end:
19743 # . restore registers
19746 89/<- %esp 5/r32/ebp
19750 # simpler version of lookup-var-helper
19751 binding-exists?: # target: (addr var), vars: (addr stack live-var) -> result/eax: boolean
19753 # var curr: (addr handle var) = &vars->data[vars->top - 12]
19754 # var min = vars->data
19755 # while curr >= min
19756 # var v: (handle var) = *curr
19757 # if v->name == target->name
19764 89/<- %ebp 4/r32/esp
19769 # var target-name/ecx: (addr array byte) = lookup(target->name)
19770 8b/-> *(ebp+8) 0/r32/eax
19771 (lookup *eax *(eax+4)) # Var-name Var-name => eax
19772 89/<- %ecx 0/r32/eax
19774 8b/-> *(ebp+0xc) 6/r32/esi
19776 8b/-> *esi 0/r32/eax
19777 # var min/edx: (addr handle var) = vars->data
19778 8d/copy-address *(esi+8) 2/r32/edx
19779 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12]
19780 8d/copy-address *(esi+eax-4) 6/r32/esi # vars + 8 + vars->type - 12
19782 $binding-exists?:loop:
19783 # if (curr < min) return
19784 39/compare %esi 2/r32/edx
19785 0f 82/jump-if-addr< break/disp32
19786 # var v/eax: (addr var) = lookup(*curr)
19787 (lookup *esi *(esi+4)) # => eax
19788 # var vn/eax: (addr array byte) = lookup(v->name)
19789 (lookup *eax *(eax+4)) # Var-name Var-name => eax
19790 # if (vn == target-name) return true
19791 (string-equal? %ecx %eax) # => eax
19792 3d/compare-eax-and 0/imm32/false
19793 75/jump-if-!= $binding-exists?:end/disp8 # eax already contains true
19795 81 5/subop/subtract %esi 0xc/imm32
19796 e9/jump loop/disp32
19798 b8/copy-to-eax 0/imm32/false
19799 $binding-exists?:end:
19800 # . restore registers
19805 89/<- %esp 5/r32/ebp
19809 test-parse-mu-stmt:
19812 89/<- %ebp 4/r32/esp
19814 8b/-> *Primitive-type-ids 0/r32/eax
19815 89/<- *Type-id 0/r32/eax # stream-write
19816 (clear-stream _test-input-stream)
19817 (write _test-input-stream "increment n\n")
19818 # var vars/ecx: (stack (addr var) 16)
19819 81 5/subop/subtract %esp 0xc0/imm32
19820 68/push 0xc0/imm32/size
19821 68/push 0/imm32/top
19822 89/<- %ecx 4/r32/esp
19824 # var v/edx: (handle var)
19827 89/<- %edx 4/r32/esp
19828 # var s/eax: (handle array byte)
19831 89/<- %eax 4/r32/esp
19833 (copy-array Heap "n" %eax)
19834 (new-var Heap *eax *(eax+4) %edx)
19837 (push %ecx *(edx+4))
19839 # var out/eax: (handle stmt)
19842 89/<- %eax 4/r32/esp
19844 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0)
19845 # var out-addr/edx: (addr stmt) = lookup(*out)
19846 (lookup *eax *(eax+4)) # => eax
19847 89/<- %edx 0/r32/eax
19849 (check-ints-equal *edx 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1
19851 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax
19852 (check-strings-equal %eax "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation
19853 # out->inouts->value->name
19854 # . eax = out->inouts
19855 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
19856 # . eax = out->inouts->value
19857 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
19858 # . eax = out->inouts->value->name
19859 (lookup *eax *(eax+4)) # Var-name Var-name => eax
19861 (check-strings-equal %eax "n" "F - test-parse-mu-stmt/inout:0")
19863 89/<- %esp 5/r32/ebp
19867 test-parse-mu-stmt-with-comma:
19870 89/<- %ebp 4/r32/esp
19872 8b/-> *Primitive-type-ids 0/r32/eax
19873 89/<- *Type-id 0/r32/eax # stream-write
19874 (clear-stream _test-input-stream)
19875 (write _test-input-stream "copy-to n, 3\n")
19876 # var vars/ecx: (stack (addr var) 16)
19877 81 5/subop/subtract %esp 0xc0/imm32
19878 68/push 0xc0/imm32/size
19879 68/push 0/imm32/top
19880 89/<- %ecx 4/r32/esp
19882 # var v/edx: (handle var)
19885 89/<- %edx 4/r32/esp
19886 # var s/eax: (handle array byte)
19889 89/<- %eax 4/r32/esp
19891 (copy-array Heap "n" %eax)
19892 (new-var Heap *eax *(eax+4) %edx)
19895 (push %ecx *(edx+4))
19897 # var out/eax: (handle stmt)
19900 89/<- %eax 4/r32/esp
19902 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0)
19903 # var out-addr/edx: (addr stmt) = lookup(*out)
19904 (lookup *eax *(eax+4)) # => eax
19905 89/<- %edx 0/r32/eax
19907 (check-ints-equal *edx 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1
19909 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax
19910 (check-strings-equal %eax "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation
19911 # out->inouts->value->name
19912 # . eax = out->inouts
19913 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
19914 # . eax = out->inouts->value
19915 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
19916 # . eax = out->inouts->value->name
19917 (lookup *eax *(eax+4)) # Var-name Var-name => eax
19919 (check-strings-equal %eax "n" "F - test-parse-mu-stmt-with-comma/inout:0")
19921 89/<- %esp 5/r32/ebp
19925 new-var: # ad: (addr allocation-descriptor), name: (handle array byte), out: (addr handle var)
19928 89/<- %ebp 4/r32/esp
19933 8b/-> *(ebp+0x14) 1/r32/ecx
19935 (allocate *(ebp+8) *Var-size %ecx)
19936 # var out-addr/eax: (addr var)
19937 (lookup *ecx *(ecx+4)) # => eax
19938 # out-addr->name = name
19939 8b/-> *(ebp+0xc) 1/r32/ecx
19940 89/<- *eax 1/r32/ecx # Var-name
19941 8b/-> *(ebp+0x10) 1/r32/ecx
19942 89/<- *(eax+4) 1/r32/ecx # Var-name
19943 #? (write-buffered Stderr "var ")
19944 #? (lookup *(ebp+0xc) *(ebp+0x10))
19945 #? (write-buffered Stderr %eax)
19946 #? (write-buffered Stderr " at ")
19947 #? 8b/-> *(ebp+0x14) 1/r32/ecx
19948 #? (lookup *ecx *(ecx+4)) # => eax
19949 #? (write-int32-hex-buffered Stderr %eax)
19950 #? (write-buffered Stderr Newline)
19953 # . restore registers
19957 89/<- %esp 5/r32/ebp
19961 # WARNING: modifies name
19962 new-literal-integer: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
19965 89/<- %ebp 4/r32/esp
19969 # first strip out metadata
19970 8b/-> *(ebp+0xc) 1/r32/ecx
19971 (next-token-from-slice *ecx *(ecx+4) 0x2f *(ebp+0xc))
19972 # if (!is-hex-int?(name)) abort
19973 (hex-int? *(ebp+0xc)) # => eax
19974 3d/compare-eax-and 0/imm32/false
19975 0f 84/jump-if-= $new-literal-integer:abort/disp32
19976 # a little more error-checking
19977 (check-mu-hex-int *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c))
19979 (new-var-from-slice *(ebp+8) *(ebp+0xc) *(ebp+0x10))
19980 # var out-addr/ecx: (addr var) = lookup(*out)
19981 8b/-> *(ebp+0x10) 0/r32/eax
19982 (lookup *eax *(eax+4)) # => eax
19983 89/<- %ecx 0/r32/eax
19984 # out-addr->block-depth = *Curr-block-depth
19985 8b/-> *Curr-block-depth 0/r32/eax
19986 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth
19987 # out-addr->type = new tree()
19988 8d/copy-address *(ecx+8) 0/r32/eax # Var-type
19989 (allocate *(ebp+8) *Type-tree-size %eax)
19990 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
19991 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom
19992 # nothing else to do; default type is 'literal'
19993 $new-literal-integer:end:
19995 81 0/subop/add %esp 8/imm32
19996 # . restore registers
20000 89/<- %esp 5/r32/ebp
20004 $new-literal-integer:abort:
20005 (write-buffered *(ebp+0x18) "fn ")
20006 8b/-> *(ebp+0x14) 0/r32/eax
20007 (lookup *eax *(eax+4)) # Function-name Function-name => eax
20008 (write-buffered *(ebp+0x18) %eax)
20009 (write-buffered *(ebp+0x18) ": variable '")
20010 (write-slice-buffered *(ebp+0x18) *(ebp+0xc))
20011 (write-buffered *(ebp+0x18) "' cannot begin with a digit (or do you have a typo in a number?)\n")
20012 (flush *(ebp+0x18))
20013 (stop *(ebp+0x1c) 1)
20016 # precondition: name is a valid hex integer; require a '0x' prefix
20017 check-mu-hex-int: # name: (addr slice), err: (addr buffered-file), ed: (addr exit-descriptor)
20020 89/<- %ebp 4/r32/esp
20026 8b/-> *(ebp+8) 1/r32/ecx
20027 # var start/edx: (addr byte) = name->start
20028 8b/-> *ecx 2/r32/edx
20029 # if (*start == '-') ++start
20030 b8/copy-to-eax 0/imm32
20031 8a/copy-byte *edx 0/r32/AL
20032 3d/compare-eax-and 0x2d/imm32/dash
20034 75/jump-if-!= break/disp8
20037 # var end/ecx: (addr byte) = name->end
20038 8b/-> *(ecx+4) 1/r32/ecx
20039 # var len/eax: int = name->end - name->start
20040 89/<- %eax 1/r32/ecx
20041 29/subtract-from %eax 2/r32/edx
20042 # if (len <= 1) return
20043 3d/compare-eax-with 1/imm32
20044 0f 8e/jump-if-<= $check-mu-hex-int:end/disp32
20045 $check-mu-hex-int:length->-1:
20046 # if slice-starts-with?({start, end}, "0x") return
20047 # . var tmp = {start, end}
20050 89/<- %eax 4/r32/esp
20052 (slice-starts-with? %eax "0x") # => eax
20054 81 0/subop/add %esp 8/imm32
20056 3d/compare-eax-with 0/imm32/false
20057 75/jump-if-!= $check-mu-hex-int:end/disp8
20058 $check-mu-hex-int:abort:
20060 (write-buffered *(ebp+0xc) "literal integers are always hex in Mu; start '")
20061 (write-slice-buffered *(ebp+0xc) *(ebp+8))
20062 (write-buffered *(ebp+0xc) "' with a '0x' to be unambiguous, converting it to hexadecimal as necessary.\n")
20064 (stop *(ebp+0x10) 1)
20065 $check-mu-hex-int:end:
20066 # . restore registers
20071 89/<- %esp 5/r32/ebp
20075 new-literal: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var)
20078 89/<- %ebp 4/r32/esp
20082 # var s/ecx: (handle array byte)
20085 89/<- %ecx 4/r32/esp
20086 # s = slice-to-string(name)
20087 (slice-to-string Heap *(ebp+0xc) %ecx)
20089 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10))
20090 # var out-addr/ecx: (addr var) = lookup(*out)
20091 8b/-> *(ebp+0x10) 1/r32/ecx
20092 (lookup *ecx *(ecx+4)) # => eax
20093 89/<- %ecx 0/r32/eax
20094 # out-addr->block-depth = *Curr-block-depth
20095 8b/-> *Curr-block-depth 0/r32/eax
20096 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth
20097 # out-addr->type/eax = new type
20098 8d/copy-address *(ecx+8) 0/r32/eax # Var-type
20099 (allocate *(ebp+8) *Type-tree-size %eax)
20100 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
20101 # nothing else to do; default type is 'literal'
20102 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom
20105 81 0/subop/add %esp 8/imm32
20106 # . restore registers
20110 89/<- %esp 5/r32/ebp
20114 new-literal-string: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var)
20117 89/<- %ebp 4/r32/esp
20121 # var s/ecx: (handle array byte)
20124 89/<- %ecx 4/r32/esp
20125 # s = slice-to-string(name)
20126 (slice-to-string Heap *(ebp+0xc) %ecx)
20128 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10))
20129 # var out-addr/ecx: (addr var) = lookup(*out)
20130 8b/-> *(ebp+0x10) 1/r32/ecx
20131 (lookup *ecx *(ecx+4)) # => eax
20132 89/<- %ecx 0/r32/eax
20133 # out-addr->block-depth = *Curr-block-depth
20134 8b/-> *Curr-block-depth 0/r32/eax
20135 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth
20136 # out-addr->type/eax = new type
20137 8d/copy-address *(ecx+8) 0/r32/eax # Var-type
20138 (allocate *(ebp+8) *Type-tree-size %eax)
20139 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
20140 # out-addr->type->value = literal-string
20141 c7 0/subop/copy *(eax+4) 0x10/imm32/type-id-string-literal # Type-tree-value
20142 # out-addr->type->is-atom? = true
20143 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom
20144 $new-literal-string:end:
20146 81 0/subop/add %esp 8/imm32
20147 # . restore registers
20151 89/<- %esp 5/r32/ebp
20155 new-var-from-slice: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var)
20158 89/<- %ebp 4/r32/esp
20161 # var tmp/ecx: (handle array byte)
20164 89/<- %ecx 4/r32/esp
20165 # tmp = slice-to-string(name)
20166 (slice-to-string Heap *(ebp+0xc) %ecx)
20167 # out = new-var(tmp)
20168 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10))
20169 $new-var-from-slice:end:
20171 81 0/subop/add %esp 8/imm32
20172 # . restore registers
20175 89/<- %esp 5/r32/ebp
20179 new-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt)
20182 89/<- %ebp 4/r32/esp
20187 (allocate *(ebp+8) *Stmt-size *(ebp+0x14))
20188 # var out-addr/eax: (addr stmt) = lookup(*out)
20189 8b/-> *(ebp+0x14) 0/r32/eax
20190 (lookup *eax *(eax+4)) # => eax
20191 # out-addr->tag = stmt
20192 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag
20193 # result->var = var
20194 8b/-> *(ebp+0xc) 1/r32/ecx
20195 89/<- *(eax+4) 1/r32/ecx # Vardef-var
20196 8b/-> *(ebp+0x10) 1/r32/ecx
20197 89/<- *(eax+8) 1/r32/ecx # Vardef-var
20199 # . restore registers
20203 89/<- %esp 5/r32/ebp
20207 new-reg-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt)
20210 89/<- %ebp 4/r32/esp
20214 8b/-> *(ebp+0x14) 0/r32/eax
20216 (allocate *(ebp+8) *Stmt-size %eax)
20217 # var out-addr/eax: (addr stmt) = lookup(*out)
20218 (lookup *eax *(eax+4)) # => eax
20220 c7 0/subop/copy *eax 3/imm32/tag/var-in-register # Stmt-tag
20222 8d/copy-address *(eax+0x14) 0/r32/eax # Regvardef-outputs
20223 (append-stmt-var Heap *(ebp+0xc) *(ebp+0x10) 0 0 0 %eax)
20224 $new-reg-var-def:end:
20225 # . restore registers
20228 89/<- %esp 5/r32/ebp
20232 append-list: # ad: (addr allocation-descriptor), value: (handle _type), list: (handle list _type), out: (addr handle list _type)
20235 89/<- %ebp 4/r32/esp
20241 8b/-> *(ebp+0x1c) 7/r32/edi
20243 (allocate *(ebp+8) *List-size %edi)
20244 # var out-addr/edi: (addr list _type) = lookup(*out)
20245 (lookup *edi *(edi+4)) # => eax
20246 89/<- %edi 0/r32/eax
20247 # out-addr->value = value
20248 8b/-> *(ebp+0xc) 0/r32/eax
20249 89/<- *edi 0/r32/eax # List-value
20250 8b/-> *(ebp+0x10) 0/r32/eax
20251 89/<- *(edi+4) 0/r32/eax # List-value
20252 # if (list == null) return
20253 81 7/subop/compare *(ebp+0x14) 0/imm32
20254 74/jump-if-= $append-list:end/disp8
20256 $append-list:non-empty-list:
20257 # var curr/eax: (addr list _type) = lookup(list)
20258 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax
20259 # while (curr->next != null) curr = curr->next
20261 81 7/subop/compare *(eax+8) 0/imm32 # List-next
20262 74/jump-if-= break/disp8
20263 # curr = lookup(curr->next)
20264 (lookup *(eax+8) *(eax+0xc)) # List-next, List-next => eax
20269 8b/-> *(ebp+0x1c) 7/r32/edi
20271 8b/-> *edi 1/r32/ecx
20272 89/<- *(eax+8) 1/r32/ecx # List-next
20273 8b/-> *(edi+4) 1/r32/ecx
20274 89/<- *(eax+0xc) 1/r32/ecx # List-next
20276 8b/-> *(ebp+0x14) 1/r32/ecx
20277 89/<- *edi 1/r32/ecx
20278 8b/-> *(ebp+0x18) 1/r32/ecx
20279 89/<- *(edi+4) 1/r32/ecx
20281 # . restore registers
20286 89/<- %esp 5/r32/ebp
20290 append-stmt-var: # ad: (addr allocation-descriptor), v: (handle var), vars: (handle stmt-var), is-deref?: boolean, out: (addr handle stmt-var)
20293 89/<- %ebp 4/r32/esp
20299 8b/-> *(ebp+0x20) 7/r32/edi
20300 # out = new stmt-var
20301 (allocate *(ebp+8) *Stmt-var-size %edi)
20302 # var out-addr/ecx: (addr stmt-var) = lookup(*out)
20303 (lookup *edi *(edi+4)) # => eax
20304 89/<- %ecx 0/r32/eax
20305 # out-addr->value = v
20306 8b/-> *(ebp+0xc) 0/r32/eax
20307 89/<- *ecx 0/r32/eax # Stmt-var-value
20308 8b/-> *(ebp+0x10) 0/r32/eax
20309 89/<- *(ecx+4) 0/r32/eax # Stmt-var-value
20310 # out-addr->is-deref? = is-deref?
20311 8b/-> *(ebp+0x1c) 0/r32/eax
20312 89/<- *(ecx+0x10) 0/r32/eax # Stmt-var-is-deref
20313 # if (vars == null) return result
20314 81 7/subop/compare *(ebp+0x14) 0/imm32/null
20315 74/jump-if-= $append-stmt-var:end/disp8
20317 # var curr/eax: (addr stmt-var) = lookup(vars)
20318 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax
20319 # while (curr->next != null) curr = curr->next
20321 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next
20322 74/jump-if-= break/disp8
20323 # curr = lookup(curr->next)
20324 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next, Stmt-var-next => eax
20329 8b/-> *edi 1/r32/ecx
20330 89/<- *(eax+8) 1/r32/ecx # Stmt-var-next
20331 8b/-> *(edi+4) 1/r32/ecx
20332 89/<- *(eax+0xc) 1/r32/ecx # Stmt-var-next
20334 8b/-> *(ebp+0x14) 1/r32/ecx
20335 89/<- *edi 1/r32/ecx
20336 8b/-> *(ebp+0x18) 1/r32/ecx
20337 89/<- *(edi+4) 1/r32/ecx
20338 $append-stmt-var:end:
20339 # . restore registers
20344 89/<- %esp 5/r32/ebp
20348 append-to-block: # ad: (addr allocation-descriptor), block: (addr block), x: (handle stmt)
20351 89/<- %ebp 4/r32/esp
20356 8b/-> *(ebp+0xc) 6/r32/esi
20357 # block->stmts = append(x, block->stmts)
20358 8d/copy-address *(esi+4) 0/r32/eax # Block-stmts
20359 (append-list *(ebp+8) *(ebp+0x10) *(ebp+0x14) *(esi+4) *(esi+8) %eax) # ad, x, x, Block-stmts, Block-stmts
20360 $append-to-block:end:
20361 # . restore registers
20365 89/<- %esp 5/r32/ebp
20370 # We need to create metadata on user-defined types, and we need to use this
20371 # metadata as we parse instructions.
20372 # However, we also want to allow types to be used before their definitions.
20373 # This means we can't ever assume any type data structures exist.
20375 lookup-or-create-constant: # container: (addr stmt-var), field-name: (addr slice), out: (addr handle var)
20378 89/<- %ebp 4/r32/esp
20382 # var container-type/esi: type-id
20383 (container-type *(ebp+8)) # => eax
20384 89/<- %esi 0/r32/eax
20385 # var tmp/eax: (handle typeinfo) = find-or-create-typeinfo(container-type)
20388 89/<- %eax 4/r32/esp
20389 (find-or-create-typeinfo %esi %eax)
20390 # var tmp-addr/eax: (addr typeinfo) = lookup(tmp)
20391 (lookup *eax *(eax+4)) # => eax
20392 # result = find-or-create-typeinfo-output-var(typeinfo, field-name)
20393 #? (write-buffered Stderr "constant: ")
20394 #? (write-slice-buffered Stderr *(ebp+0xc))
20395 #? (write-buffered Stderr Newline)
20397 (find-or-create-typeinfo-output-var %eax *(ebp+0xc) *(ebp+0x10))
20398 #? 8b/-> *(ebp+0x10) 0/r32/eax
20399 #? (write-buffered Stderr "@")
20400 #? (lookup *eax *(eax+4))
20401 #? (write-int32-hex-buffered Stderr %eax)
20402 #? (lookup *eax *(eax+4))
20403 #? (write-buffered Stderr %eax)
20404 #? (write-buffered Stderr Newline)
20406 #? (write-buffered Stderr "offset: ")
20407 #? 8b/-> *(eax+0x14) 0/r32/eax
20408 #? (write-int32-hex-buffered Stderr %eax)
20409 #? (write-buffered Stderr Newline)
20411 $lookup-or-create-constant:end:
20413 81 0/subop/add %esp 8/imm32
20414 # . restore registers
20418 89/<- %esp 5/r32/ebp
20423 # container->var->type->right->left->value
20425 # container->var->type->value
20426 container-type: # container: (addr stmt-var) -> result/eax: type-id
20429 89/<- %ebp 4/r32/esp
20431 8b/-> *(ebp+8) 0/r32/eax
20432 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
20433 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
20435 81 7/subop/compare *(eax+8) 0/imm32 # Type-tree-right
20436 74/jump-if-= break/disp8
20437 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
20438 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
20440 8b/-> *(eax+4) 0/r32/eax # Type-tree-value
20441 $container-type:end:
20443 89/<- %esp 5/r32/ebp
20447 container?: # t: type-id -> result/eax: boolean
20450 89/<- %ebp 4/r32/esp
20452 8b/-> *(ebp+8) 0/r32/eax
20453 c1/shift 4/subop/left %eax 2/imm8
20454 3b/compare 0/r32/eax *Primitive-type-ids
20455 0f 9d/set-if->= %al
20456 25/and-eax-with 0xff/imm32
20459 89/<- %esp 5/r32/ebp
20463 find-or-create-typeinfo: # t: type-id, out: (addr handle typeinfo)
20466 89/<- %ebp 4/r32/esp
20473 8b/-> *(ebp+0xc) 7/r32/edi
20474 # var fields/ecx: (handle table (handle array byte) (handle typeinfo-entry))
20477 89/<- %ecx 4/r32/esp
20478 # find-typeinfo(t, out)
20479 (find-typeinfo *(ebp+8) %edi)
20481 # if (*out != 0) break
20482 81 7/subop/compare *edi 0/imm32
20483 0f 85/jump-if-!= break/disp32
20484 $find-or-create-typeinfo:create:
20486 (allocate Heap *Typeinfo-size %edi)
20487 # var tmp/eax: (addr typeinfo) = lookup(*out)
20488 (lookup *edi *(edi+4)) # => eax
20489 #? (write-buffered Stderr "created typeinfo at ")
20490 #? (write-int32-hex-buffered Stderr %eax)
20491 #? (write-buffered Stderr " for type-id ")
20492 #? (write-int32-hex-buffered Stderr *(ebp+8))
20493 #? (write-buffered Stderr Newline)
20496 8b/-> *(ebp+8) 2/r32/edx
20497 89/<- *eax 2/r32/edx # Typeinfo-id
20498 # tmp->fields = new table
20499 # . fields = new table
20500 (new-stream Heap 0x40 *Typeinfo-fields-row-size %ecx)
20501 # . tmp->fields = fields
20502 8b/-> *ecx 2/r32/edx
20503 89/<- *(eax+4) 2/r32/edx # Typeinfo-fields
20504 8b/-> *(ecx+4) 2/r32/edx
20505 89/<- *(eax+8) 2/r32/edx # Typeinfo-fields
20506 # tmp->next = Program->types
20507 8b/-> *_Program-types 1/r32/ecx
20508 89/<- *(eax+0x10) 1/r32/ecx # Typeinfo-next
20509 8b/-> *_Program-types->payload 1/r32/ecx
20510 89/<- *(eax+0x14) 1/r32/ecx # Typeinfo-next
20511 # Program->types = out
20512 8b/-> *edi 1/r32/ecx
20513 89/<- *_Program-types 1/r32/ecx
20514 8b/-> *(edi+4) 1/r32/ecx
20515 89/<- *_Program-types->payload 1/r32/ecx
20517 $find-or-create-typeinfo:end:
20519 81 0/subop/add %esp 8/imm32
20520 # . restore registers
20526 89/<- %esp 5/r32/ebp
20530 find-typeinfo: # t: type-id, out: (addr handle typeinfo)
20533 89/<- %ebp 4/r32/esp
20540 8b/-> *(ebp+8) 1/r32/ecx
20542 8b/-> *(ebp+0xc) 7/r32/edi
20543 # *out = Program->types
20544 8b/-> *_Program-types 0/r32/eax
20545 89/<- *edi 0/r32/eax
20546 8b/-> *_Program-types->payload 0/r32/eax
20547 89/<- *(edi+4) 0/r32/eax
20549 $find-typeinfo:loop:
20550 # if (*out == 0) break
20551 81 7/subop/compare *edi 0/imm32
20552 74/jump-if-= break/disp8
20553 $find-typeinfo:check:
20554 # var tmp/eax: (addr typeinfo) = lookup(*out)
20555 (lookup *edi *(edi+4)) # => eax
20556 # if (tmp->id == t) break
20557 39/compare *eax 1/r32/ecx # Typeinfo-id
20558 74/jump-if-= break/disp8
20559 $find-typeinfo:continue:
20561 8b/-> *(eax+0x10) 2/r32/edx # Typeinfo-next
20562 89/<- *edi 2/r32/edx
20563 8b/-> *(eax+0x14) 2/r32/edx # Typeinfo-next
20564 89/<- *(edi+4) 2/r32/edx
20568 $find-typeinfo:end:
20569 # . restore registers
20575 89/<- %esp 5/r32/ebp
20579 find-or-create-typeinfo-output-var: # T: (addr typeinfo), f: (addr slice), out: (addr handle var)
20582 89/<- %ebp 4/r32/esp
20587 # var dest/edi: (handle typeinfo-entry)
20590 89/<- %edi 4/r32/esp
20591 # find-or-create-typeinfo-fields(T, f, dest)
20592 (find-or-create-typeinfo-fields *(ebp+8) *(ebp+0xc) %edi)
20593 # var dest-addr/edi: (addr typeinfo-entry) = lookup(dest)
20594 (lookup *edi *(edi+4)) # => eax
20595 89/<- %edi 0/r32/eax
20596 # if dest-addr->output-var doesn't exist, create it
20598 81 7/subop/compare *(edi+0xc) 0/imm32 # Typeinfo-entry-output-var
20599 0f 85/jump-if-!= break/disp32
20600 # dest-addr->output-var = new var(dummy name, type, -1 offset)
20601 # . var name/eax: (handle array byte) = "field"
20604 89/<- %eax 4/r32/esp
20605 (slice-to-string Heap *(ebp+0xc) %eax)
20607 8d/copy-address *(edi+0xc) 2/r32/edx
20608 (new-var Heap *eax *(eax+4) %edx)
20610 81 0/subop/add %esp 8/imm32
20611 # var result/edx: (addr var) = lookup(dest-addr->output-var)
20612 (lookup *(edi+0xc) *(edi+0x10)) # => eax
20613 89/<- %edx 0/r32/eax
20614 # result->type = new constant type
20615 8d/copy-address *(edx+8) 0/r32/eax # Var-type
20616 (allocate Heap *Type-tree-size %eax)
20617 (lookup *(edx+8) *(edx+0xc)) # => eax
20618 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom
20619 c7 0/subop/copy *(eax+4) 6/imm32/constant # Type-tree-value
20620 c7 0/subop/copy *(eax+8) 0/imm32 # Type-tree-left
20621 c7 0/subop/copy *(eax+0xc) 0/imm32 # Type-tree-right
20622 c7 0/subop/copy *(eax+0x10) 0/imm32 # Type-tree-right
20623 # result->offset isn't filled out yet
20624 c7 0/subop/copy *(edx+0x14) -1/imm32/uninitialized # Var-offset
20626 # out = dest-addr->output-var
20627 8b/-> *(ebp+0x10) 2/r32/edx
20628 8b/-> *(edi+0xc) 0/r32/eax # Typeinfo-entry-output-var
20629 89/<- *edx 0/r32/eax
20630 8b/-> *(edi+0x10) 0/r32/eax # Typeinfo-entry-output-var
20631 89/<- *(edx+4) 0/r32/eax
20632 $find-or-create-typeinfo-output-var:end:
20634 81 0/subop/add %esp 8/imm32
20635 # . restore registers
20640 89/<- %esp 5/r32/ebp
20644 find-or-create-typeinfo-fields: # T: (addr typeinfo), f: (addr slice), out: (addr handle typeinfo-entry)
20647 89/<- %ebp 4/r32/esp
20652 # eax = lookup(T->fields)
20653 8b/-> *(ebp+8) 0/r32/eax
20654 (lookup *(eax+4) *(eax+8)) # Typeinfo-fields Typeinfo-fields => eax
20656 8b/-> *(ebp+0x10) 7/r32/edi
20657 # var src/esi: (addr handle typeinfo-entry) = get-or-insert-slice(T->fields, f)
20658 (get-or-insert-slice %eax *(ebp+0xc) *Typeinfo-fields-row-size Heap) # => eax
20659 89/<- %esi 0/r32/eax
20660 # if src doesn't exist, allocate it
20662 81 7/subop/compare *esi 0/imm32
20663 75/jump-if-!= break/disp8
20664 (allocate Heap *Typeinfo-entry-size %esi)
20665 #? (write-buffered Stderr "handle at ")
20666 #? (write-int32-hex-buffered Stderr %esi)
20667 #? (write-buffered Stderr ": ")
20668 #? (write-int32-hex-buffered Stderr *esi)
20669 #? (write-buffered Stderr " ")
20670 #? (write-int32-hex-buffered Stderr *(esi+4))
20671 #? (write-buffered Stderr Newline)
20673 #? (lookup *esi *(esi+4))
20674 #? (write-buffered Stderr "created typeinfo fields at ")
20675 #? (write-int32-hex-buffered Stderr %esi)
20676 #? (write-buffered Stderr " for ")
20677 #? (write-int32-hex-buffered Stderr *(ebp+8))
20678 #? (write-buffered Stderr Newline)
20683 8b/-> *esi 0/r32/eax
20684 89/<- *edi 0/r32/eax
20685 8b/-> *(esi+4) 0/r32/eax
20686 89/<- *(edi+4) 0/r32/eax
20687 $find-or-create-typeinfo-fields:end:
20688 # . restore registers
20693 89/<- %esp 5/r32/ebp
20697 populate-mu-type: # in: (addr stream byte), t: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor)
20699 # var line: (stream byte 512)
20702 # clear-stream(line)
20703 # read-line-buffered(in, line)
20704 # if line->write == 0
20706 # word-slice = next-mu-token(line)
20707 # if slice-empty?(word-slice) # end of line
20709 # if slice-equal?(word-slice, "}")
20711 # var v: (handle var) = parse-var-with-type(word-slice, line)
20712 # var r: (handle typeinfo-fields) = find-or-create-typeinfo-fields(t, word-slice/v->name)
20713 # TODO: ensure that r->first is null
20714 # r->index = curr-index
20717 # if r->output-var == 0
20718 # r->output-var = new literal
20719 # TODO: ensure nothing else in line
20720 # t->total-size-in-bytes = -2 (not yet initialized)
20724 89/<- %ebp 4/r32/esp
20725 # var curr-index: int at *(ebp-4)
20735 8b/-> *(ebp+0xc) 7/r32/edi
20736 # var line/ecx: (stream byte 512)
20737 81 5/subop/subtract %esp 0x200/imm32
20738 68/push 0x200/imm32/size
20739 68/push 0/imm32/read
20740 68/push 0/imm32/write
20741 89/<- %ecx 4/r32/esp
20742 # var word-slice/edx: slice
20743 68/push 0/imm32/end
20744 68/push 0/imm32/start
20745 89/<- %edx 4/r32/esp
20746 # var v/esi: (handle var)
20749 89/<- %esi 4/r32/esp
20750 # var r/ebx: (handle typeinfo-entry)
20753 89/<- %ebx 4/r32/esp
20755 $populate-mu-type:line-loop:
20756 (clear-stream %ecx)
20757 (read-line-buffered *(ebp+8) %ecx)
20758 # if (line->write == 0) abort
20759 81 7/subop/compare *ecx 0/imm32
20760 0f 84/jump-if-= $populate-mu-type:error1/disp32
20762 #? (write 2 "parse-mu: ^")
20763 #? (write-stream 2 %ecx)
20765 #? (rewind-stream %ecx)
20767 (next-mu-token %ecx %edx)
20768 # if slice-empty?(word-slice) continue
20769 (slice-empty? %edx) # => eax
20770 3d/compare-eax-and 0/imm32
20771 0f 85/jump-if-!= loop/disp32
20772 # if slice-equal?(word-slice, "}") break
20773 (slice-equal? %edx "}")
20774 3d/compare-eax-and 0/imm32
20775 0f 85/jump-if-!= break/disp32
20776 $populate-mu-type:parse-element:
20777 # v = parse-var-with-type(word-slice, first-line)
20778 # must do this first to strip the trailing ':' from word-slice before
20779 # using it in find-or-create-typeinfo-fields below
20780 # TODO: clean up that mutation in parse-var-with-type
20781 (type-name *edi) # Typeinfo-id => eax
20782 (parse-var-with-type %edx %ecx %esi %eax *(ebp+0x10) *(ebp+0x14))
20783 # if v is an addr, abort
20784 (lookup *esi *(esi+4)) # => eax
20785 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
20786 (mu-addr-type? %eax) # => eax
20787 3d/compare-eax-and 0/imm32/false
20788 0f 85/jump-if-!= $populate-mu-type:error2/disp32
20789 # if v is an array, abort (we could support it, but initialization gets complex)
20790 (lookup *esi *(esi+4)) # => eax
20791 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
20792 (mu-array-type? %eax) # => eax
20793 3d/compare-eax-and 0/imm32/false
20794 0f 85/jump-if-!= $populate-mu-type:error3/disp32
20795 # if v is a byte, abort
20796 (lookup *esi *(esi+4)) # => eax
20797 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
20798 (simple-mu-type? %eax 8) # byte => eax
20799 3d/compare-eax-and 0/imm32/false
20800 0f 85/jump-if-!= $populate-mu-type:error4/disp32
20801 # if v is a slice, abort
20802 (lookup *esi *(esi+4)) # => eax
20803 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
20804 (simple-mu-type? %eax 0xc) # slice => eax
20805 3d/compare-eax-and 0/imm32/false
20806 0f 85/jump-if-!= $populate-mu-type:error5/disp32
20807 # if v is a stream, abort (we could support it, but initialization gets even more complex)
20808 (lookup *esi *(esi+4)) # => eax
20809 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
20810 (mu-stream-type? %eax) # => eax
20811 3d/compare-eax-and 0/imm32/false
20812 0f 85/jump-if-!= $populate-mu-type:error6/disp32
20815 $populate-mu-type:create-typeinfo-fields:
20816 # var r/ebx: (handle typeinfo-entry)
20817 (find-or-create-typeinfo-fields %edi %edx %ebx)
20818 # r->index = curr-index
20819 (lookup *ebx *(ebx+4)) # => eax
20820 8b/-> *(ebp-4) 1/r32/ecx
20821 #? (write-buffered Stderr "saving index ")
20822 #? (write-int32-hex-buffered Stderr %ecx)
20823 #? (write-buffered Stderr " at ")
20824 #? (write-int32-hex-buffered Stderr %edi)
20825 #? (write-buffered Stderr Newline)
20827 89/<- *(eax+8) 1/r32/ecx # Typeinfo-entry-index
20829 ff 0/subop/increment *(ebp-4)
20830 $populate-mu-type:set-input-type:
20832 8b/-> *esi 1/r32/ecx
20833 89/<- *eax 1/r32/ecx # Typeinfo-entry-input-var
20834 8b/-> *(esi+4) 1/r32/ecx
20835 89/<- *(eax+4) 1/r32/ecx # Typeinfo-entry-input-var
20839 $populate-mu-type:create-output-type:
20840 # if (r->output-var == 0) create a new var with some placeholder data
20841 81 7/subop/compare *(eax+0xc) 0/imm32 # Typeinfo-entry-output-var
20842 75/jump-if-!= break/disp8
20843 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var
20844 (new-literal Heap %edx %eax)
20846 e9/jump loop/disp32
20848 $populate-mu-type:invalidate-total-size-in-bytes:
20849 # Offsets and total size may not be accurate here since we may not yet
20850 # have encountered the element types.
20851 # We'll recompute them separately after parsing the entire program.
20852 c7 0/subop/copy *(edi+0xc) -2/imm32/uninitialized # Typeinfo-total-size-in-bytes
20853 $populate-mu-type:end:
20855 81 0/subop/add %esp 0x224/imm32
20856 # . restore registers
20863 # reclaim curr-index
20864 81 0/subop/add %esp 4/imm32
20866 89/<- %esp 5/r32/ebp
20870 $populate-mu-type:error1:
20871 # error("incomplete type definition '" t->name "'\n")
20872 (write-buffered *(ebp+0x10) "incomplete type definition '")
20873 (type-name *edi) # Typeinfo-id => eax
20874 (write-buffered *(ebp+0x10) %eax)
20875 (write-buffered *(ebp+0x10) "\n")
20876 (flush *(ebp+0x10))
20877 (stop *(ebp+0x14) 1)
20880 $populate-mu-type:error2:
20881 (write-buffered *(ebp+0x10) "type ")
20882 (type-name *edi) # Typeinfo-id => eax
20883 (write-buffered *(ebp+0x10) %eax)
20884 (write-buffered *(ebp+0x10) ": 'addr' elements not allowed\n")
20885 (flush *(ebp+0x10))
20886 (stop *(ebp+0x14) 1)
20889 $populate-mu-type:error3:
20890 (write-buffered *(ebp+0x10) "type ")
20891 (type-name *edi) # Typeinfo-id => eax
20892 (write-buffered *(ebp+0x10) %eax)
20893 (write-buffered *(ebp+0x10) ": 'array' elements not allowed for now\n")
20894 (flush *(ebp+0x10))
20895 (stop *(ebp+0x14) 1)
20898 $populate-mu-type:error4:
20899 (write-buffered *(ebp+0x10) "type ")
20900 (type-name *edi) # Typeinfo-id => eax
20901 (write-buffered *(ebp+0x10) %eax)
20902 (write-buffered *(ebp+0x10) ": 'byte' elements not allowed\n")
20903 (flush *(ebp+0x10))
20904 (stop *(ebp+0x14) 1)
20907 $populate-mu-type:error5:
20908 (write-buffered *(ebp+0x10) "type ")
20909 (type-name *edi) # Typeinfo-id => eax
20910 (write-buffered *(ebp+0x10) %eax)
20911 (write-buffered *(ebp+0x10) ": 'slice' elements not allowed\n")
20912 (flush *(ebp+0x10))
20913 (stop *(ebp+0x14) 1)
20916 $populate-mu-type:error6:
20917 (write-buffered *(ebp+0x10) "type ")
20918 (type-name *edi) # Typeinfo-id => eax
20919 (write-buffered *(ebp+0x10) %eax)
20920 (write-buffered *(ebp+0x10) ": 'stream' elements not allowed for now\n")
20921 (flush *(ebp+0x10))
20922 (stop *(ebp+0x14) 1)
20925 type-name: # index: int -> result/eax: (addr array byte)
20928 89/<- %ebp 4/r32/esp
20930 (index Type-id *(ebp+8))
20933 89/<- %esp 5/r32/ebp
20937 index: # arr: (addr stream (handle array byte)), index: int -> result/eax: (addr array byte)
20940 89/<- %ebp 4/r32/esp
20943 # TODO: bounds-check index
20945 8b/-> *(ebp+8) 6/r32/esi
20947 8b/-> *(ebp+0xc) 0/r32/eax
20948 # eax = *(arr + 12 + index)
20949 8b/-> *(esi+eax<<2+0xc) 0/r32/eax
20951 # . restore registers
20954 89/<- %esp 5/r32/ebp
20958 #######################################################
20959 # Compute type sizes
20960 #######################################################
20962 # Compute the sizes of all user-defined types.
20963 # We'll need the sizes of their elements, which may be other user-defined
20964 # types, which we will compute as needed.
20966 # Initially, all user-defined types have their sizes set to -2 (invalid)
20967 populate-mu-type-sizes: # err: (addr buffered-file), ed: (addr exit-descriptor)
20970 89/<- %ebp 4/r32/esp
20971 $populate-mu-type-sizes:total-sizes:
20972 # var curr/eax: (addr typeinfo) = lookup(Program->types)
20973 (lookup *_Program-types *_Program-types->payload) # => eax
20975 # if (curr == null) break
20976 3d/compare-eax-and 0/imm32/null
20977 74/jump-if-= break/disp8
20978 (populate-mu-type-sizes-in-type %eax *(ebp+8) *(ebp+0xc))
20979 # curr = lookup(curr->next)
20980 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax
20983 $populate-mu-type-sizes:offsets:
20984 # curr = *Program->types
20985 (lookup *_Program-types *_Program-types->payload) # => eax
20987 # if (curr == null) break
20988 3d/compare-eax-and 0/imm32/null
20989 74/jump-if-= break/disp8
20990 (populate-mu-type-offsets %eax *(ebp+8) *(ebp+0xc))
20991 # curr = curr->next
20992 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax
20995 $populate-mu-type-sizes:end:
20997 89/<- %esp 5/r32/ebp
21001 # compute sizes of all fields, recursing as necessary
21002 # sum up all their sizes to arrive at total size
21003 # fields may be out of order, but that doesn't affect the answer
21004 populate-mu-type-sizes-in-type: # T: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor)
21007 89/<- %ebp 4/r32/esp
21015 8b/-> *(ebp+8) 6/r32/esi
21016 # if T is already computed, return
21017 81 7/subop/compare *(esi+0xc) 0/imm32 # Typeinfo-total-size-in-bytes
21018 0f 8d/jump-if->= $populate-mu-type-sizes-in-type:end/disp32
21019 # if T is being computed, abort
21020 81 7/subop/compare *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes
21021 0f 84/jump-if-= $populate-mu-type-sizes-in-type:abort/disp32
21022 # tag T (-2 to -1) to avoid infinite recursion
21023 c7 0/subop/copy *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes
21024 # var total-size/edi: int = 0
21025 bf/copy-to-edi 0/imm32
21026 # - for every field, if it's a user-defined type, compute its size
21027 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields)
21028 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax
21029 89/<- %ecx 0/r32/eax
21030 # var table-size/edx: int = table->write
21031 8b/-> *ecx 2/r32/edx # stream-write
21032 # var curr/ecx: (addr table_row) = table->data
21033 8d/copy-address *(ecx+0xc) 1/r32/ecx
21034 # var max/edx: (addr table_row) = table->data + table->write
21035 8d/copy-address *(ecx+edx) 2/r32/edx
21037 $populate-mu-type-sizes-in-type:loop:
21038 # if (curr >= max) break
21039 39/compare %ecx 2/r32/edx
21040 73/jump-if-addr>= break/disp8
21041 # var t/eax: (addr typeinfo-entry) = lookup(curr->value)
21042 (lookup *(ecx+8) *(ecx+0xc)) # => eax
21043 # if (t->input-var == 0) silently ignore it; we'll emit a nice error message while type-checking
21044 81 7/subop/compare *eax 0/imm32 # Typeinfo-entry-input-var
21045 74/jump-if-= $populate-mu-type-sizes-in-type:end/disp8
21046 # compute size of t->input-var
21047 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax
21048 (compute-size-of-var %eax *(ebp+0xc) *(ebp+0x10)) # => eax
21050 01/add-to %edi 0/r32/eax
21052 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size
21057 89/<- *(esi+0xc) 7/r32/edi # Typeinfo-total-size-in-bytes
21058 $populate-mu-type-sizes-in-type:end:
21059 # . restore registers
21066 89/<- %esp 5/r32/ebp
21070 $populate-mu-type-sizes-in-type:abort:
21071 (write-buffered *(ebp+0xc) "cycle in type definitions\n")
21073 (stop *(ebp+0x10) 1)
21076 # Analogous to size-of, except we need to compute what size-of can just read
21077 # off the right data structures.
21078 compute-size-of-var: # in: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int
21081 89/<- %ebp 4/r32/esp
21084 # var t/ecx: (addr type-tree) = lookup(v->type)
21085 8b/-> *(ebp+8) 1/r32/ecx
21086 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
21087 89/<- %ecx 0/r32/eax
21088 # if (t->is-atom == false) t = lookup(t->left)
21090 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom
21091 75/jump-if-!= break/disp8
21092 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
21093 89/<- %ecx 0/r32/eax
21095 # TODO: ensure t is an atom
21096 (compute-size-of-type-id *(ecx+4) *(ebp+0xc) *(ebp+0x10)) # Type-tree-value => eax
21097 $compute-size-of-var:end:
21098 # . restore registers
21101 89/<- %esp 5/r32/ebp
21105 compute-size-of-type-id: # t: type-id, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int
21108 89/<- %ebp 4/r32/esp
21111 # var out/ecx: (handle typeinfo)
21114 89/<- %ecx 4/r32/esp
21116 8b/-> *(ebp+8) 0/r32/eax
21117 # if t is a literal, return 0
21118 3d/compare-eax-and 0/imm32/literal
21119 0f 84/jump-if-= $compute-size-of-type-id:end/disp32 # eax changes type from type-id to int
21120 # if t is a byte, return 4 (because we don't really support non-multiples of 4)
21121 3d/compare-eax-and 8/imm32/byte
21123 75/jump-if-!= break/disp8
21124 b8/copy-to-eax 4/imm32
21125 eb/jump $compute-size-of-type-id:end/disp8
21127 # if t is a handle, return 8
21128 3d/compare-eax-and 4/imm32/handle
21130 75/jump-if-!= break/disp8
21131 b8/copy-to-eax 8/imm32
21132 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int
21134 # if t is a slice, return 8
21135 3d/compare-eax-and 0xc/imm32/slice
21137 75/jump-if-!= break/disp8
21138 b8/copy-to-eax 8/imm32
21139 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int
21141 # if t is a user-defined type, compute its size
21142 # TODO: support non-atom type
21143 (find-typeinfo %eax %ecx)
21145 81 7/subop/compare *ecx 0/imm32
21146 74/jump-if-= break/disp8
21147 $compute-size-of-type-id:user-defined:
21148 (lookup *ecx *(ecx+4)) # => eax
21149 (populate-mu-type-sizes-in-type %eax *(ebp+0xc) *(ebp+0x10))
21150 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes
21151 eb/jump $compute-size-of-type-id:end/disp8
21153 # otherwise return the word size
21154 b8/copy-to-eax 4/imm32
21155 $compute-size-of-type-id:end:
21157 81 0/subop/add %esp 8/imm32
21158 # . restore registers
21161 89/<- %esp 5/r32/ebp
21165 # at this point we have total sizes for all user-defined types
21166 # compute offsets for each element
21167 # complication: fields may be out of order
21168 populate-mu-type-offsets: # in: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor)
21171 89/<- %ebp 4/r32/esp
21179 #? (dump-typeinfos "aaa\n")
21180 # var curr-offset/edi: int = 0
21181 bf/copy-to-edi 0/imm32
21182 # var table/ecx: (addr table string_key (handle typeinfo-entry)) = lookup(in->fields)
21183 8b/-> *(ebp+8) 1/r32/ecx
21184 (lookup *(ecx+4) *(ecx+8)) # Typeinfo-fields Typeinfo-fields => eax
21185 89/<- %ecx 0/r32/eax
21186 # var num-elems/edx: int = table->write / Typeinfo-fields-row-size
21187 8b/-> *ecx 2/r32/edx # stream-write
21188 c1 5/subop/shift-right-logical %edx 4/imm8
21189 # var i/ebx: int = 0
21190 bb/copy-to-ebx 0/imm32
21192 $populate-mu-type-offsets:loop:
21193 39/compare %ebx 2/r32/edx
21194 0f 8d/jump-if->= break/disp32
21195 #? (write-buffered Stderr "looking up index ")
21196 #? (write-int32-hex-buffered Stderr %ebx)
21197 #? (write-buffered Stderr " in ")
21198 #? (write-int32-hex-buffered Stderr *(ebp+8))
21199 #? (write-buffered Stderr Newline)
21201 # var v/esi: (addr typeinfo-entry)
21202 (locate-typeinfo-entry-with-index %ecx %ebx *(ebp+0xc) *(ebp+0x10)) # => eax
21203 89/<- %esi 0/r32/eax
21204 # if v is null, silently move on; we'll emit a nice error message while type-checking
21205 81 7/subop/compare %esi 0/imm32 # Typeinfo-entry-input-var
21206 74/jump-if-= $populate-mu-type-offsets:end/disp8
21207 # if (v->input-var == 0) silently ignore v; we'll emit a nice error message while type-checking
21208 81 7/subop/compare *esi 0/imm32 # Typeinfo-entry-input-var
21209 74/jump-if-= $populate-mu-type-offsets:end/disp8
21210 # v->output-var->offset = curr-offset
21211 # . eax: (addr var)
21212 (lookup *(esi+0xc) *(esi+0x10)) # Typeinfo-entry-output-var Typeinfo-entry-output-var => eax
21213 89/<- *(eax+0x14) 7/r32/edi # Var-offset
21214 # curr-offset += size-of(v->input-var)
21215 (lookup *esi *(esi+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax
21216 (size-of %eax) # => eax
21217 01/add-to %edi 0/r32/eax
21220 e9/jump loop/disp32
21222 $populate-mu-type-offsets:end:
21223 # . restore registers
21231 89/<- %esp 5/r32/ebp
21235 locate-typeinfo-entry-with-index: # table: (addr table (handle array byte) (handle typeinfo-entry)), idx: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: (addr typeinfo-entry)
21238 89/<- %ebp 4/r32/esp
21246 8b/-> *(ebp+8) 6/r32/esi
21247 # var curr/ecx: (addr row (handle array byte) (handle typeinfo-entry)) = table->data
21248 8d/copy-address *(esi+0xc) 1/r32/ecx
21249 # var max/edx: (addr byte) = &table->data[table->write]
21250 8b/-> *esi 2/r32/edx
21251 8d/copy-address *(ecx+edx) 2/r32/edx
21253 $locate-typeinfo-entry-with-index:loop:
21254 39/compare %ecx 2/r32/edx
21255 73/jump-if-addr>= break/disp8
21256 # var v/eax: (addr typeinfo-entry)
21257 (lookup *(ecx+8) *(ecx+0xc)) # => eax
21258 # if (v->index == idx) return v
21259 8b/-> *(eax+8) 3/r32/ebx # Typeinfo-entry-index
21260 #? (write-buffered Stderr "comparing ")
21261 #? (write-int32-hex-buffered Stderr %ebx)
21262 #? (write-buffered Stderr " and ")
21263 #? (write-int32-hex-buffered Stderr *(ebp+0xc))
21264 #? (write-buffered Stderr Newline)
21266 39/compare *(ebp+0xc) 3/r32/ebx
21267 74/jump-if-= $locate-typeinfo-entry-with-index:end/disp8
21268 # curr += Typeinfo-entry-size
21269 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-entry-size
21274 b8/copy-to-eax 0/imm32
21275 $locate-typeinfo-entry-with-index:end:
21276 #? (write-buffered Stderr "returning ")
21277 #? (write-int32-hex-buffered Stderr %eax)
21278 #? (write-buffered Stderr Newline)
21280 # . restore registers
21287 89/<- %esp 5/r32/ebp
21291 dump-typeinfos: # hdr: (addr array byte)
21294 89/<- %ebp 4/r32/esp
21298 (write-buffered Stderr *(ebp+8))
21300 # var curr/eax: (addr typeinfo) = lookup(Program->types)
21301 (lookup *_Program-types *_Program-types->payload) # => eax
21303 # if (curr == null) break
21304 3d/compare-eax-and 0/imm32
21305 74/jump-if-= break/disp8
21306 (write-buffered Stderr "---\n")
21308 (dump-typeinfo %eax)
21309 # curr = lookup(curr->next)
21310 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax
21313 $dump-typeinfos:end:
21314 # . restore registers
21317 89/<- %esp 5/r32/ebp
21321 dump-typeinfo: # in: (addr typeinfo)
21324 89/<- %ebp 4/r32/esp
21333 8b/-> *(ebp+8) 6/r32/esi
21334 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields)
21335 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax
21336 89/<- %ecx 0/r32/eax
21337 (write-buffered Stderr "id:")
21338 (write-int32-hex-buffered Stderr *esi)
21339 (write-buffered Stderr "\n")
21340 (write-buffered Stderr "fields @ ")
21341 (write-int32-hex-buffered Stderr %ecx)
21342 (write-buffered Stderr Newline)
21344 (write-buffered Stderr " write: ")
21345 (write-int32-hex-buffered Stderr *ecx)
21346 (write-buffered Stderr Newline)
21348 (write-buffered Stderr " read: ")
21349 (write-int32-hex-buffered Stderr *(ecx+4))
21350 (write-buffered Stderr Newline)
21352 (write-buffered Stderr " size: ")
21353 (write-int32-hex-buffered Stderr *(ecx+8))
21354 (write-buffered Stderr Newline)
21356 # var table-size/edx: int = table->write
21357 8b/-> *ecx 2/r32/edx # stream-write
21358 # var curr/ecx: (addr table_row) = table->data
21359 8d/copy-address *(ecx+0xc) 1/r32/ecx
21360 # var max/edx: (addr table_row) = table->data + table->write
21361 8d/copy-address *(ecx+edx) 2/r32/edx
21363 $dump-typeinfo:loop:
21364 # if (curr >= max) break
21365 39/compare %ecx 2/r32/edx
21366 0f 83/jump-if-addr>= break/disp32
21367 (write-buffered Stderr " row:\n")
21368 (write-buffered Stderr " key: ")
21369 (write-int32-hex-buffered Stderr *ecx)
21370 (write-buffered Stderr ",")
21371 (write-int32-hex-buffered Stderr *(ecx+4))
21372 (write-buffered Stderr " = '")
21373 (lookup *ecx *(ecx+4))
21374 (write-buffered Stderr %eax)
21375 (write-buffered Stderr "' @ ")
21376 (write-int32-hex-buffered Stderr %eax)
21377 (write-buffered Stderr Newline)
21379 (write-buffered Stderr " value: ")
21380 (write-int32-hex-buffered Stderr *(ecx+8))
21381 (write-buffered Stderr ",")
21382 (write-int32-hex-buffered Stderr *(ecx+0xc))
21383 (write-buffered Stderr " = typeinfo-entry@")
21384 (lookup *(ecx+8) *(ecx+0xc))
21385 (write-int32-hex-buffered Stderr %eax)
21386 (write-buffered Stderr Newline)
21388 (write-buffered Stderr " input var@")
21390 (lookup *(ecx+8) *(ecx+0xc))
21391 (write-buffered Stderr " index: ")
21392 (write-int32-hex-buffered Stderr *(eax+8))
21393 (write-buffered Stderr Newline)
21395 (write-buffered Stderr " output var@")
21396 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var
21400 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size
21402 e9/jump loop/disp32
21404 $dump-typeinfo:end:
21405 # . restore registers
21413 89/<- %esp 5/r32/ebp
21417 dump-var: # indent: int, v: (addr handle var)
21420 89/<- %ebp 4/r32/esp
21425 8b/-> *(ebp+0xc) 0/r32/eax
21427 (write-int32-hex-buffered Stderr *eax)
21428 (write-buffered Stderr ",")
21429 (write-int32-hex-buffered Stderr *(eax+4))
21430 (write-buffered Stderr "->")
21431 (lookup *eax *(eax+4))
21432 (write-int32-hex-buffered Stderr %eax)
21433 (write-buffered Stderr Newline)
21436 3d/compare-eax-and 0/imm32
21437 0f 84/jump-if-= break/disp32
21438 (emit-indent Stderr *(ebp+8))
21439 (write-buffered Stderr "name: ")
21440 89/<- %ebx 0/r32/eax
21441 (write-int32-hex-buffered Stderr *ebx) # Var-name
21442 (write-buffered Stderr ",")
21443 (write-int32-hex-buffered Stderr *(ebx+4)) # Var-name
21444 (write-buffered Stderr "->")
21445 (lookup *ebx *(ebx+4)) # Var-name
21446 (write-int32-hex-buffered Stderr %eax)
21448 3d/compare-eax-and 0/imm32
21449 74/jump-if-= break/disp8
21450 (write-buffered Stderr Space)
21451 (write-buffered Stderr %eax)
21453 (write-buffered Stderr Newline)
21455 (emit-indent Stderr *(ebp+8))
21456 (write-buffered Stderr "block depth: ")
21457 (write-int32-hex-buffered Stderr *(ebx+0x10)) # Var-block-depth
21458 (write-buffered Stderr Newline)
21460 (emit-indent Stderr *(ebp+8))
21461 (write-buffered Stderr "stack offset: ")
21462 (write-int32-hex-buffered Stderr *(ebx+0x14)) # Var-offset
21463 (write-buffered Stderr Newline)
21465 (emit-indent Stderr *(ebp+8))
21466 (write-buffered Stderr "reg: ")
21467 (write-int32-hex-buffered Stderr *(ebx+0x18)) # Var-register
21468 (write-buffered Stderr ",")
21469 (write-int32-hex-buffered Stderr *(ebx+0x1c)) # Var-register
21470 (write-buffered Stderr "->")
21472 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register
21473 (write-int32-hex-buffered Stderr %eax)
21475 3d/compare-eax-and 0/imm32
21476 74/jump-if-= break/disp8
21477 (write-buffered Stderr Space)
21478 (write-buffered Stderr %eax)
21480 (write-buffered Stderr Newline)
21484 # . restore registers
21488 89/<- %esp 5/r32/ebp
21492 #######################################################
21494 #######################################################
21496 check-mu-types: # err: (addr buffered-file), ed: (addr exit-descriptor)
21499 89/<- %ebp 4/r32/esp
21502 # var curr/eax: (addr function) = lookup(Program->functions)
21503 (lookup *_Program-functions *_Program-functions->payload) # => eax
21505 $check-mu-types:loop:
21506 # if (curr == null) break
21507 3d/compare-eax-and 0/imm32
21508 0f 84/jump-if-= break/disp32
21509 #? # dump curr->name {{{
21511 #? (lookup *eax *(eax+4)) # Function-name Function-name => eax
21512 #? (write-buffered Stderr %eax)
21513 #? (write-buffered Stderr Newline)
21517 (check-mu-function %eax *(ebp+8) *(ebp+0xc))
21518 # curr = lookup(curr->next)
21519 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax
21520 e9/jump loop/disp32
21522 $check-mu-types:end:
21523 # . restore registers
21526 89/<- %esp 5/r32/ebp
21530 check-mu-function: # fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
21533 89/<- %ebp 4/r32/esp
21538 8b/-> *(ebp+8) 6/r32/esi
21540 (lookup *(esi+0x10) *(esi+0x14)) # Function-outputs Function-outputs => eax
21541 (check-all-unique-registers %eax %esi *(ebp+0xc) *(ebp+0x10))
21543 (lookup *(esi+0x18) *(esi+0x1c)) # Function-body Function-body => eax
21544 (check-mu-block %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10))
21545 # if function has no outputs, we're done
21546 81 7/subop/compare *(esi+0x10) 0/imm32
21547 74/jump-if-= $check-mu-function:end/disp8
21548 # some final checks on body
21549 (check-final-stmt-is-return %eax %esi *(ebp+0xc) *(ebp+0x10))
21550 (check-no-breaks %eax %esi *(ebp+0xc) *(ebp+0x10))
21551 $check-mu-function:end:
21552 # . restore registers
21556 89/<- %esp 5/r32/ebp
21560 check-mu-block: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
21563 89/<- %ebp 4/r32/esp
21567 8b/-> *(ebp+8) 0/r32/eax
21568 # var stmts/eax: (addr list stmt) = lookup(block->statements)
21569 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax
21572 $check-mu-block:check-empty:
21573 3d/compare-eax-and 0/imm32
21574 0f 84/jump-if-= break/disp32
21575 # emit block->statements
21576 (check-mu-stmt-list %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21578 $check-mu-block:end:
21579 # . restore registers
21582 89/<- %esp 5/r32/ebp
21586 check-mu-stmt-list: # stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
21589 89/<- %ebp 4/r32/esp
21594 8b/-> *(ebp+8) 6/r32/esi
21596 $check-mu-stmt-list:loop:
21597 81 7/subop/compare %esi 0/imm32
21598 0f 84/jump-if-= break/disp32
21599 # var curr-stmt/eax: (addr stmt) = lookup(stmts->value)
21600 (lookup *esi *(esi+4)) # List-value List-value => eax
21602 $check-mu-stmt-list:check-for-block:
21603 81 7/subop/compare *eax 0/imm32/block # Stmt-tag
21604 75/jump-if-!= break/disp8
21605 $check-mu-stmt-list:block:
21606 (check-mu-block %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21607 eb/jump $check-mu-stmt-list:continue/disp8
21610 $check-mu-stmt-list:check-for-stmt1:
21611 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag
21612 0f 85/jump-if-!= break/disp32
21613 $check-mu-stmt-list:stmt1:
21614 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21615 eb/jump $check-mu-stmt-list:continue/disp8
21618 $check-mu-stmt-list:check-for-reg-var-def:
21619 81 7/subop/compare *eax 3/imm32/reg-var-def # Stmt-tag
21620 0f 85/jump-if-!= break/disp32
21621 $check-mu-stmt-list:reg-var-def:
21622 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21623 eb/jump $check-mu-stmt-list:continue/disp8
21625 $check-mu-stmt-list:continue:
21626 # TODO: raise an error on unrecognized Stmt-tag
21627 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax
21628 89/<- %esi 0/r32/eax
21629 e9/jump loop/disp32
21631 $check-mu-stmt-list:end:
21632 # . restore registers
21636 89/<- %esp 5/r32/ebp
21640 check-mu-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
21643 89/<- %ebp 4/r32/esp
21646 # - if stmt's operation matches a primitive, check against it
21647 (has-primitive-name? *(ebp+8)) # => eax
21648 3d/compare-eax-and 0/imm32/false
21650 74/jump-if-= break/disp8
21651 (check-mu-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21652 e9/jump $check-mu-stmt:end/disp32
21654 # - otherwise find a function to check against
21655 # var f/eax: (addr function) = lookup(*Program->functions)
21656 (lookup *_Program-functions *_Program-functions->payload) # => eax
21657 (find-matching-function %eax *(ebp+8)) # => eax
21658 3d/compare-eax-and 0/imm32
21660 74/jump-if-= break/disp8
21661 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21662 eb/jump $check-mu-stmt:end/disp8
21664 # var f/eax: (addr function) = lookup(*Program->signatures)
21665 (lookup *_Program-signatures *_Program-signatures->payload) # => eax
21666 (find-matching-function %eax *(ebp+8)) # => eax
21667 3d/compare-eax-and 0/imm32
21669 74/jump-if-= break/disp8
21670 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21671 eb/jump $check-mu-stmt:end/disp8
21673 # - otherwise abort
21674 e9/jump $check-mu-stmt:unknown-call/disp32
21675 $check-mu-stmt:end:
21676 # . restore registers
21679 89/<- %esp 5/r32/ebp
21683 $check-mu-stmt:unknown-call:
21684 (write-buffered *(ebp+0x10) "unknown function '")
21685 8b/-> *(ebp+8) 0/r32/eax
21686 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax
21687 (write-buffered *(ebp+0x10) %eax)
21688 (write-buffered *(ebp+0x10) "'\n")
21689 (flush *(ebp+0x10))
21690 (stop *(ebp+0x14) 1)
21693 has-primitive-name?: # stmt: (addr stmt) -> result/eax: boolean
21696 89/<- %ebp 4/r32/esp
21700 # var name/esi: (addr array byte) = lookup(stmt->operation)
21701 8b/-> *(ebp+8) 6/r32/esi
21702 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax
21703 89/<- %esi 0/r32/eax
21704 # if (name == "return") return true
21705 (string-equal? %esi "return") # => eax
21706 3d/compare-eax-and 0/imm32/false
21707 0f 85/jump-if-!= $has-primitive-name?:end/disp32
21708 # if (name == "get") return true
21709 (string-equal? %esi "get") # => eax
21710 3d/compare-eax-and 0/imm32/false
21711 0f 85/jump-if-!= $has-primitive-name?:end/disp32
21712 # if (name == "index") return true
21713 (string-equal? %esi "index") # => eax
21714 3d/compare-eax-and 0/imm32/false
21715 0f 85/jump-if-!= $has-primitive-name?:end/disp32
21716 # if (name == "length") return true
21717 (string-equal? %esi "length") # => eax
21718 3d/compare-eax-and 0/imm32/false
21719 0f 85/jump-if-!= $has-primitive-name?:end/disp32
21720 # if (name == "compute-offset") return true
21721 (string-equal? %esi "compute-offset") # => eax
21722 3d/compare-eax-and 0/imm32/false
21723 0f 85/jump-if-!= $has-primitive-name?:end/disp32
21724 # if (name == "copy-object") return true
21725 (string-equal? %esi "copy-object") # => eax
21726 3d/compare-eax-and 0/imm32/false
21727 0f 85/jump-if-!= $has-primitive-name?:end/disp32
21728 # if (name == "clear-object") return true
21729 (string-equal? %esi "clear-object") # => eax
21730 3d/compare-eax-and 0/imm32/false
21731 0f 85/jump-if-!= $has-primitive-name?:end/disp32
21732 # if (name == "allocate") return true
21733 (string-equal? %esi "allocate") # => eax
21734 3d/compare-eax-and 0/imm32/false
21735 0f 85/jump-if-!= $has-primitive-name?:end/disp32
21736 # if (name == "populate") return true
21737 (string-equal? %esi "populate") # => eax
21738 3d/compare-eax-and 0/imm32/false
21739 0f 85/jump-if-!= $has-primitive-name?:end/disp32
21740 # if (name == "populate-stream") return true
21741 (string-equal? %esi "populate-stream") # => eax
21742 3d/compare-eax-and 0/imm32/false
21743 0f 85/jump-if-!= $has-primitive-name?:end/disp32
21744 # if (name == "read-from-stream") return true
21745 (string-equal? %esi "read-from-stream") # => eax
21746 3d/compare-eax-and 0/imm32/false
21747 0f 85/jump-if-!= $has-primitive-name?:end/disp32
21748 # if (name == "write-to-stream") return true
21749 (string-equal? %esi "write-to-stream") # => eax
21750 3d/compare-eax-and 0/imm32/false
21751 0f 85/jump-if-!= $has-primitive-name?:end/disp32
21752 # var curr/ecx: (addr primitive) = Primitives
21753 b9/copy-to-ecx Primitives/imm32
21755 $has-primitive-name?:loop:
21756 # if (curr == null) break
21757 81 7/subop/compare %ecx 0/imm32
21758 74/jump-if-= break/disp8
21759 # if (primitive->name == name) return true
21760 (lookup *ecx *(ecx+4)) # Primitive-name Primitive-name => eax
21761 #? (write-buffered Stderr %eax)
21762 #? (write-buffered Stderr Newline)
21764 (string-equal? %esi %eax) # => eax
21765 3d/compare-eax-and 0/imm32/false
21766 75/jump-if-!= $has-primitive-name?:end/disp8
21767 $has-primitive-name?:next-primitive:
21768 # curr = curr->next
21769 (lookup *(ecx+0x3c) *(ecx+0x40)) # Primitive-next Primitive-next => eax
21770 89/<- %ecx 0/r32/eax
21772 e9/jump loop/disp32
21775 b8/copy-to-eax 0/imm32
21776 $has-primitive-name?:end:
21777 # . restore registers
21781 89/<- %esp 5/r32/ebp
21785 check-mu-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
21788 89/<- %ebp 4/r32/esp
21792 # var op/ecx: (addr array byte) = lookup(stmt->operation)
21793 8b/-> *(ebp+8) 0/r32/eax
21794 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax
21795 89/<- %ecx 0/r32/eax
21796 # if (op == "copy") check-mu-copy-stmt
21798 (string-equal? %ecx "copy") # => eax
21799 3d/compare-eax-and 0/imm32/false
21800 74/jump-if-= break/disp8
21801 (check-mu-copy-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21802 e9/jump $check-mu-primitive:end/disp32
21804 # if (op == "copy-to") check-mu-copy-to-stmt
21806 (string-equal? %ecx "copy-to") # => eax
21807 3d/compare-eax-and 0/imm32/false
21808 74/jump-if-= break/disp8
21809 (check-mu-copy-to-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21810 e9/jump $check-mu-primitive:end/disp32
21812 # if (op == "copy-byte") check-mu-copy-byte-stmt
21814 (string-equal? %ecx "copy-byte") # => eax
21815 3d/compare-eax-and 0/imm32/false
21816 74/jump-if-= break/disp8
21817 (check-mu-copy-byte-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21818 e9/jump $check-mu-primitive:end/disp32
21820 # if (op == "copy-byte-to") check-mu-copy-byte-to-stmt
21822 (string-equal? %ecx "copy-byte-to") # => eax
21823 3d/compare-eax-and 0/imm32/false
21824 74/jump-if-= break/disp8
21825 (check-mu-copy-byte-to-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21826 e9/jump $check-mu-primitive:end/disp32
21828 # if (op == "compare") check-mu-compare-stmt
21830 (string-equal? %ecx "compare") # => eax
21831 3d/compare-eax-and 0/imm32/false
21832 74/jump-if-= break/disp8
21833 (check-mu-compare-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21834 e9/jump $check-mu-primitive:end/disp32
21836 # if (op == "address") check-mu-address-stmt
21838 (string-equal? %ecx "address") # => eax
21839 3d/compare-eax-and 0/imm32/false
21840 74/jump-if-= break/disp8
21841 (check-mu-address-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21842 e9/jump $check-mu-primitive:end/disp32
21844 # if (op == "return") check-mu-return-stmt
21846 (string-equal? %ecx "return") # => eax
21847 3d/compare-eax-and 0/imm32/false
21848 74/jump-if-= break/disp8
21849 (check-mu-return-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21850 e9/jump $check-mu-primitive:end/disp32
21852 # if (op == "get") check-mu-get-stmt
21854 (string-equal? %ecx "get") # => eax
21855 3d/compare-eax-and 0/imm32/false
21856 74/jump-if-= break/disp8
21857 (check-mu-get-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21858 e9/jump $check-mu-primitive:end/disp32
21860 # if (op == "index") check-mu-index-stmt
21862 (string-equal? %ecx "index") # => eax
21863 3d/compare-eax-and 0/imm32/false
21864 74/jump-if-= break/disp8
21865 (check-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21866 e9/jump $check-mu-primitive:end/disp32
21868 # if (op == "length") check-mu-length-stmt
21870 (string-equal? %ecx "length") # => eax
21871 3d/compare-eax-and 0/imm32/false
21872 74/jump-if-= break/disp8
21873 (check-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21874 e9/jump $check-mu-primitive:end/disp32
21876 # if (op == "compute-offset") check-mu-compute-offset-stmt
21878 (string-equal? %ecx "compute-offset") # => eax
21879 3d/compare-eax-and 0/imm32/false
21880 74/jump-if-= break/disp8
21881 (check-mu-compute-offset-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21882 e9/jump $check-mu-primitive:end/disp32
21884 # if (op == "copy-object") check-mu-copy-object-stmt
21886 (string-equal? %ecx "copy-object") # => eax
21887 3d/compare-eax-and 0/imm32/false
21888 74/jump-if-= break/disp8
21889 (check-mu-copy-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21890 e9/jump $check-mu-primitive:end/disp32
21892 # if (op == "clear-object") check-mu-clear-object-stmt
21894 (string-equal? %ecx "clear-object") # => eax
21895 3d/compare-eax-and 0/imm32/false
21896 74/jump-if-= break/disp8
21897 (check-mu-clear-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21898 e9/jump $check-mu-primitive:end/disp32
21900 # if (op == "allocate") check-mu-allocate-stmt
21902 (string-equal? %ecx "allocate") # => eax
21903 3d/compare-eax-and 0/imm32/false
21904 74/jump-if-= break/disp8
21905 (check-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21906 e9/jump $check-mu-primitive:end/disp32
21908 # if (op == "populate") check-mu-populate-stmt
21910 (string-equal? %ecx "populate") # => eax
21911 3d/compare-eax-and 0/imm32/false
21912 74/jump-if-= break/disp8
21913 (check-mu-populate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21914 e9/jump $check-mu-primitive:end/disp32
21916 # if (op == "populate-stream") check-mu-populate-stream-stmt
21918 (string-equal? %ecx "populate-stream") # => eax
21919 3d/compare-eax-and 0/imm32/false
21920 74/jump-if-= break/disp8
21921 (check-mu-populate-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21922 e9/jump $check-mu-primitive:end/disp32
21924 # if (op == "read-from-stream") check-mu-read-from-stream-stmt
21926 (string-equal? %ecx "read-from-stream") # => eax
21927 3d/compare-eax-and 0/imm32/false
21928 74/jump-if-= break/disp8
21929 (check-mu-read-from-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21930 e9/jump $check-mu-primitive:end/disp32
21932 # if (op == "write-to-stream") check-mu-write-to-stream-stmt
21934 (string-equal? %ecx "write-to-stream") # => eax
21935 3d/compare-eax-and 0/imm32/false
21936 74/jump-if-= break/disp8
21937 (check-mu-write-to-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21938 e9/jump $check-mu-primitive:end/disp32
21940 # if (op == "convert") check-mu-convert-stmt
21942 (string-equal? %ecx "convert") # => eax
21943 3d/compare-eax-and 0/imm32/false
21944 74/jump-if-= break/disp8
21945 (check-mu-convert-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21946 e9/jump $check-mu-primitive:end/disp32
21948 # otherwise check-numberlike-stmt
21949 (check-mu-numberlike-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21950 $check-mu-primitive:end:
21951 # . restore registers
21955 89/<- %esp 5/r32/ebp
21959 # by default, Mu primitives should only operate on 'number-like' types
21960 check-mu-numberlike-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
21963 89/<- %ebp 4/r32/esp
21969 8b/-> *(ebp+8) 6/r32/esi
21970 # var gas/ecx: int = 2
21971 b9/copy-to-ecx 2/imm32
21972 # - check at most 1 output
21973 # var output/eax: (addr stmt-var) = stmt->outputs
21974 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
21976 3d/compare-eax-and 0/imm32
21977 74/jump-if-= break/disp8
21978 $check-mu-numberlike-primitive:output:
21979 (check-mu-numberlike-output %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21980 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
21981 3d/compare-eax-and 0/imm32
21982 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-outputs/disp32
21983 # check output is in a register
21987 # - check first inout
21988 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
21990 3d/compare-eax-and 0/imm32
21991 0f 84/jump-if-= $check-mu-numberlike-primitive:end/disp32
21992 $check-mu-numberlike-primitive:first-inout:
21993 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
21997 # - check second inout
21998 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
22000 3d/compare-eax-and 0/imm32
22001 74/jump-if-= $check-mu-numberlike-primitive:end/disp8
22002 $check-mu-numberlike-primitive:second-inout:
22003 # is a second inout allowed?
22004 81 7/subop/compare %ecx 0/imm32
22005 0f 84/jump-if-= $check-mu-numberlike-primitive:error-too-many-inouts/disp32
22006 $check-mu-numberlike-primitive:second-inout-permitted:
22007 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
22009 $check-mu-numberlike-primitive:third-inout:
22010 # if there's a third arg, raise an error
22011 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next
22012 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-inouts/disp32
22013 $check-mu-numberlike-primitive:end:
22014 # . restore registers
22019 89/<- %esp 5/r32/ebp
22023 $check-mu-numberlike-primitive:error-too-many-inouts:
22024 (write-buffered *(ebp+0x10) "fn ")
22025 8b/-> *(ebp+0xc) 0/r32/eax
22026 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22027 (write-buffered *(ebp+0x10) %eax)
22028 (write-buffered *(ebp+0x10) ": stmt ")
22029 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax
22030 (write-buffered *(ebp+0x10) %eax)
22031 (write-buffered *(ebp+0x10) ": too many inouts; most primitives support at most two arguments, across inouts and outputs\n")
22032 (flush *(ebp+0x10))
22033 (stop *(ebp+0x14) 1)
22036 $check-mu-numberlike-primitive:error-too-many-outputs:
22037 (write-buffered *(ebp+0x10) "fn ")
22038 8b/-> *(ebp+0xc) 0/r32/eax
22039 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22040 (write-buffered *(ebp+0x10) %eax)
22041 (write-buffered *(ebp+0x10) ": stmt ")
22042 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax
22043 (write-buffered *(ebp+0x10) %eax)
22044 (write-buffered *(ebp+0x10) ": too many outputs; most primitives support at most one output\n")
22045 (flush *(ebp+0x10))
22046 (stop *(ebp+0x14) 1)
22049 check-mu-numberlike-arg: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
22052 89/<- %ebp 4/r32/esp
22056 # var t/esi: (addr type-tree) = lookup(v->value->type)
22057 8b/-> *(ebp+8) 0/r32/eax
22058 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
22059 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22060 89/<- %esi 0/r32/eax
22061 $check-mu-numberlike-arg:check-literal:
22062 # if t is an int, return
22063 (simple-mu-type? %esi 0) # literal => eax
22064 3d/compare-eax-and 0/imm32/false
22065 0f 85/jump-if-!= $check-mu-numberlike-arg:end/disp32
22066 $check-mu-numberlike-arg:check-addr:
22067 # if t is an addr and v is dereferenced, return whether t->payload is an addr
22069 (mu-addr-type? %esi) # => eax
22070 3d/compare-eax-and 0/imm32/false
22071 74/jump-if-= break/disp8
22072 8b/-> *(ebp+8) 0/r32/eax
22073 8b/-> *(eax+0x10) 0/r32/eax # Stmt-var-is-deref
22074 3d/compare-eax-and 0/imm32/false
22076 74/jump-if-= break/disp8
22077 (lookup *(esi+0xc) *(esi+0x10)) # Type-tree-right Type-tree-right => eax
22078 # if t->right is null, t = t->left
22079 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
22081 75/jump-if-!= break/disp8
22082 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
22084 (mu-addr-type? %eax) # => eax
22085 3d/compare-eax-and 0/imm32/false
22086 74/jump-if-= $check-mu-numberlike-arg:end/disp8
22089 $check-mu-numberlike-arg:output-checks:
22090 (check-mu-numberlike-output *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18))
22091 $check-mu-numberlike-arg:end:
22092 # . restore registers
22096 89/<- %esp 5/r32/ebp
22100 check-mu-numberlike-output: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
22103 89/<- %ebp 4/r32/esp
22107 (mu-numberlike-output-var? *(ebp+8)) # => eax
22108 3d/compare-eax-and 0/imm32/false
22109 0f 84/jump-if-= $check-mu-numberlike-output:fail/disp32
22110 $check-mu-numberlike-output:end:
22111 # . restore registers
22114 89/<- %esp 5/r32/ebp
22118 $check-mu-numberlike-output:fail:
22119 # otherwise raise an error
22120 (write-buffered *(ebp+0x14) "fn ")
22121 8b/-> *(ebp+0x10) 0/r32/eax
22122 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22123 (write-buffered *(ebp+0x14) %eax)
22124 (write-buffered *(ebp+0x14) ": stmt ")
22125 8b/-> *(ebp+0xc) 0/r32/eax
22126 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax
22127 (write-buffered *(ebp+0x14) %eax)
22128 (write-buffered *(ebp+0x14) ": '")
22129 8b/-> *(ebp+8) 0/r32/eax
22130 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
22131 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22132 (write-buffered *(ebp+0x14) %eax)
22133 (write-buffered *(ebp+0x14) "' must be a non-addr non-offset scalar\n")
22134 (flush *(ebp+0x14))
22135 (stop *(ebp+0x18) 1)
22138 mu-numberlike-output-var?: # v: (addr stmt-var) -> result/eax: boolean
22141 89/<- %ebp 4/r32/esp
22143 8b/-> *(ebp+8) 0/r32/eax
22144 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
22145 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22146 (mu-numberlike-output? %eax) # => eax
22147 $mu-numberlike-output-var?:end:
22149 89/<- %esp 5/r32/ebp
22153 mu-numberlike-output?: # v: (addr type-tree) -> result/eax: boolean
22156 89/<- %ebp 4/r32/esp
22159 # var t/esi: (addr type-tree) = lookup(v->value->type)
22160 8b/-> *(ebp+8) 6/r32/esi
22161 $mu-numberlike-output?:check-int:
22162 # if t is an int, return
22163 (simple-mu-type? %esi 1) # int => eax
22164 3d/compare-eax-and 0/imm32/false
22165 0f 85/jump-if-!= $mu-numberlike-output?:return-true/disp32
22166 $mu-numberlike-output?:check-float:
22167 # if t is a float, return
22168 (simple-mu-type? %esi 0xf) # float => eax
22169 3d/compare-eax-and 0/imm32/false
22170 75/jump-if-!= $mu-numberlike-output?:return-true/disp8
22171 $mu-numberlike-output?:check-boolean:
22172 # if t is a boolean, return
22173 (simple-mu-type? %esi 5) # boolean => eax
22174 3d/compare-eax-and 0/imm32/false
22175 75/jump-if-!= $mu-numberlike-output?:return-true/disp8
22176 $mu-numberlike-output?:check-byte:
22177 # if t is a byte, return
22178 (simple-mu-type? %esi 8) # byte => eax
22179 3d/compare-eax-and 0/imm32/false
22180 75/jump-if-!= $mu-numberlike-output?:return-true/disp8
22181 $mu-numberlike-output?:check-code-point:
22182 # if t is a code-point, return
22183 (simple-mu-type? %esi 0xd) # code-point => eax
22184 3d/compare-eax-and 0/imm32/false
22185 75/jump-if-!= $mu-numberlike-output?:return-true/disp8
22186 $mu-numberlike-output?:check-grapheme:
22187 # if t is a grapheme, return
22188 (simple-mu-type? %esi 0xe) # grapheme => eax
22189 3d/compare-eax-and 0/imm32/false
22190 75/jump-if-!= $mu-numberlike-output?:return-true/disp8
22191 $mu-numberlike-output?:return-false:
22192 b8/copy-to-eax 0/imm32/false
22193 eb/jump $mu-numberlike-output?:end/disp8
22194 $mu-numberlike-output?:return-true:
22195 b8/copy-to-eax 1/imm32/true
22196 $mu-numberlike-output?:end:
22197 # . restore registers
22200 89/<- %esp 5/r32/ebp
22204 check-mu-copy-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
22207 89/<- %ebp 4/r32/esp
22214 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8)
22215 81 5/subop/subtract %esp 0x60/imm32
22216 68/push 0x60/imm32/size
22217 68/push 0/imm32/read
22218 68/push 0/imm32/write
22219 89/<- %edx 4/r32/esp
22220 $check-mu-copy-stmt:get-output:
22222 8b/-> *(ebp+8) 6/r32/esi
22223 # var output/edi: (addr stmt-var) = stmt->outputs
22224 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
22225 89/<- %edi 0/r32/eax
22227 3d/compare-eax-and 0/imm32
22228 0f 84/jump-if-= $check-mu-copy-stmt:error-no-output/disp32
22230 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
22231 3d/compare-eax-and 0/imm32
22232 0f 85/jump-if-!= $check-mu-copy-stmt:error-too-many-outputs/disp32
22233 $check-mu-copy-stmt:get-inout:
22234 # var inout/esi: (addr stmt-var) = stmt->inouts
22235 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
22236 89/<- %esi 0/r32/eax
22238 3d/compare-eax-and 0/imm32
22239 0f 84/jump-if-= $check-mu-copy-stmt:error-no-inout/disp32
22241 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
22242 3d/compare-eax-and 0/imm32
22243 0f 85/jump-if-!= $check-mu-copy-stmt:error-too-many-inouts/disp32
22244 $check-mu-copy-stmt:types:
22245 # if inout is not a scalar, abort
22246 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22247 (size-of %eax) # => eax
22248 3d/compare-eax-and 4/imm32
22249 0f 8f/jump-if-> $check-mu-copy-stmt:error-inout-too-large/disp32
22250 # var inout-type/ecx: (addr type-tree) = inout->value->type
22251 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22252 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22253 89/<- %ecx 0/r32/eax
22254 # if (inout->is-deref?) inout-type = inout-type->payload
22255 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref
22256 3d/compare-eax-and 0/imm32/false
22258 74/jump-if-= break/disp8
22259 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
22260 # if inout-type->right is null, t = inout-type->left
22261 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
22263 75/jump-if-!= break/disp8
22264 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
22266 89/<- %ecx 0/r32/eax
22268 # if output not in register, abort
22269 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22270 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
22271 3d/compare-eax-and 0/imm32
22272 0f 84/jump-if-= $check-mu-copy-stmt:error-output-not-in-register/disp32
22273 # var output-type/eax: (addr type-tree) = output->value->type
22274 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22275 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22276 # if (inout-type == output-type) return
22277 (type-match? %eax %ecx %edx) # => eax
22278 3d/compare-eax-and 0/imm32
22279 0f 85/jump-if-!= $check-mu-copy-stmt:end/disp32
22280 # if output is an addr and inout is 0, return
22282 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22283 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22284 (mu-addr-type? %eax) # => eax
22285 3d/compare-eax-and 0/imm32/false
22286 74/jump-if-= break/disp8
22287 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22288 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22289 (string-equal? %eax "0") # => eax
22290 3d/compare-eax-and 0/imm32/false
22291 74/jump-if-= break/disp8
22292 e9/jump $check-mu-copy-stmt:end/disp32
22294 # if output is an offset and inout is 0, return
22296 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22297 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22298 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
22299 75/jump-if-!= break/disp8
22300 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
22301 (simple-mu-type? %eax 7) # offset => eax
22302 3d/compare-eax-and 0/imm32/false
22303 74/jump-if-= break/disp8
22304 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22305 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22306 (string-equal? %eax "0") # => eax
22307 3d/compare-eax-and 0/imm32/false
22308 74/jump-if-= break/disp8
22309 e9/jump $check-mu-copy-stmt:end/disp32
22311 # if output is a byte, abort if inout is not a literal. Otherwise return.
22313 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22314 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22315 (simple-mu-type? %eax 8) # byte => eax
22316 3d/compare-eax-and 0/imm32/false
22317 74/jump-if-= break/disp8
22318 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22319 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22320 (simple-mu-type? %eax 0) # literal => eax
22321 3d/compare-eax-and 0/imm32/false
22322 0f 84/jump-if-= $check-mu-copy-stmt:error-non-literal-to-byte/disp32
22323 eb/jump $check-mu-copy-stmt:end/disp8
22325 # if output is not number-like, abort
22326 (check-mu-numberlike-output %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
22327 $check-mu-copy-stmt:end:
22329 81 0/subop/add %esp 0x6c/imm32
22330 # . restore registers
22337 89/<- %esp 5/r32/ebp
22341 $check-mu-copy-stmt:error-no-inout:
22342 (write-buffered *(ebp+0x10) "fn ")
22343 8b/-> *(ebp+0xc) 0/r32/eax
22344 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22345 (write-buffered *(ebp+0x10) %eax)
22346 (write-buffered *(ebp+0x10) ": stmt 'copy' expects an inout\n")
22347 (flush *(ebp+0x10))
22348 (stop *(ebp+0x14) 1)
22351 $check-mu-copy-stmt:error-too-many-inouts:
22352 (write-buffered *(ebp+0x10) "fn ")
22353 8b/-> *(ebp+0xc) 0/r32/eax
22354 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22355 (write-buffered *(ebp+0x10) %eax)
22356 (write-buffered *(ebp+0x10) ": stmt 'copy' must have just one inout\n")
22357 (flush *(ebp+0x10))
22358 (stop *(ebp+0x14) 1)
22361 $check-mu-copy-stmt:error-no-output:
22362 (write-buffered *(ebp+0x10) "fn ")
22363 8b/-> *(ebp+0xc) 0/r32/eax
22364 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22365 (write-buffered *(ebp+0x10) %eax)
22366 (write-buffered *(ebp+0x10) ": stmt 'copy' expects an output\n")
22367 (flush *(ebp+0x10))
22368 (stop *(ebp+0x14) 1)
22371 $check-mu-copy-stmt:error-output-not-in-register:
22372 (write-buffered *(ebp+0x10) "fn ")
22373 8b/-> *(ebp+0xc) 0/r32/eax
22374 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22375 (write-buffered *(ebp+0x10) %eax)
22376 (write-buffered *(ebp+0x10) ": stmt copy: output '")
22377 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22378 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22379 (write-buffered *(ebp+0x10) %eax)
22380 (write-buffered *(ebp+0x10) "' not in a register\n")
22381 (flush *(ebp+0x10))
22382 (stop *(ebp+0x14) 1)
22385 $check-mu-copy-stmt:error-too-many-outputs:
22386 (write-buffered *(ebp+0x10) "fn ")
22387 8b/-> *(ebp+0xc) 0/r32/eax
22388 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22389 (write-buffered *(ebp+0x10) %eax)
22390 (write-buffered *(ebp+0x10) ": stmt 'copy' must have just one output\n")
22391 (flush *(ebp+0x10))
22392 (stop *(ebp+0x14) 1)
22395 $check-mu-copy-stmt:error-inout-too-large:
22396 (write-buffered *(ebp+0x10) "fn ")
22397 8b/-> *(ebp+0xc) 0/r32/eax
22398 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22399 (write-buffered *(ebp+0x10) %eax)
22400 (write-buffered *(ebp+0x10) ": stmt copy: '")
22401 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22402 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22403 (write-buffered *(ebp+0x10) %eax)
22404 (write-buffered *(ebp+0x10) "' is too large to fit in a register\n")
22405 (flush *(ebp+0x10))
22406 (stop *(ebp+0x14) 1)
22409 $check-mu-copy-stmt:error-non-literal-to-byte:
22410 (write-buffered *(ebp+0x10) "fn ")
22411 8b/-> *(ebp+0xc) 0/r32/eax
22412 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22413 (write-buffered *(ebp+0x10) %eax)
22414 (write-buffered *(ebp+0x10) ": stmt copy: cannot copy non-literal to '")
22415 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22416 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22417 (write-buffered *(ebp+0x10) %eax)
22418 (write-buffered *(ebp+0x10) "' of type byte; use copy-byte\n")
22419 (flush *(ebp+0x10))
22420 (stop *(ebp+0x14) 1)
22423 check-mu-copy-to-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
22426 89/<- %ebp 4/r32/esp
22434 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8)
22435 81 5/subop/subtract %esp 0x60/imm32
22436 68/push 0x60/imm32/size
22437 68/push 0/imm32/read
22438 68/push 0/imm32/write
22439 89/<- %edx 4/r32/esp
22441 8b/-> *(ebp+8) 6/r32/esi
22442 $check-mu-copy-to-stmt:check-for-output:
22443 # if stmt->outputs abort
22444 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
22445 3d/compare-eax-and 0/imm32
22446 0f 85/jump-if-!= $check-mu-copy-to-stmt:error-too-many-outputs/disp32
22447 $check-mu-copy-to-stmt:get-dest:
22448 # var dest/edi: (addr stmt-var) = stmt->inouts
22449 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
22450 89/<- %edi 0/r32/eax
22452 3d/compare-eax-and 0/imm32
22453 0f 84/jump-if-= $check-mu-copy-to-stmt:error-incorrect-inouts/disp32
22454 $check-mu-copy-to-stmt:get-src:
22455 # var src/esi: (addr stmt-var) = dest->next
22456 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
22457 89/<- %esi 0/r32/eax
22459 3d/compare-eax-and 0/imm32
22460 0f 84/jump-if-= $check-mu-copy-to-stmt:error-incorrect-inouts/disp32
22462 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
22463 3d/compare-eax-and 0/imm32
22464 0f 85/jump-if-!= $check-mu-copy-to-stmt:error-incorrect-inouts/disp32
22465 $check-mu-copy-to-stmt:types:
22466 # if src is not a scalar, abort
22467 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22468 (size-of %eax) # => eax
22469 3d/compare-eax-and 4/imm32
22470 0f 8f/jump-if-> $check-mu-copy-to-stmt:error-src-too-large/disp32
22471 # var src-type/ecx: (addr type-tree) = src->value->type
22472 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22473 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22474 89/<- %ecx 0/r32/eax
22475 # if src not in register or literal, abort
22476 # (we can't use stack-offset because it hasn't been computed yet)
22478 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22479 (lookup *(eax+0x8) *(eax+0xc)) # Var-type Var-type => eax
22480 (simple-mu-type? %eax 0) # => eax
22481 3d/compare-eax-and 0/imm32
22482 75/jump-if-!= break/disp8
22483 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22484 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
22485 3d/compare-eax-and 0/imm32
22486 75/jump-if-!= break/disp8
22487 e9/jump $check-mu-copy-to-stmt:error-src-not-literal-or-in-register/disp32
22489 # var dest-type/ebx: (addr type-tree) = dest->value->type
22490 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22491 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22492 89/<- %ebx 0/r32/eax
22493 # if (dest->is-deref?) dest-type = dest-type->payload
22494 $check-mu-copy-to-stmt:check-dest-deref:
22495 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref
22496 3d/compare-eax-and 0/imm32/false
22498 74/jump-if-= break/disp8
22499 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
22500 $check-mu-copy-to-stmt:dest-is-deref:
22501 # if dest-type->right is null, dest-type = dest-type->left
22502 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
22504 75/jump-if-!= break/disp8
22505 $check-mu-copy-to-stmt:dest-is-deref2:
22506 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
22508 89/<- %ebx 0/r32/eax
22510 # if dest is a byte and src is not a literal, abort
22512 $check-mu-copy-to-stmt:final-check-byte:
22513 (simple-mu-type? %ebx 8) # byte => eax
22514 3d/compare-eax-and 0/imm32/false
22515 74/jump-if-= break/disp8
22516 (simple-mu-type? %ecx 0) # literal => eax
22517 3d/compare-eax-and 0/imm32/false
22518 0f 84/jump-if-= $check-mu-copy-to-stmt:error-non-literal-to-byte/disp32
22520 # if (src-type == dest-type) return
22521 (type-match? %ebx %ecx %edx) # => eax
22522 3d/compare-eax-and 0/imm32
22523 0f 85/jump-if-!= $check-mu-copy-to-stmt:end/disp32
22524 # if dest is an addr and src is 0, return
22526 $check-mu-copy-to-stmt:final-check-addr:
22527 (mu-addr-type? %ebx) # => eax
22528 3d/compare-eax-and 0/imm32/false
22529 74/jump-if-= break/disp8
22530 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22531 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22532 (string-equal? %eax "0") # => eax
22533 3d/compare-eax-and 0/imm32/false
22534 74/jump-if-= break/disp8
22535 e9/jump $check-mu-copy-to-stmt:end/disp32
22537 # if dest is an offset and src is 0, return
22539 $check-mu-copy-to-stmt:final-check-offset:
22540 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom
22541 75/jump-if-!= break/disp8
22542 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
22543 (simple-mu-type? %eax 7) # offset => eax
22544 3d/compare-eax-and 0/imm32/false
22545 74/jump-if-= break/disp8
22546 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22547 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22548 (string-equal? %eax "0") # => eax
22549 3d/compare-eax-and 0/imm32/false
22550 74/jump-if-= break/disp8
22551 e9/jump $check-mu-copy-to-stmt:end/disp32
22553 # if dest is not number-like, abort
22554 (check-mu-numberlike-arg %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
22555 $check-mu-copy-to-stmt:end:
22557 81 0/subop/add %esp 0x6c/imm32
22558 # . restore registers
22566 89/<- %esp 5/r32/ebp
22570 $check-mu-copy-to-stmt:error-incorrect-inouts:
22571 (write-buffered *(ebp+0x10) "fn ")
22572 8b/-> *(ebp+0xc) 0/r32/eax
22573 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22574 (write-buffered *(ebp+0x10) %eax)
22575 (write-buffered *(ebp+0x10) ": stmt 'copy-to' must have two inouts\n")
22576 (flush *(ebp+0x10))
22577 (stop *(ebp+0x14) 1)
22580 $check-mu-copy-to-stmt:error-too-many-outputs:
22581 (write-buffered *(ebp+0x10) "fn ")
22582 8b/-> *(ebp+0xc) 0/r32/eax
22583 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22584 (write-buffered *(ebp+0x10) %eax)
22585 (write-buffered *(ebp+0x10) ": stmt 'copy-to' must not have any outputs\n")
22586 (flush *(ebp+0x10))
22587 (stop *(ebp+0x14) 1)
22590 $check-mu-copy-to-stmt:error-src-not-literal-or-in-register:
22591 (write-buffered *(ebp+0x10) "fn ")
22592 8b/-> *(ebp+0xc) 0/r32/eax
22593 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22594 (write-buffered *(ebp+0x10) %eax)
22595 (write-buffered *(ebp+0x10) ": stmt copy-to: source (second inout) is in memory\n")
22596 (flush *(ebp+0x10))
22597 (stop *(ebp+0x14) 1)
22600 $check-mu-copy-to-stmt:error-src-too-large:
22601 (write-buffered *(ebp+0x10) "fn ")
22602 8b/-> *(ebp+0xc) 0/r32/eax
22603 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22604 (write-buffered *(ebp+0x10) %eax)
22605 (write-buffered *(ebp+0x10) ": stmt copy-to: '")
22606 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22607 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22608 (write-buffered *(ebp+0x10) %eax)
22609 (write-buffered *(ebp+0x10) "' is too large to copy\n")
22610 (flush *(ebp+0x10))
22611 (stop *(ebp+0x14) 1)
22614 $check-mu-copy-to-stmt:error-non-literal-to-byte:
22615 (write-buffered *(ebp+0x10) "fn ")
22616 8b/-> *(ebp+0xc) 0/r32/eax
22617 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22618 (write-buffered *(ebp+0x10) %eax)
22619 (write-buffered *(ebp+0x10) ": stmt copy-to: cannot copy non-literal to type byte; use copy-byte-to\n")
22620 (flush *(ebp+0x10))
22621 (stop *(ebp+0x14) 1)
22624 check-mu-copy-byte-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
22627 89/<- %ebp 4/r32/esp
22634 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8)
22635 81 5/subop/subtract %esp 0x60/imm32
22636 68/push 0x60/imm32/size
22637 68/push 0/imm32/read
22638 68/push 0/imm32/write
22639 89/<- %edx 4/r32/esp
22640 $check-mu-copy-byte-stmt:get-output:
22642 8b/-> *(ebp+8) 6/r32/esi
22643 # var output/edi: (addr stmt-var) = stmt->outputs
22644 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
22645 89/<- %edi 0/r32/eax
22647 3d/compare-eax-and 0/imm32
22648 0f 84/jump-if-= $check-mu-copy-byte-stmt:error-no-output/disp32
22650 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
22651 3d/compare-eax-and 0/imm32
22652 0f 85/jump-if-!= $check-mu-copy-byte-stmt:error-too-many-outputs/disp32
22653 $check-mu-copy-byte-stmt:get-inout:
22654 # var inout/esi: (addr stmt-var) = stmt->inouts
22655 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
22656 89/<- %esi 0/r32/eax
22658 3d/compare-eax-and 0/imm32
22659 0f 84/jump-if-= $check-mu-copy-byte-stmt:error-no-inout/disp32
22661 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
22662 3d/compare-eax-and 0/imm32
22663 0f 85/jump-if-!= $check-mu-copy-byte-stmt:error-too-many-inouts/disp32
22664 $check-mu-copy-byte-stmt:types:
22665 # if inout is not a scalar, abort
22666 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22667 (size-of %eax) # => eax
22668 3d/compare-eax-and 4/imm32
22669 0f 8f/jump-if-> $check-mu-copy-byte-stmt:error-inout-too-large/disp32
22670 # var inout-type/ecx: (addr type-tree) = inout->value->type
22671 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22672 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22673 89/<- %ecx 0/r32/eax
22674 $check-mu-copy-byte-stmt:check-inout-deref:
22675 # if (inout->is-deref?) inout-type = inout-type->payload
22676 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref
22677 3d/compare-eax-and 0/imm32/false
22679 74/jump-if-= break/disp8
22680 $check-mu-copy-byte-stmt:inout-is-deref:
22681 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
22682 # if inout-type->right is null, t = inout-type->left
22683 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
22685 75/jump-if-!= break/disp8
22686 $check-mu-copy-byte-stmt:inout-is-deref2:
22687 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
22689 89/<- %ecx 0/r32/eax
22691 # if output not in register, abort
22692 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22693 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
22694 3d/compare-eax-and 0/imm32
22695 0f 84/jump-if-= $check-mu-copy-byte-stmt:error-output-not-in-register/disp32
22696 # var output-type/eax: (addr type-tree) = output->value->type
22697 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22698 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22699 # if output is not of type byte, abort
22700 (simple-mu-type? %eax 8) # byte => eax
22701 3d/compare-eax-and 0/imm32
22702 0f 84/jump-if-= $check-mu-copy-byte-stmt:error-invalid-output-type/disp32
22703 $check-mu-copy-byte-stmt:end:
22705 81 0/subop/add %esp 0x6c/imm32
22706 # . restore registers
22713 89/<- %esp 5/r32/ebp
22717 $check-mu-copy-byte-stmt:error-no-inout:
22718 (write-buffered *(ebp+0x10) "fn ")
22719 8b/-> *(ebp+0xc) 0/r32/eax
22720 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22721 (write-buffered *(ebp+0x10) %eax)
22722 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' expects an inout\n")
22723 (flush *(ebp+0x10))
22724 (stop *(ebp+0x14) 1)
22727 $check-mu-copy-byte-stmt:error-too-many-inouts:
22728 (write-buffered *(ebp+0x10) "fn ")
22729 8b/-> *(ebp+0xc) 0/r32/eax
22730 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22731 (write-buffered *(ebp+0x10) %eax)
22732 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' must have just one inout\n")
22733 (flush *(ebp+0x10))
22734 (stop *(ebp+0x14) 1)
22737 $check-mu-copy-byte-stmt:error-no-output:
22738 (write-buffered *(ebp+0x10) "fn ")
22739 8b/-> *(ebp+0xc) 0/r32/eax
22740 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22741 (write-buffered *(ebp+0x10) %eax)
22742 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' expects an output\n")
22743 (flush *(ebp+0x10))
22744 (stop *(ebp+0x14) 1)
22747 $check-mu-copy-byte-stmt:error-output-not-in-register:
22748 (write-buffered *(ebp+0x10) "fn ")
22749 8b/-> *(ebp+0xc) 0/r32/eax
22750 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22751 (write-buffered *(ebp+0x10) %eax)
22752 (write-buffered *(ebp+0x10) ": stmt copy-byte: output '")
22753 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22754 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22755 (write-buffered *(ebp+0x10) %eax)
22756 (write-buffered *(ebp+0x10) "' not in a register\n")
22757 (flush *(ebp+0x10))
22758 (stop *(ebp+0x14) 1)
22761 $check-mu-copy-byte-stmt:error-too-many-outputs:
22762 (write-buffered *(ebp+0x10) "fn ")
22763 8b/-> *(ebp+0xc) 0/r32/eax
22764 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22765 (write-buffered *(ebp+0x10) %eax)
22766 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' must have just one output\n")
22767 (flush *(ebp+0x10))
22768 (stop *(ebp+0x14) 1)
22771 $check-mu-copy-byte-stmt:error-invalid-output-type:
22772 (write-buffered *(ebp+0x10) "fn ")
22773 8b/-> *(ebp+0xc) 0/r32/eax
22774 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22775 (write-buffered *(ebp+0x10) %eax)
22776 (write-buffered *(ebp+0x10) ": stmt 'copy-byte' must write to output of type byte\n")
22777 (flush *(ebp+0x10))
22778 (stop *(ebp+0x14) 1)
22781 $check-mu-copy-byte-stmt:error-inout-too-large:
22782 (write-buffered *(ebp+0x10) "fn ")
22783 8b/-> *(ebp+0xc) 0/r32/eax
22784 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22785 (write-buffered *(ebp+0x10) %eax)
22786 (write-buffered *(ebp+0x10) ": stmt copy-byte: '")
22787 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22788 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22789 (write-buffered *(ebp+0x10) %eax)
22790 (write-buffered *(ebp+0x10) "' is too large to fit in a register\n")
22791 (flush *(ebp+0x10))
22792 (stop *(ebp+0x14) 1)
22795 check-mu-copy-byte-to-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
22798 89/<- %ebp 4/r32/esp
22805 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8)
22806 81 5/subop/subtract %esp 0x60/imm32
22807 68/push 0x60/imm32/size
22808 68/push 0/imm32/read
22809 68/push 0/imm32/write
22810 89/<- %edx 4/r32/esp
22812 8b/-> *(ebp+8) 6/r32/esi
22813 $check-mu-copy-byte-to-stmt:check-for-output:
22814 # if stmt->outputs abort
22815 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
22816 3d/compare-eax-and 0/imm32
22817 0f 85/jump-if-!= $check-mu-copy-byte-to-stmt:error-too-many-outputs/disp32
22818 $check-mu-copy-byte-to-stmt:get-dest:
22819 # var dest/edi: (addr stmt-var) = stmt->inouts
22820 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
22821 89/<- %edi 0/r32/eax
22823 3d/compare-eax-and 0/imm32
22824 0f 84/jump-if-= $check-mu-copy-byte-to-stmt:error-incorrect-inouts/disp32
22825 $check-mu-copy-byte-to-stmt:get-src:
22826 # var src/esi: (addr stmt-var) = dest->next
22827 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
22828 89/<- %esi 0/r32/eax
22830 3d/compare-eax-and 0/imm32
22831 0f 84/jump-if-= $check-mu-copy-byte-to-stmt:error-incorrect-inouts/disp32
22833 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
22834 3d/compare-eax-and 0/imm32
22835 0f 85/jump-if-!= $check-mu-copy-byte-to-stmt:error-incorrect-inouts/disp32
22836 $check-mu-copy-byte-to-stmt:types:
22837 # if src is not a scalar, abort
22838 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22839 (size-of %eax) # => eax
22840 3d/compare-eax-and 4/imm32
22841 0f 8f/jump-if-> $check-mu-copy-byte-to-stmt:error-src-too-large/disp32
22842 # if src not in register, abort
22844 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22845 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
22846 3d/compare-eax-and 0/imm32
22847 75/jump-if-!= break/disp8
22848 e9/jump $check-mu-copy-byte-to-stmt:error-src-not-in-register/disp32
22850 # var dest-type/ebx: (addr type-tree) = dest->value->type
22851 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22852 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
22853 89/<- %ebx 0/r32/eax
22854 # if (dest->is-deref?) dest-type = dest-type->payload
22855 $check-mu-copy-byte-to-stmt:check-dest-deref:
22856 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref
22857 3d/compare-eax-and 0/imm32/false
22859 74/jump-if-= break/disp8
22860 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
22861 $check-mu-copy-byte-to-stmt:dest-is-deref:
22862 # if dest-type->right is null, dest-type = dest-type->left
22863 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
22865 75/jump-if-!= break/disp8
22866 $check-mu-copy-byte-to-stmt:dest-is-deref2:
22867 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
22869 89/<- %ebx 0/r32/eax
22871 # if dest is not a byte, abort
22872 (simple-mu-type? %ebx 8) # byte => eax
22873 3d/compare-eax-and 0/imm32/false
22874 0f 84/jump-if-= $check-mu-copy-byte-to-stmt:error-invalid-dest-type/disp32
22875 $check-mu-copy-byte-to-stmt:end:
22877 81 0/subop/add %esp 0x6c/imm32
22878 # . restore registers
22885 89/<- %esp 5/r32/ebp
22889 $check-mu-copy-byte-to-stmt:error-incorrect-inouts:
22890 (write-buffered *(ebp+0x10) "fn ")
22891 8b/-> *(ebp+0xc) 0/r32/eax
22892 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22893 (write-buffered *(ebp+0x10) %eax)
22894 (write-buffered *(ebp+0x10) ": stmt 'copy-byte-to' must have two inouts\n")
22895 (flush *(ebp+0x10))
22896 (stop *(ebp+0x14) 1)
22899 $check-mu-copy-byte-to-stmt:error-too-many-outputs:
22900 (write-buffered *(ebp+0x10) "fn ")
22901 8b/-> *(ebp+0xc) 0/r32/eax
22902 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22903 (write-buffered *(ebp+0x10) %eax)
22904 (write-buffered *(ebp+0x10) ": stmt 'copy-byte-to' must not have any outputs\n")
22905 (flush *(ebp+0x10))
22906 (stop *(ebp+0x14) 1)
22909 $check-mu-copy-byte-to-stmt:error-src-not-in-register:
22910 (write-buffered *(ebp+0x10) "fn ")
22911 8b/-> *(ebp+0xc) 0/r32/eax
22912 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22913 (write-buffered *(ebp+0x10) %eax)
22914 (write-buffered *(ebp+0x10) ": stmt copy-byte-to: source (second inout) must be in a register\n")
22915 (flush *(ebp+0x10))
22916 (stop *(ebp+0x14) 1)
22919 $check-mu-copy-byte-to-stmt:error-invalid-dest-type:
22920 (write-buffered *(ebp+0x10) "fn ")
22921 8b/-> *(ebp+0xc) 0/r32/eax
22922 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22923 (write-buffered *(ebp+0x10) %eax)
22924 (write-buffered *(ebp+0x10) ": stmt copy-byte-to: '")
22925 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
22926 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22927 (write-buffered *(ebp+0x10) %eax)
22928 (write-buffered *(ebp+0x10) "' must be a byte\n")
22929 (flush *(ebp+0x10))
22930 (stop *(ebp+0x14) 1)
22933 $check-mu-copy-byte-to-stmt:error-src-too-large:
22934 (write-buffered *(ebp+0x10) "fn ")
22935 8b/-> *(ebp+0xc) 0/r32/eax
22936 (lookup *eax *(eax+4)) # Function-name Function-name => eax
22937 (write-buffered *(ebp+0x10) %eax)
22938 (write-buffered *(ebp+0x10) ": stmt copy-byte-to: '")
22939 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22940 (lookup *eax *(eax+4)) # Var-name Var-name => eax
22941 (write-buffered *(ebp+0x10) %eax)
22942 (write-buffered *(ebp+0x10) "' is too large to copy\n")
22943 (flush *(ebp+0x10))
22944 (stop *(ebp+0x14) 1)
22947 check-mu-compare-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
22950 89/<- %ebp 4/r32/esp
22958 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8)
22959 81 5/subop/subtract %esp 0x60/imm32
22960 68/push 0x60/imm32/size
22961 68/push 0/imm32/read
22962 68/push 0/imm32/write
22963 89/<- %edx 4/r32/esp
22965 8b/-> *(ebp+8) 6/r32/esi
22966 $check-mu-compare-stmt:check-for-output:
22967 # if stmt->outputs abort
22968 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
22969 3d/compare-eax-and 0/imm32
22970 0f 85/jump-if-!= $check-mu-compare-stmt:error-too-many-outputs/disp32
22971 $check-mu-compare-stmt:get-left:
22972 # var left/edi: (addr stmt-var) = stmt->inouts
22973 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
22974 89/<- %edi 0/r32/eax
22976 3d/compare-eax-and 0/imm32
22977 0f 84/jump-if-= $check-mu-compare-stmt:error-incorrect-inouts/disp32
22978 $check-mu-compare-stmt:get-right:
22979 # var right/esi: (addr stmt-var) = left->next
22980 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
22981 89/<- %esi 0/r32/eax
22983 3d/compare-eax-and 0/imm32
22984 0f 84/jump-if-= $check-mu-compare-stmt:error-incorrect-inouts/disp32
22986 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
22987 3d/compare-eax-and 0/imm32
22988 0f 85/jump-if-!= $check-mu-compare-stmt:error-incorrect-inouts/disp32
22989 # if both inouts are in memory, abort
22991 $check-mu-compare-stmt:both-in-mem:
22992 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22993 (lookup *(eax+0x8) *(eax+0xc)) # Var-type Var-type => eax
22994 (simple-mu-type? %eax 0) # => eax
22995 3d/compare-eax-and 0/imm32
22996 0f 85/jump-if-!= break/disp32
22997 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
22998 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
22999 3d/compare-eax-and 0/imm32
23000 75/jump-if-!= break/disp8
23001 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23002 (lookup *(eax+0x8) *(eax+0xc)) # Var-type Var-type => eax
23003 (simple-mu-type? %eax 0) # => eax
23004 3d/compare-eax-and 0/imm32
23005 75/jump-if-!= break/disp8
23006 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23007 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
23008 3d/compare-eax-and 0/imm32
23009 75/jump-if-!= break/disp8
23010 e9/jump $check-mu-compare-stmt:error-both-in-memory/disp32
23012 $check-mu-compare-stmt:types:
23013 # var right-type/ecx: (addr type-tree) = right->value->type
23014 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
23015 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
23016 89/<- %ecx 0/r32/eax
23017 # if (right->is-deref?) right-type = right-type->payload
23018 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref
23019 3d/compare-eax-and 0/imm32/false
23021 74/jump-if-= break/disp8
23022 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
23023 # if right-type->right is null, right-type = right-type->left
23024 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
23026 75/jump-if-!= break/disp8
23027 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
23029 89/<- %ecx 0/r32/eax
23031 # if right-type is a literal string, abort
23032 (simple-mu-type? %ecx 0x10) # string-literal => eax
23033 3d/compare-eax-and 0/imm32/false
23034 0f 85/jump-if-!= $check-mu-compare-stmt:error-right-string-literal/disp32
23035 # if right is not a scalar, abort
23036 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
23037 (size-of %eax) # => eax
23038 3d/compare-eax-and 4/imm32
23039 0f 8f/jump-if-> $check-mu-compare-stmt:error-right-too-large/disp32
23040 # if left is not a scalar, abort
23041 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23042 (size-of %eax) # => eax
23043 3d/compare-eax-and 4/imm32
23044 0f 8f/jump-if-> $check-mu-compare-stmt:error-left-too-large/disp32
23045 # var left-type/ebx: (addr type-tree) = left->value->type
23046 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23047 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
23048 89/<- %ebx 0/r32/eax
23049 # if (left->is-deref?) left-type = left-type->payload
23050 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref
23051 3d/compare-eax-and 0/imm32/false
23053 74/jump-if-= break/disp8
23054 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
23055 # if left-type->right is null, left-type = left-type->left
23056 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
23058 75/jump-if-!= break/disp8
23059 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
23061 89/<- %ebx 0/r32/eax
23063 # if (left-type == right-type) return
23064 (type-match? %ebx %ecx %edx) # => eax
23065 3d/compare-eax-and 0/imm32
23066 0f 85/jump-if-!= $check-mu-compare-stmt:end/disp32
23067 # if left is an addr and right is 0, return
23069 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23070 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
23071 (mu-addr-type? %eax) # => eax
23072 3d/compare-eax-and 0/imm32/false
23073 74/jump-if-= break/disp8
23074 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
23075 (lookup *eax *(eax+4)) # Var-name Var-name => eax
23076 (string-equal? %eax "0") # => eax
23077 3d/compare-eax-and 0/imm32/false
23078 74/jump-if-= break/disp8
23079 eb/jump $check-mu-compare-stmt:end/disp8
23081 # if left is not number-like, abort
23082 (check-mu-numberlike-arg %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
23083 $check-mu-compare-stmt:end:
23085 81 0/subop/add %esp 0x6c/imm32
23086 # . restore registers
23094 89/<- %esp 5/r32/ebp
23098 $check-mu-compare-stmt:error-incorrect-inouts:
23099 (write-buffered *(ebp+0x10) "fn ")
23100 8b/-> *(ebp+0xc) 0/r32/eax
23101 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23102 (write-buffered *(ebp+0x10) %eax)
23103 (write-buffered *(ebp+0x10) ": stmt 'compare' must have two inouts\n")
23104 (flush *(ebp+0x10))
23105 (stop *(ebp+0x14) 1)
23108 $check-mu-compare-stmt:error-too-many-outputs:
23109 (write-buffered *(ebp+0x10) "fn ")
23110 8b/-> *(ebp+0xc) 0/r32/eax
23111 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23112 (write-buffered *(ebp+0x10) %eax)
23113 (write-buffered *(ebp+0x10) ": stmt 'compare' must not have any outputs\n")
23114 (flush *(ebp+0x10))
23115 (stop *(ebp+0x14) 1)
23118 $check-mu-compare-stmt:error-both-in-memory:
23119 (write-buffered *(ebp+0x10) "fn ")
23120 8b/-> *(ebp+0xc) 0/r32/eax
23121 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23122 (write-buffered *(ebp+0x10) %eax)
23123 (write-buffered *(ebp+0x10) ": stmt compare: both inouts are in memory\n")
23124 (flush *(ebp+0x10))
23125 (stop *(ebp+0x14) 1)
23128 $check-mu-compare-stmt:error-left-too-large:
23129 (write-buffered *(ebp+0x10) "fn ")
23130 8b/-> *(ebp+0xc) 0/r32/eax
23131 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23132 (write-buffered *(ebp+0x10) %eax)
23133 (write-buffered *(ebp+0x10) ": stmt compare: '")
23134 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23135 (lookup *eax *(eax+4)) # Var-name Var-name => eax
23136 (write-buffered *(ebp+0x10) %eax)
23137 (write-buffered *(ebp+0x10) "' is too large to compare\n")
23138 (flush *(ebp+0x10))
23139 (stop *(ebp+0x14) 1)
23142 $check-mu-compare-stmt:error-right-too-large:
23143 (write-buffered *(ebp+0x10) "fn ")
23144 8b/-> *(ebp+0xc) 0/r32/eax
23145 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23146 (write-buffered *(ebp+0x10) %eax)
23147 (write-buffered *(ebp+0x10) ": stmt compare: '")
23148 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
23149 (lookup *eax *(eax+4)) # Var-name Var-name => eax
23150 (write-buffered *(ebp+0x10) %eax)
23151 (write-buffered *(ebp+0x10) "' is too large to compare\n")
23152 (flush *(ebp+0x10))
23153 (stop *(ebp+0x14) 1)
23156 $check-mu-compare-stmt:error-right-string-literal:
23157 (write-buffered *(ebp+0x10) "fn ")
23158 8b/-> *(ebp+0xc) 0/r32/eax
23159 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23160 (write-buffered *(ebp+0x10) %eax)
23161 (write-buffered *(ebp+0x10) ": stmt compare: string literal ")
23162 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
23163 (lookup *eax *(eax+4)) # Var-name Var-name => eax
23164 (write-buffered *(ebp+0x10) %eax)
23165 (write-buffered *(ebp+0x10) " is not supported; use the string-equal? function\n")
23166 (flush *(ebp+0x10))
23167 (stop *(ebp+0x14) 1)
23170 check-mu-address-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
23173 89/<- %ebp 4/r32/esp
23180 $check-mu-address-stmt:get-output:
23182 8b/-> *(ebp+8) 6/r32/esi
23183 # var output/edi: (addr stmt-var) = stmt->outputs
23184 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
23185 89/<- %edi 0/r32/eax
23187 3d/compare-eax-and 0/imm32
23188 0f 84/jump-if-= $check-mu-address-stmt:error-no-output/disp32
23190 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
23191 3d/compare-eax-and 0/imm32
23192 0f 85/jump-if-!= $check-mu-address-stmt:error-too-many-outputs/disp32
23193 $check-mu-address-stmt:get-inout:
23194 # var inout/esi: (addr stmt-var) = stmt->inouts
23195 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
23196 89/<- %esi 0/r32/eax
23198 3d/compare-eax-and 0/imm32
23199 0f 84/jump-if-= $check-mu-address-stmt:error-no-inout/disp32
23201 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
23202 3d/compare-eax-and 0/imm32
23203 0f 85/jump-if-!= $check-mu-address-stmt:error-too-many-inouts/disp32
23204 $check-mu-address-stmt:types:
23205 # if output not in register, abort
23206 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23207 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
23208 3d/compare-eax-and 0/imm32
23209 0f 84/jump-if-= $check-mu-address-stmt:error-output-not-in-register/disp32
23210 # var output-type/edx: (addr type-tree) = output->value->type
23211 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23212 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
23213 89/<- %edx 0/r32/eax
23214 # if output-type not an addr, abort
23215 (mu-addr-type? %edx) # => eax
23216 3d/compare-eax-and 0/imm32/false
23217 0f 84/jump-if-= $check-mu-address-stmt:error-output-not-address/disp32
23218 # output-type = output-type->right
23219 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax
23220 # if output-type->right is null, output-type = output-type->left
23221 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
23223 75/jump-if-!= break/disp8
23224 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
23226 89/<- %edx 0/r32/eax
23227 # var inout-type/ecx: (addr type-tree) = inout->value->type
23228 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
23229 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
23230 89/<- %ecx 0/r32/eax
23231 # if (inout->is-deref?) inout-type = inout-type->payload
23232 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref
23233 3d/compare-eax-and 0/imm32/false
23235 74/jump-if-= break/disp8
23236 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
23237 # if inout-type->right is null, t = inout-type->left
23238 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
23240 75/jump-if-!= break/disp8
23241 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
23243 89/<- %ecx 0/r32/eax
23245 # if (inout-type != output-type) abort
23246 (type-equal-ignoring-capacity? %edx %ecx) # => eax
23247 3d/compare-eax-and 0/imm32
23248 0f 84/jump-if-= $check-mu-address-stmt:error-type-mismatch/disp32
23249 $check-mu-address-stmt:end:
23250 # . restore registers
23257 89/<- %esp 5/r32/ebp
23261 $check-mu-address-stmt:error-no-inout:
23262 (write-buffered *(ebp+0x10) "fn ")
23263 8b/-> *(ebp+0xc) 0/r32/eax
23264 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23265 (write-buffered *(ebp+0x10) %eax)
23266 (write-buffered *(ebp+0x10) ": stmt 'address' expects an inout\n")
23267 (flush *(ebp+0x10))
23268 (stop *(ebp+0x14) 1)
23271 $check-mu-address-stmt:error-too-many-inouts:
23272 (write-buffered *(ebp+0x10) "fn ")
23273 8b/-> *(ebp+0xc) 0/r32/eax
23274 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23275 (write-buffered *(ebp+0x10) %eax)
23276 (write-buffered *(ebp+0x10) ": stmt 'address' must have just one inout\n")
23277 (flush *(ebp+0x10))
23278 (stop *(ebp+0x14) 1)
23281 $check-mu-address-stmt:error-no-output:
23282 (write-buffered *(ebp+0x10) "fn ")
23283 8b/-> *(ebp+0xc) 0/r32/eax
23284 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23285 (write-buffered *(ebp+0x10) %eax)
23286 (write-buffered *(ebp+0x10) ": stmt 'address' expects an output\n")
23287 (flush *(ebp+0x10))
23288 (stop *(ebp+0x14) 1)
23291 $check-mu-address-stmt:error-output-not-in-register:
23292 (write-buffered *(ebp+0x10) "fn ")
23293 8b/-> *(ebp+0xc) 0/r32/eax
23294 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23295 (write-buffered *(ebp+0x10) %eax)
23296 (write-buffered *(ebp+0x10) ": stmt address: output '")
23297 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23298 (lookup *eax *(eax+4)) # Var-name Var-name => eax
23299 (write-buffered *(ebp+0x10) %eax)
23300 (write-buffered *(ebp+0x10) "' not in a register\n")
23301 (flush *(ebp+0x10))
23302 (stop *(ebp+0x14) 1)
23305 $check-mu-address-stmt:error-too-many-outputs:
23306 (write-buffered *(ebp+0x10) "fn ")
23307 8b/-> *(ebp+0xc) 0/r32/eax
23308 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23309 (write-buffered *(ebp+0x10) %eax)
23310 (write-buffered *(ebp+0x10) ": stmt 'address' must have just one output\n")
23311 (flush *(ebp+0x10))
23312 (stop *(ebp+0x14) 1)
23315 $check-mu-address-stmt:error-output-not-address:
23316 (write-buffered *(ebp+0x10) "fn ")
23317 8b/-> *(ebp+0xc) 0/r32/eax
23318 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23319 (write-buffered *(ebp+0x10) %eax)
23320 (write-buffered *(ebp+0x10) ": stmt address: output '")
23321 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23322 (lookup *eax *(eax+4)) # Var-name Var-name => eax
23323 (write-buffered *(ebp+0x10) %eax)
23324 (write-buffered *(ebp+0x10) "' is not an addr\n")
23325 (flush *(ebp+0x10))
23326 (stop *(ebp+0x14) 1)
23329 $check-mu-address-stmt:error-type-mismatch:
23330 (write-buffered *(ebp+0x10) "fn ")
23331 8b/-> *(ebp+0xc) 0/r32/eax
23332 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23333 (write-buffered *(ebp+0x10) %eax)
23334 (write-buffered *(ebp+0x10) ": stmt address: output '")
23335 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23336 (lookup *eax *(eax+4)) # Var-name Var-name => eax
23337 (write-buffered *(ebp+0x10) %eax)
23338 (write-buffered *(ebp+0x10) "' cannot hold address of '")
23339 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
23340 (lookup *eax *(eax+4)) # Var-name Var-name => eax
23341 (write-buffered *(ebp+0x10) %eax)
23342 (write-buffered *(ebp+0x10) "'\n")
23343 (flush *(ebp+0x10))
23344 (stop *(ebp+0x14) 1)
23347 type-equal-ignoring-capacity?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean
23350 89/<- %ebp 4/r32/esp
23355 # var curr-a/ecx: (addr type-tree) = a
23356 8b/-> *(ebp+8) 1/r32/ecx
23357 # var curr-b/ebx: (addr type-tree) = b
23358 8b/-> *(ebp+0xc) 3/r32/ebx
23359 # if (curr-a->is-atom?) fall back to regular equality
23360 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom
23361 0f 85/jump-if-!= $type-equal-ignoring-capacity?:base-case/disp32
23362 # if (curr-a->left != curr-b->left) return false
23363 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
23364 89/<- %edx 0/r32/eax
23365 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
23366 (type-equal? %edx %eax) # => eax
23367 3d/compare-eax-and 0/imm32/false
23368 0f 84/jump-if-= $type-equal-ignoring-capacity?:end/disp32 # eax switches meaning
23369 # if (curr-a->left == "array") curr-a = curr-a->element-type
23371 (mu-array? %edx) # => eax
23372 3d/compare-eax-and 0/imm32/false
23373 75/jump-if-!= break/disp8
23374 $type-equal-ignoring-capacity?:array:
23375 # curr-a = curr-a->right->left
23376 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
23377 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
23378 89/<- %ecx 0/r32/eax
23379 # curr-b = curr-b->right->left
23380 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
23381 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
23382 89/<- %ebx 0/r32/eax
23383 eb/jump $type-equal-ignoring-capacity?:base-case/disp8
23385 # if (curr-a->left == "stream") curr-a = curr-a->element-type
23387 (mu-stream? %edx) # => eax
23388 3d/compare-eax-and 0/imm32/false
23389 75/jump-if-!= break/disp8
23390 $type-equal-ignoring-capacity?:stream:
23391 # curr-a = curr-a->right->left
23392 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
23393 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
23394 89/<- %ecx 0/r32/eax
23395 # curr-b = curr-b->right->left
23396 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
23397 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
23398 89/<- %ebx 0/r32/eax
23399 eb/jump $type-equal-ignoring-capacity?:base-case/disp8
23401 $type-equal-ignoring-capacity?:base-case:
23402 # return type-equal?(curr-a, curr-b)
23403 (type-equal? %ecx %ebx) # => eax
23404 $type-equal-ignoring-capacity?:end:
23405 # . restore registers
23410 89/<- %esp 5/r32/ebp
23414 check-mu-return-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
23417 89/<- %ebp 4/r32/esp
23425 # var type-parameters/edx: (addr table (handle array byte) (addr type-tree) 8)
23426 81 5/subop/subtract %esp 0x60/imm32
23427 68/push 0x60/imm32/size
23428 68/push 0/imm32/read
23429 68/push 0/imm32/write
23430 89/<- %edx 4/r32/esp
23431 # var template/esi: (addr list var) = fn->outputs
23432 8b/-> *(ebp+0xc) 0/r32/eax
23433 (lookup *(eax+0x10) *(eax+0x14)) # Function-outputs Function-outputs => eax
23434 89/<- %esi 0/r32/eax
23435 # var curr-template/ebx: (addr list var) = fn->outputs
23436 89/<- %ebx 0/r32/eax
23437 # var curr/edi: (addr stmt-var) = stmt->inouts
23438 8b/-> *(ebp+8) 0/r32/eax
23439 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax
23440 89/<- %edi 0/r32/eax
23442 # if template is null, break
23443 81 7/subop/compare %ebx 0/imm32
23444 0f 84/jump-if-= break/disp32
23445 # if curr is null, abort
23446 81 7/subop/compare %edi 0/imm32
23447 0f 84/jump-if-= $check-mu-return-stmt:error-too-few-inouts/disp32
23448 # var template-type/ecx: (addr type-tree) = template->value->type
23449 (lookup *ebx *(ebx+4)) # List-value List-value => eax
23450 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
23451 89/<- %ecx 0/r32/eax
23452 # var curr-type/eax: (addr type-tree) = curr->value->type
23453 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23454 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
23455 # if (curr->is-deref?) curr-type = payload of curr-type
23456 81 7/subop/compare *(edi+0x10) 0/imm32/false # Stmt-var-is-deref
23458 74/jump-if-= break/disp8
23459 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
23460 # if t->right is null, t = t->left
23461 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
23462 75/jump-if-!= break/disp8
23463 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
23465 # if curr-type is literal and template-type is float, abort
23468 (simple-mu-type? %eax 0) # literal => eax
23469 3d/compare-eax-and 0/imm32/false
23470 74/jump-if-= break/disp8
23471 (simple-mu-type? %ecx 0xf) # float => eax
23472 3d/compare-eax-and 0/imm32/false
23473 0f 85/jump-if-!= $check-mu-return-stmt:error-literal-to-float/disp32
23476 # if (curr-type != template-type) abort
23477 (type-match? %ecx %eax %edx) # => eax
23478 3d/compare-eax-and 0/imm32/false
23479 0f 84/jump-if-= $check-mu-return-stmt:error1/disp32
23480 # if register-within-list-with-conflict?(curr, original template, curr-template, stmt) abort
23481 (register-within-list-with-conflict? %edi %esi %ebx *(ebp+8)) # => eax
23482 3d/compare-eax-and 0/imm32/false
23483 0f 85/jump-if-!= $check-mu-return-stmt:error2/disp32
23484 # template = template->next
23485 (lookup *(ebx+8) *(ebx+0xc)) # List-next List-next => eax
23486 89/<- %ebx 0/r32/eax
23487 # curr = curr->next
23488 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
23489 89/<- %edi 0/r32/eax
23491 e9/jump loop/disp32
23493 # if curr is not null, abort
23494 81 7/subop/compare %edi 0/imm32
23495 0f 85/jump-if-!= $check-mu-return-stmt:error-too-many-inouts/disp32
23496 $check-mu-return-stmt:end:
23498 81 0/subop/add %esp 0x6c/imm32
23499 # . restore registers
23507 89/<- %esp 5/r32/ebp
23511 $check-mu-return-stmt:error1:
23512 (write-buffered *(ebp+0x10) "fn ")
23513 8b/-> *(ebp+0xc) 0/r32/eax
23514 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23515 (write-buffered *(ebp+0x10) %eax)
23516 (write-buffered *(ebp+0x10) ": return: '")
23517 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23518 (lookup *eax *(eax+4)) # Var-name Var-name => eax
23519 (write-buffered *(ebp+0x10) %eax)
23520 (write-buffered *(ebp+0x10) "' has the wrong type\n")
23521 (flush *(ebp+0x10))
23522 (stop *(ebp+0x14) 1)
23525 $check-mu-return-stmt:error2:
23526 (write-buffered *(ebp+0x10) "fn ")
23527 8b/-> *(ebp+0xc) 0/r32/eax
23528 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23529 (write-buffered *(ebp+0x10) %eax)
23530 (write-buffered *(ebp+0x10) ": return: '")
23531 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23532 (lookup *eax *(eax+4)) # Var-name Var-name => eax
23533 (write-buffered *(ebp+0x10) %eax)
23534 (write-buffered *(ebp+0x10) "' is no longer available\n")
23535 (flush *(ebp+0x10))
23536 (stop *(ebp+0x14) 1)
23539 $check-mu-return-stmt:error-literal-to-float:
23540 (write-buffered *(ebp+0x10) "fn ")
23541 8b/-> *(ebp+0xc) 0/r32/eax
23542 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23543 (write-buffered *(ebp+0x10) %eax)
23544 (write-buffered *(ebp+0x10) ": return: cannot copy literal '")
23545 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
23546 (lookup *eax *(eax+4)) # Var-name Var-name => eax
23547 (write-buffered *(ebp+0x10) %eax)
23548 (write-buffered *(ebp+0x10) "' to float\n")
23549 (flush *(ebp+0x10))
23550 (stop *(ebp+0x14) 1)
23553 $check-mu-return-stmt:error-too-few-inouts:
23554 (write-buffered *(ebp+0x10) "fn ")
23555 8b/-> *(ebp+0xc) 0/r32/eax
23556 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23557 (write-buffered *(ebp+0x10) %eax)
23558 (write-buffered *(ebp+0x10) ": return: too few inouts\n")
23559 (flush *(ebp+0x10))
23560 (stop *(ebp+0x14) 1)
23563 $check-mu-return-stmt:error-too-many-inouts:
23564 (write-buffered *(ebp+0x10) "fn ")
23565 8b/-> *(ebp+0xc) 0/r32/eax
23566 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23567 (write-buffered *(ebp+0x10) %eax)
23568 (write-buffered *(ebp+0x10) ": return: too many inouts\n")
23569 (flush *(ebp+0x10))
23570 (stop *(ebp+0x14) 1)
23573 check-all-unique-registers: # outputs: (addr list var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
23576 89/<- %ebp 4/r32/esp
23581 # var table/esi: (addr table (handle array byte) int 8)
23582 81 5/subop/subtract %esp 0x60/imm32
23583 68/push 0x60/imm32/size
23584 68/push 0/imm32/read
23585 68/push 0/imm32/write
23586 89/<- %esi 4/r32/esp
23587 # var curr/ecx: (addr list var) = outputs
23588 8b/-> *(ebp+8) 1/r32/ecx
23590 # if (curr == 0) break
23591 81 7/subop/compare %ecx 0/imm32
23592 0f 84/jump-if-= break/disp32
23593 # var reg/eax: (addr array byte) = curr->value->register # guaranteed to exist
23594 (lookup *ecx *(ecx+4)) # List-value List-value => eax
23595 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
23596 # if reg exists in table, abort
23597 (maybe-get %esi %eax 0xc) # => eax
23598 3d/compare-eax-and 0/imm32
23599 0f 85/jump-if-!= $check-all-unique-registers:abort/disp32
23600 # insert reg in table
23601 (lookup *ecx *(ecx+4)) # List-value List-value => eax
23602 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
23603 (get-or-insert %esi %eax 0xc Heap)
23604 # curr = curr->next
23605 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax
23606 89/<- %ecx 0/r32/eax
23607 e9/jump loop/disp32
23609 $check-all-unique-registers:end:
23611 81 0/subop/add %esp 0x6c/imm32
23612 # . restore registers
23617 89/<- %esp 5/r32/ebp
23621 $check-all-unique-registers:abort:
23622 (write-buffered *(ebp+0x10) "fn ")
23623 8b/-> *(ebp+0xc) 0/r32/eax
23624 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23625 (write-buffered *(ebp+0x10) %eax)
23626 (write-buffered *(ebp+0x10) ": outputs must be in unique registers\n")
23627 (flush *(ebp+0x10))
23628 (stop *(ebp+0x14) 1)
23631 # return false if s's register is not between start (inclusive) and end (exclusive)
23632 # return false if the positionally corresponding register in stmt->inouts (where s comes from) is also s's register
23633 # otherwise return true
23634 register-within-list-with-conflict?: # s: (addr stmt-var), start: (addr list var), end: (addr list var), stmt: (addr stmt) -> result/eax: boolean
23637 89/<- %ebp 4/r32/esp
23644 # var target/ebx: (addr array byte) = s->value->register
23645 8b/-> *(ebp+8) 0/r32/eax
23646 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
23647 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
23648 #? (write-buffered Stderr "AA: ")
23649 #? (write-buffered Stderr %eax)
23650 #? (write-buffered Stderr Newline)
23652 # if (var->register == 0) return false
23653 3d/compare-eax-and 0/imm32
23654 0f 84/jump-if-= $register-within-list-with-conflict?:end/disp32 # eax turns into result
23655 89/<- %ebx 0/r32/eax
23656 # var curr/ecx: (addr list var) = start
23657 8b/-> *(ebp+0xc) 1/r32/ecx
23659 8b/-> *(ebp+0x10) 2/r32/edx
23661 # if (curr == 0) break
23662 81 7/subop/compare %edi 0/imm32
23663 0f 84/jump-if-= break/disp32
23664 # if (curr == end) break
23665 39/compare %ecx 2/r32/edx
23666 0f 84/jump-if-= break/disp32
23667 # var curr-reg/eax: (addr array byte) = curr->value->register
23668 (lookup *ecx *(ecx+4)) # List-value List-value => eax
23669 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
23670 # if (curr-reg == 0) continue
23671 3d/compare-eax-and 0/imm32
23672 74/jump-if-= $register-within-list-with-conflict?:continue/disp8
23673 # if (curr-reg == target) check for conflict
23674 (string-equal? %eax %ebx) # => eax
23675 3d/compare-eax-and 0/imm32/false
23677 74/jump-if-= break/disp8
23678 #? (write-buffered Stderr "conflict?\n")
23680 # var return-inouts/eax: (addr stmt-var) = stmt->inouts
23681 8b/-> *(ebp+0x14) 0/r32/eax
23682 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax
23683 (register-conflict? %ebx %eax *(ebp+0xc)) # => eax
23684 eb/jump $register-within-list-with-conflict?:end/disp8
23686 $register-within-list-with-conflict?:continue:
23687 # curr = curr->next
23688 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax
23689 89/<- %ecx 0/r32/eax
23690 e9/jump loop/disp32
23693 b8/copy-to-eax 0/imm32/false
23694 $register-within-list-with-conflict?:end:
23695 # . restore registers
23702 89/<- %esp 5/r32/ebp
23706 # At the first occurrence of register 'reg' in fn-outputs,
23707 # check if the corresponding element of return-inouts has a different register.
23708 # This hacky helper is intended to be called in one specific place. Don't
23710 register-conflict?: # reg: (addr array byte), return-inouts: (addr stmt-var), fn-outputs: (addr list var) => result/eax: boolean
23713 89/<- %ebp 4/r32/esp
23720 #? (write-buffered Stderr "BB: ")
23721 #? (write-buffered Stderr *(ebp+8))
23722 #? (write-buffered Stderr Newline)
23724 # var curr-output/edi: (addr list var) = fn-outputs
23725 8b/-> *(ebp+0x10) 7/r32/edi
23726 # var curr-inout/esi: (addr stmt-var) = return-inouts
23727 8b/-> *(ebp+0xc) 6/r32/esi
23729 # if (curr-output == 0) abort
23730 81 7/subop/compare %edi 0/imm32
23731 0f 84/jump-if-= break/disp32
23732 # if (curr-output->value->register != reg) continue
23733 (lookup *edi *(edi+4)) # List-value List-value => eax
23734 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
23735 (string-equal? %eax *(ebp+8)) # => eax
23736 3d/compare-eax-and 0/imm32/false
23737 0f 84/jump-if= $register-conflict?:continue/disp32
23738 #? (write-buffered Stderr "rescan\n")
23740 # var curr-reg/eax: (addr array byte) = curr-inout->value->register
23741 (lookup *esi *(esi+4)) # List-value List-value => eax
23742 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
23743 # if (curr-reg == 0) return true
23744 3d/compare-eax-and 0/imm32
23746 75/jump-if-!= break/disp8
23747 #? (write-buffered Stderr "no register\n")
23749 b8/copy-to-eax 1/imm32/true
23750 e9/jump $register-conflict?:end/disp32
23752 # return (curr-reg != reg)
23753 (string-equal? %eax *(ebp+8)) # => eax
23754 3d/compare-eax-and 0/imm32/false
23756 #? (write-buffered Stderr "final: ")
23757 #? (write-int32-hex-buffered Stderr %eax)
23758 #? (write-buffered Stderr Newline)
23760 eb/jump $register-conflict?:end/disp8
23761 $register-conflict?:continue:
23762 # curr-output = curr-output->next
23763 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax
23764 89/<- %edi 0/r32/eax
23765 # curr-inout = curr-inout->next
23766 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
23767 89/<- %esi 0/r32/eax
23768 e9/jump loop/disp32
23770 # should never get here
23771 (write-buffered Stderr "register-conflict? misused\n")
23773 e8/call syscall_exit/disp32
23774 $register-conflict?:end:
23775 # . restore registers
23782 89/<- %esp 5/r32/ebp
23786 check-final-stmt-is-return: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
23789 89/<- %ebp 4/r32/esp
23793 # var curr/ecx: (addr list stmt) = block->stmts
23794 8b/-> *(ebp+8) 0/r32/eax
23795 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax
23796 3d/compare-eax-and 0/imm32
23797 74/jump-if-= $check-final-stmt-is-return:error/disp8
23798 89/<- %ecx 0/r32/eax
23800 # if curr->next == 0, break
23801 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax
23802 3d/compare-eax-and 0/imm32
23803 74/jump-if-= break/disp8
23804 # curr = curr->next
23805 89/<- %ecx 0/r32/eax
23806 e9/jump loop/disp32
23808 $check-final-stmt-is-return:check-tag:
23809 # if curr->value->tag != Stmt1, abort
23810 (lookup *ecx *(ecx+4)) # List-value List-value => eax
23811 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag
23812 75/jump-if-!= $check-final-stmt-is-return:error/disp8
23813 $check-final-stmt-is-return:check-operation:
23814 # if curr->operation != "return", abort
23815 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax
23816 (string-equal? %eax "return")
23817 3d/compare-eax-and 0/imm32/false
23818 74/jump-if-= $check-final-stmt-is-return:error/disp8
23819 $check-final-stmt-is-return:end:
23820 # . restore registers
23824 89/<- %esp 5/r32/ebp
23828 $check-final-stmt-is-return:error:
23829 (write-buffered *(ebp+0x10) "fn ")
23830 8b/-> *(ebp+0xc) 0/r32/eax
23831 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23832 (write-buffered *(ebp+0x10) %eax)
23833 (write-buffered *(ebp+0x10) ": final statement should be a 'return'\n")
23834 (flush *(ebp+0x10))
23835 (stop *(ebp+0x14) 1)
23838 check-no-breaks: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
23841 89/<- %ebp 4/r32/esp
23845 # var curr/ecx: (addr list stmt) = block->stmts
23846 8b/-> *(ebp+8) 0/r32/eax
23847 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax
23848 3d/compare-eax-and 0/imm32
23849 0f 84/jump-if-= $check-no-breaks:end/disp32
23850 89/<- %ecx 0/r32/eax
23852 # if curr->next == 0, break
23853 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax
23854 3d/compare-eax-and 0/imm32
23855 74/jump-if-= break/disp8
23856 # if curr->value->tag != Stmt1, continue
23857 (lookup *ecx *(ecx+4)) # List-value List-value => eax
23858 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag
23859 75/jump-if-!= $check-no-breaks:continue/disp8
23860 # if curr->value->operation starts with "break", abort
23861 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax
23862 (string-starts-with? %eax "break") # => eax
23863 3d/compare-eax-and 0/imm32/false
23864 75/jump-if-!= $check-no-breaks:error/disp8
23865 $check-no-breaks:continue:
23866 # curr = curr->next
23867 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax
23868 89/<- %ecx 0/r32/eax
23869 e9/jump loop/disp32
23871 $check-no-breaks:end:
23872 # . restore registers
23876 89/<- %esp 5/r32/ebp
23880 $check-no-breaks:error:
23881 (write-buffered *(ebp+0x10) "fn ")
23882 8b/-> *(ebp+0xc) 0/r32/eax
23883 (lookup *eax *(eax+4)) # Function-name Function-name => eax
23884 (write-buffered *(ebp+0x10) %eax)
23885 (write-buffered *(ebp+0x10) " has outputs, so you cannot 'break' out of the outermost block. Use 'return'.\n")
23886 (flush *(ebp+0x10))
23887 (stop *(ebp+0x14) 1)
23890 check-mu-get-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
23893 89/<- %ebp 4/r32/esp
23902 8b/-> *(ebp+8) 6/r32/esi
23903 # - check for 0 inouts
23904 # var base/ecx: (addr var) = stmt->inouts->value
23905 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
23906 3d/compare-eax-and 0/imm32/false
23907 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32
23908 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
23909 89/<- %ecx 0/r32/eax
23910 $check-mu-get-stmt:check-base:
23911 # - check base type
23912 # if it's an 'addr', check that it's in a register
23913 # var base-type/ebx: (addr type-tree) = lookup(base->type)
23914 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
23915 89/<- %ebx 0/r32/eax
23917 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom
23918 0f 85/jump-if-!= break/disp32
23919 $check-mu-get-stmt:base-is-compound:
23920 # if (type->left != addr) break
23921 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
23922 (simple-mu-type? %eax 2) # addr => eax
23923 3d/compare-eax-and 0/imm32/false
23924 74/jump-if-= break/disp8
23925 $check-mu-get-stmt:base-is-addr:
23926 # now check for register
23927 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register
23928 0f 84/jump-if-= $check-mu-get-stmt:error-base-type-addr-but-not-register/disp32
23929 $check-mu-get-stmt:base-is-addr-in-register:
23930 # type->left is now an addr; skip it
23931 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
23932 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
23933 0f 85/jump-if-!= $check-mu-get-stmt:error-bad-base/disp32
23934 $check-mu-get-stmt:base-is-addr-to-atom-in-register:
23935 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
23936 89/<- %ebx 0/r32/eax
23938 $check-mu-get-stmt:check-base-typeinfo:
23939 # ensure type is a container
23940 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom
23942 75/jump-if-!= break/disp8
23943 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
23944 89/<- %ebx 0/r32/eax
23946 # var base-type-id/ebx: type-id = base-type->value
23947 8b/-> *(ebx+4) 3/r32/ebx # Type-tree-value
23948 (container? %ebx) # => eax
23949 3d/compare-eax-and 0/imm32/false
23950 0f 84/jump-if-= $check-mu-get-stmt:error-bad-base/disp32
23951 # var base-typeinfo/edx: (addr typeinfo) = find-typeinfo(base-type-id)
23952 # . var container/ecx: (handle typeinfo)
23955 89/<- %ecx 4/r32/esp
23957 (find-typeinfo %ebx %ecx)
23958 (lookup *ecx *(ecx+4)) # => eax
23959 # . reclaim container
23960 81 0/subop/add %esp 8/imm32
23962 89/<- %edx 0/r32/eax
23963 # var offset/ecx: (addr stmt-var) = stmt->inouts->next
23964 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
23965 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
23966 89/<- %ecx 0/r32/eax
23967 # - check for 1 inout
23968 3d/compare-eax-and 0/imm32/false
23969 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32
23970 # var offset/ecx: (addr var) = lookup(offset->value)
23971 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
23972 89/<- %ecx 0/r32/eax
23973 # - check for valid field
23974 81 7/subop/compare *(ecx+0x14) -1/imm32/uninitialized # Var-offset
23975 0f 84/jump-if-= $check-mu-get-stmt:error-bad-field/disp32
23976 # - check for too many inouts
23977 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
23978 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
23979 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
23980 3d/compare-eax-and 0/imm32/false
23981 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-inouts/disp32
23982 # var output/edi: (addr var) = stmt->outputs->value
23983 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
23984 # - check for 0 outputs
23985 3d/compare-eax-and 0/imm32/false
23986 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-outputs/disp32
23987 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
23988 89/<- %edi 0/r32/eax
23989 $check-mu-get-stmt:check-output-type:
23990 # - check output type
23991 # must be in register
23992 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax
23993 3d/compare-eax-and 0/imm32
23994 0f 84/jump-if-= $check-mu-get-stmt:error-output-not-in-register/disp32
23995 # must have a non-atomic type
23996 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax
23997 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
23998 0f 85/jump-if-!= $check-mu-get-stmt:error-output-type-not-address/disp32
23999 # type must start with (addr ...)
24000 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
24001 (simple-mu-type? %eax 2) # => eax
24002 3d/compare-eax-and 0/imm32/false
24003 0f 84/jump-if-= $check-mu-get-stmt:error-output-type-not-address/disp32
24004 $check-mu-get-stmt:check-output-type-match:
24005 # payload of addr type must match 'type' definition
24006 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax
24007 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
24008 # if (payload->right == null) payload = payload->left
24009 81 7/subop/compare *(eax+0xc) 0/imm32/null # Type-tree-right
24011 75/jump-if-!= break/disp8
24012 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
24014 89/<- %edi 0/r32/eax
24015 # . var output-name/ecx: (addr array byte)
24016 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24017 89/<- %ecx 0/r32/eax
24018 # . var base-typeinfo-entry/eax: (addr handle typeinfo-entry)
24019 (lookup *(edx+4) *(edx+8)) # Typeinfo-fields Typeinfo-fields => eax
24020 (get %eax %ecx 0x10) # => eax
24022 (lookup *eax *(eax+4)) # => eax
24023 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax
24024 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
24026 (type-equal? %edi %eax) # => eax
24027 3d/compare-eax-and 0/imm32/false
24028 0f 84/jump-if-= $check-mu-get-stmt:error-bad-output-type/disp32
24029 # - check for too many outputs
24030 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
24031 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
24032 3d/compare-eax-and 0/imm32/false
24033 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-outputs/disp32
24034 $check-mu-get-stmt:end:
24035 # . restore registers
24043 89/<- %esp 5/r32/ebp
24047 $check-mu-get-stmt:error-too-few-inouts:
24048 (write-buffered *(ebp+0x10) "fn ")
24049 8b/-> *(ebp+0xc) 0/r32/eax
24050 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24051 (write-buffered *(ebp+0x10) %eax)
24052 (write-buffered *(ebp+0x10) ": stmt get: too few inouts (2 required)\n")
24053 (flush *(ebp+0x10))
24054 (stop *(ebp+0x14) 1)
24057 $check-mu-get-stmt:error-too-many-inouts:
24058 (write-buffered *(ebp+0x10) "fn ")
24059 8b/-> *(ebp+0xc) 0/r32/eax
24060 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24061 (write-buffered *(ebp+0x10) %eax)
24062 (write-buffered *(ebp+0x10) ": stmt get: too many inouts (2 required)\n")
24063 (flush *(ebp+0x10))
24064 (stop *(ebp+0x14) 1)
24067 $check-mu-get-stmt:error-too-few-outputs:
24068 (write-buffered *(ebp+0x10) "fn ")
24069 8b/-> *(ebp+0xc) 0/r32/eax
24070 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24071 (write-buffered *(ebp+0x10) %eax)
24072 (write-buffered *(ebp+0x10) ": stmt get: must have an output\n")
24073 (flush *(ebp+0x10))
24074 (stop *(ebp+0x14) 1)
24077 $check-mu-get-stmt:error-too-many-outputs:
24078 (write-buffered *(ebp+0x10) "fn ")
24079 8b/-> *(ebp+0xc) 0/r32/eax
24080 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24081 (write-buffered *(ebp+0x10) %eax)
24082 (write-buffered *(ebp+0x10) ": stmt get: too many outputs (1 required)\n")
24083 (flush *(ebp+0x10))
24084 (stop *(ebp+0x14) 1)
24087 $check-mu-get-stmt:error-bad-base:
24088 # error("fn " fn ": stmt get: var '" base->name "' must have a 'type' definition\n")
24089 (write-buffered *(ebp+0x10) "fn ")
24090 8b/-> *(ebp+0xc) 0/r32/eax
24091 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24092 (write-buffered *(ebp+0x10) %eax)
24093 (write-buffered *(ebp+0x10) ": stmt get: var '")
24094 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24095 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24096 (lookup *eax *(eax+4)) # Var-name Var-name => eax
24097 (write-buffered *(ebp+0x10) %eax)
24098 (write-buffered *(ebp+0x10) "' must have a 'type' definition\n")
24099 (flush *(ebp+0x10))
24100 (stop *(ebp+0x14) 1)
24103 $check-mu-get-stmt:error-base-type-addr-but-not-register:
24104 (write-buffered *(ebp+0x10) "fn ")
24105 8b/-> *(ebp+0xc) 0/r32/eax
24106 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24107 (write-buffered *(ebp+0x10) %eax)
24108 (write-buffered *(ebp+0x10) ": stmt get: var '")
24109 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24110 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24111 (lookup *eax *(eax+4)) # Var-name Var-name => eax
24112 (write-buffered *(ebp+0x10) %eax)
24113 (write-buffered *(ebp+0x10) "' is an 'addr' type, and so must live in a register\n")
24114 (flush *(ebp+0x10))
24115 (stop *(ebp+0x14) 1)
24118 $check-mu-get-stmt:error-bad-field:
24119 # error("fn " fn ": stmt get: type " type " has no member called '" curr->name "'\n")
24120 (write-buffered *(ebp+0x10) "fn ")
24121 8b/-> *(ebp+0xc) 0/r32/eax
24122 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24123 (write-buffered *(ebp+0x10) %eax)
24124 (write-buffered *(ebp+0x10) ": stmt get: type '")
24125 # . write(Type-id->data[tmp])
24126 bf/copy-to-edi Type-id/imm32
24127 8b/-> *(edi+ebx<<2+0xc) 6/r32/esi
24129 81 7/subop/compare %esi 0/imm32
24130 74/jump-if-= break/disp8
24131 (write-buffered *(ebp+0x10) %esi)
24134 (write-buffered *(ebp+0x10) "' has no member called '")
24135 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24136 (write-buffered *(ebp+0x10) %eax)
24137 (write-buffered *(ebp+0x10) "'\n")
24138 (flush *(ebp+0x10))
24139 (stop *(ebp+0x14) 1)
24142 $check-mu-get-stmt:error-output-not-in-register:
24143 (write-buffered *(ebp+0x10) "fn ")
24144 8b/-> *(ebp+0xc) 0/r32/eax
24145 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24146 (write-buffered *(ebp+0x10) %eax)
24147 (write-buffered *(ebp+0x10) ": stmt get: output '")
24148 (lookup *edi *(edi+4)) # Var-name Var-name => eax
24149 (write-buffered *(ebp+0x10) %eax)
24150 (write-buffered *(ebp+0x10) "' is not in a register\n")
24151 (flush *(ebp+0x10))
24152 (stop *(ebp+0x14) 1)
24155 $check-mu-get-stmt:error-output-type-not-address:
24156 (write-buffered *(ebp+0x10) "fn ")
24157 8b/-> *(ebp+0xc) 0/r32/eax
24158 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24159 (write-buffered *(ebp+0x10) %eax)
24160 (write-buffered *(ebp+0x10) ": stmt get: output must be an addr\n")
24161 (flush *(ebp+0x10))
24162 (stop *(ebp+0x14) 1)
24165 $check-mu-get-stmt:error-bad-output-type:
24166 (write-buffered *(ebp+0x10) "fn ")
24167 8b/-> *(ebp+0xc) 0/r32/eax
24168 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24169 (write-buffered *(ebp+0x10) %eax)
24170 (write-buffered *(ebp+0x10) ": stmt get: wrong output type for member '")
24171 (write-buffered *(ebp+0x10) %ecx)
24172 (write-buffered *(ebp+0x10) "' of type '")
24173 bf/copy-to-edi Type-id/imm32
24174 8b/-> *(edi+ebx<<2+0xc) 6/r32/esi
24176 81 7/subop/compare %esi 0/imm32
24177 74/jump-if-= break/disp8
24178 (write-buffered *(ebp+0x10) %esi)
24180 (write-buffered *(ebp+0x10) "'\n")
24181 (flush *(ebp+0x10))
24182 (stop *(ebp+0x14) 1)
24185 check-mu-index-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
24188 89/<- %ebp 4/r32/esp
24197 8b/-> *(ebp+8) 6/r32/esi
24198 # - check for 0 inouts
24199 # var base/ecx: (addr var) = stmt->inouts->value
24200 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24201 $check-mu-index-stmt:check-no-inouts:
24202 3d/compare-eax-and 0/imm32
24203 0f 84/jump-if-= $check-mu-index-stmt:error-too-few-inouts/disp32
24204 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24205 89/<- %ecx 0/r32/eax
24206 # - check base type is either (addr array ...) in register or (array ...) on stack
24207 # var base-type/ebx: (addr type-tree) = lookup(base->type)
24208 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
24209 89/<- %ebx 0/r32/eax
24210 # if base-type is an atom, abort with a precise error
24211 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom
24213 74/jump-if-= break/disp8
24214 (simple-mu-type? %ebx 3) # array => eax
24215 3d/compare-eax-and 0/imm32/false
24216 0f 85/jump-if-!= $check-mu-index-stmt:error-base-array-atom-type/disp32
24217 0f 84/jump-if-= $check-mu-index-stmt:error-base-non-array-type/disp32
24219 $check-mu-index-stmt:base-is-compound:
24220 # if type->left not addr or array, abort
24222 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24223 (simple-mu-type? %eax 2) # addr => eax
24224 3d/compare-eax-and 0/imm32/false
24225 75/jump-if-!= break/disp8
24226 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24227 (simple-mu-type? %eax 3) # array => eax
24228 3d/compare-eax-and 0/imm32/false
24229 75/jump-if-!= break/disp8
24230 e9/jump $check-mu-index-stmt:error-base-non-array-type/disp32
24232 # if (type->left == addr) ensure type->right->left == array and type->register exists
24234 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24235 (simple-mu-type? %eax 2) # addr => eax
24236 3d/compare-eax-and 0/imm32/false
24237 74/jump-if-= break/disp8
24238 $check-mu-index-stmt:base-is-addr:
24239 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
24240 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
24241 (simple-mu-type? %eax 3) # array => eax
24242 3d/compare-eax-and 0/imm32/false
24243 0f 84/jump-if-= $check-mu-index-stmt:error-base-non-array-type/disp32
24244 $check-mu-index-stmt:check-base-addr-is-register:
24245 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register
24246 0f 84/jump-if-= $check-mu-index-stmt:error-base-address-array-type-on-stack/disp32
24248 # if (type->left == array) ensure type->register doesn't exist
24250 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24251 (simple-mu-type? %eax 3) # array => eax
24252 3d/compare-eax-and 0/imm32/false
24253 74/jump-if-= break/disp8
24254 $check-mu-index-stmt:base-is-array:
24255 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register
24256 0f 85/jump-if-!= $check-mu-index-stmt:error-base-array-type-in-register/disp32
24258 # if (base-type->left == addr) base-type = base-type->right
24260 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24261 (simple-mu-type? %eax 2) # addr => eax
24262 3d/compare-eax-and 0/imm32/false
24263 74/jump-if-= break/disp8
24264 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
24265 89/<- %ebx 0/r32/eax
24267 # - check for 1 inout
24268 # var index/ecx: (addr stmt-var) = stmt->inouts->next->value
24269 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24270 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
24271 $check-mu-index-stmt:check-single-inout:
24272 3d/compare-eax-and 0/imm32
24273 0f 84/jump-if-= $check-mu-index-stmt:error-too-few-inouts/disp32
24274 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24275 89/<- %ecx 0/r32/eax
24276 # - check index is either a literal or register
24277 # var index-type/edx: (addr type-tree)
24278 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
24279 89/<- %edx 0/r32/eax
24280 # if index type is an atom, it must be a literal or int
24281 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom
24283 74/jump-if-= break/disp8
24284 $check-mu-index-stmt:index-type-is-atom:
24285 (simple-mu-type? %edx 0) # literal => eax
24286 3d/compare-eax-and 0/imm32/false
24287 75/jump-if-!= $check-mu-index-stmt:index-type-done/disp8
24288 (simple-mu-type? %edx 1) # int => eax
24289 3d/compare-eax-and 0/imm32/false
24290 75/jump-if-!= $check-mu-index-stmt:index-type-done/disp8
24291 (simple-mu-type? %edx 7) # offset => eax
24292 3d/compare-eax-and 0/imm32/false
24293 0f 85/jump-if-!= $check-mu-index-stmt:error-index-offset-atom-type/disp32
24294 e9/jump $check-mu-index-stmt:error-invalid-index-type/disp32
24296 # if index type is a non-atom: it must be an offset
24298 75/jump-if-!= break/disp8
24299 $check-mu-index-stmt:index-type-is-non-atom:
24300 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax
24301 (simple-mu-type? %eax 7) # offset => eax
24302 3d/compare-eax-and 0/imm32/false
24303 0f 84/jump-if-= $check-mu-index-stmt:error-invalid-index-type/disp32
24305 $check-mu-index-stmt:index-type-done:
24306 # check index is either a literal or in a register
24308 (simple-mu-type? %edx 0) # literal => eax
24309 3d/compare-eax-and 0/imm32/false
24310 75/jump-if-!= break/disp8
24311 $check-mu-index-stmt:check-index-in-register:
24312 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register
24313 0f 84/jump-if-= $check-mu-index-stmt:error-index-on-stack/disp32
24315 # - if index is an 'int', check that element type of base has size 1, 2, 4 or 8 bytes.
24317 (simple-mu-type? %edx 1) # int => eax
24318 3d/compare-eax-and 0/imm32/false
24319 74/jump-if-= break/disp8
24320 $check-mu-index-stmt:check-index-can-be-int:
24321 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24322 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24323 (array-element-size %eax) # => eax
24324 3d/compare-eax-and 1/imm32
24325 74/jump-if-= break/disp8
24326 3d/compare-eax-and 2/imm32
24327 74/jump-if-= break/disp8
24328 3d/compare-eax-and 4/imm32
24329 74/jump-if-= break/disp8
24330 3d/compare-eax-and 8/imm32
24331 74/jump-if-= break/disp8
24332 e9/jump $check-mu-index-stmt:error-index-needs-offset/disp32
24334 # - check for too many inouts
24335 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24336 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
24337 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
24338 3d/compare-eax-and 0/imm32/false
24339 0f 85/jump-if-!= $check-mu-index-stmt:error-too-many-inouts/disp32
24340 # - check for 0 outputs
24341 # var output/edi: (addr var) = stmt->outputs->value
24342 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
24343 3d/compare-eax-and 0/imm32/false
24344 0f 84/jump-if-= $check-mu-index-stmt:error-too-few-outputs/disp32
24345 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24346 89/<- %edi 0/r32/eax
24347 # - check output type
24348 # must have a non-atomic type
24349 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax
24350 89/<- %edx 0/r32/eax
24351 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom
24352 0f 85/jump-if-!= $check-mu-index-stmt:error-output-type-not-address/disp32
24353 # type must start with (addr ...)
24354 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax
24355 (simple-mu-type? %eax 2) # addr => eax
24356 3d/compare-eax-and 0/imm32/false
24357 0f 84/jump-if-= $check-mu-index-stmt:error-output-type-not-address/disp32
24358 # if tail(base-type) != tail(output-type) abort
24359 (type-tail %ebx) # => eax
24360 89/<- %ebx 0/r32/eax
24361 (type-tail %edx) # => eax
24362 (type-equal? %ebx %eax) # => eax
24363 3d/compare-eax-and 0/imm32/false
24364 0f 84/jump-if-= $check-mu-index-stmt:error-bad-output-type/disp32
24365 # - check for too many outputs
24366 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
24367 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
24368 3d/compare-eax-and 0/imm32/false
24369 0f 85/jump-if-!= $check-mu-index-stmt:error-too-many-outputs/disp32
24370 $check-mu-index-stmt:end:
24371 # . restore registers
24379 89/<- %esp 5/r32/ebp
24383 $check-mu-index-stmt:error-base-non-array-type:
24384 (write-buffered *(ebp+0x10) "fn ")
24385 8b/-> *(ebp+0xc) 0/r32/eax
24386 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24387 (write-buffered *(ebp+0x10) %eax)
24388 (write-buffered *(ebp+0x10) ": stmt index: var '")
24389 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24390 (write-buffered *(ebp+0x10) %eax)
24391 (write-buffered *(ebp+0x10) "' is not an array\n")
24392 (flush *(ebp+0x10))
24393 (stop *(ebp+0x14) 1)
24396 $check-mu-index-stmt:error-base-array-atom-type:
24397 (write-buffered *(ebp+0x10) "fn ")
24398 8b/-> *(ebp+0xc) 0/r32/eax
24399 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24400 (write-buffered *(ebp+0x10) %eax)
24401 (write-buffered *(ebp+0x10) ": stmt index: array '")
24402 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24403 (write-buffered *(ebp+0x10) %eax)
24404 (write-buffered *(ebp+0x10) "' must specify the type of its elements\n")
24405 (flush *(ebp+0x10))
24406 (stop *(ebp+0x14) 1)
24409 $check-mu-index-stmt:error-base-address-array-type-on-stack:
24410 (write-buffered *(ebp+0x10) "fn ")
24411 8b/-> *(ebp+0xc) 0/r32/eax
24412 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24413 (write-buffered *(ebp+0x10) %eax)
24414 (write-buffered *(ebp+0x10) ": stmt index: var '")
24415 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24416 (write-buffered *(ebp+0x10) %eax)
24417 (write-buffered *(ebp+0x10) "' is an addr to an array, and so must live in a register\n")
24418 (flush *(ebp+0x10))
24419 (stop *(ebp+0x14) 1)
24422 $check-mu-index-stmt:error-base-array-type-in-register:
24423 (write-buffered *(ebp+0x10) "fn ")
24424 8b/-> *(ebp+0xc) 0/r32/eax
24425 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24426 (write-buffered *(ebp+0x10) %eax)
24427 (write-buffered *(ebp+0x10) ": stmt index: var '")
24428 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24429 (write-buffered *(ebp+0x10) %eax)
24430 (write-buffered *(ebp+0x10) "' is an array, and so must live on the stack\n")
24431 (flush *(ebp+0x10))
24432 (stop *(ebp+0x14) 1)
24435 $check-mu-index-stmt:error-too-few-inouts:
24436 (write-buffered *(ebp+0x10) "fn ")
24437 8b/-> *(ebp+0xc) 0/r32/eax
24438 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24439 (write-buffered *(ebp+0x10) %eax)
24440 (write-buffered *(ebp+0x10) ": stmt index: too few inouts (2 required)\n")
24441 (flush *(ebp+0x10))
24442 (stop *(ebp+0x14) 1)
24445 $check-mu-index-stmt:error-invalid-index-type:
24446 (write-buffered *(ebp+0x10) "fn ")
24447 8b/-> *(ebp+0xc) 0/r32/eax
24448 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24449 (write-buffered *(ebp+0x10) %eax)
24450 (write-buffered *(ebp+0x10) ": stmt index: second argument '")
24451 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24452 (write-buffered *(ebp+0x10) %eax)
24453 (write-buffered *(ebp+0x10) "' must be an int or offset\n")
24454 (flush *(ebp+0x10))
24455 (stop *(ebp+0x14) 1)
24458 $check-mu-index-stmt:error-index-offset-atom-type:
24459 (write-buffered *(ebp+0x10) "fn ")
24460 8b/-> *(ebp+0xc) 0/r32/eax
24461 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24462 (write-buffered *(ebp+0x10) %eax)
24463 (write-buffered *(ebp+0x10) ": stmt index: offset '")
24464 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24465 (write-buffered *(ebp+0x10) %eax)
24466 (write-buffered *(ebp+0x10) "' must specify the type of array elements\n")
24467 (flush *(ebp+0x10))
24468 (stop *(ebp+0x14) 1)
24471 $check-mu-index-stmt:error-index-on-stack:
24472 (write-buffered *(ebp+0x10) "fn ")
24473 8b/-> *(ebp+0xc) 0/r32/eax
24474 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24475 (write-buffered *(ebp+0x10) %eax)
24476 (write-buffered *(ebp+0x10) ": stmt index: second argument '")
24477 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24478 (write-buffered *(ebp+0x10) %eax)
24479 (write-buffered *(ebp+0x10) "' must be in a register\n")
24480 (flush *(ebp+0x10))
24481 (stop *(ebp+0x14) 1)
24484 $check-mu-index-stmt:error-index-needs-offset:
24485 (write-buffered *(ebp+0x10) "fn ")
24486 8b/-> *(ebp+0xc) 0/r32/eax
24487 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24488 (write-buffered *(ebp+0x10) %eax)
24489 (write-buffered *(ebp+0x10) ": stmt index: cannot take an int for array '")
24490 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24491 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24492 (lookup *eax *(eax+4)) # Var-name Var-name => eax
24493 (write-buffered *(ebp+0x10) %eax)
24494 (write-buffered *(ebp+0x10) "'; create an offset instead. See mu.md for details.\n")
24495 (flush *(ebp+0x10))
24496 (stop *(ebp+0x14) 1)
24499 $check-mu-index-stmt:error-too-many-inouts:
24500 (write-buffered *(ebp+0x10) "fn ")
24501 8b/-> *(ebp+0xc) 0/r32/eax
24502 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24503 (write-buffered *(ebp+0x10) %eax)
24504 (write-buffered *(ebp+0x10) ": stmt index: too many inouts (2 required)\n")
24505 (flush *(ebp+0x10))
24506 (stop *(ebp+0x14) 1)
24509 $check-mu-index-stmt:error-too-few-outputs:
24510 (write-buffered *(ebp+0x10) "fn ")
24511 8b/-> *(ebp+0xc) 0/r32/eax
24512 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24513 (write-buffered *(ebp+0x10) %eax)
24514 (write-buffered *(ebp+0x10) ": stmt index: must have an output\n")
24515 (flush *(ebp+0x10))
24516 (stop *(ebp+0x14) 1)
24519 $check-mu-index-stmt:error-too-many-outputs:
24520 (write-buffered *(ebp+0x10) "fn ")
24521 8b/-> *(ebp+0xc) 0/r32/eax
24522 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24523 (write-buffered *(ebp+0x10) %eax)
24524 (write-buffered *(ebp+0x10) ": stmt index: too many outputs (1 required)\n")
24525 (flush *(ebp+0x10))
24526 (stop *(ebp+0x14) 1)
24529 $check-mu-index-stmt:error-output-not-in-register:
24530 (write-buffered *(ebp+0x10) "fn ")
24531 8b/-> *(ebp+0xc) 0/r32/eax
24532 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24533 (write-buffered *(ebp+0x10) %eax)
24534 (write-buffered *(ebp+0x10) ": stmt index: output '")
24535 (lookup *edi *(edi+4)) # Var-name Var-name => eax
24536 (write-buffered *(ebp+0x10) %eax)
24537 (write-buffered *(ebp+0x10) "' is not in a register\n")
24538 (flush *(ebp+0x10))
24539 (stop *(ebp+0x14) 1)
24542 $check-mu-index-stmt:error-output-type-not-address:
24543 (write-buffered *(ebp+0x10) "fn ")
24544 8b/-> *(ebp+0xc) 0/r32/eax
24545 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24546 (write-buffered *(ebp+0x10) %eax)
24547 (write-buffered *(ebp+0x10) ": stmt index: output '")
24548 (lookup *edi *(edi+4)) # Var-name Var-name => eax
24549 (write-buffered *(ebp+0x10) %eax)
24550 (write-buffered *(ebp+0x10) "' must be an addr\n")
24551 (flush *(ebp+0x10))
24552 (stop *(ebp+0x14) 1)
24555 $check-mu-index-stmt:error-bad-output-type:
24556 (write-buffered *(ebp+0x10) "fn ")
24557 8b/-> *(ebp+0xc) 0/r32/eax
24558 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24559 (write-buffered *(ebp+0x10) %eax)
24560 (write-buffered *(ebp+0x10) ": stmt index: output '")
24561 (lookup *edi *(edi+4)) # Var-name Var-name => eax
24562 (write-buffered *(ebp+0x10) %eax)
24563 (write-buffered *(ebp+0x10) "' does not have the right type\n")
24564 (flush *(ebp+0x10))
24565 (stop *(ebp+0x14) 1)
24568 check-mu-length-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
24571 89/<- %ebp 4/r32/esp
24580 8b/-> *(ebp+8) 6/r32/esi
24581 # - check for 0 inouts
24582 # var base/ecx: (addr var) = stmt->inouts->value
24583 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24584 $check-mu-length-stmt:check-no-inouts:
24585 3d/compare-eax-and 0/imm32
24586 0f 84/jump-if-= $check-mu-length-stmt:error-too-few-inouts/disp32
24587 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24588 89/<- %ecx 0/r32/eax
24589 # - check base type is either (addr array ...) in register or (array ...) on stack
24590 # var base-type/ebx: (addr type-tree) = lookup(base->type)
24591 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
24592 89/<- %ebx 0/r32/eax
24593 # if base-type is an atom, abort with a precise error
24594 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom
24596 74/jump-if-= break/disp8
24597 (simple-mu-type? %ebx 3) # array => eax
24598 3d/compare-eax-and 0/imm32/false
24599 0f 85/jump-if-!= $check-mu-length-stmt:error-base-array-atom-type/disp32
24600 0f 84/jump-if-= $check-mu-length-stmt:error-base-non-array-type/disp32
24602 $check-mu-length-stmt:base-is-compound:
24603 # if type->left not addr or array, abort
24605 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24606 (simple-mu-type? %eax 2) # addr => eax
24607 3d/compare-eax-and 0/imm32/false
24608 75/jump-if-!= break/disp8
24609 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24610 (simple-mu-type? %eax 3) # array => eax
24611 3d/compare-eax-and 0/imm32/false
24612 75/jump-if-!= break/disp8
24613 e9/jump $check-mu-length-stmt:error-base-non-array-type/disp32
24615 # if (type->left == addr) ensure type->right->left == array and type->register exists
24617 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24618 (simple-mu-type? %eax 2) # addr => eax
24619 3d/compare-eax-and 0/imm32/false
24620 74/jump-if-= break/disp8
24621 $check-mu-length-stmt:base-is-addr:
24622 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
24623 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
24624 (simple-mu-type? %eax 3) # array => eax
24625 3d/compare-eax-and 0/imm32/false
24626 0f 84/jump-if-= $check-mu-length-stmt:error-base-non-array-type/disp32
24627 $check-mu-length-stmt:check-base-addr-is-register:
24628 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register
24629 0f 84/jump-if-= $check-mu-length-stmt:error-base-address-array-type-on-stack/disp32
24631 # if (type->left == array) ensure type->register doesn't exist
24633 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24634 (simple-mu-type? %eax 3) # array => eax
24635 3d/compare-eax-and 0/imm32/false
24636 74/jump-if-= break/disp8
24637 $check-mu-length-stmt:base-is-array:
24638 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register
24639 0f 85/jump-if-!= $check-mu-length-stmt:error-base-array-type-in-register/disp32
24641 # if (base-type->left == addr) base-type = base-type->right
24643 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24644 (simple-mu-type? %eax 2) # addr => eax
24645 3d/compare-eax-and 0/imm32/false
24646 74/jump-if-= break/disp8
24647 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
24648 89/<- %ebx 0/r32/eax
24650 # - check for too many inouts
24651 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24652 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
24653 3d/compare-eax-and 0/imm32/false
24654 0f 85/jump-if-!= $check-mu-length-stmt:error-too-many-inouts/disp32
24655 # - check for 0 outputs
24656 # var output/edi: (addr var) = stmt->outputs->value
24657 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
24658 3d/compare-eax-and 0/imm32/false
24659 0f 84/jump-if-= $check-mu-length-stmt:error-too-few-outputs/disp32
24660 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24661 89/<- %edi 0/r32/eax
24662 # - check output type
24663 # must have a non-atomic type
24664 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax
24665 (simple-mu-type? %eax 1) # int => eax
24666 3d/compare-eax-and 0/imm32/false
24667 0f 84/jump-if-= $check-mu-length-stmt:error-invalid-output-type/disp32
24668 # - check for too many outputs
24669 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
24670 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
24671 3d/compare-eax-and 0/imm32/false
24672 0f 85/jump-if-!= $check-mu-length-stmt:error-too-many-outputs/disp32
24673 $check-mu-length-stmt:end:
24674 # . restore registers
24682 89/<- %esp 5/r32/ebp
24686 $check-mu-length-stmt:error-base-non-array-type:
24687 (write-buffered *(ebp+0x10) "fn ")
24688 8b/-> *(ebp+0xc) 0/r32/eax
24689 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24690 (write-buffered *(ebp+0x10) %eax)
24691 (write-buffered *(ebp+0x10) ": stmt length: var '")
24692 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24693 (write-buffered *(ebp+0x10) %eax)
24694 (write-buffered *(ebp+0x10) "' is not an array\n")
24695 (flush *(ebp+0x10))
24696 (stop *(ebp+0x14) 1)
24699 $check-mu-length-stmt:error-base-array-atom-type:
24700 (write-buffered *(ebp+0x10) "fn ")
24701 8b/-> *(ebp+0xc) 0/r32/eax
24702 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24703 (write-buffered *(ebp+0x10) %eax)
24704 (write-buffered *(ebp+0x10) ": stmt length: array '")
24705 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24706 (write-buffered *(ebp+0x10) %eax)
24707 (write-buffered *(ebp+0x10) "' must specify the type of its elements\n")
24708 (flush *(ebp+0x10))
24709 (stop *(ebp+0x14) 1)
24712 $check-mu-length-stmt:error-base-address-array-type-on-stack:
24713 (write-buffered *(ebp+0x10) "fn ")
24714 8b/-> *(ebp+0xc) 0/r32/eax
24715 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24716 (write-buffered *(ebp+0x10) %eax)
24717 (write-buffered *(ebp+0x10) ": stmt length: var '")
24718 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24719 (write-buffered *(ebp+0x10) %eax)
24720 (write-buffered *(ebp+0x10) "' is an addr to an array, and so must live in a register\n")
24721 (flush *(ebp+0x10))
24722 (stop *(ebp+0x14) 1)
24725 $check-mu-length-stmt:error-base-array-type-in-register:
24726 (write-buffered *(ebp+0x10) "fn ")
24727 8b/-> *(ebp+0xc) 0/r32/eax
24728 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24729 (write-buffered *(ebp+0x10) %eax)
24730 (write-buffered *(ebp+0x10) ": stmt length: var '")
24731 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24732 (write-buffered *(ebp+0x10) %eax)
24733 (write-buffered *(ebp+0x10) "' is an array, and so must live on the stack\n")
24734 (flush *(ebp+0x10))
24735 (stop *(ebp+0x14) 1)
24738 $check-mu-length-stmt:error-too-few-inouts:
24739 (write-buffered *(ebp+0x10) "fn ")
24740 8b/-> *(ebp+0xc) 0/r32/eax
24741 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24742 (write-buffered *(ebp+0x10) %eax)
24743 (write-buffered *(ebp+0x10) ": stmt length: too few inouts (1 required)\n")
24744 (flush *(ebp+0x10))
24745 (stop *(ebp+0x14) 1)
24748 $check-mu-length-stmt:error-invalid-index-type:
24749 (write-buffered *(ebp+0x10) "fn ")
24750 8b/-> *(ebp+0xc) 0/r32/eax
24751 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24752 (write-buffered *(ebp+0x10) %eax)
24753 (write-buffered *(ebp+0x10) ": stmt length: second argument '")
24754 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24755 (write-buffered *(ebp+0x10) %eax)
24756 (write-buffered *(ebp+0x10) "' must be an int or offset\n")
24757 (flush *(ebp+0x10))
24758 (stop *(ebp+0x14) 1)
24761 $check-mu-length-stmt:error-index-offset-atom-type:
24762 (write-buffered *(ebp+0x10) "fn ")
24763 8b/-> *(ebp+0xc) 0/r32/eax
24764 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24765 (write-buffered *(ebp+0x10) %eax)
24766 (write-buffered *(ebp+0x10) ": stmt length: offset '")
24767 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24768 (write-buffered *(ebp+0x10) %eax)
24769 (write-buffered *(ebp+0x10) "' must specify the type of array elements\n")
24770 (flush *(ebp+0x10))
24771 (stop *(ebp+0x14) 1)
24774 $check-mu-length-stmt:error-index-on-stack:
24775 (write-buffered *(ebp+0x10) "fn ")
24776 8b/-> *(ebp+0xc) 0/r32/eax
24777 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24778 (write-buffered *(ebp+0x10) %eax)
24779 (write-buffered *(ebp+0x10) ": stmt length: second argument '")
24780 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
24781 (write-buffered *(ebp+0x10) %eax)
24782 (write-buffered *(ebp+0x10) "' must be in a register\n")
24783 (flush *(ebp+0x10))
24784 (stop *(ebp+0x14) 1)
24787 $check-mu-length-stmt:error-index-needs-offset:
24788 (write-buffered *(ebp+0x10) "fn ")
24789 8b/-> *(ebp+0xc) 0/r32/eax
24790 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24791 (write-buffered *(ebp+0x10) %eax)
24792 (write-buffered *(ebp+0x10) ": stmt length: cannot take an int for array '")
24793 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24794 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24795 (lookup *eax *(eax+4)) # Var-name Var-name => eax
24796 (write-buffered *(ebp+0x10) %eax)
24797 (write-buffered *(ebp+0x10) "'; create an offset instead. See mu.md for details.\n")
24798 (flush *(ebp+0x10))
24799 (stop *(ebp+0x14) 1)
24802 $check-mu-length-stmt:error-too-many-inouts:
24803 (write-buffered *(ebp+0x10) "fn ")
24804 8b/-> *(ebp+0xc) 0/r32/eax
24805 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24806 (write-buffered *(ebp+0x10) %eax)
24807 (write-buffered *(ebp+0x10) ": stmt length: too many inouts (1 required)\n")
24808 (flush *(ebp+0x10))
24809 (stop *(ebp+0x14) 1)
24812 $check-mu-length-stmt:error-too-few-outputs:
24813 (write-buffered *(ebp+0x10) "fn ")
24814 8b/-> *(ebp+0xc) 0/r32/eax
24815 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24816 (write-buffered *(ebp+0x10) %eax)
24817 (write-buffered *(ebp+0x10) ": stmt length: must have an output\n")
24818 (flush *(ebp+0x10))
24819 (stop *(ebp+0x14) 1)
24822 $check-mu-length-stmt:error-too-many-outputs:
24823 (write-buffered *(ebp+0x10) "fn ")
24824 8b/-> *(ebp+0xc) 0/r32/eax
24825 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24826 (write-buffered *(ebp+0x10) %eax)
24827 (write-buffered *(ebp+0x10) ": stmt length: too many outputs (1 required)\n")
24828 (flush *(ebp+0x10))
24829 (stop *(ebp+0x14) 1)
24832 $check-mu-length-stmt:error-output-not-in-register:
24833 (write-buffered *(ebp+0x10) "fn ")
24834 8b/-> *(ebp+0xc) 0/r32/eax
24835 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24836 (write-buffered *(ebp+0x10) %eax)
24837 (write-buffered *(ebp+0x10) ": stmt length: output '")
24838 (lookup *edi *(edi+4)) # Var-name Var-name => eax
24839 (write-buffered *(ebp+0x10) %eax)
24840 (write-buffered *(ebp+0x10) "' is not in a register\n")
24841 (flush *(ebp+0x10))
24842 (stop *(ebp+0x14) 1)
24845 $check-mu-length-stmt:error-invalid-output-type:
24846 (write-buffered *(ebp+0x10) "fn ")
24847 8b/-> *(ebp+0xc) 0/r32/eax
24848 (lookup *eax *(eax+4)) # Function-name Function-name => eax
24849 (write-buffered *(ebp+0x10) %eax)
24850 (write-buffered *(ebp+0x10) ": stmt length: output '")
24851 (lookup *edi *(edi+4)) # Var-name Var-name => eax
24852 (write-buffered *(ebp+0x10) %eax)
24853 (write-buffered *(ebp+0x10) "' does not have the right type\n")
24854 (flush *(ebp+0x10))
24855 (stop *(ebp+0x14) 1)
24858 check-mu-compute-offset-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
24861 89/<- %ebp 4/r32/esp
24870 8b/-> *(ebp+8) 6/r32/esi
24871 # - check for 0 inouts
24872 # var base/ecx: (addr var) = stmt->inouts->value
24873 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24874 $check-mu-compute-offset-stmt:check-no-inouts:
24875 3d/compare-eax-and 0/imm32
24876 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-too-few-inouts/disp32
24877 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24878 89/<- %ecx 0/r32/eax
24879 # - check base type is either (addr array ...) in register or (array ...) on stack
24880 # var base-type/ebx: (addr type-tree) = lookup(base->type)
24881 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
24882 89/<- %ebx 0/r32/eax
24883 # if base-type is an atom, abort with a precise error
24884 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom
24886 74/jump-if-= break/disp8
24887 (simple-mu-type? %ebx 3) # array => eax
24888 3d/compare-eax-and 0/imm32/false
24889 0f 85/jump-if-!= $check-mu-compute-offset-stmt:error-base-array-atom-type/disp32
24890 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-base-non-array-type/disp32
24892 $check-mu-compute-offset-stmt:base-is-compound:
24893 # if type->left not addr or array, abort
24895 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24896 (simple-mu-type? %eax 2) # addr => eax
24897 3d/compare-eax-and 0/imm32/false
24898 75/jump-if-!= break/disp8
24899 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24900 (simple-mu-type? %eax 3) # array => eax
24901 3d/compare-eax-and 0/imm32/false
24902 75/jump-if-!= break/disp8
24903 e9/jump $check-mu-compute-offset-stmt:error-base-non-array-type/disp32
24905 # if (type->left == addr) ensure type->right->left == array and type->register exists
24907 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24908 (simple-mu-type? %eax 2) # addr => eax
24909 3d/compare-eax-and 0/imm32/false
24910 74/jump-if-= break/disp8
24911 $check-mu-compute-offset-stmt:base-is-addr:
24912 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
24913 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
24914 (simple-mu-type? %eax 3) # array => eax
24915 3d/compare-eax-and 0/imm32/false
24916 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-base-non-array-type/disp32
24918 # if (base-type->left == addr) base-type = base-type->right
24920 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
24921 (simple-mu-type? %eax 2) # addr => eax
24922 3d/compare-eax-and 0/imm32/false
24923 74/jump-if-= break/disp8
24924 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
24925 89/<- %ebx 0/r32/eax
24927 # - check for 1 inout
24928 # var index/ecx: (addr stmt-var) = stmt->inouts->next->value
24929 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24930 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
24931 $check-mu-compute-offset-stmt:check-single-inout:
24932 3d/compare-eax-and 0/imm32
24933 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-too-few-inouts/disp32
24934 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24935 89/<- %ecx 0/r32/eax
24936 # - check index is either a literal or register
24937 # var index-type/edx: (addr type-tree)
24938 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
24939 89/<- %edx 0/r32/eax
24940 # index type must be a literal or int
24941 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom
24942 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-invalid-index-type/disp32
24944 $check-mu-compute-offset-stmt:index-type-is-atom:
24945 (simple-mu-type? %edx 0) # literal => eax
24946 3d/compare-eax-and 0/imm32/false
24947 75/jump-if-!= break/disp8
24948 (simple-mu-type? %edx 1) # int => eax
24949 3d/compare-eax-and 0/imm32/false
24950 75/jump-if-!= break/disp8
24951 e9/jump $check-mu-compute-offset-stmt:error-invalid-index-type/disp32
24953 # - check for too many inouts
24954 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
24955 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
24956 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
24957 3d/compare-eax-and 0/imm32/false
24958 0f 85/jump-if-!= $check-mu-compute-offset-stmt:error-too-many-inouts/disp32
24959 # - check for 0 outputs
24960 # var output/edi: (addr var) = stmt->outputs->value
24961 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
24962 3d/compare-eax-and 0/imm32/false
24963 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-too-few-outputs/disp32
24964 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
24965 89/<- %edi 0/r32/eax
24966 # - check output type
24967 # must have a non-atomic type
24968 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax
24969 89/<- %edx 0/r32/eax
24970 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom
24971 0f 85/jump-if-!= $check-mu-compute-offset-stmt:error-output-type-not-offset/disp32
24972 # type must start with (offset ...)
24973 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax
24974 (simple-mu-type? %eax 7) # offset => eax
24975 3d/compare-eax-and 0/imm32/false
24976 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-output-type-not-offset/disp32
24977 # if tail(base-type) != tail(output-type) abort
24978 (type-tail %ebx) # => eax
24979 89/<- %ebx 0/r32/eax
24980 (type-tail %edx) # => eax
24981 (type-equal? %ebx %eax) # => eax
24982 3d/compare-eax-and 0/imm32/false
24983 0f 84/jump-if-= $check-mu-compute-offset-stmt:error-bad-output-type/disp32
24984 # - check for too many outputs
24985 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
24986 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
24987 3d/compare-eax-and 0/imm32/false
24988 0f 85/jump-if-!= $check-mu-compute-offset-stmt:error-too-many-outputs/disp32
24989 $check-mu-compute-offset-stmt:end:
24990 # . restore registers
24998 89/<- %esp 5/r32/ebp
25002 $check-mu-compute-offset-stmt:error-base-non-array-type:
25003 (write-buffered *(ebp+0x10) "fn ")
25004 8b/-> *(ebp+0xc) 0/r32/eax
25005 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25006 (write-buffered *(ebp+0x10) %eax)
25007 (write-buffered *(ebp+0x10) ": stmt compute-offset: var '")
25008 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
25009 (write-buffered *(ebp+0x10) %eax)
25010 (write-buffered *(ebp+0x10) "' is not an array\n")
25011 (flush *(ebp+0x10))
25012 (stop *(ebp+0x14) 1)
25015 $check-mu-compute-offset-stmt:error-base-array-atom-type:
25016 (write-buffered *(ebp+0x10) "fn ")
25017 8b/-> *(ebp+0xc) 0/r32/eax
25018 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25019 (write-buffered *(ebp+0x10) %eax)
25020 (write-buffered *(ebp+0x10) ": stmt compute-offset: array '")
25021 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
25022 (write-buffered *(ebp+0x10) %eax)
25023 (write-buffered *(ebp+0x10) "' must specify the type of its elements\n")
25024 (flush *(ebp+0x10))
25025 (stop *(ebp+0x14) 1)
25028 $check-mu-compute-offset-stmt:error-too-few-inouts:
25029 (write-buffered *(ebp+0x10) "fn ")
25030 8b/-> *(ebp+0xc) 0/r32/eax
25031 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25032 (write-buffered *(ebp+0x10) %eax)
25033 (write-buffered *(ebp+0x10) ": stmt compute-offset: too few inouts (2 required)\n")
25034 (flush *(ebp+0x10))
25035 (stop *(ebp+0x14) 1)
25038 $check-mu-compute-offset-stmt:error-invalid-index-type:
25039 (write-buffered *(ebp+0x10) "fn ")
25040 8b/-> *(ebp+0xc) 0/r32/eax
25041 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25042 (write-buffered *(ebp+0x10) %eax)
25043 (write-buffered *(ebp+0x10) ": stmt compute-offset: second argument '")
25044 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
25045 (write-buffered *(ebp+0x10) %eax)
25046 (write-buffered *(ebp+0x10) "' must be an int\n")
25047 (flush *(ebp+0x10))
25048 (stop *(ebp+0x14) 1)
25051 $check-mu-compute-offset-stmt:error-index-offset-atom-type:
25052 (write-buffered *(ebp+0x10) "fn ")
25053 8b/-> *(ebp+0xc) 0/r32/eax
25054 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25055 (write-buffered *(ebp+0x10) %eax)
25056 (write-buffered *(ebp+0x10) ": stmt compute-offset: offset '")
25057 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
25058 (write-buffered *(ebp+0x10) %eax)
25059 (write-buffered *(ebp+0x10) "' must specify the type of array elements\n")
25060 (flush *(ebp+0x10))
25061 (stop *(ebp+0x14) 1)
25064 $check-mu-compute-offset-stmt:error-index-on-stack:
25065 (write-buffered *(ebp+0x10) "fn ")
25066 8b/-> *(ebp+0xc) 0/r32/eax
25067 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25068 (write-buffered *(ebp+0x10) %eax)
25069 (write-buffered *(ebp+0x10) ": stmt compute-offset: second argument '")
25070 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
25071 (write-buffered *(ebp+0x10) %eax)
25072 (write-buffered *(ebp+0x10) "' must be in a register\n")
25073 (flush *(ebp+0x10))
25074 (stop *(ebp+0x14) 1)
25077 $check-mu-compute-offset-stmt:error-too-many-inouts:
25078 (write-buffered *(ebp+0x10) "fn ")
25079 8b/-> *(ebp+0xc) 0/r32/eax
25080 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25081 (write-buffered *(ebp+0x10) %eax)
25082 (write-buffered *(ebp+0x10) ": stmt compute-offset: too many inouts (2 required)\n")
25083 (flush *(ebp+0x10))
25084 (stop *(ebp+0x14) 1)
25087 $check-mu-compute-offset-stmt:error-too-few-outputs:
25088 (write-buffered *(ebp+0x10) "fn ")
25089 8b/-> *(ebp+0xc) 0/r32/eax
25090 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25091 (write-buffered *(ebp+0x10) %eax)
25092 (write-buffered *(ebp+0x10) ": stmt compute-offset: must have an output\n")
25093 (flush *(ebp+0x10))
25094 (stop *(ebp+0x14) 1)
25097 $check-mu-compute-offset-stmt:error-too-many-outputs:
25098 (write-buffered *(ebp+0x10) "fn ")
25099 8b/-> *(ebp+0xc) 0/r32/eax
25100 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25101 (write-buffered *(ebp+0x10) %eax)
25102 (write-buffered *(ebp+0x10) ": stmt compute-offset: too many outputs (1 required)\n")
25103 (flush *(ebp+0x10))
25104 (stop *(ebp+0x14) 1)
25107 $check-mu-compute-offset-stmt:error-output-not-in-register:
25108 (write-buffered *(ebp+0x10) "fn ")
25109 8b/-> *(ebp+0xc) 0/r32/eax
25110 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25111 (write-buffered *(ebp+0x10) %eax)
25112 (write-buffered *(ebp+0x10) ": stmt compute-offset: output '")
25113 (lookup *edi *(edi+4)) # Var-name Var-name => eax
25114 (write-buffered *(ebp+0x10) %eax)
25115 (write-buffered *(ebp+0x10) "' is not in a register\n")
25116 (flush *(ebp+0x10))
25117 (stop *(ebp+0x14) 1)
25120 $check-mu-compute-offset-stmt:error-output-type-not-offset:
25121 (write-buffered *(ebp+0x10) "fn ")
25122 8b/-> *(ebp+0xc) 0/r32/eax
25123 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25124 (write-buffered *(ebp+0x10) %eax)
25125 (write-buffered *(ebp+0x10) ": stmt compute-offset: output '")
25126 (lookup *edi *(edi+4)) # Var-name Var-name => eax
25127 (write-buffered *(ebp+0x10) %eax)
25128 (write-buffered *(ebp+0x10) "' must be an offset\n")
25129 (flush *(ebp+0x10))
25130 (stop *(ebp+0x14) 1)
25133 $check-mu-compute-offset-stmt:error-bad-output-type:
25134 (write-buffered *(ebp+0x10) "fn ")
25135 8b/-> *(ebp+0xc) 0/r32/eax
25136 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25137 (write-buffered *(ebp+0x10) %eax)
25138 (write-buffered *(ebp+0x10) ": stmt compute-offset: output '")
25139 (lookup *edi *(edi+4)) # Var-name Var-name => eax
25140 (write-buffered *(ebp+0x10) %eax)
25141 (write-buffered *(ebp+0x10) "' does not have the right type\n")
25142 (flush *(ebp+0x10))
25143 (stop *(ebp+0x14) 1)
25146 check-mu-copy-object-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
25149 89/<- %ebp 4/r32/esp
25157 8b/-> *(ebp+8) 6/r32/esi
25158 $check-mu-copy-object-stmt:check-for-output:
25159 # if stmt->outputs abort
25160 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
25161 3d/compare-eax-and 0/imm32
25162 0f 85/jump-if-!= $check-mu-copy-object-stmt:error-too-many-outputs/disp32
25163 $check-mu-copy-object-stmt:get-left:
25164 # var dest/edi: (addr stmt-var) = stmt->inouts
25165 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
25166 89/<- %edi 0/r32/eax
25168 3d/compare-eax-and 0/imm32
25169 0f 84/jump-if-= $check-mu-copy-object-stmt:error-incorrect-inouts/disp32
25170 $check-mu-copy-object-stmt:get-src:
25171 # var src/esi: (addr stmt-var) = dest->next
25172 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
25173 89/<- %esi 0/r32/eax
25175 3d/compare-eax-and 0/imm32
25176 0f 84/jump-if-= $check-mu-copy-object-stmt:error-incorrect-inouts/disp32
25178 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
25179 3d/compare-eax-and 0/imm32
25180 0f 85/jump-if-!= $check-mu-copy-object-stmt:error-incorrect-inouts/disp32
25181 $check-mu-copy-object-stmt:types:
25182 # var src-type/ecx: (addr type-tree) = src->value->type
25183 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
25184 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
25185 89/<- %ecx 0/r32/eax
25186 # if (src->is-deref?) src-type = src-type->payload
25187 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref
25188 3d/compare-eax-and 0/imm32/false
25190 74/jump-if-= break/disp8
25191 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
25192 # if src-type->right is null, src-type = src-type->left
25193 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
25195 75/jump-if-!= break/disp8
25196 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
25198 89/<- %ecx 0/r32/eax
25200 # if src-type is not addr, abort
25201 (mu-addr-type? %ecx) # => eax
25202 3d/compare-eax-and 0/imm32/false
25203 0f 84/jump-if-= $check-mu-copy-object-stmt:error-invalid-types/disp32
25204 # var dest-type/ebx: (addr type-tree) = dest->value->type
25205 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
25206 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
25207 89/<- %ebx 0/r32/eax
25208 # if (dest->is-deref?) dest-type = dest-type->payload
25209 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref
25210 3d/compare-eax-and 0/imm32/false
25212 74/jump-if-= break/disp8
25213 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
25214 # if dest-type->right is null, dest-type = dest-type->left
25215 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
25217 75/jump-if-!= break/disp8
25218 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
25220 89/<- %ebx 0/r32/eax
25222 # if (dest-type != src-type) abort
25223 (type-equal? %ecx %ebx) # => eax
25224 3d/compare-eax-and 0/imm32
25225 0f 84/jump-if-= $check-mu-copy-object-stmt:error-invalid-types/disp32
25226 $check-mu-copy-object-stmt:end:
25227 # . restore registers
25234 89/<- %esp 5/r32/ebp
25238 $check-mu-copy-object-stmt:error-incorrect-inouts:
25239 (write-buffered *(ebp+0x10) "fn ")
25240 8b/-> *(ebp+0xc) 0/r32/eax
25241 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25242 (write-buffered *(ebp+0x10) %eax)
25243 (write-buffered *(ebp+0x10) ": stmt 'copy-object' must have two inouts\n")
25244 (flush *(ebp+0x10))
25245 (stop *(ebp+0x14) 1)
25248 $check-mu-copy-object-stmt:error-too-many-outputs:
25249 (write-buffered *(ebp+0x10) "fn ")
25250 8b/-> *(ebp+0xc) 0/r32/eax
25251 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25252 (write-buffered *(ebp+0x10) %eax)
25253 (write-buffered *(ebp+0x10) ": stmt 'copy-object' must not have any outputs\n")
25254 (flush *(ebp+0x10))
25255 (stop *(ebp+0x14) 1)
25258 $check-mu-copy-object-stmt:error-invalid-types:
25259 (write-buffered *(ebp+0x10) "fn ")
25260 8b/-> *(ebp+0xc) 0/r32/eax
25261 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25262 (write-buffered *(ebp+0x10) %eax)
25263 (write-buffered *(ebp+0x10) ": stmt copy-object: two inouts with identical addr types expected\n")
25264 (flush *(ebp+0x10))
25265 (stop *(ebp+0x14) 1)
25268 check-mu-clear-object-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
25271 89/<- %ebp 4/r32/esp
25279 8b/-> *(ebp+8) 6/r32/esi
25280 $check-mu-clear-object-stmt:check-for-output:
25281 # if stmt->outputs abort
25282 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
25283 3d/compare-eax-and 0/imm32
25284 0f 85/jump-if-!= $check-mu-clear-object-stmt:error-too-many-outputs/disp32
25285 $check-mu-clear-object-stmt:get-left:
25286 # var dest/edi: (addr stmt-var) = stmt->inouts
25287 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
25288 89/<- %edi 0/r32/eax
25290 3d/compare-eax-and 0/imm32
25291 0f 84/jump-if-= $check-mu-clear-object-stmt:error-incorrect-inouts/disp32
25292 $check-mu-clear-object-stmt:get-src:
25294 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
25295 3d/compare-eax-and 0/imm32
25296 0f 85/jump-if-!= $check-mu-clear-object-stmt:error-incorrect-inouts/disp32
25297 $check-mu-clear-object-stmt:types:
25298 # var src-type/ecx: (addr type-tree) = src->value->type
25299 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
25300 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
25301 89/<- %ecx 0/r32/eax
25302 # if (src->is-deref?) src-type = src-type->payload
25303 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref
25304 3d/compare-eax-and 0/imm32/false
25306 74/jump-if-= break/disp8
25307 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
25308 # if src-type->right is null, src-type = src-type->left
25309 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
25311 75/jump-if-!= break/disp8
25312 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
25314 89/<- %ecx 0/r32/eax
25316 # if src-type is not addr, abort
25317 (mu-addr-type? %ecx) # => eax
25318 3d/compare-eax-and 0/imm32/false
25319 0f 84/jump-if-= $check-mu-clear-object-stmt:error-invalid-type/disp32
25320 $check-mu-clear-object-stmt:end:
25321 # . restore registers
25328 89/<- %esp 5/r32/ebp
25332 $check-mu-clear-object-stmt:error-incorrect-inouts:
25333 (write-buffered *(ebp+0x10) "fn ")
25334 8b/-> *(ebp+0xc) 0/r32/eax
25335 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25336 (write-buffered *(ebp+0x10) %eax)
25337 (write-buffered *(ebp+0x10) ": stmt 'clear-object' must have a single inout\n")
25338 (flush *(ebp+0x10))
25339 (stop *(ebp+0x14) 1)
25342 $check-mu-clear-object-stmt:error-too-many-outputs:
25343 (write-buffered *(ebp+0x10) "fn ")
25344 8b/-> *(ebp+0xc) 0/r32/eax
25345 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25346 (write-buffered *(ebp+0x10) %eax)
25347 (write-buffered *(ebp+0x10) ": stmt 'clear-object' must not have any outputs\n")
25348 (flush *(ebp+0x10))
25349 (stop *(ebp+0x14) 1)
25352 $check-mu-clear-object-stmt:error-invalid-type:
25353 (write-buffered *(ebp+0x10) "fn ")
25354 8b/-> *(ebp+0xc) 0/r32/eax
25355 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25356 (write-buffered *(ebp+0x10) %eax)
25357 (write-buffered *(ebp+0x10) ": stmt clear-object: inout must have an addr type\n")
25358 (flush *(ebp+0x10))
25359 (stop *(ebp+0x14) 1)
25362 check-mu-allocate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
25365 89/<- %ebp 4/r32/esp
25372 8b/-> *(ebp+8) 6/r32/esi
25373 $check-mu-allocate-stmt:check-for-output:
25374 # if stmt->outputs abort
25375 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
25376 3d/compare-eax-and 0/imm32
25377 0f 85/jump-if-!= $check-mu-allocate-stmt:error-too-many-outputs/disp32
25378 $check-mu-allocate-stmt:get-target:
25379 # var target/edi: (addr stmt-var) = stmt->inouts
25380 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
25381 89/<- %edi 0/r32/eax
25383 3d/compare-eax-and 0/imm32
25384 0f 84/jump-if-= $check-mu-allocate-stmt:error-incorrect-inouts/disp32
25386 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
25387 3d/compare-eax-and 0/imm32
25388 0f 85/jump-if-!= $check-mu-allocate-stmt:error-incorrect-inouts/disp32
25389 $check-mu-allocate-stmt:check-type:
25390 # var target-type/ebx: (addr type-tree) = target->value->type
25391 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
25392 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
25393 89/<- %ebx 0/r32/eax
25394 # if (target->is-deref?) target-type = target-type->payload
25395 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref
25396 3d/compare-eax-and 0/imm32/false
25398 74/jump-if-= break/disp8
25399 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
25400 # if target-type->right is null, target-type = target-type->left
25401 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
25403 75/jump-if-!= break/disp8
25404 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
25406 89/<- %ebx 0/r32/eax
25408 # if target-type is not addr, abort
25409 (mu-addr-type? %ebx) # => eax
25410 3d/compare-eax-and 0/imm32/false
25411 0f 84/jump-if-= $check-mu-allocate-stmt:error-invalid-type/disp32
25412 # if target-type->right is an atom, abort
25413 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
25414 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
25415 0f 85/jump-if-!= $check-mu-allocate-stmt:error-invalid-type/disp32
25416 # if target-type->right->left is not handle, abort
25417 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
25418 (simple-mu-type? %eax 4) # handle => eax
25419 3d/compare-eax-and 0/imm32/false
25420 0f 84/jump-if-= $check-mu-allocate-stmt:error-invalid-type/disp32
25421 $check-mu-allocate-stmt:end:
25422 # . restore registers
25428 89/<- %esp 5/r32/ebp
25432 $check-mu-allocate-stmt:error-incorrect-inouts:
25433 (write-buffered *(ebp+0x10) "fn ")
25434 8b/-> *(ebp+0xc) 0/r32/eax
25435 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25436 (write-buffered *(ebp+0x10) %eax)
25437 (write-buffered *(ebp+0x10) ": stmt 'allocate' must have a single inout\n")
25438 (flush *(ebp+0x10))
25439 (stop *(ebp+0x14) 1)
25442 $check-mu-allocate-stmt:error-too-many-outputs:
25443 (write-buffered *(ebp+0x10) "fn ")
25444 8b/-> *(ebp+0xc) 0/r32/eax
25445 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25446 (write-buffered *(ebp+0x10) %eax)
25447 (write-buffered *(ebp+0x10) ": stmt 'allocate' must not have any outputs\n")
25448 (flush *(ebp+0x10))
25449 (stop *(ebp+0x14) 1)
25452 $check-mu-allocate-stmt:error-invalid-type:
25453 (write-buffered *(ebp+0x10) "fn ")
25454 8b/-> *(ebp+0xc) 0/r32/eax
25455 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25456 (write-buffered *(ebp+0x10) %eax)
25457 (write-buffered *(ebp+0x10) ": stmt allocate: inout '")
25458 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
25459 (lookup *eax *(eax+4)) # Var-name Var-name => eax
25460 (write-buffered *(ebp+0x10) %eax)
25461 (write-buffered *(ebp+0x10) "' must have type (addr handle ...)\n")
25462 (flush *(ebp+0x10))
25463 (stop *(ebp+0x14) 1)
25466 check-mu-populate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
25469 89/<- %ebp 4/r32/esp
25476 8b/-> *(ebp+8) 6/r32/esi
25477 $check-mu-populate-stmt:check-for-output:
25478 # if stmt->outputs abort
25479 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
25480 3d/compare-eax-and 0/imm32
25481 0f 85/jump-if-!= $check-mu-populate-stmt:error-too-many-outputs/disp32
25482 $check-mu-populate-stmt:get-target:
25483 # var target/edi: (addr stmt-var) = stmt->inouts
25484 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
25485 89/<- %edi 0/r32/eax
25487 3d/compare-eax-and 0/imm32
25488 0f 84/jump-if-= $check-mu-populate-stmt:error-incorrect-inouts/disp32
25489 $check-mu-populate-stmt:get-length:
25490 # var length/esi: (addr stmt-var) = dest->next
25491 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
25492 89/<- %esi 0/r32/eax
25494 3d/compare-eax-and 0/imm32
25495 0f 84/jump-if-= $check-mu-populate-stmt:error-incorrect-inouts/disp32
25497 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
25498 3d/compare-eax-and 0/imm32
25499 0f 85/jump-if-!= $check-mu-populate-stmt:error-incorrect-inouts/disp32
25500 $check-mu-populate-stmt:check-target-type:
25501 # var target-type/ebx: (addr type-tree) = target->value->type
25502 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
25503 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
25504 89/<- %ebx 0/r32/eax
25505 $check-mu-populate-stmt:check-target-type-deref:
25506 # if (target->is-deref?) target-type = target-type->payload
25507 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref
25508 3d/compare-eax-and 0/imm32/false
25510 74/jump-if-= break/disp8
25511 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
25512 # if target-type->right is null, target-type = target-type->left
25513 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
25515 75/jump-if-!= break/disp8
25516 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
25518 89/<- %ebx 0/r32/eax
25520 $check-mu-populate-stmt:check-target-type-addr:
25521 # if target-type is not addr, abort
25522 (mu-addr-type? %ebx) # => eax
25523 3d/compare-eax-and 0/imm32/false
25524 0f 84/jump-if-= $check-mu-populate-stmt:error-invalid-target-type/disp32
25525 # if target-type->right is an atom, abort
25526 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
25527 89/<- %ebx 0/r32/eax
25528 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom
25529 0f 85/jump-if-!= $check-mu-populate-stmt:error-invalid-target-type/disp32
25530 $check-mu-populate-stmt:check-target-type-handle:
25531 # if target-type->right->left is not handle, abort
25532 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
25533 (simple-mu-type? %eax 4) # handle => eax
25534 3d/compare-eax-and 0/imm32/false
25535 0f 84/jump-if-= $check-mu-populate-stmt:error-invalid-target-type/disp32
25536 # if target-type->right->right is an atom, abort
25537 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
25538 89/<- %ebx 0/r32/eax
25539 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom
25540 0f 85/jump-if-!= $check-mu-populate-stmt:error-invalid-target-type/disp32
25541 $check-mu-populate-stmt:check-target-type-array:
25542 # if target-type->right->right->left is not array, abort
25543 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
25544 (simple-mu-type? %eax 3) # array => eax
25545 3d/compare-eax-and 0/imm32/false
25546 0f 84/jump-if-= $check-mu-populate-stmt:error-invalid-target-type/disp32
25547 $check-mu-populate-stmt:check-length-type:
25548 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
25549 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
25550 89/<- %ebx 0/r32/eax
25551 (simple-mu-type? %ebx 0) # literal => eax
25552 3d/compare-eax-and 0/imm32/false
25553 75/jump-if-!= $check-mu-populate-stmt:end/disp8
25554 (simple-mu-type? %ebx 1) # int => eax
25555 3d/compare-eax-and 0/imm32/false
25556 0f 84/jump-if-= $check-mu-populate-stmt:error-invalid-length-type/disp32
25557 $check-mu-populate-stmt:end:
25558 # . restore registers
25564 89/<- %esp 5/r32/ebp
25568 $check-mu-populate-stmt:error-incorrect-inouts:
25569 (write-buffered *(ebp+0x10) "fn ")
25570 8b/-> *(ebp+0xc) 0/r32/eax
25571 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25572 (write-buffered *(ebp+0x10) %eax)
25573 (write-buffered *(ebp+0x10) ": stmt 'populate' must have two inouts\n")
25574 (flush *(ebp+0x10))
25575 (stop *(ebp+0x14) 1)
25578 $check-mu-populate-stmt:error-too-many-outputs:
25579 (write-buffered *(ebp+0x10) "fn ")
25580 8b/-> *(ebp+0xc) 0/r32/eax
25581 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25582 (write-buffered *(ebp+0x10) %eax)
25583 (write-buffered *(ebp+0x10) ": stmt 'populate' must not have any outputs\n")
25584 (flush *(ebp+0x10))
25585 (stop *(ebp+0x14) 1)
25588 $check-mu-populate-stmt:error-invalid-target-type:
25589 (write-buffered *(ebp+0x10) "fn ")
25590 8b/-> *(ebp+0xc) 0/r32/eax
25591 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25592 (write-buffered *(ebp+0x10) %eax)
25593 (write-buffered *(ebp+0x10) ": stmt populate: first inout '")
25594 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
25595 (lookup *eax *(eax+4)) # Var-name Var-name => eax
25596 (write-buffered *(ebp+0x10) %eax)
25597 (write-buffered *(ebp+0x10) "' must have type (addr handle array ...)\n")
25598 (flush *(ebp+0x10))
25599 (stop *(ebp+0x14) 1)
25602 $check-mu-populate-stmt:error-invalid-length-type:
25603 (write-buffered *(ebp+0x10) "fn ")
25604 8b/-> *(ebp+0xc) 0/r32/eax
25605 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25606 (write-buffered *(ebp+0x10) %eax)
25607 (write-buffered *(ebp+0x10) ": stmt populate: second inout '")
25608 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
25609 (lookup *eax *(eax+4)) # Var-name Var-name => eax
25610 (write-buffered *(ebp+0x10) %eax)
25611 (write-buffered *(ebp+0x10) "' must be an int\n")
25612 (flush *(ebp+0x10))
25613 (stop *(ebp+0x14) 1)
25616 check-mu-populate-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
25619 89/<- %ebp 4/r32/esp
25626 8b/-> *(ebp+8) 6/r32/esi
25627 $check-mu-populate-stream-stmt:check-for-output:
25628 # if stmt->outputs abort
25629 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
25630 3d/compare-eax-and 0/imm32
25631 0f 85/jump-if-!= $check-mu-populate-stream-stmt:error-too-many-outputs/disp32
25632 $check-mu-populate-stream-stmt:get-target:
25633 # var target/edi: (addr stmt-var) = stmt->inouts
25634 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
25635 89/<- %edi 0/r32/eax
25637 3d/compare-eax-and 0/imm32
25638 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-incorrect-inouts/disp32
25639 $check-mu-populate-stream-stmt:get-length:
25640 # var length/esi: (addr stmt-var) = dest->next
25641 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
25642 89/<- %esi 0/r32/eax
25644 3d/compare-eax-and 0/imm32
25645 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-incorrect-inouts/disp32
25647 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
25648 3d/compare-eax-and 0/imm32
25649 0f 85/jump-if-!= $check-mu-populate-stream-stmt:error-incorrect-inouts/disp32
25650 $check-mu-populate-stream-stmt:check-target-type:
25651 # var target-type/ebx: (addr type-tree) = target->value->type
25652 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
25653 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
25654 89/<- %ebx 0/r32/eax
25655 $check-mu-populate-stream-stmt:check-target-type-deref:
25656 # if (target->is-deref?) target-type = target-type->payload
25657 8b/-> *(edi+0x10) 0/r32/eax # Stmt-var-is-deref
25658 3d/compare-eax-and 0/imm32/false
25660 74/jump-if-= break/disp8
25661 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
25662 # if target-type->right is null, target-type = target-type->left
25663 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
25665 75/jump-if-!= break/disp8
25666 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
25668 89/<- %ebx 0/r32/eax
25670 $check-mu-populate-stream-stmt:check-target-type-addr:
25671 # if target-type is not addr, abort
25672 (mu-addr-type? %ebx) # => eax
25673 3d/compare-eax-and 0/imm32/false
25674 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32
25675 # if target-type->right is an atom, abort
25676 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
25677 89/<- %ebx 0/r32/eax
25678 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom
25679 0f 85/jump-if-!= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32
25680 $check-mu-populate-stream-stmt:check-target-type-handle:
25681 # if target-type->right->left is not handle, abort
25682 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
25683 (simple-mu-type? %eax 4) # handle => eax
25684 3d/compare-eax-and 0/imm32/false
25685 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32
25686 # if target-type->right->right is an atom, abort
25687 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
25688 89/<- %ebx 0/r32/eax
25689 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom
25690 0f 85/jump-if-!= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32
25691 $check-mu-populate-stream-stmt:check-target-type-stream:
25692 # if target-type->right->right->left is not stream, abort
25693 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
25694 (simple-mu-type? %eax 0xb) # stream => eax
25695 3d/compare-eax-and 0/imm32/false
25696 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-invalid-target-type/disp32
25697 $check-mu-populate-stream-stmt:check-length-type:
25698 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
25699 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
25700 89/<- %ebx 0/r32/eax
25701 (simple-mu-type? %ebx 0) # literal => eax
25702 3d/compare-eax-and 0/imm32/false
25703 75/jump-if-!= $check-mu-populate-stream-stmt:end/disp8
25704 (simple-mu-type? %ebx 1) # int => eax
25705 3d/compare-eax-and 0/imm32/false
25706 0f 84/jump-if-= $check-mu-populate-stream-stmt:error-invalid-length-type/disp32
25707 $check-mu-populate-stream-stmt:end:
25708 # . restore registers
25714 89/<- %esp 5/r32/ebp
25718 $check-mu-populate-stream-stmt:error-incorrect-inouts:
25719 (write-buffered *(ebp+0x10) "fn ")
25720 8b/-> *(ebp+0xc) 0/r32/eax
25721 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25722 (write-buffered *(ebp+0x10) %eax)
25723 (write-buffered *(ebp+0x10) ": stmt 'populate-stream' must have two inouts\n")
25724 (flush *(ebp+0x10))
25725 (stop *(ebp+0x14) 1)
25728 $check-mu-populate-stream-stmt:error-too-many-outputs:
25729 (write-buffered *(ebp+0x10) "fn ")
25730 8b/-> *(ebp+0xc) 0/r32/eax
25731 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25732 (write-buffered *(ebp+0x10) %eax)
25733 (write-buffered *(ebp+0x10) ": stmt 'populate-stream' must not have any outputs\n")
25734 (flush *(ebp+0x10))
25735 (stop *(ebp+0x14) 1)
25738 $check-mu-populate-stream-stmt:error-invalid-target-type:
25739 (write-buffered *(ebp+0x10) "fn ")
25740 8b/-> *(ebp+0xc) 0/r32/eax
25741 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25742 (write-buffered *(ebp+0x10) %eax)
25743 (write-buffered *(ebp+0x10) ": stmt populate-stream: first inout '")
25744 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
25745 (lookup *eax *(eax+4)) # Var-name Var-name => eax
25746 (write-buffered *(ebp+0x10) %eax)
25747 (write-buffered *(ebp+0x10) "' must have type (addr handle stream ...)\n")
25748 (flush *(ebp+0x10))
25749 (stop *(ebp+0x14) 1)
25752 $check-mu-populate-stream-stmt:error-invalid-length-type:
25753 (write-buffered *(ebp+0x10) "fn ")
25754 8b/-> *(ebp+0xc) 0/r32/eax
25755 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25756 (write-buffered *(ebp+0x10) %eax)
25757 (write-buffered *(ebp+0x10) ": stmt populate-stream: second inout '")
25758 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
25759 (lookup *eax *(eax+4)) # Var-name Var-name => eax
25760 (write-buffered *(ebp+0x10) %eax)
25761 (write-buffered *(ebp+0x10) "' must be an int\n")
25762 (flush *(ebp+0x10))
25763 (stop *(ebp+0x14) 1)
25766 check-mu-read-from-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
25769 89/<- %ebp 4/r32/esp
25778 8b/-> *(ebp+8) 6/r32/esi
25779 # - check for 0 inouts
25780 # var base/ecx: (addr var) = stmt->inouts->value
25781 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
25782 $check-mu-read-from-stream-stmt:check-no-inouts:
25783 3d/compare-eax-and 0/imm32
25784 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-too-few-inouts/disp32
25785 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
25786 89/<- %ecx 0/r32/eax
25787 # - check base type is (addr stream T)
25788 # var base-type/ebx: (addr type-tree) = lookup(base->type)
25789 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
25790 89/<- %ebx 0/r32/eax
25791 $check-mu-read-from-stream-stmt:check-base-is-compound:
25792 # if base-type is an atom, abort
25793 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom
25794 0f 85/jump-if-!= $check-mu-read-from-stream-stmt:error-invalid-base-type/disp32
25795 $check-mu-read-from-stream-stmt:check-base-is-addr:
25796 # if type->left not addr, abort
25797 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
25798 (simple-mu-type? %eax 2) # addr => eax
25799 3d/compare-eax-and 0/imm32/false
25800 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-invalid-base-type/disp32
25801 $check-mu-read-from-stream-stmt:check-base-is-addr-to-stream:
25802 # base-type = base-type->right
25803 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
25804 89/<- %ebx 0/r32/eax
25805 # ensure base-type->left == stream
25806 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
25807 (simple-mu-type? %eax 0xb) # stream => eax
25808 3d/compare-eax-and 0/imm32/false
25809 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-invalid-base-type/disp32
25810 # - check target type is (addr T)
25811 # var target/ecx: (addr stmt-var) = stmt->inouts->next->value
25812 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
25813 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
25814 $check-mu-read-from-stream-stmt:check-single-inout:
25815 3d/compare-eax-and 0/imm32
25816 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-too-few-inouts/disp32
25817 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
25818 89/<- %ecx 0/r32/eax
25819 # var target-type/edx: (addr type-tree)
25820 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
25821 89/<- %edx 0/r32/eax
25822 # if target-type is an atom, it must be a literal or int
25823 $check-mu-read-from-stream-stmt:check-target-is-compound:
25824 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom
25825 0f 85/jump-if-!= $check-mu-read-from-stream-stmt:error-target-type-not-address/disp32
25826 $check-mu-read-from-stream-stmt:check-target-type:
25827 # target type must start with (addr ...)
25828 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax
25829 (simple-mu-type? %eax 2) # addr => eax
25830 3d/compare-eax-and 0/imm32/false
25831 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-target-type-not-address/disp32
25832 # if tail(base-type) != tail(target-type) abort
25833 (type-tail %ebx) # => eax
25834 89/<- %ebx 0/r32/eax
25835 (type-tail %edx) # => eax
25836 (type-equal? %ebx %eax) # => eax
25837 3d/compare-eax-and 0/imm32/false
25838 0f 84/jump-if-= $check-mu-read-from-stream-stmt:error-invalid-target-type/disp32
25839 $check-mu-read-from-stream-stmt:check-too-many-inouts:
25840 # - check for too many inouts
25841 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
25842 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
25843 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
25844 3d/compare-eax-and 0/imm32/false
25845 0f 85/jump-if-!= $check-mu-read-from-stream-stmt:error-too-many-inouts/disp32
25846 $check-mu-read-from-stream-stmt:check-unexpected-output:
25847 # - check for any output
25848 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
25849 3d/compare-eax-and 0/imm32/false
25850 0f 85/jump-if-!= $check-mu-read-from-stream-stmt:error-unexpected-output/disp32
25851 $check-mu-read-from-stream-stmt:end:
25852 # . restore registers
25860 89/<- %esp 5/r32/ebp
25864 $check-mu-read-from-stream-stmt:error-invalid-base-type:
25865 (write-buffered *(ebp+0x10) "fn ")
25866 8b/-> *(ebp+0xc) 0/r32/eax
25867 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25868 (write-buffered *(ebp+0x10) %eax)
25869 (write-buffered *(ebp+0x10) ": stmt read-from-stream: var '")
25870 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
25871 (write-buffered *(ebp+0x10) %eax)
25872 (write-buffered *(ebp+0x10) "' must be an addr to a stream\n")
25873 (flush *(ebp+0x10))
25874 (stop *(ebp+0x14) 1)
25877 $check-mu-read-from-stream-stmt:error-too-few-inouts:
25878 (write-buffered *(ebp+0x10) "fn ")
25879 8b/-> *(ebp+0xc) 0/r32/eax
25880 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25881 (write-buffered *(ebp+0x10) %eax)
25882 (write-buffered *(ebp+0x10) ": stmt read-from-stream: too few inouts (2 required)\n")
25883 (flush *(ebp+0x10))
25884 (stop *(ebp+0x14) 1)
25887 $check-mu-read-from-stream-stmt:error-target-type-not-address:
25888 (write-buffered *(ebp+0x10) "fn ")
25889 8b/-> *(ebp+0xc) 0/r32/eax
25890 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25891 (write-buffered *(ebp+0x10) %eax)
25892 (write-buffered *(ebp+0x10) ": stmt read-from-stream: target '")
25893 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
25894 (write-buffered *(ebp+0x10) %eax)
25895 (write-buffered *(ebp+0x10) "' must be an addr\n")
25896 (flush *(ebp+0x10))
25897 (stop *(ebp+0x14) 1)
25900 $check-mu-read-from-stream-stmt:error-invalid-target-type:
25901 (write-buffered *(ebp+0x10) "fn ")
25902 8b/-> *(ebp+0xc) 0/r32/eax
25903 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25904 (write-buffered *(ebp+0x10) %eax)
25905 (write-buffered *(ebp+0x10) ": stmt read-from-stream: second inout '")
25906 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
25907 (write-buffered *(ebp+0x10) %eax)
25908 (write-buffered *(ebp+0x10) "' does not have the right type\n")
25909 (flush *(ebp+0x10))
25910 (stop *(ebp+0x14) 1)
25913 $check-mu-read-from-stream-stmt:error-too-many-inouts:
25914 (write-buffered *(ebp+0x10) "fn ")
25915 8b/-> *(ebp+0xc) 0/r32/eax
25916 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25917 (write-buffered *(ebp+0x10) %eax)
25918 (write-buffered *(ebp+0x10) ": stmt read-from-stream: too many inouts (2 required)\n")
25919 (flush *(ebp+0x10))
25920 (stop *(ebp+0x14) 1)
25923 $check-mu-read-from-stream-stmt:error-unexpected-output:
25924 (write-buffered *(ebp+0x10) "fn ")
25925 8b/-> *(ebp+0xc) 0/r32/eax
25926 (lookup *eax *(eax+4)) # Function-name Function-name => eax
25927 (write-buffered *(ebp+0x10) %eax)
25928 (write-buffered *(ebp+0x10) ": stmt read-from-stream: unexpected output\n")
25929 (flush *(ebp+0x10))
25930 (stop *(ebp+0x14) 1)
25933 check-mu-write-to-stream-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
25936 89/<- %ebp 4/r32/esp
25945 8b/-> *(ebp+8) 6/r32/esi
25946 # - check for 0 inouts
25947 # var base/ecx: (addr var) = stmt->inouts->value
25948 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
25949 $check-mu-write-to-stream-stmt:check-no-inouts:
25950 3d/compare-eax-and 0/imm32
25951 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-too-few-inouts/disp32
25952 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
25953 89/<- %ecx 0/r32/eax
25954 # - check base type is (addr stream T)
25955 # var base-type/ebx: (addr type-tree) = lookup(base->type)
25956 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
25957 89/<- %ebx 0/r32/eax
25958 $check-mu-write-to-stream-stmt:check-base-is-compound:
25959 # if base-type is an atom, abort
25960 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom
25961 0f 85/jump-if-!= $check-mu-write-to-stream-stmt:error-invalid-base-type/disp32
25962 $check-mu-write-to-stream-stmt:check-base-is-addr:
25963 # if type->left not addr, abort
25964 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
25965 (simple-mu-type? %eax 2) # addr => eax
25966 3d/compare-eax-and 0/imm32/false
25967 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-invalid-base-type/disp32
25968 $check-mu-write-to-stream-stmt:check-base-is-addr-to-stream:
25969 # base-type = base-type->right
25970 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
25971 89/<- %ebx 0/r32/eax
25972 # ensure base-type->left == stream
25973 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
25974 (simple-mu-type? %eax 0xb) # stream => eax
25975 3d/compare-eax-and 0/imm32/false
25976 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-invalid-base-type/disp32
25977 # - check target type is (addr T)
25978 # var target/ecx: (addr stmt-var) = stmt->inouts->next->value
25979 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
25980 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
25981 $check-mu-write-to-stream-stmt:check-single-inout:
25982 3d/compare-eax-and 0/imm32
25983 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-too-few-inouts/disp32
25984 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
25985 89/<- %ecx 0/r32/eax
25986 # var target-type/edx: (addr type-tree)
25987 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
25988 89/<- %edx 0/r32/eax
25989 # if target-type is an atom, it must be a literal or int
25990 $check-mu-write-to-stream-stmt:check-target-is-compound:
25991 81 7/subop/compare *edx 0/imm32/false # Type-tree-is-atom
25992 0f 85/jump-if-!= $check-mu-write-to-stream-stmt:error-target-type-not-address/disp32
25993 $check-mu-write-to-stream-stmt:check-target-type:
25994 # target type must start with (addr ...)
25995 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax
25996 (simple-mu-type? %eax 2) # addr => eax
25997 3d/compare-eax-and 0/imm32/false
25998 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-target-type-not-address/disp32
25999 # if tail(base-type) != tail(target-type) abort
26000 (type-tail %ebx) # => eax
26001 89/<- %ebx 0/r32/eax
26002 (type-tail %edx) # => eax
26003 (type-equal? %ebx %eax) # => eax
26004 3d/compare-eax-and 0/imm32/false
26005 0f 84/jump-if-= $check-mu-write-to-stream-stmt:error-invalid-target-type/disp32
26006 $check-mu-write-to-stream-stmt:check-too-many-inouts:
26007 # - check for too many inouts
26008 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
26009 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
26010 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
26011 3d/compare-eax-and 0/imm32/false
26012 0f 85/jump-if-!= $check-mu-write-to-stream-stmt:error-too-many-inouts/disp32
26013 $check-mu-write-to-stream-stmt:check-unexpected-output:
26014 # - check for any output
26015 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
26016 3d/compare-eax-and 0/imm32/false
26017 0f 85/jump-if-!= $check-mu-write-to-stream-stmt:error-unexpected-output/disp32
26018 $check-mu-write-to-stream-stmt:end:
26019 # . restore registers
26027 89/<- %esp 5/r32/ebp
26031 $check-mu-write-to-stream-stmt:error-invalid-base-type:
26032 (write-buffered *(ebp+0x10) "fn ")
26033 8b/-> *(ebp+0xc) 0/r32/eax
26034 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26035 (write-buffered *(ebp+0x10) %eax)
26036 (write-buffered *(ebp+0x10) ": stmt write-to-stream: var '")
26037 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
26038 (write-buffered *(ebp+0x10) %eax)
26039 (write-buffered *(ebp+0x10) "' must be an addr to a stream\n")
26040 (flush *(ebp+0x10))
26041 (stop *(ebp+0x14) 1)
26044 $check-mu-write-to-stream-stmt:error-too-few-inouts:
26045 (write-buffered *(ebp+0x10) "fn ")
26046 8b/-> *(ebp+0xc) 0/r32/eax
26047 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26048 (write-buffered *(ebp+0x10) %eax)
26049 (write-buffered *(ebp+0x10) ": stmt write-to-stream: too few inouts (2 required)\n")
26050 (flush *(ebp+0x10))
26051 (stop *(ebp+0x14) 1)
26054 $check-mu-write-to-stream-stmt:error-target-type-not-address:
26055 (write-buffered *(ebp+0x10) "fn ")
26056 8b/-> *(ebp+0xc) 0/r32/eax
26057 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26058 (write-buffered *(ebp+0x10) %eax)
26059 (write-buffered *(ebp+0x10) ": stmt write-to-stream: target '")
26060 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
26061 (write-buffered *(ebp+0x10) %eax)
26062 (write-buffered *(ebp+0x10) "' must be an addr\n")
26063 (flush *(ebp+0x10))
26064 (stop *(ebp+0x14) 1)
26067 $check-mu-write-to-stream-stmt:error-invalid-target-type:
26068 (write-buffered *(ebp+0x10) "fn ")
26069 8b/-> *(ebp+0xc) 0/r32/eax
26070 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26071 (write-buffered *(ebp+0x10) %eax)
26072 (write-buffered *(ebp+0x10) ": stmt write-to-stream: second inout '")
26073 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
26074 (write-buffered *(ebp+0x10) %eax)
26075 (write-buffered *(ebp+0x10) "' does not have the right type\n")
26076 (flush *(ebp+0x10))
26077 (stop *(ebp+0x14) 1)
26080 $check-mu-write-to-stream-stmt:error-too-many-inouts:
26081 (write-buffered *(ebp+0x10) "fn ")
26082 8b/-> *(ebp+0xc) 0/r32/eax
26083 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26084 (write-buffered *(ebp+0x10) %eax)
26085 (write-buffered *(ebp+0x10) ": stmt write-to-stream: too many inouts (2 required)\n")
26086 (flush *(ebp+0x10))
26087 (stop *(ebp+0x14) 1)
26090 $check-mu-write-to-stream-stmt:error-unexpected-output:
26091 (write-buffered *(ebp+0x10) "fn ")
26092 8b/-> *(ebp+0xc) 0/r32/eax
26093 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26094 (write-buffered *(ebp+0x10) %eax)
26095 (write-buffered *(ebp+0x10) ": stmt write-to-stream: unexpected output\n")
26096 (flush *(ebp+0x10))
26097 (stop *(ebp+0x14) 1)
26100 check-mu-convert-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
26103 89/<- %ebp 4/r32/esp
26110 $check-mu-convert-stmt:get-output:
26112 8b/-> *(ebp+8) 6/r32/esi
26113 # var output/edi: (addr stmt-var) = stmt->outputs
26114 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
26115 89/<- %edi 0/r32/eax
26117 3d/compare-eax-and 0/imm32
26118 0f 84/jump-if-= $check-mu-convert-stmt:error-no-output/disp32
26120 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
26121 3d/compare-eax-and 0/imm32
26122 0f 85/jump-if-!= $check-mu-convert-stmt:error-too-many-outputs/disp32
26123 $check-mu-convert-stmt:get-inout:
26124 # var inout/esi: (addr stmt-var) = stmt->inouts
26125 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
26126 89/<- %esi 0/r32/eax
26128 3d/compare-eax-and 0/imm32
26129 0f 84/jump-if-= $check-mu-convert-stmt:error-no-inout/disp32
26131 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
26132 3d/compare-eax-and 0/imm32
26133 0f 85/jump-if-!= $check-mu-convert-stmt:error-too-many-inouts/disp32
26134 $check-mu-convert-stmt:types:
26135 # var inout-type/ecx: (addr type-tree) = inout->value->type
26136 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
26137 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
26138 89/<- %ecx 0/r32/eax
26139 # if (inout->is-deref?) inout-type = inout-type->payload
26140 8b/-> *(esi+0x10) 0/r32/eax # Stmt-var-is-deref
26141 3d/compare-eax-and 0/imm32/false
26143 74/jump-if-= break/disp8
26144 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
26145 # if inout-type->right is null, t = inout-type->left
26146 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right
26148 75/jump-if-!= break/disp8
26149 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
26151 89/<- %ecx 0/r32/eax
26153 # if input is not int or float, abort
26155 (simple-mu-type? %ecx 1) # int => eax
26156 3d/compare-eax-and 0/imm32/false
26157 75/jump-if-!= break/disp8
26158 (simple-mu-type? %ecx 0xf) # float => eax
26159 3d/compare-eax-and 0/imm32/false
26160 75/jump-if-!= break/disp8
26161 e9/jump $check-mu-convert-stmt:error-invalid-inout-type/disp32
26163 # if output not in register, abort
26164 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
26165 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
26166 3d/compare-eax-and 0/imm32
26167 0f 84/jump-if-= $check-mu-convert-stmt:error-output-not-in-register/disp32
26168 # var output-type/edx: (addr type-tree) = output->value->type
26169 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
26170 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
26171 89/<- %edx 0/r32/eax
26172 # if output is not int or float, abort
26174 (simple-mu-type? %edx 1) # int => eax
26175 3d/compare-eax-and 0/imm32/false
26176 75/jump-if-!= break/disp8
26177 (simple-mu-type? %edx 0xf) # float => eax
26178 3d/compare-eax-and 0/imm32/false
26179 75/jump-if-!= break/disp8
26180 e9/jump $check-mu-convert-stmt:error-invalid-output-type/disp32
26182 # if both are ints, abort
26184 (simple-mu-type? %edx 1) # int => eax
26185 3d/compare-eax-and 0/imm32/false
26186 74/jump-if-= break/disp8
26187 (simple-mu-type? %ecx 1) # int => eax
26188 3d/compare-eax-and 0/imm32/false
26189 74/jump-if-= break/disp8
26190 e9/jump $check-mu-convert-stmt:error-int-to-int/disp32
26192 # if both are floats, abort
26194 (simple-mu-type? %edx 0xf) # float => eax
26195 3d/compare-eax-and 0/imm32/false
26196 74/jump-if-= break/disp8
26197 (simple-mu-type? %ecx 0xf) # float => eax
26198 3d/compare-eax-and 0/imm32/false
26199 74/jump-if-= break/disp8
26200 e9/jump $check-mu-convert-stmt:error-float-to-float/disp32
26202 $check-mu-convert-stmt:end:
26203 # . restore registers
26210 89/<- %esp 5/r32/ebp
26214 $check-mu-convert-stmt:error-no-inout:
26215 (write-buffered *(ebp+0x10) "fn ")
26216 8b/-> *(ebp+0xc) 0/r32/eax
26217 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26218 (write-buffered *(ebp+0x10) %eax)
26219 (write-buffered *(ebp+0x10) ": stmt 'convert' expects an inout\n")
26220 (flush *(ebp+0x10))
26221 (stop *(ebp+0x14) 1)
26224 $check-mu-convert-stmt:error-too-many-inouts:
26225 (write-buffered *(ebp+0x10) "fn ")
26226 8b/-> *(ebp+0xc) 0/r32/eax
26227 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26228 (write-buffered *(ebp+0x10) %eax)
26229 (write-buffered *(ebp+0x10) ": stmt 'convert' must have just one inout\n")
26230 (flush *(ebp+0x10))
26231 (stop *(ebp+0x14) 1)
26234 $check-mu-convert-stmt:error-no-output:
26235 (write-buffered *(ebp+0x10) "fn ")
26236 8b/-> *(ebp+0xc) 0/r32/eax
26237 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26238 (write-buffered *(ebp+0x10) %eax)
26239 (write-buffered *(ebp+0x10) ": stmt 'convert' expects an output\n")
26240 (flush *(ebp+0x10))
26241 (stop *(ebp+0x14) 1)
26244 $check-mu-convert-stmt:error-output-not-in-register:
26245 (write-buffered *(ebp+0x10) "fn ")
26246 8b/-> *(ebp+0xc) 0/r32/eax
26247 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26248 (write-buffered *(ebp+0x10) %eax)
26249 (write-buffered *(ebp+0x10) ": stmt convert: output '")
26250 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
26251 (lookup *eax *(eax+4)) # Var-name Var-name => eax
26252 (write-buffered *(ebp+0x10) %eax)
26253 (write-buffered *(ebp+0x10) "' not in a register\n")
26254 (flush *(ebp+0x10))
26255 (stop *(ebp+0x14) 1)
26258 $check-mu-convert-stmt:error-too-many-outputs:
26259 (write-buffered *(ebp+0x10) "fn ")
26260 8b/-> *(ebp+0xc) 0/r32/eax
26261 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26262 (write-buffered *(ebp+0x10) %eax)
26263 (write-buffered *(ebp+0x10) ": stmt 'convert' must have just one output\n")
26264 (flush *(ebp+0x10))
26265 (stop *(ebp+0x14) 1)
26268 $check-mu-convert-stmt:error-invalid-inout-type:
26269 (write-buffered *(ebp+0x10) "fn ")
26270 8b/-> *(ebp+0xc) 0/r32/eax
26271 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26272 (write-buffered *(ebp+0x10) %eax)
26273 (write-buffered *(ebp+0x10) ": stmt convert: inout '")
26274 (lookup *esi *(esi+4)) # Stmt-var-value Stmt-var-value => eax
26275 (lookup *eax *(eax+4)) # Var-name Var-name => eax
26276 (write-buffered *(ebp+0x10) %eax)
26277 (write-buffered *(ebp+0x10) "' must be an int or float\n")
26278 (flush *(ebp+0x10))
26279 (stop *(ebp+0x14) 1)
26282 $check-mu-convert-stmt:error-invalid-output-type:
26283 (write-buffered *(ebp+0x10) "fn ")
26284 8b/-> *(ebp+0xc) 0/r32/eax
26285 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26286 (write-buffered *(ebp+0x10) %eax)
26287 (write-buffered *(ebp+0x10) ": stmt convert: output '")
26288 (lookup *edi *(edi+4)) # Stmt-var-value Stmt-var-value => eax
26289 (lookup *eax *(eax+4)) # Var-name Var-name => eax
26290 (write-buffered *(ebp+0x10) %eax)
26291 (write-buffered *(ebp+0x10) "' must be an int or float\n")
26292 (flush *(ebp+0x10))
26293 (stop *(ebp+0x14) 1)
26296 $check-mu-convert-stmt:error-int-to-int:
26297 (write-buffered *(ebp+0x10) "fn ")
26298 8b/-> *(ebp+0xc) 0/r32/eax
26299 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26300 (write-buffered *(ebp+0x10) %eax)
26301 (write-buffered *(ebp+0x10) ": stmt convert: no need to convert int to int\n")
26302 (flush *(ebp+0x10))
26303 (stop *(ebp+0x14) 1)
26306 $check-mu-convert-stmt:error-float-to-float:
26307 (write-buffered *(ebp+0x10) "fn ")
26308 8b/-> *(ebp+0xc) 0/r32/eax
26309 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26310 (write-buffered *(ebp+0x10) %eax)
26311 (write-buffered *(ebp+0x10) ": stmt convert: no need to convert float to float\n")
26312 (flush *(ebp+0x10))
26313 (stop *(ebp+0x14) 1)
26316 check-mu-call: # stmt: (addr stmt), callee: (addr function), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
26319 89/<- %ebp 4/r32/esp
26320 # var type-parameters: (addr table (handle array byte) (addr type-tree) 8)
26322 # var type-parameters-storage: (table (handle array byte) (addr type-tree) 8)
26323 81 5/subop/subtract %esp 0x60/imm32
26324 68/push 0x60/imm32/size
26325 68/push 0/imm32/read
26326 68/push 0/imm32/write
26327 # save a pointer to type-parameters-storage at type-parameters
26328 89/<- *(ebp-4) 4/r32/esp
26329 (clear-stream *(ebp-4))
26338 8b/-> *(ebp+8) 6/r32/esi
26340 8b/-> *(ebp+0xc) 7/r32/edi
26341 # var inouts/ecx: (addr stmt-var) = lookup(stmt->inouts)
26342 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
26343 89/<- %ecx 0/r32/eax
26344 # var expected/edx: (addr list var) = lookup(f->inouts)
26345 (lookup *(edi+8) *(edi+0xc)) # Function-inouts Function-inouts => eax
26346 89/<- %edx 0/r32/eax
26348 $check-mu-call:check-for-inouts:
26349 # if (inouts == 0) break
26350 81 7/subop/compare %ecx 0/imm32
26351 0f 84/jump-if-= break/disp32
26352 # if (expected == 0) error
26353 81 7/subop/compare %edx 0/imm32
26354 0f 84/jump-if-= break/disp32
26355 $check-mu-call:check-null-addr:
26356 # if (inouts->value->name == "0") continue
26357 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
26358 (lookup *eax *(eax+4)) # Var-name Var-name => eax
26359 (string-equal? %eax "0") # => eax
26360 3d/compare-eax-and 0/imm32/false
26361 0f 85/jump-if-!= $check-mu-call:continue-to-next-inout/disp32
26362 $check-mu-call:check-inout-type:
26363 # var t/ebx: (addr type-tree) = inouts->value->type
26364 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
26365 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
26366 89/<- %ebx 0/r32/eax
26367 # if (inouts->is-deref?) t = t->right
26368 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref
26370 74/jump-if-= break/disp8
26371 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
26372 89/<- %ebx 0/r32/eax
26373 # if t->right is null, t = t->left
26374 81 7/subop/compare *(ebx+0xc) 0/imm32 # Type-tree-right
26375 75/jump-if-!= break/disp8
26376 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax
26377 89/<- %ebx 0/r32/eax
26379 # var v2/eax: (addr v) = lookup(expected->value)
26380 (lookup *edx *(edx+4)) # List-value List-value => eax
26381 # var t2/eax: (addr type-tree) = lookup(v2->type)
26382 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
26383 # if (t != t2) error
26384 (type-match? %eax %ebx *(ebp-4)) # => eax
26385 3d/compare-eax-and 0/imm32/false
26387 0f 85/jump-if-!= break/disp32
26388 (write-buffered *(ebp+0x14) "fn ")
26389 8b/-> *(ebp+0x10) 0/r32/eax
26390 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26391 (write-buffered *(ebp+0x14) %eax)
26392 (write-buffered *(ebp+0x14) ": call ")
26393 (lookup *edi *(edi+4)) # Function-name Function-name => eax
26394 (write-buffered *(ebp+0x14) %eax)
26395 (write-buffered *(ebp+0x14) ": type for inout '")
26396 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
26397 (lookup *eax *(eax+4)) # Var-name Var-name => eax
26398 (write-buffered *(ebp+0x14) %eax)
26399 (write-buffered *(ebp+0x14) "' is not right\n")
26400 (flush *(ebp+0x14))
26401 (stop *(ebp+0x18) 1)
26403 $check-mu-call:continue-to-next-inout:
26404 # inouts = lookup(inouts->next)
26405 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax
26406 89/<- %ecx 0/r32/eax
26407 # expected = lookup(expected->next)
26408 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax
26409 89/<- %edx 0/r32/eax
26411 e9/jump loop/disp32
26413 $check-mu-call:check-inout-count:
26414 # if (inouts == expected) proceed
26415 39/compare %ecx 2/r32/edx
26417 0f 84/jump-if-= break/disp32
26418 # exactly one of the two is null
26419 # if (inouts == 0) error("too many inouts")
26421 81 7/subop/compare %ecx 0/imm32
26422 0f 84/jump-if-= break/disp32
26423 (write-buffered *(ebp+0x14) "fn ")
26424 8b/-> *(ebp+0x10) 0/r32/eax
26425 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26426 (write-buffered *(ebp+0x14) %eax)
26427 (write-buffered *(ebp+0x14) ": call ")
26428 (lookup *edi *(edi+4)) # Function-name Function-name => eax
26429 (write-buffered *(ebp+0x14) %eax)
26430 (write-buffered *(ebp+0x14) ": too many inouts\n")
26431 (flush *(ebp+0x14))
26432 (stop *(ebp+0x18) 1)
26434 # if (expected == 0) error("too few inouts")
26436 81 7/subop/compare %edx 0/imm32
26437 0f 84/jump-if-= break/disp32
26438 (write-buffered *(ebp+0x14) "fn ")
26439 8b/-> *(ebp+0x10) 0/r32/eax
26440 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26441 (write-buffered *(ebp+0x14) %eax)
26442 (write-buffered *(ebp+0x14) ": call ")
26443 (lookup *edi *(edi+4)) # Function-name Function-name => eax
26444 (write-buffered *(ebp+0x14) %eax)
26445 (write-buffered *(ebp+0x14) ": too few inouts\n")
26446 (flush *(ebp+0x14))
26447 (stop *(ebp+0x18) 1)
26450 $check-mu-call:check-outputs:
26451 # var outputs/ecx: (addr stmt-var) = lookup(stmt->outputs)
26452 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
26453 89/<- %ecx 0/r32/eax
26454 # var expected/edx: (addr list var) = lookup(f->outputs)
26455 (lookup *(edi+0x10) *(edi+0x14)) # Function-outputs Function-outputs => eax
26456 89/<- %edx 0/r32/eax
26458 $check-mu-call:check-for-outputs:
26459 # if (outputs == 0) break
26460 81 7/subop/compare %ecx 0/imm32
26461 0f 84/jump-if-= break/disp32
26462 # if (expected == 0) error
26463 81 7/subop/compare %edx 0/imm32
26464 0f 84/jump-if-= break/disp32
26465 $check-mu-call:check-output-type:
26466 # var v/eax: (addr v) = lookup(outputs->value)
26467 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
26468 # var t/ebx: (addr type-tree) = lookup(v->type)
26469 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
26470 89/<- %ebx 0/r32/eax
26471 # if (outputs->is-deref?) t = t->right # TODO: check that t->left is an addr
26472 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref
26474 74/jump-if-= break/disp8
26475 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
26476 89/<- %ebx 0/r32/eax
26478 # var v2/eax: (addr v) = lookup(expected->value)
26479 (lookup *edx *(edx+4)) # List-value List-value => eax
26480 # var t2/eax: (addr type-tree) = lookup(v2->type)
26481 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
26482 # if (t != t2) error
26483 (type-match? %eax %ebx *(ebp-4)) # => eax
26484 3d/compare-eax-and 0/imm32/false
26486 0f 85/jump-if-!= break/disp32
26487 (write-buffered *(ebp+0x14) "fn ")
26488 8b/-> *(ebp+0x10) 0/r32/eax
26489 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26490 (write-buffered *(ebp+0x14) %eax)
26491 (write-buffered *(ebp+0x14) ": call ")
26492 (lookup *edi *(edi+4)) # Function-name Function-name => eax
26493 (write-buffered *(ebp+0x14) %eax)
26494 (write-buffered *(ebp+0x14) ": type for output '")
26495 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
26496 (lookup *eax *(eax+4)) # Var-name Var-name => eax
26497 (write-buffered *(ebp+0x14) %eax)
26498 (write-buffered *(ebp+0x14) "' is not right\n")
26499 (flush *(ebp+0x14))
26500 (stop *(ebp+0x18) 1)
26502 $check-mu-call:check-output-register:
26503 # var v/eax: (addr v) = lookup(outputs->value)
26504 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
26505 # var r/ebx: (addr array byte) = lookup(v->register)
26506 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax
26507 89/<- %ebx 0/r32/eax
26508 # if (r == 0) error
26509 3d/compare-eax-and 0/imm32
26511 0f 85/jump-if-!= break/disp32
26512 (write-buffered *(ebp+0x14) "fn ")
26513 8b/-> *(ebp+0x10) 0/r32/eax
26514 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26515 (write-buffered *(ebp+0x14) %eax)
26516 (write-buffered *(ebp+0x14) ": call ")
26517 (lookup *edi *(edi+4)) # Function-name Function-name => eax
26518 (write-buffered *(ebp+0x14) %eax)
26519 (write-buffered *(ebp+0x14) ": output '")
26520 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
26521 (lookup *eax *(eax+4)) # Var-name Var-name => eax
26522 (write-buffered *(ebp+0x14) %eax)
26523 (write-buffered *(ebp+0x14) "' is not in a register\n")
26524 (flush *(ebp+0x14))
26525 (stop *(ebp+0x18) 1)
26527 # var v2/eax: (addr v) = lookup(expected->value)
26528 (lookup *edx *(edx+4)) # Stmt-var-value Stmt-var-value => eax
26529 # var r2/eax: (addr array byte) = lookup(v2->register)
26530 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax
26531 # if (r != r2) error
26532 (string-equal? %eax %ebx) # => eax
26533 3d/compare-eax-and 0/imm32/false
26535 0f 85/jump-if-!= break/disp32
26536 (write-buffered *(ebp+0x14) "fn ")
26537 8b/-> *(ebp+0x10) 0/r32/eax
26538 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26539 (write-buffered *(ebp+0x14) %eax)
26540 (write-buffered *(ebp+0x14) ": call ")
26541 (lookup *edi *(edi+4)) # Function-name Function-name => eax
26542 (write-buffered *(ebp+0x14) %eax)
26543 (write-buffered *(ebp+0x14) ": register for output '")
26544 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
26545 (lookup *eax *(eax+4)) # Var-name Var-name => eax
26546 (write-buffered *(ebp+0x14) %eax)
26547 (write-buffered *(ebp+0x14) "' is not right\n")
26548 (flush *(ebp+0x14))
26549 (stop *(ebp+0x18) 1)
26551 $check-mu-call:continue-to-next-output:
26552 # outputs = lookup(outputs->next)
26553 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax
26554 89/<- %ecx 0/r32/eax
26555 # expected = lookup(expected->next)
26556 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax
26557 89/<- %edx 0/r32/eax
26559 e9/jump loop/disp32
26561 $check-mu-call:check-output-count:
26562 # if (outputs == expected) proceed
26563 39/compare %ecx 2/r32/edx
26565 0f 84/jump-if-= break/disp32
26566 # exactly one of the two is null
26567 # if (outputs == 0) error("too many outputs")
26569 81 7/subop/compare %ecx 0/imm32
26570 0f 84/jump-if-= break/disp32
26571 (write-buffered *(ebp+0x14) "fn ")
26572 8b/-> *(ebp+0x10) 0/r32/eax
26573 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26574 (write-buffered *(ebp+0x14) %eax)
26575 (write-buffered *(ebp+0x14) ": call ")
26576 (lookup *edi *(edi+4)) # Function-name Function-name => eax
26577 (write-buffered *(ebp+0x14) %eax)
26578 (write-buffered *(ebp+0x14) ": too many outputs\n")
26579 (flush *(ebp+0x14))
26580 (stop *(ebp+0x18) 1)
26582 # if (expected == 0) error("too few outputs")
26584 81 7/subop/compare %edx 0/imm32
26585 0f 84/jump-if-= break/disp32
26586 (write-buffered *(ebp+0x14) "fn ")
26587 8b/-> *(ebp+0x10) 0/r32/eax
26588 (lookup *eax *(eax+4)) # Function-name Function-name => eax
26589 (write-buffered *(ebp+0x14) %eax)
26590 (write-buffered *(ebp+0x14) ": call ")
26591 (lookup *edi *(edi+4)) # Function-name Function-name => eax
26592 (write-buffered *(ebp+0x14) %eax)
26593 (write-buffered *(ebp+0x14) ": too few outputs\n")
26594 (flush *(ebp+0x14))
26595 (stop *(ebp+0x18) 1)
26598 $check-mu-call:end:
26599 # . restore registers
26606 # . reclaim locals exclusively on the stack
26607 81 0/subop/add %esp 0x70/imm32
26609 89/<- %esp 5/r32/ebp
26613 # like type-equal? but takes literals type parameters into account
26614 type-match?: # def: (addr type-tree), call: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean
26617 89/<- %ebp 4/r32/esp
26618 # if call is literal and def is numberlike, return true
26620 $type-match?:check-literal-int:
26621 (simple-mu-type? *(ebp+0xc) 0) # literal => eax
26622 3d/compare-eax-and 0/imm32/false
26623 74/jump-if-= break/disp8
26624 (mu-numberlike-output? *(ebp+8)) # => eax
26625 3d/compare-eax-and 0/imm32/false
26626 74/jump-if-= break/disp8
26627 b8/copy-to-eax 1/imm32/true
26628 e9/jump $type-match?:end/disp32
26630 # if call is literal-string, match against (addr array byte)
26632 $type-match?:check-literal-string:
26633 (simple-mu-type? *(ebp+0xc) 0x10) # literal-string => eax
26634 3d/compare-eax-and 0/imm32/false
26635 74/jump-if-= break/disp8
26636 (type-component-match? *(ebp+8) Addr-type-string *(ebp+0x10)) # => eax
26637 e9/jump $type-match?:end/disp32
26639 $type-match?:baseline:
26640 # otherwise fall back
26641 (type-component-match? *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax
26644 89/<- %esp 5/r32/ebp
26648 type-component-match?: # def: (addr type-tree), call: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean
26651 89/<- %ebp 4/r32/esp
26657 8b/-> *(ebp+8) 1/r32/ecx
26659 8b/-> *(ebp+0xc) 2/r32/edx
26660 $type-component-match?:compare-addr:
26661 # if (def == call) return true
26662 8b/-> %ecx 0/r32/eax # Var-type
26663 39/compare %edx 0/r32/eax # Var-type
26664 b8/copy-to-eax 1/imm32/true
26665 0f 84/jump-if-= $type-component-match?:end/disp32
26666 # if (def == 0) return false
26667 b8/copy-to-eax 0/imm32/false
26668 81 7/subop/compare %ecx 0/imm32 # Type-tree-is-atom
26669 0f 84/jump-if-= $type-component-match?:end/disp32
26670 # if (call == 0) return false
26671 81 7/subop/compare %edx 0/imm32 # Type-tree-is-atom
26672 0f 84/jump-if-= $type-component-match?:end/disp32
26673 # if def is a type parameter, just check in type-parameters
26675 $type-component-match?:check-type-parameter:
26676 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom
26677 74/jump-if-= break/disp8
26678 81 7/subop/compare *(ecx+4) 0xa/imm32/type-parameter # Type-tree-value
26679 75/jump-if-!= break/disp8
26680 $type-component-match?:type-parameter:
26681 (type-parameter-match? *(ecx+8) *(ecx+0xc) %edx *(ebp+0x10)) # => eax
26682 e9/jump $type-component-match?:end/disp32
26684 # if def is a list containing just a type parameter, just check in type-parameters
26686 $type-component-match?:check-list-type-parameter:
26687 # if def is a list..
26688 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom
26689 75/jump-if-!= break/disp8
26690 # ..that's a singleton
26691 81 7/subop/compare *(ecx+0xc) 0/imm32 # Type-tree-left
26692 75/jump-if-!= break/disp8
26693 # ..and whose head is a type parameter
26694 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
26695 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
26696 74/jump-if-= break/disp8
26697 81 7/subop/compare *(eax+4) 0xa/imm32/type-parameter # Type-tree-value
26698 75/jump-if-!= break/disp8
26699 $type-component-match?:list-type-parameter:
26700 (type-parameter-match? *(eax+8) *(eax+0xc) %edx *(ebp+0x10)) # => eax
26701 e9/jump $type-component-match?:end/disp32
26703 $type-component-match?:compare-atom-state:
26704 # if (def->is-atom? != call->is-atom?) return false
26705 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom
26706 39/compare *edx 3/r32/ebx # Type-tree-is-atom
26707 b8/copy-to-eax 0/imm32/false
26708 0f 85/jump-if-!= $type-component-match?:end/disp32
26709 # if def->is-atom? return (def->value == call->value)
26711 $type-component-match?:check-atom:
26712 81 7/subop/compare %ebx 0/imm32/false
26713 74/jump-if-= break/disp8
26714 $type-component-match?:is-atom:
26715 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value
26716 39/compare *(edx+4) 0/r32/eax # Type-tree-value
26718 25/and-eax-with 0xff/imm32
26719 e9/jump $type-component-match?:end/disp32
26721 $type-component-match?:check-left:
26722 # if (!type-component-match?(def->left, call->left)) return false
26723 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
26724 89/<- %ebx 0/r32/eax
26725 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax
26726 (type-component-match? %ebx %eax *(ebp+0x10)) # => eax
26727 3d/compare-eax-and 0/imm32/false
26728 74/jump-if-= $type-component-match?:end/disp8
26729 $type-component-match?:check-right:
26730 # return type-component-match?(def->right, call->right)
26731 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
26732 89/<- %ebx 0/r32/eax
26733 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax
26734 (type-component-match? %ebx %eax *(ebp+0x10)) # => eax
26735 $type-component-match?:end:
26736 # . restore registers
26741 89/<- %esp 5/r32/ebp
26745 type-parameter-match?: # type-parameter-name: (handle array byte), type: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean
26748 89/<- %ebp 4/r32/esp
26752 (get-or-insert-handle *(ebp+0x14) *(ebp+8) *(ebp+0xc) 0xc) # => eax
26753 # if parameter wasn't saved, save it
26755 81 7/subop/compare *eax 0/imm32
26756 75/jump-if-!= break/disp8
26757 8b/-> *(ebp+0x10) 1/r32/ecx
26758 89/<- *eax 1/r32/ecx
26761 (type-equal? *(ebp+0x10) *eax) # => eax
26762 $type-parameter-match?:end:
26763 # . restore registers
26766 89/<- %esp 5/r32/ebp
26770 size-of: # v: (addr var) -> result/eax: int
26773 89/<- %ebp 4/r32/esp
26776 # var t/ecx: (addr type-tree) = lookup(v->type)
26777 8b/-> *(ebp+8) 1/r32/ecx
26778 #? (write-buffered Stderr "size-of ")
26779 #? (write-int32-hex-buffered Stderr %ecx)
26780 #? (write-buffered Stderr Newline)
26781 #? (write-buffered Stderr "type allocid: ")
26782 #? (write-int32-hex-buffered Stderr *(ecx+8))
26783 #? (write-buffered Stderr Newline)
26785 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
26786 89/<- %ecx 0/r32/eax
26787 # if mu-array?(t) return size-of-array(t)
26789 (mu-array? %ecx) # => eax
26790 3d/compare-eax-and 0/imm32/false
26791 74/jump-if-= break/disp8
26792 (size-of-array %ecx) # => eax
26793 eb/jump $size-of:end/disp8
26795 # if mu-stream?(t) return size-of-stream(t)
26797 (mu-stream? %ecx) # => eax
26798 3d/compare-eax-and 0/imm32/false
26799 74/jump-if-= break/disp8
26800 (size-of-stream %ecx) # => eax
26801 eb/jump $size-of:end/disp8
26803 # if (!t->is-atom?) t = lookup(t->left)
26805 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom
26806 75/jump-if-!= break/disp8
26807 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
26808 89/<- %ecx 0/r32/eax
26810 # TODO: assert t->is-atom?
26811 (size-of-type-id *(ecx+4)) # Type-tree-value => eax
26813 # . restore registers
26816 89/<- %esp 5/r32/ebp
26820 size-of-deref: # v: (addr var) -> result/eax: int
26823 89/<- %ebp 4/r32/esp
26826 # var t/ecx: (addr type-tree) = lookup(v->type)
26827 8b/-> *(ebp+8) 1/r32/ecx
26828 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
26829 89/<- %ecx 0/r32/eax
26830 # TODO: assert(t is an addr)
26831 # t = lookup(t->right)
26832 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
26833 89/<- %ecx 0/r32/eax
26834 # if mu-array?(t) return size-of-array(t)
26836 (mu-array? %ecx) # => eax
26837 3d/compare-eax-and 0/imm32/false
26838 74/jump-if-= break/disp8
26839 (size-of-array %ecx) # => eax
26840 eb/jump $size-of-deref:end/disp8
26842 # if mu-stream?(t) return size-of-stream(t)
26844 (mu-stream? %ecx) # => eax
26845 3d/compare-eax-and 0/imm32/false
26846 74/jump-if-= break/disp8
26847 (size-of-stream %ecx) # => eax
26848 eb/jump $size-of-deref:end/disp8
26850 # if (!t->is-atom?) t = lookup(t->left)
26852 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom
26853 75/jump-if-!= break/disp8
26854 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
26855 89/<- %ecx 0/r32/eax
26857 # TODO: assert t->is-atom?
26858 (size-of-type-id *(ecx+4)) # Type-tree-value => eax
26859 $size-of-deref:end:
26860 # . restore registers
26863 89/<- %esp 5/r32/ebp
26867 mu-array?: # t: (addr type-tree) -> result/eax: boolean
26870 89/<- %ebp 4/r32/esp
26874 8b/-> *(ebp+8) 1/r32/ecx
26875 # if t->is-atom?, return false
26876 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom
26877 75/jump-if-!= $mu-array?:return-false/disp8
26878 # if !t->left->is-atom?, return false
26879 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
26880 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
26881 74/jump-if-= $mu-array?:return-false/disp8
26882 # return t->left->value == array
26883 81 7/subop/compare *(eax+4) 3/imm32/array-type-id # Type-tree-value
26885 25/and-eax-with 0xff/imm32
26886 eb/jump $mu-array?:end/disp8
26887 $mu-array?:return-false:
26888 b8/copy-to-eax 0/imm32/false
26890 # . restore registers
26893 89/<- %esp 5/r32/ebp
26897 # size of a statically allocated array where the size is part of the type expression
26898 size-of-array: # a: (addr type-tree) -> result/eax: int
26901 89/<- %ebp 4/r32/esp
26906 8b/-> *(ebp+8) 1/r32/ecx
26907 # TODO: assert that a->left is 'array'
26908 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
26909 89/<- %ecx 0/r32/eax
26910 # var elem-type/edx: type-id = a->right->left->value
26911 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
26912 8b/-> *(eax+4) 2/r32/edx # Type-tree-value
26913 # TODO: assert that a->right->right->left->value == size
26914 # var array-size/ecx: int = a->right->right->left->value-size
26915 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
26916 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
26917 8b/-> *(eax+8) 1/r32/ecx # Type-tree-value-size
26918 # return 4 + array-size * size-of(elem-type)
26919 (size-of-type-id-as-array-element %edx) # => eax
26920 f7 4/subop/multiply-into-edx-eax %ecx
26921 05/add-to-eax 4/imm32 # for array size
26922 # TODO: check edx for overflow
26923 $size-of-array:end:
26924 # . restore registers
26928 89/<- %esp 5/r32/ebp
26932 mu-stream?: # t: (addr type-tree) -> result/eax: boolean
26935 89/<- %ebp 4/r32/esp
26939 8b/-> *(ebp+8) 1/r32/ecx
26940 # if t->is-atom?, return false
26941 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom
26942 75/jump-if-!= $mu-stream?:return-false/disp8
26943 # if !t->left->is-atom?, return false
26944 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
26945 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
26946 74/jump-if-= $mu-stream?:return-false/disp8
26947 # return t->left->value == stream
26948 81 7/subop/compare *(eax+4) 0xb/imm32/stream-type-id # Type-tree-value
26950 25/and-eax-with 0xff/imm32
26951 eb/jump $mu-stream?:end/disp8
26952 $mu-stream?:return-false:
26953 b8/copy-to-eax 0/imm32/false
26955 # . restore registers
26958 89/<- %esp 5/r32/ebp
26962 # size of a statically allocated stream where the size is part of the type expression
26963 size-of-stream: # a: (addr type-tree) -> result/eax: int
26966 89/<- %ebp 4/r32/esp
26968 (size-of-array *(ebp+8)) # assumes we ignore the actual type name 'array' in the type
26969 05/add-to-eax 8/imm32 # for read/write pointers
26970 $size-of-stream:end:
26972 89/<- %esp 5/r32/ebp
26976 size-of-type-id: # t: type-id -> result/eax: int
26979 89/<- %ebp 4/r32/esp
26982 # var out/ecx: (handle typeinfo)
26985 89/<- %ecx 4/r32/esp
26987 8b/-> *(ebp+8) 0/r32/eax
26988 # if t is a literal, return 0
26989 3d/compare-eax-and 0/imm32
26990 0f 84/jump-if-= $size-of-type-id:end/disp32 # eax changes type from type-id to int
26991 # if t is a byte, return 4 (because we don't really support non-multiples of 4)
26992 3d/compare-eax-and 8/imm32/byte
26994 75/jump-if-!= break/disp8
26995 b8/copy-to-eax 4/imm32
26996 eb/jump $size-of-type-id:end/disp8
26998 # if t is a handle, return 8
26999 3d/compare-eax-and 4/imm32/handle
27001 75/jump-if-!= break/disp8
27002 b8/copy-to-eax 8/imm32
27003 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int
27005 # if t is a slice, return 8
27006 3d/compare-eax-and 0xc/imm32/slice
27008 75/jump-if-!= break/disp8
27009 b8/copy-to-eax 8/imm32
27010 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int
27012 # if t is a user-defined type, return its size
27013 # TODO: support non-atom type
27014 (find-typeinfo %eax %ecx)
27016 81 7/subop/compare *ecx 0/imm32
27017 74/jump-if-= break/disp8
27018 $size-of-type-id:user-defined:
27019 (lookup *ecx *(ecx+4)) # => eax
27020 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes
27021 eb/jump $size-of-type-id:end/disp8
27023 # otherwise return the word size
27024 b8/copy-to-eax 4/imm32
27025 $size-of-type-id:end:
27027 81 0/subop/add %esp 8/imm32
27028 # . restore registers
27031 89/<- %esp 5/r32/ebp
27035 # Minor violation of our type system since it returns an addr. But we could
27036 # replace it with a handle some time.
27037 # Returns null if t is an atom.
27038 type-tail: # t: (addr type-tree) -> out/eax: (addr type-tree)
27041 89/<- %ebp 4/r32/esp
27045 b8/copy-to-eax 0/imm32
27047 8b/-> *(ebp+8) 1/r32/ecx
27048 $type-tail:check-atom:
27049 # if t->is-atom? return 0
27050 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom
27051 0f 85/jump-if-!= $type-tail:end/disp32
27052 # var tail = t->right
27053 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
27054 89/<- %ecx 0/r32/eax
27055 $type-tail:check-singleton:
27056 # if (tail->right == 0) return tail->left
27058 81 7/subop/compare *(ecx+0xc) 0/imm32 # Type-tree-right
27059 75/jump-if-!= break/disp8
27060 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
27061 e9/jump $type-tail:end/disp32
27063 # if tail->right->left is an array-capacity, return tail->left
27065 $type-tail:check-array-capacity:
27066 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
27067 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
27068 75/jump-if-!= break/disp8
27069 $type-tail:check-array-capacity-1:
27070 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
27071 3d/compare-eax-and 0/imm32
27072 74/jump-if-= break/disp8
27073 $type-tail:check-array-capacity-2:
27074 (simple-mu-type? %eax 9) # array-capacity => eax
27075 3d/compare-eax-and 0/imm32/false
27076 74/jump-if-= break/disp8
27077 $type-tail:array-capacity:
27078 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
27079 eb/jump $type-tail:end/disp8
27081 $type-tail:check-compound-left:
27082 # if !tail->left->is-atom? return tail->left
27083 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
27084 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
27085 74/jump-if-= $type-tail:end/disp8
27086 $type-tail:return-tail:
27088 89/<- %eax 1/r32/ecx
27090 # . restore registers
27093 89/<- %esp 5/r32/ebp
27097 type-equal?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean
27100 89/<- %ebp 4/r32/esp
27106 8b/-> *(ebp+8) 1/r32/ecx
27108 8b/-> *(ebp+0xc) 2/r32/edx
27109 $type-equal?:compare-addr:
27110 # if (a == b) return true
27111 8b/-> %ecx 0/r32/eax # Var-type
27112 39/compare %edx 0/r32/eax # Var-type
27113 b8/copy-to-eax 1/imm32/true
27114 0f 84/jump-if-= $type-equal?:end/disp32
27115 $type-equal?:compare-null-a:
27116 # if (a == 0) return false
27117 b8/copy-to-eax 0/imm32/false
27118 81 7/subop/compare %ecx 0/imm32
27119 0f 84/jump-if-= $type-equal?:end/disp32
27120 $type-equal?:compare-null-b:
27121 # if (b == 0) return false
27122 81 7/subop/compare %edx 0/imm32
27123 0f 84/jump-if-= $type-equal?:end/disp32
27124 $type-equal?:compare-atom-state:
27125 # if (a->is-atom? != b->is-atom?) return false
27126 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom
27127 39/compare *edx 3/r32/ebx # Type-tree-is-atom
27128 b8/copy-to-eax 0/imm32/false
27129 0f 85/jump-if-!= $type-equal?:end/disp32
27130 # if a->is-atom? return (a->value == b->value)
27132 $type-equal?:check-atom:
27133 81 7/subop/compare %ebx 0/imm32/false
27134 74/jump-if-= break/disp8
27135 $type-equal?:is-atom:
27136 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value
27137 39/compare *(edx+4) 0/r32/eax # Type-tree-value
27139 25/and-eax-with 0xff/imm32
27140 e9/jump $type-equal?:end/disp32
27142 $type-equal?:check-left:
27143 # if (!type-equal?(a->left, b->left)) return false
27144 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax
27145 89/<- %ebx 0/r32/eax
27146 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax
27147 (type-equal? %eax %ebx) # => eax
27148 3d/compare-eax-and 0/imm32/false
27149 74/jump-if-= $type-equal?:end/disp8
27150 $type-equal?:check-right:
27151 # return type-equal?(a->right, b->right)
27152 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax
27153 89/<- %ebx 0/r32/eax
27154 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax
27155 (type-equal? %eax %ebx) # => eax
27157 # . restore registers
27162 89/<- %esp 5/r32/ebp
27166 #######################################################
27168 #######################################################
27172 # Global state added to each var record when performing code-generation.
27173 Curr-local-stack-offset: # (addr int)
27178 # We may not need to pass err/ed everywhere here. I think they're relics of Mu
27179 # getting type checks later in life.
27180 # But we do need them for runtime checks, particularly array index bounds checks.
27181 # So perhaps it's not worth taking them out. They're a safety net.
27183 emit-subx: # out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor)
27186 89/<- %ebp 4/r32/esp
27189 # var curr/eax: (addr function) = *Program->functions
27190 (lookup *_Program-functions *_Program-functions->payload) # => eax
27192 # if (curr == null) break
27193 3d/compare-eax-and 0/imm32
27194 0f 84/jump-if-= break/disp32
27195 (emit-subx-function *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10))
27196 # curr = lookup(curr->next)
27197 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax
27198 e9/jump loop/disp32
27201 # . restore registers
27204 89/<- %esp 5/r32/ebp
27208 emit-subx-function: # out: (addr buffered-file), f: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
27211 89/<- %ebp 4/r32/esp
27212 # some preprocessing
27213 (populate-mu-type-offsets-in-inouts *(ebp+0xc))
27218 # initialize some global state
27219 c7 0/subop/copy *Curr-block-depth 1/imm32 # Important: keep this in sync with the parse phase
27220 c7 0/subop/copy *Curr-local-stack-offset 0/imm32
27222 8b/-> *(ebp+0xc) 1/r32/ecx
27223 # var vars/edx: (stack (addr var) 256)
27224 81 5/subop/subtract %esp 0xc00/imm32
27225 68/push 0xc00/imm32/size
27226 68/push 0/imm32/top
27227 89/<- %edx 4/r32/esp
27228 # var name/eax: (addr array byte) = lookup(f->name)
27229 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax
27231 (write-buffered *(ebp+8) %eax)
27232 (write-buffered *(ebp+8) ":\n")
27233 (emit-subx-prologue *(ebp+8))
27234 # var body/eax: (addr block) = lookup(f->body)
27235 (lookup *(ecx+0x18) *(ecx+0x1c)) # Function-body Function-body => eax
27237 (emit-subx-block *(ebp+8) %eax %edx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
27238 (emit-subx-epilogue *(ebp+8))
27239 # TODO: validate that *Curr-block-depth and *Curr-local-stack-offset have
27241 $emit-subx-function:end:
27243 81 0/subop/add %esp 0xc08/imm32
27244 # . restore registers
27249 89/<- %esp 5/r32/ebp
27253 populate-mu-type-offsets-in-inouts: # f: (addr function)
27256 89/<- %ebp 4/r32/esp
27263 # var next-offset/edx: int = 8
27264 ba/copy-to-edx 8/imm32
27265 # var curr/ecx: (addr list var) = lookup(f->inouts)
27266 8b/-> *(ebp+8) 1/r32/ecx
27267 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax
27268 89/<- %ecx 0/r32/eax
27270 $populate-mu-type-offsets-in-inouts:loop:
27271 81 7/subop/compare %ecx 0/imm32
27272 74/jump-if-= break/disp8
27273 # var v/ebx: (addr var) = lookup(curr->value)
27274 (lookup *ecx *(ecx+4)) # List-value List-value => eax
27275 89/<- %ebx 0/r32/eax
27276 #? (lookup *ebx *(ebx+4))
27277 #? (write-buffered Stderr "setting offset of fn inout ")
27278 #? (write-buffered Stderr %eax)
27279 #? (write-buffered Stderr "@")
27280 #? (write-int32-hex-buffered Stderr %ebx)
27281 #? (write-buffered Stderr " to ")
27282 #? (write-int32-hex-buffered Stderr %edx)
27283 #? (write-buffered Stderr Newline)
27285 # v->offset = next-offset
27286 89/<- *(ebx+0x14) 2/r32/edx # Var-offset
27287 # next-offset += size-of(v)
27288 (size-of %ebx) # => eax
27289 01/add-to %edx 0/r32/eax
27290 # curr = lookup(curr->next)
27291 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax
27292 89/<- %ecx 0/r32/eax
27296 $populate-mu-type-offsets-in-inouts:end:
27297 # . restore registers
27304 89/<- %esp 5/r32/ebp
27308 emit-subx-stmt-list: # out: (addr buffered-file), stmts: (addr list stmt), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
27311 89/<- %ebp 4/r32/esp
27318 8b/-> *(ebp+0xc) 6/r32/esi
27321 $emit-subx-stmt-list:loop:
27322 81 7/subop/compare %esi 0/imm32
27323 0f 84/jump-if-= break/disp32
27324 # var curr-stmt/ecx: (addr stmt) = lookup(stmts->value)
27325 (lookup *esi *(esi+4)) # List-value List-value => eax
27326 89/<- %ecx 0/r32/eax
27328 $emit-subx-stmt-list:check-for-block:
27329 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag
27330 75/jump-if-!= break/disp8
27331 $emit-subx-stmt-list:block:
27332 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c))
27335 $emit-subx-stmt-list:check-for-stmt:
27336 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag
27337 0f 85/jump-if-!= break/disp32
27338 $emit-subx-stmt-list:stmt1:
27340 (mu-branch? %ecx) # => eax
27341 3d/compare-eax-and 0/imm32/false
27342 0f 84/jump-if-= break/disp32
27343 $emit-subx-stmt-list:branch-stmt:
27344 # unconditional return {{{
27346 $emit-subx-stmt-list:return:
27347 # if (!string-equal?(curr-stmt->operation, "return")) break
27348 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax
27349 (string-equal? %eax "return") # => eax
27350 3d/compare-eax-and 0/imm32/false
27351 0f 84/jump-if-= break/disp32
27353 (emit-outputs *(ebp+8) %ecx *(ebp+0x14))
27354 (emit-cleanup-code-for-non-outputs *(ebp+8) *(ebp+0x10) *(ebp+0x14))
27355 # emit jump to end of function
27356 # getting at the name of the label is challenging
27357 (emit-indent *(ebp+8) *Curr-block-depth)
27358 (write-buffered *(ebp+8) "e9/jump ")
27359 # var b/eax: (addr array byte) = fn->body->var->name
27360 8b/-> *(ebp+0x14) 0/r32/eax
27361 (lookup *(eax+0x18) *(eax+0x1c)) # Function-body Function-body => eax
27362 (lookup *(eax+0xc) *(eax+0x10)) # Block-var Block-var => eax
27363 (lookup *eax *(eax+4)) # Var-name Var-name => eax
27364 (write-buffered *(ebp+8) %eax)
27365 (write-buffered *(ebp+8) ":break/disp32\n")
27366 e9/jump $emit-subx-stmt-list:clean-up/disp32
27369 # unconditional loops {{{
27371 # if (!string-equal?(var->operation, "loop")) break
27372 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax
27373 (string-equal? %eax "loop") # => eax
27374 3d/compare-eax-and 0/imm32/false
27375 0f 84/jump-if-= break/disp32
27376 $emit-subx-stmt-list:unconditional-loop:
27377 81 7/subop/compare *(ecx+0xc) 0/imm32 # Stmt1-inouts
27378 # simple unconditional loops without a target
27380 0f 85/jump-if-!= break/disp32
27381 $emit-subx-stmt-list:zero-arg-unconditional-loop:
27382 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) *Curr-block-depth)
27383 (emit-indent *(ebp+8) *Curr-block-depth)
27384 (write-buffered *(ebp+8) "e9/jump loop/disp32")
27385 (write-buffered *(ebp+8) Newline)
27386 e9/jump $emit-subx-stmt-list:clean-up/disp32 # skip remaining statements; they're dead code
27388 # unconditional loops with a target
27390 0f 84/jump-if-= break/disp32
27391 (emit-subx-cleanup-and-unconditional-nonlocal-branch *(ebp+8) %ecx *(ebp+0x10))
27392 e9/jump $emit-subx-stmt-list:clean-up/disp32
27396 # unconditional breaks {{{
27398 # if (!string-equal?(curr-stmt->operation, "break")) break
27399 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax
27400 (string-equal? %eax "break") # => eax
27401 3d/compare-eax-and 0/imm32/false
27402 0f 84/jump-if-= break/disp32
27403 $emit-subx-stmt-list:unconditional-break:
27404 81 7/subop/compare *(ecx+0xc) 0/imm32 # Stmt1-inouts
27405 # simple unconditional breaks without a target
27406 0f 84/jump-if-= $emit-subx-stmt-list:emit-cleanup/disp32 # easy: just skip remaining statements
27407 # unconditional breaks with a target
27408 (emit-subx-cleanup-and-unconditional-nonlocal-branch *(ebp+8) %ecx *(ebp+0x10))
27409 e9/jump $emit-subx-stmt-list:clean-up/disp32
27412 # simple conditional branches without a target {{{
27413 81 7/subop/compare *(ecx+0xc) 0/imm32 # Stmt1-inouts
27415 0f 85/jump-if-!= break/disp32
27416 $emit-subx-stmt-list:zero-arg-conditional-branch:
27417 # var old-block-depth/ebx: int = Curr-block-depth - 1
27418 8b/-> *Curr-block-depth 3/r32/ebx
27420 (emit-indent *(ebp+8) *Curr-block-depth)
27421 (write-buffered *(ebp+8) "{\n")
27422 ff 0/subop/increment *Curr-block-depth
27424 (emit-reverse-break *(ebp+8) %ecx)
27425 # clean up until old block depth
27426 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) %ebx)
27427 # var target-block-depth/ebx: int = Curr-block-depth - 1
27429 # emit jump to target block
27430 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax
27431 (string-starts-with? %eax "break") # => eax
27432 3d/compare-eax-and 0/imm32/false
27434 74/jump-if-= break/disp8
27435 (emit-unconditional-jump-to-depth *(ebp+8) *(ebp+0x10) %ebx "break")
27437 3d/compare-eax-and 0/imm32/false # just in case the function call modified flags
27439 75/jump-if-!= break/disp8
27440 (emit-unconditional-jump-to-depth *(ebp+8) *(ebp+0x10) %ebx "loop")
27443 ff 1/subop/decrement *Curr-block-depth
27444 (emit-indent *(ebp+8) *Curr-block-depth)
27445 (write-buffered *(ebp+8) "}\n")
27447 e9/jump $emit-subx-stmt-list:continue/disp32
27450 # conditional branches with an explicit target {{{
27452 0f 84/jump-if-= break/disp32
27453 $emit-subx-stmt-list:conditional-branch-with-target:
27455 (emit-indent *(ebp+8) *Curr-block-depth)
27456 (write-buffered *(ebp+8) "{\n")
27457 ff 0/subop/increment *Curr-block-depth
27459 (emit-reverse-break *(ebp+8) %ecx)
27460 (emit-subx-cleanup-and-unconditional-nonlocal-branch *(ebp+8) %ecx *(ebp+0x10))
27462 ff 1/subop/decrement *Curr-block-depth
27463 (emit-indent *(ebp+8) *Curr-block-depth)
27464 (write-buffered *(ebp+8) "}\n")
27466 e9/jump $emit-subx-stmt-list:continue/disp32
27470 $emit-subx-stmt-list:1-to-1:
27471 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c))
27472 e9/jump $emit-subx-stmt-list:continue/disp32
27475 $emit-subx-stmt-list:check-for-var-def:
27476 81 7/subop/compare *ecx 2/imm32/var-def # Stmt-tag
27477 75/jump-if-!= break/disp8
27478 $emit-subx-stmt-list:var-def:
27479 (emit-subx-var-def *(ebp+8) %ecx *(ebp+0x18) *(ebp+0x1c))
27480 (push *(ebp+0x10) *(ecx+4)) # Vardef-var
27481 (push *(ebp+0x10) *(ecx+8)) # Vardef-var
27482 (push *(ebp+0x10) 0) # Live-var-register-spilled = 0 for vars on the stack
27484 eb/jump $emit-subx-stmt-list:continue/disp8
27487 $emit-subx-stmt-list:check-for-reg-var-def:
27488 81 7/subop/compare *ecx 3/imm32/reg-var-def # Stmt-tag
27489 0f 85/jump-if-!= break/disp32
27490 $emit-subx-stmt-list:reg-var-def:
27491 # TODO: ensure that there's exactly one output
27492 (push-output-and-maybe-emit-spill *(ebp+8) %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c))
27493 # emit the instruction as usual
27494 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c))
27496 eb/jump $emit-subx-stmt-list:continue/disp8
27498 $emit-subx-stmt-list:continue:
27499 # TODO: raise an error on unrecognized Stmt-tag
27500 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax
27501 89/<- %esi 0/r32/eax
27502 e9/jump loop/disp32
27504 $emit-subx-stmt-list:emit-cleanup:
27505 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) *Curr-block-depth)
27506 $emit-subx-stmt-list:clean-up:
27507 (clean-up-stack-offset-state *(ebp+0x10) *Curr-block-depth)
27508 (clean-up-blocks *(ebp+0x10) *Curr-block-depth *(ebp+0x14))
27509 $emit-subx-stmt-list:end:
27510 # . restore registers
27516 89/<- %esp 5/r32/ebp
27520 # 'later-stmts' includes 'stmt', but will behave the same even without it; reg-var-def stmts are guaranteed not to write to function outputs.
27521 push-output-and-maybe-emit-spill: # out: (addr buffered-file), stmt: (addr reg-var-def), vars: (addr stack (handle var)), later-stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
27524 89/<- %ebp 4/r32/esp
27530 8b/-> *(ebp+0xc) 1/r32/ecx
27531 # var sv/eax: (addr stmt-var) = lookup(curr-stmt->outputs)
27532 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax
27533 # TODO: assert !sv->is-deref?
27534 # var v/ecx: (addr var) = lookup(sv->value)
27535 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
27536 89/<- %ecx 0/r32/eax
27537 # v->block-depth = *Curr-block-depth
27538 8b/-> *Curr-block-depth 0/r32/eax
27539 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth
27540 #? (write-buffered Stderr "var ")
27541 #? (lookup *ecx *(ecx+4))
27542 #? (write-buffered Stderr %eax)
27543 #? (write-buffered Stderr " at depth ")
27544 #? (write-int32-hex-buffered Stderr *(ecx+0x10))
27545 #? (write-buffered Stderr Newline)
27547 # ensure that v is in a register
27548 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register
27549 0f 84/jump-if-= $push-output-and-maybe-emit-spill:abort/disp32
27550 # var emit-spill?/edx: boolean = not-yet-spilled-this-block? && will-not-write-some-register?(fn)
27551 (not-yet-spilled-this-block? %ecx *(ebp+0x10)) # => eax
27552 89/<- %edx 0/r32/eax
27553 3d/compare-eax-and 0/imm32/false
27554 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32
27555 (will-not-write-some-register? %ecx *(ebp+0x14) *(ebp+0x18)) # => eax
27556 89/<- %edx 0/r32/eax
27557 # check emit-spill?
27558 3d/compare-eax-and 0/imm32/false
27559 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32
27560 # TODO: assert(size-of(output) == 4)
27561 # *Curr-local-stack-offset -= 4
27562 81 5/subop/subtract *Curr-local-stack-offset 4/imm32
27564 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax
27565 (emit-push-register *(ebp+8) %eax)
27566 $push-output-and-maybe-emit-spill:push:
27567 8b/-> *(ebp+0xc) 1/r32/ecx
27568 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax
27569 # push(vars, {sv->value, emit-spill?})
27570 (push *(ebp+0x10) *eax) # Stmt-var-value
27571 (push *(ebp+0x10) *(eax+4)) # Stmt-var-value
27572 (push *(ebp+0x10) %edx)
27573 $push-output-and-maybe-emit-spill:end:
27574 # . restore registers
27579 89/<- %esp 5/r32/ebp
27583 $push-output-and-maybe-emit-spill:abort:
27584 # error("var '" var->name "' initialized from an instruction must live in a register\n")
27585 (write-buffered *(ebp+0x1c) "var '")
27586 (write-buffered *(ebp+0x1c) *eax) # Var-name
27587 (write-buffered *(ebp+0x1c) "' initialized from an instruction must live in a register\n")
27588 (flush *(ebp+0x1c))
27589 (stop *(ebp+0x20) 1)
27592 emit-subx-cleanup-and-unconditional-nonlocal-branch: # out: (addr buffered-file), stmt: (addr stmt1), vars: (addr stack live-var)
27595 89/<- %ebp 4/r32/esp
27600 8b/-> *(ebp+0xc) 1/r32/ecx
27601 # var target/eax: (addr array byte) = curr-stmt->inouts->value->name
27602 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
27603 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
27604 (lookup *eax *(eax+4)) # Var-name Var-name => eax
27605 # clean up until target block
27606 (emit-cleanup-code-until-target *(ebp+8) *(ebp+0x10) %eax)
27607 # emit jump to target block
27608 (emit-indent *(ebp+8) *Curr-block-depth)
27609 (write-buffered *(ebp+8) "e9/jump ")
27610 (write-buffered *(ebp+8) %eax)
27611 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax
27612 (string-starts-with? %eax "break")
27613 3d/compare-eax-and 0/imm32/false
27615 74/jump-if-= break/disp8
27616 (write-buffered *(ebp+8) ":break/disp32\n")
27617 eb/jump $emit-subx-cleanup-and-unconditional-nonlocal-branch:end/disp8
27619 (write-buffered *(ebp+8) ":loop/disp32\n")
27620 $emit-subx-cleanup-and-unconditional-nonlocal-branch:end:
27621 # . restore registers
27625 89/<- %esp 5/r32/ebp
27629 emit-outputs: # out: (addr buffered-file), return-stmt: (addr stmt1), fn: (addr function)
27632 89/<- %ebp 4/r32/esp
27638 # var curr-inout/esi: (addr stmt-var) = return-stmt->inouts
27639 8b/-> *(ebp+0xc) 0/r32/eax
27640 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax
27641 89/<- %esi 0/r32/eax
27642 # var curr-output/edi: (addr list var) = fn->outputs
27643 8b/-> *(ebp+0x10) 0/r32/eax
27644 (lookup *(eax+0x10) *(eax+0x14)) # Function-outputs Function-outputs => eax
27645 89/<- %edi 0/r32/eax
27647 $emit-outputs:loop:
27648 81 7/subop/compare %esi 0/imm32
27649 0f 84/jump-if-= break/disp32
27650 # emit copy to output register
27651 # var curr-output-register/ecx: (addr array byte) = curr-output->value->register
27652 (lookup *edi *(edi+4)) # List-value List-value => eax
27653 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
27654 89/<- %ecx 0/r32/eax
27655 # if curr-output-register starts with "x", emit a floating-point copy
27656 8a/copy-byte *(ecx+4) 0/r32/AL
27657 25/and-eax-with 0xff/imm32
27658 3d/compare-eax-and 0x78/imm32/x
27660 75/jump-if-!= break/disp8
27661 (emit-float-output *(ebp+8) %esi %ecx)
27662 eb/jump $emit-outputs:continue/disp8
27664 # otherwise emit an int copy
27665 (emit-int-output *(ebp+8) %esi %ecx)
27666 $emit-outputs:continue:
27667 # curr-inout = curr-inout->next
27668 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
27669 89/<- %esi 0/r32/eax
27670 # curr-output = curr-output->next
27671 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax
27672 89/<- %edi 0/r32/eax
27674 e9/jump loop/disp32
27677 # . restore registers
27683 89/<- %esp 5/r32/ebp
27687 emit-int-output: # out: (addr buffered-file), return-var: (addr stmt-var), dest-reg: (addr array byte)
27690 89/<- %ebp 4/r32/esp
27694 # ecx = return-var->value
27695 8b/-> *(ebp+0xc) 0/r32/eax
27696 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
27697 89/<- %ecx 0/r32/eax
27698 # if curr-var is a literal, emit copy of a literal to the output
27699 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
27700 (simple-mu-type? %eax 0) # literal => eax
27702 3d/compare-eax-and 0/imm32/false
27703 0f 84/jump-if-= break/disp32
27704 (emit-indent *(ebp+8) *Curr-block-depth)
27705 (write-buffered *(ebp+8) "c7 0/subop/copy %")
27706 (write-buffered *(ebp+8) *(ebp+0x10))
27707 (write-buffered *(ebp+8) " ")
27708 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
27709 (write-buffered *(ebp+8) %eax)
27710 (write-buffered *(ebp+8) "/imm32\n")
27711 e9/jump $emit-int-output:end/disp32
27713 # otherwise emit an integer copy
27714 (emit-indent *(ebp+8) *Curr-block-depth)
27715 (write-buffered *(ebp+8) "8b/->")
27716 (emit-subx-var-as-rm32 *(ebp+8) *(ebp+0xc))
27717 (write-buffered *(ebp+8) " ")
27718 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax
27719 (write-int32-hex-buffered *(ebp+8) *eax)
27720 (write-buffered *(ebp+8) "/r32\n")
27721 $emit-int-output:end:
27722 # . restore registers
27726 89/<- %esp 5/r32/ebp
27730 emit-float-output: # out: (addr buffered-file), return-var: (addr stmt-var), dest-reg: (addr array byte)
27733 89/<- %ebp 4/r32/esp
27737 (emit-indent *(ebp+8) *Curr-block-depth)
27738 (write-buffered *(ebp+8) "f3 0f 10/->")
27739 (emit-subx-var-as-rm32 *(ebp+8) *(ebp+0xc))
27740 (write-buffered *(ebp+8) " ")
27741 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax
27742 (write-int32-hex-buffered *(ebp+8) *eax)
27743 (write-buffered *(ebp+8) "/x32\n")
27744 $emit-float-output:end:
27745 # . restore registers
27748 89/<- %esp 5/r32/ebp
27752 mu-branch?: # stmt: (addr stmt1) -> result/eax: boolean
27755 89/<- %ebp 4/r32/esp
27758 # ecx = lookup(stmt->operation)
27759 8b/-> *(ebp+8) 1/r32/ecx
27760 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax
27761 89/<- %ecx 0/r32/eax
27762 # if (stmt->operation starts with "loop") return true
27763 (string-starts-with? %ecx "loop") # => eax
27764 3d/compare-eax-and 0/imm32/false
27765 75/jump-if-not-equal $mu-branch?:end/disp8
27766 # if (stmt->operation starts with "break") return true
27767 (string-starts-with? %ecx "break") # => eax
27768 3d/compare-eax-and 0/imm32/false
27769 75/jump-if-not-equal $mu-branch?:end/disp8
27770 # otherwise return (stmt->operation starts with "return")
27771 (string-starts-with? %ecx "return") # => eax
27773 # . restore registers
27776 89/<- %esp 5/r32/ebp
27780 emit-reverse-break: # out: (addr buffered-file), stmt: (addr stmt1)
27783 89/<- %ebp 4/r32/esp
27787 8b/-> *(ebp+0xc) 0/r32/eax
27789 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax
27790 (get Reverse-branch %eax 0x10 "reverse-branch: ") # => eax: (addr handle array byte)
27791 (emit-indent *(ebp+8) *Curr-block-depth)
27792 (lookup *eax *(eax+4)) # => eax
27793 (write-buffered *(ebp+8) %eax)
27794 (write-buffered *(ebp+8) " break/disp32\n")
27795 $emit-reverse-break:end:
27796 # . restore registers
27799 89/<- %esp 5/r32/ebp
27805 # Table from Mu branch instructions to the reverse SubX opcodes for them.
27806 Reverse-branch: # (table (handle array byte) (handle array byte))
27807 # a table is a stream
27812 0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32
27813 0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32
27814 0x11/imm32/alloc-id _string-break-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32
27815 0x11/imm32/alloc-id _string-loop-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32
27816 0x11/imm32/alloc-id _string-break-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32
27817 0x11/imm32/alloc-id _string-loop-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32
27818 0x11/imm32/alloc-id _string-break-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32
27819 0x11/imm32/alloc-id _string-loop-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32
27820 0x11/imm32/alloc-id _string-break-if-<=/imm32 0x11/imm32/alloc-id _string_0f_8f_jump_label/imm32
27821 0x11/imm32/alloc-id _string-loop-if-<=/imm32 0x11/imm32/alloc-id _string_0f_8f_jump_label/imm32
27822 0x11/imm32/alloc-id _string-break-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32
27823 0x11/imm32/alloc-id _string-loop-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32
27824 0x11/imm32/alloc-id _string-break-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32
27825 0x11/imm32/alloc-id _string-loop-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32
27826 0x11/imm32/alloc-id _string-break-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32
27827 0x11/imm32/alloc-id _string-loop-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32
27828 0x11/imm32/alloc-id _string-break-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32
27829 0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32
27830 0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
27831 0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
27832 0x11/imm32/alloc-id _string-break-if-float</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32
27833 0x11/imm32/alloc-id _string-loop-if-float</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32
27834 0x11/imm32/alloc-id _string-break-if-float>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32
27835 0x11/imm32/alloc-id _string-loop-if-float>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32
27836 0x11/imm32/alloc-id _string-break-if-float<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32
27837 0x11/imm32/alloc-id _string-loop-if-float<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32
27838 0x11/imm32/alloc-id _string-break-if-float>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
27839 0x11/imm32/alloc-id _string-loop-if-float>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
27840 0x11/imm32/alloc-id _string-break-if-carry/imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32
27841 0x11/imm32/alloc-id _string-loop-if-carry/imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32
27842 0x11/imm32/alloc-id _string-break-if-not-carry/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
27843 0x11/imm32/alloc-id _string-loop-if-not-carry/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
27844 0x11/imm32/alloc-id _string-break-if-overflow/imm32 0x11/imm32/alloc-id _string_0f_81_jump_label/imm32
27845 0x11/imm32/alloc-id _string-loop-if-overflow/imm32 0x11/imm32/alloc-id _string_0f_81_jump_label/imm32
27846 0x11/imm32/alloc-id _string-break-if-not-overflow/imm32 0x11/imm32/alloc-id _string_0f_80_jump_label/imm32
27847 0x11/imm32/alloc-id _string-loop-if-not-overflow/imm32 0x11/imm32/alloc-id _string_0f_80_jump_label/imm32
27851 emit-unconditional-jump-to-depth: # out: (addr buffered-file), vars: (addr stack live-var), depth: int, label-suffix: (addr array byte)
27854 89/<- %ebp 4/r32/esp
27862 8b/-> *(ebp+0xc) 1/r32/ecx
27863 # var eax: int = vars->top
27864 8b/-> *ecx 0/r32/eax
27865 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12]
27866 8d/copy-address *(ecx+eax-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size
27867 # var min/ecx: (addr handle var) = vars->data
27868 8d/copy-address *(ecx+8) 1/r32/ecx
27870 8b/-> *(ebp+0x10) 2/r32/edx
27872 $emit-unconditional-jump-to-depth:loop:
27873 # if (curr < min) break
27874 39/compare %esi 1/r32/ecx
27875 0f 82/jump-if-addr< break/disp32
27876 # var v/ebx: (addr var) = lookup(*curr)
27877 (lookup *esi *(esi+4)) # => eax
27878 89/<- %ebx 0/r32/eax
27879 # if (v->block-depth < until-block-depth) break
27880 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth
27881 0f 8c/jump-if-< break/disp32
27883 $emit-unconditional-jump-to-depth:check:
27884 # if v->block-depth != until-block-depth, continue
27885 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth
27886 0f 85/jump-if-!= break/disp32
27887 $emit-unconditional-jump-to-depth:depth-found:
27888 # if v is not a literal, continue
27889 (size-of %ebx) # => eax
27890 3d/compare-eax-and 0/imm32
27891 0f 85/jump-if-!= break/disp32
27892 $emit-unconditional-jump-to-depth:label-found:
27893 # emit unconditional jump, then return
27894 (emit-indent *(ebp+8) *Curr-block-depth)
27895 (write-buffered *(ebp+8) "e9/jump ")
27896 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax
27897 (write-buffered *(ebp+8) %eax)
27898 (write-buffered *(ebp+8) ":")
27899 (write-buffered *(ebp+8) *(ebp+0x14))
27900 (write-buffered *(ebp+8) "/disp32\n")
27901 eb/jump $emit-unconditional-jump-to-depth:end/disp8
27904 81 5/subop/subtract %esi 0xc/imm32
27905 e9/jump loop/disp32
27907 # TODO: error if no label at 'depth' was found
27908 $emit-unconditional-jump-to-depth:end:
27909 # . restore registers
27916 89/<- %esp 5/r32/ebp
27920 # emit clean-up code for 'vars' until some block depth
27921 # doesn't actually modify 'vars' so we need traverse manually inside the stack
27922 emit-cleanup-code-until-depth: # out: (addr buffered-file), vars: (addr stack live-var), until-block-depth: int
27925 89/<- %ebp 4/r32/esp
27932 #? (write-buffered Stderr "--- cleanup\n")
27935 8b/-> *(ebp+0xc) 1/r32/ecx
27936 # var esi: int = vars->top
27937 8b/-> *ecx 6/r32/esi
27938 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12]
27939 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size
27940 # var min/ecx: (addr handle var) = vars->data
27941 81 0/subop/add %ecx 8/imm32
27942 # edx = until-block-depth
27943 8b/-> *(ebp+0x10) 2/r32/edx
27945 $emit-cleanup-code-until-depth:loop:
27946 # if (curr < min) break
27947 39/compare %esi 1/r32/ecx
27948 0f 82/jump-if-addr< break/disp32
27949 # var v/ebx: (addr var) = lookup(*curr)
27950 (lookup *esi *(esi+4)) # => eax
27951 89/<- %ebx 0/r32/eax
27952 #? (lookup *ebx *(ebx+4)) # Var-name
27953 #? (write-buffered Stderr "var ")
27954 #? (write-buffered Stderr %eax)
27955 #? (write-buffered Stderr Newline)
27957 # if (v->block-depth < until-block-depth) break
27958 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth
27959 0f 8c/jump-if-< break/disp32
27960 # if v is in a register
27961 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register
27963 0f 84/jump-if-= break/disp32
27965 $emit-cleanup-code-until-depth:check-for-previous-spill:
27966 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled
27967 3d/compare-eax-and 0/imm32/false
27968 74/jump-if-= break/disp8
27969 $emit-cleanup-code-until-depth:reclaim-var-in-register:
27970 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax
27971 (emit-pop-register *(ebp+8) %eax)
27973 eb/jump $emit-cleanup-code-until-depth:continue/disp8
27975 # otherwise v is on the stack
27977 75/jump-if-!= break/disp8
27978 $emit-cleanup-code-until-depth:var-on-stack:
27979 (size-of %ebx) # => eax
27980 # don't emit code for labels
27981 3d/compare-eax-and 0/imm32
27982 74/jump-if-= break/disp8
27983 $emit-cleanup-code-until-depth:reclaim-var-on-stack:
27984 (emit-indent *(ebp+8) *Curr-block-depth)
27985 (write-buffered *(ebp+8) "81 0/subop/add %esp ")
27986 (write-int32-hex-buffered *(ebp+8) %eax)
27987 (write-buffered *(ebp+8) "/imm32\n")
27989 $emit-cleanup-code-until-depth:continue:
27991 81 5/subop/subtract %esi 0xc/imm32
27992 e9/jump loop/disp32
27994 $emit-cleanup-code-until-depth:end:
27995 # . restore registers
28002 89/<- %esp 5/r32/ebp
28006 # emit clean-up code for 'vars' that don't conflict with output registers
28007 # doesn't actually modify 'vars' so we need traverse manually inside the stack
28008 emit-cleanup-code-for-non-outputs: # out: (addr buffered-file), vars: (addr stack live-var), fn: (addr function)
28011 89/<- %ebp 4/r32/esp
28020 8b/-> *(ebp+0xc) 1/r32/ecx
28021 # var esi: int = vars->top
28022 8b/-> *ecx 6/r32/esi
28023 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12]
28024 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size
28025 # var min/ecx: (addr handle var) = vars->data
28026 81 0/subop/add %ecx 8/imm32
28028 $emit-cleanup-code-for-non-outputs:loop:
28029 # if (curr < min) break
28030 39/compare %esi 1/r32/ecx
28031 0f 82/jump-if-addr< break/disp32
28032 # var v/ebx: (addr var) = lookup(*curr)
28033 (lookup *esi *(esi+4)) # => eax
28034 89/<- %ebx 0/r32/eax
28035 # if v is in a register
28036 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register
28038 0f 84/jump-if-= break/disp32
28040 $emit-cleanup-code-for-non-outputs:check-for-previous-spill:
28041 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled
28042 3d/compare-eax-and 0/imm32/false
28043 0f 84/jump-if-= break/disp32
28044 $emit-cleanup-code-for-non-outputs:reclaim-var-in-register:
28045 # var reg/edi: (addr array name) = v->register
28046 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax
28047 89/<- %edi 0/r32/eax
28048 # if reg is not in function outputs, emit a pop
28049 (reg-in-function-outputs? *(ebp+0x10) %edi) # => eax
28050 3d/compare-eax-and 0/imm32/false
28052 75/jump-if-!= break/disp8
28053 (emit-pop-register *(ebp+8) %edi)
28054 eb/jump $emit-cleanup-code-for-non-outputs:reclaim-var-in-register-done/disp8
28056 # otherwise just drop it from the stack
28057 (emit-indent *(ebp+8) *Curr-block-depth)
28058 (write-buffered *(ebp+8) "81 0/subop/add %esp 4/imm32\n")
28060 $emit-cleanup-code-for-non-outputs:reclaim-var-in-register-done:
28061 eb/jump $emit-cleanup-code-for-non-outputs:continue/disp8
28063 # otherwise v is on the stack
28065 75/jump-if-!= break/disp8
28066 $emit-cleanup-code-for-non-outputs:var-on-stack:
28067 (size-of %ebx) # => eax
28068 # don't emit code for labels
28069 3d/compare-eax-and 0/imm32
28070 74/jump-if-= break/disp8
28071 $emit-cleanup-code-for-non-outputs:reclaim-var-on-stack:
28072 (emit-indent *(ebp+8) *Curr-block-depth)
28073 (write-buffered *(ebp+8) "81 0/subop/add %esp ")
28074 (write-int32-hex-buffered *(ebp+8) %eax)
28075 (write-buffered *(ebp+8) "/imm32\n")
28077 $emit-cleanup-code-for-non-outputs:continue:
28079 81 5/subop/subtract %esi 0xc/imm32
28080 e9/jump loop/disp32
28082 $emit-cleanup-code-for-non-outputs:end:
28083 # . restore registers
28091 89/<- %esp 5/r32/ebp
28095 emit-push-register: # out: (addr buffered-file), reg: (addr array byte)
28098 89/<- %ebp 4/r32/esp
28100 8b/-> *(ebp+0xc) 0/r32/eax
28101 # var prefix/eax: byte = reg->data[0]
28102 8a/copy-byte *(eax+4) 0/r32/AL
28103 25/and-eax-with 0xff/imm32
28104 # if (prefix == 'x') push xmm register
28106 3d/compare-eax-and 0x78/imm32/x
28107 0f 85/jump-if-!= break/disp32
28108 # TODO validate register
28109 (emit-indent *(ebp+8) *Curr-block-depth)
28110 (write-buffered *(ebp+8) "81 5/subop/subtract %esp 4/imm32\n")
28111 (emit-indent *(ebp+8) *Curr-block-depth)
28112 (write-buffered *(ebp+8) "f3 0f 11/<- *esp ")
28113 # var prefix/eax: byte = reg->data[3]
28114 8b/-> *(ebp+0xc) 0/r32/eax
28115 8a/copy-byte *(eax+7) 0/r32/AL
28116 25/and-eax-with 0xff/imm32
28117 (write-byte-buffered *(ebp+8) %eax)
28118 (write-buffered *(ebp+8) "/x32\n")
28119 e9/jump $emit-push-register:end/disp32
28121 # otherwise push gp register
28122 (emit-indent *(ebp+8) *Curr-block-depth)
28123 (write-buffered *(ebp+8) "ff 6/subop/push %")
28124 (write-buffered *(ebp+8) *(ebp+0xc))
28125 (write-buffered *(ebp+8) Newline)
28126 $emit-push-register:end:
28128 89/<- %esp 5/r32/ebp
28132 emit-pop-register: # out: (addr buffered-file), reg: (addr array byte)
28135 89/<- %ebp 4/r32/esp
28139 8b/-> *(ebp+0xc) 0/r32/eax
28140 # var prefix/eax: byte = reg->data[0]
28141 8a/copy-byte *(eax+4) 0/r32/AL
28142 25/and-eax-with 0xff/imm32
28143 # if (prefix == 'x') pop to xmm register
28145 3d/compare-eax-and 0x78/imm32/x
28146 0f 85/jump-if-!= break/disp32
28147 # TODO validate register
28148 (emit-indent *(ebp+8) *Curr-block-depth)
28149 (write-buffered *(ebp+8) "f3 0f 10/-> *esp ")
28150 # var prefix/eax: byte = reg->data[3]
28151 8b/-> *(ebp+0xc) 0/r32/eax
28152 8a/copy-byte *(eax+7) 0/r32/AL
28153 25/and-eax-with 0xff/imm32
28154 (write-byte-buffered *(ebp+8) %eax)
28155 (write-buffered *(ebp+8) "/x32\n")
28156 (emit-indent *(ebp+8) *Curr-block-depth)
28157 (write-buffered *(ebp+8) "81 0/subop/add %esp 4/imm32\n")
28158 e9/jump $emit-pop-register:end/disp32
28160 # otherwise pop to gp register
28161 (emit-indent *(ebp+8) *Curr-block-depth)
28162 (write-buffered *(ebp+8) "8f 0/subop/pop %")
28163 (write-buffered *(ebp+8) *(ebp+0xc))
28164 (write-buffered *(ebp+8) Newline)
28165 $emit-pop-register:end:
28166 # . restore registers
28169 89/<- %esp 5/r32/ebp
28173 # emit clean-up code for 'vars' until a given label is encountered
28174 # doesn't actually modify 'vars' so we need traverse manually inside the stack
28175 emit-cleanup-code-until-target: # out: (addr buffered-file), vars: (addr stack live-var), until-block-label: (addr array byte)
28178 89/<- %ebp 4/r32/esp
28185 8b/-> *(ebp+0xc) 1/r32/ecx
28186 # var eax: int = vars->top
28187 8b/-> *ecx 0/r32/eax
28188 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12]
28189 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size
28190 # var min/ecx: (addr handle var) = vars->data
28191 81 0/subop/add %ecx 8/imm32
28193 $emit-cleanup-code-until-target:loop:
28194 # if (curr < min) break
28195 39/compare %edx 1/r32/ecx
28196 0f 82/jump-if-addr< break/disp32
28197 # var v/ebx: (handle var) = lookup(*curr)
28198 (lookup *edx *(edx+4)) # => eax
28199 89/<- %ebx 0/r32/eax
28200 # if (v->name == until-block-label) break
28201 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax
28202 (string-equal? %eax *(ebp+0x10)) # => eax
28203 3d/compare-eax-and 0/imm32/false
28204 0f 85/jump-if-!= break/disp32
28205 # if v is in a register
28206 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register
28208 0f 84/jump-if-= break/disp32
28210 $emit-cleanup-code-until-target:check-for-previous-spill:
28211 8b/-> *(edx+8) 0/r32/eax # Live-var-register-spilled
28212 3d/compare-eax-and 0/imm32/false
28213 74/jump-if-= break/disp8
28214 $emit-cleanup-code-until-target:reclaim-var-in-register:
28215 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax
28216 (emit-pop-register *(ebp+8) %eax)
28218 eb/jump $emit-cleanup-code-until-target:continue/disp8
28220 # otherwise v is on the stack
28222 75/jump-if-!= break/disp8
28223 $emit-cleanup-code-until-target:reclaim-var-on-stack:
28224 (size-of %ebx) # => eax
28225 # don't emit code for labels
28226 3d/compare-eax-and 0/imm32
28227 74/jump-if-= break/disp8
28229 (emit-indent *(ebp+8) *Curr-block-depth)
28230 (write-buffered *(ebp+8) "81 0/subop/add %esp ")
28231 (write-int32-hex-buffered *(ebp+8) %eax)
28232 (write-buffered *(ebp+8) "/imm32\n")
28234 $emit-cleanup-code-until-target:continue:
28236 81 5/subop/subtract %edx 0xc/imm32
28237 e9/jump loop/disp32
28239 $emit-cleanup-code-until-target:end:
28240 # . restore registers
28246 89/<- %esp 5/r32/ebp
28250 # update Curr-local-stack-offset assuming vars until some block depth are popped
28251 # doesn't actually modify 'vars', so we need traverse manually inside the stack
28252 clean-up-stack-offset-state: # vars: (addr stack live-var), until-block-depth: int
28255 89/<- %ebp 4/r32/esp
28263 8b/-> *(ebp+8) 1/r32/ecx
28264 # var esi: int = vars->top
28265 8b/-> *ecx 6/r32/esi
28266 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12]
28267 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size
28268 # var min/ecx: (addr handle var) = vars->data
28269 81 0/subop/add %ecx 8/imm32
28270 # edx = until-block-depth
28271 8b/-> *(ebp+0xc) 2/r32/edx
28273 $clean-up-stack-offset-state:loop:
28274 # if (curr < min) break
28275 39/compare %esi 1/r32/ecx
28276 0f 82/jump-if-addr< break/disp32
28277 # var v/ebx: (addr var) = lookup(*curr)
28278 (lookup *esi *(esi+4)) # => eax
28279 89/<- %ebx 0/r32/eax
28280 # if (v->block-depth < until-block-depth) break
28281 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth
28282 0f 8c/jump-if-< break/disp32
28283 # if v is in a register
28284 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register
28286 0f 84/jump-if-= break/disp32
28288 $clean-up-stack-offset-state:check-for-previous-spill:
28289 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled
28290 3d/compare-eax-and 0/imm32/false
28291 74/jump-if-= break/disp8
28292 $clean-up-stack-offset-state:reclaim-var-in-register:
28293 81 0/subop/add *Curr-local-stack-offset 4/imm32
28295 eb/jump $clean-up-stack-offset-state:continue/disp8
28297 # otherwise v is on the stack
28299 75/jump-if-!= break/disp8
28300 $clean-up-stack-offset-state:var-on-stack:
28301 (size-of %ebx) # => eax
28302 01/add-to *Curr-local-stack-offset 0/r32/eax
28304 $clean-up-stack-offset-state:continue:
28306 81 5/subop/subtract %esi 0xc/imm32
28307 e9/jump loop/disp32
28309 $clean-up-stack-offset-state:end:
28310 # . restore registers
28317 89/<- %esp 5/r32/ebp
28321 # Return true if there isn't a variable in 'vars' with the same block-depth
28322 # and register as 'v'.
28323 # 'v' is guaranteed not to be within 'vars'.
28324 not-yet-spilled-this-block?: # v: (addr var), vars: (addr stack live-var) -> result/eax: boolean
28327 89/<- %ebp 4/r32/esp
28335 8b/-> *(ebp+0xc) 1/r32/ecx
28336 # var eax: int = vars->top
28337 8b/-> *ecx 0/r32/eax
28338 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12]
28339 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size
28340 # var min/ecx: (addr handle var) = vars->data
28341 8d/copy-address *(ecx+8) 1/r32/ecx
28342 # var depth/ebx: int = v->block-depth
28343 8b/-> *(ebp+8) 3/r32/ebx
28344 8b/-> *(ebx+0x10) 3/r32/ebx # Var-block-depth
28345 # var needle/esi: (addr array byte) = v->register
28346 8b/-> *(ebp+8) 6/r32/esi
28347 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax
28348 89/<- %esi 0/r32/eax
28350 $not-yet-spilled-this-block?:loop:
28351 # if (curr < min) break
28352 39/compare %edx 1/r32/ecx
28353 0f 82/jump-if-addr< break/disp32
28354 # var cand/edi: (addr var) = lookup(*curr)
28355 (lookup *edx *(edx+4)) # => eax
28356 89/<- %edi 0/r32/eax
28357 # if (cand->block-depth < depth) break
28358 39/compare *(edi+0x10) 3/r32/ebx # Var-block-depth
28359 0f 8c/jump-if-< break/disp32
28360 # var cand-reg/edi: (array array byte) = cand->reg
28361 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax
28362 89/<- %edi 0/r32/eax
28363 # if (cand-reg == null) continue
28365 $not-yet-spilled-this-block?:check-reg:
28366 81 7/subop/compare %edi 0/imm32
28367 0f 84/jump-if-= break/disp32
28368 # if (cand-reg == needle) return true
28369 (string-equal? %esi %edi) # => eax
28370 3d/compare-eax-and 0/imm32/false
28371 74/jump-if-= break/disp8
28372 $not-yet-spilled-this-block?:return-false:
28373 b8/copy-to-eax 0/imm32/false
28374 eb/jump $not-yet-spilled-this-block?:end/disp8
28376 $not-yet-spilled-this-block?:continue:
28378 81 5/subop/subtract %edx 0xc/imm32
28379 e9/jump loop/disp32
28381 $not-yet-spilled-this-block?:return-true:
28383 b8/copy-to-eax 1/imm32/true
28384 $not-yet-spilled-this-block?:end:
28385 # . restore registers
28392 89/<- %esp 5/r32/ebp
28396 # could the register of 'v' ever be written to by one of the vars in fn-outputs?
28397 will-not-write-some-register?: # v: (addr var), stmts: (addr list stmt), fn: (addr function) -> result/eax: boolean
28400 89/<- %ebp 4/r32/esp
28402 8b/-> *(ebp+8) 0/r32/eax
28403 # var reg/eax: (addr array byte) = lookup(v->register)
28404 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
28405 # var target/eax: (addr var) = find-register(fn-outputs, reg)
28406 (find-register *(ebp+0x10) %eax) # => eax
28407 # if (target == 0) return true
28409 3d/compare-eax-and 0/imm32
28410 75/jump-if-!= break/disp8
28411 b8/copy-to-eax 1/imm32/true
28412 eb/jump $will-not-write-some-register?:end/disp8
28414 # return !assigns-in-stmts?(stmts, target)
28415 (assigns-in-stmts? *(ebp+0xc) %eax) # => eax
28416 3d/compare-eax-and 0/imm32/false
28417 # assume: true = 1, so no need to mask with 0x000000ff
28419 $will-not-write-some-register?:end:
28421 89/<- %esp 5/r32/ebp
28425 # return fn output with matching register
28426 # always returns false if 'reg' is null
28427 find-register: # fn: (addr function), reg: (addr array byte) -> result/eax: (addr var)
28430 89/<- %ebp 4/r32/esp
28433 # var curr/ecx: (addr list var) = lookup(fn->outputs)
28434 8b/-> *(ebp+8) 1/r32/ecx
28435 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax
28436 89/<- %ecx 0/r32/eax
28438 $find-register:loop:
28439 # if (curr == 0) break
28440 81 7/subop/compare %ecx 0/imm32
28441 74/jump-if-= break/disp8
28442 # eax = curr->value->register
28443 (lookup *ecx *(ecx+4)) # List-value List-value => eax
28444 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
28445 # if (eax == reg) return curr->value
28446 $find-register:compare:
28447 (string-equal? *(ebp+0xc) %eax) # => eax
28449 3d/compare-eax-and 0/imm32/false
28450 74/jump-if-= break/disp8
28451 $find-register:found:
28452 (lookup *ecx *(ecx+4)) # List-value List-value => eax
28453 eb/jump $find-register:end/disp8
28455 # curr = lookup(curr->next)
28456 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax
28457 89/<- %ecx 0/r32/eax
28461 $find-register:end:
28462 # . restore registers
28465 89/<- %esp 5/r32/ebp
28469 assigns-in-stmts?: # stmts: (addr list stmt), v: (addr var) -> result/eax: boolean
28472 89/<- %ebp 4/r32/esp
28475 # var curr/ecx: (addr list stmt) = stmts
28476 8b/-> *(ebp+8) 1/r32/ecx
28478 # if (curr == 0) break
28479 81 7/subop/compare %ecx 0/imm32
28480 74/jump-if-= break/disp8
28481 # if assigns-in-stmt?(curr->value, v) return true
28482 (lookup *ecx *(ecx+4)) # List-value List-value => eax
28483 (assigns-in-stmt? %eax *(ebp+0xc)) # => eax
28484 3d/compare-eax-and 0/imm32/false
28485 75/jump-if-!= break/disp8
28486 # curr = lookup(curr->next)
28487 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax
28488 89/<- %ecx 0/r32/eax
28492 $assigns-in-stmts?:end:
28493 # . restore registers
28496 89/<- %esp 5/r32/ebp
28500 assigns-in-stmt?: # stmt: (addr stmt), v: (addr var) -> result/eax: boolean
28503 89/<- %ebp 4/r32/esp
28507 8b/-> *(ebp+8) 1/r32/ecx
28508 # if stmt is a stmt1, return assigns-in-stmt-vars?(stmt->outputs, v)
28510 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag
28511 75/jump-if-!= break/disp8
28512 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax
28513 (assigns-in-stmt-vars? %eax *(ebp+0xc)) # => eax
28514 eb/jump $assigns-in-stmt?:end/disp8
28516 # if stmt is a block, return assigns-in-stmts?(stmt->stmts, v)
28518 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag
28519 75/jump-if-!= break/disp8
28520 (lookup *(ecx+4) *(ecx+8)) # Block-stmts Block-stmts => eax
28521 (assigns-in-stmts? %eax *(ebp+0xc)) # => eax
28522 eb/jump $assigns-in-stmt?:end/disp8
28524 # otherwise return false
28525 b8/copy 0/imm32/false
28526 $assigns-in-stmt?:end:
28527 # . restore registers
28530 89/<- %esp 5/r32/ebp
28534 assigns-in-stmt-vars?: # stmt-var: (addr stmt-var), v: (addr var) -> result/eax: boolean
28537 89/<- %ebp 4/r32/esp
28540 # var curr/ecx: (addr stmt-var) = stmt-var
28541 8b/-> *(ebp+8) 1/r32/ecx
28543 # if (curr == 0) break
28544 81 7/subop/compare %ecx 0/imm32
28545 74/jump-if-= break/disp8
28546 # eax = lookup(curr->value)
28547 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
28548 # if (eax == v && curr->is-deref? == false) return true
28550 39/compare *(ebp+0xc) 0/r32/eax
28551 75/jump-if-!= break/disp8
28552 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref
28553 75/jump-if-!= break/disp8
28554 b8/copy-to-eax 1/imm32/true
28555 eb/jump $assigns-in-stmt-vars?:end/disp8
28557 # curr = lookup(curr->next)
28558 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax
28559 89/<- %ecx 0/r32/eax
28563 $assigns-in-stmt-vars?:end:
28564 # . restore registers
28567 89/<- %esp 5/r32/ebp
28571 # is there a var before 'v' with the same block-depth and register on the 'vars' stack?
28572 # v is guaranteed to be within vars
28573 # 'start' is provided as an optimization, a pointer within vars
28575 same-register-spilled-before?: # v: (addr var), vars: (addr stack (handle var)), start: (addr var) -> result/eax: boolean
28578 89/<- %ebp 4/r32/esp
28586 8b/-> *(ebp+8) 1/r32/ecx
28587 # var reg/edx: (addr array byte) = lookup(v->register)
28588 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax
28589 89/<- %edx 0/r32/eax
28590 # var depth/ebx: int = v->block-depth
28591 8b/-> *(ecx+0x10) 3/r32/ebx # Var-block-depth
28592 # var min/ecx: (addr handle var) = vars->data
28593 8b/-> *(ebp+0xc) 1/r32/ecx
28594 81 0/subop/add %ecx 8/imm32
28595 # TODO: check that start >= min and start < &vars->data[top]
28596 # TODO: check that *start == v
28597 # var curr/esi: (addr handle var) = start
28598 8b/-> *(ebp+0x10) 6/r32/esi
28600 81 5/subop/subtract %esi 8/imm32
28602 $same-register-spilled-before?:loop:
28603 # if (curr < min) break
28604 39/compare %esi 1/r32/ecx
28605 0f 82/jump-if-addr< break/disp32
28606 # var x/eax: (addr var) = lookup(*curr)
28607 (lookup *esi *(esi+4)) # => eax
28608 # if (x->block-depth < depth) break
28609 39/compare *(eax+0x10) 3/r32/ebx # Var-block-depth
28610 0f 8c/jump-if-< break/disp32
28611 # if (x->register == 0) continue
28612 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register
28613 74/jump-if-= $same-register-spilled-before?:continue/disp8
28614 # if (x->register == reg) return true
28615 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
28616 (string-equal? %eax %edx) # => eax
28617 3d/compare-eax-and 0/imm32/false
28618 b8/copy-to-eax 1/imm32/true
28619 75/jump-if-!= $same-register-spilled-before?:end/disp8
28620 $same-register-spilled-before?:continue:
28622 81 5/subop/subtract %esi 8/imm32
28623 e9/jump loop/disp32
28625 $same-register-spilled-before?:false:
28626 b8/copy-to-eax 0/imm32/false
28627 $same-register-spilled-before?:end:
28628 # . restore registers
28635 89/<- %esp 5/r32/ebp
28639 # clean up global state for 'vars' until some block depth (inclusive)
28640 clean-up-blocks: # vars: (addr stack live-var), until-block-depth: int, fn: (addr function)
28643 89/<- %ebp 4/r32/esp
28649 8b/-> *(ebp+8) 6/r32/esi
28650 # ecx = until-block-depth
28651 8b/-> *(ebp+0xc) 1/r32/ecx
28653 $clean-up-blocks:reclaim-loop:
28654 # if (vars->top <= 0) break
28655 8b/-> *esi 0/r32/eax # Stack-top
28656 3d/compare-eax-and 0/imm32
28657 0f 8e/jump-if-<= break/disp32
28658 # var v/eax: (addr var) = lookup(vars[vars->top-12])
28659 (lookup *(esi+eax-4) *(esi+eax)) # vars + 8 + vars->top - 12 => eax
28660 # if (v->block-depth < until-block-depth) break
28661 39/compare *(eax+0x10) 1/r32/ecx # Var-block-depth
28662 0f 8c/jump-if-< break/disp32
28663 (pop %esi) # => eax
28664 (pop %esi) # => eax
28665 (pop %esi) # => eax
28666 e9/jump loop/disp32
28668 $clean-up-blocks:end:
28669 # . restore registers
28674 89/<- %esp 5/r32/ebp
28678 reg-in-function-outputs?: # fn: (addr function), target: (addr array byte) -> result/eax: boolean
28681 89/<- %ebp 4/r32/esp
28684 # var curr/ecx: (addr list var) = lookup(fn->outputs)
28685 8b/-> *(ebp+8) 0/r32/eax
28686 (lookup *(eax+0x10) *(eax+0x14)) # Function-outputs Function-outputs => eax
28687 89/<- %ecx 0/r32/eax
28688 # while curr != null
28690 81 7/subop/compare %ecx 0/imm32
28691 74/jump-if-= break/disp8
28692 # var v/eax: (addr var) = lookup(curr->value)
28693 (lookup *ecx *(ecx+4)) # List-value List-value => eax
28694 # var reg/eax: (addr array byte) = lookup(v->register)
28695 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
28696 # if (reg == target) return true
28697 (string-equal? %eax *(ebp+0xc)) # => eax
28698 3d/compare-eax-and 0/imm32/false
28699 75/jump-if-!= $reg-in-function-outputs?:end/disp8
28700 # curr = curr->next
28701 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax
28702 89/<- %ecx 0/r32/eax
28707 b8/copy-to-eax 0/imm32
28708 $reg-in-function-outputs?:end:
28709 # . restore registers
28712 89/<- %esp 5/r32/ebp
28716 emit-subx-var-def: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
28719 89/<- %ebp 4/r32/esp
28725 8b/-> *(ebp+0xc) 0/r32/eax
28726 # var v/ecx: (addr var)
28727 (lookup *(eax+4) *(eax+8)) # Vardef-var Vardef-var => eax
28728 89/<- %ecx 0/r32/eax
28729 # v->block-depth = *Curr-block-depth
28730 8b/-> *Curr-block-depth 0/r32/eax
28731 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth
28732 # var n/edx: int = size-of(stmt->var)
28733 (size-of %ecx) # => eax
28734 89/<- %edx 0/r32/eax
28735 # *Curr-local-stack-offset -= n
28736 29/subtract-from *Curr-local-stack-offset 2/r32/edx
28737 # v->offset = *Curr-local-stack-offset
28738 8b/-> *Curr-local-stack-offset 0/r32/eax
28739 89/<- *(ecx+0x14) 0/r32/eax # Var-offset
28740 # if v is an array, do something special to initialize it
28742 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
28743 (mu-array? %eax) # => eax
28744 3d/compare-eax-and 0/imm32/false
28745 0f 84/jump-if-= break/disp32
28746 # var array-size-without-size/edx: int = n-4
28747 81 5/subop/subtract %edx 4/imm32
28749 (emit-array-data-initialization *(ebp+8) %edx)
28750 e9/jump $emit-subx-var-def:end/disp32
28752 # another special-case for initializing streams
28753 # a stream is an array with 2 extra pointers
28755 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
28756 (mu-stream? %eax) # => eax
28757 3d/compare-eax-and 0/imm32/false
28758 0f 84/jump-if-= break/disp32
28759 # var array-size-without-size/edx: int = n-12
28760 81 5/subop/subtract %edx 0xc/imm32
28761 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax
28762 (emit-stream-data-initialization *(ebp+8) %edx %eax *(ebp+0x10) *(ebp+0x14))
28763 # emit read and write pointers
28764 (emit-indent *(ebp+8) *Curr-block-depth)
28765 (write-buffered *(ebp+8) "68/push 0/imm32\n")
28766 (emit-indent *(ebp+8) *Curr-block-depth)
28767 (write-buffered *(ebp+8) "68/push 0/imm32\n")
28769 eb/jump $emit-subx-var-def:end/disp8
28773 81 7/subop/compare %edx 0/imm32
28774 7e/jump-if-<= break/disp8
28775 (emit-indent *(ebp+8) *Curr-block-depth)
28776 (write-buffered *(ebp+8) "68/push 0/imm32\n")
28778 81 5/subop/subtract %edx 4/imm32
28782 $emit-subx-var-def:end:
28783 # . restore registers
28788 89/<- %esp 5/r32/ebp
28792 emit-array-data-initialization: # out: (addr buffered-file), n: int
28795 89/<- %ebp 4/r32/esp
28797 (emit-indent *(ebp+8) *Curr-block-depth)
28798 (write-buffered *(ebp+8) "(push-n-zero-bytes ")
28799 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc))
28800 (write-buffered *(ebp+8) ")\n")
28801 (emit-indent *(ebp+8) *Curr-block-depth)
28802 (write-buffered *(ebp+8) "68/push ")
28803 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc))
28804 (write-buffered *(ebp+8) "/imm32\n")
28805 $emit-array-data-initialization:end:
28807 89/<- %esp 5/r32/ebp
28811 emit-stream-data-initialization: # out: (addr buffered-file), n: int, type: (addr type-tree), err: (addr buffered-file), ed: (addr exit-descriptor)
28814 89/<- %ebp 4/r32/esp
28817 # Optimization: if it's a stream of bytes, don't initialize.
28819 # We often construct large temporary streams on the stack for 'trace'
28820 # statements. Initializing such streams can significantly slow programs
28823 # Mu doesn't really depend on initializing stream contents for type- or
28824 # memory-safety; we're mostly doing so to make it easy to debug unsafe
28825 # SubX code that misuses stream objects by manipulating read/write
28826 # pointers. But you can't _really_ protect from unsafe SubX, so I think we
28827 # don't give up much safety or security here.
28829 (stream-element-type-id *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) # => eax
28830 3d/compare-eax-and 8/imm32/byte
28831 75/jump-if-!= break/disp8
28832 (emit-indent *(ebp+8) *Curr-block-depth)
28833 (write-buffered *(ebp+8) "81 5/subop/subtract %esp ")
28834 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc))
28835 (write-buffered *(ebp+8) "/imm32\n")
28836 eb/jump $emit-stream-data-initialization:emit-length/disp8
28838 (emit-indent *(ebp+8) *Curr-block-depth)
28839 (write-buffered *(ebp+8) "(push-n-zero-bytes ")
28840 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc))
28841 (write-buffered *(ebp+8) ")\n")
28842 $emit-stream-data-initialization:emit-length:
28843 (emit-indent *(ebp+8) *Curr-block-depth)
28844 (write-buffered *(ebp+8) "68/push ")
28845 (write-int32-hex-buffered *(ebp+8) *(ebp+0xc))
28846 (write-buffered *(ebp+8) "/imm32\n")
28847 $emit-stream-data-initialization:end:
28848 # . restore registers
28851 89/<- %esp 5/r32/ebp
28855 emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (addr primitive), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
28858 89/<- %ebp 4/r32/esp
28862 # - some special-case primitives that don't actually use the 'primitives' data structure
28863 # var op/ecx: (addr array byte) = lookup(stmt->operation)
28864 8b/-> *(ebp+0xc) 1/r32/ecx
28865 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax
28866 89/<- %ecx 0/r32/eax
28867 # copy byte (can be a primitive except we need to emit a second instruction)
28869 # if (!string-equal?(stmt->operation, "copy-byte")) break
28870 (string-equal? %ecx "copy-byte") # => eax
28871 3d/compare-eax-and 0/imm32/false
28872 0f 84/jump-if-= break/disp32
28873 (translate-mu-copy-byte-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c))
28874 e9/jump $emit-subx-stmt:end/disp32
28876 # copy-byte-to can be a primitive; writes to memory don't need to clear surrounding bytes
28879 # if (!string-equal?(stmt->operation, "length")) break
28880 (string-equal? %ecx "length") # => eax
28881 3d/compare-eax-and 0/imm32/false
28882 0f 84/jump-if-= break/disp32
28883 (translate-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c))
28884 e9/jump $emit-subx-stmt:end/disp32
28888 # if (!string-equal?(stmt->operation, "index")) break
28889 (string-equal? %ecx "index") # => eax
28890 3d/compare-eax-and 0/imm32/false
28891 0f 84/jump-if-= break/disp32
28892 (translate-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c))
28893 e9/jump $emit-subx-stmt:end/disp32
28895 # compute-offset for index into array
28897 # if (!string-equal?(stmt->operation, "compute-offset")) break
28898 (string-equal? %ecx "compute-offset") # => eax
28899 3d/compare-eax-and 0/imm32/false
28900 0f 84/jump-if-= break/disp32
28901 (translate-mu-compute-offset-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c))
28902 e9/jump $emit-subx-stmt:end/disp32
28904 # get field from record
28906 # if (!string-equal?(stmt->operation, "get")) break
28907 (string-equal? %ecx "get") # => eax
28908 3d/compare-eax-and 0/imm32/false
28909 0f 84/jump-if-= break/disp32
28910 (translate-mu-get-stmt *(ebp+8) *(ebp+0xc))
28911 e9/jump $emit-subx-stmt:end/disp32
28915 # if (!string-equal?(stmt->operation, "allocate")) break
28916 (string-equal? %ecx "allocate") # => eax
28917 3d/compare-eax-and 0/imm32/false
28918 0f 84/jump-if-= break/disp32
28919 (translate-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c))
28920 e9/jump $emit-subx-stmt:end/disp32
28924 # if (!string-equal?(stmt->operation, "copy-object")) break
28925 (string-equal? %ecx "copy-object") # => eax
28926 3d/compare-eax-and 0/imm32/false
28927 0f 84/jump-if-= break/disp32
28928 (translate-mu-copy-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c))
28929 e9/jump $emit-subx-stmt:end/disp32
28933 # if (!string-equal?(stmt->operation, "clear-object")) break
28934 (string-equal? %ecx "clear-object") # => eax
28935 3d/compare-eax-and 0/imm32/false
28936 0f 84/jump-if-= break/disp32
28937 (translate-mu-clear-object-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c))
28938 e9/jump $emit-subx-stmt:end/disp32
28942 # if (!string-equal?(stmt->operation, "populate")) break
28943 (string-equal? %ecx "populate") # => eax
28944 3d/compare-eax-and 0/imm32/false
28945 0f 84/jump-if-= break/disp32
28946 (translate-mu-populate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c))
28947 e9/jump $emit-subx-stmt:end/disp32
28951 # if (!string-equal?(stmt->operation, "populate-stream")) break
28952 (string-equal? %ecx "populate-stream") # => eax
28953 3d/compare-eax-and 0/imm32/false
28954 0f 84/jump-if-= break/disp32
28955 (translate-mu-populate-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c))
28956 e9/jump $emit-subx-stmt:end/disp32
28960 # if (!string-equal?(stmt->operation, "read-from-stream")) break
28961 (string-equal? %ecx "read-from-stream") # => eax
28962 3d/compare-eax-and 0/imm32/false
28963 0f 84/jump-if-= break/disp32
28964 (translate-mu-read-from-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c))
28965 e9/jump $emit-subx-stmt:end/disp32
28969 # if (!string-equal?(stmt->operation, "write-to-stream")) break
28970 (string-equal? %ecx "write-to-stream") # => eax
28971 3d/compare-eax-and 0/imm32/false
28972 0f 84/jump-if-= break/disp32
28973 (translate-mu-write-to-stream-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c))
28974 e9/jump $emit-subx-stmt:end/disp32
28977 # if copy instruction has same register in source and destination, emit nothing
28978 (redundant-copy? *(ebp+0xc)) # => eax
28979 3d/compare-eax-and 0/imm32/false
28980 75/jump-if-!= $emit-subx-stmt:end/disp8
28981 # - if stmt matches a primitive, emit it
28983 $emit-subx-stmt:check-for-primitive:
28984 # var curr/eax: (addr primitive)
28985 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => eax
28986 3d/compare-eax-and 0/imm32
28987 74/jump-if-= break/disp8
28988 $emit-subx-stmt:primitive:
28989 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr
28990 e9/jump $emit-subx-stmt:end/disp32
28992 # - otherwise emit a call
28993 $emit-subx-stmt:call:
28994 (emit-call *(ebp+8) *(ebp+0xc))
28995 $emit-subx-stmt:end:
28996 # . restore registers
29000 89/<- %esp 5/r32/ebp
29004 redundant-copy?: # stmt: (addr stmt) -> result/eax: boolean
29007 89/<- %ebp 4/r32/esp
29012 8b/-> *(ebp+8) 6/r32/esi
29013 # if stmt->operation != "copy" return false
29014 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax
29015 (string-equal? %eax "copy") # => eax
29016 3d/compare-eax-and 0/imm32/false
29017 0f 84/jump-if-= $redundant-copy?:end/disp32
29018 # var output-reg/edi: (addr stmt-var) = stmt->outputs->value->register
29019 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
29020 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29021 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
29022 # . if output-reg == null, return false
29023 3d/compare-eax-and 0/imm32
29024 74/jump-if-= $redundant-copy?:end/disp8
29025 89/<- %edi 0/r32/eax
29026 # return (inout->value->register == output->value->register)
29027 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
29028 # . if inout->is-deref return false
29029 81 7/subop/compare *(eax+0x10) 0/imm32/false # Stmt-var-is-deref
29031 74/jump-if-= break/disp8
29032 b8/copy-to-eax 0/imm32/false
29033 e9/jump $redundant-copy?:end/disp32
29035 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29036 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
29037 # . if inout-reg == null, return false
29038 3d/compare-eax-and 0/imm32
29039 74/jump-if-= $redundant-copy?:end/disp8
29040 (string-equal? %eax %edi) # => eax
29041 $redundant-copy?:end:
29042 # . restore registers
29046 89/<- %esp 5/r32/ebp
29050 translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
29053 89/<- %ebp 4/r32/esp
29061 8b/-> *(ebp+0xc) 6/r32/esi
29062 # var base/ebx: (addr var) = stmt->inouts[0]->value
29063 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
29064 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29065 89/<- %ebx 0/r32/eax
29066 # var elemsize/ecx: int = array-element-size(base)
29067 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax
29068 89/<- %ecx 0/r32/eax
29069 # var outreg/edx: (addr array byte) = stmt->outputs[0]->value->register
29070 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
29071 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29072 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
29073 89/<- %edx 0/r32/eax
29076 81 7/subop/compare %ecx 1/imm32
29077 75/jump-if-!= break/disp8
29078 $translate-mu-length-stmt:size-1:
29079 (emit-save-size-to *(ebp+8) %ebx %edx)
29080 e9/jump $translate-mu-length-stmt:end/disp32
29082 # if elemsize is a power of 2 less than 256
29084 (power-of-2? %ecx *(ebp+0x10) *(ebp+0x14)) # => eax
29085 3d/compare-eax-and 0/imm32/false
29086 74/jump-if-= break/disp8
29087 81 7/subop/compare %ecx 0xff/imm32
29088 7f/jump-if-> break/disp8
29089 $translate-mu-length-stmt:size-power-of-2:
29090 (emit-save-size-to *(ebp+8) %ebx %edx)
29091 (emit-divide-by-shift-right *(ebp+8) %edx %ecx)
29092 e9/jump $translate-mu-length-stmt:end/disp32
29094 # otherwise, the complex case
29095 # . emit register spills
29097 $translate-mu-length-stmt:complex:
29098 (string-equal? %edx "eax") # => eax
29099 3d/compare-eax-and 0/imm32/false
29100 75/break-if-!= break/disp8
29101 (emit-indent *(ebp+8) *Curr-block-depth)
29102 (write-buffered *(ebp+8) "50/push-eax\n")
29105 (string-equal? %edx "ecx") # => eax
29106 3d/compare-eax-and 0/imm32/false
29107 75/break-if-!= break/disp8
29108 (emit-indent *(ebp+8) *Curr-block-depth)
29109 (write-buffered *(ebp+8) "51/push-ecx\n")
29112 (string-equal? %edx "edx") # => eax
29113 3d/compare-eax-and 0/imm32/false
29114 75/break-if-!= break/disp8
29115 (emit-indent *(ebp+8) *Curr-block-depth)
29116 (write-buffered *(ebp+8) "52/push-edx\n")
29119 (emit-save-size-to *(ebp+8) %ebx "eax")
29120 (emit-indent *(ebp+8) *Curr-block-depth)
29121 (write-buffered *(ebp+8) "31/xor %edx 2/r32/edx\n")
29122 (emit-indent *(ebp+8) *Curr-block-depth)
29123 (write-buffered *(ebp+8) "b9/copy-to-ecx ")
29124 (write-int32-hex-buffered *(ebp+8) %ecx)
29125 (write-buffered *(ebp+8) "/imm32\n")
29126 (emit-indent *(ebp+8) *Curr-block-depth)
29127 (write-buffered *(ebp+8) "f7 7/subop/idiv-eax-edx-by %ecx\n")
29129 (string-equal? %edx "eax") # => eax
29130 3d/compare-eax-and 0/imm32/false
29131 75/break-if-!= break/disp8
29132 (emit-indent *(ebp+8) *Curr-block-depth)
29133 (write-buffered *(ebp+8) "89/<- %")
29134 (write-buffered *(ebp+8) %edx)
29135 (write-buffered *(ebp+8) " 0/r32/eax\n")
29137 # . emit register restores
29139 (string-equal? %edx "edx") # => eax
29140 3d/compare-eax-and 0/imm32/false
29141 75/break-if-!= break/disp8
29142 (emit-indent *(ebp+8) *Curr-block-depth)
29143 (write-buffered *(ebp+8) "5a/pop-to-edx\n")
29146 (string-equal? %edx "ecx") # => eax
29147 3d/compare-eax-and 0/imm32/false
29148 75/break-if-!= break/disp8
29149 (emit-indent *(ebp+8) *Curr-block-depth)
29150 (write-buffered *(ebp+8) "59/pop-to-ecx\n")
29153 (string-equal? %edx "eax") # => eax
29154 3d/compare-eax-and 0/imm32/false
29155 75/break-if-!= break/disp8
29156 (emit-indent *(ebp+8) *Curr-block-depth)
29157 (write-buffered *(ebp+8) "58/pop-to-eax\n")
29159 $translate-mu-length-stmt:end:
29160 # . restore registers
29167 89/<- %esp 5/r32/ebp
29171 array-element-size: # arr: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int
29174 89/<- %ebp 4/r32/esp
29176 (array-element-type-id *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax
29177 (size-of-type-id-as-array-element %eax) # => eax
29178 $array-element-size:end:
29180 89/<- %esp 5/r32/ebp
29184 array-element-type-id: # v: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: type-id
29185 # precondition: n is positive
29188 89/<- %ebp 4/r32/esp
29190 8b/-> *(ebp+8) 0/r32/eax
29191 # var t/eax: (addr type-tree)
29192 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
29194 3d/compare-eax-with 0/imm32
29195 0f 84/jump-if-== $array-element-type-id:error0/disp32
29196 # if t->is-atom? abort
29197 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
29198 0f 85/jump-if-!= $array-element-type-id:error1/disp32
29199 # if (t->left == addr) t = t->right
29202 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
29203 (simple-mu-type? %eax 2) # addr => eax
29204 3d/compare-eax-with 0/imm32/false
29206 74/jump-if-= break/disp8
29207 $array-element-type-id:skip-addr:
29208 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
29211 3d/compare-eax-with 0/imm32
29212 0f 84/jump-if-= $array-element-type-id:error2/disp32
29213 # if t->is-atom? abort
29214 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
29215 0f 85/jump-if-!= $array-element-type-id:error2/disp32
29216 # if t->left != array abort
29219 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
29220 (simple-mu-type? %eax 3) # array => eax
29221 3d/compare-eax-with 0/imm32/false
29223 $array-element-type-id:no-array:
29224 0f 84/jump-if-= $array-element-type-id:error2/disp32
29226 $array-element-type-id:skip-array:
29228 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
29230 3d/compare-eax-with 0/imm32
29231 0f 84/jump-if-= $array-element-type-id:error2/disp32
29232 # if t->is-atom? abort
29233 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
29234 0f 85/jump-if-!= $array-element-type-id:error2/disp32
29236 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
29237 # if (!t->is-atom?) t = t->left # TODO: assumes array element size can be determined from just first word of array element type
29238 # if (t->is-atom == false) t = lookup(t->left)
29240 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
29241 75/jump-if-!= break/disp8
29242 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
29245 8b/-> *(eax+4) 0/r32/eax # Type-tree-value
29246 $array-element-type-id:end:
29248 89/<- %esp 5/r32/ebp
29252 $array-element-type-id:error0:
29253 (write-buffered *(ebp+0xc) "array-element-type-id: var '")
29255 8b/-> *(ebp+8) 0/r32/eax
29256 (lookup *eax *(eax+4)) # Var-name Var-name => eax
29257 (write-buffered *(ebp+0xc) %eax)
29259 (write-buffered *(ebp+0xc) "' has no type\n")
29261 (stop *(ebp+0x10) 1)
29264 $array-element-type-id:error1:
29265 (write-buffered *(ebp+0xc) "array-element-type-id: var '")
29267 8b/-> *(ebp+8) 0/r32/eax
29268 (lookup *eax *(eax+4)) # Var-name Var-name => eax
29269 (write-buffered *(ebp+0xc) %eax)
29271 (write-buffered *(ebp+0xc) "' has atomic type ")
29272 (write-int32-hex-buffered *(ebp+0xc) *(eax+4)) # Type-tree-value
29273 (write-buffered *(ebp+0xc) Newline)
29275 (stop *(ebp+0x10) 1)
29278 $array-element-type-id:error2:
29279 (write-buffered *(ebp+0xc) "array-element-type-id: var '")
29281 8b/-> *(ebp+8) 0/r32/eax
29282 (lookup *eax *(eax+4)) # Var-name Var-name => eax
29283 (write-buffered *(ebp+0xc) %eax)
29285 (write-buffered *(ebp+0xc) "' has non-array type\n")
29287 (stop *(ebp+0x10) 1)
29290 size-of-type-id-as-array-element: # t: type-id -> result/eax: int
29293 89/<- %ebp 4/r32/esp
29295 8b/-> *(ebp+8) 0/r32/eax
29296 # if t is 'byte', size is 1
29297 3d/compare-eax-and 8/imm32/byte
29299 75/jump-if-!= break/disp8
29300 b8/copy-to-eax 1/imm32
29301 eb/jump $size-of-type-id-as-array-element:end/disp8
29303 # otherwise proceed as usual
29304 (size-of-type-id %eax) # => eax
29305 $size-of-type-id-as-array-element:end:
29307 89/<- %esp 5/r32/ebp
29311 stream-element-type-id: # type: (addr type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: type-id
29312 # precondition: n is positive
29315 89/<- %ebp 4/r32/esp
29317 8b/-> *(ebp+8) 0/r32/eax
29318 # if type == 0 abort
29319 3d/compare-eax-with 0/imm32
29320 0f 84/jump-if-== $stream-element-type-id:error0/disp32
29321 # if type->is-atom? abort
29322 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
29323 0f 85/jump-if-!= $stream-element-type-id:error1/disp32
29324 # if (type->left == addr) type = type->right
29327 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
29328 (simple-mu-type? %eax 2) # addr => eax
29329 3d/compare-eax-with 0/imm32/false
29331 74/jump-if-= break/disp8
29332 $stream-element-type-id:skip-addr:
29333 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
29335 # if type == 0 abort
29336 3d/compare-eax-with 0/imm32
29337 0f 84/jump-if-= $stream-element-type-id:error2/disp32
29338 # if type->is-atom? abort
29339 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
29340 0f 85/jump-if-!= $stream-element-type-id:error2/disp32
29341 # if type->left != stream abort
29344 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
29345 (simple-mu-type? %eax 0xb) # stream => eax
29346 3d/compare-eax-with 0/imm32/false
29348 $stream-element-type-id:no-stream:
29349 0f 84/jump-if-= $stream-element-type-id:error2/disp32
29351 $stream-element-type-id:skip-stream:
29352 # type = type->right
29353 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
29354 # if type == 0 abort
29355 3d/compare-eax-with 0/imm32
29356 0f 84/jump-if-= $stream-element-type-id:error2/disp32
29357 # if type->is-atom? abort
29358 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
29359 0f 85/jump-if-!= $stream-element-type-id:error2/disp32
29361 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
29362 # if (!type->is-atom?) type = type->left # TODO: assumes stream element size can be determined from just first word of stream element type
29364 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
29365 75/jump-if-!= break/disp8
29366 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
29368 # return type->value
29369 8b/-> *(eax+4) 0/r32/eax # Type-tree-value
29370 $stream-element-type-id:end:
29372 89/<- %esp 5/r32/ebp
29376 $stream-element-type-id:error0:
29377 (write-buffered *(ebp+0xc) "stream-element-type-id: var '")
29379 8b/-> *(ebp+8) 0/r32/eax
29380 (lookup *eax *(eax+4)) # Var-name Var-name => eax
29381 (write-buffered *(ebp+0xc) %eax)
29383 (write-buffered *(ebp+0xc) "' has no type\n")
29385 (stop *(ebp+0x10) 1)
29388 $stream-element-type-id:error1:
29389 (write-buffered *(ebp+0xc) "stream-element-type-id: var '")
29391 8b/-> *(ebp+8) 0/r32/eax
29392 (lookup *eax *(eax+4)) # Var-name Var-name => eax
29393 (write-buffered *(ebp+0xc) %eax)
29395 (write-buffered *(ebp+0xc) "' has atomic type ")
29396 (write-int32-hex-buffered *(ebp+0xc) *(eax+4)) # Type-tree-value
29397 (write-buffered *(ebp+0xc) Newline)
29399 (stop *(ebp+0x10) 1)
29402 $stream-element-type-id:error2:
29403 (write-buffered *(ebp+0xc) "stream-element-type-id: var '")
29405 8b/-> *(ebp+8) 0/r32/eax
29406 (lookup *eax *(eax+4)) # Var-name Var-name => eax
29407 (write-buffered *(ebp+0xc) %eax)
29409 (write-buffered *(ebp+0xc) "' has non-stream type\n")
29411 (stop *(ebp+0x10) 1)
29414 emit-save-size-to: # out: (addr buffered-file), base: (addr var), outreg: (addr array byte)
29417 89/<- %ebp 4/r32/esp
29422 8b/-> *(ebp+0xc) 3/r32/ebx
29423 (emit-indent *(ebp+8) *Curr-block-depth)
29424 (write-buffered *(ebp+8) "8b/-> *")
29425 # if base is an (addr array ...) in a register
29427 81 7/subop/compare *(ebx+0x18)) 0/imm32 # Var-register
29428 74/jump-if-= break/disp8
29429 $emit-save-size-to:emit-base-from-register:
29430 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax
29431 (write-buffered *(ebp+8) %eax)
29432 eb/jump $emit-save-size-to:emit-output/disp8
29434 # otherwise if base is an (array ...) on the stack
29436 81 7/subop/compare *(ebx+0x14)) 0/imm32 # Var-offset
29437 74/jump-if-= break/disp8
29438 $emit-save-size-to:emit-base-from-stack:
29439 (write-buffered *(ebp+8) "(ebp+")
29440 (write-int32-hex-buffered *(ebp+8) *(ebx+0x14)) # Var-offset
29441 (write-buffered *(ebp+8) ")")
29443 $emit-save-size-to:emit-output:
29444 (write-buffered *(ebp+8) " ")
29445 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax
29446 (write-int32-hex-buffered *(ebp+8) *eax)
29447 (write-buffered *(ebp+8) "/r32\n")
29448 $emit-save-size-to:end:
29449 # . restore registers
29453 89/<- %esp 5/r32/ebp
29457 emit-divide-by-shift-right: # out: (addr buffered-file), reg: (addr array byte), size: int
29460 89/<- %ebp 4/r32/esp
29464 (emit-indent *(ebp+8) *Curr-block-depth)
29465 (write-buffered *(ebp+8) "c1/shift 5/subop/>> %")
29466 (write-buffered *(ebp+8) *(ebp+0xc))
29467 (write-buffered *(ebp+8) Space)
29468 (num-shift-rights *(ebp+0x10)) # => eax
29469 (write-int32-hex-buffered *(ebp+8) %eax)
29470 (write-buffered *(ebp+8) "/imm8\n")
29471 $emit-divide-by-shift-right:end:
29472 # . restore registers
29475 89/<- %esp 5/r32/ebp
29479 translate-mu-copy-byte-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
29482 89/<- %ebp 4/r32/esp
29487 8b/-> *(ebp+0xc) 6/r32/esi
29489 (emit-indent *(ebp+8) *Curr-block-depth)
29490 (write-buffered *(ebp+8) "8a/byte->")
29491 # emit stmt->inouts[0]
29492 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
29493 (emit-subx-var-as-rm32 *(ebp+8) %eax)
29494 # emit /r32 for stmt->outputs[0]->register
29495 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
29496 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29497 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
29498 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index)
29499 (write-buffered *(ebp+8) Space)
29500 (write-int32-hex-buffered *(ebp+8) *eax)
29501 (write-buffered *(ebp+8) "/r32\n")
29502 # clear rest of register
29503 (emit-indent *(ebp+8) *Curr-block-depth)
29504 (write-buffered *(ebp+8) "81 4/subop/and %")
29505 8b/-> *(ebp+0xc) 0/r32/eax
29506 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
29507 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29508 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
29509 (write-buffered *(ebp+8) %eax)
29510 (write-buffered *(ebp+8) " 0xff/imm32\n")
29511 $translate-mu-copy-byte-stmt:end:
29512 # . restore registers
29516 89/<- %esp 5/r32/ebp
29520 # a little different from other translate- functions; notice the extra 'fn' argument
29521 translate-mu-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
29524 89/<- %ebp 4/r32/esp
29528 8b/-> *(ebp+0xc) 3/r32/ebx
29529 # var base/ebx: (addr var) = stmt->inouts[0]
29530 (lookup *(ebx+0xc) *(ebx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
29531 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29532 89/<- %ebx 0/r32/eax
29533 # emit bounds-check
29534 (emit-mu-index-bounds-check *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18))
29535 # if (var->register) do one thing
29537 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register
29538 74/jump-if-= break/disp8
29539 # TODO: ensure there's no dereference
29540 (translate-mu-index-stmt-with-array-in-register *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18))
29541 eb/jump $translate-mu-index-stmt:end/disp8
29543 # if (var->offset) do a different thing
29545 81 7/subop/compare *(ebx+0x14) 0/imm32 # Var-offset
29546 74/jump-if-= break/disp8
29547 # TODO: ensure there's no dereference
29548 (translate-mu-index-stmt-with-array-on-stack *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18))
29549 eb/jump $translate-mu-index-stmt:end/disp8
29551 $translate-mu-index-stmt:end:
29552 # . restore registers
29555 89/<- %esp 5/r32/ebp
29559 $translate-mu-index-stmt:error1:
29560 (write-buffered *(ebp+0x14) "couldn't translate an index instruction. second (index) input must either lie in a register or be a literal\n")
29561 (flush *(ebp+0x14))
29562 (stop *(ebp+0x18) 1)
29565 $translate-mu-index-stmt:error2:
29566 (write-buffered *(ebp+0x14) "couldn't translate an index instruction. second (index) input when in a register must be an int or offset\n")
29567 (flush *(ebp+0x14))
29568 (stop *(ebp+0x18) 1)
29571 emit-mu-index-bounds-check: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
29574 89/<- %ebp 4/r32/esp
29581 8b/-> *(ebp+0xc) 1/r32/ecx
29583 (emit-indent *(ebp+8) *Curr-block-depth)
29584 (write-buffered *(ebp+8) "(__check-mu-array-bounds ")
29585 $emit-mu-index-bounds-check:compute-base:
29586 # var base/ebx: (addr var) = inouts[0]
29587 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
29588 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29589 89/<- %ebx 0/r32/eax
29590 $emit-mu-index-bounds-check:emit-index:
29591 # var index/edx: (addr var) = inouts[1]
29592 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
29593 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
29594 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29595 89/<- %edx 0/r32/eax
29596 # if index->register, print its code
29597 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register
29599 0f 84/jump-if-= break/disp32
29600 $emit-mu-index-bounds-check:emit-register-index:
29601 (write-buffered *(ebp+8) "%")
29602 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax
29603 (write-buffered *(ebp+8) %eax)
29604 eb/jump $emit-mu-index-bounds-check:index-done/disp8
29606 # otherwise if index is a literal, print it
29607 $emit-mu-index-bounds-check:emit-literal-index:
29608 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
29609 (simple-mu-type? %eax 0) # => eax
29610 3d/compare-eax-and 0/imm32/false
29612 0f 84/jump-if-= break/disp32
29613 (lookup *edx *(edx+4)) # Var-name Var-name => eax
29614 (write-buffered *(ebp+8) %eax)
29616 $emit-mu-index-bounds-check:index-done:
29617 (write-buffered *(ebp+8) " ")
29618 $emit-mu-index-bounds-check:emit-element-size:
29619 # if index is a literal or int, print size of array element
29622 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
29623 (simple-mu-type? %eax 0) # literal => eax
29624 3d/compare-eax-and 0/imm32/false
29625 75/jump-if-!= break/disp8
29626 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
29627 (simple-mu-type? %eax 1) # int => eax
29628 3d/compare-eax-and 0/imm32/false
29629 75/jump-if-!= break/disp8
29630 eb/jump $emit-mu-index-bounds-check:emit-element-size-offset/disp8
29632 $emit-mu-index-bounds-check:emit-int-register-index:
29633 (array-element-size %ebx *(ebp+0x14) *(ebp+0x18)) # => eax
29634 (write-int32-hex-buffered *(ebp+8) %eax)
29635 e9/jump $emit-mu-index-bounds-check:emit-base/disp32
29637 $emit-mu-index-bounds-check:emit-element-size-offset:
29638 # if index has type (offset ...), print "1"
29639 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
29640 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
29642 75/jump-if-!= break/disp8
29643 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
29644 (simple-mu-type? %eax 7) # => eax
29645 3d/compare-eax-and 0/imm32/false
29647 0f 84/jump-if-= break/disp32
29648 $emit-mu-index-bounds-check:emit-offset-register-index:
29649 (write-buffered *(ebp+8) "1")
29652 $emit-mu-index-bounds-check:emit-base:
29653 # if base is in a register, print " *" base->register
29654 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register
29656 74/jump-if-= break/disp8
29657 (write-buffered *(ebp+8) " *")
29658 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax
29659 (write-buffered *(ebp+8) %eax)
29660 e9/jump $emit-mu-index-bounds-check:emit-function-name/disp32
29662 # otherwise print " *(ebp+" base->offset ")"
29663 (write-buffered *(ebp+8) " *(ebp+")
29664 (write-int32-hex-buffered *(ebp+8) *(ebx+0x14)) # Var-offset
29665 (write-buffered *(ebp+8) ")")
29666 $emit-mu-index-bounds-check:emit-function-name:
29667 # " \"" function-name "\""
29668 (write-buffered *(ebp+8) " \"")
29669 8b/-> *(ebp+0x10) 1/r32/ecx
29670 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax
29671 (write-buffered *(ebp+8) %eax)
29672 (write-buffered *(ebp+8) "\"")
29673 $emit-mu-index-bounds-check:emit-array-name:
29674 # " \"" base->name "\""
29675 (write-buffered *(ebp+8) " \"")
29676 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax
29677 (write-buffered *(ebp+8) %eax)
29678 (write-buffered *(ebp+8) "\")\n")
29679 $emit-mu-index-bounds-check:end:
29680 # . restore registers
29686 89/<- %esp 5/r32/ebp
29690 translate-mu-index-stmt-with-array-in-register: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
29693 89/<- %ebp 4/r32/esp
29700 8b/-> *(ebp+0xc) 1/r32/ecx
29701 # var base/ebx: (addr var) = inouts[0]
29702 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
29703 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29704 89/<- %ebx 0/r32/eax
29706 (emit-indent *(ebp+8) *Curr-block-depth)
29707 (write-buffered *(ebp+8) "81 7/subop/compare %")
29708 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax
29709 (write-buffered *(ebp+8) %eax)
29710 (write-buffered *(ebp+8) " 0/imm32\n")
29711 (emit-indent *(ebp+8) *Curr-block-depth)
29712 (write-buffered *(ebp+8) "0f 84/jump-if-= __mu-abort-null-index-base-address/disp32\n")
29714 (emit-indent *(ebp+8) *Curr-block-depth)
29715 (write-buffered *(ebp+8) "8d/copy-address *(")
29716 # TODO: ensure inouts[0] is in a register and not dereferenced
29717 $translate-mu-index-stmt-with-array-in-register:emit-base:
29718 # print base->register " + "
29719 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax
29720 (write-buffered *(ebp+8) %eax)
29721 (write-buffered *(ebp+8) " + ")
29722 # var index/edx: (addr var) = inouts[1]
29723 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
29724 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
29725 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29726 89/<- %edx 0/r32/eax
29727 # if index->register
29728 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register
29730 0f 84/jump-if-= break/disp32
29731 $translate-mu-index-stmt-with-array-in-register:emit-register-index:
29732 # if index is an int
29733 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
29734 (simple-mu-type? %eax 1) # int => eax
29735 3d/compare-eax-and 0/imm32/false
29737 0f 84/jump-if-= break/disp32
29738 $translate-mu-index-stmt-with-array-in-register:emit-int-register-index:
29739 # print index->register "<<" log2(array-element-size(base)) " + 4) "
29740 # . index->register "<<"
29741 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax
29742 (write-buffered *(ebp+8) %eax)
29743 (write-buffered *(ebp+8) "<<")
29744 # . log2(array-element-size(base->type))
29745 # we know size is a power of 2
29746 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax
29747 (num-shift-rights %eax) # => eax
29748 (write-int32-hex-buffered *(ebp+8) %eax)
29749 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-register-index-done/disp32
29751 # if index->type is any other atom, abort
29752 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
29753 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
29754 0f 85/jump-if-!= $translate-mu-index-stmt:error2/disp32
29755 # if index has type (offset ...)
29756 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
29757 (simple-mu-type? %eax 7) # => eax
29758 3d/compare-eax-and 0/imm32/false
29760 0f 84/jump-if-= break/disp32
29761 # print index->register
29762 $translate-mu-index-stmt-with-array-in-register:emit-offset-register-index:
29763 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax
29764 (write-buffered *(ebp+8) %eax)
29766 $translate-mu-index-stmt-with-array-in-register:emit-register-index-done:
29767 (write-buffered *(ebp+8) " + 4) ")
29768 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32
29770 # otherwise if index is a literal
29771 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
29772 (simple-mu-type? %eax 0) # => eax
29773 3d/compare-eax-and 0/imm32/false
29775 0f 84/jump-if-= break/disp32
29776 $translate-mu-index-stmt-with-array-in-register:emit-literal-index:
29777 # var index-value/edx: int = parse-hex-int(index->name)
29778 (lookup *edx *(edx+4)) # Var-name Var-name => eax
29779 (parse-hex-int %eax) # => eax
29780 89/<- %edx 0/r32/eax
29781 # offset = idx-value * array-element-size(base->type)
29782 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax
29783 f7 4/subop/multiply-into-edx-eax %edx # clobbers edx
29784 # offset += 4 for array size
29785 05/add-to-eax 4/imm32
29786 # TODO: check edx for overflow
29788 (write-int32-hex-buffered *(ebp+8) %eax)
29789 (write-buffered *(ebp+8) ") ")
29790 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32
29793 e9/jump $translate-mu-index-stmt:error1/disp32
29794 $translate-mu-index-stmt-with-array-in-register:emit-output:
29795 # outputs[0] "/r32"
29796 8b/-> *(ebp+0xc) 1/r32/ecx
29797 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax
29798 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29799 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
29800 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int)
29801 (write-int32-hex-buffered *(ebp+8) *eax)
29802 (write-buffered *(ebp+8) "/r32\n")
29803 $translate-mu-index-stmt-with-array-in-register:end:
29804 # . restore registers
29810 89/<- %esp 5/r32/ebp
29814 translate-mu-index-stmt-with-array-on-stack: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
29817 89/<- %ebp 4/r32/esp
29824 (emit-indent *(ebp+8) *Curr-block-depth)
29825 (write-buffered *(ebp+8) "8d/copy-address *(ebp + ")
29826 # var curr/edx: (addr stmt-var) = lookup(stmt->inouts)
29827 8b/-> *(ebp+0xc) 0/r32/eax
29828 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax
29829 89/<- %edx 0/r32/eax
29830 # var base/ecx: (addr var) = lookup(curr->value)
29831 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29832 89/<- %ecx 0/r32/eax
29833 # var curr2/eax: (addr stmt-var) = lookup(curr->next)
29834 (lookup *(edx+8) *(edx+0xc)) # Stmt-var-next Stmt-var-next => eax
29835 # var index/edx: (handle var) = curr2->value
29836 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29837 89/<- %edx 0/r32/eax
29838 # if index->register
29839 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register
29841 0f 84/jump-if-= break/disp32
29842 $translate-mu-index-stmt-with-array-on-stack:emit-register-index:
29843 # if index is an int
29844 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
29845 (simple-mu-type? %eax 1) # int => eax
29846 3d/compare-eax-and 0/imm32/false
29848 0f 84/jump-if-= break/disp32
29849 $translate-mu-index-stmt-with-array-on-stack:emit-int-register-index:
29850 # print index->register "<<" log2(array-element-size(base)) " + " base->offset+4
29851 # . inouts[1]->register "<<"
29852 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax
29853 (write-buffered *(ebp+8) %eax)
29854 (write-buffered *(ebp+8) "<<")
29855 # . log2(array-element-size(base))
29856 # TODO: ensure size is a power of 2
29857 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax
29858 (num-shift-rights %eax) # => eax
29859 (write-int32-hex-buffered *(ebp+8) %eax)
29861 (write-buffered *(ebp+8) " + ")
29863 8b/-> *(ecx+0x14) 0/r32/eax # Var-offset
29864 05/add-to-eax 4/imm32 # for array length
29865 (write-int32-hex-buffered *(ebp+8) %eax)
29866 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done/disp32
29868 # if index->type is any other atom, abort
29869 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
29870 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
29871 0f 85/jump-if-!= $translate-mu-index-stmt:error2/disp32
29872 # if index has type (offset ...)
29873 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
29874 (simple-mu-type? %eax 7) # => eax
29875 3d/compare-eax-and 0/imm32/false
29877 0f 84/jump-if-= break/disp32
29878 # print index->register
29879 $translate-mu-index-stmt-with-array-on-stack:emit-offset-register-index:
29880 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax
29881 (write-buffered *(ebp+8) %eax)
29883 $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done:
29884 (write-buffered *(ebp+8) ") ")
29885 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32
29887 # otherwise if index is a literal
29888 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax
29889 (simple-mu-type? %eax 0) # => eax
29890 3d/compare-eax-and 0/imm32/false
29892 0f 84/jump-if-= break/disp32
29893 $translate-mu-index-stmt-with-array-on-stack:emit-literal-index:
29894 # var idx-value/edx: int = parse-hex-int(index->name)
29895 (lookup *edx *(edx+4)) # Var-name Var-name => eax
29896 (parse-hex-int %eax) # => eax
29897 89/<- %edx 0/r32/eax
29898 # offset = idx-value * array-element-size(base)
29899 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax
29900 f7 4/subop/multiply-into-edx-eax %edx # clobbers edx
29901 # offset += base->offset
29902 03/add *(ecx+0x14) 0/r32/eax # Var-offset
29903 # offset += 4 for array size
29904 05/add-to-eax 4/imm32
29905 # TODO: check edx for overflow
29907 (write-int32-hex-buffered *(ebp+8) %eax)
29908 (write-buffered *(ebp+8) ") ")
29909 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32
29912 e9/jump $translate-mu-index-stmt:error1/disp32
29913 $translate-mu-index-stmt-with-array-on-stack:emit-output:
29914 # outputs[0] "/r32"
29915 8b/-> *(ebp+0xc) 0/r32/eax
29916 (lookup *(eax+0x14) *(eax+0x18)) # Stmt1-outputs Stmt1-outputs => eax
29917 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29918 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
29919 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int)
29920 (write-int32-hex-buffered *(ebp+8) *eax)
29921 (write-buffered *(ebp+8) "/r32\n")
29922 $translate-mu-index-stmt-with-array-on-stack:end:
29923 # . restore registers
29929 89/<- %esp 5/r32/ebp
29933 translate-mu-compute-offset-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
29936 89/<- %ebp 4/r32/esp
29939 # var index-type/eax: (addr type-tree) = stmt->inouts->next->value->type
29940 8b/-> *(ebp+0xc) 0/r32/eax
29941 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax
29942 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
29943 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29944 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
29945 (simple-mu-type? %eax 0) # literal => eax
29946 3d/compare-eax-and 0/imm32/false
29948 74/jump-if-= break/disp8
29949 # special-case: index is a literal
29950 (translate-mu-compute-offset-stmt-with-literal-index *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
29951 eb/jump $translate-mu-compute-offset-stmt:end/disp8
29953 (translate-mu-compute-offset-stmt-with-register-index *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
29954 $translate-mu-compute-offset-stmt:end:
29955 # . restore registers
29958 89/<- %esp 5/r32/ebp
29962 translate-mu-compute-offset-stmt-with-register-index: # out: (addr buffered-file), stmt-with-register-index: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
29965 89/<- %ebp 4/r32/esp
29972 (emit-indent *(ebp+8) *Curr-block-depth)
29973 (write-buffered *(ebp+8) "69/multiply")
29975 8b/-> *(ebp+0xc) 1/r32/ecx
29976 # var first-inout/ebx: (addr stmt-var) = stmt->inouts[0]
29977 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
29978 89/<- %ebx 0/r32/eax
29979 $translate-mu-compute-offset-stmt-with-register-index:emit-index:
29980 (lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax
29981 (emit-subx-var-as-rm32 *(ebp+8) %eax)
29982 (write-buffered *(ebp+8) Space)
29983 $translate-mu-compute-offset-stmt-with-register-index:emit-elem-size:
29984 # var base/ebx: (addr var)
29985 (lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax
29986 89/<- %ebx 0/r32/eax
29987 # print array-element-size(base)
29988 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax
29989 (write-int32-hex-buffered *(ebp+8) %eax)
29990 (write-buffered *(ebp+8) "/imm32 ")
29991 $translate-mu-compute-offset-stmt-with-register-index:emit-output:
29992 # outputs[0] "/r32"
29993 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax
29994 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
29995 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
29996 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int)
29997 (write-int32-hex-buffered *(ebp+8) *eax)
29998 (write-buffered *(ebp+8) "/r32\n")
29999 $translate-mu-compute-offset-stmt-with-register-index:end:
30000 # . restore registers
30006 89/<- %esp 5/r32/ebp
30010 translate-mu-compute-offset-stmt-with-literal-index: # out: (addr buffered-file), stmt-with-literal-index: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
30013 89/<- %ebp 4/r32/esp
30020 (emit-indent *(ebp+8) *Curr-block-depth)
30021 (write-buffered *(ebp+8) "c7/copy %")
30023 8b/-> *(ebp+0xc) 1/r32/ecx
30024 $translate-mu-compute-offset-stmt-with-literal-index:emit-output:
30025 # emit outputs[0]->register
30026 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax
30027 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
30028 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
30029 (write-buffered *(ebp+8) %eax)
30030 (write-buffered *(ebp+8) Space)
30031 $translate-mu-compute-offset-stmt-with-literal-index:emit-offset:
30032 # var first-inout/ebx: (addr stmt-var) = stmt->inouts
30033 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
30034 89/<- %ebx 0/r32/eax
30035 # var index/edx: int = int(first-inout->next->value)
30036 (lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax
30037 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
30038 (lookup *eax *(eax+4)) # Var-name Var-name => eax
30039 (parse-hex-int %eax) # => eax
30040 89/<- %edx 0/r32/eax
30041 # var base/ebx: (addr var) = first-inout->value
30042 (lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax
30043 # emit index * sizeof(base element type)
30044 (array-element-size %eax *(ebp+0x10) *(ebp+0x14)) # => eax
30045 0f af/multiply %edx 0/r32/eax
30046 (write-int32-hex-buffered *(ebp+8) %eax)
30047 (write-buffered *(ebp+8) "/imm32\n")
30048 $translate-mu-compute-offset-stmt-with-literal-index:end:
30049 # . restore registers
30055 89/<- %esp 5/r32/ebp
30059 translate-mu-get-stmt: # out: (addr buffered-file), stmt: (addr stmt)
30062 89/<- %ebp 4/r32/esp
30068 8b/-> *(ebp+0xc) 1/r32/ecx
30069 # var base/eax: (addr var) = stmt->inouts->value
30070 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
30071 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
30072 # if base is in a register, insert a null check
30073 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register
30075 0f 84/jump-if-= break/disp32
30076 $translate-mu-get-stmt:emit-null-check-for-register-input:
30077 # emit "81 7/subop/compare %" base->register " 0/imm32\n"
30078 (emit-indent *(ebp+8) *Curr-block-depth)
30079 (write-buffered *(ebp+8) "81 7/subop/compare %")
30080 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
30081 (write-buffered *(ebp+8) %eax)
30082 (write-buffered *(ebp+8) " 0/imm32\n")
30084 (emit-indent *(ebp+8) *Curr-block-depth)
30085 (write-buffered *(ebp+8) "0f 84/jump-if-= __mu-abort-null-get-base-address/disp32\n")
30087 # var offset/edx: int = get offset of stmt
30088 (mu-get-offset %ecx) # => eax
30089 89/<- %edx 0/r32/eax
30090 # var base/eax: (addr var) = stmt->inouts->value
30091 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
30092 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
30094 (emit-indent *(ebp+8) *Curr-block-depth)
30095 (write-buffered *(ebp+8) "8d/copy-address ")
30096 # if base is in a register
30097 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register
30099 0f 84/jump-if-= break/disp32
30100 $translate-mu-get-stmt:emit-register-input:
30101 # emit "*(" base->register " + " offset ") "
30102 (write-buffered *(ebp+8) "*(")
30103 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
30104 (write-buffered *(ebp+8) %eax)
30105 (write-buffered *(ebp+8) " + ")
30106 (write-int32-hex-buffered *(ebp+8) %edx)
30107 (write-buffered *(ebp+8) ") ")
30108 e9/jump $translate-mu-get-stmt:emit-output/disp32
30110 # otherwise base is on the stack
30112 $translate-mu-get-stmt:emit-stack-input:
30113 # emit "*(ebp + " inouts[0]->stack-offset + offset ") "
30114 (write-buffered *(ebp+8) "*(ebp+")
30115 03/add *(eax+0x14) 2/r32/edx # Var-offset
30116 (write-int32-hex-buffered *(ebp+8) %edx)
30117 (write-buffered *(ebp+8) ") ")
30118 eb/jump $translate-mu-get-stmt:emit-output/disp8
30120 $translate-mu-get-stmt:emit-output:
30121 # var output/eax: (addr var) = stmt->outputs->value
30122 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax
30123 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
30124 # emit offset->register "/r32"
30125 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
30126 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int)
30127 (write-int32-hex-buffered *(ebp+8) *eax)
30128 (write-buffered *(ebp+8) "/r32\n")
30129 $translate-mu-get-stmt:end:
30130 # . restore registers
30135 89/<- %esp 5/r32/ebp
30139 translate-mu-copy-object-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
30142 89/<- %ebp 4/r32/esp
30146 (emit-indent *(ebp+8) *Curr-block-depth)
30147 (write-buffered *(ebp+8) "(copy-bytes")
30149 8b/-> *(ebp+0xc) 0/r32/eax
30150 # var first-inout/eax: (addr stmt-var) = stmt->inouts[0]
30151 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax
30152 (emit-subx-call-operand *(ebp+8) %eax)
30153 # var second-inout/eax: (addr stmt-var) = stmt->inouts[1]
30154 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
30155 (emit-subx-call-operand *(ebp+8) %eax)
30156 # emit size of inouts
30157 (write-buffered *(ebp+8) Space)
30158 (addr-payload-size %eax *(ebp+0x10) *(ebp+0x14)) # => eax
30159 (write-int32-hex-buffered *(ebp+8) %eax)
30160 (write-buffered *(ebp+8) ")\n")
30161 $translate-mu-copy-object-stmt:end:
30162 # . restore registers
30165 89/<- %esp 5/r32/ebp
30169 translate-mu-clear-object-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
30172 89/<- %ebp 4/r32/esp
30176 (emit-indent *(ebp+8) *Curr-block-depth)
30177 (write-buffered *(ebp+8) "(zero-out")
30179 8b/-> *(ebp+0xc) 0/r32/eax
30180 # var dest/eax: (addr stmt-var) = stmt->inouts[0]
30181 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax
30183 (emit-subx-call-operand *(ebp+8) %eax)
30184 (write-buffered *(ebp+8) Space)
30185 (addr-payload-size %eax *(ebp+0x10) *(ebp+0x14)) # => eax
30186 (write-int32-hex-buffered *(ebp+8) %eax)
30187 (write-buffered *(ebp+8) ")\n")
30188 $translate-mu-clear-object-stmt:end:
30189 # . restore registers
30192 89/<- %esp 5/r32/ebp
30196 translate-mu-allocate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
30199 89/<- %ebp 4/r32/esp
30205 8b/-> *(ebp+0xc) 6/r32/esi
30206 # var target/edi: (addr stmt-var) = stmt->inouts[0]
30207 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
30208 89/<- %edi 0/r32/eax
30210 (emit-indent *(ebp+8) *Curr-block-depth)
30211 (write-buffered *(ebp+8) "(allocate Heap ")
30212 (addr-handle-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax
30213 (write-int32-hex-buffered *(ebp+8) %eax)
30214 (emit-subx-call-operand *(ebp+8) %edi)
30215 (write-buffered *(ebp+8) ")\n")
30216 $translate-mu-allocate-stmt:end:
30217 # . restore registers
30222 89/<- %esp 5/r32/ebp
30226 addr-handle-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int
30229 89/<- %ebp 4/r32/esp
30230 # var t/eax: (addr type-tree) = s->value->type
30231 8b/-> *(ebp+8) 0/r32/eax
30232 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
30233 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
30234 # TODO: check eax != 0
30235 # TODO: check !t->is-atom?
30236 # TODO: check t->left == addr
30238 $addr-handle-payload-size:skip-addr:
30239 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
30240 # TODO: check eax != 0
30241 # TODO: check !t->is-atom?
30242 # TODO: check t->left == handle
30244 $addr-handle-payload-size:skip-handle:
30245 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
30246 # TODO: check eax != 0
30247 # if !t->is-atom? t = t->left
30248 81 7/subop/compare *eax 0/imm32/false
30250 75/jump-if-!= break/disp8
30251 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
30253 # TODO: check t->is-atom?
30254 # return size(t->value)
30255 (size-of-type-id *(eax+4)) # Type-tree-value => eax
30256 $addr-handle-payload-size:end:
30258 89/<- %esp 5/r32/ebp
30262 addr-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int
30265 89/<- %ebp 4/r32/esp
30266 # var t/eax: (addr type-tree) = s->value->type
30267 8b/-> *(ebp+8) 0/r32/eax
30268 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
30269 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
30270 # TODO: check eax != 0
30271 # TODO: check !t->is-atom?
30272 # TODO: check t->left == addr
30274 $addr-payload-size:skip-addr:
30275 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
30276 # TODO: check eax != 0
30277 # if !t->is-atom? t = t->left
30278 81 7/subop/compare *eax 0/imm32/false
30280 75/jump-if-!= break/disp8
30281 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
30283 # TODO: check t->is-atom?
30284 # return size(t->value)
30285 (size-of-type-id *(eax+4)) # Type-tree-value => eax
30286 $addr-payload-size:end:
30288 89/<- %esp 5/r32/ebp
30292 translate-mu-populate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
30295 89/<- %ebp 4/r32/esp
30302 8b/-> *(ebp+0xc) 6/r32/esi
30303 # var target/edi: (addr stmt-var) = stmt->inouts[0]
30304 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
30305 89/<- %edi 0/r32/eax
30306 # var len/ecx: (addr stmt-var) = stmt->inouts[1]
30307 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
30308 89/<- %ecx 0/r32/eax
30310 (emit-indent *(ebp+8) *Curr-block-depth)
30311 (write-buffered *(ebp+8) "(allocate-array2 Heap ")
30312 (addr-handle-array-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax
30313 (write-int32-hex-buffered *(ebp+8) %eax)
30314 (emit-subx-call-operand *(ebp+8) %ecx)
30315 (emit-subx-call-operand *(ebp+8) %edi)
30316 (write-buffered *(ebp+8) ")\n")
30317 $translate-mu-populate-stmt:end:
30318 # . restore registers
30324 89/<- %esp 5/r32/ebp
30328 translate-mu-populate-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
30331 89/<- %ebp 4/r32/esp
30338 8b/-> *(ebp+0xc) 6/r32/esi
30339 # var target/edi: (addr stmt-var) = stmt->inouts[0]
30340 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
30341 89/<- %edi 0/r32/eax
30342 # var len/ecx: (addr stmt-var) = stmt->inouts[1]
30343 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax
30344 89/<- %ecx 0/r32/eax
30346 (emit-indent *(ebp+8) *Curr-block-depth)
30347 (write-buffered *(ebp+8) "(new-stream Heap ")
30348 (addr-handle-stream-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax
30349 (write-int32-hex-buffered *(ebp+8) %eax)
30350 (emit-subx-call-operand *(ebp+8) %ecx)
30351 (emit-subx-call-operand *(ebp+8) %edi)
30352 (write-buffered *(ebp+8) ")\n")
30353 $translate-mu-populate-stream-stmt:end:
30354 # . restore registers
30360 89/<- %esp 5/r32/ebp
30364 translate-mu-read-from-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
30367 89/<- %ebp 4/r32/esp
30374 8b/-> *(ebp+0xc) 6/r32/esi
30375 # var stream/ecx: (addr stmt-var) = stmt->inouts[0]
30376 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
30377 89/<- %ecx 0/r32/eax
30378 # var target/edi: (addr stmt-var) = stmt->inouts[1]
30379 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax
30380 89/<- %edi 0/r32/eax
30382 (emit-indent *(ebp+8) *Curr-block-depth)
30383 (write-buffered *(ebp+8) "(read-from-stream")
30384 (emit-subx-call-operand *(ebp+8) %ecx)
30385 (emit-subx-call-operand *(ebp+8) %edi)
30386 (write-buffered *(ebp+8) Space)
30387 (addr-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax
30388 (write-int32-hex-buffered *(ebp+8) %eax)
30389 (write-buffered *(ebp+8) ")\n")
30390 $translate-mu-read-from-stream-stmt:end:
30391 # . restore registers
30397 89/<- %esp 5/r32/ebp
30401 translate-mu-write-to-stream-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
30404 89/<- %ebp 4/r32/esp
30411 8b/-> *(ebp+0xc) 6/r32/esi
30412 # var stream/ecx: (addr stmt-var) = stmt->inouts[0]
30413 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
30414 89/<- %ecx 0/r32/eax
30415 # var target/edi: (addr stmt-var) = stmt->inouts[1]
30416 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax
30417 89/<- %edi 0/r32/eax
30419 (emit-indent *(ebp+8) *Curr-block-depth)
30420 (write-buffered *(ebp+8) "(write-to-stream")
30421 (emit-subx-call-operand *(ebp+8) %ecx)
30423 (emit-subx-call-operand *(ebp+8) %edi)
30425 (write-buffered *(ebp+8) Space)
30427 (addr-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax
30428 (write-int32-hex-buffered *(ebp+8) %eax)
30429 (write-buffered *(ebp+8) ")\n")
30430 $translate-mu-write-to-stream-stmt:end:
30431 # . restore registers
30437 89/<- %esp 5/r32/ebp
30441 addr-handle-array-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int
30444 89/<- %ebp 4/r32/esp
30445 # var t/eax: (addr type-tree) = s->value->type
30446 8b/-> *(ebp+8) 0/r32/eax
30447 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
30448 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
30449 # TODO: check eax != 0
30450 # TODO: check !t->is-atom?
30451 # TODO: check t->left == addr
30453 $addr-handle-array-payload-size:skip-addr:
30454 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
30455 # TODO: check eax != 0
30456 # TODO: check !t->is-atom?
30457 # TODO: check t->left == handle
30459 $addr-handle-array-payload-size:skip-handle:
30460 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
30461 # TODO: check eax != 0
30462 # TODO: check !t->is-atom?
30463 # TODO: check t->left == array
30465 $addr-handle-array-payload-size:skip-array:
30466 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
30467 # TODO: check eax != 0
30468 # if !t->is-atom? t = t->left
30469 81 7/subop/compare *eax 0/imm32/false
30471 75/jump-if-!= break/disp8
30472 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
30474 $addr-handle-array-payload-size:compute-size:
30475 # TODO: check t->is-atom?
30476 # return size(t->value)
30477 (size-of-type-id-as-array-element *(eax+4)) # Type-tree-value => eax
30478 $addr-handle-array-payload-size:end:
30480 89/<- %esp 5/r32/ebp
30484 addr-handle-stream-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int
30487 89/<- %ebp 4/r32/esp
30488 # var t/eax: (addr type-tree) = s->value->type
30489 8b/-> *(ebp+8) 0/r32/eax
30490 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
30491 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax
30492 # TODO: check eax != 0
30493 # TODO: check !t->is-atom?
30494 # TODO: check t->left == addr
30496 $addr-handle-stream-payload-size:skip-addr:
30497 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
30498 # TODO: check eax != 0
30499 # TODO: check !t->is-atom?
30500 # TODO: check t->left == handle
30502 $addr-handle-stream-payload-size:skip-handle:
30503 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
30504 # TODO: check eax != 0
30505 # TODO: check !t->is-atom?
30506 # TODO: check t->left == stream
30508 $addr-handle-stream-payload-size:skip-stream:
30509 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
30510 # TODO: check eax != 0
30511 # if !t->is-atom? t = t->left
30512 81 7/subop/compare *eax 0/imm32/false
30514 75/jump-if-!= break/disp8
30515 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
30517 $addr-handle-stream-payload-size:compute-size:
30518 # TODO: check t->is-atom?
30519 # return size(t->value)
30520 (size-of-type-id-as-array-element *(eax+4)) # Type-tree-value => eax
30521 $addr-handle-stream-payload-size:end:
30523 89/<- %esp 5/r32/ebp
30527 power-of-2?: # n: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: boolean
30528 # precondition: n is positive
30531 89/<- %ebp 4/r32/esp
30533 8b/-> *(ebp+8) 0/r32/eax
30535 3d/compare-eax-with 0/imm32
30536 0f 8c/jump-if-< $power-of-2?:abort/disp32
30537 # var tmp/eax: int = n-1
30539 # var tmp2/eax: int = n & tmp
30540 23/and-> *(ebp+8) 0/r32/eax
30541 # return (tmp2 == 0)
30542 3d/compare-eax-and 0/imm32
30543 0f 94/set-byte-if-= %al
30544 25/and-eax-with 0xff/imm32
30547 89/<- %esp 5/r32/ebp
30551 $power-of-2?:abort:
30552 (write-buffered *(ebp+0xc) "power-of-2?: negative number\n")
30554 (stop *(ebp+0x10) 1)
30557 num-shift-rights: # n: int -> result/eax: int
30558 # precondition: n is a positive power of 2
30561 89/<- %ebp 4/r32/esp
30564 # var curr/ecx: int = n
30565 8b/-> *(ebp+8) 1/r32/ecx
30567 b8/copy-to-eax 0/imm32
30569 # if (curr <= 1) break
30570 81 7/subop/compare %ecx 1/imm32
30571 7e/jump-if-<= break/disp8
30573 c1/shift 5/subop/arithmetic-right %ecx 1/imm8
30576 $num-shift-rights:end:
30577 # . restore registers
30580 89/<- %esp 5/r32/ebp
30584 mu-get-offset: # stmt: (addr stmt) -> result/eax: int
30587 89/<- %ebp 4/r32/esp
30588 # var second-inout/eax: (addr stmt-var) = stmt->inouts->next
30589 8b/-> *(ebp+8) 0/r32/eax
30590 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax
30591 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
30592 # var output-var/eax: (addr var) = second-inout->value
30593 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
30594 #? (write-buffered Stderr "mu-get-offset: ")
30595 #? (write-int32-hex-buffered Stderr %eax)
30596 #? (write-buffered Stderr " name: ")
30598 #? (lookup *eax *(eax+4)) # Var-name
30599 #? (write-buffered Stderr %eax)
30601 #? (write-buffered Stderr Newline)
30603 # return output-var->stack-offset
30604 8b/-> *(eax+0x14) 0/r32/eax # Var-offset
30605 #? (write-buffered Stderr "=> ")
30606 #? (write-int32-hex-buffered Stderr %eax)
30607 #? (write-buffered Stderr Newline)
30609 $emit-get-offset:end:
30611 89/<- %esp 5/r32/ebp
30615 emit-subx-block: # out: (addr buffered-file), block: (addr block), vars: (addr stack live-var), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
30618 89/<- %ebp 4/r32/esp
30624 8b/-> *(ebp+0xc) 6/r32/esi
30625 # block->var->block-depth = *Curr-block-depth
30626 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax
30627 8b/-> *Curr-block-depth 1/r32/ecx
30628 89/<- *(eax+0x10) 1/r32/ecx # Var-block-depth
30629 # var stmts/eax: (addr list stmt) = lookup(block->statements)
30630 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax
30633 $emit-subx-block:check-empty:
30634 3d/compare-eax-and 0/imm32
30635 0f 84/jump-if-= break/disp32
30636 (emit-indent *(ebp+8) *Curr-block-depth)
30637 (write-buffered *(ebp+8) "{\n")
30638 # var v/ecx: (addr var) = lookup(block->var)
30639 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax
30640 89/<- %ecx 0/r32/eax
30642 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
30643 (write-buffered *(ebp+8) %eax)
30644 (write-buffered *(ebp+8) ":loop:\n")
30645 ff 0/subop/increment *Curr-block-depth
30646 (push *(ebp+0x10) *(esi+0xc)) # Block-var
30647 (push *(ebp+0x10) *(esi+0x10)) # Block-var
30648 (push *(ebp+0x10) 0) # false
30649 # emit block->statements
30650 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax
30651 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c))
30652 (pop *(ebp+0x10)) # => eax
30653 (pop *(ebp+0x10)) # => eax
30654 (pop *(ebp+0x10)) # => eax
30655 ff 1/subop/decrement *Curr-block-depth
30656 (emit-indent *(ebp+8) *Curr-block-depth)
30657 (write-buffered *(ebp+8) "}\n")
30658 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax
30659 (write-buffered *(ebp+8) %eax)
30660 (write-buffered *(ebp+8) ":break:\n")
30662 $emit-subx-block:end:
30663 # . restore registers
30668 89/<- %esp 5/r32/ebp
30672 # Primitives supported
30673 # See mu_instructions for a summary of this linked-list data structure.
30675 # For each operation, put variants with hard-coded registers before flexible ones.
30677 # Unfortunately, our restrictions on addresses require that various fields in
30678 # primitives be handles, which complicates these definitions.
30679 # - we need to insert dummy fields all over the place for fake alloc-ids
30680 # - we can't use our syntax sugar of quoted literals for string fields
30682 # Fake alloc-ids are needed because our type definitions up top require
30683 # handles but it's clearer to statically allocate these long-lived objects.
30684 # Fake alloc-ids are perfectly safe, but they can't be reclaimed.
30686 # Every 'object' below starts with a fake alloc-id. It may also contain other
30687 # fake alloc-ids for various handle fields.
30689 # I think of objects starting with a fake alloc-id as having type 'payload'.
30690 # It's not really intended to be created dynamically; for that use `allocate`
30693 # Idea for a notation to simplify such definitions:
30694 # _Primitive-increment-eax: # (payload primitive)
30695 # 0x11/alloc-id:fake:payload
30696 # 0x11 @(0x11 "increment") # name
30698 # 0x11 @(0x11/payload
30699 # 0x11 @(0x11/payload # List-value
30701 # 0x11 @(0x11 # Var-type
30703 # 1/value 0/unused # Type-tree-left
30704 # 0 0 # Type-tree-right
30708 # 0x11 @(0x11 "eax") # Var-register
30712 # _Primitive-increment-ecx/imm32/next
30714 # Awfully complex and non-obvious. But also clearly signals there's something
30715 # to learn here, so may be worth trying.
30717 # '@' is just an initial thought. Punctuation used so far in Mu: () * % # / "
30719 # For now we'll continue to just use comments and manually ensure they stay up
30722 Primitives: # (addr primitive)
30723 # - increment/decrement
30724 _Primitive-increment-eax: # (addr primitive)
30725 # var/eax <- increment => 40/increment-eax
30726 0x11/imm32/alloc-id:fake
30727 _string-increment/imm32/name
30730 0x11/imm32/alloc-id:fake
30731 Single-int-var-in-eax/imm32/outputs
30732 0x11/imm32/alloc-id:fake
30733 _string_40_increment_eax/imm32/subx-name
30741 0x11/imm32/alloc-id:fake
30742 _Primitive-increment-ecx/imm32/next
30743 _Primitive-increment-ecx: # (payload primitive)
30744 0x11/imm32/alloc-id:fake:payload
30745 # var/ecx <- increment => 41/increment-ecx
30746 0x11/imm32/alloc-id:fake
30747 _string-increment/imm32/name
30750 0x11/imm32/alloc-id:fake
30751 Single-int-var-in-ecx/imm32/outputs
30752 0x11/imm32/alloc-id:fake
30753 _string_41_increment_ecx/imm32/subx-name
30761 0x11/imm32/alloc-id:fake
30762 _Primitive-increment-edx/imm32/next
30763 _Primitive-increment-edx: # (payload primitive)
30764 0x11/imm32/alloc-id:fake:payload
30765 # var/edx <- increment => 42/increment-edx
30766 0x11/imm32/alloc-id:fake
30767 _string-increment/imm32/name
30770 0x11/imm32/alloc-id:fake
30771 Single-int-var-in-edx/imm32/outputs
30772 0x11/imm32/alloc-id:fake
30773 _string_42_increment_edx/imm32/subx-name
30781 0x11/imm32/alloc-id:fake
30782 _Primitive-increment-ebx/imm32/next
30783 _Primitive-increment-ebx: # (payload primitive)
30784 0x11/imm32/alloc-id:fake:payload
30785 # var/ebx <- increment => 43/increment-ebx
30786 0x11/imm32/alloc-id:fake
30787 _string-increment/imm32/name
30790 0x11/imm32/alloc-id:fake
30791 Single-int-var-in-ebx/imm32/outputs
30792 0x11/imm32/alloc-id:fake
30793 _string_43_increment_ebx/imm32/subx-name
30801 0x11/imm32/alloc-id:fake
30802 _Primitive-increment-esi/imm32/next
30803 _Primitive-increment-esi: # (payload primitive)
30804 0x11/imm32/alloc-id:fake:payload
30805 # var/esi <- increment => 46/increment-esi
30806 0x11/imm32/alloc-id:fake
30807 _string-increment/imm32/name
30810 0x11/imm32/alloc-id:fake
30811 Single-int-var-in-esi/imm32/outputs
30812 0x11/imm32/alloc-id:fake
30813 _string_46_increment_esi/imm32/subx-name
30821 0x11/imm32/alloc-id:fake
30822 _Primitive-increment-edi/imm32/next
30823 _Primitive-increment-edi: # (payload primitive)
30824 0x11/imm32/alloc-id:fake:payload
30825 # var/edi <- increment => 47/increment-edi
30826 0x11/imm32/alloc-id:fake
30827 _string-increment/imm32/name
30830 0x11/imm32/alloc-id:fake
30831 Single-int-var-in-edi/imm32/outputs
30832 0x11/imm32/alloc-id:fake
30833 _string_47_increment_edi/imm32/subx-name
30841 0x11/imm32/alloc-id:fake
30842 _Primitive-decrement-eax/imm32/next
30843 _Primitive-decrement-eax: # (payload primitive)
30844 0x11/imm32/alloc-id:fake:payload
30845 # var/eax <- decrement => 48/decrement-eax
30846 0x11/imm32/alloc-id:fake
30847 _string-decrement/imm32/name
30850 0x11/imm32/alloc-id:fake
30851 Single-int-var-in-eax/imm32/outputs
30852 0x11/imm32/alloc-id:fake
30853 _string_48_decrement_eax/imm32/subx-name
30861 0x11/imm32/alloc-id:fake
30862 _Primitive-decrement-ecx/imm32/next
30863 _Primitive-decrement-ecx: # (payload primitive)
30864 0x11/imm32/alloc-id:fake:payload
30865 # var/ecx <- decrement => 49/decrement-ecx
30866 0x11/imm32/alloc-id:fake
30867 _string-decrement/imm32/name
30870 0x11/imm32/alloc-id:fake
30871 Single-int-var-in-ecx/imm32/outputs
30872 0x11/imm32/alloc-id:fake
30873 _string_49_decrement_ecx/imm32/subx-name
30881 0x11/imm32/alloc-id:fake
30882 _Primitive-decrement-edx/imm32/next
30883 _Primitive-decrement-edx: # (payload primitive)
30884 0x11/imm32/alloc-id:fake:payload
30885 # var/edx <- decrement => 4a/decrement-edx
30886 0x11/imm32/alloc-id:fake
30887 _string-decrement/imm32/name
30890 0x11/imm32/alloc-id:fake
30891 Single-int-var-in-edx/imm32/outputs
30892 0x11/imm32/alloc-id:fake
30893 _string_4a_decrement_edx/imm32/subx-name
30901 0x11/imm32/alloc-id:fake
30902 _Primitive-decrement-ebx/imm32/next
30903 _Primitive-decrement-ebx: # (payload primitive)
30904 0x11/imm32/alloc-id:fake:payload
30905 # var/ebx <- decrement => 4b/decrement-ebx
30906 0x11/imm32/alloc-id:fake
30907 _string-decrement/imm32/name
30910 0x11/imm32/alloc-id:fake
30911 Single-int-var-in-ebx/imm32/outputs
30912 0x11/imm32/alloc-id:fake
30913 _string_4b_decrement_ebx/imm32/subx-name
30921 0x11/imm32/alloc-id:fake
30922 _Primitive-decrement-esi/imm32/next
30923 _Primitive-decrement-esi: # (payload primitive)
30924 0x11/imm32/alloc-id:fake:payload
30925 # var/esi <- decrement => 4e/decrement-esi
30926 0x11/imm32/alloc-id:fake
30927 _string-decrement/imm32/name
30930 0x11/imm32/alloc-id:fake
30931 Single-int-var-in-esi/imm32/outputs
30932 0x11/imm32/alloc-id:fake
30933 _string_4e_decrement_esi/imm32/subx-name
30941 0x11/imm32/alloc-id:fake
30942 _Primitive-decrement-edi/imm32/next
30943 _Primitive-decrement-edi: # (payload primitive)
30944 0x11/imm32/alloc-id:fake:payload
30945 # var/edi <- decrement => 4f/decrement-edi
30946 0x11/imm32/alloc-id:fake
30947 _string-decrement/imm32/name
30950 0x11/imm32/alloc-id:fake
30951 Single-int-var-in-edi/imm32/outputs
30952 0x11/imm32/alloc-id:fake
30953 _string_4f_decrement_edi/imm32/subx-name
30961 0x11/imm32/alloc-id:fake
30962 _Primitive-increment-mem/imm32/next
30963 _Primitive-increment-mem: # (payload primitive)
30964 0x11/imm32/alloc-id:fake:payload
30965 # increment var => ff 0/subop/increment *(ebp+__)
30966 0x11/imm32/alloc-id:fake
30967 _string-increment/imm32/name
30968 0x11/imm32/alloc-id:fake
30969 Single-int-var-in-mem/imm32/inouts
30972 0x11/imm32/alloc-id:fake
30973 _string_ff_subop_increment/imm32/subx-name
30974 1/imm32/rm32-is-first-inout
30981 0x11/imm32/alloc-id:fake
30982 _Primitive-increment-reg/imm32/next
30983 _Primitive-increment-reg: # (payload primitive)
30984 0x11/imm32/alloc-id:fake:payload
30985 # var/reg <- increment => ff 0/subop/increment %__
30986 0x11/imm32/alloc-id:fake
30987 _string-increment/imm32/name
30990 0x11/imm32/alloc-id:fake
30991 Single-int-var-in-some-register/imm32/outputs
30992 0x11/imm32/alloc-id:fake
30993 _string_ff_subop_increment/imm32/subx-name
30994 3/imm32/rm32-is-first-output
31001 0x11/imm32/alloc-id:fake
31002 _Primitive-decrement-mem/imm32/next
31003 _Primitive-decrement-mem: # (payload primitive)
31004 0x11/imm32/alloc-id:fake:payload
31005 # decrement var => ff 1/subop/decrement *(ebp+__)
31006 0x11/imm32/alloc-id:fake
31007 _string-decrement/imm32/name
31008 0x11/imm32/alloc-id:fake
31009 Single-int-var-in-mem/imm32/inouts
31012 0x11/imm32/alloc-id:fake
31013 _string_ff_subop_decrement/imm32/subx-name
31014 1/imm32/rm32-is-first-inout
31021 0x11/imm32/alloc-id:fake
31022 _Primitive-decrement-reg/imm32/next
31023 _Primitive-decrement-reg: # (payload primitive)
31024 0x11/imm32/alloc-id:fake:payload
31025 # var/reg <- decrement => ff 1/subop/decrement %__
31026 0x11/imm32/alloc-id:fake
31027 _string-decrement/imm32/name
31030 0x11/imm32/alloc-id:fake
31031 Single-int-var-in-some-register/imm32/outputs
31032 0x11/imm32/alloc-id:fake
31033 _string_ff_subop_decrement/imm32/subx-name
31034 3/imm32/rm32-is-first-output
31041 0x11/imm32/alloc-id:fake
31042 _Primitive-add-to-eax/imm32/next
31044 _Primitive-add-to-eax: # (payload primitive)
31045 0x11/imm32/alloc-id:fake:payload
31046 # var/eax <- add lit => 05/add-to-eax lit/imm32
31047 0x11/imm32/alloc-id:fake
31048 _string-add/imm32/name
31049 0x11/imm32/alloc-id:fake
31050 Single-lit-var/imm32/inouts
31051 0x11/imm32/alloc-id:fake
31052 Single-int-var-in-eax/imm32/outputs
31053 0x11/imm32/alloc-id:fake
31054 _string_05_add_to_eax/imm32/subx-name
31057 1/imm32/imm32-is-first-inout
31062 0x11/imm32/alloc-id:fake
31063 _Primitive-add-reg-to-reg/imm32/next
31064 _Primitive-add-reg-to-reg: # (payload primitive)
31065 0x11/imm32/alloc-id:fake:payload
31066 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32
31067 0x11/imm32/alloc-id:fake
31068 _string-add/imm32/name
31069 0x11/imm32/alloc-id:fake
31070 Single-int-var-in-some-register/imm32/inouts
31071 0x11/imm32/alloc-id:fake
31072 Single-int-var-in-some-register/imm32/outputs
31073 0x11/imm32/alloc-id:fake
31074 _string_01_add_to/imm32/subx-name
31075 3/imm32/rm32-is-first-output
31076 1/imm32/r32-is-first-inout
31082 0x11/imm32/alloc-id:fake
31083 _Primitive-add-reg-to-mem/imm32/next
31084 _Primitive-add-reg-to-mem: # (payload primitive)
31085 0x11/imm32/alloc-id:fake:payload
31086 # add-to var1 var2/reg => 01/add-to var1 var2/r32
31087 0x11/imm32/alloc-id:fake
31088 _string-add-to/imm32/name
31089 0x11/imm32/alloc-id:fake
31090 Two-args-int-stack-int-reg/imm32/inouts
31093 0x11/imm32/alloc-id:fake
31094 _string_01_add_to/imm32/subx-name
31095 1/imm32/rm32-is-first-inout
31096 2/imm32/r32-is-second-inout
31102 0x11/imm32/alloc-id:fake
31103 _Primitive-add-mem-to-reg/imm32/next
31104 _Primitive-add-mem-to-reg: # (payload primitive)
31105 0x11/imm32/alloc-id:fake:payload
31106 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32
31107 0x11/imm32/alloc-id:fake
31108 _string-add/imm32/name
31109 0x11/imm32/alloc-id:fake
31110 Single-int-var-in-mem/imm32/inouts
31111 0x11/imm32/alloc-id:fake
31112 Single-int-var-in-some-register/imm32/outputs
31113 0x11/imm32/alloc-id:fake
31114 _string_03_add/imm32/subx-name
31115 1/imm32/rm32-is-first-inout
31116 3/imm32/r32-is-first-output
31122 0x11/imm32/alloc-id:fake
31123 _Primitive-add-lit-to-reg/imm32/next
31124 _Primitive-add-lit-to-reg: # (payload primitive)
31125 0x11/imm32/alloc-id:fake:payload
31126 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32
31127 0x11/imm32/alloc-id:fake
31128 _string-add/imm32/name
31129 0x11/imm32/alloc-id:fake
31130 Single-lit-var/imm32/inouts
31131 0x11/imm32/alloc-id:fake
31132 Single-int-var-in-some-register/imm32/outputs
31133 0x11/imm32/alloc-id:fake
31134 _string_81_subop_add/imm32/subx-name
31135 3/imm32/rm32-is-first-output
31137 1/imm32/imm32-is-first-inout
31142 0x11/imm32/alloc-id:fake
31143 _Primitive-add-lit-to-mem/imm32/next
31144 _Primitive-add-lit-to-mem: # (payload primitive)
31145 0x11/imm32/alloc-id:fake:payload
31146 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32
31147 0x11/imm32/alloc-id:fake
31148 _string-add-to/imm32/name
31149 0x11/imm32/alloc-id:fake
31150 Int-var-and-literal/imm32/inouts
31153 0x11/imm32/alloc-id:fake
31154 _string_81_subop_add/imm32/subx-name
31155 1/imm32/rm32-is-first-inout
31157 2/imm32/imm32-is-second-inout
31162 0x11/imm32/alloc-id:fake
31163 _Primitive-subtract-from-eax/imm32/next
31165 _Primitive-subtract-from-eax: # (payload primitive)
31166 0x11/imm32/alloc-id:fake:payload
31167 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32
31168 0x11/imm32/alloc-id:fake
31169 _string-subtract/imm32/name
31170 0x11/imm32/alloc-id:fake
31171 Single-lit-var/imm32/inouts
31172 0x11/imm32/alloc-id:fake
31173 Single-int-var-in-eax/imm32/outputs
31174 0x11/imm32/alloc-id:fake
31175 _string_2d_subtract_from_eax/imm32/subx-name
31178 1/imm32/imm32-is-first-inout
31183 0x11/imm32/alloc-id:fake
31184 _Primitive-subtract-reg-from-reg/imm32/next
31185 _Primitive-subtract-reg-from-reg: # (payload primitive)
31186 0x11/imm32/alloc-id:fake:payload
31187 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32
31188 0x11/imm32/alloc-id:fake
31189 _string-subtract/imm32/name
31190 0x11/imm32/alloc-id:fake
31191 Single-int-var-in-some-register/imm32/inouts
31192 0x11/imm32/alloc-id:fake
31193 Single-int-var-in-some-register/imm32/outputs
31194 0x11/imm32/alloc-id:fake
31195 _string_29_subtract_from/imm32/subx-name
31196 3/imm32/rm32-is-first-output
31197 1/imm32/r32-is-first-inout
31203 0x11/imm32/alloc-id:fake
31204 _Primitive-subtract-reg-from-mem/imm32/next
31205 _Primitive-subtract-reg-from-mem: # (payload primitive)
31206 0x11/imm32/alloc-id:fake:payload
31207 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32
31208 0x11/imm32/alloc-id:fake
31209 _string-subtract-from/imm32/name
31210 0x11/imm32/alloc-id:fake
31211 Two-args-int-stack-int-reg/imm32/inouts
31214 0x11/imm32/alloc-id:fake
31215 _string_29_subtract_from/imm32/subx-name
31216 1/imm32/rm32-is-first-inout
31217 2/imm32/r32-is-second-inout
31223 0x11/imm32/alloc-id:fake
31224 _Primitive-subtract-mem-from-reg/imm32/next
31225 _Primitive-subtract-mem-from-reg: # (payload primitive)
31226 0x11/imm32/alloc-id:fake:payload
31227 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32
31228 0x11/imm32/alloc-id:fake
31229 _string-subtract/imm32/name
31230 0x11/imm32/alloc-id:fake
31231 Single-int-var-in-mem/imm32/inouts
31232 0x11/imm32/alloc-id:fake
31233 Single-int-var-in-some-register/imm32/outputs
31234 0x11/imm32/alloc-id:fake
31235 _string_2b_subtract/imm32/subx-name
31236 1/imm32/rm32-is-first-inout
31237 3/imm32/r32-is-first-output
31243 0x11/imm32/alloc-id:fake
31244 _Primitive-subtract-lit-from-reg/imm32/next
31245 _Primitive-subtract-lit-from-reg: # (payload primitive)
31246 0x11/imm32/alloc-id:fake:payload
31247 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32
31248 0x11/imm32/alloc-id:fake
31249 _string-subtract/imm32/name
31250 0x11/imm32/alloc-id:fake
31251 Single-lit-var/imm32/inouts
31252 0x11/imm32/alloc-id:fake
31253 Single-int-var-in-some-register/imm32/outputs
31254 0x11/imm32/alloc-id:fake
31255 _string_81_subop_subtract/imm32/subx-name
31256 3/imm32/rm32-is-first-output
31258 1/imm32/imm32-is-first-inout
31263 0x11/imm32/alloc-id:fake
31264 _Primitive-subtract-lit-from-mem/imm32/next
31265 _Primitive-subtract-lit-from-mem: # (payload primitive)
31266 0x11/imm32/alloc-id:fake:payload
31267 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32
31268 0x11/imm32/alloc-id:fake
31269 _string-subtract-from/imm32/name
31270 0x11/imm32/alloc-id:fake
31271 Int-var-and-literal/imm32/inouts
31274 0x11/imm32/alloc-id:fake
31275 _string_81_subop_subtract/imm32/subx-name
31276 1/imm32/rm32-is-first-inout
31278 2/imm32/imm32-is-second-inout
31283 0x11/imm32/alloc-id:fake
31284 _Primitive-and-with-eax/imm32/next
31286 _Primitive-and-with-eax: # (payload primitive)
31287 0x11/imm32/alloc-id:fake:payload
31288 # var/eax <- and lit => 25/and-with-eax lit/imm32
31289 0x11/imm32/alloc-id:fake
31290 _string-and/imm32/name
31291 0x11/imm32/alloc-id:fake
31292 Single-lit-var/imm32/inouts
31293 0x11/imm32/alloc-id:fake
31294 Single-int-var-in-eax/imm32/outputs
31295 0x11/imm32/alloc-id:fake
31296 _string_25_and_with_eax/imm32/subx-name
31299 1/imm32/imm32-is-first-inout
31304 0x11/imm32/alloc-id:fake
31305 _Primitive-and-reg-with-reg/imm32/next
31306 _Primitive-and-reg-with-reg: # (payload primitive)
31307 0x11/imm32/alloc-id:fake:payload
31308 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32
31309 0x11/imm32/alloc-id:fake
31310 _string-and/imm32/name
31311 0x11/imm32/alloc-id:fake
31312 Single-int-var-in-some-register/imm32/inouts
31313 0x11/imm32/alloc-id:fake
31314 Single-int-var-in-some-register/imm32/outputs
31315 0x11/imm32/alloc-id:fake
31316 _string_21_and_with/imm32/subx-name
31317 3/imm32/rm32-is-first-output
31318 1/imm32/r32-is-first-inout
31324 0x11/imm32/alloc-id:fake
31325 _Primitive-and-reg-with-mem/imm32/next
31326 _Primitive-and-reg-with-mem: # (payload primitive)
31327 0x11/imm32/alloc-id:fake:payload
31328 # and-with var1 var2/reg => 21/and-with var1 var2/r32
31329 0x11/imm32/alloc-id:fake
31330 _string-and-with/imm32/name
31331 0x11/imm32/alloc-id:fake
31332 Two-args-int-stack-int-reg/imm32/inouts
31335 0x11/imm32/alloc-id:fake
31336 _string_21_and_with/imm32/subx-name
31337 1/imm32/rm32-is-first-inout
31338 2/imm32/r32-is-second-inout
31344 0x11/imm32/alloc-id:fake
31345 _Primitive-and-mem-with-reg/imm32/next
31346 _Primitive-and-mem-with-reg: # (payload primitive)
31347 0x11/imm32/alloc-id:fake:payload
31348 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32
31349 0x11/imm32/alloc-id:fake
31350 _string-and/imm32/name
31351 0x11/imm32/alloc-id:fake
31352 Single-int-var-in-mem/imm32/inouts
31353 0x11/imm32/alloc-id:fake
31354 Single-int-var-in-some-register/imm32/outputs
31355 0x11/imm32/alloc-id:fake
31356 _string_23_and/imm32/subx-name
31357 1/imm32/rm32-is-first-inout
31358 3/imm32/r32-is-first-output
31364 0x11/imm32/alloc-id:fake
31365 _Primitive-and-lit-with-reg/imm32/next
31366 _Primitive-and-lit-with-reg: # (payload primitive)
31367 0x11/imm32/alloc-id:fake:payload
31368 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32
31369 0x11/imm32/alloc-id:fake
31370 _string-and/imm32/name
31371 0x11/imm32/alloc-id:fake
31372 Single-lit-var/imm32/inouts
31373 0x11/imm32/alloc-id:fake
31374 Single-int-var-in-some-register/imm32/outputs
31375 0x11/imm32/alloc-id:fake
31376 _string_81_subop_and/imm32/subx-name
31377 3/imm32/rm32-is-first-output
31379 1/imm32/imm32-is-first-inout
31384 0x11/imm32/alloc-id:fake
31385 _Primitive-and-lit-with-mem/imm32/next
31386 _Primitive-and-lit-with-mem: # (payload primitive)
31387 0x11/imm32/alloc-id:fake:payload
31388 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32
31389 0x11/imm32/alloc-id:fake
31390 _string-and-with/imm32/name
31391 0x11/imm32/alloc-id:fake
31392 Int-var-and-literal/imm32/inouts
31395 0x11/imm32/alloc-id:fake
31396 _string_81_subop_and/imm32/subx-name
31397 1/imm32/rm32-is-first-inout
31399 2/imm32/imm32-is-second-inout
31404 0x11/imm32/alloc-id:fake
31405 _Primitive-or-with-eax/imm32/next
31407 _Primitive-or-with-eax: # (payload primitive)
31408 0x11/imm32/alloc-id:fake:payload
31409 # var/eax <- or lit => 0d/or-with-eax lit/imm32
31410 0x11/imm32/alloc-id:fake
31411 _string-or/imm32/name
31412 0x11/imm32/alloc-id:fake
31413 Single-lit-var/imm32/inouts
31414 0x11/imm32/alloc-id:fake
31415 Single-int-var-in-eax/imm32/outputs
31416 0x11/imm32/alloc-id:fake
31417 _string_0d_or_with_eax/imm32/subx-name
31420 1/imm32/imm32-is-first-inout
31425 0x11/imm32/alloc-id:fake
31426 _Primitive-or-reg-with-reg/imm32/next
31427 _Primitive-or-reg-with-reg: # (payload primitive)
31428 0x11/imm32/alloc-id:fake:payload
31429 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32
31430 0x11/imm32/alloc-id:fake
31431 _string-or/imm32/name
31432 0x11/imm32/alloc-id:fake
31433 Single-int-var-in-some-register/imm32/inouts
31434 0x11/imm32/alloc-id:fake
31435 Single-int-var-in-some-register/imm32/outputs
31436 0x11/imm32/alloc-id:fake
31437 _string_09_or_with/imm32/subx-name
31438 3/imm32/rm32-is-first-output
31439 1/imm32/r32-is-first-inout
31445 0x11/imm32/alloc-id:fake
31446 _Primitive-or-reg-with-mem/imm32/next
31447 _Primitive-or-reg-with-mem: # (payload primitive)
31448 0x11/imm32/alloc-id:fake:payload
31449 # or-with var1 var2/reg => 09/or-with var1 var2/r32
31450 0x11/imm32/alloc-id:fake
31451 _string-or-with/imm32/name
31452 0x11/imm32/alloc-id:fake
31453 Two-args-int-stack-int-reg/imm32/inouts
31456 0x11/imm32/alloc-id:fake
31457 _string_09_or_with/imm32/subx-name
31458 1/imm32/rm32-is-first-inout
31459 2/imm32/r32-is-second-inout
31465 0x11/imm32/alloc-id:fake
31466 _Primitive-or-mem-with-reg/imm32/next
31467 _Primitive-or-mem-with-reg: # (payload primitive)
31468 0x11/imm32/alloc-id:fake:payload
31469 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32
31470 0x11/imm32/alloc-id:fake
31471 _string-or/imm32/name
31472 0x11/imm32/alloc-id:fake
31473 Single-int-var-in-mem/imm32/inouts
31474 0x11/imm32/alloc-id:fake
31475 Single-int-var-in-some-register/imm32/outputs
31476 0x11/imm32/alloc-id:fake
31477 _string_0b_or/imm32/subx-name
31478 1/imm32/rm32-is-first-inout
31479 3/imm32/r32-is-first-output
31485 0x11/imm32/alloc-id:fake
31486 _Primitive-or-lit-with-reg/imm32/next
31487 _Primitive-or-lit-with-reg: # (payload primitive)
31488 0x11/imm32/alloc-id:fake:payload
31489 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32
31490 0x11/imm32/alloc-id:fake
31491 _string-or/imm32/name
31492 0x11/imm32/alloc-id:fake
31493 Single-lit-var/imm32/inouts
31494 0x11/imm32/alloc-id:fake
31495 Single-int-var-in-some-register/imm32/outputs
31496 0x11/imm32/alloc-id:fake
31497 _string_81_subop_or/imm32/subx-name
31498 3/imm32/rm32-is-first-output
31500 1/imm32/imm32-is-first-inout
31505 0x11/imm32/alloc-id:fake
31506 _Primitive-or-lit-with-mem/imm32/next
31507 _Primitive-or-lit-with-mem: # (payload primitive)
31508 0x11/imm32/alloc-id:fake:payload
31509 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32
31510 0x11/imm32/alloc-id:fake
31511 _string-or-with/imm32/name
31512 0x11/imm32/alloc-id:fake
31513 Int-var-and-literal/imm32/inouts
31516 0x11/imm32/alloc-id:fake
31517 _string_81_subop_or/imm32/subx-name
31518 1/imm32/rm32-is-first-inout
31520 2/imm32/imm32-is-second-inout
31525 0x11/imm32/alloc-id:fake
31526 _Primitive-not-reg/imm32/next
31528 _Primitive-not-reg: # (payload primitive)
31529 0x11/imm32/alloc-id:fake:payload
31530 # var1/reg <- not => f7 2/subop/not var1/rm32
31531 0x11/imm32/alloc-id:fake
31532 _string-not/imm32/name
31535 0x11/imm32/alloc-id:fake
31536 Single-int-var-in-some-register/imm32/outputs
31537 0x11/imm32/alloc-id:fake
31538 _string_f7_subop_not/imm32/subx-name
31539 3/imm32/rm32-is-first-output
31546 0x11/imm32/alloc-id:fake
31547 _Primitive-not-mem/imm32/next
31548 _Primitive-not-mem: # (payload primitive)
31549 0x11/imm32/alloc-id:fake:payload
31550 # not var1 => f7 2/subop/not var1/rm32
31551 0x11/imm32/alloc-id:fake
31552 _string-not/imm32/name
31553 0x11/imm32/alloc-id:fake
31554 Single-int-var-in-mem/imm32/inouts
31557 0x11/imm32/alloc-id:fake
31558 _string_f7_subop_not/imm32/subx-name
31559 1/imm32/rm32-is-first-inout
31566 0x11/imm32/alloc-id:fake
31567 _Primitive-xor-with-eax/imm32/next
31569 _Primitive-xor-with-eax: # (payload primitive)
31570 0x11/imm32/alloc-id:fake:payload
31571 # var/eax <- xor lit => 35/xor-with-eax lit/imm32
31572 0x11/imm32/alloc-id:fake
31573 _string-xor/imm32/name
31574 0x11/imm32/alloc-id:fake
31575 Single-lit-var/imm32/inouts
31576 0x11/imm32/alloc-id:fake
31577 Single-int-var-in-eax/imm32/outputs
31578 0x11/imm32/alloc-id:fake
31579 _string_35_xor_with_eax/imm32/subx-name
31582 1/imm32/imm32-is-first-inout
31587 0x11/imm32/alloc-id:fake
31588 _Primitive-xor-reg-with-reg/imm32/next
31589 _Primitive-xor-reg-with-reg: # (payload primitive)
31590 0x11/imm32/alloc-id:fake:payload
31591 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32
31592 0x11/imm32/alloc-id:fake
31593 _string-xor/imm32/name
31594 0x11/imm32/alloc-id:fake
31595 Single-int-var-in-some-register/imm32/inouts
31596 0x11/imm32/alloc-id:fake
31597 Single-int-var-in-some-register/imm32/outputs
31598 0x11/imm32/alloc-id:fake
31599 _string_31_xor_with/imm32/subx-name
31600 3/imm32/rm32-is-first-output
31601 1/imm32/r32-is-first-inout
31607 0x11/imm32/alloc-id:fake
31608 _Primitive-xor-reg-with-mem/imm32/next
31609 _Primitive-xor-reg-with-mem: # (payload primitive)
31610 0x11/imm32/alloc-id:fake:payload
31611 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32
31612 0x11/imm32/alloc-id:fake
31613 _string-xor-with/imm32/name
31614 0x11/imm32/alloc-id:fake
31615 Two-args-int-stack-int-reg/imm32/inouts
31618 0x11/imm32/alloc-id:fake
31619 _string_31_xor_with/imm32/subx-name
31620 1/imm32/rm32-is-first-inout
31621 2/imm32/r32-is-second-inout
31627 0x11/imm32/alloc-id:fake
31628 _Primitive-xor-mem-with-reg/imm32/next
31629 _Primitive-xor-mem-with-reg: # (payload primitive)
31630 0x11/imm32/alloc-id:fake:payload
31631 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32
31632 0x11/imm32/alloc-id:fake
31633 _string-xor/imm32/name
31634 0x11/imm32/alloc-id:fake
31635 Single-int-var-in-mem/imm32/inouts
31636 0x11/imm32/alloc-id:fake
31637 Single-int-var-in-some-register/imm32/outputs
31638 0x11/imm32/alloc-id:fake
31639 _string_33_xor/imm32/subx-name
31640 1/imm32/rm32-is-first-inout
31641 3/imm32/r32-is-first-output
31647 0x11/imm32/alloc-id:fake
31648 _Primitive-xor-lit-with-reg/imm32/next
31649 _Primitive-xor-lit-with-reg: # (payload primitive)
31650 0x11/imm32/alloc-id:fake:payload
31651 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32
31652 0x11/imm32/alloc-id:fake
31653 _string-xor/imm32/name
31654 0x11/imm32/alloc-id:fake
31655 Single-lit-var/imm32/inouts
31656 0x11/imm32/alloc-id:fake
31657 Single-int-var-in-some-register/imm32/outputs
31658 0x11/imm32/alloc-id:fake
31659 _string_81_subop_xor/imm32/subx-name
31660 3/imm32/rm32-is-first-output
31662 1/imm32/imm32-is-first-inout
31667 0x11/imm32/alloc-id:fake
31668 _Primitive-xor-lit-with-mem/imm32/next
31669 _Primitive-xor-lit-with-mem: # (payload primitive)
31670 0x11/imm32/alloc-id:fake:payload
31671 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32
31672 0x11/imm32/alloc-id:fake
31673 _string-xor-with/imm32/name
31674 0x11/imm32/alloc-id:fake
31675 Int-var-and-literal/imm32/inouts
31678 0x11/imm32/alloc-id:fake
31679 _string_81_subop_xor/imm32/subx-name
31680 1/imm32/rm32-is-first-inout
31682 2/imm32/imm32-is-second-inout
31687 0x11/imm32/alloc-id:fake
31688 _Primitive-shift-reg-left-by-lit/imm32/next
31689 _Primitive-shift-reg-left-by-lit: # (payload primitive)
31690 0x11/imm32/alloc-id:fake:payload
31691 # var1/reg <- shift-left lit => c1/shift 4/subop/left var1/rm32 lit/imm32
31692 0x11/imm32/alloc-id:fake
31693 _string-shift-left/imm32/name
31694 0x11/imm32/alloc-id:fake
31695 Single-lit-var/imm32/inouts
31696 0x11/imm32/alloc-id:fake
31697 Single-int-var-in-some-register/imm32/outputs
31698 0x11/imm32/alloc-id:fake
31699 _string_c1_subop_shift_left/imm32/subx-name
31700 3/imm32/rm32-is-first-output
31703 1/imm32/imm8-is-first-inout
31707 0x11/imm32/alloc-id:fake
31708 _Primitive-shift-reg-right-by-lit/imm32/next
31709 _Primitive-shift-reg-right-by-lit: # (payload primitive)
31710 0x11/imm32/alloc-id:fake:payload
31711 # var1/reg <- shift-right lit => c1/shift 5/subop/right var1/rm32 lit/imm32
31712 0x11/imm32/alloc-id:fake
31713 _string-shift-right/imm32/name
31714 0x11/imm32/alloc-id:fake
31715 Single-lit-var/imm32/inouts
31716 0x11/imm32/alloc-id:fake
31717 Single-int-var-in-some-register/imm32/outputs
31718 0x11/imm32/alloc-id:fake
31719 _string_c1_subop_shift_right_padding_zeroes/imm32/subx-name
31720 3/imm32/rm32-is-first-output
31723 1/imm32/imm8-is-first-inout
31727 0x11/imm32/alloc-id:fake
31728 _Primitive-shift-reg-right-signed-by-lit/imm32/next
31729 _Primitive-shift-reg-right-signed-by-lit: # (payload primitive)
31730 0x11/imm32/alloc-id:fake:payload
31731 # var1/reg <- shift-right-signed lit => c1/shift 7/subop/right-preserving-sign var1/rm32 lit/imm32
31732 0x11/imm32/alloc-id:fake
31733 _string-shift-right-signed/imm32/name
31734 0x11/imm32/alloc-id:fake
31735 Single-lit-var/imm32/inouts
31736 0x11/imm32/alloc-id:fake
31737 Single-int-var-in-some-register/imm32/outputs
31738 0x11/imm32/alloc-id:fake
31739 _string_c1_subop_shift_right_preserving_sign/imm32/subx-name
31740 3/imm32/rm32-is-first-output
31743 1/imm32/imm8-is-first-inout
31747 0x11/imm32/alloc-id:fake
31748 _Primitive-shift-mem-left-by-lit/imm32/next
31749 _Primitive-shift-mem-left-by-lit: # (payload primitive)
31750 0x11/imm32/alloc-id:fake:payload
31751 # shift-left var1, lit => c1/shift 4/subop/left var1/rm32 lit/imm32
31752 0x11/imm32/alloc-id:fake
31753 _string-shift-left/imm32/name
31754 0x11/imm32/alloc-id:fake
31755 Int-var-and-literal/imm32/inouts
31758 0x11/imm32/alloc-id:fake
31759 _string_c1_subop_shift_left/imm32/subx-name
31760 1/imm32/rm32-is-first-inout
31763 2/imm32/imm8-is-second-inout
31767 0x11/imm32/alloc-id:fake
31768 _Primitive-shift-mem-right-by-lit/imm32/next
31769 _Primitive-shift-mem-right-by-lit: # (payload primitive)
31770 0x11/imm32/alloc-id:fake:payload
31771 # shift-right var1, lit => c1/shift 5/subop/right var1/rm32 lit/imm32
31772 0x11/imm32/alloc-id:fake
31773 _string-shift-right/imm32/name
31774 0x11/imm32/alloc-id:fake
31775 Int-var-and-literal/imm32/inouts
31778 0x11/imm32/alloc-id:fake
31779 _string_c1_subop_shift_right_padding_zeroes/imm32/subx-name
31780 1/imm32/rm32-is-first-inout
31783 2/imm32/imm8-is-second-inout
31787 0x11/imm32/alloc-id:fake
31788 _Primitive-shift-mem-right-signed-by-lit/imm32/next
31789 _Primitive-shift-mem-right-signed-by-lit: # (payload primitive)
31790 0x11/imm32/alloc-id:fake:payload
31791 # shift-right-signed var1, lit => c1/shift 7/subop/right-preserving-sign var1/rm32 lit/imm32
31792 0x11/imm32/alloc-id:fake
31793 _string-shift-right-signed/imm32/name
31794 0x11/imm32/alloc-id:fake
31795 Int-var-and-literal/imm32/inouts
31798 0x11/imm32/alloc-id:fake
31799 _string_c1_subop_shift_right_preserving_sign/imm32/subx-name
31800 1/imm32/rm32-is-first-inout
31803 2/imm32/imm8-is-second-inout
31807 0x11/imm32/alloc-id:fake
31808 _Primitive-copy-to-eax/imm32/next
31810 _Primitive-copy-to-eax: # (payload primitive)
31811 0x11/imm32/alloc-id:fake:payload
31812 # var/eax <- copy lit => b8/copy-to-eax lit/imm32
31813 0x11/imm32/alloc-id:fake
31814 _string-copy/imm32/name
31815 0x11/imm32/alloc-id:fake
31816 Single-lit-var/imm32/inouts
31817 0x11/imm32/alloc-id:fake
31818 Single-int-var-in-eax/imm32/outputs
31819 0x11/imm32/alloc-id:fake
31820 _string_b8_copy_to_eax/imm32/subx-name
31823 1/imm32/imm32-is-first-inout
31828 0x11/imm32/alloc-id:fake
31829 _Primitive-copy-to-ecx/imm32/next
31830 _Primitive-copy-to-ecx: # (payload primitive)
31831 0x11/imm32/alloc-id:fake:payload
31832 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32
31833 0x11/imm32/alloc-id:fake
31834 _string-copy/imm32/name
31835 0x11/imm32/alloc-id:fake
31836 Single-lit-var/imm32/inouts
31837 0x11/imm32/alloc-id:fake
31838 Single-int-var-in-ecx/imm32/outputs
31839 0x11/imm32/alloc-id:fake
31840 _string_b9_copy_to_ecx/imm32/subx-name
31843 1/imm32/imm32-is-first-inout
31848 0x11/imm32/alloc-id:fake
31849 _Primitive-copy-to-edx/imm32/next
31850 _Primitive-copy-to-edx: # (payload primitive)
31851 0x11/imm32/alloc-id:fake:payload
31852 # var/edx <- copy lit => ba/copy-to-edx lit/imm32
31853 0x11/imm32/alloc-id:fake
31854 _string-copy/imm32/name
31855 0x11/imm32/alloc-id:fake
31856 Single-lit-var/imm32/inouts
31857 0x11/imm32/alloc-id:fake
31858 Single-int-var-in-edx/imm32/outputs
31859 0x11/imm32/alloc-id:fake
31860 _string_ba_copy_to_edx/imm32/subx-name
31863 1/imm32/imm32-is-first-inout
31868 0x11/imm32/alloc-id:fake
31869 _Primitive-copy-to-ebx/imm32/next
31870 _Primitive-copy-to-ebx: # (payload primitive)
31871 0x11/imm32/alloc-id:fake:payload
31872 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32
31873 0x11/imm32/alloc-id:fake
31874 _string-copy/imm32/name
31875 0x11/imm32/alloc-id:fake
31876 Single-lit-var/imm32/inouts
31877 0x11/imm32/alloc-id:fake
31878 Single-int-var-in-ebx/imm32/outputs
31879 0x11/imm32/alloc-id:fake
31880 _string_bb_copy_to_ebx/imm32/subx-name
31883 1/imm32/imm32-is-first-inout
31888 0x11/imm32/alloc-id:fake
31889 _Primitive-copy-to-esi/imm32/next
31890 _Primitive-copy-to-esi: # (payload primitive)
31891 0x11/imm32/alloc-id:fake:payload
31892 # var/esi <- copy lit => be/copy-to-esi lit/imm32
31893 0x11/imm32/alloc-id:fake
31894 _string-copy/imm32/name
31895 0x11/imm32/alloc-id:fake
31896 Single-lit-var/imm32/inouts
31897 0x11/imm32/alloc-id:fake
31898 Single-int-var-in-esi/imm32/outputs
31899 0x11/imm32/alloc-id:fake
31900 _string_be_copy_to_esi/imm32/subx-name
31903 1/imm32/imm32-is-first-inout
31908 0x11/imm32/alloc-id:fake
31909 _Primitive-copy-to-edi/imm32/next
31910 _Primitive-copy-to-edi: # (payload primitive)
31911 0x11/imm32/alloc-id:fake:payload
31912 # var/edi <- copy lit => bf/copy-to-edi lit/imm32
31913 0x11/imm32/alloc-id:fake
31914 _string-copy/imm32/name
31915 0x11/imm32/alloc-id:fake
31916 Single-lit-var/imm32/inouts
31917 0x11/imm32/alloc-id:fake
31918 Single-int-var-in-edi/imm32/outputs
31919 0x11/imm32/alloc-id:fake
31920 _string_bf_copy_to_edi/imm32/subx-name
31923 1/imm32/imm32-is-first-inout
31928 0x11/imm32/alloc-id:fake
31929 _Primitive-copy-reg-to-reg/imm32/next
31930 _Primitive-copy-reg-to-reg: # (payload primitive)
31931 0x11/imm32/alloc-id:fake:payload
31932 # var1/reg <- copy var2/reg => 89/<- var1/rm32 var2/r32
31933 0x11/imm32/alloc-id:fake
31934 _string-copy/imm32/name
31935 0x11/imm32/alloc-id:fake
31936 Single-int-var-in-some-register/imm32/inouts
31937 0x11/imm32/alloc-id:fake
31938 Single-int-var-in-some-register/imm32/outputs
31939 0x11/imm32/alloc-id:fake
31940 _string_89_<-/imm32/subx-name
31941 3/imm32/rm32-is-first-output
31942 1/imm32/r32-is-first-inout
31948 0x11/imm32/alloc-id:fake
31949 _Primitive-copy-reg-to-mem/imm32/next
31950 _Primitive-copy-reg-to-mem: # (payload primitive)
31951 0x11/imm32/alloc-id:fake:payload
31952 # copy-to var1 var2/reg => 89/<- var1 var2/r32
31953 0x11/imm32/alloc-id:fake
31954 _string-copy-to/imm32/name
31955 0x11/imm32/alloc-id:fake
31956 Two-args-int-stack-int-reg/imm32/inouts
31959 0x11/imm32/alloc-id:fake
31960 _string_89_<-/imm32/subx-name
31961 1/imm32/rm32-is-first-inout
31962 2/imm32/r32-is-second-inout
31968 0x11/imm32/alloc-id:fake
31969 _Primitive-copy-mem-to-reg/imm32/next
31970 _Primitive-copy-mem-to-reg: # (payload primitive)
31971 0x11/imm32/alloc-id:fake:payload
31972 # var1/reg <- copy var2 => 8b/-> var2/rm32 var1/r32
31973 0x11/imm32/alloc-id:fake
31974 _string-copy/imm32/name
31975 0x11/imm32/alloc-id:fake
31976 Single-int-var-in-mem/imm32/inouts
31977 0x11/imm32/alloc-id:fake
31978 Single-int-var-in-some-register/imm32/outputs
31979 0x11/imm32/alloc-id:fake
31980 _string_8b_->/imm32/subx-name
31981 1/imm32/rm32-is-first-inout
31982 3/imm32/r32-is-first-output
31988 0x11/imm32/alloc-id:fake
31989 _Primitive-copy-lit-to-reg/imm32/next
31990 _Primitive-copy-lit-to-reg: # (payload primitive)
31991 0x11/imm32/alloc-id:fake:payload
31992 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32
31993 0x11/imm32/alloc-id:fake
31994 _string-copy/imm32/name
31995 0x11/imm32/alloc-id:fake
31996 Single-lit-var/imm32/inouts
31997 0x11/imm32/alloc-id:fake
31998 Single-int-var-in-some-register/imm32/outputs
31999 0x11/imm32/alloc-id:fake
32000 _string_c7_subop_copy/imm32/subx-name
32001 3/imm32/rm32-is-first-output
32003 1/imm32/imm32-is-first-inout
32008 0x11/imm32/alloc-id:fake
32009 _Primitive-copy-lit-to-mem/imm32/next
32010 _Primitive-copy-lit-to-mem: # (payload primitive)
32011 0x11/imm32/alloc-id:fake:payload
32012 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32
32013 0x11/imm32/alloc-id:fake
32014 _string-copy-to/imm32/name
32015 0x11/imm32/alloc-id:fake
32016 Int-var-and-literal/imm32/inouts
32019 0x11/imm32/alloc-id:fake
32020 _string_c7_subop_copy/imm32/subx-name
32021 1/imm32/rm32-is-first-inout
32023 2/imm32/imm32-is-second-inout
32028 0x11/imm32/alloc-id:fake
32029 _Primitive-copy-byte-from-reg/imm32/next
32031 _Primitive-copy-byte-from-reg:
32032 0x11/imm32/alloc-id:fake:payload
32033 # var/reg <- copy-byte var2/reg2 => 8a/byte-> %var2 var/r32
32034 0x11/imm32/alloc-id:fake
32035 _string-copy-byte/imm32/name
32036 0x11/imm32/alloc-id:fake
32037 Single-byte-var-in-some-register/imm32/inouts
32038 0x11/imm32/alloc-id:fake
32039 Single-byte-var-in-some-register/imm32/outputs
32040 0x11/imm32/alloc-id:fake
32041 _string_8a_copy_byte/imm32/subx-name
32042 1/imm32/rm32-is-first-inout
32043 3/imm32/r32-is-first-output
32049 0x11/imm32/alloc-id:fake
32050 _Primitive-copy-byte-from-mem/imm32/next
32051 _Primitive-copy-byte-from-mem:
32052 0x11/imm32/alloc-id:fake:payload
32053 # var/reg <- copy-byte *var2/reg2 => 8a/byte-> *var2 var/r32
32054 0x11/imm32/alloc-id:fake
32055 _string-copy-byte/imm32/name
32056 0x11/imm32/alloc-id:fake
32057 Single-byte-var-in-mem/imm32/inouts
32058 0x11/imm32/alloc-id:fake
32059 Single-byte-var-in-some-register/imm32/outputs
32060 0x11/imm32/alloc-id:fake
32061 _string_8a_copy_byte/imm32/subx-name
32062 1/imm32/rm32-is-first-inout
32063 3/imm32/r32-is-first-output
32069 0x11/imm32/alloc-id:fake
32070 _Primitive-copy-byte-to-mem/imm32/next
32071 _Primitive-copy-byte-to-mem:
32072 0x11/imm32/alloc-id:fake:payload
32073 # copy-byte-to *var1/reg1, var2/reg2 => 88/byte<- *reg1 reg2/r32
32074 0x11/imm32/alloc-id:fake
32075 _string-copy-byte-to/imm32/name
32076 0x11/imm32/alloc-id:fake
32077 Two-args-byte-stack-byte-reg/imm32/inouts
32080 0x11/imm32/alloc-id:fake
32081 _string_88_copy_byte/imm32/subx-name
32082 1/imm32/rm32-is-first-inout
32083 2/imm32/r32-is-second-inout
32089 0x11/imm32/alloc-id:fake
32090 _Primitive-address/imm32/next
32092 _Primitive-address: # (payload primitive)
32093 0x11/imm32/alloc-id:fake:payload
32094 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32
32095 0x11/imm32/alloc-id:fake
32096 _string-address/imm32/name
32097 0x11/imm32/alloc-id:fake
32098 Single-int-var-in-mem/imm32/inouts
32099 0x11/imm32/alloc-id:fake
32100 Single-addr-var-in-some-register/imm32/outputs
32101 0x11/imm32/alloc-id:fake
32102 _string_8d_copy_address/imm32/subx-name
32103 1/imm32/rm32-is-first-inout
32104 3/imm32/r32-is-first-output
32110 0x11/imm32/alloc-id:fake
32111 _Primitive-compare-reg-with-reg/imm32/next
32113 _Primitive-compare-reg-with-reg: # (payload primitive)
32114 0x11/imm32/alloc-id:fake:payload
32115 # compare var1/reg1 var2/reg2 => 39/compare var1/rm32 var2/r32
32116 0x11/imm32/alloc-id:fake
32117 _string-compare/imm32/name
32118 0x11/imm32/alloc-id:fake
32119 Two-int-args-in-regs/imm32/inouts
32122 0x11/imm32/alloc-id:fake
32123 _string_39_compare->/imm32/subx-name
32124 1/imm32/rm32-is-first-inout
32125 2/imm32/r32-is-second-inout
32131 0x11/imm32/alloc-id:fake
32132 _Primitive-compare-mem-with-reg/imm32/next
32133 _Primitive-compare-mem-with-reg: # (payload primitive)
32134 0x11/imm32/alloc-id:fake:payload
32135 # compare var1 var2/reg => 39/compare var1/rm32 var2/r32
32136 0x11/imm32/alloc-id:fake
32137 _string-compare/imm32/name
32138 0x11/imm32/alloc-id:fake
32139 Two-args-int-stack-int-reg/imm32/inouts
32142 0x11/imm32/alloc-id:fake
32143 _string_39_compare->/imm32/subx-name
32144 1/imm32/rm32-is-first-inout
32145 2/imm32/r32-is-second-inout
32151 0x11/imm32/alloc-id:fake
32152 _Primitive-compare-reg-with-mem/imm32/next
32153 _Primitive-compare-reg-with-mem: # (payload primitive)
32154 0x11/imm32/alloc-id:fake:payload
32155 # compare var1/reg var2 => 3b/compare<- var2/rm32 var1/r32
32156 0x11/imm32/alloc-id:fake
32157 _string-compare/imm32/name
32158 0x11/imm32/alloc-id:fake
32159 Two-args-int-reg-int-stack/imm32/inouts
32162 0x11/imm32/alloc-id:fake
32163 _string_3b_compare<-/imm32/subx-name
32164 2/imm32/rm32-is-second-inout
32165 1/imm32/r32-is-first-inout
32171 0x11/imm32/alloc-id:fake
32172 _Primitive-compare-eax-with-literal/imm32/next
32173 _Primitive-compare-eax-with-literal: # (payload primitive)
32174 0x11/imm32/alloc-id:fake:payload
32175 # compare var1/eax n => 3d/compare-eax-with n/imm32
32176 0x11/imm32/alloc-id:fake
32177 _string-compare/imm32/name
32178 0x11/imm32/alloc-id:fake
32179 Two-args-int-eax-int-literal/imm32/inouts
32182 0x11/imm32/alloc-id:fake
32183 _string_3d_compare_eax_with/imm32/subx-name
32186 2/imm32/imm32-is-second-inout
32191 0x11/imm32/alloc-id:fake
32192 _Primitive-compare-reg-with-literal/imm32/next
32193 _Primitive-compare-reg-with-literal: # (payload primitive)
32194 0x11/imm32/alloc-id:fake:payload
32195 # compare var1/reg n => 81 7/subop/compare %reg n/imm32
32196 0x11/imm32/alloc-id:fake
32197 _string-compare/imm32/name
32198 0x11/imm32/alloc-id:fake
32199 Int-var-in-register-and-literal/imm32/inouts
32202 0x11/imm32/alloc-id:fake
32203 _string_81_subop_compare/imm32/subx-name
32204 1/imm32/rm32-is-first-inout
32206 2/imm32/imm32-is-second-inout
32211 0x11/imm32/alloc-id:fake
32212 _Primitive-compare-mem-with-literal/imm32/next
32213 _Primitive-compare-mem-with-literal: # (payload primitive)
32214 0x11/imm32/alloc-id:fake:payload
32215 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32
32216 0x11/imm32/alloc-id:fake
32217 _string-compare/imm32/name
32218 0x11/imm32/alloc-id:fake
32219 Int-var-and-literal/imm32/inouts
32222 0x11/imm32/alloc-id:fake
32223 _string_81_subop_compare/imm32/subx-name
32224 1/imm32/rm32-is-first-inout
32226 2/imm32/imm32-is-second-inout
32231 0x11/imm32/alloc-id:fake
32232 _Primitive-negate-reg/imm32/next
32234 _Primitive-negate-reg: # (payload primitive)
32235 0x11/imm32/alloc-id:fake:payload
32236 # var1/reg <- negate => f7 3/subop/negate var1/rm32
32237 0x11/imm32/alloc-id:fake
32238 _string-negate/imm32/name
32241 0x11/imm32/alloc-id:fake
32242 Single-int-var-in-some-register/imm32/outputs
32243 0x11/imm32/alloc-id:fake
32244 _string_f7_subop_negate/imm32/subx-name
32245 3/imm32/rm32-is-first-output
32252 0x11/imm32/alloc-id:fake
32253 _Primitive-negate-mem/imm32/next
32254 _Primitive-negate-mem: # (payload primitive)
32255 0x11/imm32/alloc-id:fake:payload
32256 # negate var1 => f7 3/subop/negate var1/rm32
32257 0x11/imm32/alloc-id:fake
32258 _string-negate/imm32/name
32259 0x11/imm32/alloc-id:fake
32260 Single-int-var-in-mem/imm32/inouts
32263 0x11/imm32/alloc-id:fake
32264 _string_f7_subop_negate/imm32/subx-name
32265 1/imm32/rm32-is-first-inout
32272 0x11/imm32/alloc-id:fake
32273 _Primitive-multiply-reg-by-reg/imm32/next
32275 _Primitive-multiply-reg-by-reg: # (payload primitive)
32276 0x11/imm32/alloc-id:fake:payload
32277 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32
32278 0x11/imm32/alloc-id:fake
32279 _string-multiply/imm32/name
32280 0x11/imm32/alloc-id:fake
32281 Single-int-var-in-some-register/imm32/inouts
32282 0x11/imm32/alloc-id:fake
32283 Single-int-var-in-some-register/imm32/outputs
32284 0x11/imm32/alloc-id:fake
32285 _string_0f_af_multiply/imm32/subx-name
32286 1/imm32/rm32-is-first-inout
32287 3/imm32/r32-is-first-output
32293 0x11/imm32/alloc-id:fake
32294 _Primitive-multiply-reg-by-mem/imm32/next
32295 _Primitive-multiply-reg-by-mem: # (payload primitive)
32296 0x11/imm32/alloc-id:fake:payload
32297 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32
32298 0x11/imm32/alloc-id:fake
32299 _string-multiply/imm32/name
32300 0x11/imm32/alloc-id:fake
32301 Single-int-var-in-mem/imm32/inouts
32302 0x11/imm32/alloc-id:fake
32303 Single-int-var-in-some-register/imm32/outputs
32304 0x11/imm32/alloc-id:fake
32305 _string_0f_af_multiply/imm32/subx-name
32306 1/imm32/rm32-is-first-inout
32307 3/imm32/r32-is-first-output
32313 0x11/imm32/alloc-id:fake
32314 _Primitive-convert-mem-to-xreg/imm32/next
32315 # - convert int to floating point
32316 _Primitive-convert-mem-to-xreg: # (payload primitive)
32317 0x11/imm32/alloc-id:fake:payload
32318 # var1/xreg <- convert var2 => f3 0f 2a/convert-to-float var2/rm32 var1/x32
32319 0x11/imm32/alloc-id:fake
32320 _string-convert/imm32/name
32321 0x11/imm32/alloc-id:fake
32322 Single-int-var-in-mem/imm32/inouts
32323 0x11/imm32/alloc-id:fake
32324 Single-float-var-in-some-register/imm32/outputs
32325 0x11/imm32/alloc-id:fake
32326 _string_f3_0f_2a_convert_to_float/imm32/subx-name
32327 1/imm32/rm32-is-first-inout
32333 3/imm32/x32-is-first-output
32334 0x11/imm32/alloc-id:fake
32335 _Primitive-convert-reg-to-xreg/imm32/next
32336 _Primitive-convert-reg-to-xreg: # (payload primitive)
32337 0x11/imm32/alloc-id:fake:payload
32338 # var1/xreg <- convert var2/reg => f3 0f 2a/convert-to-float var2/rm32 var1/x32
32339 0x11/imm32/alloc-id:fake
32340 _string-convert/imm32/name
32341 0x11/imm32/alloc-id:fake
32342 Single-int-var-in-some-register/imm32/inouts
32343 0x11/imm32/alloc-id:fake
32344 Single-float-var-in-some-register/imm32/outputs
32345 0x11/imm32/alloc-id:fake
32346 _string_f3_0f_2a_convert_to_float/imm32/subx-name
32347 1/imm32/rm32-is-first-inout
32353 3/imm32/x32-is-first-output
32354 0x11/imm32/alloc-id:fake
32355 _Primitive-convert-xmem-to-reg/imm32/next
32356 # - convert floating point to int
32357 _Primitive-convert-xmem-to-reg: # (payload primitive)
32358 0x11/imm32/alloc-id:fake:payload
32359 # var1/reg <- convert var2 => f3 0f 2d/convert-to-int var2/xm32 var1/r32
32360 0x11/imm32/alloc-id:fake
32361 _string-convert/imm32/name
32362 0x11/imm32/alloc-id:fake
32363 Single-float-var-in-mem/imm32/inouts
32364 0x11/imm32/alloc-id:fake
32365 Single-int-var-in-some-register/imm32/outputs
32366 0x11/imm32/alloc-id:fake
32367 _string_f3_0f_2d_convert_to_int/imm32/subx-name
32369 3/imm32/r32-is-first-output
32373 1/imm32/xm32-is-first-inout
32375 0x11/imm32/alloc-id:fake
32376 _Primitive-convert-xreg-to-reg/imm32/next
32377 _Primitive-convert-xreg-to-reg: # (payload primitive)
32378 0x11/imm32/alloc-id:fake:payload
32379 # var1/reg <- convert var2/xreg => f3 0f 2d/convert-to-int var2/xm32 var1/r32
32380 0x11/imm32/alloc-id:fake
32381 _string-convert/imm32/name
32382 0x11/imm32/alloc-id:fake
32383 Single-float-var-in-some-register/imm32/inouts
32384 0x11/imm32/alloc-id:fake
32385 Single-int-var-in-some-register/imm32/outputs
32386 0x11/imm32/alloc-id:fake
32387 _string_f3_0f_2d_convert_to_int/imm32/subx-name
32389 3/imm32/r32-is-first-output
32393 1/imm32/xm32-is-first-inout
32395 0x11/imm32/alloc-id:fake
32396 _Primitive-truncate-xmem-to-reg/imm32/next
32397 _Primitive-truncate-xmem-to-reg: # (payload primitive)
32398 0x11/imm32/alloc-id:fake:payload
32399 # var1/reg <- truncate var2 => f3 0f 2c/truncate-to-int var2/xm32 var1/r32
32400 0x11/imm32/alloc-id:fake
32401 _string-truncate/imm32/name
32402 0x11/imm32/alloc-id:fake
32403 Single-float-var-in-mem/imm32/inouts
32404 0x11/imm32/alloc-id:fake
32405 Single-int-var-in-some-register/imm32/outputs
32406 0x11/imm32/alloc-id:fake
32407 _string_f3_0f_2c_truncate_to_int/imm32/subx-name
32409 3/imm32/r32-is-first-output
32413 1/imm32/xm32-is-first-inout
32415 0x11/imm32/alloc-id:fake
32416 _Primitive-truncate-xreg-to-reg/imm32/next
32417 _Primitive-truncate-xreg-to-reg: # (payload primitive)
32418 0x11/imm32/alloc-id:fake:payload
32419 # var1/reg <- truncate var2/xreg => f3 0f 2c/truncate-to-int var2/xm32 var1/r32
32420 0x11/imm32/alloc-id:fake
32421 _string-truncate/imm32/name
32422 0x11/imm32/alloc-id:fake
32423 Single-float-var-in-some-register/imm32/inouts
32424 0x11/imm32/alloc-id:fake
32425 Single-int-var-in-some-register/imm32/outputs
32426 0x11/imm32/alloc-id:fake
32427 _string_f3_0f_2c_truncate_to_int/imm32/subx-name
32429 3/imm32/r32-is-first-output
32433 1/imm32/xm32-is-first-inout
32435 0x11/imm32/alloc-id:fake
32436 _Primitive-reinterpret-xmem-as-reg/imm32/next
32437 # - reinterpret bytes (just for debugging)
32438 _Primitive-reinterpret-xmem-as-reg: # (payload primitive)
32439 0x11/imm32/alloc-id:fake:payload
32440 # var1/reg <- reinterpret var2 => 8b/-> var2/xm32 var1/r32
32441 0x11/imm32/alloc-id:fake
32442 _string-reinterpret/imm32/name
32443 0x11/imm32/alloc-id:fake
32444 Single-float-var-in-mem/imm32/inouts
32445 0x11/imm32/alloc-id:fake
32446 Single-int-var-in-some-register/imm32/outputs
32447 0x11/imm32/alloc-id:fake
32448 _string_8b_->/imm32/subx-name
32450 3/imm32/r32-is-first-output
32454 1/imm32/xm32-is-first-inout
32456 0x11/imm32/alloc-id:fake
32457 _Primitive-reinterpret-mem-as-xreg/imm32/next
32458 _Primitive-reinterpret-mem-as-xreg: # (payload primitive)
32459 0x11/imm32/alloc-id:fake:payload
32460 # var1/xreg <- reinterpret var2 => f3 0f 10/-> var2/rm32 var1/x32
32461 0x11/imm32/alloc-id:fake
32462 _string-reinterpret/imm32/name
32463 0x11/imm32/alloc-id:fake
32464 Single-int-var-in-mem/imm32/inouts
32465 0x11/imm32/alloc-id:fake
32466 Single-float-var-in-some-register/imm32/outputs
32467 0x11/imm32/alloc-id:fake
32468 _string_f3_0f_10_copy/imm32/subx-name
32469 1/imm32/rm32-is-first-inout
32475 3/imm32/x32-is-first-output
32476 0x11/imm32/alloc-id:fake
32477 _Primitive-copy-xreg-to-xreg/imm32/next
32478 # - floating-point copy
32479 _Primitive-copy-xreg-to-xreg: # (payload primitive)
32480 0x11/imm32/alloc-id:fake:payload
32481 # var1/xreg <- copy var2/xreg => f3 0f 11/<- var1/xm32 var2/x32
32482 0x11/imm32/alloc-id:fake
32483 _string-copy/imm32/name
32484 0x11/imm32/alloc-id:fake
32485 Single-float-var-in-some-register/imm32/inouts
32486 0x11/imm32/alloc-id:fake
32487 Single-float-var-in-some-register/imm32/outputs
32488 0x11/imm32/alloc-id:fake
32489 _string_f3_0f_11_copy/imm32/subx-name
32495 3/imm32/xm32-is-first-output
32496 1/imm32/x32-is-first-inout
32497 0x11/imm32/alloc-id:fake
32498 _Primitive-copy-xreg-to-mem/imm32/next
32499 _Primitive-copy-xreg-to-mem: # (payload primitive)
32500 0x11/imm32/alloc-id:fake:payload
32501 # copy-to var1 var2/xreg => f3 0f 11/<- var1 var2/x32
32502 0x11/imm32/alloc-id:fake
32503 _string-copy-to/imm32/name
32504 0x11/imm32/alloc-id:fake
32505 Two-args-float-stack-float-reg/imm32/inouts
32508 0x11/imm32/alloc-id:fake
32509 _string_f3_0f_11_copy/imm32/subx-name
32515 1/imm32/xm32-is-first-inout
32516 2/imm32/x32-is-second-inout
32517 0x11/imm32/alloc-id:fake
32518 _Primitive-copy-mem-to-xreg/imm32/next
32519 _Primitive-copy-mem-to-xreg: # (payload primitive)
32520 0x11/imm32/alloc-id:fake:payload
32521 # var1/xreg <- copy var2 => f3 0f 10/-> var2/rm32 var1/x32
32522 0x11/imm32/alloc-id:fake
32523 _string-copy/imm32/name
32524 0x11/imm32/alloc-id:fake
32525 Single-float-var-in-mem/imm32/inouts
32526 0x11/imm32/alloc-id:fake
32527 Single-float-var-in-some-register/imm32/outputs
32528 0x11/imm32/alloc-id:fake
32529 _string_f3_0f_10_copy/imm32/subx-name
32535 1/imm32/xm32-is-first-inout
32536 3/imm32/x32-is-first-output
32537 0x11/imm32/alloc-id:fake
32538 _Primitive-address-of-xmem/imm32/next
32539 # - floating-point-address
32540 _Primitive-address-of-xmem: # (payload primitive)
32541 0x11/imm32/alloc-id:fake:payload
32542 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32
32543 0x11/imm32/alloc-id:fake
32544 _string-address/imm32/name
32545 0x11/imm32/alloc-id:fake
32546 Single-float-var-in-mem/imm32/inouts
32547 0x11/imm32/alloc-id:fake
32548 Single-addr-var-in-some-register/imm32/outputs
32549 0x11/imm32/alloc-id:fake
32550 _string_8d_copy_address/imm32/subx-name
32551 1/imm32/rm32-is-first-inout
32552 3/imm32/r32-is-first-output
32558 0x11/imm32/alloc-id:fake
32559 _Primitive-add-xreg-to-xreg/imm32/next
32560 # - floating-point add
32561 _Primitive-add-xreg-to-xreg: # (payload primitive)
32562 0x11/imm32/alloc-id:fake:payload
32563 # var1/xreg <- add var2/xreg => f3 0f 58/add var1/xm32 var2/x32
32564 0x11/imm32/alloc-id:fake
32565 _string-add/imm32/name
32566 0x11/imm32/alloc-id:fake
32567 Single-float-var-in-some-register/imm32/inouts
32568 0x11/imm32/alloc-id:fake
32569 Single-float-var-in-some-register/imm32/outputs
32570 0x11/imm32/alloc-id:fake
32571 _string_f3_0f_58_add/imm32/subx-name
32577 1/imm32/xm32-is-first-inout
32578 3/imm32/x32-is-first-output
32579 0x11/imm32/alloc-id:fake
32580 _Primitive-add-mem-to-xreg/imm32/next
32581 _Primitive-add-mem-to-xreg: # (payload primitive)
32582 0x11/imm32/alloc-id:fake:payload
32583 # var1/xreg <- add var2 => f3 0f 58/add var2/xm32 var1/x32
32584 0x11/imm32/alloc-id:fake
32585 _string-add/imm32/name
32586 0x11/imm32/alloc-id:fake
32587 Single-float-var-in-mem/imm32/inouts
32588 0x11/imm32/alloc-id:fake
32589 Single-float-var-in-some-register/imm32/outputs
32590 0x11/imm32/alloc-id:fake
32591 _string_f3_0f_58_add/imm32/subx-name
32597 1/imm32/xm32-is-first-inout
32598 3/imm32/x32-is-first-output
32599 0x11/imm32/alloc-id:fake
32600 _Primitive-subtract-xreg-from-xreg/imm32/next
32601 # - floating-point subtract
32602 _Primitive-subtract-xreg-from-xreg: # (payload primitive)
32603 0x11/imm32/alloc-id:fake:payload
32604 # var1/xreg <- subtract var2/xreg => f3 0f 5c/subtract var1/xm32 var2/x32
32605 0x11/imm32/alloc-id:fake
32606 _string-subtract/imm32/name
32607 0x11/imm32/alloc-id:fake
32608 Single-float-var-in-some-register/imm32/inouts
32609 0x11/imm32/alloc-id:fake
32610 Single-float-var-in-some-register/imm32/outputs
32611 0x11/imm32/alloc-id:fake
32612 _string_f3_0f_5c_subtract/imm32/subx-name
32618 1/imm32/xm32-is-first-inout
32619 3/imm32/x32-is-first-output
32620 0x11/imm32/alloc-id:fake
32621 _Primitive-subtract-mem-from-xreg/imm32/next
32622 _Primitive-subtract-mem-from-xreg: # (payload primitive)
32623 0x11/imm32/alloc-id:fake:payload
32624 # var1/xreg <- subtract var2 => f3 0f 5c/subtract var2/xm32 var1/x32
32625 0x11/imm32/alloc-id:fake
32626 _string-subtract/imm32/name
32627 0x11/imm32/alloc-id:fake
32628 Single-float-var-in-mem/imm32/inouts
32629 0x11/imm32/alloc-id:fake
32630 Single-float-var-in-some-register/imm32/outputs
32631 0x11/imm32/alloc-id:fake
32632 _string_f3_0f_5c_subtract/imm32/subx-name
32638 1/imm32/xm32-is-first-inout
32639 3/imm32/x32-is-first-output
32640 0x11/imm32/alloc-id:fake
32641 _Primitive-multiply-xreg-by-xreg/imm32/next
32642 # - floating-point multiply
32643 _Primitive-multiply-xreg-by-xreg: # (payload primitive)
32644 0x11/imm32/alloc-id:fake:payload
32645 # var1/xreg <- multiply var2 => f3 0f 59/multiply var2/xm32 var1/x32
32646 0x11/imm32/alloc-id:fake
32647 _string-multiply/imm32/name
32648 0x11/imm32/alloc-id:fake
32649 Single-float-var-in-some-register/imm32/inouts
32650 0x11/imm32/alloc-id:fake
32651 Single-float-var-in-some-register/imm32/outputs
32652 0x11/imm32/alloc-id:fake
32653 _string_f3_0f_59_multiply/imm32/subx-name
32659 1/imm32/xm32-is-first-inout
32660 3/imm32/x32-is-first-output
32661 0x11/imm32/alloc-id:fake
32662 _Primitive-multiply-xreg-by-mem/imm32/next
32663 _Primitive-multiply-xreg-by-mem: # (payload primitive)
32664 0x11/imm32/alloc-id:fake:payload
32665 # var1/xreg <- multiply var2 => 53 0f 59/multiply var2/xm32 var1/x32
32666 0x11/imm32/alloc-id:fake
32667 _string-multiply/imm32/name
32668 0x11/imm32/alloc-id:fake
32669 Single-float-var-in-mem/imm32/inouts
32670 0x11/imm32/alloc-id:fake
32671 Single-float-var-in-some-register/imm32/outputs
32672 0x11/imm32/alloc-id:fake
32673 _string_f3_0f_59_multiply/imm32/subx-name
32679 1/imm32/xm32-is-first-inout
32680 3/imm32/x32-is-first-output
32681 0x11/imm32/alloc-id:fake
32682 _Primitive-divide-xreg-by-xreg/imm32/next
32683 # - floating-point divide
32684 _Primitive-divide-xreg-by-xreg: # (payload primitive)
32685 0x11/imm32/alloc-id:fake:payload
32686 # var1/xreg <- divide var2 => f3 0f 5e/divide var2/xm32 var1/x32
32687 0x11/imm32/alloc-id:fake
32688 _string-divide/imm32/name
32689 0x11/imm32/alloc-id:fake
32690 Single-float-var-in-some-register/imm32/inouts
32691 0x11/imm32/alloc-id:fake
32692 Single-float-var-in-some-register/imm32/outputs
32693 0x11/imm32/alloc-id:fake
32694 _string_f3_0f_5e_divide/imm32/subx-name
32700 1/imm32/xm32-is-first-inout
32701 3/imm32/x32-is-first-output
32702 0x11/imm32/alloc-id:fake
32703 _Primitive-divide-xreg-by-mem/imm32/next
32704 _Primitive-divide-xreg-by-mem: # (payload primitive)
32705 0x11/imm32/alloc-id:fake:payload
32706 # var1/xreg <- divide var2 => f3 0f 5e/divide var2/xm32 var1/x32
32707 0x11/imm32/alloc-id:fake
32708 _string-divide/imm32/name
32709 0x11/imm32/alloc-id:fake
32710 Single-float-var-in-mem/imm32/inouts
32711 0x11/imm32/alloc-id:fake
32712 Single-float-var-in-some-register/imm32/outputs
32713 0x11/imm32/alloc-id:fake
32714 _string_f3_0f_5e_divide/imm32/subx-name
32720 1/imm32/xm32-is-first-inout
32721 3/imm32/x32-is-first-output
32722 0x11/imm32/alloc-id:fake
32723 _Primitive-max-xreg-with-xreg/imm32/next
32724 # - floating-point maximum
32725 _Primitive-max-xreg-with-xreg: # (payload primitive)
32726 0x11/imm32/alloc-id:fake:payload
32727 # var1/xreg <- max var2 => f3 0f 5f/max var2/xm32 var1/x32
32728 0x11/imm32/alloc-id:fake
32729 _string-max/imm32/name
32730 0x11/imm32/alloc-id:fake
32731 Single-float-var-in-some-register/imm32/inouts
32732 0x11/imm32/alloc-id:fake
32733 Single-float-var-in-some-register/imm32/outputs
32734 0x11/imm32/alloc-id:fake
32735 _string_f3_0f_5f_max/imm32/subx-name
32741 1/imm32/xm32-is-first-inout
32742 3/imm32/x32-is-first-output
32743 0x11/imm32/alloc-id:fake
32744 _Primitive-max-xreg-with-mem/imm32/next
32745 _Primitive-max-xreg-with-mem: # (payload primitive)
32746 0x11/imm32/alloc-id:fake:payload
32747 # var1/xreg <- divide var2 => f3 0f 5f/max var2/xm32 var1/x32
32748 0x11/imm32/alloc-id:fake
32749 _string-max/imm32/name
32750 0x11/imm32/alloc-id:fake
32751 Single-float-var-in-mem/imm32/inouts
32752 0x11/imm32/alloc-id:fake
32753 Single-float-var-in-some-register/imm32/outputs
32754 0x11/imm32/alloc-id:fake
32755 _string_f3_0f_5f_max/imm32/subx-name
32761 1/imm32/xm32-is-first-inout
32762 3/imm32/x32-is-first-output
32763 0x11/imm32/alloc-id:fake
32764 _Primitive-min-xreg-with-xreg/imm32/next
32765 # - floating-point minimum
32766 _Primitive-min-xreg-with-xreg: # (payload primitive)
32767 0x11/imm32/alloc-id:fake:payload
32768 # var1/xreg <- divide var2 => f3 0f 5d/min var2/xm32 var1/x32
32769 0x11/imm32/alloc-id:fake
32770 _string-min/imm32/name
32771 0x11/imm32/alloc-id:fake
32772 Single-float-var-in-some-register/imm32/inouts
32773 0x11/imm32/alloc-id:fake
32774 Single-float-var-in-some-register/imm32/outputs
32775 0x11/imm32/alloc-id:fake
32776 _string_f3_0f_5d_min/imm32/subx-name
32782 1/imm32/xm32-is-first-inout
32783 3/imm32/x32-is-first-output
32784 0x11/imm32/alloc-id:fake
32785 _Primitive-min-xreg-with-mem/imm32/next
32786 _Primitive-min-xreg-with-mem: # (payload primitive)
32787 0x11/imm32/alloc-id:fake:payload
32788 # var1/xreg <- divide var2 => f3 0f 5d/min var2/xm32 var1/x32
32789 0x11/imm32/alloc-id:fake
32790 _string-min/imm32/name
32791 0x11/imm32/alloc-id:fake
32792 Single-float-var-in-mem/imm32/inouts
32793 0x11/imm32/alloc-id:fake
32794 Single-float-var-in-some-register/imm32/outputs
32795 0x11/imm32/alloc-id:fake
32796 _string_f3_0f_5d_min/imm32/subx-name
32802 1/imm32/xm32-is-first-inout
32803 3/imm32/x32-is-first-output
32804 0x11/imm32/alloc-id:fake
32805 _Primitive-reciprocal-xreg-to-xreg/imm32/next
32806 # - floating-point reciprocal
32807 _Primitive-reciprocal-xreg-to-xreg: # (payload primitive)
32808 0x11/imm32/alloc-id:fake:payload
32809 # var1/xreg <- reciprocal var2 => f3 0f 53/reciprocal var2/xm32 var1/x32
32810 0x11/imm32/alloc-id:fake
32811 _string-reciprocal/imm32/name
32812 0x11/imm32/alloc-id:fake
32813 Single-float-var-in-some-register/imm32/inouts
32814 0x11/imm32/alloc-id:fake
32815 Single-float-var-in-some-register/imm32/outputs
32816 0x11/imm32/alloc-id:fake
32817 _string_f3_0f_53_reciprocal/imm32/subx-name
32823 1/imm32/xm32-is-first-inout
32824 3/imm32/x32-is-first-output
32825 0x11/imm32/alloc-id:fake
32826 _Primitive-reciprocal-mem-to-xreg/imm32/next
32827 _Primitive-reciprocal-mem-to-xreg: # (payload primitive)
32828 0x11/imm32/alloc-id:fake:payload
32829 # var1/xreg <- divide var2 => f3 0f 53/reciprocal var2/xm32 var1/x32
32830 0x11/imm32/alloc-id:fake
32831 _string-reciprocal/imm32/name
32832 0x11/imm32/alloc-id:fake
32833 Single-float-var-in-mem/imm32/inouts
32834 0x11/imm32/alloc-id:fake
32835 Single-float-var-in-some-register/imm32/outputs
32836 0x11/imm32/alloc-id:fake
32837 _string_f3_0f_53_reciprocal/imm32/subx-name
32843 1/imm32/xm32-is-first-inout
32844 3/imm32/x32-is-first-output
32845 0x11/imm32/alloc-id:fake
32846 _Primitive-square-root-xreg-to-xreg/imm32/next
32847 # - floating-point square root
32848 _Primitive-square-root-xreg-to-xreg: # (payload primitive)
32849 0x11/imm32/alloc-id:fake:payload
32850 # var1/xreg <- square-root var2 => f3 0f 51/square-root var2/xm32 var1/x32
32851 0x11/imm32/alloc-id:fake
32852 _string-square-root/imm32/name
32853 0x11/imm32/alloc-id:fake
32854 Single-float-var-in-some-register/imm32/inouts
32855 0x11/imm32/alloc-id:fake
32856 Single-float-var-in-some-register/imm32/outputs
32857 0x11/imm32/alloc-id:fake
32858 _string_f3_0f_51_square_root/imm32/subx-name
32864 1/imm32/xm32-is-first-inout
32865 3/imm32/x32-is-first-output
32866 0x11/imm32/alloc-id:fake
32867 _Primitive-square-root-mem-to-xreg/imm32/next
32868 _Primitive-square-root-mem-to-xreg: # (payload primitive)
32869 0x11/imm32/alloc-id:fake:payload
32870 # var1/xreg <- divide var2 => f3 0f 51/square-root var2/xm32 var1/x32
32871 0x11/imm32/alloc-id:fake
32872 _string-square-root/imm32/name
32873 0x11/imm32/alloc-id:fake
32874 Single-float-var-in-mem/imm32/inouts
32875 0x11/imm32/alloc-id:fake
32876 Single-float-var-in-some-register/imm32/outputs
32877 0x11/imm32/alloc-id:fake
32878 _string_f3_0f_51_square_root/imm32/subx-name
32884 1/imm32/xm32-is-first-inout
32885 3/imm32/x32-is-first-output
32886 0x11/imm32/alloc-id:fake
32887 _Primitive-inverse-square-root-xreg-to-xreg/imm32/next
32888 # - floating-point inverse square root 1/sqrt(x)
32889 _Primitive-inverse-square-root-xreg-to-xreg: # (payload primitive)
32890 0x11/imm32/alloc-id:fake:payload
32891 # var1/xreg <- reciprocal var2 => f3 0f 52/inverse-square-root var2/xm32 var1/x32
32892 0x11/imm32/alloc-id:fake
32893 _string-inverse-square-root/imm32/name
32894 0x11/imm32/alloc-id:fake
32895 Single-float-var-in-some-register/imm32/inouts
32896 0x11/imm32/alloc-id:fake
32897 Single-float-var-in-some-register/imm32/outputs
32898 0x11/imm32/alloc-id:fake
32899 _string_f3_0f_52_inverse_square_root/imm32/subx-name
32905 1/imm32/xm32-is-first-inout
32906 3/imm32/x32-is-first-output
32907 0x11/imm32/alloc-id:fake
32908 _Primitive-inverse-square-root-mem-to-xreg/imm32/next
32909 _Primitive-inverse-square-root-mem-to-xreg: # (payload primitive)
32910 0x11/imm32/alloc-id:fake:payload
32911 # var1/xreg <- divide var2 => f3 0f 52/inverse-square-root var2/xm32 var1/x32
32912 0x11/imm32/alloc-id:fake
32913 _string-inverse-square-root/imm32/name
32914 0x11/imm32/alloc-id:fake
32915 Single-float-var-in-mem/imm32/inouts
32916 0x11/imm32/alloc-id:fake
32917 Single-float-var-in-some-register/imm32/outputs
32918 0x11/imm32/alloc-id:fake
32919 _string_f3_0f_52_inverse_square_root/imm32/subx-name
32925 1/imm32/xm32-is-first-inout
32926 3/imm32/x32-is-first-output
32927 0x11/imm32/alloc-id:fake
32928 _Primitive-compare-xreg-with-xreg/imm32/next
32929 # - floating-point compare
32930 _Primitive-compare-xreg-with-xreg: # (payload primitive)
32931 0x11/imm32/alloc-id:fake:payload
32932 # compare var1/reg1 var2/reg2 => 0f 2f/compare var2/x32 var1/xm32
32933 0x11/imm32/alloc-id:fake
32934 _string-compare/imm32/name
32935 0x11/imm32/alloc-id:fake
32936 Two-float-args-in-regs/imm32/inouts
32939 0x11/imm32/alloc-id:fake
32940 _string_0f_2f_compare/imm32/subx-name
32946 2/imm32/xm32-is-second-inout
32947 1/imm32/x32-is-first-inout
32948 0x11/imm32/alloc-id:fake
32949 _Primitive-compare-xreg-with-mem/imm32/next
32950 _Primitive-compare-xreg-with-mem: # (payload primitive)
32951 0x11/imm32/alloc-id:fake:payload
32952 # compare var1/xreg var2 => 0f 2f/compare var1/x32 var2/xm32
32953 0x11/imm32/alloc-id:fake
32954 _string-compare/imm32/name
32955 0x11/imm32/alloc-id:fake
32956 Two-args-float-reg-float-stack/imm32/inouts
32959 0x11/imm32/alloc-id:fake
32960 _string_0f_2f_compare/imm32/subx-name
32966 2/imm32/xm32-is-second-inout
32967 1/imm32/x32-is-first-inout
32968 0x11/imm32/alloc-id:fake
32969 _Primitive-break-if-addr</imm32/next
32971 _Primitive-break-if-addr<: # (payload primitive)
32972 0x11/imm32/alloc-id:fake:payload
32973 0x11/imm32/alloc-id:fake
32974 _string-break-if-addr</imm32/name
32979 0x11/imm32/alloc-id:fake
32980 _string_0f_82_jump_break/imm32/subx-name
32988 0x11/imm32/alloc-id:fake
32989 _Primitive-break-if-addr>=/imm32/next
32990 _Primitive-break-if-addr>=: # (payload primitive)
32991 0x11/imm32/alloc-id:fake:payload
32992 0x11/imm32/alloc-id:fake
32993 _string-break-if-addr>=/imm32/name
32998 0x11/imm32/alloc-id:fake
32999 _string_0f_83_jump_break/imm32/subx-name
33007 0x11/imm32/alloc-id:fake
33008 _Primitive-break-if-=/imm32/next
33009 _Primitive-break-if-=: # (payload primitive)
33010 0x11/imm32/alloc-id:fake:payload
33011 0x11/imm32/alloc-id:fake
33012 _string-break-if-=/imm32/name
33017 0x11/imm32/alloc-id:fake
33018 _string_0f_84_jump_break/imm32/subx-name
33026 0x11/imm32/alloc-id:fake
33027 _Primitive-break-if-!=/imm32/next
33028 _Primitive-break-if-!=: # (payload primitive)
33029 0x11/imm32/alloc-id:fake:payload
33030 0x11/imm32/alloc-id:fake
33031 _string-break-if-!=/imm32/name
33036 0x11/imm32/alloc-id:fake
33037 _string_0f_85_jump_break/imm32/subx-name
33045 0x11/imm32/alloc-id:fake
33046 _Primitive-break-if-addr<=/imm32/next
33047 _Primitive-break-if-addr<=: # (payload primitive)
33048 0x11/imm32/alloc-id:fake:payload
33049 0x11/imm32/alloc-id:fake
33050 _string-break-if-addr<=/imm32/name
33055 0x11/imm32/alloc-id:fake
33056 _string_0f_86_jump_break/imm32/subx-name
33064 0x11/imm32/alloc-id:fake
33065 _Primitive-break-if-addr>/imm32/next
33066 _Primitive-break-if-addr>: # (payload primitive)
33067 0x11/imm32/alloc-id:fake:payload
33068 0x11/imm32/alloc-id:fake
33069 _string-break-if-addr>/imm32/name
33074 0x11/imm32/alloc-id:fake
33075 _string_0f_87_jump_break/imm32/subx-name
33083 0x11/imm32/alloc-id:fake
33084 _Primitive-break-if-</imm32/next
33085 _Primitive-break-if-<: # (payload primitive)
33086 0x11/imm32/alloc-id:fake:payload
33087 0x11/imm32/alloc-id:fake
33088 _string-break-if-</imm32/name
33093 0x11/imm32/alloc-id:fake
33094 _string_0f_8c_jump_break/imm32/subx-name
33102 0x11/imm32/alloc-id:fake
33103 _Primitive-break-if->=/imm32/next
33104 _Primitive-break-if->=: # (payload primitive)
33105 0x11/imm32/alloc-id:fake:payload
33106 0x11/imm32/alloc-id:fake
33107 _string-break-if->=/imm32/name
33112 0x11/imm32/alloc-id:fake
33113 _string_0f_8d_jump_break/imm32/subx-name
33121 0x11/imm32/alloc-id:fake
33122 _Primitive-break-if-<=/imm32/next
33123 _Primitive-break-if-<=: # (payload primitive)
33124 0x11/imm32/alloc-id:fake:payload
33125 0x11/imm32/alloc-id:fake
33126 _string-break-if-<=/imm32/name
33131 0x11/imm32/alloc-id:fake
33132 _string_0f_8e_jump_break/imm32/subx-name
33140 0x11/imm32/alloc-id:fake
33141 _Primitive-break-if->/imm32/next
33142 _Primitive-break-if->: # (payload primitive)
33143 0x11/imm32/alloc-id:fake:payload
33144 0x11/imm32/alloc-id:fake
33145 _string-break-if->/imm32/name
33150 0x11/imm32/alloc-id:fake
33151 _string_0f_8f_jump_break/imm32/subx-name
33159 0x11/imm32/alloc-id:fake
33160 _Primitive-break-if-carry/imm32/next
33161 _Primitive-break-if-carry: # (payload primitive)
33162 0x11/imm32/alloc-id:fake:payload
33163 0x11/imm32/alloc-id:fake
33164 _string-break-if-carry/imm32/name
33169 0x11/imm32/alloc-id:fake
33170 _string_0f_82_jump_break/imm32/subx-name
33178 0x11/imm32/alloc-id:fake
33179 _Primitive-break-if-not-carry/imm32/next
33180 _Primitive-break-if-not-carry: # (payload primitive)
33181 0x11/imm32/alloc-id:fake:payload
33182 0x11/imm32/alloc-id:fake
33183 _string-break-if-not-carry/imm32/name
33188 0x11/imm32/alloc-id:fake
33189 _string_0f_83_jump_break/imm32/subx-name
33197 0x11/imm32/alloc-id:fake
33198 _Primitive-break-if-overflow/imm32/next
33199 _Primitive-break-if-overflow: # (payload primitive)
33200 0x11/imm32/alloc-id:fake:payload
33201 0x11/imm32/alloc-id:fake
33202 _string-break-if-overflow/imm32/name
33207 0x11/imm32/alloc-id:fake
33208 _string_0f_80_jump_break/imm32/subx-name
33216 0x11/imm32/alloc-id:fake
33217 _Primitive-break-if-not-overflow/imm32/next
33218 _Primitive-break-if-not-overflow: # (payload primitive)
33219 0x11/imm32/alloc-id:fake:payload
33220 0x11/imm32/alloc-id:fake
33221 _string-break-if-not-overflow/imm32/name
33226 0x11/imm32/alloc-id:fake
33227 _string_0f_81_jump_break/imm32/subx-name
33235 0x11/imm32/alloc-id:fake
33236 _Primitive-break/imm32/next
33237 _Primitive-break: # (payload primitive)
33238 0x11/imm32/alloc-id:fake:payload
33239 0x11/imm32/alloc-id:fake
33240 _string-break/imm32/name
33245 0x11/imm32/alloc-id:fake
33246 _string_e9_jump_break/imm32/subx-name
33254 0x11/imm32/alloc-id:fake
33255 _Primitive-loop-if-addr</imm32/next
33256 _Primitive-loop-if-addr<: # (payload primitive)
33257 0x11/imm32/alloc-id:fake:payload
33258 0x11/imm32/alloc-id:fake
33259 _string-loop-if-addr</imm32/name
33264 0x11/imm32/alloc-id:fake
33265 _string_0f_82_jump_loop/imm32/subx-name
33273 0x11/imm32/alloc-id:fake
33274 _Primitive-loop-if-addr>=/imm32/next
33275 _Primitive-loop-if-addr>=: # (payload primitive)
33276 0x11/imm32/alloc-id:fake:payload
33277 0x11/imm32/alloc-id:fake
33278 _string-loop-if-addr>=/imm32/name
33283 0x11/imm32/alloc-id:fake
33284 _string_0f_83_jump_loop/imm32/subx-name
33292 0x11/imm32/alloc-id:fake
33293 _Primitive-loop-if-=/imm32/next
33294 _Primitive-loop-if-=: # (payload primitive)
33295 0x11/imm32/alloc-id:fake:payload
33296 0x11/imm32/alloc-id:fake
33297 _string-loop-if-=/imm32/name
33302 0x11/imm32/alloc-id:fake
33303 _string_0f_84_jump_loop/imm32/subx-name
33311 0x11/imm32/alloc-id:fake
33312 _Primitive-loop-if-!=/imm32/next
33313 _Primitive-loop-if-!=: # (payload primitive)
33314 0x11/imm32/alloc-id:fake:payload
33315 0x11/imm32/alloc-id:fake
33316 _string-loop-if-!=/imm32/name
33321 0x11/imm32/alloc-id:fake
33322 _string_0f_85_jump_loop/imm32/subx-name
33330 0x11/imm32/alloc-id:fake
33331 _Primitive-loop-if-addr<=/imm32/next
33332 _Primitive-loop-if-addr<=: # (payload primitive)
33333 0x11/imm32/alloc-id:fake:payload
33334 0x11/imm32/alloc-id:fake
33335 _string-loop-if-addr<=/imm32/name
33340 0x11/imm32/alloc-id:fake
33341 _string_0f_86_jump_loop/imm32/subx-name
33349 0x11/imm32/alloc-id:fake
33350 _Primitive-loop-if-addr>/imm32/next
33351 _Primitive-loop-if-addr>: # (payload primitive)
33352 0x11/imm32/alloc-id:fake:payload
33353 0x11/imm32/alloc-id:fake
33354 _string-loop-if-addr>/imm32/name
33359 0x11/imm32/alloc-id:fake
33360 _string_0f_87_jump_loop/imm32/subx-name
33368 0x11/imm32/alloc-id:fake
33369 _Primitive-loop-if-</imm32/next
33370 _Primitive-loop-if-<: # (payload primitive)
33371 0x11/imm32/alloc-id:fake:payload
33372 0x11/imm32/alloc-id:fake
33373 _string-loop-if-</imm32/name
33378 0x11/imm32/alloc-id:fake
33379 _string_0f_8c_jump_loop/imm32/subx-name
33387 0x11/imm32/alloc-id:fake
33388 _Primitive-loop-if->=/imm32/next
33389 _Primitive-loop-if->=: # (payload primitive)
33390 0x11/imm32/alloc-id:fake:payload
33391 0x11/imm32/alloc-id:fake
33392 _string-loop-if->=/imm32/name
33397 0x11/imm32/alloc-id:fake
33398 _string_0f_8d_jump_loop/imm32/subx-name
33406 0x11/imm32/alloc-id:fake
33407 _Primitive-loop-if-<=/imm32/next
33408 _Primitive-loop-if-<=: # (payload primitive)
33409 0x11/imm32/alloc-id:fake:payload
33410 0x11/imm32/alloc-id:fake
33411 _string-loop-if-<=/imm32/name
33416 0x11/imm32/alloc-id:fake
33417 _string_0f_8e_jump_loop/imm32/subx-name
33425 0x11/imm32/alloc-id:fake
33426 _Primitive-loop-if->/imm32/next
33427 _Primitive-loop-if->: # (payload primitive)
33428 0x11/imm32/alloc-id:fake:payload
33429 0x11/imm32/alloc-id:fake
33430 _string-loop-if->/imm32/name
33435 0x11/imm32/alloc-id:fake
33436 _string_0f_8f_jump_loop/imm32/subx-name
33444 0x11/imm32/alloc-id:fake
33445 _Primitive-loop-if-carry/imm32/next
33446 _Primitive-loop-if-carry: # (payload primitive)
33447 0x11/imm32/alloc-id:fake:payload
33448 0x11/imm32/alloc-id:fake
33449 _string-loop-if-carry/imm32/name
33454 0x11/imm32/alloc-id:fake
33455 _string_0f_82_jump_loop/imm32/subx-name
33463 0x11/imm32/alloc-id:fake
33464 _Primitive-loop-if-not-carry/imm32/next
33465 _Primitive-loop-if-not-carry: # (payload primitive)
33466 0x11/imm32/alloc-id:fake:payload
33467 0x11/imm32/alloc-id:fake
33468 _string-loop-if-not-carry/imm32/name
33473 0x11/imm32/alloc-id:fake
33474 _string_0f_83_jump_loop/imm32/subx-name
33482 0x11/imm32/alloc-id:fake
33483 _Primitive-loop-if-overflow/imm32/next
33484 _Primitive-loop-if-overflow: # (payload primitive)
33485 0x11/imm32/alloc-id:fake:payload
33486 0x11/imm32/alloc-id:fake
33487 _string-loop-if-overflow/imm32/name
33492 0x11/imm32/alloc-id:fake
33493 _string_0f_80_jump_loop/imm32/subx-name
33501 0x11/imm32/alloc-id:fake
33502 _Primitive-loop-if-not-overflow/imm32/next
33503 _Primitive-loop-if-not-overflow: # (payload primitive)
33504 0x11/imm32/alloc-id:fake:payload
33505 0x11/imm32/alloc-id:fake
33506 _string-loop-if-not-overflow/imm32/name
33511 0x11/imm32/alloc-id:fake
33512 _string_0f_81_jump_loop/imm32/subx-name
33520 0x11/imm32/alloc-id:fake
33521 _Primitive-loop/imm32/next # we probably don't need an unconditional break
33522 _Primitive-loop: # (payload primitive)
33523 0x11/imm32/alloc-id:fake:payload
33524 0x11/imm32/alloc-id:fake
33525 _string-loop/imm32/name
33530 0x11/imm32/alloc-id:fake
33531 _string_e9_jump_loop/imm32/subx-name
33539 0x11/imm32/alloc-id:fake
33540 _Primitive-break-if-addr<-named/imm32/next
33541 # - branches to named blocks
33542 _Primitive-break-if-addr<-named: # (payload primitive)
33543 0x11/imm32/alloc-id:fake:payload
33544 0x11/imm32/alloc-id:fake
33545 _string-break-if-addr</imm32/name
33546 0x11/imm32/alloc-id:fake
33547 Single-lit-var/imm32/inouts
33550 0x11/imm32/alloc-id:fake
33551 _string_0f_82_jump_label/imm32/subx-name
33556 1/imm32/disp32-is-first-inout
33559 0x11/imm32/alloc-id:fake
33560 _Primitive-break-if-addr>=-named/imm32/next
33561 _Primitive-break-if-addr>=-named: # (payload primitive)
33562 0x11/imm32/alloc-id:fake:payload
33563 0x11/imm32/alloc-id:fake
33564 _string-break-if-addr>=/imm32/name
33565 0x11/imm32/alloc-id:fake
33566 Single-lit-var/imm32/inouts
33569 0x11/imm32/alloc-id:fake
33570 _string_0f_83_jump_label/imm32/subx-name
33575 1/imm32/disp32-is-first-inout
33578 0x11/imm32/alloc-id:fake
33579 _Primitive-break-if-=-named/imm32/next
33580 _Primitive-break-if-=-named: # (payload primitive)
33581 0x11/imm32/alloc-id:fake:payload
33582 0x11/imm32/alloc-id:fake
33583 _string-break-if-=/imm32/name
33584 0x11/imm32/alloc-id:fake
33585 Single-lit-var/imm32/inouts
33588 0x11/imm32/alloc-id:fake
33589 _string_0f_84_jump_label/imm32/subx-name
33594 1/imm32/disp32-is-first-inout
33597 0x11/imm32/alloc-id:fake
33598 _Primitive-break-if-!=-named/imm32/next
33599 _Primitive-break-if-!=-named: # (payload primitive)
33600 0x11/imm32/alloc-id:fake:payload
33601 0x11/imm32/alloc-id:fake
33602 _string-break-if-!=/imm32/name
33603 0x11/imm32/alloc-id:fake
33604 Single-lit-var/imm32/inouts
33607 0x11/imm32/alloc-id:fake
33608 _string_0f_85_jump_label/imm32/subx-name
33613 1/imm32/disp32-is-first-inout
33616 0x11/imm32/alloc-id:fake
33617 _Primitive-break-if-addr<=-named/imm32/next
33618 _Primitive-break-if-addr<=-named: # (payload primitive)
33619 0x11/imm32/alloc-id:fake:payload
33620 0x11/imm32/alloc-id:fake
33621 _string-break-if-addr<=/imm32/name
33622 0x11/imm32/alloc-id:fake
33623 Single-lit-var/imm32/inouts
33626 0x11/imm32/alloc-id:fake
33627 _string_0f_86_jump_label/imm32/subx-name
33632 1/imm32/disp32-is-first-inout
33635 0x11/imm32/alloc-id:fake
33636 _Primitive-break-if-addr>-named/imm32/next
33637 _Primitive-break-if-addr>-named: # (payload primitive)
33638 0x11/imm32/alloc-id:fake:payload
33639 0x11/imm32/alloc-id:fake
33640 _string-break-if-addr>/imm32/name
33641 0x11/imm32/alloc-id:fake
33642 Single-lit-var/imm32/inouts
33645 0x11/imm32/alloc-id:fake
33646 _string_0f_87_jump_label/imm32/subx-name
33651 1/imm32/disp32-is-first-inout
33654 0x11/imm32/alloc-id:fake
33655 _Primitive-break-if-<-named/imm32/next
33656 _Primitive-break-if-<-named: # (payload primitive)
33657 0x11/imm32/alloc-id:fake:payload
33658 0x11/imm32/alloc-id:fake
33659 _string-break-if-</imm32/name
33660 0x11/imm32/alloc-id:fake
33661 Single-lit-var/imm32/inouts
33664 0x11/imm32/alloc-id:fake
33665 _string_0f_8c_jump_label/imm32/subx-name
33670 1/imm32/disp32-is-first-inout
33673 0x11/imm32/alloc-id:fake
33674 _Primitive-break-if->=-named/imm32/next
33675 _Primitive-break-if->=-named: # (payload primitive)
33676 0x11/imm32/alloc-id:fake:payload
33677 0x11/imm32/alloc-id:fake
33678 _string-break-if->=/imm32/name
33679 0x11/imm32/alloc-id:fake
33680 Single-lit-var/imm32/inouts
33683 0x11/imm32/alloc-id:fake
33684 _string_0f_8d_jump_label/imm32/subx-name
33689 1/imm32/disp32-is-first-inout
33692 0x11/imm32/alloc-id:fake
33693 _Primitive-break-if-<=-named/imm32/next
33694 _Primitive-break-if-<=-named: # (payload primitive)
33695 0x11/imm32/alloc-id:fake:payload
33696 0x11/imm32/alloc-id:fake
33697 _string-break-if-<=/imm32/name
33698 0x11/imm32/alloc-id:fake
33699 Single-lit-var/imm32/inouts
33702 0x11/imm32/alloc-id:fake
33703 _string_0f_8e_jump_label/imm32/subx-name
33708 1/imm32/disp32-is-first-inout
33711 0x11/imm32/alloc-id:fake
33712 _Primitive-break-if->-named/imm32/next
33713 _Primitive-break-if->-named: # (payload primitive)
33714 0x11/imm32/alloc-id:fake:payload
33715 0x11/imm32/alloc-id:fake
33716 _string-break-if->/imm32/name
33717 0x11/imm32/alloc-id:fake
33718 Single-lit-var/imm32/inouts
33721 0x11/imm32/alloc-id:fake
33722 _string_0f_8f_jump_label/imm32/subx-name
33727 1/imm32/disp32-is-first-inout
33730 0x11/imm32/alloc-id:fake
33731 _Primitive-break-named/imm32/next
33732 _Primitive-break-named: # (payload primitive)
33733 0x11/imm32/alloc-id:fake:payload
33734 0x11/imm32/alloc-id:fake
33735 _string-break/imm32/name
33736 0x11/imm32/alloc-id:fake
33737 Single-lit-var/imm32/inouts
33740 0x11/imm32/alloc-id:fake
33741 _string_e9_jump_label/imm32/subx-name
33746 1/imm32/disp32-is-first-inout
33749 0x11/imm32/alloc-id:fake
33750 _Primitive-loop-if-addr<-named/imm32/next
33751 _Primitive-loop-if-addr<-named: # (payload primitive)
33752 0x11/imm32/alloc-id:fake:payload
33753 0x11/imm32/alloc-id:fake
33754 _string-loop-if-addr</imm32/name
33755 0x11/imm32/alloc-id:fake
33756 Single-lit-var/imm32/inouts
33759 0x11/imm32/alloc-id:fake
33760 _string_0f_82_jump_label/imm32/subx-name
33765 1/imm32/disp32-is-first-inout
33768 0x11/imm32/alloc-id:fake
33769 _Primitive-loop-if-addr>=-named/imm32/next
33770 _Primitive-loop-if-addr>=-named: # (payload primitive)
33771 0x11/imm32/alloc-id:fake:payload
33772 0x11/imm32/alloc-id:fake
33773 _string-loop-if-addr>=/imm32/name
33774 0x11/imm32/alloc-id:fake
33775 Single-lit-var/imm32/inouts
33778 0x11/imm32/alloc-id:fake
33779 _string_0f_83_jump_label/imm32/subx-name
33784 1/imm32/disp32-is-first-inout
33787 0x11/imm32/alloc-id:fake
33788 _Primitive-loop-if-=-named/imm32/next
33789 _Primitive-loop-if-=-named: # (payload primitive)
33790 0x11/imm32/alloc-id:fake:payload
33791 0x11/imm32/alloc-id:fake
33792 _string-loop-if-=/imm32/name
33793 0x11/imm32/alloc-id:fake
33794 Single-lit-var/imm32/inouts
33797 0x11/imm32/alloc-id:fake
33798 _string_0f_84_jump_label/imm32/subx-name
33803 1/imm32/disp32-is-first-inout
33806 0x11/imm32/alloc-id:fake
33807 _Primitive-loop-if-!=-named/imm32/next
33808 _Primitive-loop-if-!=-named: # (payload primitive)
33809 0x11/imm32/alloc-id:fake:payload
33810 0x11/imm32/alloc-id:fake
33811 _string-loop-if-!=/imm32/name
33812 0x11/imm32/alloc-id:fake
33813 Single-lit-var/imm32/inouts
33816 0x11/imm32/alloc-id:fake
33817 _string_0f_85_jump_label/imm32/subx-name
33822 1/imm32/disp32-is-first-inout
33825 0x11/imm32/alloc-id:fake
33826 _Primitive-loop-if-addr<=-named/imm32/next
33827 _Primitive-loop-if-addr<=-named: # (payload primitive)
33828 0x11/imm32/alloc-id:fake:payload
33829 0x11/imm32/alloc-id:fake
33830 _string-loop-if-addr<=/imm32/name
33831 0x11/imm32/alloc-id:fake
33832 Single-lit-var/imm32/inouts
33835 0x11/imm32/alloc-id:fake
33836 _string_0f_86_jump_label/imm32/subx-name
33841 1/imm32/disp32-is-first-inout
33844 0x11/imm32/alloc-id:fake
33845 _Primitive-loop-if-addr>-named/imm32/next
33846 _Primitive-loop-if-addr>-named: # (payload primitive)
33847 0x11/imm32/alloc-id:fake:payload
33848 0x11/imm32/alloc-id:fake
33849 _string-loop-if-addr>/imm32/name
33850 0x11/imm32/alloc-id:fake
33851 Single-lit-var/imm32/inouts
33854 0x11/imm32/alloc-id:fake
33855 _string_0f_87_jump_label/imm32/subx-name
33860 1/imm32/disp32-is-first-inout
33863 0x11/imm32/alloc-id:fake
33864 _Primitive-loop-if-<-named/imm32/next
33865 _Primitive-loop-if-<-named: # (payload primitive)
33866 0x11/imm32/alloc-id:fake:payload
33867 0x11/imm32/alloc-id:fake
33868 _string-loop-if-</imm32/name
33869 0x11/imm32/alloc-id:fake
33870 Single-lit-var/imm32/inouts
33873 0x11/imm32/alloc-id:fake
33874 _string_0f_8c_jump_label/imm32/subx-name
33879 1/imm32/disp32-is-first-inout
33882 0x11/imm32/alloc-id:fake
33883 _Primitive-loop-if->=-named/imm32/next
33884 _Primitive-loop-if->=-named: # (payload primitive)
33885 0x11/imm32/alloc-id:fake:payload
33886 0x11/imm32/alloc-id:fake
33887 _string-loop-if->=/imm32/name
33888 0x11/imm32/alloc-id:fake
33889 Single-lit-var/imm32/inouts
33892 0x11/imm32/alloc-id:fake
33893 _string_0f_8d_jump_label/imm32/subx-name
33898 1/imm32/disp32-is-first-inout
33901 0x11/imm32/alloc-id:fake
33902 _Primitive-loop-if-<=-named/imm32/next
33903 _Primitive-loop-if-<=-named: # (payload primitive)
33904 0x11/imm32/alloc-id:fake:payload
33905 0x11/imm32/alloc-id:fake
33906 _string-loop-if-<=/imm32/name
33907 0x11/imm32/alloc-id:fake
33908 Single-lit-var/imm32/inouts
33911 0x11/imm32/alloc-id:fake
33912 _string_0f_8e_jump_label/imm32/subx-name
33917 1/imm32/disp32-is-first-inout
33920 0x11/imm32/alloc-id:fake
33921 _Primitive-loop-if->-named/imm32/next
33922 _Primitive-loop-if->-named: # (payload primitive)
33923 0x11/imm32/alloc-id:fake:payload
33924 0x11/imm32/alloc-id:fake
33925 _string-loop-if->/imm32/name
33926 0x11/imm32/alloc-id:fake
33927 Single-lit-var/imm32/inouts
33930 0x11/imm32/alloc-id:fake
33931 _string_0f_8f_jump_label/imm32/subx-name
33936 1/imm32/disp32-is-first-inout
33939 0x11/imm32/alloc-id:fake
33940 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break
33941 _Primitive-loop-named: # (payload primitive)
33942 0x11/imm32/alloc-id:fake:payload
33943 0x11/imm32/alloc-id:fake
33944 _string-loop/imm32/name
33945 0x11/imm32/alloc-id:fake
33946 Single-lit-var/imm32/inouts
33949 0x11/imm32/alloc-id:fake
33950 _string_e9_jump_label/imm32/subx-name
33955 1/imm32/disp32-is-first-inout
33958 0x11/imm32/alloc-id:fake
33959 _Primitive-break-if-float</imm32/next
33960 # - branches based on floating-point comparisons
33961 _Primitive-break-if-float<: # (payload primitive)
33962 0x11/imm32/alloc-id:fake:payload
33963 0x11/imm32/alloc-id:fake
33964 _string-break-if-float</imm32/name
33969 0x11/imm32/alloc-id:fake
33970 _string_0f_82_jump_break/imm32/subx-name
33978 0x11/imm32/alloc-id:fake
33979 _Primitive-break-if-float>=/imm32/next
33980 _Primitive-break-if-float>=: # (payload primitive)
33981 0x11/imm32/alloc-id:fake:payload
33982 0x11/imm32/alloc-id:fake
33983 _string-break-if-float>=/imm32/name
33988 0x11/imm32/alloc-id:fake
33989 _string_0f_83_jump_break/imm32/subx-name
33997 0x11/imm32/alloc-id:fake
33998 _Primitive-break-if-float<=/imm32/next
33999 _Primitive-break-if-float<=: # (payload primitive)
34000 0x11/imm32/alloc-id:fake:payload
34001 0x11/imm32/alloc-id:fake
34002 _string-break-if-float<=/imm32/name
34007 0x11/imm32/alloc-id:fake
34008 _string_0f_86_jump_break/imm32/subx-name
34016 0x11/imm32/alloc-id:fake
34017 _Primitive-break-if-float>/imm32/next
34018 _Primitive-break-if-float>: # (payload primitive)
34019 0x11/imm32/alloc-id:fake:payload
34020 0x11/imm32/alloc-id:fake
34021 _string-break-if-float>/imm32/name
34026 0x11/imm32/alloc-id:fake
34027 _string_0f_87_jump_break/imm32/subx-name
34035 0x11/imm32/alloc-id:fake
34036 _Primitive-loop-if-float</imm32/next
34037 _Primitive-loop-if-float<: # (payload primitive)
34038 0x11/imm32/alloc-id:fake:payload
34039 0x11/imm32/alloc-id:fake
34040 _string-loop-if-float</imm32/name
34045 0x11/imm32/alloc-id:fake
34046 _string_0f_82_jump_loop/imm32/subx-name
34054 0x11/imm32/alloc-id:fake
34055 _Primitive-loop-if-float>=/imm32/next
34056 _Primitive-loop-if-float>=: # (payload primitive)
34057 0x11/imm32/alloc-id:fake:payload
34058 0x11/imm32/alloc-id:fake
34059 _string-loop-if-float>=/imm32/name
34064 0x11/imm32/alloc-id:fake
34065 _string_0f_83_jump_loop/imm32/subx-name
34073 0x11/imm32/alloc-id:fake
34074 _Primitive-loop-if-float<=/imm32/next
34075 _Primitive-loop-if-float<=: # (payload primitive)
34076 0x11/imm32/alloc-id:fake:payload
34077 0x11/imm32/alloc-id:fake
34078 _string-loop-if-float<=/imm32/name
34083 0x11/imm32/alloc-id:fake
34084 _string_0f_86_jump_loop/imm32/subx-name
34092 0x11/imm32/alloc-id:fake
34093 _Primitive-loop-if-float>/imm32/next
34094 _Primitive-loop-if-float>: # (payload primitive)
34095 0x11/imm32/alloc-id:fake:payload
34096 0x11/imm32/alloc-id:fake
34097 _string-loop-if-float>/imm32/name
34102 0x11/imm32/alloc-id:fake
34103 _string_0f_87_jump_loop/imm32/subx-name
34111 0x11/imm32/alloc-id:fake
34112 _Primitive-break-if-float<-named/imm32/next
34113 _Primitive-break-if-float<-named: # (payload primitive)
34114 0x11/imm32/alloc-id:fake:payload
34115 0x11/imm32/alloc-id:fake
34116 _string-break-if-float</imm32/name
34117 0x11/imm32/alloc-id:fake
34118 Single-lit-var/imm32/inouts
34121 0x11/imm32/alloc-id:fake
34122 _string_0f_82_jump_label/imm32/subx-name
34127 1/imm32/disp32-is-first-inout
34130 0x11/imm32/alloc-id:fake
34131 _Primitive-break-if-float>=-named/imm32/next
34132 _Primitive-break-if-float>=-named: # (payload primitive)
34133 0x11/imm32/alloc-id:fake:payload
34134 0x11/imm32/alloc-id:fake
34135 _string-break-if-float>=/imm32/name
34136 0x11/imm32/alloc-id:fake
34137 Single-lit-var/imm32/inouts
34140 0x11/imm32/alloc-id:fake
34141 _string_0f_83_jump_label/imm32/subx-name
34146 1/imm32/disp32-is-first-inout
34149 0x11/imm32/alloc-id:fake
34150 _Primitive-break-if-float<=-named/imm32/next
34151 _Primitive-break-if-float<=-named: # (payload primitive)
34152 0x11/imm32/alloc-id:fake:payload
34153 0x11/imm32/alloc-id:fake
34154 _string-break-if-float<=/imm32/name
34155 0x11/imm32/alloc-id:fake
34156 Single-lit-var/imm32/inouts
34159 0x11/imm32/alloc-id:fake
34160 _string_0f_86_jump_label/imm32/subx-name
34165 1/imm32/disp32-is-first-inout
34168 0x11/imm32/alloc-id:fake
34169 _Primitive-break-if-float>-named/imm32/next
34170 _Primitive-break-if-float>-named: # (payload primitive)
34171 0x11/imm32/alloc-id:fake:payload
34172 0x11/imm32/alloc-id:fake
34173 _string-break-if-float>/imm32/name
34174 0x11/imm32/alloc-id:fake
34175 Single-lit-var/imm32/inouts
34178 0x11/imm32/alloc-id:fake
34179 _string_0f_87_jump_label/imm32/subx-name
34184 1/imm32/disp32-is-first-inout
34187 0x11/imm32/alloc-id:fake
34188 _Primitive-loop-if-float<-named/imm32/next
34189 _Primitive-loop-if-float<-named: # (payload primitive)
34190 0x11/imm32/alloc-id:fake:payload
34191 0x11/imm32/alloc-id:fake
34192 _string-loop-if-float</imm32/name
34193 0x11/imm32/alloc-id:fake
34194 Single-lit-var/imm32/inouts
34197 0x11/imm32/alloc-id:fake
34198 _string_0f_82_jump_label/imm32/subx-name
34203 1/imm32/disp32-is-first-inout
34206 0x11/imm32/alloc-id:fake
34207 _Primitive-loop-if-float>=-named/imm32/next
34208 _Primitive-loop-if-float>=-named: # (payload primitive)
34209 0x11/imm32/alloc-id:fake:payload
34210 0x11/imm32/alloc-id:fake
34211 _string-loop-if-float>=/imm32/name
34212 0x11/imm32/alloc-id:fake
34213 Single-lit-var/imm32/inouts
34216 0x11/imm32/alloc-id:fake
34217 _string_0f_83_jump_label/imm32/subx-name
34222 1/imm32/disp32-is-first-inout
34225 0x11/imm32/alloc-id:fake
34226 _Primitive-loop-if-float<=-named/imm32/next
34227 _Primitive-loop-if-float<=-named: # (payload primitive)
34228 0x11/imm32/alloc-id:fake:payload
34229 0x11/imm32/alloc-id:fake
34230 _string-loop-if-float<=/imm32/name
34231 0x11/imm32/alloc-id:fake
34232 Single-lit-var/imm32/inouts
34235 0x11/imm32/alloc-id:fake
34236 _string_0f_86_jump_label/imm32/subx-name
34241 1/imm32/disp32-is-first-inout
34244 0x11/imm32/alloc-id:fake
34245 _Primitive-loop-if-float>-named/imm32/next
34246 _Primitive-loop-if-float>-named: # (payload primitive)
34247 0x11/imm32/alloc-id:fake:payload
34248 0x11/imm32/alloc-id:fake
34249 _string-loop-if-float>/imm32/name
34250 0x11/imm32/alloc-id:fake
34251 Single-lit-var/imm32/inouts
34254 0x11/imm32/alloc-id:fake
34255 _string_0f_87_jump_label/imm32/subx-name
34260 1/imm32/disp32-is-first-inout
34266 # string literals for Mu instructions
34267 _string-add: # (payload array byte)
34268 0x11/imm32/alloc-id:fake:payload
34271 0x61/a 0x64/d 0x64/d
34272 _string-address: # (payload array byte)
34273 0x11/imm32/alloc-id:fake:payload
34276 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s
34277 _string-add-to: # (payload array byte)
34278 0x11/imm32/alloc-id:fake:payload
34281 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o
34282 _string-and: # (payload array byte)
34283 0x11/imm32/alloc-id:fake:payload
34286 0x61/a 0x6e/n 0x64/d
34287 _string-and-with: # (payload array byte)
34288 0x11/imm32/alloc-id:fake:payload
34291 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h
34292 _string-break: # (payload array byte)
34293 0x11/imm32/alloc-id:fake:payload
34296 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k
34297 _string-break-if-<: # (payload array byte)
34298 0x11/imm32/alloc-id:fake:payload
34301 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/<
34302 _string-break-if-<=: # (payload array byte)
34303 0x11/imm32/alloc-id:fake:payload
34306 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/=
34307 _string-break-if-=: # (payload array byte)
34308 0x11/imm32/alloc-id:fake:payload
34311 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/=
34312 _string-break-if->: # (payload array byte)
34313 0x11/imm32/alloc-id:fake:payload
34316 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/>
34317 _string-break-if->=: # (payload array byte)
34318 0x11/imm32/alloc-id:fake:payload
34321 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/=
34322 _string-break-if-!=: # (payload array byte)
34323 0x11/imm32/alloc-id:fake:payload
34326 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/=
34327 _string-break-if-addr<: # (payload array byte)
34328 0x11/imm32/alloc-id:fake:payload
34331 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/<
34332 _string-break-if-addr<=: # (payload array byte)
34333 0x11/imm32/alloc-id:fake:payload
34334 # "break-if-addr<="
34336 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/=
34337 _string-break-if-addr>: # (payload array byte)
34338 0x11/imm32/alloc-id:fake:payload
34341 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/>
34342 _string-break-if-addr>=: # (payload array byte)
34343 0x11/imm32/alloc-id:fake:payload
34344 # "break-if-addr>="
34346 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/=
34347 _string-break-if-float<: # (payload array byte)
34348 0x11/imm32/alloc-id:fake:payload
34349 # "break-if-float<"
34351 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/<
34352 _string-break-if-float<=: # (payload array byte)
34353 0x11/imm32/alloc-id:fake:payload
34354 # "break-if-float<="
34356 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/< 0x3d/=
34357 _string-break-if-float>: # (payload array byte)
34358 0x11/imm32/alloc-id:fake:payload
34359 # "break-if-float>"
34361 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/>
34362 _string-break-if-float>=: # (payload array byte)
34363 0x11/imm32/alloc-id:fake:payload
34364 # "break-if-float>="
34366 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> 0x3d/=
34367 _string-break-if-carry: # (payload array byte)
34368 0x11/imm32/alloc-id:fake:payload
34371 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y
34372 _string-break-if-not-carry: # (payload array byte)
34373 0x11/imm32/alloc-id:fake:payload
34374 # "break-if-not-carry"
34376 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y
34377 _string-break-if-overflow: # (payload array byte)
34378 0x11/imm32/alloc-id:fake:payload
34379 # "break-if-overflow"
34381 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
34382 _string-break-if-not-overflow: # (payload array byte)
34383 0x11/imm32/alloc-id:fake:payload
34384 # "break-if-not-overflow"
34386 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
34387 _string-compare: # (payload array byte)
34388 0x11/imm32/alloc-id:fake:payload
34391 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e
34392 _string-copy: # (payload array byte)
34393 0x11/imm32/alloc-id:fake:payload
34396 0x63/c 0x6f/o 0x70/p 0x79/y
34397 _string-copy-to: # (payload array byte)
34398 0x11/imm32/alloc-id:fake:payload
34401 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o
34403 0x11/imm32/alloc-id:fake:payload
34406 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x62/b 0x79/y 0x74/t 0x65/e
34407 _string-copy-byte-to:
34408 0x11/imm32/alloc-id:fake:payload
34411 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/dash 0x74/t 0x6f/o
34412 _string-decrement: # (payload array byte)
34413 0x11/imm32/alloc-id:fake:payload
34416 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t
34417 _string-increment: # (payload array byte)
34418 0x11/imm32/alloc-id:fake:payload
34421 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t
34422 _string-loop: # (payload array byte)
34423 0x11/imm32/alloc-id:fake:payload
34426 0x6c/l 0x6f/o 0x6f/o 0x70/p
34427 _string-loop-if-<: # (payload array byte)
34428 0x11/imm32/alloc-id:fake:payload
34431 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/<
34432 _string-loop-if-<=: # (payload array byte)
34433 0x11/imm32/alloc-id:fake:payload
34436 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/=
34437 _string-loop-if-=: # (payload array byte)
34438 0x11/imm32/alloc-id:fake:payload
34441 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/=
34442 _string-loop-if->: # (payload array byte)
34443 0x11/imm32/alloc-id:fake:payload
34446 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/>
34447 _string-loop-if->=: # (payload array byte)
34448 0x11/imm32/alloc-id:fake:payload
34451 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/=
34452 _string-loop-if-!=: # (payload array byte)
34453 0x11/imm32/alloc-id:fake:payload
34456 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/=
34457 _string-loop-if-addr<: # (payload array byte)
34458 0x11/imm32/alloc-id:fake:payload
34461 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/<
34462 _string-loop-if-addr<=: # (payload array byte)
34463 0x11/imm32/alloc-id:fake:payload
34466 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/=
34467 _string-loop-if-addr>: # (payload array byte)
34468 0x11/imm32/alloc-id:fake:payload
34471 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/>
34472 _string-loop-if-addr>=: # (payload array byte)
34473 0x11/imm32/alloc-id:fake:payload
34476 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/=
34477 _string-loop-if-float<: # (payload array byte)
34478 0x11/imm32/alloc-id:fake:payload
34481 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/<
34482 _string-loop-if-float<=: # (payload array byte)
34483 0x11/imm32/alloc-id:fake:payload
34484 # "loop-if-float<="
34486 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/< 0x3d/=
34487 _string-loop-if-float>: # (payload array byte)
34488 0x11/imm32/alloc-id:fake:payload
34491 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/>
34492 _string-loop-if-float>=: # (payload array byte)
34493 0x11/imm32/alloc-id:fake:payload
34494 # "loop-if-float>="
34496 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> 0x3d/=
34497 _string-loop-if-carry: # (payload array byte)
34498 0x11/imm32/alloc-id:fake:payload
34501 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y
34502 _string-loop-if-not-carry: # (payload array byte)
34503 0x11/imm32/alloc-id:fake:payload
34504 # "loop-if-not-carry"
34506 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y
34507 _string-loop-if-overflow: # (payload array byte)
34508 0x11/imm32/alloc-id:fake:payload
34509 # "loop-if-overflow"
34511 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
34512 _string-loop-if-not-overflow: # (payload array byte)
34513 0x11/imm32/alloc-id:fake:payload
34514 # "loop-if-not-overflow"
34516 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
34517 _string-multiply: # (payload array byte)
34518 0x11/imm32/alloc-id:fake:payload
34521 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y
34522 _string-convert: # (payload array byte)
34523 0x11/imm32/alloc-id:fake:payload
34526 0x63/c 0x6f/o 0x6e/n 0x76/v 0x65/e 0x72/r 0x74/t
34527 _string-truncate: # (payload array byte)
34528 0x11/imm32/alloc-id:fake:payload
34531 0x74/t 0x72/r 0x75/u 0x6e/n 0x63/c 0x61/a 0x74/t 0x65/e
34532 _string-reinterpret: # (payload array byte)
34533 0x11/imm32/alloc-id:fake:payload
34536 0x72/r 0x65/e 0x69/i 0x6e/n 0x74/t 0x65/e 0x72/r 0x70/p 0x72/r 0x65/e 0x74/t
34538 0x11/imm32/alloc-id:fake:payload
34541 0x64/d 0x69/i 0x76/v 0x69/i 0x64/d 0x65/e
34543 0x11/imm32/alloc-id:fake:payload
34546 0x6d/m 0x61/a 0x78/x
34548 0x11/imm32/alloc-id:fake:payload
34551 0x6d/m 0x69/i 0x6e/n
34552 _string-reciprocal:
34553 0x11/imm32/alloc-id:fake:payload
34556 0x72/r 0x65/e 0x63/c 0x69/i 0x70/p 0x72/r 0x6f/o 0x63/c 0x61/a 0x6c/l
34557 _string-square-root:
34558 0x11/imm32/alloc-id:fake:payload
34561 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t
34562 _string-inverse-square-root:
34563 0x11/imm32/alloc-id:fake:payload
34564 # "inverse-square-root"
34566 0x69/i 0x6e/n 0x76/v 0x65/e 0x72/r 0x73/s 0x65/e 0x2d/dash 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t
34567 _string-negate: # (payload array byte)
34568 0x11/imm32/alloc-id:fake:payload
34571 0x6e/n 0x65/e 0x67/g 0x61/a 0x74/t 0x65/e
34572 _string-not: # (payload array byte)
34573 0x11/imm32/alloc-id:fake:payload
34576 0x6e/n 0x6f/o 0x74/t
34577 _string-or: # (payload array byte)
34578 0x11/imm32/alloc-id:fake:payload
34582 _string-or-with: # (payload array byte)
34583 0x11/imm32/alloc-id:fake:payload
34586 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h
34587 _string-subtract: # (payload array byte)
34588 0x11/imm32/alloc-id:fake:payload
34591 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t
34592 _string-subtract-from: # (payload array byte)
34593 0x11/imm32/alloc-id:fake:payload
34596 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m
34597 _string-xor: # (payload array byte)
34598 0x11/imm32/alloc-id:fake:payload
34601 0x78/x 0x6f/o 0x72/r
34602 _string-xor-with: # (payload array byte)
34603 0x11/imm32/alloc-id:fake:payload
34606 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h
34607 _string-shift-left: # (payload array byte)
34608 0x11/imm32/alloc-id:fake:payload
34611 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x6c/l 0x65/e 0x66/f 0x74/t
34612 _string-shift-right: # (payload array byte)
34613 0x11/imm32/alloc-id:fake:payload
34616 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t
34617 _string-shift-right-signed: # (payload array byte)
34618 0x11/imm32/alloc-id:fake:payload
34619 # "shift-right-signed"
34621 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x73/s 0x69/i 0x67/g 0x6e/n 0x65/e 0x64/d
34623 # string literals for SubX instructions
34624 _string_01_add_to: # (payload array byte)
34625 0x11/imm32/alloc-id:fake:payload
34628 0x30/0 0x31/1 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o
34629 _string_03_add: # (payload array byte)
34630 0x11/imm32/alloc-id:fake:payload
34633 0x30/0 0x33/3 0x2f/slash 0x61/a 0x64/d 0x64/d
34634 _string_05_add_to_eax: # (payload array byte)
34635 0x11/imm32/alloc-id:fake:payload
34638 0x30/0 0x35/5 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x
34639 _string_09_or_with: # (payload array byte)
34640 0x11/imm32/alloc-id:fake:payload
34643 0x30/0 0x39/9 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h
34644 _string_0b_or: # (payload array byte)
34645 0x11/imm32/alloc-id:fake:payload
34648 0x30/0 0x62/b 0x2f/slash 0x6f/o 0x72/r
34649 _string_0d_or_with_eax: # (payload array byte)
34650 0x11/imm32/alloc-id:fake:payload
34653 0x30/0 0x64/d 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x
34654 _string_0f_80_jump_label: # (payload array byte)
34655 0x11/imm32/alloc-id:fake:payload
34656 # "0f 80/jump-if-overflow"
34658 0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
34659 _string_0f_80_jump_break: # (payload array byte)
34660 0x11/imm32/alloc-id:fake:payload
34661 # "0f 80/jump-if-overflow break/disp32"
34663 0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34664 _string_0f_80_jump_loop: # (payload array byte)
34665 0x11/imm32/alloc-id:fake:payload
34666 # "0f 80/jump-if-overflow loop/disp32"
34668 0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34669 _string_0f_81_jump_label: # (payload array byte)
34670 0x11/imm32/alloc-id:fake:payload
34671 # "0f 81/jump-if-not-overflow"
34673 0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
34674 _string_0f_81_jump_break: # (payload array byte)
34675 0x11/imm32/alloc-id:fake:payload
34676 # "0f 81/jump-if-not-overflow break/disp32"
34678 0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34679 _string_0f_81_jump_loop: # (payload array byte)
34680 0x11/imm32/alloc-id:fake:payload
34681 # "0f 81/jump-if-not-overflow loop/disp32"
34683 0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34684 _string_0f_82_jump_label: # (payload array byte)
34685 0x11/imm32/alloc-id:fake:payload
34686 # "0f 82/jump-if-addr<"
34688 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/<
34689 _string_0f_82_jump_break: # (payload array byte)
34690 0x11/imm32/alloc-id:fake:payload
34691 # "0f 82/jump-if-addr< break/disp32"
34693 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34694 _string_0f_82_jump_loop: # (payload array byte)
34695 0x11/imm32/alloc-id:fake:payload
34696 # "0f 82/jump-if-addr< loop/disp32"
34698 0x30/0 0x66/f 0x20/space 0x38/8 0x32/2 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34699 _string_0f_83_jump_label: # (payload array byte)
34700 0x11/imm32/alloc-id:fake:payload
34701 # "0f 83/jump-if-addr>="
34703 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/=
34704 _string_0f_83_jump_break: # (payload array byte)
34705 0x11/imm32/alloc-id:fake:payload
34706 # "0f 83/jump-if-addr>= break/disp32"
34708 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34709 _string_0f_83_jump_loop: # (payload array byte)
34710 0x11/imm32/alloc-id:fake:payload
34711 # "0f 83/jump-if-addr>= loop/disp32"
34713 0x30/0 0x66/f 0x20/space 0x38/8 0x33/3 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34714 _string_0f_84_jump_label: # (payload array byte)
34715 0x11/imm32/alloc-id:fake:payload
34716 # "0f 84/jump-if-="
34718 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/=
34719 _string_0f_84_jump_break: # (payload array byte)
34720 0x11/imm32/alloc-id:fake:payload
34721 # "0f 84/jump-if-= break/disp32"
34723 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34724 _string_0f_84_jump_loop: # (payload array byte)
34725 0x11/imm32/alloc-id:fake:payload
34726 # "0f 84/jump-if-= loop/disp32"
34728 0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34729 _string_0f_85_jump_label: # (payload array byte)
34730 0x11/imm32/alloc-id:fake:payload
34731 # "0f 85/jump-if-!="
34733 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/=
34734 _string_0f_85_jump_break: # (payload array byte)
34735 0x11/imm32/alloc-id:fake:payload
34736 # "0f 85/jump-if-!= break/disp32"
34738 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34739 _string_0f_85_jump_loop: # (payload array byte)
34740 0x11/imm32/alloc-id:fake:payload
34741 # "0f 85/jump-if-!= loop/disp32"
34743 0x30/0 0x66/f 0x20/space 0x38/8 0x35/5 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34744 _string_0f_86_jump_label: # (payload array byte)
34745 0x11/imm32/alloc-id:fake:payload
34746 # "0f 86/jump-if-addr<="
34748 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/=
34749 _string_0f_86_jump_break: # (payload array byte)
34750 0x11/imm32/alloc-id:fake:payload
34751 # "0f 86/jump-if-addr<= break/disp32"
34753 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34754 _string_0f_86_jump_loop: # (payload array byte)
34755 0x11/imm32/alloc-id:fake:payload
34756 # "0f 86/jump-if-addr<= loop/disp32"
34758 0x30/0 0x66/f 0x20/space 0x38/8 0x36/6 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34759 _string_0f_87_jump_label: # (payload array byte)
34760 0x11/imm32/alloc-id:fake:payload
34761 # "0f 87/jump-if-addr>"
34763 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/>
34764 _string_0f_87_jump_break: # (payload array byte)
34765 0x11/imm32/alloc-id:fake:payload
34766 # "0f 87/jump-if-addr> break/disp32"
34768 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34769 _string_0f_87_jump_loop: # (payload array byte)
34770 0x11/imm32/alloc-id:fake:payload
34771 # "0f 87/jump-if-addr> loop/disp32"
34773 0x30/0 0x66/f 0x20/space 0x38/8 0x37/7 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34774 _string_0f_8c_jump_label: # (payload array byte)
34775 0x11/imm32/alloc-id:fake:payload
34776 # "0f 8c/jump-if-<"
34778 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/<
34779 _string_0f_8c_jump_break: # (payload array byte)
34780 0x11/imm32/alloc-id:fake:payload
34781 # "0f 8c/jump-if-< break/disp32"
34783 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34784 _string_0f_8c_jump_loop: # (payload array byte)
34785 0x11/imm32/alloc-id:fake:payload
34786 # "0f 8c/jump-if-< loop/disp32"
34788 0x30/0 0x66/f 0x20/space 0x38/8 0x63/c 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34789 _string_0f_8d_jump_label: # (payload array byte)
34790 0x11/imm32/alloc-id:fake:payload
34791 # "0f 8d/jump-if->="
34793 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/=
34794 _string_0f_8d_jump_break: # (payload array byte)
34795 0x11/imm32/alloc-id:fake:payload
34796 # "0f 8d/jump-if->= break/disp32"
34798 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34799 _string_0f_8d_jump_loop: # (payload array byte)
34800 0x11/imm32/alloc-id:fake:payload
34801 # "0f 8d/jump-if->= loop/disp32"
34803 0x30/0 0x66/f 0x20/space 0x38/8 0x64/d 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34804 _string_0f_8e_jump_label: # (payload array byte)
34805 0x11/imm32/alloc-id:fake:payload
34806 # "0f 8e/jump-if-<="
34808 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/=
34809 _string_0f_8e_jump_break: # (payload array byte)
34810 0x11/imm32/alloc-id:fake:payload
34811 # "0f 8e/jump-if-<= break/disp32"
34813 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34814 _string_0f_8e_jump_loop: # (payload array byte)
34815 0x11/imm32/alloc-id:fake:payload
34816 # "0f 8e/jump-if-<= loop/disp32"
34818 0x30/0 0x66/f 0x20/space 0x38/8 0x65/e 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34819 _string_0f_8f_jump_label: # (payload array byte)
34820 0x11/imm32/alloc-id:fake:payload
34821 # "0f 8f/jump-if->"
34823 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/>
34824 _string_0f_8f_jump_break: # (payload array byte)
34825 0x11/imm32/alloc-id:fake:payload
34826 # "0f 8f/jump-if-> break/disp32"
34828 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34829 _string_0f_8f_jump_loop: # (payload array byte)
34830 0x11/imm32/alloc-id:fake:payload
34831 # "0f 8f/jump-if-> loop/disp32"
34833 0x30/0 0x66/f 0x20/space 0x38/8 0x66/f 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
34834 _string_0f_af_multiply: # (payload array byte)
34835 0x11/imm32/alloc-id:fake:payload
34838 0x30/0 0x66/f 0x20/space 0x61/a 0x66/f 0x2f/slash 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y
34839 _string_f3_0f_2a_convert_to_float:
34840 0x11/imm32/alloc-id:fake:payload
34841 # "f3 0f 2a/convert-to-float"
34843 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x32/2 0x61/a 0x2f/slash 0x63/c 0x6f/o 0x6e/n 0x76/v 0x65/e 0x72/r 0x74/t 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t
34844 _string_f3_0f_2d_convert_to_int:
34845 0x11/imm32/alloc-id:fake:payload
34846 # "f3 0f 2d/convert-to-int"
34848 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x32/2 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x6e/n 0x76/v 0x65/e 0x72/r 0x74/t 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x69/i 0x6e/n 0x74/t
34849 _string_f3_0f_2c_truncate_to_int:
34850 0x11/imm32/alloc-id:fake:payload
34851 # "f3 0f 2c/truncate-to-int"
34853 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x32/2 0x63/c 0x2f/slash 0x74/t 0x72/r 0x75/u 0x6e/n 0x63/c 0x61/a 0x74/t 0x65/e 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x69/i 0x6e/n 0x74/t
34854 _string_f3_0f_58_add:
34855 0x11/imm32/alloc-id:fake:payload
34858 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x38/8 0x2f/slash 0x61/a 0x64/d 0x64/d
34859 _string_f3_0f_5c_subtract:
34860 0x11/imm32/alloc-id:fake:payload
34861 # "f3 0f 5c/subtract"
34863 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x63/c 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t
34864 _string_f3_0f_59_multiply:
34865 0x11/imm32/alloc-id:fake:payload
34866 # "f3 0f 59/multiply"
34868 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x39/9 0x2f/slash 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y
34869 _string_f3_0f_5e_divide:
34870 0x11/imm32/alloc-id:fake:payload
34871 # "f3 0f 5e/divide"
34873 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x65/e 0x2f/slash 0x64/d 0x69/i 0x76/v 0x69/i 0x64/d 0x65/e
34874 _string_f3_0f_53_reciprocal:
34875 0x11/imm32/alloc-id:fake:payload
34876 # "f3 0f 53/reciprocal"
34878 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x33/3 0x2f/slash 0x72/r 0x65/e 0x63/c 0x69/i 0x70/p 0x72/r 0x6f/o 0x63/c 0x61/a 0x6c/l
34879 _string_f3_0f_51_square_root:
34880 0x11/imm32/alloc-id:fake:payload
34881 # "f3 0f 51/square-root"
34883 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x31/1 0x2f/slash 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t
34884 _string_f3_0f_52_inverse_square_root:
34885 0x11/imm32/alloc-id:fake:payload
34886 # "f3 0f 52/inverse-square-root"
34888 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x32/2 0x2f/slash 0x69/i 0x6e/n 0x76/v 0x65/e 0x72/r 0x73/s 0x65/e 0x2d/dash 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t
34889 _string_f3_0f_5d_min:
34890 0x11/imm32/alloc-id:fake:payload
34893 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x64/d 0x2f/slash 0x6d/m 0x69/i 0x6e/n
34894 _string_f3_0f_5f_max:
34895 0x11/imm32/alloc-id:fake:payload
34898 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x66/f 0x2f/slash 0x6d/m 0x61/a 0x78/x
34899 _string_f3_0f_10_copy:
34900 0x11/imm32/alloc-id:fake:payload
34903 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x31/1 0x30/0 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y
34904 _string_f3_0f_11_copy:
34905 0x11/imm32/alloc-id:fake:payload
34908 0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x31/1 0x31/1 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y
34909 _string_0f_2f_compare:
34910 0x11/imm32/alloc-id:fake:payload
34913 0x30/0 0x66/f 0x20/space 0x32/2 0x66/f 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e
34914 _string_21_and_with: # (payload array byte)
34915 0x11/imm32/alloc-id:fake:payload
34918 0x32/2 0x31/1 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h
34919 _string_23_and: # (payload array byte)
34920 0x11/imm32/alloc-id:fake:payload
34923 0x32/2 0x33/3 0x2f/slash 0x61/a 0x6e/n 0x64/d
34924 _string_25_and_with_eax: # (payload array byte)
34925 0x11/imm32/alloc-id:fake:payload
34926 # "25/and-with-eax"
34928 0x32/2 0x35/5 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x
34929 _string_29_subtract_from: # (payload array byte)
34930 0x11/imm32/alloc-id:fake:payload
34931 # "29/subtract-from"
34933 0x32/2 0x39/9 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m
34934 _string_2b_subtract: # (payload array byte)
34935 0x11/imm32/alloc-id:fake:payload
34938 0x32/2 0x62/b 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t
34939 _string_2d_subtract_from_eax: # (payload array byte)
34940 0x11/imm32/alloc-id:fake:payload
34941 # "2d/subtract-from-eax"
34943 0x32/2 0x64/d 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t 0x2d/dash 0x66/f 0x72/r 0x6f/o 0x6d/m 0x2d/dash 0x65/e 0x61/a 0x78/x
34944 _string_31_xor_with: # (payload array byte)
34945 0x11/imm32/alloc-id:fake:payload
34948 0x33/3 0x31/1 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h
34949 _string_33_xor: # (payload array byte)
34950 0x11/imm32/alloc-id:fake:payload
34953 0x33/3 0x33/3 0x2f/slash 0x78/x 0x6f/o 0x72/r
34954 _string_35_xor_with_eax: # (payload array byte)
34955 0x11/imm32/alloc-id:fake:payload
34956 # "35/xor-with-eax"
34958 0x33/3 0x35/5 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x
34959 _string_39_compare->: # (payload array byte)
34960 0x11/imm32/alloc-id:fake:payload
34963 0x33/3 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x3e/>
34964 _string_3b_compare<-: # (payload array byte)
34965 0x11/imm32/alloc-id:fake:payload
34968 0x33/3 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x3c/< 0x2d/dash
34969 _string_3d_compare_eax_with: # (payload array byte)
34970 0x11/imm32/alloc-id:fake:payload
34971 # "3d/compare-eax-with"
34973 0x33/3 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x65/e 0x61/a 0x78/x 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h
34974 _string_40_increment_eax: # (payload array byte)
34975 0x11/imm32/alloc-id:fake:payload
34976 # "40/increment-eax"
34978 0x34/4 0x30/0 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x
34979 _string_41_increment_ecx: # (payload array byte)
34980 0x11/imm32/alloc-id:fake:payload
34981 # "41/increment-ecx"
34983 0x34/4 0x31/1 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x
34984 _string_42_increment_edx: # (payload array byte)
34985 0x11/imm32/alloc-id:fake:payload
34986 # "42/increment-edx"
34988 0x34/4 0x32/2 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x
34989 _string_43_increment_ebx: # (payload array byte)
34990 0x11/imm32/alloc-id:fake:payload
34991 # "43/increment-ebx"
34993 0x34/4 0x33/3 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x
34994 _string_46_increment_esi: # (payload array byte)
34995 0x11/imm32/alloc-id:fake:payload
34996 # "46/increment-esi"
34998 0x34/4 0x36/6 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i
34999 _string_47_increment_edi: # (payload array byte)
35000 0x11/imm32/alloc-id:fake:payload
35001 # "47/increment-edi"
35003 0x34/4 0x37/7 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i
35004 _string_48_decrement_eax: # (payload array byte)
35005 0x11/imm32/alloc-id:fake:payload
35006 # "48/decrement-eax"
35008 0x34/4 0x38/8 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x61/a 0x78/x
35009 _string_49_decrement_ecx: # (payload array byte)
35010 0x11/imm32/alloc-id:fake:payload
35011 # "49/decrement-ecx"
35013 0x34/4 0x39/9 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x63/c 0x78/x
35014 _string_4a_decrement_edx: # (payload array byte)
35015 0x11/imm32/alloc-id:fake:payload
35016 # "4a/decrement-edx"
35018 0x34/4 0x61/a 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x78/x
35019 _string_4b_decrement_ebx: # (payload array byte)
35020 0x11/imm32/alloc-id:fake:payload
35021 # "4b/decrement-ebx"
35023 0x34/4 0x62/b 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x62/b 0x78/x
35024 _string_4e_decrement_esi: # (payload array byte)
35025 0x11/imm32/alloc-id:fake:payload
35026 # "4e/decrement-esi"
35028 0x34/4 0x65/e 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x73/s 0x69/i
35029 _string_4f_decrement_edi: # (payload array byte)
35030 0x11/imm32/alloc-id:fake:payload
35031 # "4f/decrement-edi"
35033 0x34/4 0x66/f 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t 0x2d/dash 0x65/e 0x64/d 0x69/i
35034 _string_81_subop_add: # (payload array byte)
35035 0x11/imm32/alloc-id:fake:payload
35038 0x38/8 0x31/1 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x64/d 0x64/d
35039 _string_81_subop_or: # (payload array byte)
35040 0x11/imm32/alloc-id:fake:payload
35043 0x38/8 0x31/1 0x20/space 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6f/o 0x72/r
35044 _string_81_subop_and: # (payload array byte)
35045 0x11/imm32/alloc-id:fake:payload
35048 0x38/8 0x31/1 0x20/space 0x34/4 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x61/a 0x6e/n 0x64/d
35049 _string_81_subop_subtract: # (payload array byte)
35050 0x11/imm32/alloc-id:fake:payload
35051 # "81 5/subop/subtract"
35053 0x38/8 0x31/1 0x20/space 0x35/5 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t
35054 _string_81_subop_xor: # (payload array byte)
35055 0x11/imm32/alloc-id:fake:payload
35058 0x38/8 0x31/1 0x20/space 0x36/6 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x78/x 0x6f/o 0x72/r
35059 _string_81_subop_compare: # (payload array byte)
35060 0x11/imm32/alloc-id:fake:payload
35061 # "81 7/subop/compare"
35063 0x38/8 0x31/1 0x20/space 0x37/7 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e
35064 _string_89_<-: # (payload array byte)
35065 0x11/imm32/alloc-id:fake:payload
35068 0x38/8 0x39/9 0x2f/slash 0x3c/< 0x2d/dash
35069 _string_8b_->: # (payload array byte)
35070 0x11/imm32/alloc-id:fake:payload
35073 0x38/8 0x62/b 0x2f/slash 0x2d/dash 0x3e/>
35074 _string_8a_copy_byte:
35075 0x11/imm32/alloc-id:fake:payload
35078 0x38/8 0x61/a 0x2f/slash 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/dash 0x3e/>
35079 _string_88_copy_byte:
35080 0x11/imm32/alloc-id:fake:payload
35083 0x38/8 0x38/8 0x2f/slash 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/-
35084 _string_8d_copy_address: # (payload array byte)
35085 0x11/imm32/alloc-id:fake:payload
35086 # "8d/copy-address"
35088 0x38/8 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s
35089 _string_b8_copy_to_eax: # (payload array byte)
35090 0x11/imm32/alloc-id:fake:payload
35093 0x62/b 0x38/8 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x61/a 0x78/x
35094 _string_b9_copy_to_ecx: # (payload array byte)
35095 0x11/imm32/alloc-id:fake:payload
35098 0x62/b 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x63/c 0x78/x
35099 _string_ba_copy_to_edx: # (payload array byte)
35100 0x11/imm32/alloc-id:fake:payload
35103 0x62/b 0x61/a 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x78/x
35104 _string_bb_copy_to_ebx: # (payload array byte)
35105 0x11/imm32/alloc-id:fake:payload
35108 0x62/b 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x62/b 0x78/x
35109 _string_be_copy_to_esi: # (payload array byte)
35110 0x11/imm32/alloc-id:fake:payload
35113 0x62/b 0x65/e 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x73/s 0x69/i
35114 _string_bf_copy_to_edi: # (payload array byte)
35115 0x11/imm32/alloc-id:fake:payload
35118 0x62/b 0x66/f 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x65/e 0x64/d 0x69/i
35119 _string_c7_subop_copy: # (payload array byte)
35120 0x11/imm32/alloc-id:fake:payload
35121 # "c7 0/subop/copy"
35123 0x63/c 0x37/7 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y
35124 _string_e9_jump_label: # (payload array byte)
35125 0x11/imm32/alloc-id:fake:payload
35128 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p
35129 _string_e9_jump_break: # (payload array byte)
35130 0x11/imm32/alloc-id:fake:payload
35131 # "e9/jump break/disp32"
35133 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
35134 _string_e9_jump_loop: # (payload array byte)
35135 0x11/imm32/alloc-id:fake:payload
35136 # "e9/jump loop/disp32"
35138 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
35139 _string_f7_subop_negate:
35140 0x11/imm32/alloc-id:fake:payload
35141 # "f7 3/subop/negate"
35143 0x66/f 0x37/7 0x20/space 0x33/3 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6e/n 0x65/e 0x67/g 0x61/a 0x74/t 0x65/e
35144 _string_f7_subop_not:
35145 0x11/imm32/alloc-id:fake:payload
35148 0x66/f 0x37/7 0x20/space 0x32/2 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6e/n 0x6f/o 0x74/t
35149 _string_ff_subop_increment: # (payload array byte)
35150 0x11/imm32/alloc-id:fake:payload
35151 # "ff 0/subop/increment"
35153 0x66/f 0x66/f 0x20/space 0x30/0 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t
35154 _string_ff_subop_decrement: # (payload array byte)
35155 0x11/imm32/alloc-id:fake:payload
35156 # "ff 1/subop/decrement"
35158 0x66/f 0x66/f 0x20/space 0x31/1 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t
35159 _string_c1_subop_shift_left: # (payload array byte)
35160 0x11/imm32/alloc-id:fake:payload
35161 # "c1/shift 4/subop/left"
35163 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x34/4 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x6c/l 0x65/e 0x66/f 0x74/t
35164 _string_c1_subop_shift_right_padding_zeroes: # (payload array byte)
35165 0x11/imm32/alloc-id:fake:payload
35166 # "c1/shift 5/subop/right-padding-zeroes"
35168 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x35/5 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x70/p 0x61/a 0x64/d 0x64/d 0x69/i 0x6e/n 0x67/g 0x2d/dash 0x7a/z 0x65/e 0x72/r 0x6f/o 0x65/e 0x73/s
35169 _string_c1_subop_shift_right_preserving_sign: # (payload array byte)
35170 0x11/imm32/alloc-id:fake:payload
35171 # "c1/shift 7/subop/right-preserving-sign"
35173 0x63/c 0x31/1 0x2f/slash 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x20/space 0x37/7 0x2f/slash 0x73/s 0x75/u 0x62/b 0x6f/o 0x70/p 0x2f/slash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t 0x2d/dash 0x70/p 0x72/r 0x65/e 0x73/s 0x65/e 0x72/r 0x76/v 0x69/i 0x6e/n 0x67/g 0x2d/dash 0x73/s 0x69/i 0x67/g 0x6e/n
35175 Single-int-var-in-mem: # (payload list var)
35176 0x11/imm32/alloc-id:fake:payload
35177 0x11/imm32/alloc-id:fake
35178 Int-var-in-mem/imm32
35182 Int-var-in-mem: # (payload var)
35183 0x11/imm32/alloc-id:fake:payload
35186 0x11/imm32/alloc-id:fake
35188 1/imm32/some-block-depth
35189 1/imm32/some-stack-offset
35190 0/imm32/no-register
35191 0/imm32/no-register
35193 # Not really legal, but closest we can currently represent a dereference of an (addr byte)
35194 Single-byte-var-in-mem: # (payload list var)
35195 0x11/imm32/alloc-id:fake:payload
35196 0x11/imm32/alloc-id:fake
35197 Byte-var-in-mem/imm32
35201 # Not really legal, but closest we can currently represent a dereference of an (addr byte)
35202 Byte-var-in-mem: # (payload var)
35203 0x11/imm32/alloc-id:fake:payload
35206 0x11/imm32/alloc-id:fake
35208 1/imm32/some-block-depth
35209 1/imm32/some-stack-offset
35210 0/imm32/no-register
35211 0/imm32/no-register
35213 Two-args-int-stack-int-reg: # (payload list var)
35214 0x11/imm32/alloc-id:fake:payload
35215 0x11/imm32/alloc-id:fake
35216 Int-var-in-mem/imm32
35217 0x11/imm32/alloc-id:fake
35218 Single-int-var-in-some-register/imm32/next
35220 Two-int-args-in-regs: # (payload list var)
35221 0x11/imm32/alloc-id:fake:payload
35222 0x11/imm32/alloc-id:fake
35223 Int-var-in-some-register/imm32
35224 0x11/imm32/alloc-id:fake
35225 Single-int-var-in-some-register/imm32/next
35227 # Not really legal, but closest we can currently represent a dereference of an (addr byte)
35228 Two-args-byte-stack-byte-reg: # (payload list var)
35229 0x11/imm32/alloc-id:fake:payload
35230 0x11/imm32/alloc-id:fake
35231 Byte-var-in-mem/imm32
35232 0x11/imm32/alloc-id:fake
35233 Single-byte-var-in-some-register/imm32/next
35235 Two-args-int-reg-int-stack: # (payload list var)
35236 0x11/imm32/alloc-id:fake:payload
35237 0x11/imm32/alloc-id:fake
35238 Int-var-in-some-register/imm32
35239 0x11/imm32/alloc-id:fake
35240 Single-int-var-in-mem/imm32/next
35242 Two-args-int-eax-int-literal: # (payload list var)
35243 0x11/imm32/alloc-id:fake:payload
35244 0x11/imm32/alloc-id:fake
35245 Int-var-in-eax/imm32
35246 0x11/imm32/alloc-id:fake
35247 Single-lit-var/imm32/next
35249 Int-var-and-literal: # (payload list var)
35250 0x11/imm32/alloc-id:fake:payload
35251 0x11/imm32/alloc-id:fake
35252 Int-var-in-mem/imm32
35253 0x11/imm32/alloc-id:fake
35254 Single-lit-var/imm32/next
35256 Int-var-in-register-and-literal: # (payload list var)
35257 0x11/imm32/alloc-id:fake:payload
35258 0x11/imm32/alloc-id:fake
35259 Int-var-in-some-register/imm32
35260 0x11/imm32/alloc-id:fake
35261 Single-lit-var/imm32/next
35263 Two-float-args-in-regs: # (payload list var)
35264 0x11/imm32/alloc-id:fake:payload
35265 0x11/imm32/alloc-id:fake
35266 Float-var-in-some-register/imm32
35267 0x11/imm32/alloc-id:fake
35268 Single-float-var-in-some-register/imm32/next
35270 Two-args-float-reg-float-stack: # (payload list var)
35271 0x11/imm32/alloc-id:fake:payload
35272 0x11/imm32/alloc-id:fake
35273 Float-var-in-some-register/imm32
35274 0x11/imm32/alloc-id:fake
35275 Single-float-var-in-mem/imm32/next
35277 Two-args-float-stack-float-reg: # (payload list var)
35278 0x11/imm32/alloc-id:fake:payload
35279 0x11/imm32/alloc-id:fake
35280 Float-var-in-mem/imm32
35281 0x11/imm32/alloc-id:fake
35282 Single-float-var-in-some-register/imm32/next
35284 Single-int-var-in-some-register: # (payload list var)
35285 0x11/imm32/alloc-id:fake:payload
35286 0x11/imm32/alloc-id:fake
35287 Int-var-in-some-register/imm32
35291 Single-addr-var-in-some-register: # (payload list var)
35292 0x11/imm32/alloc-id:fake:payload
35293 0x11/imm32/alloc-id:fake
35294 Addr-var-in-some-register/imm32
35298 Single-byte-var-in-some-register: # (payload list var)
35299 0x11/imm32/alloc-id:fake:payload
35300 0x11/imm32/alloc-id:fake
35301 Byte-var-in-some-register/imm32
35305 Int-var-in-some-register: # (payload var)
35306 0x11/imm32/alloc-id:fake:payload
35309 0x11/imm32/alloc-id:fake
35311 1/imm32/some-block-depth
35312 0/imm32/no-stack-offset
35313 0x11/imm32/alloc-id:fake
35316 Any-register: # (payload array byte)
35317 0x11/imm32/alloc-id:fake:payload
35322 Addr-var-in-some-register: # (payload var)
35323 0x11/imm32/alloc-id:fake:payload
35326 0x11/imm32/alloc-id:fake
35328 1/imm32/some-block-depth
35329 0/imm32/no-stack-offset
35330 0x11/imm32/alloc-id:fake
35333 Byte-var-in-some-register: # (payload var)
35334 0x11/imm32/alloc-id:fake:payload
35337 0x11/imm32/alloc-id:fake
35339 1/imm32/some-block-depth
35340 0/imm32/no-stack-offset
35341 0x11/imm32/alloc-id:fake
35344 Single-int-var-in-eax: # (payload list var)
35345 0x11/imm32/alloc-id:fake:payload
35346 0x11/imm32/alloc-id:fake
35347 Int-var-in-eax/imm32
35352 0x11/imm32/alloc-id:fake:payload
35355 0x11/imm32/alloc-id:fake
35357 1/imm32/some-block-depth
35358 0/imm32/no-stack-offset
35359 0x11/imm32/alloc-id:fake
35360 $Mu-register-eax/imm32 # can't use Register-eax only to keep our buggy tools/treeshake.cc happy (TODO)
35362 Single-int-var-in-ecx: # (payload list var)
35363 0x11/imm32/alloc-id:fake:payload
35364 0x11/imm32/alloc-id:fake
35365 Int-var-in-ecx/imm32
35370 0x11/imm32/alloc-id:fake:payload
35373 0x11/imm32/alloc-id:fake
35375 1/imm32/some-block-depth
35376 0/imm32/no-stack-offset
35377 0x11/imm32/alloc-id:fake
35378 $Register-ecx/imm32/register
35380 Single-int-var-in-edx: # (payload list var)
35381 0x11/imm32/alloc-id:fake:payload
35382 0x11/imm32/alloc-id:fake
35383 Int-var-in-edx/imm32
35387 Int-var-in-edx: # (payload list var)
35388 0x11/imm32/alloc-id:fake:payload
35391 0x11/imm32/alloc-id:fake
35393 1/imm32/some-block-depth
35394 0/imm32/no-stack-offset
35395 0x11/imm32/alloc-id:fake
35396 $Register-edx/imm32/register
35398 Single-int-var-in-ebx: # (payload list var)
35399 0x11/imm32/alloc-id:fake:payload
35400 0x11/imm32/alloc-id:fake
35401 Int-var-in-ebx/imm32
35405 Int-var-in-ebx: # (payload list var)
35406 0x11/imm32/alloc-id:fake:payload
35409 0x11/imm32/alloc-id:fake
35411 1/imm32/some-block-depth
35412 0/imm32/no-stack-offset
35413 0x11/imm32/alloc-id:fake
35414 $Register-ebx/imm32/register
35416 Single-int-var-in-esi: # (payload list var)
35417 0x11/imm32/alloc-id:fake:payload
35418 0x11/imm32/alloc-id:fake
35419 Int-var-in-esi/imm32
35423 Int-var-in-esi: # (payload list var)
35424 0x11/imm32/alloc-id:fake:payload
35427 0x11/imm32/alloc-id:fake
35429 1/imm32/some-block-depth
35430 0/imm32/no-stack-offset
35431 0x11/imm32/alloc-id:fake
35432 $Register-esi/imm32/register
35434 Single-int-var-in-edi: # (payload list var)
35435 0x11/imm32/alloc-id:fake:payload
35436 0x11/imm32/alloc-id:fake
35437 Int-var-in-edi/imm32
35441 Int-var-in-edi: # (payload list var)
35442 0x11/imm32/alloc-id:fake:payload
35445 0x11/imm32/alloc-id:fake
35447 1/imm32/some-block-depth
35448 0/imm32/no-stack-offset
35449 0x11/imm32/alloc-id:fake
35450 $Register-edi/imm32/register
35452 Single-lit-var: # (payload list var)
35453 0x11/imm32/alloc-id:fake:payload
35454 0x11/imm32/alloc-id:fake
35459 Lit-var: # (payload var)
35460 0x11/imm32/alloc-id:fake:payload
35463 0x11/imm32/alloc-id:fake
35465 1/imm32/some-block-depth
35466 0/imm32/no-stack-offset
35467 0/imm32/no-register
35468 0/imm32/no-register
35470 Single-float-var-in-mem: # (payload list var)
35471 0x11/imm32/alloc-id:fake:payload
35472 0x11/imm32/alloc-id:fake
35473 Float-var-in-mem/imm32
35477 Float-var-in-mem: # (payload var)
35478 0x11/imm32/alloc-id:fake:payload
35481 0x11/imm32/alloc-id:fake
35483 1/imm32/some-block-depth
35484 1/imm32/some-stack-offset
35485 0/imm32/no-register
35486 0/imm32/no-register
35488 Single-float-var-in-some-register: # (payload list var)
35489 0x11/imm32/alloc-id:fake:payload
35490 0x11/imm32/alloc-id:fake
35491 Float-var-in-some-register/imm32
35495 Float-var-in-some-register: # (payload var)
35496 0x11/imm32/alloc-id:fake:payload
35499 0x11/imm32/alloc-id:fake
35501 1/imm32/some-block-depth
35502 0/imm32/no-stack-offset
35503 0x11/imm32/alloc-id:fake
35506 Type-int: # (payload type-tree)
35507 0x11/imm32/alloc-id:fake:payload
35510 0/imm32/left:unused
35514 Type-literal: # (payload type-tree)
35515 0x11/imm32/alloc-id:fake:payload
35517 0/imm32/value:literal
35518 0/imm32/left:unused
35522 Type-addr: # (payload type-tree)
35523 0x11/imm32/alloc-id:fake:payload
35526 0/imm32/left:unused
35530 Type-array: # (payload type-tree)
35531 0x11/imm32/alloc-id:fake:payload
35533 3/imm32/value:array
35534 0/imm32/left:unused
35538 Type-byte: # (payload type-tree)
35539 0x11/imm32/alloc-id:fake:payload
35542 0/imm32/left:unused
35546 Type-float: # (payload type-tree)
35547 0x11/imm32/alloc-id:fake:payload
35549 0xf/imm32/value:float
35550 0/imm32/left:unused
35554 Addr-type-string: # (addr type-tree)
35556 0x11/imm32/alloc-id:fake
35557 Type-addr/imm32/left
35558 0x11/imm32/alloc-id:fake
35559 _Addr-type-string:array/imm32/right
35560 _Addr-type-string:array: # (payload type-tree)
35561 0x11/imm32/alloc-id:fake:payload
35563 0x11/imm32/alloc-id:fake
35564 Type-array/imm32/left
35565 0x11/imm32/alloc-id:fake
35566 _Addr-type-string:byte/imm32/right
35567 _Addr-type-string:byte: # (payload type-tree)
35568 0x11/imm32/alloc-id:fake:payload
35570 0x11/imm32/alloc-id:fake
35571 Type-byte/imm32/left
35576 emit-subx-primitive: # out: (addr buffered-file), stmt: (addr stmt), primitive: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor)
35579 89/<- %ebp 4/r32/esp
35584 8b/-> *(ebp+0x10) 1/r32/ecx
35585 # emit primitive name
35586 (emit-indent *(ebp+8) *Curr-block-depth)
35587 (lookup *(ecx+0x18) *(ecx+0x1c)) # Primitive-subx-name Primitive-subx-name => eax
35588 (write-buffered *(ebp+8) %eax)
35589 # emit rm32 if necessary
35590 (emit-subx-rm32 *(ebp+8) *(ecx+0x20) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-rm32
35591 # emit xm32 if necessary
35592 (emit-subx-rm32 *(ebp+8) *(ecx+0x34) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-xm32
35593 # emit r32 if necessary
35594 (emit-subx-r32 *(ebp+8) *(ecx+0x24) *(ebp+0xc)) # Primitive-subx-r32
35595 # emit x32 if necessary
35596 (emit-subx-x32 *(ebp+8) *(ecx+0x38) *(ebp+0xc)) # Primitive-subx-x32
35597 # emit imm32 if necessary
35598 (emit-subx-imm32 *(ebp+8) *(ecx+0x28) *(ebp+0xc)) # Primitive-subx-imm32
35599 # emit imm8 if necessary
35600 (emit-subx-imm8 *(ebp+8) *(ecx+0x2c) *(ebp+0xc)) # Primitive-subx-imm8
35601 # emit disp32 if necessary
35602 (emit-subx-disp32 *(ebp+8) *(ecx+0x30) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-disp32
35603 (write-buffered *(ebp+8) Newline)
35604 $emit-subx-primitive:end:
35605 # . restore registers
35609 89/<- %esp 5/r32/ebp
35613 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
35616 89/<- %ebp 4/r32/esp
35619 # if (l == 0) return
35620 81 7/subop/compare *(ebp+0xc) 0/imm32
35621 74/jump-if-= $emit-subx-rm32:end/disp8
35622 # var v/eax: (addr stmt-var)
35623 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax
35624 (emit-subx-var-as-rm32 *(ebp+8) %eax)
35625 $emit-subx-rm32:end:
35626 # . restore registers
35629 89/<- %esp 5/r32/ebp
35633 get-stmt-operand-from-arg-location: # stmt: (addr stmt), l: arg-location, err: (addr buffered-file), ed: (addr exit-descriptor) -> var/eax: (addr stmt-var)
35636 89/<- %ebp 4/r32/esp
35640 8b/-> *(ebp+0xc) 0/r32/eax
35642 8b/-> *(ebp+8) 1/r32/ecx
35643 # if (l == 1) return stmt->inouts
35645 3d/compare-eax-and 1/imm32
35646 75/jump-if-!= break/disp8
35647 $get-stmt-operand-from-arg-location:1:
35648 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
35649 eb/jump $get-stmt-operand-from-arg-location:end/disp8
35651 # if (l == 2) return stmt->inouts->next
35653 3d/compare-eax-and 2/imm32
35654 75/jump-if-!= break/disp8
35655 $get-stmt-operand-from-arg-location:2:
35656 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
35657 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
35658 eb/jump $get-stmt-operand-from-arg-location:end/disp8
35660 # if (l == 3) return stmt->outputs
35662 3d/compare-eax-and 3/imm32
35663 75/jump-if-!= break/disp8
35664 $get-stmt-operand-from-arg-location:3:
35665 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax
35666 eb/jump $get-stmt-operand-from-arg-location:end/disp8
35669 e9/jump $get-stmt-operand-from-arg-location:abort/disp32
35670 $get-stmt-operand-from-arg-location:end:
35671 # . restore registers
35674 89/<- %esp 5/r32/ebp
35678 $get-stmt-operand-from-arg-location:abort:
35679 # error("invalid arg-location " eax)
35680 (write-buffered *(ebp+0x10) "invalid arg-location ")
35681 (write-int32-hex-buffered *(ebp+0x10) %eax)
35682 (write-buffered *(ebp+0x10) Newline)
35683 (flush *(ebp+0x10))
35684 (stop *(ebp+0x14) 1)
35687 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt)
35690 89/<- %ebp 4/r32/esp
35694 # if (l == 0) return
35695 81 7/subop/compare *(ebp+0xc) 0/imm32
35696 0f 84/jump-if-= $emit-subx-r32:end/disp32
35697 # var v/eax: (addr stmt-var)
35698 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax
35699 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
35700 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
35701 #? (write-buffered Stderr "looking up ")
35702 #? (write-buffered Stderr %eax)
35703 #? (write-buffered Stderr Newline)
35705 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index)
35706 (write-buffered *(ebp+8) Space)
35707 (write-int32-hex-buffered *(ebp+8) *eax)
35708 (write-buffered *(ebp+8) "/r32")
35709 $emit-subx-r32:end:
35710 # . restore registers
35714 89/<- %esp 5/r32/ebp
35718 emit-subx-x32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt)
35721 89/<- %ebp 4/r32/esp
35725 # if (l == 0) return
35726 81 7/subop/compare *(ebp+0xc) 0/imm32
35727 0f 84/jump-if-= $emit-subx-x32:end/disp32
35728 # var v/eax: (addr stmt-var)
35729 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax
35730 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
35731 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
35732 #? (write-buffered Stderr "looking up ")
35733 #? (write-buffered Stderr %eax)
35734 #? (write-buffered Stderr Newline)
35736 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index)
35737 (write-buffered *(ebp+8) Space)
35738 (write-int32-hex-buffered *(ebp+8) *eax)
35739 (write-buffered *(ebp+8) "/x32")
35740 $emit-subx-x32:end:
35741 # . restore registers
35745 89/<- %esp 5/r32/ebp
35749 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt)
35752 89/<- %ebp 4/r32/esp
35756 # if (l == 0) return
35757 81 7/subop/compare *(ebp+0xc) 0/imm32
35758 0f 84/jump-if-= $emit-subx-imm32:end/disp32
35759 # var v/eax: (handle var)
35760 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax
35761 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
35762 (lookup *eax *(eax+4)) # Var-name Var-name => eax
35763 (write-buffered *(ebp+8) Space)
35764 (write-buffered *(ebp+8) %eax)
35765 (write-buffered *(ebp+8) "/imm32")
35766 $emit-subx-imm32:end:
35767 # . restore registers
35771 89/<- %esp 5/r32/ebp
35775 emit-subx-imm8: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt)
35778 89/<- %ebp 4/r32/esp
35782 # if (l == 0) return
35783 81 7/subop/compare *(ebp+0xc) 0/imm32
35784 0f 84/jump-if-= $emit-subx-imm32:end/disp32
35785 # var v/eax: (handle var)
35786 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax
35787 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
35788 (lookup *eax *(eax+4)) # Var-name Var-name => eax
35789 (write-buffered *(ebp+8) Space)
35790 (write-buffered *(ebp+8) %eax)
35791 (write-buffered *(ebp+8) "/imm8")
35792 $emit-subx-imm8:end:
35793 # . restore registers
35797 89/<- %esp 5/r32/ebp
35801 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
35804 89/<- %ebp 4/r32/esp
35808 # if (location == 0) return
35809 81 7/subop/compare *(ebp+0xc) 0/imm32
35810 0f 84/jump-if-= $emit-subx-disp32:end/disp32
35811 # var v/eax: (addr stmt-var)
35812 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax
35813 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
35814 (lookup *eax *(eax+4)) # Var-name Var-name => eax
35815 (write-buffered *(ebp+8) Space)
35816 (write-buffered *(ebp+8) %eax)
35817 # hack: if instruction operation starts with "break", emit ":break"
35818 # var name/ecx: (addr array byte) = lookup(stmt->operation)
35819 8b/-> *(ebp+0x10) 0/r32/eax
35820 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax
35821 89/<- %ecx 0/r32/eax
35823 (string-starts-with? %ecx "break") # => eax
35824 3d/compare-eax-and 0/imm32/false
35825 74/jump-if-= break/disp8
35826 (write-buffered *(ebp+8) ":break")
35828 # hack: if instruction operation starts with "loop", emit ":loop"
35830 (string-starts-with? %ecx "loop") # => eax
35831 3d/compare-eax-and 0/imm32/false
35832 74/jump-if-= break/disp8
35833 (write-buffered *(ebp+8) ":loop")
35835 (write-buffered *(ebp+8) "/disp32")
35836 $emit-subx-disp32:end:
35837 # . restore registers
35841 89/<- %esp 5/r32/ebp
35845 emit-call: # out: (addr buffered-file), stmt: (addr stmt)
35848 89/<- %ebp 4/r32/esp
35853 (emit-indent *(ebp+8) *Curr-block-depth)
35854 (write-buffered *(ebp+8) "(")
35856 8b/-> *(ebp+0xc) 1/r32/ecx
35857 # - emit function name
35858 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax
35859 (write-buffered *(ebp+8) %eax)
35861 # var curr/eax: (addr stmt-var) = lookup(stmt->inouts)
35862 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
35864 # if (curr == null) break
35865 3d/compare-eax-and 0/imm32
35866 74/jump-if-= break/disp8
35868 (emit-subx-call-operand *(ebp+8) %eax)
35869 # curr = lookup(curr->next)
35870 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax
35874 (write-buffered *(ebp+8) ")\n")
35876 # . restore registers
35880 89/<- %esp 5/r32/ebp
35884 emit-subx-call-operand: # out: (addr buffered-file), s: (addr stmt-var)
35885 # shares code with emit-subx-var-as-rm32
35888 89/<- %ebp 4/r32/esp
35894 8b/-> *(ebp+0xc) 1/r32/ecx
35895 # var operand/esi: (addr var) = lookup(s->value)
35896 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
35897 89/<- %esi 0/r32/eax
35898 # if (operand->register && !s->is-deref?) emit "%__"
35900 $emit-subx-call-operand:check-for-register-direct:
35901 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register
35902 74/jump-if-= break/disp8
35903 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref
35904 75/jump-if-!= break/disp8
35905 $emit-subx-call-operand:register-direct:
35906 (write-buffered *(ebp+8) " %")
35907 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax
35908 (write-buffered *(ebp+8) %eax)
35909 e9/jump $emit-subx-call-operand:end/disp32
35911 # else if (operand->register && s->is-deref?) emit "*__"
35913 $emit-subx-call-operand:check-for-register-indirect:
35914 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register
35915 74/jump-if-= break/disp8
35916 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref
35917 74/jump-if-= break/disp8
35918 $emit-subx-call-operand:register-indirect:
35919 (emit-subx-call-operand-register-indirect *(ebp+8) %esi)
35920 e9/jump $emit-subx-call-operand:end/disp32
35922 # else if (operand->stack-offset) emit "*(ebp+__)"
35924 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset
35925 74/jump-if-= break/disp8
35926 $emit-subx-call-operand:stack:
35927 (emit-subx-call-operand-stack *(ebp+8) %esi)
35928 e9/jump $emit-subx-call-operand:end/disp32
35930 # else if (operand->type == literal) emit "__"
35932 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax
35933 81 7/subop/compare *(eax+4) 0/imm32 # Type-tree-value
35934 75/jump-if-!= break/disp8
35935 $emit-subx-call-operand:literal:
35936 (write-buffered *(ebp+8) Space)
35937 (lookup *esi *(esi+4)) # Var-name Var-name => eax
35938 (write-buffered *(ebp+8) %eax)
35939 e9/jump $emit-subx-call-operand:end/disp32
35941 # else if (operand->type == literal-string) emit "__"
35943 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax
35944 81 7/subop/compare *(eax+4) 0x10/imm32 # Type-tree-value
35945 75/jump-if-!= break/disp8
35946 $emit-subx-call-operand:literal-string:
35947 (write-buffered *(ebp+8) Space)
35948 (lookup *esi *(esi+4)) # Var-name Var-name => eax
35949 (write-buffered *(ebp+8) %eax)
35951 $emit-subx-call-operand:end:
35952 # . restore registers
35957 89/<- %esp 5/r32/ebp
35961 emit-subx-call-operand-register-indirect: # out: (addr buffered-file), v: (addr var)
35964 89/<- %ebp 4/r32/esp
35970 8b/-> *(ebp+0xc) 6/r32/esi
35971 # var size/ecx: int = size-of-deref(v)
35972 (size-of-deref %esi) # => eax
35973 89/<- %ecx 0/r32/eax
35974 # var reg-name/esi: (addr array byte) = lookup(v->register)
35975 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax
35976 89/<- %esi 0/r32/eax
35977 # TODO: assert size is a multiple of 4
35978 # var i/eax: int = 0
35979 b8/copy-to-eax 0/imm32
35981 $emit-subx-call-operand-register-indirect:loop:
35982 # if (i >= size) break
35983 39/compare %eax 1/r32/ecx
35984 7d/jump-if->= break/disp8
35985 # emit " *(" v->register "+" i ")"
35986 (write-buffered *(ebp+8) " *(")
35987 (write-buffered *(ebp+8) %esi)
35988 (write-buffered *(ebp+8) "+")
35989 (write-int32-hex-buffered *(ebp+8) %eax)
35990 (write-buffered *(ebp+8) ")")
35992 05/add-to-eax 4/imm32
35996 $emit-subx-call-operand-register-indirect:end:
35997 # . restore registers
36002 89/<- %esp 5/r32/ebp
36006 emit-subx-call-operand-stack: # out: (addr buffered-file), v: (addr var)
36009 89/<- %ebp 4/r32/esp
36015 8b/-> *(ebp+0xc) 6/r32/esi
36016 # var curr/ecx: int = v->offset
36017 8b/-> *(esi+0x14) 1/r32/ecx # Var-offset
36018 # var max/eax: int = v->offset + size-of(v)
36019 (size-of %esi) # => eax
36020 # TODO: assert size is a multiple of 4
36021 01/add-to %eax 1/r32/ecx
36023 $emit-subx-call-operand-stack:loop:
36024 # if (curr >= max) break
36025 39/compare %ecx 0/r32/eax
36026 7d/jump-if->= break/disp8
36027 # emit " *(ebp+" curr ")"
36028 (write-buffered *(ebp+8) " *(ebp+")
36029 (write-int32-hex-buffered *(ebp+8) %ecx)
36030 (write-buffered *(ebp+8) ")")
36032 81 0/subop/add %ecx 4/imm32
36036 $emit-subx-call-operand-stack:end:
36037 # . restore registers
36042 89/<- %esp 5/r32/ebp
36046 emit-subx-var-as-rm32: # out: (addr buffered-file), s: (addr stmt-var)
36049 89/<- %ebp 4/r32/esp
36055 8b/-> *(ebp+0xc) 1/r32/ecx
36056 # var operand/esi: (addr var) = lookup(s->value)
36057 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
36058 89/<- %esi 0/r32/eax
36059 # if (operand->register && s->is-deref?) emit "*__"
36061 $emit-subx-var-as-rm32:check-for-register-indirect:
36062 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register
36063 74/jump-if-= break/disp8
36064 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref
36065 74/jump-if-= break/disp8
36066 $emit-subx-var-as-rm32:register-indirect:
36067 (write-buffered *(ebp+8) " *")
36068 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax
36069 (write-buffered *(ebp+8) %eax)
36070 e9/jump $emit-subx-var-as-rm32:end/disp32
36072 # if (operand->register && !s->is-deref?) emit "%__"
36074 $emit-subx-var-as-rm32:check-for-register-direct:
36075 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register
36076 74/jump-if-= break/disp8
36077 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref
36078 75/jump-if-!= break/disp8
36079 $emit-subx-var-as-rm32:register-direct:
36080 (write-buffered *(ebp+8) " %")
36081 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax
36082 (write-buffered *(ebp+8) %eax)
36083 e9/jump $emit-subx-var-as-rm32:end/disp32
36085 # else if (operand->stack-offset) emit "*(ebp+__)"
36087 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset
36088 74/jump-if-= break/disp8
36089 $emit-subx-var-as-rm32:stack:
36090 (write-buffered *(ebp+8) Space)
36091 (write-buffered *(ebp+8) "*(ebp+")
36092 (write-int32-hex-buffered *(ebp+8) *(esi+0x14)) # Var-offset
36093 (write-buffered *(ebp+8) ")")
36095 $emit-subx-var-as-rm32:end:
36096 # . restore registers
36101 89/<- %esp 5/r32/ebp
36105 find-matching-primitive: # primitives: (addr primitive), stmt: (addr stmt) -> result/eax: (addr primitive)
36108 89/<- %ebp 4/r32/esp
36111 # var curr/ecx: (addr primitive) = primitives
36112 8b/-> *(ebp+8) 1/r32/ecx
36114 $find-matching-primitive:loop:
36115 # if (curr == null) break
36116 81 7/subop/compare %ecx 0/imm32
36117 74/jump-if-= break/disp8
36118 # if match(curr, stmt) return curr
36120 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax
36121 3d/compare-eax-and 0/imm32/false
36122 74/jump-if-= break/disp8
36123 89/<- %eax 1/r32/ecx
36124 eb/jump $find-matching-primitive:end/disp8
36126 $find-matching-primitive:next-primitive:
36127 # curr = curr->next
36128 (lookup *(ecx+0x3c) *(ecx+0x40)) # Primitive-next Primitive-next => eax
36129 89/<- %ecx 0/r32/eax
36131 e9/jump loop/disp32
36134 b8/copy-to-eax 0/imm32
36135 $find-matching-primitive:end:
36136 # . restore registers
36139 89/<- %esp 5/r32/ebp
36143 mu-stmt-matches-primitive?: # stmt: (addr stmt), primitive: (addr primitive) -> result/eax: boolean
36144 # A mu stmt matches a primitive if the name matches, all the inout vars
36145 # match, and all the output vars match.
36146 # Vars match if types match and registers match.
36147 # In addition, a stmt output matches a primitive's output if types match
36148 # and the primitive has a wildcard register.
36151 89/<- %ebp 4/r32/esp
36159 8b/-> *(ebp+8) 1/r32/ecx
36161 8b/-> *(ebp+0xc) 2/r32/edx
36163 $mu-stmt-matches-primitive?:check-name:
36164 # if (primitive->name != stmt->operation) return false
36165 # . var esi: (addr array byte) = lookup(stmt->operation)
36166 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax
36167 89/<- %esi 0/r32/eax
36168 # . var edi: (addr array byte) = lookup(primitive->name)
36169 (lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax
36170 #? (write-buffered Stderr %eax)
36171 #? (write-buffered Stderr Newline)
36173 89/<- %edi 0/r32/eax
36174 (string-equal? %esi %edi) # => eax
36175 3d/compare-eax-and 0/imm32/false
36176 75/jump-if-!= break/disp8
36177 b8/copy-to-eax 0/imm32
36178 e9/jump $mu-stmt-matches-primitive?:end/disp32
36180 # var curr/esi: (addr stmt-var) = lookup(stmt->inouts)
36181 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax
36182 89/<- %esi 0/r32/eax
36183 # var curr2/edi: (addr list var) = lookup(primitive->inouts)
36184 (lookup *(edx+8) *(edx+0xc)) # Primitive-inouts Primitive-inouts => eax
36185 89/<- %edi 0/r32/eax
36187 $mu-stmt-matches-primitive?:inouts-loop:
36188 # if (curr == 0 && curr2 == 0) move on to check outputs
36190 $mu-stmt-matches-primitive?:check-both-inouts-null:
36191 81 7/subop/compare %esi 0/imm32
36192 75/jump-if-!= break/disp8
36193 $mu-stmt-matches-primitive?:stmt-inout-null:
36194 81 7/subop/compare %edi 0/imm32
36195 0f 84/jump-if-= $mu-stmt-matches-primitive?:check-outputs/disp32
36196 $mu-stmt-matches-primitive?:stmt-inout-null-and-prim-inout-not-null:
36198 b8/copy-to-eax 0/imm32/false
36199 e9/jump $mu-stmt-matches-primitive?:end/disp32
36201 # if (curr2 == 0) return false
36203 $mu-stmt-matches-primitive?:check-prim-inout-null:
36204 81 7/subop/compare %edi 0/imm32
36205 75/jump-if-!= break/disp8
36206 $mu-stmt-matches-primitive?:prim-inout-null:
36207 b8/copy-to-eax 0/imm32/false
36208 e9/jump $mu-stmt-matches-primitive?:end/disp32
36210 # if (curr != curr2) return false
36212 $mu-stmt-matches-primitive?:check-inouts-match:
36213 (lookup *edi *(edi+4)) # List-value List-value => eax
36214 (operand-matches-primitive? %esi %eax) # => eax
36215 3d/compare-eax-and 0/imm32/false
36216 75/jump-if-!= break/disp8
36217 $mu-stmt-matches-primitive?:inouts-match:
36218 b8/copy-to-eax 0/imm32/false
36219 e9/jump $mu-stmt-matches-primitive?:end/disp32
36221 $mu-stmt-matches-primitive?:next-inout:
36222 # curr = lookup(curr->next)
36223 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
36224 89/<- %esi 0/r32/eax
36225 # curr2 = lookup(curr2->next)
36226 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax
36227 89/<- %edi 0/r32/eax
36229 e9/jump loop/disp32
36231 $mu-stmt-matches-primitive?:check-outputs:
36232 # var curr/esi: (addr stmt-var) = lookup(stmt->outputs)
36233 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax
36234 89/<- %esi 0/r32/eax
36235 # var curr2/edi: (addr list var) = lookup(primitive->outputs)
36236 (lookup *(edx+0x10) *(edx+0x14)) # Primitive-outputs Primitive-outputs => eax
36237 89/<- %edi 0/r32/eax
36239 $mu-stmt-matches-primitive?:outputs-loop:
36240 # if (curr == 0) return (curr2 == 0)
36242 $mu-stmt-matches-primitive?:check-both-outputs-null:
36243 81 7/subop/compare %esi 0/imm32
36244 75/jump-if-!= break/disp8
36246 $mu-stmt-matches-primitive?:stmt-output-null:
36247 81 7/subop/compare %edi 0/imm32
36248 75/jump-if-!= break/disp8
36249 $mu-stmt-matches-primitive?:both-outputs-null:
36251 b8/copy-to-eax 1/imm32
36252 e9/jump $mu-stmt-matches-primitive?:end/disp32
36254 $mu-stmt-matches-primitive?:stmt-output-null-and-prim-output-not-null:
36256 b8/copy-to-eax 0/imm32
36257 e9/jump $mu-stmt-matches-primitive?:end/disp32
36259 # if (curr2 == 0) return false
36261 $mu-stmt-matches-primitive?:check-prim-output-null:
36262 81 7/subop/compare %edi 0/imm32
36263 75/jump-if-!= break/disp8
36264 $mu-stmt-matches-primitive?:prim-output-is-null:
36265 b8/copy-to-eax 0/imm32
36266 e9/jump $mu-stmt-matches-primitive?:end/disp32
36268 # if (curr != curr2) return false
36270 $mu-stmt-matches-primitive?:check-outputs-match:
36271 (lookup *edi *(edi+4)) # List-value List-value => eax
36272 (operand-matches-primitive? %esi %eax) # => eax
36273 3d/compare-eax-and 0/imm32/false
36274 75/jump-if-!= break/disp8
36275 $mu-stmt-matches-primitive?:outputs-match:
36276 b8/copy-to-eax 0/imm32
36277 e9/jump $mu-stmt-matches-primitive?:end/disp32
36279 $mu-stmt-matches-primitive?:next-output:
36280 # curr = lookup(curr->next)
36281 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax
36282 89/<- %esi 0/r32/eax
36283 # curr2 = lookup(curr2->next)
36284 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax
36285 89/<- %edi 0/r32/eax
36287 e9/jump loop/disp32
36289 $mu-stmt-matches-primitive?:return-true:
36290 b8/copy-to-eax 1/imm32
36291 $mu-stmt-matches-primitive?:end:
36292 # . restore registers
36299 89/<- %esp 5/r32/ebp
36303 operand-matches-primitive?: # s: (addr stmt-var), prim-var: (addr var) -> result/eax: boolean
36306 89/<- %ebp 4/r32/esp
36314 8b/-> *(ebp+8) 1/r32/ecx
36315 # var var/esi: (addr var) = lookup(s->value)
36316 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax
36317 89/<- %esi 0/r32/eax
36319 8b/-> *(ebp+0xc) 7/r32/edi
36320 $operand-matches-primitive?:check-type:
36321 # if !category-match?(var->type, prim-var->type) return false
36322 # . var vtype/ebx: (addr type-tree) = lookup(var->type)
36323 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax
36324 89/<- %ebx 0/r32/eax
36325 # . if s is deref, vtype = vtype->right
36327 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref
36328 74/jump-if-= break/disp8
36329 $operand-matches-primitive?:is-deref:
36330 # . var t/eax: (addr type)
36331 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax
36332 # . if !t->is-atom? t = t->left
36333 81 7/subop/compare *eax 0/imm32/false
36335 75/jump-if-!= break/disp8
36336 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
36339 89/<- %ebx 0/r32/eax
36341 # . var ptype/eax: (addr type-tree) = lookup(prim-var->type)
36342 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax
36343 (subx-type-category-match? %ebx %eax) # => eax
36344 3d/compare-eax-and 0/imm32/false
36345 0f 84/jump-if-= $operand-matches-primitive?:return-false/disp32
36347 $operand-matches-primitive?:check-register:
36348 # if prim-var is in memory and var is in register but dereference, match
36350 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register
36351 0f 85/jump-if-!= break/disp32
36352 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register
36353 74/jump-if-= break/disp8
36354 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref
36355 74/jump-if-= break/disp8
36356 $operand-matches-primitive?:var-deref-match:
36357 e9/jump $operand-matches-primitive?:return-true/disp32
36359 # if prim-var is in register and var is in register but dereference, no match
36361 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register
36362 0f 84/jump-if-= break/disp32
36363 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register
36364 0f 84/jump-if-= break/disp32
36365 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref
36366 74/jump-if-= break/disp8
36367 $operand-matches-primitive?:var-deref-no-match:
36368 e9/jump $operand-matches-primitive?:return-false/disp32
36370 # return false if var->register doesn't match prim-var->register
36372 # if register addresses are equal, it's a match
36373 # var vreg/ebx: (addr array byte) = lookup(var->register)
36374 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax
36375 89/<- %ebx 0/r32/eax
36376 # var preg/ecx: (addr array byte) = lookup(prim-var->register)
36377 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax
36378 89/<- %ecx 0/r32/eax
36379 # if (vreg == preg) break
36380 39/compare %ecx 3/r32/ebx
36381 74/jump-if-= break/disp8
36382 $operand-matches-primitive?:var-register-no-match:
36383 # if either address is 0, return false
36384 81 7/subop/compare %ebx 0/imm32
36385 74/jump-if-= $operand-matches-primitive?:return-false/disp8
36386 81 7/subop/compare %ecx 0/imm32
36387 74/jump-if-= $operand-matches-primitive?:return-false/disp8
36388 # if prim-var->register is wildcard, it's a match
36389 (string-equal? %ecx "*") # Any-register => eax
36390 3d/compare-eax-and 0/imm32/false
36391 75/jump-if-!= break/disp8
36392 $operand-matches-primitive?:wildcard-no-match:
36393 # if string contents aren't equal, return false
36394 (string-equal? %ecx %ebx) # => eax
36395 3d/compare-eax-and 0/imm32/false
36396 74/jump-if-= $operand-matches-primitive?:return-false/disp8
36399 $operand-matches-primitive?:return-true:
36400 b8/copy-to-eax 1/imm32/true
36401 eb/jump $operand-matches-primitive?:end/disp8
36402 $operand-matches-primitive?:return-false:
36403 b8/copy-to-eax 0/imm32/false
36404 $operand-matches-primitive?:end:
36405 # . restore registers
36412 89/<- %esp 5/r32/ebp
36416 find-matching-function: # functions: (addr function), stmt: (addr stmt) -> result/eax: (addr function)
36419 89/<- %ebp 4/r32/esp
36422 # var curr/ecx: (handle function) = functions
36423 8b/-> *(ebp+8) 1/r32/ecx
36425 # if (curr == null) break
36426 81 7/subop/compare %ecx 0/imm32
36427 74/jump-if-= break/disp8
36428 #? (write-buffered Stderr "iter\n")
36430 # if match(stmt, curr) return curr
36432 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax
36433 3d/compare-eax-and 0/imm32/false
36434 74/jump-if-= break/disp8
36435 89/<- %eax 1/r32/ecx
36436 eb/jump $find-matching-function:end/disp8
36438 # curr = curr->next
36439 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax
36440 89/<- %ecx 0/r32/eax
36445 b8/copy-to-eax 0/imm32
36446 $find-matching-function:end:
36447 # . restore registers
36450 89/<- %esp 5/r32/ebp
36454 # Just compare names; user-defined functions don't support overloading yet.
36455 mu-stmt-matches-function?: # stmt: (addr stmt1), function: (addr function) -> result/eax: boolean
36458 89/<- %ebp 4/r32/esp
36461 # return function->name == stmt->operation
36462 # ecx = lookup(stmt->operation)
36463 8b/-> *(ebp+8) 0/r32/eax
36464 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax
36465 89/<- %ecx 0/r32/eax
36466 # eax = lookup(function->name)
36467 8b/-> *(ebp+0xc) 0/r32/eax
36468 (lookup *eax *(eax+4)) # Function-name Function-name => eax
36469 (string-equal? %eax %ecx) # => eax
36470 $mu-stmt-matches-function?:end:
36471 # . restore registers
36474 89/<- %esp 5/r32/ebp
36478 # Type-checking happens elsewhere. This method is for selecting between
36480 subx-type-category-match?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean
36483 89/<- %ebp 4/r32/esp
36486 # var cata/ecx: int = type-category(a)
36487 (type-category *(ebp+8)) # => eax
36488 89/<- %ecx 0/r32/eax
36489 # var catb/eax: int = type-category(b)
36490 (type-category *(ebp+0xc)) # => eax
36491 # return cata == catb
36492 39/compare %eax 1/r32/ecx
36493 0f 94/set-byte-if-= %al
36494 25/and-eax-with 0xff/imm32
36495 $subx-type-category-match?:end:
36496 # . restore registers
36499 89/<- %esp 5/r32/ebp
36503 type-category: # a: (addr type-tree) -> result/eax: int
36506 89/<- %ebp 4/r32/esp
36509 # var lit?/ecx: boolean = literal-type?(a)
36510 (simple-mu-type? *(ebp+8) 0) # literal => eax
36511 89/<- %ecx 0/r32/eax
36512 # lit? |= string-literal?(a)
36513 (simple-mu-type? *(ebp+8) 0x10) # literal-string => eax
36514 09/or %ecx 0/r32/eax
36515 # var float?/eax: int = float?(a)
36516 (simple-mu-type? *(ebp+8) 0xf) # => eax
36517 # set bits for lit? and float?
36518 c1/shift 4/subop/left %ecx 1/imm8
36519 09/or %eax 1/r32/ecx
36520 $type-category:end:
36521 # . restore registers
36524 89/<- %esp 5/r32/ebp
36528 simple-mu-type?: # a: (addr type-tree), n: type-id -> result/eax: boolean
36531 89/<- %ebp 4/r32/esp
36535 8b/-> *(ebp+0xc) 1/r32/ecx
36536 # return (a->value == n)
36537 8b/-> *(ebp+8) 0/r32/eax
36538 39/compare *(eax+4) 1/r32/ecx # Type-tree-value
36539 0f 94/set-byte-if-= %al
36540 25/and-eax-with 0xff/imm32
36541 $simple-mu-type?:end:
36542 # . restore registers
36545 89/<- %esp 5/r32/ebp
36549 mu-addr-type?: # a: (addr type-tree) -> result/eax: boolean
36552 89/<- %ebp 4/r32/esp
36554 8b/-> *(ebp+8) 0/r32/eax
36555 # if (!a->is-atom?) a = a->left
36556 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
36558 75/jump-if-!= break/disp8
36559 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
36561 # return (a->value == addr)
36562 81 7/subop/compare *(eax+4) 2/imm32/addr # Type-tree-value
36563 0f 94/set-byte-if-= %al
36564 25/and-eax-with 0xff/imm32
36565 $mu-addr-type?:end:
36567 89/<- %esp 5/r32/ebp
36571 mu-array-type?: # a: (addr type-tree) -> result/eax: boolean
36574 89/<- %ebp 4/r32/esp
36576 8b/-> *(ebp+8) 0/r32/eax
36577 # if (!a->is-atom?) a = a->left
36578 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
36580 75/jump-if-!= break/disp8
36581 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
36583 # return (a->value == array)
36584 81 7/subop/compare *(eax+4) 3/imm32/array # Type-tree-value
36585 0f 94/set-byte-if-= %al
36586 25/and-eax-with 0xff/imm32
36587 $mu-array-type?:end:
36589 89/<- %esp 5/r32/ebp
36593 mu-string-type?: # a: (addr type-tree) -> result/eax: boolean
36596 89/<- %ebp 4/r32/esp
36600 8b/-> *(ebp+8) 6/r32/esi
36601 # if (a->is-atom?) return false
36602 81 7/subop/compare *esi 0/imm32/false # Type-tree-is-atom
36603 0f 85/jump-if-!= $mu-string-type?:return-false/disp32
36604 # if a is not an addr, return false
36605 (mu-addr-type? %esi) # => eax
36606 3d/compare-eax-with 0/imm32/false
36607 0f 84/jump-if-= $mu-string-type?:end/disp32 # eax changes var
36608 # if a is not an array, return false
36609 (lookup *(esi+0xc) *(esi+0x10)) # Type-tree-right Type-tree-right => eax
36610 (mu-array-type? %eax) # => eax
36611 3d/compare-eax-with 0/imm32/false
36612 74/jump-if-= $mu-string-type?:end/disp8 # eax changes var
36613 # var p/eax: (addr type-tree) = payload of a
36614 (lookup *(esi+0xc) *(esi+0x10)) # Type-tree-right Type-tree-right => eax
36615 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax
36616 # if p is an atom, return false
36617 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
36618 75/jump-if-!= $mu-string-type?:return-false/disp8
36619 # return (p == byte)
36620 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
36621 (simple-mu-type? %eax 8) # byte => eax
36622 eb/jump $mu-string-type?:end/disp8
36623 $mu-string-type?:return-false:
36624 b8/copy-to-eax 0/imm32/false
36625 $mu-string-type?:end:
36626 # . restore registers
36629 89/<- %esp 5/r32/ebp
36633 mu-stream-type?: # a: (addr type-tree) -> result/eax: boolean
36636 89/<- %ebp 4/r32/esp
36638 8b/-> *(ebp+8) 0/r32/eax
36639 # if (!a->is-atom?) a = a->left
36640 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom
36642 75/jump-if-!= break/disp8
36643 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax
36645 # return (a->value == stream)
36646 81 7/subop/compare *(eax+4) 0xb/imm32/stream # Type-tree-value
36647 0f 94/set-byte-if-= %al
36648 25/and-eax-with 0xff/imm32
36649 $mu-stream-type?:end:
36651 89/<- %esp 5/r32/ebp
36655 test-emit-subx-stmt-primitive:
36656 # Primitive operation on a variable on the stack.
36659 # ff 0/subop/increment *(ebp-8)
36661 # There's a variable on the var stack as follows:
36666 # There's a primitive with this info:
36667 # name: 'increment'
36669 # value: 'ff 0/subop/increment'
36673 89/<- %ebp 4/r32/esp
36675 (clear-stream _test-output-stream)
36676 (clear-stream $_test-output-buffered-file->buffer)
36677 # simulate allocated payloads starting with an initial fake alloc-id (0x11)
36678 $test-emit-subx-stmt-primitive:initialize-type:
36679 # var type/ecx: (payload type-tree) = int
36680 68/push 0/imm32/right:null
36681 68/push 0/imm32/right:null
36682 68/push 0/imm32/left:unused
36683 68/push 1/imm32/value:int
36684 68/push 1/imm32/is-atom?:true
36685 68/push 0x11/imm32/alloc-id:fake:payload
36686 89/<- %ecx 4/r32/esp
36687 $test-emit-subx-stmt-primitive:initialize-var:
36688 # var var-foo/ecx: (payload var) = var(type)
36689 68/push 0/imm32/no-register
36690 68/push 0/imm32/no-register
36691 68/push -8/imm32/stack-offset
36692 68/push 1/imm32/block-depth
36694 68/push 0x11/imm32/alloc-id:fake
36695 68/push 0/imm32/name
36696 68/push 0/imm32/name
36697 68/push 0x11/imm32/alloc-id:fake:payload
36698 89/<- %ecx 4/r32/esp
36699 $test-emit-subx-stmt-primitive:initialize-var-name:
36700 # var-foo->name = "foo"
36701 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
36702 (copy-array Heap "foo" %eax)
36703 $test-emit-subx-stmt-primitive:initialize-stmt-var:
36704 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo)
36705 68/push 0/imm32/is-deref:false
36706 68/push 0/imm32/next
36707 68/push 0/imm32/next
36708 51/push-ecx/var-foo
36709 68/push 0x11/imm32/alloc-id:fake
36710 68/push 0x11/imm32/alloc-id:fake:payload
36711 89/<- %ebx 4/r32/esp
36712 $test-emit-subx-stmt-primitive:initialize-stmt:
36713 # var stmt/esi: (addr statement)
36714 68/push 0/imm32/no-outputs
36715 68/push 0/imm32/no-outputs
36717 68/push 0x11/imm32/alloc-id:fake
36718 68/push 0/imm32/operation
36719 68/push 0/imm32/operation
36720 68/push 1/imm32/tag
36721 89/<- %esi 4/r32/esp
36722 $test-emit-subx-stmt-primitive:initialize-stmt-operation:
36723 # stmt->operation = "increment"
36724 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
36725 (copy-array Heap "increment" %eax)
36726 $test-emit-subx-stmt-primitive:initialize-primitive:
36727 # var primitives/ebx: (addr primitive)
36728 68/push 0/imm32/next
36729 68/push 0/imm32/next
36730 68/push 0/imm32/no-x32
36731 68/push 0/imm32/no-xm32
36732 68/push 0/imm32/no-disp32
36733 68/push 0/imm32/no-imm8
36734 68/push 0/imm32/no-imm32
36735 68/push 0/imm32/no-r32
36736 68/push 1/imm32/rm32-is-first-inout
36737 68/push 0/imm32/subx-name
36738 68/push 0/imm32/subx-name
36739 68/push 0/imm32/no-outputs
36740 68/push 0/imm32/no-outputs
36741 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration
36742 68/push 0x11/imm32/alloc-id:fake
36743 68/push 0/imm32/name
36744 68/push 0/imm32/name
36745 89/<- %ebx 4/r32/esp
36746 $test-emit-subx-stmt-primitive:initialize-primitive-name:
36747 # primitives->name = "increment"
36748 (copy-array Heap "increment" %ebx) # Primitive-name
36749 $test-emit-subx-stmt-primitive:initialize-primitive-subx-name:
36750 # primitives->subx-name = "ff 0/subop/increment"
36751 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name
36752 (copy-array Heap "ff 0/subop/increment" %eax)
36754 c7 0/subop/copy *Curr-block-depth 0/imm32
36755 (emit-subx-stmt _test-output-buffered-file %esi %ebx 0 Stderr 0)
36756 (flush _test-output-buffered-file)
36757 #? # dump _test-output-stream {{{
36759 #? (write-stream 2 _test-output-stream)
36761 #? (rewind-stream _test-output-stream)
36764 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-stmt-primitive")
36766 89/<- %esp 5/r32/ebp
36770 test-emit-subx-stmt-primitive-register:
36771 # Primitive operation on a variable in a register.
36774 # ff 0/subop/increment %eax # sub-optimal, but should suffice
36776 # There's a variable on the var stack as follows:
36781 # There's a primitive with this info:
36782 # name: 'increment'
36784 # value: 'ff 0/subop/increment'
36788 89/<- %ebp 4/r32/esp
36790 (clear-stream _test-output-stream)
36791 (clear-stream $_test-output-buffered-file->buffer)
36792 $test-emit-subx-stmt-primitive-register:initialize-type:
36793 # var type/ecx: (payload type-tree) = int
36794 68/push 0/imm32/right:null
36795 68/push 0/imm32/right:null
36796 68/push 0/imm32/left:unused
36797 68/push 1/imm32/value:int
36798 68/push 1/imm32/is-atom?:true
36799 68/push 0x11/imm32/alloc-id:fake:payload
36800 89/<- %ecx 4/r32/esp
36801 $test-emit-subx-stmt-primitive-register:initialize-var:
36802 # var var-foo/ecx: (payload var)
36803 68/push 0/imm32/register
36804 68/push 0/imm32/register
36805 68/push 0/imm32/no-stack-offset
36806 68/push 1/imm32/block-depth
36808 68/push 0x11/imm32/alloc-id:fake
36809 68/push 0/imm32/name
36810 68/push 0/imm32/name
36811 68/push 0x11/imm32/alloc-id:fake:payload
36812 89/<- %ecx 4/r32/esp
36813 $test-emit-subx-stmt-primitive-register:initialize-var-name:
36814 # var-foo->name = "foo"
36815 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
36816 (copy-array Heap "foo" %eax)
36817 $test-emit-subx-stmt-primitive-register:initialize-var-register:
36818 # var-foo->register = "eax"
36819 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
36820 (copy-array Heap "eax" %eax)
36821 $test-emit-subx-stmt-primitive-register:initialize-stmt-var:
36822 # var operand/ebx: (payload stmt-var)
36823 68/push 0/imm32/is-deref:false
36824 68/push 0/imm32/next
36825 68/push 0/imm32/next
36826 51/push-ecx/var-foo
36827 68/push 0x11/imm32/alloc-id:fake
36828 68/push 0x11/imm32/alloc-id:fake:payload
36829 89/<- %ebx 4/r32/esp
36830 $test-emit-subx-stmt-primitive-register:initialize-stmt:
36831 # var stmt/esi: (addr statement)
36832 53/push-ebx/outputs
36833 68/push 0x11/imm32/alloc-id:fake
36834 68/push 0/imm32/no-inouts
36835 68/push 0/imm32/no-inouts
36836 68/push 0/imm32/operation
36837 68/push 0/imm32/operation
36839 89/<- %esi 4/r32/esp
36840 $test-emit-subx-stmt-primitive-register:initialize-stmt-operation:
36841 # stmt->operation = "increment"
36842 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
36843 (copy-array Heap "increment" %eax)
36844 $test-emit-subx-stmt-primitive-register:initialize-formal-var:
36845 # var formal-var/ebx: (payload var)
36846 68/push 0/imm32/register
36847 68/push 0/imm32/register
36848 68/push 0/imm32/no-stack-offset
36849 68/push 1/imm32/block-depth
36850 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id
36851 68/push 0x11/imm32/alloc-id:fake
36852 68/push 0/imm32/name
36853 68/push 0/imm32/name
36854 68/push 0x11/imm32/alloc-id:fake:payload
36855 89/<- %ebx 4/r32/esp
36856 $test-emit-subx-stmt-primitive-register:initialize-formal-var-name:
36857 # formal-var->name = "dummy"
36858 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4
36859 (copy-array Heap "dummy" %eax)
36860 $test-emit-subx-stmt-primitive-register:initialize-formal-register:
36861 # formal-var->register = "*"
36862 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4
36863 (copy-array Heap "*" %eax) # Any-register
36864 $test-emit-subx-stmt-primitive-register:initialize-var-list:
36865 # var formal-outputs/ebx: (payload list var)
36866 68/push 0/imm32/next
36867 68/push 0/imm32/next
36868 53/push-ebx/formal-var
36869 68/push 0x11/imm32/alloc-id:fake
36870 68/push 0x11/imm32/alloc-id:fake:payload
36871 89/<- %ebx 4/r32/esp
36872 $test-emit-subx-stmt-primitive-register:initialize-primitive:
36873 # var primitives/ebx: (addr primitive)
36874 68/push 0/imm32/next
36875 68/push 0/imm32/next
36876 68/push 0/imm32/no-x32
36877 68/push 0/imm32/no-xm32
36878 68/push 0/imm32/no-disp32
36879 68/push 0/imm32/no-imm8
36880 68/push 0/imm32/no-imm32
36881 68/push 0/imm32/no-r32
36882 68/push 3/imm32/rm32-is-first-output
36883 68/push 0/imm32/subx-name
36884 68/push 0/imm32/subx-name
36885 53/push-ebx/outputs
36886 68/push 0x11/imm32/alloc-id:fake
36887 68/push 0/imm32/no-inouts
36888 68/push 0/imm32/no-inouts
36889 68/push 0/imm32/name
36890 68/push 0/imm32/name
36891 89/<- %ebx 4/r32/esp
36892 $test-emit-subx-stmt-primitive-register:initialize-primitive-name:
36893 # primitives->name = "increment"
36894 (copy-array Heap "increment" %ebx) # Primitive-name
36895 $test-emit-subx-stmt-primitive-register:initialize-primitive-subx-name:
36896 # primitives->subx-name = "ff 0/subop/increment"
36897 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name
36898 (copy-array Heap "ff 0/subop/increment" %eax)
36900 c7 0/subop/copy *Curr-block-depth 0/imm32
36901 (emit-subx-stmt _test-output-buffered-file %esi %ebx 0 Stderr 0)
36902 (flush _test-output-buffered-file)
36903 #? # dump _test-output-stream {{{
36905 #? (write-stream 2 _test-output-stream)
36907 #? (rewind-stream _test-output-stream)
36910 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-primitive-register")
36912 89/<- %esp 5/r32/ebp
36916 test-emit-subx-stmt-select-primitive:
36917 # Select the right primitive between overloads.
36920 # ff 0/subop/increment %eax # sub-optimal, but should suffice
36922 # There's a variable on the var stack as follows:
36927 # There's two primitives, as follows:
36928 # - name: 'increment'
36930 # value: 'ff 0/subop/increment'
36931 # - name: 'increment'
36933 # value: 'ff 0/subop/increment'
36937 89/<- %ebp 4/r32/esp
36939 (clear-stream _test-output-stream)
36940 (clear-stream $_test-output-buffered-file->buffer)
36941 $test-emit-subx-stmt-select-primitive:initialize-type:
36942 # var type/ecx: (payload type-tree) = int
36943 68/push 0/imm32/right:null
36944 68/push 0/imm32/right:null
36945 68/push 0/imm32/left:unused
36946 68/push 1/imm32/value:int
36947 68/push 1/imm32/is-atom?:true
36948 68/push 0x11/imm32/alloc-id:fake:payload
36949 89/<- %ecx 4/r32/esp
36950 $test-emit-subx-stmt-select-primitive:initialize-var:
36951 # var var-foo/ecx: (payload var)
36952 68/push 0/imm32/register
36953 68/push 0/imm32/register
36954 68/push 0/imm32/no-stack-offset
36955 68/push 1/imm32/block-depth
36957 68/push 0x11/imm32/alloc-id:fake
36958 68/push 0/imm32/name
36959 68/push 0/imm32/name
36960 68/push 0x11/imm32/alloc-id:fake:payload
36961 89/<- %ecx 4/r32/esp
36962 $test-emit-subx-stmt-select-primitive:initialize-var-name:
36963 # var-foo->name = "foo"
36964 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
36965 (copy-array Heap "foo" %eax)
36966 $test-emit-subx-stmt-select-primitive:initialize-var-register:
36967 # var-foo->register = "eax"
36968 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
36969 (copy-array Heap "eax" %eax)
36970 $test-emit-subx-stmt-select-primitive:initialize-stmt-var:
36971 # var operand/ebx: (payload stmt-var)
36972 68/push 0/imm32/is-deref:false
36973 68/push 0/imm32/next
36974 68/push 0/imm32/next
36975 51/push-ecx/var-foo
36976 68/push 0x11/imm32/alloc-id:fake
36977 68/push 0x11/imm32/alloc-id:fake:payload
36978 89/<- %ebx 4/r32/esp
36979 $test-emit-subx-stmt-select-primitive:initialize-stmt:
36980 # var stmt/esi: (addr statement)
36981 53/push-ebx/outputs
36982 68/push 0x11/imm32/alloc-id:fake
36983 68/push 0/imm32/no-inouts
36984 68/push 0/imm32/no-inouts
36985 68/push 0/imm32/operation
36986 68/push 0/imm32/operation
36988 89/<- %esi 4/r32/esp
36989 $test-emit-subx-stmt-select-primitive:initialize-stmt-operation:
36990 # stmt->operation = "increment"
36991 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
36992 (copy-array Heap "increment" %eax)
36993 $test-emit-subx-stmt-select-primitive:initialize-formal-var:
36994 # var formal-var/ebx: (payload var)
36995 68/push 0/imm32/register
36996 68/push 0/imm32/register
36997 68/push 0/imm32/no-stack-offset
36998 68/push 1/imm32/block-depth
36999 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id
37000 68/push 0x11/imm32/alloc-id:fake
37001 68/push 0/imm32/name
37002 68/push 0/imm32/name
37003 68/push 0x11/imm32/alloc-id:fake:payload
37004 89/<- %ebx 4/r32/esp
37005 $test-emit-subx-stmt-select-primitive:initialize-formal-var-name:
37006 # formal-var->name = "dummy"
37007 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4
37008 (copy-array Heap "dummy" %eax)
37009 $test-emit-subx-stmt-select-primitive:initialize-formal-register:
37010 # formal-var->register = "*"
37011 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4
37012 (copy-array Heap "*" %eax) # Any-register
37013 $test-emit-subx-stmt-select-primitive:initialize-var-list:
37014 # var formal-outputs/ebx: (payload list var)
37015 68/push 0/imm32/next
37016 68/push 0/imm32/next
37017 53/push-ebx/formal-var
37018 68/push 0x11/imm32/alloc-id:fake
37019 68/push 0x11/imm32/alloc-id:fake:payload
37020 89/<- %ebx 4/r32/esp
37021 $test-emit-subx-stmt-select-primitive:initialize-primitive2:
37022 # var primitive2/edi: (payload primitive)
37023 68/push 0/imm32/next
37024 68/push 0/imm32/next
37025 68/push 0/imm32/no-x32
37026 68/push 0/imm32/no-xm32
37027 68/push 0/imm32/no-disp32
37028 68/push 0/imm32/no-imm8
37029 68/push 0/imm32/no-imm32
37030 68/push 0/imm32/no-r32
37031 68/push 3/imm32/rm32-is-first-output
37032 68/push 0/imm32/subx-name
37033 68/push 0/imm32/subx-name
37034 53/push-ebx/outputs
37035 68/push 0x11/imm32/alloc-id:fake
37036 68/push 0/imm32/no-inouts
37037 68/push 0/imm32/no-inouts
37038 68/push 0/imm32/name
37039 68/push 0/imm32/name
37040 68/push 0x11/imm32/alloc-id:fake:payload
37041 89/<- %edi 4/r32/esp
37042 $test-emit-subx-stmt-select-primitive:initialize-primitive2-name:
37043 # primitives->name = "increment"
37044 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4
37045 (copy-array Heap "increment" %eax)
37046 $test-emit-subx-stmt-select-primitive:initialize-primitive2-subx-name:
37047 # primitives->subx-name = "ff 0/subop/increment"
37048 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4
37049 (copy-array Heap "ff 0/subop/increment" %eax)
37050 $test-emit-subx-stmt-select-primitive:initialize-primitive:
37051 # var primitives/ebx: (addr primitive)
37053 68/push 0x11/imm32/alloc-id:fake
37054 68/push 0/imm32/no-x32
37055 68/push 0/imm32/no-xm32
37056 68/push 0/imm32/no-disp32
37057 68/push 0/imm32/no-imm8
37058 68/push 0/imm32/no-imm32
37059 68/push 0/imm32/no-r32
37060 68/push 1/imm32/rm32-is-first-inout
37061 68/push 0/imm32/subx-name
37062 68/push 0/imm32/subx-name
37063 68/push 0/imm32/no-outputs
37064 68/push 0/imm32/no-outputs
37065 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration
37066 68/push 0x11/imm32/alloc-id:fake
37067 68/push 0/imm32/name
37068 68/push 0/imm32/name
37069 89/<- %ebx 4/r32/esp
37070 $test-emit-subx-stmt-select-primitive:initialize-primitive-name:
37071 # primitives->name = "increment"
37072 (copy-array Heap "increment" %ebx) # Primitive-name
37073 $test-emit-subx-stmt-select-primitive:initialize-primitive-subx-name:
37074 # primitives->subx-name = "ff 0/subop/increment"
37075 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name
37076 (copy-array Heap "ff 0/subop/increment" %eax)
37078 c7 0/subop/copy *Curr-block-depth 0/imm32
37079 (emit-subx-stmt _test-output-buffered-file %esi %ebx 0 Stderr 0)
37080 (flush _test-output-buffered-file)
37081 #? # dump _test-output-stream {{{
37083 #? (write-stream 2 _test-output-stream)
37085 #? (rewind-stream _test-output-stream)
37088 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive")
37090 89/<- %esp 5/r32/ebp
37094 test-emit-subx-stmt-select-primitive-2:
37095 # Select the right primitive between overloads.
37098 # ff 0/subop/increment %eax # sub-optimal, but should suffice
37100 # There's a variable on the var stack as follows:
37105 # There's two primitives, as follows:
37106 # - name: 'increment'
37108 # value: 'ff 0/subop/increment'
37109 # - name: 'increment'
37111 # value: 'ff 0/subop/increment'
37115 89/<- %ebp 4/r32/esp
37117 (clear-stream _test-output-stream)
37118 (clear-stream $_test-output-buffered-file->buffer)
37119 $test-emit-subx-stmt-select-primitive-2:initialize-type:
37120 # var type/ecx: (payload type-tree) = int
37121 68/push 0/imm32/right:null
37122 68/push 0/imm32/right:null
37123 68/push 0/imm32/left:unused
37124 68/push 1/imm32/value:int
37125 68/push 1/imm32/is-atom?:true
37126 68/push 0x11/imm32/alloc-id:fake:payload
37127 89/<- %ecx 4/r32/esp
37128 $test-emit-subx-stmt-select-primitive-2:initialize-var:
37129 # var var-foo/ecx: (payload var)
37130 68/push 0/imm32/register
37131 68/push 0/imm32/register
37132 68/push 0/imm32/no-stack-offset
37133 68/push 1/imm32/block-depth
37135 68/push 0x11/imm32/alloc-id:fake
37136 68/push 0/imm32/name
37137 68/push 0/imm32/name
37138 68/push 0x11/imm32/alloc-id:fake:payload
37139 89/<- %ecx 4/r32/esp
37140 $test-emit-subx-stmt-select-primitive-2:initialize-var-name:
37141 # var-foo->name = "foo"
37142 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
37143 (copy-array Heap "foo" %eax)
37144 $test-emit-subx-stmt-select-primitive-2:initialize-var-register:
37145 # var-foo->register = "eax"
37146 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
37147 (copy-array Heap "eax" %eax)
37148 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-var:
37149 # var operand/ebx: (payload stmt-var)
37150 68/push 0/imm32/is-deref:false
37151 68/push 0/imm32/next
37152 68/push 0/imm32/next
37153 51/push-ecx/var-foo
37154 68/push 0x11/imm32/alloc-id:fake
37155 68/push 0x11/imm32/alloc-id:fake:payload
37156 89/<- %ebx 4/r32/esp
37157 $test-emit-subx-stmt-select-primitive-2:initialize-stmt:
37158 # var stmt/esi: (addr statement)
37159 68/push 0/imm32/no-outputs
37160 68/push 0/imm32/no-outputs
37162 68/push 0x11/imm32/alloc-id:fake
37163 68/push 0/imm32/operation
37164 68/push 0/imm32/operation
37166 89/<- %esi 4/r32/esp
37167 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-operation:
37168 # stmt->operation = "increment"
37169 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
37170 (copy-array Heap "increment" %eax)
37171 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var:
37172 # var formal-var/ebx: (payload var)
37173 68/push 0/imm32/register
37174 68/push 0/imm32/register
37175 68/push 0/imm32/no-stack-offset
37176 68/push 1/imm32/block-depth
37177 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id
37178 68/push 0x11/imm32/alloc-id:fake
37179 68/push 0/imm32/name
37180 68/push 0/imm32/name
37181 68/push 0x11/imm32/alloc-id:fake:payload
37182 89/<- %ebx 4/r32/esp
37183 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var-name:
37184 # formal-var->name = "dummy"
37185 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4
37186 (copy-array Heap "dummy" %eax)
37187 $test-emit-subx-stmt-select-primitive-2:initialize-formal-register:
37188 # formal-var->register = "*"
37189 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4
37190 (copy-array Heap "*" %eax) # Any-register
37191 $test-emit-subx-stmt-select-primitive-2:initialize-var-list:
37192 # var formal-outputs/ebx: (payload list stmt-var)
37193 68/push 0/imm32/next
37194 68/push 0/imm32/next
37195 53/push-ebx/formal-var
37196 68/push 0x11/imm32/alloc-id:fake
37197 68/push 0x11/imm32/alloc-id:fake:payload
37198 89/<- %ebx 4/r32/esp
37199 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2:
37200 # var primitive2/edi: (payload primitive)
37201 68/push 0/imm32/next
37202 68/push 0/imm32/next
37203 68/push 0/imm32/no-x32
37204 68/push 0/imm32/no-xm32
37205 68/push 0/imm32/no-disp32
37206 68/push 0/imm32/no-imm8
37207 68/push 0/imm32/no-imm32
37208 68/push 0/imm32/no-r32
37209 68/push 3/imm32/rm32-is-first-output
37210 68/push 0/imm32/subx-name
37211 68/push 0/imm32/subx-name
37212 53/push-ebx/outputs
37213 68/push 0x11/imm32/alloc-id:fake
37214 68/push 0/imm32/no-inouts
37215 68/push 0/imm32/no-inouts
37216 68/push 0/imm32/name
37217 68/push 0/imm32/name
37218 68/push 0x11/imm32/alloc-id:fake:payload
37219 89/<- %edi 4/r32/esp
37220 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-name:
37221 # primitives->name = "increment"
37222 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4
37223 (copy-array Heap "increment" %eax)
37224 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-subx-name:
37225 # primitives->subx-name = "ff 0/subop/increment"
37226 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4
37227 (copy-array Heap "ff 0/subop/increment" %eax)
37228 $test-emit-subx-stmt-select-primitive-2:initialize-primitive:
37229 # var primitives/ebx: (addr primitive)
37231 68/push 0x11/imm32/alloc-id:fake
37232 68/push 0/imm32/no-x32
37233 68/push 0/imm32/no-xm32
37234 68/push 0/imm32/no-disp32
37235 68/push 0/imm32/no-imm8
37236 68/push 0/imm32/no-imm32
37237 68/push 0/imm32/no-r32
37238 68/push 1/imm32/rm32-is-first-inout
37239 68/push 0/imm32/subx-name
37240 68/push 0/imm32/subx-name
37241 68/push 0/imm32/no-outputs
37242 68/push 0/imm32/no-outputs
37243 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration
37244 68/push 0x11/imm32/alloc-id:fake
37245 68/push 0/imm32/name
37246 68/push 0/imm32/name
37247 89/<- %ebx 4/r32/esp
37248 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-name:
37249 # primitives->name = "increment"
37250 (copy-array Heap "increment" %ebx) # Primitive-name
37251 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-subx-name:
37252 # primitives->subx-name = "ff 0/subop/increment"
37253 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name
37254 (copy-array Heap "ff 0/subop/increment" %eax)
37256 c7 0/subop/copy *Curr-block-depth 0/imm32
37257 (emit-subx-stmt _test-output-buffered-file %esi %ebx 0 Stderr 0)
37258 (flush _test-output-buffered-file)
37259 #? # dump _test-output-stream {{{
37261 #? (write-stream 2 _test-output-stream)
37263 #? (rewind-stream _test-output-stream)
37266 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive-2")
37268 89/<- %esp 5/r32/ebp
37272 test-increment-register:
37273 # Select the right register between overloads.
37278 # There's a variable on the var stack as follows:
37283 # Primitives are the global definitions.
37287 89/<- %ebp 4/r32/esp
37289 (clear-stream _test-output-stream)
37290 (clear-stream $_test-output-buffered-file->buffer)
37291 $test-increment-register:initialize-type:
37292 # var type/ecx: (payload type-tree) = int
37293 68/push 0/imm32/right:null
37294 68/push 0/imm32/right:null
37295 68/push 0/imm32/left:unused
37296 68/push 1/imm32/value:int
37297 68/push 1/imm32/is-atom?:true
37298 68/push 0x11/imm32/alloc-id:fake:payload
37299 89/<- %ecx 4/r32/esp
37300 $test-increment-register:initialize-var:
37301 # var var-foo/ecx: (payload var)
37302 68/push 0/imm32/register
37303 68/push 0/imm32/register
37304 68/push 0/imm32/no-stack-offset
37305 68/push 1/imm32/block-depth
37307 68/push 0x11/imm32/alloc-id:fake
37308 68/push 0/imm32/name
37309 68/push 0/imm32/name
37310 68/push 0x11/imm32/alloc-id:fake:payload
37311 89/<- %ecx 4/r32/esp
37312 $test-increment-register:initialize-var-name:
37313 # var-foo->name = "foo"
37314 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
37315 (copy-array Heap "foo" %eax)
37316 $test-increment-register:initialize-var-register:
37317 # var-foo->register = "eax"
37318 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
37319 (copy-array Heap "eax" %eax)
37320 $test-increment-register:initialize-stmt-var:
37321 # var operand/ebx: (payload stmt-var)
37322 68/push 0/imm32/is-deref:false
37323 68/push 0/imm32/next
37324 68/push 0/imm32/next
37325 51/push-ecx/var-foo
37326 68/push 0x11/imm32/alloc-id:fake
37327 68/push 0x11/imm32/alloc-id:fake:payload
37328 89/<- %ebx 4/r32/esp
37329 $test-increment-register:initialize-stmt:
37330 # var stmt/esi: (addr statement)
37331 53/push-ebx/outputs
37332 68/push 0x11/imm32/alloc-id:fake
37333 68/push 0/imm32/no-inouts
37334 68/push 0/imm32/no-inouts
37335 68/push 0/imm32/operation
37336 68/push 0/imm32/operation
37338 89/<- %esi 4/r32/esp
37339 $test-increment-register:initialize-stmt-operation:
37340 # stmt->operation = "increment"
37341 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
37342 (copy-array Heap "increment" %eax)
37344 c7 0/subop/copy *Curr-block-depth 0/imm32
37345 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
37346 (flush _test-output-buffered-file)
37347 #? # dump _test-output-stream {{{
37349 #? (write-stream 2 _test-output-stream)
37351 #? (rewind-stream _test-output-stream)
37354 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register")
37356 89/<- %esp 5/r32/ebp
37360 test-add-reg-to-reg:
37361 # var1/reg <- add var2/reg
37363 # 01/add-to %var1 var2
37367 89/<- %ebp 4/r32/esp
37369 (clear-stream _test-output-stream)
37370 (clear-stream $_test-output-buffered-file->buffer)
37371 $test-add-reg-to-reg:initialize-type:
37372 # var type/ecx: (payload type-tree) = int
37373 68/push 0/imm32/right:null
37374 68/push 0/imm32/right:null
37375 68/push 0/imm32/left:unused
37376 68/push 1/imm32/value:int
37377 68/push 1/imm32/is-atom?:true
37378 68/push 0x11/imm32/alloc-id:fake:payload
37379 89/<- %ecx 4/r32/esp
37380 $test-add-reg-to-reg:initialize-var1:
37381 # var var1/ecx: (payload var)
37382 68/push 0/imm32/register
37383 68/push 0/imm32/register
37384 68/push 0/imm32/no-stack-offset
37385 68/push 1/imm32/block-depth
37387 68/push 0x11/imm32/alloc-id:fake
37388 68/push 0/imm32/name
37389 68/push 0/imm32/name
37390 68/push 0x11/imm32/alloc-id:fake:payload
37391 89/<- %ecx 4/r32/esp
37392 $test-add-reg-to-reg:initialize-var1-name:
37393 # var1->name = "var1"
37394 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
37395 (copy-array Heap "var1" %eax)
37396 $test-add-reg-to-reg:initialize-var1-register:
37397 # var1->register = "eax"
37398 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
37399 (copy-array Heap "eax" %eax)
37400 $test-add-reg-to-reg:initialize-var2:
37401 # var var2/edx: (payload var)
37402 68/push 0/imm32/register
37403 68/push 0/imm32/register
37404 68/push 0/imm32/no-stack-offset
37405 68/push 1/imm32/block-depth
37406 ff 6/subop/push *(ecx+0x10)
37407 68/push 0x11/imm32/alloc-id:fake
37408 68/push 0/imm32/name
37409 68/push 0/imm32/name
37410 68/push 0x11/imm32/alloc-id:fake:payload
37411 89/<- %edx 4/r32/esp
37412 $test-add-reg-to-reg:initialize-var2-name:
37413 # var2->name = "var2"
37414 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
37415 (copy-array Heap "var2" %eax)
37416 $test-add-reg-to-reg:initialize-var2-register:
37417 # var2->register = "ecx"
37418 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4
37419 (copy-array Heap "ecx" %eax)
37420 $test-add-reg-to-reg:initialize-inouts:
37421 # var inouts/esi: (payload stmt-var) = [var2]
37422 68/push 0/imm32/is-deref:false
37423 68/push 0/imm32/next
37424 68/push 0/imm32/next
37426 68/push 0x11/imm32/alloc-id:fake
37427 68/push 0x11/imm32/alloc-id:fake:payload
37428 89/<- %esi 4/r32/esp
37429 $test-add-reg-to-reg:initialize-outputs:
37430 # var outputs/edi: (payload stmt-var) = [var1]
37431 68/push 0/imm32/is-deref:false
37432 68/push 0/imm32/next
37433 68/push 0/imm32/next
37435 68/push 0x11/imm32/alloc-id:fake
37436 68/push 0x11/imm32/alloc-id:fake:payload
37437 89/<- %edi 4/r32/esp
37438 $test-add-reg-to-reg:initialize-stmt:
37439 # var stmt/esi: (addr statement)
37440 68/push 0/imm32/next
37441 68/push 0/imm32/next
37442 57/push-edi/outputs
37443 68/push 0x11/imm32/alloc-id:fake
37445 68/push 0x11/imm32/alloc-id:fake
37446 68/push 0/imm32/operation
37447 68/push 0/imm32/operation
37448 68/push 1/imm32/tag:stmt1
37449 89/<- %esi 4/r32/esp
37450 $test-add-reg-to-reg:initialize-stmt-operation:
37451 # stmt->operation = "add"
37452 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
37453 (copy-array Heap "add" %eax)
37455 c7 0/subop/copy *Curr-block-depth 0/imm32
37456 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
37457 (flush _test-output-buffered-file)
37458 #? # dump _test-output-stream {{{
37460 #? (write-stream 2 _test-output-stream)
37462 #? (rewind-stream _test-output-stream)
37465 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg")
37467 89/<- %esp 5/r32/ebp
37471 test-add-reg-to-mem:
37472 # add-to var1 var2/reg
37474 # 01/add-to *(ebp+__) var2
37478 89/<- %ebp 4/r32/esp
37480 (clear-stream _test-output-stream)
37481 (clear-stream $_test-output-buffered-file->buffer)
37482 $test-add-reg-to-mem:initialize-type:
37483 # var type/ecx: (payload type-tree) = int
37484 68/push 0/imm32/right:null
37485 68/push 0/imm32/right:null
37486 68/push 0/imm32/left:unused
37487 68/push 1/imm32/value:int
37488 68/push 1/imm32/is-atom?:true
37489 68/push 0x11/imm32/alloc-id:fake:payload
37490 89/<- %ecx 4/r32/esp
37491 $test-add-reg-to-mem:initialize-var1:
37492 # var var1/ecx: (payload var)
37493 68/push 0/imm32/register
37494 68/push 0/imm32/register
37495 68/push 8/imm32/stack-offset
37496 68/push 1/imm32/block-depth
37498 68/push 0x11/imm32/alloc-id:fake
37499 68/push 0/imm32/name
37500 68/push 0/imm32/name
37501 68/push 0x11/imm32/alloc-id:fake:payload
37502 89/<- %ecx 4/r32/esp
37503 $test-add-reg-to-mem:initialize-var1-name:
37504 # var1->name = "var1"
37505 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
37506 (copy-array Heap "var1" %eax)
37507 $test-add-reg-to-mem:initialize-var2:
37508 # var var2/edx: (payload var)
37509 68/push 0/imm32/register
37510 68/push 0/imm32/register
37511 68/push 0/imm32/no-stack-offset
37512 68/push 1/imm32/block-depth
37513 ff 6/subop/push *(ecx+0x10)
37514 68/push 0x11/imm32/alloc-id:fake
37515 68/push 0/imm32/name
37516 68/push 0/imm32/name
37517 68/push 0x11/imm32/alloc-id:fake:payload
37518 89/<- %edx 4/r32/esp
37519 $test-add-reg-to-mem:initialize-var2-name:
37520 # var2->name = "var2"
37521 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
37522 (copy-array Heap "var2" %eax)
37523 $test-add-reg-to-mem:initialize-var2-register:
37524 # var2->register = "ecx"
37525 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4
37526 (copy-array Heap "ecx" %eax)
37527 $test-add-reg-to-mem:initialize-inouts:
37528 # var inouts/esi: (payload stmt-var) = [var2]
37529 68/push 0/imm32/is-deref:false
37530 68/push 0/imm32/next
37531 68/push 0/imm32/next
37533 68/push 0x11/imm32/alloc-id:fake
37534 68/push 0x11/imm32/alloc-id:fake:payload
37535 89/<- %esi 4/r32/esp
37536 # inouts = [var1, var2]
37537 68/push 0/imm32/is-deref:false
37539 68/push 0x11/imm32/alloc-id:fake
37541 68/push 0x11/imm32/alloc-id:fake
37542 68/push 0x11/imm32/alloc-id:fake:payload
37543 89/<- %esi 4/r32/esp
37544 $test-add-reg-to-mem:initialize-stmt:
37545 # var stmt/esi: (addr statement)
37546 68/push 0/imm32/next
37547 68/push 0/imm32/next
37548 68/push 0/imm32/outputs
37549 68/push 0/imm32/outputs
37551 68/push 0x11/imm32/alloc-id:fake
37552 68/push 0/imm32/operation
37553 68/push 0/imm32/operation
37554 68/push 1/imm32/tag:stmt1
37555 89/<- %esi 4/r32/esp
37556 $test-add-reg-to-mem:initialize-stmt-operation:
37557 # stmt->operation = "add-to"
37558 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
37559 (copy-array Heap "add-to" %eax)
37561 c7 0/subop/copy *Curr-block-depth 0/imm32
37562 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
37563 (flush _test-output-buffered-file)
37564 #? # dump _test-output-stream {{{
37566 #? (write-stream 2 _test-output-stream)
37568 #? (rewind-stream _test-output-stream)
37571 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem")
37573 89/<- %esp 5/r32/ebp
37577 test-add-mem-to-reg:
37578 # var1/reg <- add var2
37580 # 03/add *(ebp+__) var1
37584 89/<- %ebp 4/r32/esp
37586 (clear-stream _test-output-stream)
37587 (clear-stream $_test-output-buffered-file->buffer)
37588 $test-add-mem-to-reg:initialize-type:
37589 # var type/ecx: (payload type-tree) = int
37590 68/push 0/imm32/right:null
37591 68/push 0/imm32/right:null
37592 68/push 0/imm32/left:unused
37593 68/push 1/imm32/value:int
37594 68/push 1/imm32/is-atom?:true
37595 68/push 0x11/imm32/alloc-id:fake:payload
37596 89/<- %ecx 4/r32/esp
37597 $test-add-mem-to-reg:initialize-var:
37598 # var var1/ecx: (payload var)
37599 68/push 0/imm32/register
37600 68/push 0/imm32/register
37601 68/push 0/imm32/no-stack-offset
37602 68/push 1/imm32/block-depth
37604 68/push 0x11/imm32/alloc-id:fake
37605 68/push 0/imm32/name
37606 68/push 0/imm32/name
37607 68/push 0x11/imm32/alloc-id:fake:payload
37608 89/<- %ecx 4/r32/esp
37609 $test-add-mem-to-reg:initialize-var-name:
37610 # var1->name = "foo"
37611 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
37612 (copy-array Heap "var1" %eax)
37613 $test-add-mem-to-reg:initialize-var-register:
37614 # var1->register = "eax"
37615 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
37616 (copy-array Heap "eax" %eax)
37617 $test-add-mem-to-reg:initialize-var2:
37618 # var var2/edx: (payload var)
37619 68/push 0/imm32/register
37620 68/push 0/imm32/register
37621 68/push 8/imm32/stack-offset
37622 68/push 1/imm32/block-depth
37623 ff 6/subop/push *(ecx+0x10)
37624 68/push 0x11/imm32/alloc-id:fake
37625 68/push 0/imm32/name
37626 68/push 0/imm32/name
37627 68/push 0x11/imm32/alloc-id:fake:payload
37628 89/<- %edx 4/r32/esp
37629 $test-add-mem-to-reg:initialize-var2-name:
37630 # var2->name = "var2"
37631 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
37632 (copy-array Heap "var2" %eax)
37633 $test-add-mem-to-reg:initialize-inouts:
37634 # var inouts/esi: (payload stmt-var) = [var2]
37635 68/push 0/imm32/is-deref:false
37636 68/push 0/imm32/next
37637 68/push 0/imm32/next
37639 68/push 0x11/imm32/alloc-id:fake
37640 68/push 0x11/imm32/alloc-id:fake:payload
37641 89/<- %esi 4/r32/esp
37642 $test-add-mem-to-reg:initialize-outputs:
37643 # var outputs/edi: (payload stmt-var) = [var1]
37644 68/push 0/imm32/is-deref:false
37645 68/push 0/imm32/next
37646 68/push 0/imm32/next
37648 68/push 0x11/imm32/alloc-id:fake
37649 68/push 0x11/imm32/alloc-id:fake:payload
37650 89/<- %edi 4/r32/esp
37651 $test-add-mem-to-reg:initialize-stmt:
37652 # var stmt/esi: (addr statement)
37653 68/push 0/imm32/next
37654 68/push 0/imm32/next
37655 57/push-edi/outputs
37656 68/push 0x11/imm32/alloc-id:fake
37658 68/push 0x11/imm32/alloc-id:fake
37659 68/push 0/imm32/operation
37660 68/push 0/imm32/operation
37661 68/push 1/imm32/tag:stmt1
37662 89/<- %esi 4/r32/esp
37663 $test-add-mem-to-reg:initialize-stmt-operation:
37664 # stmt->operation = "add"
37665 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
37666 (copy-array Heap "add" %eax)
37668 c7 0/subop/copy *Curr-block-depth 0/imm32
37669 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
37670 (flush _test-output-buffered-file)
37671 #? # dump _test-output-stream {{{
37673 #? (write-stream 2 _test-output-stream)
37675 #? (rewind-stream _test-output-stream)
37678 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg")
37680 89/<- %esp 5/r32/ebp
37684 test-add-literal-to-eax:
37685 # var1/eax <- add 0x34
37687 # 05/add-to-eax 0x34/imm32
37691 89/<- %ebp 4/r32/esp
37693 (clear-stream _test-output-stream)
37694 (clear-stream $_test-output-buffered-file->buffer)
37695 $test-add-literal-to-eax:initialize-var-type:
37696 # var type/ecx: (payload type-tree) = int
37697 68/push 0/imm32/right:null
37698 68/push 0/imm32/right:null
37699 68/push 0/imm32/left:unused
37700 68/push 1/imm32/value:int
37701 68/push 1/imm32/is-atom?:true
37702 68/push 0x11/imm32/alloc-id:fake:payload
37703 89/<- %ecx 4/r32/esp
37704 $test-add-literal-to-eax:initialize-var:
37705 # var v/ecx: (payload var)
37706 68/push 0/imm32/register
37707 68/push 0/imm32/register
37708 68/push 0/imm32/no-stack-offset
37709 68/push 1/imm32/block-depth
37711 68/push 0x11/imm32/alloc-id:fake
37712 68/push 0/imm32/name
37713 68/push 0/imm32/name
37714 68/push 0x11/imm32/alloc-id:fake:payload
37715 89/<- %ecx 4/r32/esp
37716 $test-add-literal-to-eax:initialize-var-name:
37718 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
37719 (copy-array Heap "v" %eax)
37720 $test-add-literal-to-eax:initialize-var-register:
37721 # v->register = "eax"
37722 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
37723 (copy-array Heap "eax" %eax)
37724 $test-add-literal-to-eax:initialize-literal-type:
37725 # var type/edx: (payload type-tree) = literal
37726 68/push 0/imm32/right:null
37727 68/push 0/imm32/right:null
37728 68/push 0/imm32/left:unused
37729 68/push 0/imm32/value:literal
37730 68/push 1/imm32/is-atom?:true
37731 68/push 0x11/imm32/alloc-id:fake:payload
37732 89/<- %edx 4/r32/esp
37733 $test-add-literal-to-eax:initialize-literal:
37734 # var l/edx: (payload var)
37735 68/push 0/imm32/register
37736 68/push 0/imm32/register
37737 68/push 0/imm32/no-stack-offset
37738 68/push 1/imm32/block-depth
37740 68/push 0x11/imm32/alloc-id:fake
37741 68/push 0/imm32/name
37742 68/push 0/imm32/name
37743 68/push 0x11/imm32/alloc-id:fake:payload
37744 89/<- %edx 4/r32/esp
37745 $test-add-literal-to-eax:initialize-literal-value:
37747 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
37748 (copy-array Heap "0x34" %eax)
37749 $test-add-literal-to-eax:initialize-inouts:
37750 # var inouts/esi: (payload stmt-var) = [l]
37751 68/push 0/imm32/is-deref:false
37752 68/push 0/imm32/next
37753 68/push 0/imm32/next
37755 68/push 0x11/imm32/alloc-id:fake
37756 68/push 0x11/imm32/alloc-id:fake:payload
37757 89/<- %esi 4/r32/esp
37758 $test-add-literal-to-eax:initialize-outputs:
37759 # var outputs/edi: (payload stmt-var) = [v]
37760 68/push 0/imm32/is-deref:false
37761 68/push 0/imm32/next
37762 68/push 0/imm32/next
37764 68/push 0x11/imm32/alloc-id:fake
37765 68/push 0x11/imm32/alloc-id:fake:payload
37766 89/<- %edi 4/r32/esp
37767 $test-add-literal-to-eax:initialize-stmt:
37768 # var stmt/esi: (addr statement)
37769 68/push 0/imm32/next
37770 68/push 0/imm32/next
37771 57/push-edi/outputs
37772 68/push 0x11/imm32/alloc-id:fake
37774 68/push 0x11/imm32/alloc-id:fake
37775 68/push 0/imm32/operation
37776 68/push 0/imm32/operation
37777 68/push 1/imm32/tag:stmt1
37778 89/<- %esi 4/r32/esp
37779 $test-add-literal-to-eax:initialize-stmt-operation:
37780 # stmt->operation = "add"
37781 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
37782 (copy-array Heap "add" %eax)
37784 c7 0/subop/copy *Curr-block-depth 0/imm32
37785 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
37786 (flush _test-output-buffered-file)
37787 #? # dump _test-output-stream {{{
37789 #? (write-stream 2 _test-output-stream)
37791 #? (rewind-stream _test-output-stream)
37794 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax")
37796 89/<- %esp 5/r32/ebp
37800 test-add-literal-to-reg:
37801 # var1/ecx <- add 0x34
37803 # 81 0/subop/add %ecx 0x34/imm32
37807 89/<- %ebp 4/r32/esp
37809 (clear-stream _test-output-stream)
37810 (clear-stream $_test-output-buffered-file->buffer)
37811 $test-add-literal-to-reg:initialize-var-type:
37812 # var type/ecx: (payload type-tree) = int
37813 68/push 0/imm32/right:null
37814 68/push 0/imm32/right:null
37815 68/push 0/imm32/left:unused
37816 68/push 1/imm32/value:int
37817 68/push 1/imm32/is-atom?:true
37818 68/push 0x11/imm32/alloc-id:fake:payload
37819 89/<- %ecx 4/r32/esp
37820 $test-add-literal-to-reg:initialize-var:
37821 # var v/ecx: (payload var)
37822 68/push 0/imm32/register
37823 68/push 0/imm32/register
37824 68/push 0/imm32/no-stack-offset
37825 68/push 1/imm32/block-depth
37827 68/push 0x11/imm32/alloc-id:fake
37828 68/push 0/imm32/name
37829 68/push 0/imm32/name
37830 68/push 0x11/imm32/alloc-id:fake:payload
37831 89/<- %ecx 4/r32/esp
37832 $test-add-literal-to-reg:initialize-var-name:
37834 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
37835 (copy-array Heap "v" %eax)
37836 $test-add-literal-to-reg:initialize-var-register:
37837 # v->register = "ecx"
37838 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
37839 (copy-array Heap "ecx" %eax)
37840 $test-add-literal-to-reg:initialize-literal-type:
37841 # var type/edx: (payload type-tree) = literal
37842 68/push 0/imm32/right:null
37843 68/push 0/imm32/right:null
37844 68/push 0/imm32/left:unused
37845 68/push 0/imm32/value:literal
37846 68/push 1/imm32/is-atom?:true
37847 68/push 0x11/imm32/alloc-id:fake:payload
37848 89/<- %edx 4/r32/esp
37849 $test-add-literal-to-reg:initialize-literal:
37850 # var l/edx: (payload var)
37851 68/push 0/imm32/register
37852 68/push 0/imm32/register
37853 68/push 0/imm32/no-stack-offset
37854 68/push 1/imm32/block-depth
37856 68/push 0x11/imm32/alloc-id:fake
37857 68/push 0/imm32/name
37858 68/push 0/imm32/name
37859 68/push 0x11/imm32/alloc-id:fake:payload
37860 89/<- %edx 4/r32/esp
37861 $test-add-literal-to-reg:initialize-literal-value:
37863 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
37864 (copy-array Heap "0x34" %eax)
37865 $test-add-literal-to-reg:initialize-inouts:
37866 # var inouts/esi: (payload stmt-var) = [l]
37867 68/push 0/imm32/is-deref:false
37868 68/push 0/imm32/next
37869 68/push 0/imm32/next
37871 68/push 0x11/imm32/alloc-id:fake
37872 68/push 0x11/imm32/alloc-id:fake:payload
37873 89/<- %esi 4/r32/esp
37874 $test-add-literal-to-reg:initialize-outputs:
37875 # var outputs/edi: (payload stmt-var) = [v]
37876 68/push 0/imm32/is-deref:false
37877 68/push 0/imm32/next
37878 68/push 0/imm32/next
37880 68/push 0x11/imm32/alloc-id:fake
37881 68/push 0x11/imm32/alloc-id:fake:payload
37882 89/<- %edi 4/r32/esp
37883 $test-add-literal-to-reg:initialize-stmt:
37884 # var stmt/esi: (addr statement)
37885 68/push 0/imm32/next
37886 68/push 0/imm32/next
37887 57/push-edi/outputs
37888 68/push 0x11/imm32/alloc-id:fake
37890 68/push 0x11/imm32/alloc-id:fake
37891 68/push 0/imm32/operation
37892 68/push 0/imm32/operation
37893 68/push 1/imm32/tag:stmt1
37894 89/<- %esi 4/r32/esp
37895 $test-add-literal-to-reg:initialize-stmt-operation:
37896 # stmt->operation = "add"
37897 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
37898 (copy-array Heap "add" %eax)
37900 c7 0/subop/copy *Curr-block-depth 0/imm32
37901 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
37902 (flush _test-output-buffered-file)
37903 #? # dump _test-output-stream {{{
37905 #? (write-stream 2 _test-output-stream)
37907 #? (rewind-stream _test-output-stream)
37910 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg")
37912 89/<- %esp 5/r32/ebp
37916 test-add-literal-to-mem:
37917 # add-to var1, 0x34
37919 # 81 0/subop/add %eax 0x34/imm32
37923 89/<- %ebp 4/r32/esp
37925 (clear-stream _test-output-stream)
37926 (clear-stream $_test-output-buffered-file->buffer)
37927 $test-add-literal-to-mem:initialize-type:
37928 # var type/ecx: (payload type-tree) = int
37929 68/push 0/imm32/right:null
37930 68/push 0/imm32/right:null
37931 68/push 0/imm32/left:unused
37932 68/push 1/imm32/value:int
37933 68/push 1/imm32/is-atom?:true
37934 68/push 0x11/imm32/alloc-id:fake:payload
37935 89/<- %ecx 4/r32/esp
37936 $test-add-literal-to-mem:initialize-var1:
37937 # var var1/ecx: (payload var)
37938 68/push 0/imm32/register
37939 68/push 0/imm32/register
37940 68/push 8/imm32/stack-offset
37941 68/push 1/imm32/block-depth
37943 68/push 0x11/imm32/alloc-id:fake
37944 68/push 0/imm32/name
37945 68/push 0/imm32/name
37946 68/push 0x11/imm32/alloc-id:fake:payload
37947 89/<- %ecx 4/r32/esp
37948 $test-add-literal-to-mem:initialize-var1-name:
37949 # var1->name = "var1"
37950 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
37951 (copy-array Heap "var1" %eax)
37952 $test-add-literal-to-mem:initialize-literal-type:
37953 # var type/edx: (payload type-tree) = literal
37954 68/push 0/imm32/right:null
37955 68/push 0/imm32/right:null
37956 68/push 0/imm32/left:unused
37957 68/push 0/imm32/value:literal
37958 68/push 1/imm32/is-atom?:true
37959 68/push 0x11/imm32/alloc-id:fake:payload
37960 89/<- %edx 4/r32/esp
37961 $test-add-literal-to-mem:initialize-literal:
37962 # var l/edx: (payload var)
37963 68/push 0/imm32/register
37964 68/push 0/imm32/register
37965 68/push 0/imm32/no-stack-offset
37966 68/push 1/imm32/block-depth
37968 68/push 0x11/imm32/alloc-id:fake
37969 68/push 0/imm32/name
37970 68/push 0/imm32/name
37971 68/push 0x11/imm32/alloc-id:fake:payload
37972 89/<- %edx 4/r32/esp
37973 $test-add-literal-to-mem:initialize-literal-value:
37975 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
37976 (copy-array Heap "0x34" %eax)
37977 $test-add-literal-to-mem:initialize-inouts:
37978 # var inouts/esi: (payload stmt-var) = [l]
37979 68/push 0/imm32/is-deref:false
37980 68/push 0/imm32/next
37981 68/push 0/imm32/next
37983 68/push 0x11/imm32/alloc-id:fake
37984 68/push 0x11/imm32/alloc-id:fake:payload
37985 89/<- %esi 4/r32/esp
37986 # var inouts = (handle stmt-var) = [var1, var2]
37987 68/push 0/imm32/is-deref:false
37989 68/push 0x11/imm32/alloc-id:fake
37991 68/push 0x11/imm32/alloc-id:fake
37992 68/push 0x11/imm32/alloc-id:fake:payload
37993 89/<- %esi 4/r32/esp
37994 $test-add-literal-to-mem:initialize-stmt:
37995 # var stmt/esi: (addr statement)
37996 68/push 0/imm32/next
37997 68/push 0/imm32/next
37998 68/push 0/imm32/outputs
37999 68/push 0/imm32/outputs
38001 68/push 0x11/imm32/alloc-id:fake
38002 68/push 0/imm32/operation
38003 68/push 0/imm32/operation
38004 68/push 1/imm32/tag:stmt1
38005 89/<- %esi 4/r32/esp
38006 $test-add-literal-to-mem:initialize-stmt-operation:
38007 # stmt->operation = "add-to"
38008 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
38009 (copy-array Heap "add-to" %eax)
38011 c7 0/subop/copy *Curr-block-depth 0/imm32
38012 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
38013 (flush _test-output-buffered-file)
38014 #? # dump _test-output-stream {{{
38016 #? (write-stream 2 _test-output-stream)
38018 #? (rewind-stream _test-output-stream)
38021 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem")
38023 89/<- %esp 5/r32/ebp
38027 test-shift-reg-by-literal:
38028 # var1/ecx <- shift-left 2
38030 # c1/shift 4/subop/left %ecx 2/imm8
38034 89/<- %ebp 4/r32/esp
38036 (clear-stream _test-output-stream)
38037 (clear-stream $_test-output-buffered-file->buffer)
38038 $test-shift-reg-by-literal:initialize-var-type:
38039 # var type/ecx: (payload type-tree) = int
38040 68/push 0/imm32/right:null
38041 68/push 0/imm32/right:null
38042 68/push 0/imm32/left:unused
38043 68/push 1/imm32/value:int
38044 68/push 1/imm32/is-atom?:true
38045 68/push 0x11/imm32/alloc-id:fake:payload
38046 89/<- %ecx 4/r32/esp
38047 $test-shift-reg-by-literal:initialize-var:
38048 # var v/ecx: (payload var)
38049 68/push 0/imm32/register
38050 68/push 0/imm32/register
38051 68/push 0/imm32/no-stack-offset
38052 68/push 1/imm32/block-depth
38054 68/push 0x11/imm32/alloc-id:fake
38055 68/push 0/imm32/name
38056 68/push 0/imm32/name
38057 68/push 0x11/imm32/alloc-id:fake:payload
38058 89/<- %ecx 4/r32/esp
38059 $test-shift-reg-by-literal:initialize-var-name:
38061 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
38062 (copy-array Heap "v" %eax)
38063 $test-shift-reg-by-literal:initialize-var-register:
38064 # v->register = "ecx"
38065 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
38066 (copy-array Heap "ecx" %eax)
38067 $test-shift-reg-by-literal:initialize-literal-type:
38068 # var type/edx: (payload type-tree) = literal
38069 68/push 0/imm32/right:null
38070 68/push 0/imm32/right:null
38071 68/push 0/imm32/left:unused
38072 68/push 0/imm32/value:literal
38073 68/push 1/imm32/is-atom?:true
38074 68/push 0x11/imm32/alloc-id:fake:payload
38075 89/<- %edx 4/r32/esp
38076 $test-shift-reg-by-literal:initialize-literal:
38077 # var l/edx: (payload var)
38078 68/push 0/imm32/register
38079 68/push 0/imm32/register
38080 68/push 0/imm32/no-stack-offset
38081 68/push 1/imm32/block-depth
38083 68/push 0x11/imm32/alloc-id:fake
38084 68/push 0/imm32/name
38085 68/push 0/imm32/name
38086 68/push 0x11/imm32/alloc-id:fake:payload
38087 89/<- %edx 4/r32/esp
38088 $test-shift-reg-by-literal:initialize-literal-value:
38090 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
38091 (copy-array Heap "2" %eax)
38092 $test-shift-reg-by-literal:initialize-inouts:
38093 # var inouts/esi: (payload stmt-var) = [l]
38094 68/push 0/imm32/is-deref:false
38095 68/push 0/imm32/next
38096 68/push 0/imm32/next
38098 68/push 0x11/imm32/alloc-id:fake
38099 68/push 0x11/imm32/alloc-id:fake:payload
38100 89/<- %esi 4/r32/esp
38101 $test-shift-reg-by-literal:initialize-outputs:
38102 # var outputs/edi: (payload stmt-var) = [v]
38103 68/push 0/imm32/is-deref:false
38104 68/push 0/imm32/next
38105 68/push 0/imm32/next
38107 68/push 0x11/imm32/alloc-id:fake
38108 68/push 0x11/imm32/alloc-id:fake:payload
38109 89/<- %edi 4/r32/esp
38110 $test-shift-reg-by-literal:initialize-stmt:
38111 # var stmt/esi: (addr statement)
38112 68/push 0/imm32/next
38113 68/push 0/imm32/next
38114 57/push-edi/outputs
38115 68/push 0x11/imm32/alloc-id:fake
38117 68/push 0x11/imm32/alloc-id:fake
38118 68/push 0/imm32/operation
38119 68/push 0/imm32/operation
38120 68/push 1/imm32/tag:stmt1
38121 89/<- %esi 4/r32/esp
38122 $test-shift-reg-by-literal:initialize-stmt-operation:
38123 # stmt->operation = "shift-left"
38124 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
38125 (copy-array Heap "shift-left" %eax)
38127 c7 0/subop/copy *Curr-block-depth 0/imm32
38128 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
38129 (flush _test-output-buffered-file)
38130 #? # dump _test-output-stream {{{
38132 #? (write-stream 2 _test-output-stream)
38134 #? (rewind-stream _test-output-stream)
38137 (check-next-stream-line-equal _test-output-stream "c1/shift 4/subop/left %ecx 2/imm8" "F - test-shift-reg-by-literal")
38139 89/<- %esp 5/r32/ebp
38143 test-shift-mem-by-literal:
38146 # c1/shift 4/subop/left *(ebp+8) 3/imm8
38150 89/<- %ebp 4/r32/esp
38152 (clear-stream _test-output-stream)
38153 (clear-stream $_test-output-buffered-file->buffer)
38154 $test-shift-mem-by-literal:initialize-type:
38155 # var type/ecx: (payload type-tree) = int
38156 68/push 0/imm32/right:null
38157 68/push 0/imm32/right:null
38158 68/push 0/imm32/left:unused
38159 68/push 1/imm32/value:int
38160 68/push 1/imm32/is-atom?:true
38161 68/push 0x11/imm32/alloc-id:fake:payload
38162 89/<- %ecx 4/r32/esp
38163 $test-shift-mem-by-literal:initialize-var1:
38164 # var var1/ecx: (payload var)
38165 68/push 0/imm32/register
38166 68/push 0/imm32/register
38167 68/push 8/imm32/stack-offset
38168 68/push 1/imm32/block-depth
38170 68/push 0x11/imm32/alloc-id:fake
38171 68/push 0/imm32/name
38172 68/push 0/imm32/name
38173 68/push 0x11/imm32/alloc-id:fake:payload
38174 89/<- %ecx 4/r32/esp
38175 $test-shift-mem-by-literal:initialize-var1-name:
38176 # var1->name = "var1"
38177 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
38178 (copy-array Heap "var1" %eax)
38179 $test-shift-mem-by-literal:initialize-literal-type:
38180 # var type/edx: (payload type-tree) = literal
38181 68/push 0/imm32/right:null
38182 68/push 0/imm32/right:null
38183 68/push 0/imm32/left:unused
38184 68/push 0/imm32/value:literal
38185 68/push 1/imm32/is-atom?:true
38186 68/push 0x11/imm32/alloc-id:fake:payload
38187 89/<- %edx 4/r32/esp
38188 $test-shift-mem-by-literal:initialize-literal:
38189 # var l/edx: (payload var)
38190 68/push 0/imm32/register
38191 68/push 0/imm32/register
38192 68/push 0/imm32/no-stack-offset
38193 68/push 1/imm32/block-depth
38195 68/push 0x11/imm32/alloc-id:fake
38196 68/push 0/imm32/name
38197 68/push 0/imm32/name
38198 68/push 0x11/imm32/alloc-id:fake:payload
38199 89/<- %edx 4/r32/esp
38200 $test-shift-mem-by-literal:initialize-literal-value:
38202 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
38203 (copy-array Heap "3" %eax)
38204 $test-shift-mem-by-literal:initialize-inouts:
38205 # var inouts/esi: (payload stmt-var) = [l]
38206 68/push 0/imm32/is-deref:false
38207 68/push 0/imm32/next
38208 68/push 0/imm32/next
38210 68/push 0x11/imm32/alloc-id:fake
38211 68/push 0x11/imm32/alloc-id:fake:payload
38212 89/<- %esi 4/r32/esp
38213 # var inouts = (handle stmt-var) = [var1, var2]
38214 68/push 0/imm32/is-deref:false
38216 68/push 0x11/imm32/alloc-id:fake
38218 68/push 0x11/imm32/alloc-id:fake
38219 68/push 0x11/imm32/alloc-id:fake:payload
38220 89/<- %esi 4/r32/esp
38221 $test-shift-mem-by-literal:initialize-stmt:
38222 # var stmt/esi: (addr statement)
38223 68/push 0/imm32/next
38224 68/push 0/imm32/next
38225 68/push 0/imm32/outputs
38226 68/push 0/imm32/outputs
38228 68/push 0x11/imm32/alloc-id:fake
38229 68/push 0/imm32/operation
38230 68/push 0/imm32/operation
38231 68/push 1/imm32/tag:stmt1
38232 89/<- %esi 4/r32/esp
38233 $test-shift-mem-by-literal:initialize-stmt-operation:
38234 # stmt->operation = "shift-left"
38235 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
38236 (copy-array Heap "shift-left" %eax)
38238 c7 0/subop/copy *Curr-block-depth 0/imm32
38239 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
38240 (flush _test-output-buffered-file)
38241 #? # dump _test-output-stream {{{
38243 #? (write-stream 2 _test-output-stream)
38245 #? (rewind-stream _test-output-stream)
38248 (check-next-stream-line-equal _test-output-stream "c1/shift 4/subop/left *(ebp+0x00000008) 3/imm8" "F - test-shift-mem-by-literal")
38250 89/<- %esp 5/r32/ebp
38254 test-compare-reg-with-reg:
38255 # compare var1/ecx, var2/eax
38257 # 39/compare %ecx 0/r32/eax
38261 89/<- %ebp 4/r32/esp
38263 (clear-stream _test-output-stream)
38264 (clear-stream $_test-output-buffered-file->buffer)
38265 $test-compare-reg-with-reg:initialize-type:
38266 # var type/ecx: (payload type-tree) = int
38267 68/push 0/imm32/right:null
38268 68/push 0/imm32/right:null
38269 68/push 0/imm32/left:unused
38270 68/push 1/imm32/value:int
38271 68/push 1/imm32/is-atom?:true
38272 68/push 0x11/imm32/alloc-id:fake:payload
38273 89/<- %ecx 4/r32/esp
38274 $test-compare-reg-with-reg:initialize-var1:
38275 # var var1/ecx: (payload var)
38276 68/push 0/imm32/register
38277 68/push 0/imm32/register
38278 68/push 0/imm32/no-stack-offset
38279 68/push 1/imm32/block-depth
38281 68/push 0x11/imm32/alloc-id:fake
38282 68/push 0/imm32/name
38283 68/push 0/imm32/name
38284 68/push 0x11/imm32/alloc-id:fake:payload
38285 89/<- %ecx 4/r32/esp
38286 $test-compare-reg-with-reg:initialize-var1-name:
38287 # var1->name = "var1"
38288 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
38289 (copy-array Heap "var1" %eax)
38290 $test-compare-reg-with-reg:initialize-var1-register:
38291 # var1->register = "ecx"
38292 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
38293 (copy-array Heap "ecx" %eax)
38294 $test-compare-reg-with-reg:initialize-var2:
38295 # var var2/edx: (payload var)
38296 68/push 0/imm32/register
38297 68/push 0/imm32/register
38298 68/push 0/imm32/no-stack-offset
38299 68/push 1/imm32/block-depth
38300 ff 6/subop/push *(ecx+0x10)
38301 68/push 0x11/imm32/alloc-id:fake
38302 68/push 0/imm32/name
38303 68/push 0/imm32/name
38304 68/push 0x11/imm32/alloc-id:fake:payload
38305 89/<- %edx 4/r32/esp
38306 $test-compare-reg-with-reg:initialize-var2-name:
38307 # var2->name = "var2"
38308 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
38309 (copy-array Heap "var2" %eax)
38310 $test-compare-reg-with-reg:initialize-var2-register:
38311 # var2->register = "eax"
38312 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4
38313 (copy-array Heap "eax" %eax)
38314 $test-compare-reg-with-reg:initialize-inouts:
38315 # var inouts/esi: (payload stmt-var) = [var2]
38316 68/push 0/imm32/is-deref:false
38317 68/push 0/imm32/next
38318 68/push 0/imm32/next
38320 68/push 0x11/imm32/alloc-id:fake
38321 68/push 0x11/imm32/alloc-id:fake:payload
38322 89/<- %esi 4/r32/esp
38323 # inouts = [var1, var2]
38324 68/push 0/imm32/is-deref:false
38326 68/push 0x11/imm32/alloc-id:fake
38328 68/push 0x11/imm32/alloc-id:fake
38329 68/push 0x11/imm32/alloc-id:fake:payload
38330 89/<- %esi 4/r32/esp
38331 $test-compare-reg-with-reg:initialize-stmt:
38332 # var stmt/esi: (addr statement)
38333 68/push 0/imm32/next
38334 68/push 0/imm32/next
38335 68/push 0/imm32/outputs
38336 68/push 0/imm32/outputs
38338 68/push 0x11/imm32/alloc-id:fake
38339 68/push 0/imm32/operation
38340 68/push 0/imm32/operation
38341 68/push 1/imm32/tag:stmt1
38342 89/<- %esi 4/r32/esp
38343 $test-compare-reg-with-reg:initialize-stmt-operation:
38344 # stmt->operation = "compare"
38345 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
38346 (copy-array Heap "compare" %eax)
38348 c7 0/subop/copy *Curr-block-depth 0/imm32
38349 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
38350 (flush _test-output-buffered-file)
38351 #? # dump _test-output-stream {{{
38353 #? (write-stream 2 _test-output-stream)
38355 #? (rewind-stream _test-output-stream)
38358 (check-next-stream-line-equal _test-output-stream "39/compare-> %ecx 0x00000000/r32" "F - test-compare-reg-with-reg")
38360 89/<- %esp 5/r32/ebp
38364 test-compare-mem-with-reg:
38365 # compare var1, var2/eax
38367 # 39/compare *(ebp+___) 0/r32/eax
38371 89/<- %ebp 4/r32/esp
38373 (clear-stream _test-output-stream)
38374 (clear-stream $_test-output-buffered-file->buffer)
38375 $test-compare-mem-with-reg:initialize-type:
38376 # var type/ecx: (payload type-tree) = int
38377 68/push 0/imm32/right:null
38378 68/push 0/imm32/right:null
38379 68/push 0/imm32/left:unused
38380 68/push 1/imm32/value:int
38381 68/push 1/imm32/is-atom?:true
38382 68/push 0x11/imm32/alloc-id:fake:payload
38383 89/<- %ecx 4/r32/esp
38384 $test-compare-mem-with-reg:initialize-var1:
38385 # var var1/ecx: (payload var)
38386 68/push 0/imm32/register
38387 68/push 0/imm32/register
38388 68/push 8/imm32/stack-offset
38389 68/push 1/imm32/block-depth
38391 68/push 0x11/imm32/alloc-id:fake
38392 68/push 0/imm32/name
38393 68/push 0/imm32/name
38394 68/push 0x11/imm32/alloc-id:fake:payload
38395 89/<- %ecx 4/r32/esp
38396 $test-compare-mem-with-reg:initialize-var1-name:
38397 # var1->name = "var1"
38398 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
38399 (copy-array Heap "var1" %eax)
38400 $test-compare-mem-with-reg:initialize-var2:
38401 # var var2/edx: (payload var)
38402 68/push 0/imm32/register
38403 68/push 0/imm32/register
38404 68/push 0/imm32/no-stack-offset
38405 68/push 1/imm32/block-depth
38406 ff 6/subop/push *(ecx+0x10)
38407 68/push 0x11/imm32/alloc-id:fake
38408 68/push 0/imm32/name
38409 68/push 0/imm32/name
38410 68/push 0x11/imm32/alloc-id:fake:payload
38411 89/<- %edx 4/r32/esp
38412 $test-compare-mem-with-reg:initialize-var2-name:
38413 # var2->name = "var2"
38414 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
38415 (copy-array Heap "var2" %eax)
38416 $test-compare-mem-with-reg:initialize-var2-register:
38417 # var2->register = "eax"
38418 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4
38419 (copy-array Heap "eax" %eax)
38420 $test-compare-mem-with-reg:initialize-inouts:
38421 # var inouts/esi: (payload stmt-var) = [var2]
38422 68/push 0/imm32/is-deref:false
38423 68/push 0/imm32/next
38424 68/push 0/imm32/next
38426 68/push 0x11/imm32/alloc-id:fake
38427 68/push 0x11/imm32/alloc-id:fake:payload
38428 89/<- %esi 4/r32/esp
38429 # inouts = [var1, var2]
38430 68/push 0/imm32/is-deref:false
38432 68/push 0x11/imm32/alloc-id:fake
38434 68/push 0x11/imm32/alloc-id:fake
38435 68/push 0x11/imm32/alloc-id:fake:payload
38436 89/<- %esi 4/r32/esp
38437 $test-compare-mem-with-reg:initialize-stmt:
38438 # var stmt/esi: (addr statement)
38439 68/push 0/imm32/next
38440 68/push 0/imm32/next
38441 68/push 0/imm32/outputs
38442 68/push 0/imm32/outputs
38444 68/push 0x11/imm32/alloc-id:fake
38445 68/push 0/imm32/operation
38446 68/push 0/imm32/operation
38447 68/push 1/imm32/tag:stmt1
38448 89/<- %esi 4/r32/esp
38449 $test-compare-mem-with-reg:initialize-stmt-operation:
38450 # stmt->operation = "compare"
38451 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
38452 (copy-array Heap "compare" %eax)
38454 c7 0/subop/copy *Curr-block-depth 0/imm32
38455 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
38456 (flush _test-output-buffered-file)
38457 #? # dump _test-output-stream {{{
38459 #? (write-stream 2 _test-output-stream)
38461 #? (rewind-stream _test-output-stream)
38464 (check-next-stream-line-equal _test-output-stream "39/compare-> *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg")
38466 89/<- %esp 5/r32/ebp
38470 test-compare-reg-with-mem:
38471 # compare var1/eax, var2
38473 # 3b/compare<- *(ebp+___) 0/r32/eax
38477 89/<- %ebp 4/r32/esp
38479 (clear-stream _test-output-stream)
38480 (clear-stream $_test-output-buffered-file->buffer)
38481 $test-compare-reg-with-mem:initialize-type:
38482 # var type/ecx: (payload type-tree) = int
38483 68/push 0/imm32/right:null
38484 68/push 0/imm32/right:null
38485 68/push 0/imm32/left:unused
38486 68/push 1/imm32/value:int
38487 68/push 1/imm32/is-atom?:true
38488 68/push 0x11/imm32/alloc-id:fake:payload
38489 89/<- %ecx 4/r32/esp
38490 $test-compare-reg-with-mem:initialize-var1:
38491 # var var1/ecx: (payload var)
38492 68/push 0/imm32/register
38493 68/push 0/imm32/register
38494 68/push 0/imm32/no-stack-offset
38495 68/push 1/imm32/block-depth
38497 68/push 0x11/imm32/alloc-id:fake
38498 68/push 0/imm32/name
38499 68/push 0/imm32/name
38500 68/push 0x11/imm32/alloc-id:fake:payload
38501 89/<- %ecx 4/r32/esp
38502 $test-compare-reg-with-mem:initialize-var1-name:
38503 # var1->name = "var1"
38504 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
38505 (copy-array Heap "var1" %eax)
38506 $test-compare-reg-with-mem:initialize-var1-register:
38507 # var1->register = "eax"
38508 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
38509 (copy-array Heap "eax" %eax)
38510 $test-compare-reg-with-mem:initialize-var2:
38511 # var var2/edx: (payload var)
38512 68/push 0/imm32/register
38513 68/push 0/imm32/register
38514 68/push 8/imm32/stack-offset
38515 68/push 1/imm32/block-depth
38516 ff 6/subop/push *(ecx+0x10)
38517 68/push 0x11/imm32/alloc-id:fake
38518 68/push 0/imm32/name
38519 68/push 0/imm32/name
38520 68/push 0x11/imm32/alloc-id:fake:payload
38521 89/<- %edx 4/r32/esp
38522 $test-compare-reg-with-mem:initialize-var2-name:
38523 # var2->name = "var2"
38524 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
38525 (copy-array Heap "var2" %eax)
38526 $test-compare-reg-with-mem:initialize-inouts:
38527 # var inouts/esi: (payload stmt-var) = [var2]
38528 68/push 0/imm32/is-deref:false
38529 68/push 0/imm32/next
38530 68/push 0/imm32/next
38532 68/push 0x11/imm32/alloc-id:fake
38533 68/push 0x11/imm32/alloc-id:fake:payload
38534 89/<- %esi 4/r32/esp
38535 # inouts = [var1, var2]
38536 68/push 0/imm32/is-deref:false
38538 68/push 0x11/imm32/alloc-id:fake
38540 68/push 0x11/imm32/alloc-id:fake
38541 68/push 0x11/imm32/alloc-id:fake:payload
38542 89/<- %esi 4/r32/esp
38543 $test-compare-reg-with-mem:initialize-stmt:
38544 # var stmt/esi: (addr statement)
38545 68/push 0/imm32/next
38546 68/push 0/imm32/next
38547 68/push 0/imm32/outputs
38548 68/push 0/imm32/outputs
38550 68/push 0x11/imm32/alloc-id:fake
38551 68/push 0/imm32/operation
38552 68/push 0/imm32/operation
38553 68/push 1/imm32/tag:stmt1
38554 89/<- %esi 4/r32/esp
38555 $test-compare-reg-with-mem:initialize-stmt-operation:
38556 # stmt->operation = "compare"
38557 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
38558 (copy-array Heap "compare" %eax)
38560 c7 0/subop/copy *Curr-block-depth 0/imm32
38561 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
38562 (flush _test-output-buffered-file)
38563 #? # dump _test-output-stream {{{
38565 #? (write-stream 2 _test-output-stream)
38567 #? (rewind-stream _test-output-stream)
38570 (check-next-stream-line-equal _test-output-stream "3b/compare<- *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem")
38572 89/<- %esp 5/r32/ebp
38576 test-compare-mem-with-literal:
38577 # compare var1, 0x34
38579 # 81 7/subop/compare *(ebp+___) 0x34/imm32
38583 89/<- %ebp 4/r32/esp
38585 (clear-stream _test-output-stream)
38586 (clear-stream $_test-output-buffered-file->buffer)
38587 $test-compare-mem-with-literal:initialize-type:
38588 # var type/ecx: (payload type-tree) = int
38589 68/push 0/imm32/right:null
38590 68/push 0/imm32/right:null
38591 68/push 0/imm32/left:unused
38592 68/push 1/imm32/value:int
38593 68/push 1/imm32/is-atom?:true
38594 68/push 0x11/imm32/alloc-id:fake:payload
38595 89/<- %ecx 4/r32/esp
38596 $test-compare-mem-with-literal:initialize-var1:
38597 # var var1/ecx: (payload var)
38598 68/push 0/imm32/register
38599 68/push 0/imm32/register
38600 68/push 8/imm32/stack-offset
38601 68/push 1/imm32/block-depth
38603 68/push 0x11/imm32/alloc-id:fake
38604 68/push 0/imm32/name
38605 68/push 0/imm32/name
38606 68/push 0x11/imm32/alloc-id:fake:payload
38607 89/<- %ecx 4/r32/esp
38608 $test-compare-mem-with-literal:initialize-var1-name:
38609 # var1->name = "var1"
38610 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
38611 (copy-array Heap "var1" %eax)
38612 $test-compare-mem-with-literal:initialize-literal-type:
38613 # var type/edx: (payload type-tree) = literal
38614 68/push 0/imm32/right:null
38615 68/push 0/imm32/right:null
38616 68/push 0/imm32/left:unused
38617 68/push 0/imm32/value:literal
38618 68/push 1/imm32/is-atom?:true
38619 68/push 0x11/imm32/alloc-id:fake:payload
38620 89/<- %edx 4/r32/esp
38621 $test-compare-mem-with-literal:initialize-literal:
38622 # var l/edx: (payload var)
38623 68/push 0/imm32/register
38624 68/push 0/imm32/register
38625 68/push 0/imm32/no-stack-offset
38626 68/push 1/imm32/block-depth
38628 68/push 0x11/imm32/alloc-id:fake
38629 68/push 0/imm32/name
38630 68/push 0/imm32/name
38631 68/push 0x11/imm32/alloc-id:fake:payload
38632 89/<- %edx 4/r32/esp
38633 $test-compare-mem-with-literal:initialize-literal-value:
38635 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
38636 (copy-array Heap "0x34" %eax)
38637 $test-compare-mem-with-literal:initialize-inouts:
38638 # var inouts/esi: (payload stmt-var) = [l]
38639 68/push 0/imm32/is-deref:false
38640 68/push 0/imm32/next
38641 68/push 0/imm32/next
38643 68/push 0x11/imm32/alloc-id:fake
38644 68/push 0x11/imm32/alloc-id:fake:payload
38645 89/<- %esi 4/r32/esp
38646 # var inouts = (handle stmt-var) = [var1, var2]
38647 68/push 0/imm32/is-deref:false
38649 68/push 0x11/imm32/alloc-id:fake
38651 68/push 0x11/imm32/alloc-id:fake
38652 68/push 0x11/imm32/alloc-id:fake:payload
38653 89/<- %esi 4/r32/esp
38654 $test-compare-mem-with-literal:initialize-stmt:
38655 # var stmt/esi: (addr statement)
38656 68/push 0/imm32/next
38657 68/push 0/imm32/next
38658 68/push 0/imm32/outputs
38659 68/push 0/imm32/outputs
38661 68/push 0x11/imm32/alloc-id:fake
38662 68/push 0/imm32/operation
38663 68/push 0/imm32/operation
38664 68/push 1/imm32/tag:stmt1
38665 89/<- %esi 4/r32/esp
38666 $test-compare-mem-with-literal:initialize-stmt-operation:
38667 # stmt->operation = "compare"
38668 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
38669 (copy-array Heap "compare" %eax)
38671 c7 0/subop/copy *Curr-block-depth 0/imm32
38672 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
38673 (flush _test-output-buffered-file)
38674 #? # dump _test-output-stream {{{
38676 #? (write-stream 2 _test-output-stream)
38678 #? (rewind-stream _test-output-stream)
38681 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal")
38683 89/<- %esp 5/r32/ebp
38687 test-compare-eax-with-literal:
38688 # compare var1/eax 0x34
38690 # 3d/compare-eax-with 0x34/imm32
38694 89/<- %ebp 4/r32/esp
38696 (clear-stream _test-output-stream)
38697 (clear-stream $_test-output-buffered-file->buffer)
38698 $test-compare-eax-with-literal:initialize-type:
38699 # var type/ecx: (payload type-tree) = int
38700 68/push 0/imm32/right:null
38701 68/push 0/imm32/right:null
38702 68/push 0/imm32/left:unused
38703 68/push 1/imm32/value:int
38704 68/push 1/imm32/is-atom?:true
38705 68/push 0x11/imm32/alloc-id:fake:payload
38706 89/<- %ecx 4/r32/esp
38707 $test-compare-eax-with-literal:initialize-var1:
38708 # var var1/ecx: (payload var)
38709 68/push 0/imm32/register
38710 68/push 0/imm32/register
38711 68/push 0/imm32/no-stack-offset
38712 68/push 1/imm32/block-depth
38714 68/push 0x11/imm32/alloc-id:fake
38715 68/push 0/imm32/name
38716 68/push 0/imm32/name
38717 68/push 0x11/imm32/alloc-id:fake:payload
38718 89/<- %ecx 4/r32/esp
38719 $test-compare-eax-with-literal:initialize-var1-name:
38720 # var1->name = "var1"
38721 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
38722 (copy-array Heap "var1" %eax)
38723 $test-compare-eax-with-literal:initialize-var1-register:
38724 # v->register = "eax"
38725 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
38726 (copy-array Heap "eax" %eax)
38727 $test-compare-eax-with-literal:initialize-literal-type:
38728 # var type/edx: (payload type-tree) = literal
38729 68/push 0/imm32/right:null
38730 68/push 0/imm32/right:null
38731 68/push 0/imm32/left:unused
38732 68/push 0/imm32/value:literal
38733 68/push 1/imm32/is-atom?:true
38734 68/push 0x11/imm32/alloc-id:fake:payload
38735 89/<- %edx 4/r32/esp
38736 $test-compare-eax-with-literal:initialize-literal:
38737 # var l/edx: (payload var)
38738 68/push 0/imm32/register
38739 68/push 0/imm32/register
38740 68/push 0/imm32/no-stack-offset
38741 68/push 1/imm32/block-depth
38743 68/push 0x11/imm32/alloc-id:fake
38744 68/push 0/imm32/name
38745 68/push 0/imm32/name
38746 68/push 0x11/imm32/alloc-id:fake:payload
38747 89/<- %edx 4/r32/esp
38748 $test-compare-eax-with-literal:initialize-literal-value:
38750 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
38751 (copy-array Heap "0x34" %eax)
38752 $test-compare-eax-with-literal:initialize-inouts:
38753 # var inouts/esi: (payload stmt-var) = [l]
38754 68/push 0/imm32/is-deref:false
38755 68/push 0/imm32/next
38756 68/push 0/imm32/next
38758 68/push 0x11/imm32/alloc-id:fake
38759 68/push 0x11/imm32/alloc-id:fake:payload
38760 89/<- %esi 4/r32/esp
38761 # var inouts = (handle stmt-var) = [var1, var2]
38762 68/push 0/imm32/is-deref:false
38764 68/push 0x11/imm32/alloc-id:fake
38766 68/push 0x11/imm32/alloc-id:fake
38767 68/push 0x11/imm32/alloc-id:fake:payload
38768 89/<- %esi 4/r32/esp
38769 $test-compare-eax-with-literal:initialize-stmt:
38770 # var stmt/esi: (addr statement)
38771 68/push 0/imm32/next
38772 68/push 0/imm32/next
38773 68/push 0/imm32/outputs
38774 68/push 0/imm32/outputs
38776 68/push 0x11/imm32/alloc-id:fake
38777 68/push 0/imm32/operation
38778 68/push 0/imm32/operation
38779 68/push 1/imm32/tag:stmt1
38780 89/<- %esi 4/r32/esp
38781 $test-compare-eax-with-literal:initialize-stmt-operation:
38782 # stmt->operation = "compare"
38783 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
38784 (copy-array Heap "compare" %eax)
38786 c7 0/subop/copy *Curr-block-depth 0/imm32
38787 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
38788 (flush _test-output-buffered-file)
38789 #? # dump _test-output-stream {{{
38791 #? (write-stream 2 _test-output-stream)
38793 #? (rewind-stream _test-output-stream)
38796 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal")
38798 89/<- %esp 5/r32/ebp
38802 test-compare-reg-with-literal:
38803 # compare var1/ecx 0x34
38805 # 81 7/subop/compare %ecx 0x34/imm32
38809 89/<- %ebp 4/r32/esp
38811 (clear-stream _test-output-stream)
38812 (clear-stream $_test-output-buffered-file->buffer)
38813 $test-compare-reg-with-literal:initialize-type:
38814 # var type/ecx: (payload type-tree) = int
38815 68/push 0/imm32/right:null
38816 68/push 0/imm32/right:null
38817 68/push 0/imm32/left:unused
38818 68/push 1/imm32/value:int
38819 68/push 1/imm32/is-atom?:true
38820 68/push 0x11/imm32/alloc-id:fake:payload
38821 89/<- %ecx 4/r32/esp
38822 $test-compare-reg-with-literal:initialize-var1:
38823 # var var1/ecx: (payload var)
38824 68/push 0/imm32/register
38825 68/push 0/imm32/register
38826 68/push 0/imm32/no-stack-offset
38827 68/push 1/imm32/block-depth
38829 68/push 0x11/imm32/alloc-id:fake
38830 68/push 0/imm32/name
38831 68/push 0/imm32/name
38832 68/push 0x11/imm32/alloc-id:fake:payload
38833 89/<- %ecx 4/r32/esp
38834 $test-compare-reg-with-literal:initialize-var1-name:
38835 # var1->name = "var1"
38836 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
38837 (copy-array Heap "var1" %eax)
38838 $test-compare-reg-with-literal:initialize-var1-register:
38839 # v->register = "ecx"
38840 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4
38841 (copy-array Heap "ecx" %eax)
38842 $test-compare-reg-with-literal:initialize-literal-type:
38843 # var type/edx: (payload type-tree) = literal
38844 68/push 0/imm32/right:null
38845 68/push 0/imm32/right:null
38846 68/push 0/imm32/left:unused
38847 68/push 0/imm32/value:literal
38848 68/push 1/imm32/is-atom?:true
38849 68/push 0x11/imm32/alloc-id:fake:payload
38850 89/<- %edx 4/r32/esp
38851 $test-compare-reg-with-literal:initialize-literal:
38852 # var l/edx: (payload var)
38853 68/push 0/imm32/register
38854 68/push 0/imm32/register
38855 68/push 0/imm32/no-stack-offset
38856 68/push 1/imm32/block-depth
38858 68/push 0x11/imm32/alloc-id:fake
38859 68/push 0/imm32/name
38860 68/push 0/imm32/name
38861 68/push 0x11/imm32/alloc-id:fake:payload
38862 89/<- %edx 4/r32/esp
38863 $test-compare-reg-with-literal:initialize-literal-value:
38865 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4
38866 (copy-array Heap "0x34" %eax)
38867 $test-compare-reg-with-literal:initialize-inouts:
38868 # var inouts/esi: (payload stmt-var) = [l]
38869 68/push 0/imm32/is-deref:false
38870 68/push 0/imm32/next
38871 68/push 0/imm32/next
38873 68/push 0x11/imm32/alloc-id:fake
38874 68/push 0x11/imm32/alloc-id:fake:payload
38875 89/<- %esi 4/r32/esp
38876 # var inouts = (handle stmt-var) = [var1, var2]
38877 68/push 0/imm32/is-deref:false
38879 68/push 0x11/imm32/alloc-id:fake
38881 68/push 0x11/imm32/alloc-id:fake
38882 68/push 0x11/imm32/alloc-id:fake:payload
38883 89/<- %esi 4/r32/esp
38884 $test-compare-reg-with-literal:initialize-stmt:
38885 # var stmt/esi: (addr statement)
38886 68/push 0/imm32/next
38887 68/push 0/imm32/next
38888 68/push 0/imm32/outputs
38889 68/push 0/imm32/outputs
38891 68/push 0x11/imm32/alloc-id:fake
38892 68/push 0/imm32/operation
38893 68/push 0/imm32/operation
38894 68/push 1/imm32/tag:stmt1
38895 89/<- %esi 4/r32/esp
38896 $test-compare-reg-with-literal:initialize-stmt-operation:
38897 # stmt->operation = "compare"
38898 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
38899 (copy-array Heap "compare" %eax)
38901 c7 0/subop/copy *Curr-block-depth 0/imm32
38902 (emit-subx-stmt _test-output-buffered-file %esi Primitives 0 Stderr 0)
38903 (flush _test-output-buffered-file)
38904 #? # dump _test-output-stream {{{
38906 #? (write-stream 2 _test-output-stream)
38908 #? (rewind-stream _test-output-stream)
38911 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal")
38913 89/<- %esp 5/r32/ebp
38917 test-emit-subx-stmt-function-call:
38918 # Call a function on a variable on the stack.
38922 # (Changing the function name supports overloading in general, but here it
38923 # just serves to help disambiguate things.)
38925 # There's a variable on the var stack as follows:
38930 # There's nothing in primitives.
38932 # We don't perform any checking here on the type of 'f'.
38936 89/<- %ebp 4/r32/esp
38938 (clear-stream _test-output-stream)
38939 (clear-stream $_test-output-buffered-file->buffer)
38940 $test-emit-subx-function-call:initialize-type:
38941 # var type/ecx: (payload type-tree) = int
38942 68/push 0/imm32/right:null
38943 68/push 0/imm32/right:null
38944 68/push 0/imm32/left:unused
38945 68/push 1/imm32/value:int
38946 68/push 1/imm32/is-atom?:true
38947 68/push 0x11/imm32/alloc-id:fake:payload
38948 89/<- %ecx 4/r32/esp
38949 $test-emit-subx-function-call:initialize-var:
38950 # var var-foo/ecx: (payload var) = var(type)
38951 68/push 0/imm32/no-register
38952 68/push 0/imm32/no-register
38953 68/push -8/imm32/stack-offset
38954 68/push 1/imm32/block-depth
38956 68/push 0x11/imm32/alloc-id:fake
38957 68/push 0/imm32/name
38958 68/push 0/imm32/name
38959 68/push 0x11/imm32/alloc-id:fake:payload
38960 89/<- %ecx 4/r32/esp
38961 $test-emit-subx-function-call:initialize-var-name:
38962 # var-foo->name = "foo"
38963 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
38964 (copy-array Heap "foo" %eax)
38965 $test-emit-subx-function-call:initialize-stmt-var:
38966 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo)
38967 68/push 0/imm32/is-deref:false
38968 68/push 0/imm32/next
38969 68/push 0/imm32/next
38970 51/push-ecx/var-foo
38971 68/push 0x11/imm32/alloc-id:fake
38972 68/push 0x11/imm32/alloc-id:fake:payload
38973 89/<- %ebx 4/r32/esp
38974 $test-emit-subx-function-call:initialize-stmt:
38975 # var stmt/esi: (addr statement)
38976 68/push 0/imm32/no-outputs
38977 68/push 0/imm32/no-outputs
38979 68/push 0x11/imm32/alloc-id:fake
38980 68/push 0/imm32/operation
38981 68/push 0/imm32/operation
38982 68/push 1/imm32/tag
38983 89/<- %esi 4/r32/esp
38984 $test-emit-subx-function-call:initialize-stmt-operation:
38985 # stmt->operation = "f"
38986 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
38987 (copy-array Heap "f" %eax)
38989 c7 0/subop/copy *Curr-block-depth 0/imm32
38990 (emit-subx-stmt _test-output-buffered-file %esi 0 0 Stderr 0)
38991 (flush _test-output-buffered-file)
38992 #? # dump _test-output-stream {{{
38994 #? (write-stream 2 _test-output-stream)
38996 #? (rewind-stream _test-output-stream)
38999 (check-next-stream-line-equal _test-output-stream "(f *(ebp+0xfffffff8))" "F - test-emit-subx-stmt-function-call")
39001 89/<- %esp 5/r32/ebp
39005 test-emit-subx-stmt-function-call-with-literal-arg:
39006 # Call a function on a literal.
39013 89/<- %ebp 4/r32/esp
39015 (clear-stream _test-output-stream)
39016 (clear-stream $_test-output-buffered-file->buffer)
39017 $test-emit-subx-function-call-with-literal-arg:initialize-type:
39018 # var type/ecx: (payload type-tree) = int
39019 68/push 0/imm32/right:null
39020 68/push 0/imm32/right:null
39021 68/push 0/imm32/left:unused
39022 68/push 0/imm32/value:literal
39023 68/push 1/imm32/is-atom?:true
39024 68/push 0x11/imm32/alloc-id:fake:payload
39025 89/<- %ecx 4/r32/esp
39026 $test-emit-subx-function-call-with-literal-arg:initialize-var:
39027 # var var-foo/ecx: (payload var) = var(lit)
39028 68/push 0/imm32/no-register
39029 68/push 0/imm32/no-register
39030 68/push 0/imm32/no-stack-offset
39031 68/push 1/imm32/block-depth
39033 68/push 0x11/imm32/alloc-id:fake
39034 68/push 0/imm32/name
39035 68/push 0/imm32/name
39036 68/push 0x11/imm32/alloc-id:fake:payload
39037 89/<- %ecx 4/r32/esp
39038 $test-emit-subx-function-call-with-literal-arg:initialize-var-name:
39039 # var-foo->name = "0x34"
39040 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4
39041 (copy-array Heap "0x34" %eax)
39042 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-var:
39043 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo)
39044 68/push 0/imm32/is-deref:false
39045 68/push 0/imm32/next
39046 68/push 0/imm32/next
39047 51/push-ecx/var-foo
39048 68/push 0x11/imm32/alloc-id:fake
39049 68/push 0x11/imm32/alloc-id:fake:payload
39050 89/<- %ebx 4/r32/esp
39051 $test-emit-subx-function-call-with-literal-arg:initialize-stmt:
39052 # var stmt/esi: (addr statement)
39053 68/push 0/imm32/no-outputs
39054 68/push 0/imm32/no-outputs
39056 68/push 0x11/imm32/alloc-id:fake
39057 68/push 0/imm32/operation
39058 68/push 0/imm32/operation
39059 68/push 1/imm32/tag
39060 89/<- %esi 4/r32/esp
39061 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-operation:
39062 # stmt->operation = "f"
39063 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation
39064 (copy-array Heap "f" %eax)
39066 c7 0/subop/copy *Curr-block-depth 0/imm32
39067 (emit-subx-stmt _test-output-buffered-file %esi 0 %ebx 0 Stderr 0)
39068 (flush _test-output-buffered-file)
39069 #? # dump _test-output-stream {{{
39071 #? (write-stream 2 _test-output-stream)
39073 #? (rewind-stream _test-output-stream)
39076 (check-next-stream-line-equal _test-output-stream "(f 0x34)" "F - test-emit-subx-stmt-function-call-with-literal-arg")
39078 89/<- %esp 5/r32/ebp
39082 emit-indent: # out: (addr buffered-file), n: int
39085 89/<- %ebp 4/r32/esp
39088 # var i/eax: int = n
39089 8b/-> *(ebp+0xc) 0/r32/eax
39091 # if (i <= 0) break
39092 3d/compare-eax-with 0/imm32
39093 7e/jump-if-<= break/disp8
39094 (write-buffered *(ebp+8) " ")
39099 # . restore registers
39102 89/<- %esp 5/r32/ebp
39106 emit-subx-prologue: # out: (addr buffered-file)
39109 89/<- %ebp 4/r32/esp
39111 (write-buffered *(ebp+8) " # . prologue\n")
39112 (write-buffered *(ebp+8) " 55/push-ebp\n")
39113 (write-buffered *(ebp+8) " 89/<- %ebp 4/r32/esp\n")
39114 $emit-subx-prologue:end:
39116 89/<- %esp 5/r32/ebp
39120 emit-subx-epilogue: # out: (addr buffered-file)
39123 89/<- %ebp 4/r32/esp
39125 (write-buffered *(ebp+8) " # . epilogue\n")
39126 (write-buffered *(ebp+8) " 89/<- %esp 5/r32/ebp\n")
39127 (write-buffered *(ebp+8) " 5d/pop-to-ebp\n")
39128 (write-buffered *(ebp+8) " c3/return\n")
39129 $emit-subx-epilogue:end:
39131 89/<- %esp 5/r32/ebp