From cd07e9b22c969ec1c501f34698e25e9ccb765593 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 25 Jul 2020 15:11:08 -0700 Subject: 6673 --- html/apps/mu.subx.html | 40294 ++++++++++++++++++++++++----------------------- 1 file changed, 20874 insertions(+), 19420 deletions(-) (limited to 'html/apps/mu.subx.html') diff --git a/html/apps/mu.subx.html b/html/apps/mu.subx.html index f4a10378..ee5ea823 100644 --- a/html/apps/mu.subx.html +++ b/html/apps/mu.subx.html @@ -270,12847 +270,12787 @@ if ('onhashchange' in window) { 208 # subx-rm32: enum arg-location 209 # subx-r32: enum arg-location 210 # subx-imm32: enum arg-location - 211 # subx-disp32: enum arg-location - 212 # output-is-write-only: boolean - 213 # arg-location: enum - 214 # 0 means none - 215 # 1 means first inout - 216 # 2 means second inout - 217 # 3 means first output - 218 - 219 # == Translating a block - 220 # Emit block name if necessary - 221 # Emit '{' - 222 # When you encounter a statement, emit it as above - 223 # When you encounter a variable declaration - 224 # emit any code needed for it (bzeros) - 225 # push it on the var stack - 226 # update register dict if necessary - 227 # When you encounter '}' - 228 # While popping variables off the var stack until block id changes - 229 # Emit code needed to clean up the stack - 230 # either increment esp - 231 # or pop into appropriate register - 232 - 233 # The rest is straightforward. - 234 - 235 == data - 236 - 237 Program: - 238 _Program-functions: # (handle function) - 239 0/imm32 - 240 _Program-functions->payload: - 241 0/imm32 - 242 _Program-types: # (handle typeinfo) - 243 0/imm32 - 244 _Program-types->payload: - 245 0/imm32 - 246 _Program-signatures: # (handle function) - 247 0/imm32 - 248 _Program-signatures->payload: - 249 0/imm32 - 250 - 251 # Some constants for simulating the data structures described above. - 252 # Many constants here come with a type in a comment. - 253 # - 254 # Sometimes the type is of the value at that offset for the given type. For - 255 # example, if you start at a function record and move forward Function-inouts - 256 # bytes, you'll find a (handle list var). - 257 # - 258 # At other times, the type is of the constant itself. For example, the type of - 259 # the constant Function-size is (addr int). To get the size of a function, - 260 # look in *Function-size. - 261 - 262 Function-name: # (handle array byte) - 263 0/imm32 - 264 Function-inouts: # (handle list var) - 265 8/imm32 - 266 Function-outputs: # (handle list var) - 267 0x10/imm32 - 268 Function-body: # (handle block) - 269 0x18/imm32 - 270 Function-next: # (handle function) - 271 0x20/imm32 - 272 Function-size: # (addr int) - 273 0x28/imm32/40 - 274 - 275 Primitive-name: # (handle array byte) - 276 0/imm32 - 277 Primitive-inouts: # (handle list var) - 278 8/imm32 - 279 Primitive-outputs: # (handle list var) - 280 0x10/imm32 - 281 Primitive-subx-name: # (handle array byte) - 282 0x18/imm32 - 283 Primitive-subx-rm32: # enum arg-location - 284 0x20/imm32 - 285 Primitive-subx-r32: # enum arg-location - 286 0x24/imm32 - 287 Primitive-subx-imm32: # enum arg-location - 288 0x28/imm32 - 289 Primitive-subx-disp32: # enum arg-location -- only for branches - 290 0x2c/imm32 - 291 Primitive-output-is-write-only: # boolean - 292 0x30/imm32 - 293 Primitive-next: # (handle function) - 294 0x34/imm32 - 295 Primitive-size: # (addr int) - 296 0x3c/imm32/60 - 297 - 298 Stmt-tag: # int - 299 0/imm32 + 211 # subx-imm8: enum arg-location + 212 # subx-disp32: enum arg-location + 213 # output-is-write-only: boolean + 214 # arg-location: enum + 215 # 0 means none + 216 # 1 means first inout + 217 # 2 means second inout + 218 # 3 means first output + 219 + 220 # == Translating a block + 221 # Emit block name if necessary + 222 # Emit '{' + 223 # When you encounter a statement, emit it as above + 224 # When you encounter a variable declaration + 225 # emit any code needed for it (bzeros) + 226 # push it on the var stack + 227 # update register dict if necessary + 228 # When you encounter '}' + 229 # While popping variables off the var stack until block id changes + 230 # Emit code needed to clean up the stack + 231 # either increment esp + 232 # or pop into appropriate register + 233 + 234 # The rest is straightforward. + 235 + 236 == data + 237 + 238 Program: + 239 _Program-functions: # (handle function) + 240 0/imm32 + 241 _Program-functions->payload: + 242 0/imm32 + 243 _Program-types: # (handle typeinfo) + 244 0/imm32 + 245 _Program-types->payload: + 246 0/imm32 + 247 _Program-signatures: # (handle function) + 248 0/imm32 + 249 _Program-signatures->payload: + 250 0/imm32 + 251 + 252 # Some constants for simulating the data structures described above. + 253 # Many constants here come with a type in a comment. + 254 # + 255 # Sometimes the type is of the value at that offset for the given type. For + 256 # example, if you start at a function record and move forward Function-inouts + 257 # bytes, you'll find a (handle list var). + 258 # + 259 # At other times, the type is of the constant itself. For example, the type of + 260 # the constant Function-size is (addr int). To get the size of a function, + 261 # look in *Function-size. + 262 + 263 Function-name: # (handle array byte) + 264 0/imm32 + 265 Function-inouts: # (handle list var) + 266 8/imm32 + 267 Function-outputs: # (handle list var) + 268 0x10/imm32 + 269 Function-body: # (handle block) + 270 0x18/imm32 + 271 Function-next: # (handle function) + 272 0x20/imm32 + 273 Function-size: # (addr int) + 274 0x28/imm32/40 + 275 + 276 Primitive-name: # (handle array byte) + 277 0/imm32 + 278 Primitive-inouts: # (handle list var) + 279 8/imm32 + 280 Primitive-outputs: # (handle list var) + 281 0x10/imm32 + 282 Primitive-subx-name: # (handle array byte) + 283 0x18/imm32 + 284 Primitive-subx-rm32: # enum arg-location + 285 0x20/imm32 + 286 Primitive-subx-r32: # enum arg-location + 287 0x24/imm32 + 288 Primitive-subx-imm32: # enum arg-location + 289 0x28/imm32 + 290 Primitive-subx-imm8: # enum arg-location -- only for bit shifts + 291 0x2c/imm32 + 292 Primitive-subx-disp32: # enum arg-location -- only for branches + 293 0x30/imm32 + 294 Primitive-output-is-write-only: # boolean + 295 0x34/imm32 + 296 Primitive-next: # (handle function) + 297 0x38/imm32 + 298 Primitive-size: # (addr int) + 299 0x40/imm32/60 300 - 301 Block-stmts: # (handle list stmt) - 302 4/imm32 - 303 Block-var: # (handle var) - 304 0xc/imm32 - 305 - 306 Stmt1-operation: # (handle array byte) - 307 4/imm32 - 308 Stmt1-inouts: # (handle stmt-var) - 309 0xc/imm32 - 310 Stmt1-outputs: # (handle stmt-var) - 311 0x14/imm32 - 312 - 313 Vardef-var: # (handle var) - 314 4/imm32 + 301 Stmt-tag: # int + 302 0/imm32 + 303 + 304 Block-stmts: # (handle list stmt) + 305 4/imm32 + 306 Block-var: # (handle var) + 307 0xc/imm32 + 308 + 309 Stmt1-operation: # (handle array byte) + 310 4/imm32 + 311 Stmt1-inouts: # (handle stmt-var) + 312 0xc/imm32 + 313 Stmt1-outputs: # (handle stmt-var) + 314 0x14/imm32 315 - 316 Regvardef-operation: # (handle array byte) + 316 Vardef-var: # (handle var) 317 4/imm32 - 318 Regvardef-inouts: # (handle stmt-var) - 319 0xc/imm32 - 320 Regvardef-outputs: # (handle stmt-var) # will have exactly one element - 321 0x14/imm32 - 322 - 323 Stmt-size: # (addr int) - 324 0x1c/imm32 + 318 + 319 Regvardef-operation: # (handle array byte) + 320 4/imm32 + 321 Regvardef-inouts: # (handle stmt-var) + 322 0xc/imm32 + 323 Regvardef-outputs: # (handle stmt-var) # will have exactly one element + 324 0x14/imm32 325 - 326 Var-name: # (handle array byte) - 327 0/imm32 - 328 Var-type: # (handle type-tree) - 329 8/imm32 - 330 Var-block-depth: # int -- not available until code-generation time - 331 0x10/imm32 - 332 Var-offset: # int -- not available until code-generation time - 333 0x14/imm32 - 334 Var-register: # (handle array byte) -- name of a register - 335 0x18/imm32 - 336 Var-size: # (addr int) - 337 0x20/imm32 - 338 - 339 List-value: # (handle _) - 340 0/imm32 - 341 List-next: # (handle list _) - 342 8/imm32 - 343 List-size: # (addr int) - 344 0x10/imm32 - 345 - 346 # A stmt-var is like a list of vars with call-site specific metadata - 347 Stmt-var-value: # (handle var) - 348 0/imm32 - 349 Stmt-var-next: # (handle stmt-var) - 350 8/imm32 - 351 Stmt-var-is-deref: # boolean - 352 0x10/imm32 - 353 Stmt-var-size: # (addr int) - 354 0x14/imm32 - 355 - 356 # A live-var is a var augmented with information needed for tracking live - 357 # variables. - 358 Live-var-value: # (handle var) - 359 0/imm32 - 360 Live-var-register-spilled: # boolean; only used if value is in a register, and only during code-gen - 361 8/imm32 - 362 Live-var-size: # (addr int) - 363 0xc/imm32 - 364 - 365 # Types are expressed as trees (s-expressions) of type-ids (ints). - 366 - 367 Type-tree-is-atom: # boolean - 368 0/imm32 - 369 # if left-is-atom? - 370 Type-tree-value: # type-id - 371 4/imm32 - 372 Type-tree-value-size: # int (for static data structure sizes) - 373 8/imm32 - 374 # unless left-is-atom? - 375 Type-tree-left: # (addr type-tree) - 376 4/imm32 - 377 Type-tree-right: # (addr type-tree) - 378 0xc/imm32 - 379 # - 380 Type-tree-size: # (addr int) - 381 0x14/imm32 - 382 - 383 # Types - 384 - 385 # TODO: Turn this data structure into valid Mu, with (fake) handles rather than addrs. - 386 Type-id: # (stream (addr array byte)) - 387 0/imm32/write # initialized later from Primitive-type-ids - 388 0/imm32/read - 389 0x100/imm32/size - 390 # data - 391 "literal"/imm32 # 0: value is just the name - 392 "int"/imm32 # 1 - 393 "addr"/imm32 # 2 - 394 "array"/imm32 # 3 - 395 "handle"/imm32 # 4 - 396 "boolean"/imm32 # 5 - 397 "constant"/imm32 # 6: like a literal, but value is an int in Var-offset - 398 "offset"/imm32 # 7: (offset T) is guaranteed to be a 32-bit multiple of size-of(T) - 399 # 0x20 - 400 "byte"/imm32 # 8 - 401 0/imm32 # 9 reserved for array-capacity; value is in Type-tree-size - 402 # Not to be used directly, so we don't include a name here. - 403 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 404 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 405 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 406 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 407 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 408 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 409 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 - 410 - 411 Primitive-type-ids: # (addr int) - 412 0x24 - 413 - 414 # == Type definitions - 415 # Program->types contains some typeinfo for each type definition. - 416 # Types contain vars with types, but can't specify registers. - 417 Typeinfo-id: # type-id - 418 0/imm32 - 419 Typeinfo-fields: # (handle table (handle array byte) (handle typeinfo-entry)) - 420 4/imm32 - 421 # Total size must be >= 0 - 422 # During parsing it may take on two additional values: - 423 # -2: not yet initialized - 424 # -1: in process of being computed - 425 # See populate-mu-type-sizes for details. - 426 Typeinfo-total-size-in-bytes: # int - 427 0xc/imm32 - 428 Typeinfo-next: # (handle typeinfo) - 429 0x10/imm32 - 430 Typeinfo-size: # (addr int) - 431 0x18/imm32 - 432 - 433 # Each entry in the typeinfo->fields table has a pointer to a string and a - 434 # pointer to a typeinfo-entry. - 435 Typeinfo-fields-row-size: # (addr int) - 436 0x10/imm32 - 437 - 438 # typeinfo-entry objects have information about a field in a single record type - 439 # - 440 # each field of a type is represented using two var's: - 441 # 1. the input var: expected type of the field; convenient for creating using parse-var-with-type - 442 # 2. the output var: a constant containing the byte offset; convenient for code-generation - 443 # computing the output happens after parsing; in the meantime we preserve the - 444 # order of fields in the 'index' field. - 445 Typeinfo-entry-input-var: # (handle var) - 446 0/imm32 - 447 Typeinfo-entry-index: # int - 448 8/imm32 - 449 Typeinfo-entry-output-var: # (handle var) - 450 0xc/imm32 - 451 Typeinfo-entry-size: # (addr int) - 452 0x14/imm32 - 453 - 454 == code - 455 - 456 Entry: - 457 # . prologue - 458 89/<- %ebp 4/r32/esp - 459 (new-segment *Heap-size Heap) - 460 # if (argv[1] == "test') run-tests() - 461 { - 462 # if (argc <= 1) break - 463 81 7/subop/compare *ebp 1/imm32 - 464 7e/jump-if-<= break/disp8 - 465 # if (argv[1] != "test") break - 466 (kernel-string-equal? *(ebp+8) "test") # => eax - 467 3d/compare-eax-and 0/imm32/false - 468 74/jump-if-= break/disp8 - 469 # - 470 (run-tests) - 471 # syscall(exit, *Num-test-failures) - 472 8b/-> *Num-test-failures 3/r32/ebx - 473 eb/jump $mu-main:end/disp8 - 474 } - 475 # otherwise convert Stdin - 476 (convert-mu Stdin Stdout Stderr 0) - 477 (flush Stdout) - 478 # syscall(exit, 0) - 479 bb/copy-to-ebx 0/imm32 - 480 $mu-main:end: - 481 e8/call syscall_exit/disp32 - 482 - 483 convert-mu: # in: (addr buffered-file), out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) - 484 # . prologue - 485 55/push-ebp - 486 89/<- %ebp 4/r32/esp - 487 # . save registers - 488 50/push-eax - 489 # initialize global data structures - 490 c7 0/subop/copy *Next-block-index 1/imm32 - 491 8b/-> *Primitive-type-ids 0/r32/eax - 492 89/<- *Type-id 0/r32/eax # stream-write - 493 c7 0/subop/copy *_Program-functions 0/imm32 - 494 c7 0/subop/copy *_Program-functions->payload 0/imm32 - 495 c7 0/subop/copy *_Program-types 0/imm32 - 496 c7 0/subop/copy *_Program-types->payload 0/imm32 - 497 # - 498 (parse-mu *(ebp+8) *(ebp+0x10) *(ebp+0x14)) - 499 (populate-mu-type-sizes *(ebp+0x10) *(ebp+0x14)) - 500 #? (dump-typeinfos "=== typeinfos\n") - 501 (check-mu-types *(ebp+0x10) *(ebp+0x14)) - 502 (emit-subx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) - 503 $convert-mu:end: - 504 # . restore registers - 505 58/pop-to-eax - 506 # . epilogue - 507 89/<- %esp 5/r32/ebp - 508 5d/pop-to-ebp - 509 c3/return - 510 - 511 test-convert-empty-input: - 512 # empty input => empty output - 513 # . prologue - 514 55/push-ebp - 515 89/<- %ebp 4/r32/esp - 516 # setup - 517 (clear-stream _test-input-stream) - 518 (clear-stream $_test-input-buffered-file->buffer) - 519 (clear-stream _test-output-stream) - 520 (clear-stream $_test-output-buffered-file->buffer) - 521 # - 522 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 523 (flush _test-output-buffered-file) - 524 (check-stream-equal _test-output-stream "" "F - test-convert-empty-input") - 525 # . epilogue - 526 89/<- %esp 5/r32/ebp - 527 5d/pop-to-ebp - 528 c3/return - 529 - 530 test-convert-function-skeleton: - 531 # . prologue - 532 55/push-ebp - 533 89/<- %ebp 4/r32/esp - 534 # setup - 535 (clear-stream _test-input-stream) - 536 (clear-stream $_test-input-buffered-file->buffer) - 537 (clear-stream _test-output-stream) - 538 (clear-stream $_test-output-buffered-file->buffer) - 539 # - 540 (write _test-input-stream "fn foo {\n") - 541 (write _test-input-stream "}\n") - 542 # convert - 543 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 544 (flush _test-output-buffered-file) - 545 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 551 # check output - 552 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0") - 553 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-skeleton/1") - 554 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-skeleton/2") - 555 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3") - 556 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-skeleton/4") - 557 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5") - 558 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-skeleton/6") - 559 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-skeleton/7") - 560 # . epilogue - 561 89/<- %esp 5/r32/ebp - 562 5d/pop-to-ebp - 563 c3/return - 564 - 565 test-convert-multiple-function-skeletons: - 566 # . prologue - 567 55/push-ebp - 568 89/<- %ebp 4/r32/esp - 569 # setup - 570 (clear-stream _test-input-stream) - 571 (clear-stream $_test-input-buffered-file->buffer) - 572 (clear-stream _test-output-stream) - 573 (clear-stream $_test-output-buffered-file->buffer) - 574 # - 575 (write _test-input-stream "fn foo {\n") - 576 (write _test-input-stream "}\n") - 577 (write _test-input-stream "fn bar {\n") - 578 (write _test-input-stream "}\n") - 579 # convert - 580 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 581 (flush _test-output-buffered-file) - 582 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 588 # check first function - 589 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-multiple-function-skeletons/0") - 590 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/1") - 591 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/2") - 592 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/3") - 593 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/4") - 594 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/5") - 595 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/6") - 596 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/7") - 597 # check second function - 598 (check-next-stream-line-equal _test-output-stream "bar:" "F - test-convert-multiple-function-skeletons/10") - 599 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/11") - 600 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/12") - 601 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/13") - 602 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/14") - 603 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/15") - 604 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/16") - 605 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/17") - 606 # . epilogue - 607 89/<- %esp 5/r32/ebp - 608 5d/pop-to-ebp - 609 c3/return - 610 - 611 test-convert-function-with-arg: - 612 # . prologue - 613 55/push-ebp - 614 89/<- %ebp 4/r32/esp - 615 # setup - 616 (clear-stream _test-input-stream) - 617 (clear-stream $_test-input-buffered-file->buffer) - 618 (clear-stream _test-output-stream) - 619 (clear-stream $_test-output-buffered-file->buffer) - 620 # - 621 (write _test-input-stream "fn foo n: int {\n") - 622 (write _test-input-stream "}\n") - 623 # convert - 624 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 625 (flush _test-output-buffered-file) - 626 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 632 # check output - 633 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg/0") - 634 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg/1") - 635 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg/2") - 636 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg/3") - 637 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg/4") - 638 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg/5") - 639 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg/6") - 640 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg/7") - 641 # . epilogue - 642 89/<- %esp 5/r32/ebp - 643 5d/pop-to-ebp - 644 c3/return - 645 - 646 test-convert-function-with-arg-and-body: - 647 # . prologue - 648 55/push-ebp - 649 89/<- %ebp 4/r32/esp - 650 # setup - 651 (clear-stream _test-input-stream) - 652 (clear-stream $_test-input-buffered-file->buffer) - 653 (clear-stream _test-output-stream) - 654 (clear-stream $_test-output-buffered-file->buffer) - 655 # - 656 (write _test-input-stream "fn foo n: int {\n") - 657 (write _test-input-stream " increment n\n") - 658 (write _test-input-stream "}\n") - 659 # convert - 660 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 661 (flush _test-output-buffered-file) - 662 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 668 # check output - 669 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg-and-body/0") - 670 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg-and-body/1") - 671 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg-and-body/2") - 672 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg-and-body/3") - 673 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-arg-and-body/4") - 674 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-arg-and-body/5") - 675 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-arg-and-body/6") - 676 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-arg-and-body/7") - 677 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-arg-and-body/8") - 678 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg-and-body/9") - 679 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg-and-body/10") - 680 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg-and-body/11") - 681 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg-and-body/12") - 682 # . epilogue - 683 89/<- %esp 5/r32/ebp - 684 5d/pop-to-ebp - 685 c3/return - 686 - 687 test-convert-function-distinguishes-args: - 688 # . prologue - 689 55/push-ebp - 690 89/<- %ebp 4/r32/esp - 691 # setup - 692 (clear-stream _test-input-stream) - 693 (clear-stream $_test-input-buffered-file->buffer) - 694 (clear-stream _test-output-stream) - 695 (clear-stream $_test-output-buffered-file->buffer) - 696 # - 697 (write _test-input-stream "fn foo a: int, b: int {\n") - 698 (write _test-input-stream " increment b\n") - 699 (write _test-input-stream "}\n") - 700 # convert - 701 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 702 (flush _test-output-buffered-file) - 703 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 709 # check output - 710 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-distinguishes-args/0") - 711 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-distinguishes-args/1") - 712 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-distinguishes-args/2") - 713 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-distinguishes-args/3") - 714 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-distinguishes-args/4") - 715 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-distinguishes-args/5") - 716 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x0000000c)" "F - test-convert-function-distinguishes-args/6") - 717 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-distinguishes-args/7") - 718 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-distinguishes-args/8") - 719 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-distinguishes-args/9") - 720 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-distinguishes-args/10") - 721 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-distinguishes-args/11") - 722 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-distinguishes-args/12") - 723 # . epilogue - 724 89/<- %esp 5/r32/ebp - 725 5d/pop-to-ebp - 726 c3/return - 727 - 728 test-convert-function-returns-result: - 729 # . prologue - 730 55/push-ebp - 731 89/<- %ebp 4/r32/esp - 732 # setup - 733 (clear-stream _test-input-stream) - 734 (clear-stream $_test-input-buffered-file->buffer) - 735 (clear-stream _test-output-stream) - 736 (clear-stream $_test-output-buffered-file->buffer) - 737 # - 738 (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n") - 739 (write _test-input-stream " result <- copy a\n") - 740 (write _test-input-stream " result <- increment\n") - 741 (write _test-input-stream "}\n") - 742 # convert - 743 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 744 (flush _test-output-buffered-file) - 745 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 751 # check output - 752 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-returns-result/0") - 753 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-returns-result/1") - 754 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-returns-result/2") - 755 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-returns-result/3") - 756 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-returns-result/4") - 757 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-returns-result/5") - 758 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-returns-result/6") - 759 (check-next-stream-line-equal _test-output-stream " 40/increment-eax" "F - test-convert-function-returns-result/7") - 760 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-returns-result/8") - 761 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-returns-result/9") - 762 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-returns-result/10") - 763 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-returns-result/11") - 764 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-returns-result/12") - 765 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-returns-result/13") - 766 # . epilogue - 767 89/<- %esp 5/r32/ebp - 768 5d/pop-to-ebp - 769 c3/return - 770 - 771 test-convert-function-with-literal-arg: - 772 # . prologue - 773 55/push-ebp - 774 89/<- %ebp 4/r32/esp - 775 # setup - 776 (clear-stream _test-input-stream) - 777 (clear-stream $_test-input-buffered-file->buffer) - 778 (clear-stream _test-output-stream) - 779 (clear-stream $_test-output-buffered-file->buffer) - 780 # - 781 (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n") - 782 (write _test-input-stream " result <- copy a\n") - 783 (write _test-input-stream " result <- add 1\n") - 784 (write _test-input-stream "}\n") - 785 # convert - 786 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 787 (flush _test-output-buffered-file) - 788 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 794 # check output - 795 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg/0") - 796 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg/1") - 797 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg/2") - 798 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg/3") - 799 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg/4") - 800 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg/5") - 801 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-with-literal-arg/6") - 802 (check-next-stream-line-equal _test-output-stream " 05/add-to-eax 1/imm32" "F - test-convert-function-with-literal-arg/7") - 803 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg/8") - 804 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg/9") - 805 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg/10") - 806 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg/11") - 807 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg/12") - 808 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg/13") - 809 # . epilogue - 810 89/<- %esp 5/r32/ebp - 811 5d/pop-to-ebp - 812 c3/return - 813 - 814 test-convert-function-with-literal-arg-2: - 815 # . prologue - 816 55/push-ebp - 817 89/<- %ebp 4/r32/esp - 818 # setup - 819 (clear-stream _test-input-stream) - 820 (clear-stream $_test-input-buffered-file->buffer) - 821 (clear-stream _test-output-stream) - 822 (clear-stream $_test-output-buffered-file->buffer) - 823 # - 824 (write _test-input-stream "fn foo a: int, b: int -> result/ebx: int {\n") - 825 (write _test-input-stream " result <- copy a\n") - 826 (write _test-input-stream " result <- add 1\n") - 827 (write _test-input-stream "}\n") - 828 # convert - 829 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 830 (flush _test-output-buffered-file) - 831 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 837 # check output - 838 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg-2/0") - 839 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg-2/1") - 840 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg-2/2") - 841 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg-2/3") - 842 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg-2/4") - 843 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg-2/5") - 844 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/6") - 845 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %ebx 1/imm32" "F - test-convert-function-with-literal-arg-2/7") - 846 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg-2/8") - 847 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg-2/9") - 848 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg-2/10") - 849 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg-2/11") - 850 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg-2/12") - 851 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg-2/13") - 852 # . epilogue - 853 89/<- %esp 5/r32/ebp - 854 5d/pop-to-ebp - 855 c3/return - 856 - 857 test-convert-function-call-with-literal-arg: - 858 # . prologue - 859 55/push-ebp - 860 89/<- %ebp 4/r32/esp - 861 # setup - 862 (clear-stream _test-input-stream) - 863 (clear-stream $_test-input-buffered-file->buffer) - 864 (clear-stream _test-output-stream) - 865 (clear-stream $_test-output-buffered-file->buffer) - 866 # - 867 (write _test-input-stream "fn main -> result/ebx: int {\n") - 868 (write _test-input-stream " result <- do-add 3 4\n") - 869 (write _test-input-stream "}\n") - 870 (write _test-input-stream "fn do-add a: int, b: int -> result/ebx: int {\n") - 871 (write _test-input-stream " result <- copy a\n") - 872 (write _test-input-stream " result <- add b\n") - 873 (write _test-input-stream "}\n") - 874 # convert - 875 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 876 (flush _test-output-buffered-file) - 877 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 883 # check output - 884 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-literal-arg/0") - 885 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/1") - 886 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/2") - 887 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/3") - 888 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/4") - 889 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-literal-arg/5") - 890 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-literal-arg/6") - 891 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/7") - 892 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-literal-arg/8") - 893 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/9") - 894 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/10") - 895 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/11") - 896 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/12") - 897 (check-next-stream-line-equal _test-output-stream "do-add:" "F - test-convert-function-call-with-literal-arg/13") - 898 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/14") - 899 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/15") - 900 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/16") - 901 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/17") - 902 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:loop:" "F - test-convert-function-call-with-literal-arg/18") - 903 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/19") - 904 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0x0000000c) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/20") - 905 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/21") - 906 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:break:" "F - test-convert-function-call-with-literal-arg/22") - 907 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/23") - 908 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/24") - 909 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/25") - 910 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/26") - 911 # . epilogue - 912 89/<- %esp 5/r32/ebp - 913 5d/pop-to-ebp - 914 c3/return - 915 - 916 test-convert-function-call-with-signature: - 917 # . prologue - 918 55/push-ebp - 919 89/<- %ebp 4/r32/esp - 920 # setup - 921 (clear-stream _test-input-stream) - 922 (clear-stream $_test-input-buffered-file->buffer) - 923 (clear-stream _test-output-stream) - 924 (clear-stream $_test-output-buffered-file->buffer) - 925 # - 926 (write _test-input-stream "fn main -> result/ebx: int {\n") - 927 (write _test-input-stream " result <- do-add 3 4\n") - 928 (write _test-input-stream "}\n") - 929 (write _test-input-stream "sig do-add a: int, b: int -> result/ebx: int\n") - 930 # convert - 931 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 932 (flush _test-output-buffered-file) - 933 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 939 # check output - 940 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-signature/0") - 941 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-signature/1") - 942 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-signature/2") - 943 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-signature/3") - 944 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-signature/4") - 945 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-signature/5") - 946 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-signature/6") - 947 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-signature/7") - 948 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-signature/8") - 949 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-signature/9") - 950 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-signature/10") - 951 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-signature/11") - 952 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-signature/12") - 953 # . epilogue - 954 89/<- %esp 5/r32/ebp - 955 5d/pop-to-ebp - 956 c3/return - 957 - 958 test-convert-function-with-local-var-in-mem: - 959 # . prologue - 960 55/push-ebp - 961 89/<- %ebp 4/r32/esp - 962 # setup - 963 (clear-stream _test-input-stream) - 964 (clear-stream $_test-input-buffered-file->buffer) - 965 (clear-stream _test-output-stream) - 966 (clear-stream $_test-output-buffered-file->buffer) - 967 # - 968 (write _test-input-stream "fn foo {\n") - 969 (write _test-input-stream " var x: int\n") - 970 (write _test-input-stream " increment x\n") - 971 (write _test-input-stream "}\n") - 972 # convert - 973 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 974 (flush _test-output-buffered-file) - 975 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 981 # check output - 982 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-mem/0") - 983 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-mem/1") - 984 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-mem/2") - 985 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-mem/3") - 986 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem/4") - 987 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-mem/5") - 988 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem/6") - 989 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-mem/7") - 990 (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") - 991 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem/9") - 992 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-mem/10") - 993 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-mem/11") - 994 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-mem/12") - 995 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-mem/13") - 996 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-mem/14") - 997 # . epilogue - 998 89/<- %esp 5/r32/ebp - 999 5d/pop-to-ebp - 1000 c3/return - 1001 - 1002 test-local-var-in-mem-has-no-initializer: - 1003 # . prologue - 1004 55/push-ebp - 1005 89/<- %ebp 4/r32/esp - 1006 # setup - 1007 (clear-stream _test-input-stream) - 1008 (clear-stream $_test-input-buffered-file->buffer) - 1009 (clear-stream _test-output-stream) - 1010 (clear-stream $_test-output-buffered-file->buffer) - 1011 (clear-stream _test-error-stream) - 1012 (clear-stream $_test-error-buffered-file->buffer) - 1013 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1014 68/push 0/imm32 - 1015 68/push 0/imm32 - 1016 89/<- %edx 4/r32/esp - 1017 (tailor-exit-descriptor %edx 0x10) - 1018 # - 1019 (write _test-input-stream "fn foo {\n") - 1020 (write _test-input-stream " var x: int <- copy 0\n") - 1021 (write _test-input-stream " increment x\n") - 1022 (write _test-input-stream "}\n") - 1023 # convert - 1024 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1025 # registers except esp clobbered at this point - 1026 # restore ed - 1027 89/<- %edx 4/r32/esp - 1028 (flush _test-output-buffered-file) - 1029 (flush _test-error-buffered-file) - 1030 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1036 # check output - 1037 (check-stream-equal _test-output-stream "" "F - test-var-in-mem-has-no-initializer: output should be empty") - 1038 (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") - 1039 # check that stop(1) was called - 1040 (check-ints-equal *(edx+4) 2 "F - test-var-in-mem-has-no-initializer: exit status") - 1041 # don't restore from ebp - 1042 81 0/subop/add %esp 8/imm32 - 1043 # . epilogue - 1044 5d/pop-to-ebp - 1045 c3/return - 1046 - 1047 test-convert-function-with-local-var-with-compound-type-in-mem: - 1048 # . prologue - 1049 55/push-ebp - 1050 89/<- %ebp 4/r32/esp - 1051 # setup - 1052 (clear-stream _test-input-stream) - 1053 (clear-stream $_test-input-buffered-file->buffer) - 1054 (clear-stream _test-output-stream) - 1055 (clear-stream $_test-output-buffered-file->buffer) - 1056 # - 1057 (write _test-input-stream "fn foo {\n") - 1058 (write _test-input-stream " var x: (addr int)\n") - 1059 (write _test-input-stream " copy-to x, 0\n") - 1060 (write _test-input-stream "}\n") - 1061 # convert - 1062 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1063 (flush _test-output-buffered-file) - 1064 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1070 # check output - 1071 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/0") - 1072 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/1") - 1073 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/2") - 1074 (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") - 1075 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-compound-type-in-mem/4") - 1076 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/5") - 1077 (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") - 1078 (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") - 1079 (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") - 1080 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-compound-type-in-mem/9") - 1081 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/10") - 1082 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/11") - 1083 (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") - 1084 (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") - 1085 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-compound-type-in-mem/14") - 1086 # . epilogue - 1087 89/<- %esp 5/r32/ebp - 1088 5d/pop-to-ebp - 1089 c3/return - 1090 - 1091 test-convert-function-with-local-var-in-reg: - 1092 # . prologue - 1093 55/push-ebp - 1094 89/<- %ebp 4/r32/esp - 1095 # setup - 1096 (clear-stream _test-input-stream) - 1097 (clear-stream $_test-input-buffered-file->buffer) - 1098 (clear-stream _test-output-stream) - 1099 (clear-stream $_test-output-buffered-file->buffer) - 1100 # - 1101 (write _test-input-stream "fn foo {\n") - 1102 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1103 (write _test-input-stream " x <- increment\n") - 1104 (write _test-input-stream "}\n") - 1105 # convert - 1106 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1107 (flush _test-output-buffered-file) - 1108 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1114 # check output - 1115 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-reg/0") - 1116 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-reg/1") - 1117 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-reg/2") - 1118 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-reg/3") - 1119 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-reg/4") - 1120 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-reg/5") - 1121 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-reg/6") - 1122 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-local-var-in-reg/7") - 1123 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-local-var-in-reg/8") - 1124 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-reg/9") - 1125 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-reg/10") - 1126 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-reg/11") - 1127 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-reg/12") - 1128 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-reg/13") - 1129 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-reg/14") - 1130 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-reg/15") - 1131 # . epilogue - 1132 89/<- %esp 5/r32/ebp - 1133 5d/pop-to-ebp - 1134 c3/return - 1135 - 1136 test-convert-function-with-second-local-var-in-same-reg: - 1137 # . prologue - 1138 55/push-ebp - 1139 89/<- %ebp 4/r32/esp - 1140 # setup - 1141 (clear-stream _test-input-stream) - 1142 (clear-stream $_test-input-buffered-file->buffer) - 1143 (clear-stream _test-output-stream) - 1144 (clear-stream $_test-output-buffered-file->buffer) - 1145 # - 1146 (write _test-input-stream "fn foo {\n") - 1147 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1148 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 1149 (write _test-input-stream " y <- increment\n") - 1150 (write _test-input-stream "}\n") - 1151 # convert - 1152 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1153 (flush _test-output-buffered-file) - 1154 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1160 # check output - 1161 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-second-local-var-in-same-reg/0") - 1162 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-second-local-var-in-same-reg/1") - 1163 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/2") - 1164 (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") - 1165 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-second-local-var-in-same-reg/4") - 1166 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-second-local-var-in-same-reg/5") - 1167 (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") - 1168 (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") - 1169 (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") - 1170 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-second-local-var-in-same-reg/9") - 1171 (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") - 1172 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-second-local-var-in-same-reg/11") - 1173 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-second-local-var-in-same-reg/12") - 1174 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-second-local-var-in-same-reg/13") - 1175 (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") - 1176 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/15") - 1177 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-second-local-var-in-same-reg/16") - 1178 # . epilogue - 1179 89/<- %esp 5/r32/ebp - 1180 5d/pop-to-ebp - 1181 c3/return - 1182 - 1183 test-read-clobbered-reg-var: - 1184 # . prologue - 1185 55/push-ebp - 1186 89/<- %ebp 4/r32/esp - 1187 # setup - 1188 (clear-stream _test-input-stream) - 1189 (clear-stream $_test-input-buffered-file->buffer) - 1190 (clear-stream _test-output-stream) - 1191 (clear-stream $_test-output-buffered-file->buffer) - 1192 (clear-stream _test-error-stream) - 1193 (clear-stream $_test-error-buffered-file->buffer) - 1194 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu - 1195 68/push 0/imm32 - 1196 68/push 0/imm32 - 1197 89/<- %edx 4/r32/esp - 1198 (tailor-exit-descriptor %edx 0x10) + 326 Stmt-size: # (addr int) + 327 0x1c/imm32 + 328 + 329 Var-name: # (handle array byte) + 330 0/imm32 + 331 Var-type: # (handle type-tree) + 332 8/imm32 + 333 Var-block-depth: # int -- not available until code-generation time + 334 0x10/imm32 + 335 Var-offset: # int -- not available until code-generation time + 336 0x14/imm32 + 337 Var-register: # (handle array byte) -- name of a register + 338 0x18/imm32 + 339 Var-size: # (addr int) + 340 0x20/imm32 + 341 + 342 List-value: # (handle _) + 343 0/imm32 + 344 List-next: # (handle list _) + 345 8/imm32 + 346 List-size: # (addr int) + 347 0x10/imm32 + 348 + 349 # A stmt-var is like a list of vars with call-site specific metadata + 350 Stmt-var-value: # (handle var) + 351 0/imm32 + 352 Stmt-var-next: # (handle stmt-var) + 353 8/imm32 + 354 Stmt-var-is-deref: # boolean + 355 0x10/imm32 + 356 Stmt-var-size: # (addr int) + 357 0x14/imm32 + 358 + 359 # A live-var is a var augmented with information needed for tracking live + 360 # variables. + 361 Live-var-value: # (handle var) + 362 0/imm32 + 363 Live-var-register-spilled: # boolean; only used if value is in a register, and only during code-gen + 364 8/imm32 + 365 Live-var-size: # (addr int) + 366 0xc/imm32 + 367 + 368 # Types are expressed as trees (s-expressions) of type-ids (ints). + 369 + 370 Type-tree-is-atom: # boolean + 371 0/imm32 + 372 # if is-atom? + 373 Type-tree-value: # type-id + 374 4/imm32 + 375 Type-tree-value-size: # int (for static data structure sizes) + 376 8/imm32 + 377 Type-tree-parameter-name: # (handle array byte) for type parameters + 378 8/imm32 + 379 # unless is-atom? + 380 Type-tree-left: # (addr type-tree) + 381 4/imm32 + 382 Type-tree-right: # (addr type-tree) + 383 0xc/imm32 + 384 # + 385 Type-tree-size: # (addr int) + 386 0x14/imm32 + 387 + 388 # Types + 389 + 390 # TODO: Turn this data structure into valid Mu, with (fake) handles rather than addrs. + 391 Type-id: # (stream (addr array byte)) + 392 0/imm32/write # initialized later from Primitive-type-ids + 393 0/imm32/read + 394 0x100/imm32/size + 395 # data + 396 "literal"/imm32 # 0: value is just the name + 397 "int"/imm32 # 1 + 398 "addr"/imm32 # 2 + 399 "array"/imm32 # 3 + 400 "handle"/imm32 # 4 + 401 "boolean"/imm32 # 5 + 402 "constant"/imm32 # 6: like a literal, but value is an int in Var-offset + 403 "offset"/imm32 # 7: (offset T) is guaranteed to be a 32-bit multiple of size-of(T) + 404 # 0x20 + 405 "byte"/imm32 # 8 + 406 0/imm32 # 9 reserved for array-capacity; value is in Type-tree-size. + 407 # Not to be used directly, so we don't include a name here. + 408 0/imm32 # 10 reserved for type parameters; value is (address array byte) in Type-tree-value2. + 409 # Not to be used directly, so we don't include a name here. + 410 # Keep Primitive-type-ids in sync if you add types here. + 411 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 412 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 413 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 414 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 415 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 416 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 417 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 + 418 + 419 Primitive-type-ids: # (addr int) + 420 0x2c + 421 + 422 # == Type definitions + 423 # Program->types contains some typeinfo for each type definition. + 424 # Types contain vars with types, but can't specify registers. + 425 Typeinfo-id: # type-id + 426 0/imm32 + 427 Typeinfo-fields: # (handle table (handle array byte) (handle typeinfo-entry)) + 428 4/imm32 + 429 # Total size must be >= 0 + 430 # During parsing it may take on two additional values: + 431 # -2: not yet initialized + 432 # -1: in process of being computed + 433 # See populate-mu-type-sizes for details. + 434 Typeinfo-total-size-in-bytes: # int + 435 0xc/imm32 + 436 Typeinfo-next: # (handle typeinfo) + 437 0x10/imm32 + 438 Typeinfo-size: # (addr int) + 439 0x18/imm32 + 440 + 441 # Each entry in the typeinfo->fields table has a pointer to a string and a + 442 # pointer to a typeinfo-entry. + 443 Typeinfo-fields-row-size: # (addr int) + 444 0x10/imm32 + 445 + 446 # typeinfo-entry objects have information about a field in a single record type + 447 # + 448 # each field of a type is represented using two var's: + 449 # 1. the input var: expected type of the field; convenient for creating using parse-var-with-type + 450 # 2. the output var: a constant containing the byte offset; convenient for code-generation + 451 # computing the output happens after parsing; in the meantime we preserve the + 452 # order of fields in the 'index' field. + 453 Typeinfo-entry-input-var: # (handle var) + 454 0/imm32 + 455 Typeinfo-entry-index: # int + 456 8/imm32 + 457 Typeinfo-entry-output-var: # (handle var) + 458 0xc/imm32 + 459 Typeinfo-entry-size: # (addr int) + 460 0x14/imm32 + 461 + 462 == code + 463 + 464 Entry: + 465 # . prologue + 466 89/<- %ebp 4/r32/esp + 467 (new-segment *Heap-size Heap) + 468 # if (argv[1] == "test') run-tests() + 469 { + 470 # if (argc <= 1) break + 471 81 7/subop/compare *ebp 1/imm32 + 472 7e/jump-if-<= break/disp8 + 473 # if (argv[1] != "test") break + 474 (kernel-string-equal? *(ebp+8) "test") # => eax + 475 3d/compare-eax-and 0/imm32/false + 476 74/jump-if-= break/disp8 + 477 # + 478 (run-tests) + 479 # syscall(exit, *Num-test-failures) + 480 8b/-> *Num-test-failures 3/r32/ebx + 481 eb/jump $mu-main:end/disp8 + 482 } + 483 # otherwise convert Stdin + 484 (convert-mu Stdin Stdout Stderr 0) + 485 (flush Stdout) + 486 # syscall(exit, 0) + 487 bb/copy-to-ebx 0/imm32 + 488 $mu-main:end: + 489 e8/call syscall_exit/disp32 + 490 + 491 convert-mu: # in: (addr buffered-file), out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) + 492 # . prologue + 493 55/push-ebp + 494 89/<- %ebp 4/r32/esp + 495 # . save registers + 496 50/push-eax + 497 # initialize global data structures + 498 c7 0/subop/copy *Next-block-index 1/imm32 + 499 8b/-> *Primitive-type-ids 0/r32/eax + 500 89/<- *Type-id 0/r32/eax # stream-write + 501 c7 0/subop/copy *_Program-functions 0/imm32 + 502 c7 0/subop/copy *_Program-functions->payload 0/imm32 + 503 c7 0/subop/copy *_Program-types 0/imm32 + 504 c7 0/subop/copy *_Program-types->payload 0/imm32 + 505 c7 0/subop/copy *_Program-signatures 0/imm32 + 506 c7 0/subop/copy *_Program-signatures->payload 0/imm32 + 507 # + 508 (parse-mu *(ebp+8) *(ebp+0x10) *(ebp+0x14)) + 509 (populate-mu-type-sizes *(ebp+0x10) *(ebp+0x14)) + 510 #? (dump-typeinfos "=== typeinfos\n") + 511 (check-mu-types *(ebp+0x10) *(ebp+0x14)) + 512 (emit-subx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) + 513 $convert-mu:end: + 514 # . restore registers + 515 58/pop-to-eax + 516 # . epilogue + 517 89/<- %esp 5/r32/ebp + 518 5d/pop-to-ebp + 519 c3/return + 520 + 521 test-convert-empty-input: + 522 # empty input => empty output + 523 # . prologue + 524 55/push-ebp + 525 89/<- %ebp 4/r32/esp + 526 # setup + 527 (clear-stream _test-input-stream) + 528 (clear-stream $_test-input-buffered-file->buffer) + 529 (clear-stream _test-output-stream) + 530 (clear-stream $_test-output-buffered-file->buffer) + 531 # + 532 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 533 (flush _test-output-buffered-file) + 534 (check-stream-equal _test-output-stream "" "F - test-convert-empty-input") + 535 # . epilogue + 536 89/<- %esp 5/r32/ebp + 537 5d/pop-to-ebp + 538 c3/return + 539 + 540 test-convert-function-skeleton: + 541 # . prologue + 542 55/push-ebp + 543 89/<- %ebp 4/r32/esp + 544 # setup + 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) + 549 # + 550 (write _test-input-stream "fn foo {\n") + 551 (write _test-input-stream "}\n") + 552 # convert + 553 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 554 (flush _test-output-buffered-file) + 555 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 561 # check output + 562 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0") + 563 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-skeleton/1") + 564 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-skeleton/2") + 565 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3") + 566 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-skeleton/4") + 567 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5") + 568 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-skeleton/6") + 569 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-skeleton/7") + 570 # . epilogue + 571 89/<- %esp 5/r32/ebp + 572 5d/pop-to-ebp + 573 c3/return + 574 + 575 test-convert-multiple-function-skeletons: + 576 # . prologue + 577 55/push-ebp + 578 89/<- %ebp 4/r32/esp + 579 # setup + 580 (clear-stream _test-input-stream) + 581 (clear-stream $_test-input-buffered-file->buffer) + 582 (clear-stream _test-output-stream) + 583 (clear-stream $_test-output-buffered-file->buffer) + 584 # + 585 (write _test-input-stream "fn foo {\n") + 586 (write _test-input-stream "}\n") + 587 (write _test-input-stream "fn bar {\n") + 588 (write _test-input-stream "}\n") + 589 # convert + 590 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 591 (flush _test-output-buffered-file) + 592 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 598 # check first function + 599 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-multiple-function-skeletons/0") + 600 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/1") + 601 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/2") + 602 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/3") + 603 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/4") + 604 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/5") + 605 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/6") + 606 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/7") + 607 # check second function + 608 (check-next-stream-line-equal _test-output-stream "bar:" "F - test-convert-multiple-function-skeletons/10") + 609 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/11") + 610 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/12") + 611 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/13") + 612 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/14") + 613 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/15") + 614 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/16") + 615 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/17") + 616 # . epilogue + 617 89/<- %esp 5/r32/ebp + 618 5d/pop-to-ebp + 619 c3/return + 620 + 621 test-convert-function-with-arg: + 622 # . prologue + 623 55/push-ebp + 624 89/<- %ebp 4/r32/esp + 625 # setup + 626 (clear-stream _test-input-stream) + 627 (clear-stream $_test-input-buffered-file->buffer) + 628 (clear-stream _test-output-stream) + 629 (clear-stream $_test-output-buffered-file->buffer) + 630 # + 631 (write _test-input-stream "fn foo n: int {\n") + 632 (write _test-input-stream "}\n") + 633 # convert + 634 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 635 (flush _test-output-buffered-file) + 636 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 642 # check output + 643 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg/0") + 644 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg/1") + 645 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg/2") + 646 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg/3") + 647 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg/4") + 648 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg/5") + 649 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg/6") + 650 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg/7") + 651 # . epilogue + 652 89/<- %esp 5/r32/ebp + 653 5d/pop-to-ebp + 654 c3/return + 655 + 656 test-convert-function-with-arg-and-body: + 657 # . prologue + 658 55/push-ebp + 659 89/<- %ebp 4/r32/esp + 660 # setup + 661 (clear-stream _test-input-stream) + 662 (clear-stream $_test-input-buffered-file->buffer) + 663 (clear-stream _test-output-stream) + 664 (clear-stream $_test-output-buffered-file->buffer) + 665 # + 666 (write _test-input-stream "fn foo n: int {\n") + 667 (write _test-input-stream " increment n\n") + 668 (write _test-input-stream "}\n") + 669 # convert + 670 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 671 (flush _test-output-buffered-file) + 672 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 678 # check output + 679 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg-and-body/0") + 680 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg-and-body/1") + 681 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg-and-body/2") + 682 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg-and-body/3") + 683 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-arg-and-body/4") + 684 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-arg-and-body/5") + 685 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-arg-and-body/6") + 686 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-arg-and-body/7") + 687 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-arg-and-body/8") + 688 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg-and-body/9") + 689 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg-and-body/10") + 690 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg-and-body/11") + 691 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg-and-body/12") + 692 # . epilogue + 693 89/<- %esp 5/r32/ebp + 694 5d/pop-to-ebp + 695 c3/return + 696 + 697 test-convert-function-distinguishes-args: + 698 # . prologue + 699 55/push-ebp + 700 89/<- %ebp 4/r32/esp + 701 # setup + 702 (clear-stream _test-input-stream) + 703 (clear-stream $_test-input-buffered-file->buffer) + 704 (clear-stream _test-output-stream) + 705 (clear-stream $_test-output-buffered-file->buffer) + 706 # + 707 (write _test-input-stream "fn foo a: int, b: int {\n") + 708 (write _test-input-stream " increment b\n") + 709 (write _test-input-stream "}\n") + 710 # convert + 711 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 712 (flush _test-output-buffered-file) + 713 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 719 # check output + 720 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-distinguishes-args/0") + 721 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-distinguishes-args/1") + 722 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-distinguishes-args/2") + 723 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-distinguishes-args/3") + 724 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-distinguishes-args/4") + 725 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-distinguishes-args/5") + 726 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x0000000c)" "F - test-convert-function-distinguishes-args/6") + 727 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-distinguishes-args/7") + 728 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-distinguishes-args/8") + 729 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-distinguishes-args/9") + 730 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-distinguishes-args/10") + 731 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-distinguishes-args/11") + 732 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-distinguishes-args/12") + 733 # . epilogue + 734 89/<- %esp 5/r32/ebp + 735 5d/pop-to-ebp + 736 c3/return + 737 + 738 test-convert-function-returns-result: + 739 # . prologue + 740 55/push-ebp + 741 89/<- %ebp 4/r32/esp + 742 # setup + 743 (clear-stream _test-input-stream) + 744 (clear-stream $_test-input-buffered-file->buffer) + 745 (clear-stream _test-output-stream) + 746 (clear-stream $_test-output-buffered-file->buffer) + 747 # + 748 (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n") + 749 (write _test-input-stream " result <- copy a\n") + 750 (write _test-input-stream " result <- increment\n") + 751 (write _test-input-stream "}\n") + 752 # convert + 753 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 754 (flush _test-output-buffered-file) + 755 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 761 # check output + 762 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-returns-result/0") + 763 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-returns-result/1") + 764 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-returns-result/2") + 765 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-returns-result/3") + 766 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-returns-result/4") + 767 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-returns-result/5") + 768 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-returns-result/6") + 769 (check-next-stream-line-equal _test-output-stream " 40/increment-eax" "F - test-convert-function-returns-result/7") + 770 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-returns-result/8") + 771 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-returns-result/9") + 772 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-returns-result/10") + 773 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-returns-result/11") + 774 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-returns-result/12") + 775 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-returns-result/13") + 776 # . epilogue + 777 89/<- %esp 5/r32/ebp + 778 5d/pop-to-ebp + 779 c3/return + 780 + 781 test-convert-function-with-literal-arg: + 782 # . prologue + 783 55/push-ebp + 784 89/<- %ebp 4/r32/esp + 785 # setup + 786 (clear-stream _test-input-stream) + 787 (clear-stream $_test-input-buffered-file->buffer) + 788 (clear-stream _test-output-stream) + 789 (clear-stream $_test-output-buffered-file->buffer) + 790 # + 791 (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n") + 792 (write _test-input-stream " result <- copy a\n") + 793 (write _test-input-stream " result <- add 1\n") + 794 (write _test-input-stream "}\n") + 795 # convert + 796 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 797 (flush _test-output-buffered-file) + 798 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 804 # check output + 805 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg/0") + 806 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg/1") + 807 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg/2") + 808 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg/3") + 809 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg/4") + 810 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg/5") + 811 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-with-literal-arg/6") + 812 (check-next-stream-line-equal _test-output-stream " 05/add-to-eax 1/imm32" "F - test-convert-function-with-literal-arg/7") + 813 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg/8") + 814 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg/9") + 815 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg/10") + 816 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg/11") + 817 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg/12") + 818 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg/13") + 819 # . epilogue + 820 89/<- %esp 5/r32/ebp + 821 5d/pop-to-ebp + 822 c3/return + 823 + 824 test-convert-function-with-literal-arg-2: + 825 # . prologue + 826 55/push-ebp + 827 89/<- %ebp 4/r32/esp + 828 # setup + 829 (clear-stream _test-input-stream) + 830 (clear-stream $_test-input-buffered-file->buffer) + 831 (clear-stream _test-output-stream) + 832 (clear-stream $_test-output-buffered-file->buffer) + 833 # + 834 (write _test-input-stream "fn foo a: int, b: int -> result/ebx: int {\n") + 835 (write _test-input-stream " result <- copy a\n") + 836 (write _test-input-stream " result <- add 1\n") + 837 (write _test-input-stream "}\n") + 838 # convert + 839 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 840 (flush _test-output-buffered-file) + 841 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 847 # check output + 848 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg-2/0") + 849 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg-2/1") + 850 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg-2/2") + 851 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg-2/3") + 852 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg-2/4") + 853 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg-2/5") + 854 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/6") + 855 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %ebx 1/imm32" "F - test-convert-function-with-literal-arg-2/7") + 856 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg-2/8") + 857 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg-2/9") + 858 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg-2/10") + 859 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg-2/11") + 860 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg-2/12") + 861 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg-2/13") + 862 # . epilogue + 863 89/<- %esp 5/r32/ebp + 864 5d/pop-to-ebp + 865 c3/return + 866 + 867 test-convert-function-call-with-literal-arg: + 868 # . prologue + 869 55/push-ebp + 870 89/<- %ebp 4/r32/esp + 871 # setup + 872 (clear-stream _test-input-stream) + 873 (clear-stream $_test-input-buffered-file->buffer) + 874 (clear-stream _test-output-stream) + 875 (clear-stream $_test-output-buffered-file->buffer) + 876 # + 877 (write _test-input-stream "fn main -> result/ebx: int {\n") + 878 (write _test-input-stream " result <- do-add 3 4\n") + 879 (write _test-input-stream "}\n") + 880 (write _test-input-stream "fn do-add a: int, b: int -> result/ebx: int {\n") + 881 (write _test-input-stream " result <- copy a\n") + 882 (write _test-input-stream " result <- add b\n") + 883 (write _test-input-stream "}\n") + 884 # convert + 885 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 886 (flush _test-output-buffered-file) + 887 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 893 # check output + 894 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-literal-arg/0") + 895 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/1") + 896 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/2") + 897 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/3") + 898 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/4") + 899 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-literal-arg/5") + 900 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-literal-arg/6") + 901 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/7") + 902 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-literal-arg/8") + 903 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/9") + 904 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/10") + 905 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/11") + 906 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/12") + 907 (check-next-stream-line-equal _test-output-stream "do-add:" "F - test-convert-function-call-with-literal-arg/13") + 908 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/14") + 909 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/15") + 910 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/16") + 911 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/17") + 912 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:loop:" "F - test-convert-function-call-with-literal-arg/18") + 913 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/19") + 914 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0x0000000c) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/20") + 915 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/21") + 916 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:break:" "F - test-convert-function-call-with-literal-arg/22") + 917 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/23") + 918 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/24") + 919 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/25") + 920 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/26") + 921 # . epilogue + 922 89/<- %esp 5/r32/ebp + 923 5d/pop-to-ebp + 924 c3/return + 925 + 926 test-convert-function-call-with-signature: + 927 # . prologue + 928 55/push-ebp + 929 89/<- %ebp 4/r32/esp + 930 # setup + 931 (clear-stream _test-input-stream) + 932 (clear-stream $_test-input-buffered-file->buffer) + 933 (clear-stream _test-output-stream) + 934 (clear-stream $_test-output-buffered-file->buffer) + 935 # + 936 (write _test-input-stream "fn main -> result/ebx: int {\n") + 937 (write _test-input-stream " result <- do-add 3 4\n") + 938 (write _test-input-stream "}\n") + 939 (write _test-input-stream "sig do-add a: int, b: int -> result/ebx: int\n") + 940 # convert + 941 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 942 (flush _test-output-buffered-file) + 943 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 949 # check output + 950 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-signature/0") + 951 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-signature/1") + 952 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-signature/2") + 953 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-signature/3") + 954 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-signature/4") + 955 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-signature/5") + 956 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-signature/6") + 957 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-signature/7") + 958 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-signature/8") + 959 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-signature/9") + 960 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-signature/10") + 961 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-signature/11") + 962 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-signature/12") + 963 # . epilogue + 964 89/<- %esp 5/r32/ebp + 965 5d/pop-to-ebp + 966 c3/return + 967 + 968 test-convert-function-with-local-var-in-mem: + 969 # . prologue + 970 55/push-ebp + 971 89/<- %ebp 4/r32/esp + 972 # setup + 973 (clear-stream _test-input-stream) + 974 (clear-stream $_test-input-buffered-file->buffer) + 975 (clear-stream _test-output-stream) + 976 (clear-stream $_test-output-buffered-file->buffer) + 977 # + 978 (write _test-input-stream "fn foo {\n") + 979 (write _test-input-stream " var x: int\n") + 980 (write _test-input-stream " increment x\n") + 981 (write _test-input-stream "}\n") + 982 # convert + 983 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 984 (flush _test-output-buffered-file) + 985 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 991 # check output + 992 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-mem/0") + 993 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-mem/1") + 994 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-mem/2") + 995 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-mem/3") + 996 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem/4") + 997 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-mem/5") + 998 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem/6") + 999 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-mem/7") + 1000 (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") + 1001 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem/9") + 1002 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-mem/10") + 1003 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-mem/11") + 1004 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-mem/12") + 1005 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-mem/13") + 1006 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-mem/14") + 1007 # . epilogue + 1008 89/<- %esp 5/r32/ebp + 1009 5d/pop-to-ebp + 1010 c3/return + 1011 + 1012 test-convert-invalid-literal: + 1013 # . prologue + 1014 55/push-ebp + 1015 89/<- %ebp 4/r32/esp + 1016 # setup + 1017 (clear-stream _test-input-stream) + 1018 (clear-stream $_test-input-buffered-file->buffer) + 1019 (clear-stream _test-output-stream) + 1020 (clear-stream $_test-output-buffered-file->buffer) + 1021 (clear-stream _test-error-stream) + 1022 (clear-stream $_test-error-buffered-file->buffer) + 1023 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1024 68/push 0/imm32 + 1025 68/push 0/imm32 + 1026 89/<- %edx 4/r32/esp + 1027 (tailor-exit-descriptor %edx 0x10) + 1028 # + 1029 (write _test-input-stream "fn foo {\n") + 1030 (write _test-input-stream " increment 1n\n") + 1031 (write _test-input-stream "}\n") + 1032 # convert + 1033 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1034 # registers except esp clobbered at this point + 1035 # restore ed + 1036 89/<- %edx 4/r32/esp + 1037 (flush _test-output-buffered-file) + 1038 (flush _test-error-buffered-file) + 1039 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1045 # check output + 1046 (check-stream-equal _test-output-stream "" "F - test-convert-invalid-literal: output should be empty") + 1047 (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") + 1048 # check that stop(1) was called + 1049 (check-ints-equal *(edx+4) 2 "F - test-convert-invalid-literal: exit status") + 1050 # don't restore from ebp + 1051 81 0/subop/add %esp 8/imm32 + 1052 # . epilogue + 1053 5d/pop-to-ebp + 1054 c3/return + 1055 + 1056 test-local-var-in-mem-has-no-initializer: + 1057 # . prologue + 1058 55/push-ebp + 1059 89/<- %ebp 4/r32/esp + 1060 # setup + 1061 (clear-stream _test-input-stream) + 1062 (clear-stream $_test-input-buffered-file->buffer) + 1063 (clear-stream _test-output-stream) + 1064 (clear-stream $_test-output-buffered-file->buffer) + 1065 (clear-stream _test-error-stream) + 1066 (clear-stream $_test-error-buffered-file->buffer) + 1067 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1068 68/push 0/imm32 + 1069 68/push 0/imm32 + 1070 89/<- %edx 4/r32/esp + 1071 (tailor-exit-descriptor %edx 0x10) + 1072 # + 1073 (write _test-input-stream "fn foo {\n") + 1074 (write _test-input-stream " var x: int <- copy 0\n") + 1075 (write _test-input-stream " increment x\n") + 1076 (write _test-input-stream "}\n") + 1077 # convert + 1078 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1079 # registers except esp clobbered at this point + 1080 # restore ed + 1081 89/<- %edx 4/r32/esp + 1082 (flush _test-output-buffered-file) + 1083 (flush _test-error-buffered-file) + 1084 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1090 # check output + 1091 (check-stream-equal _test-output-stream "" "F - test-var-in-mem-has-no-initializer: output should be empty") + 1092 (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") + 1093 # check that stop(1) was called + 1094 (check-ints-equal *(edx+4) 2 "F - test-var-in-mem-has-no-initializer: exit status") + 1095 # don't restore from ebp + 1096 81 0/subop/add %esp 8/imm32 + 1097 # . epilogue + 1098 5d/pop-to-ebp + 1099 c3/return + 1100 + 1101 test-convert-function-with-local-var-with-compound-type-in-mem: + 1102 # . prologue + 1103 55/push-ebp + 1104 89/<- %ebp 4/r32/esp + 1105 # setup + 1106 (clear-stream _test-input-stream) + 1107 (clear-stream $_test-input-buffered-file->buffer) + 1108 (clear-stream _test-output-stream) + 1109 (clear-stream $_test-output-buffered-file->buffer) + 1110 # + 1111 (write _test-input-stream "fn foo {\n") + 1112 (write _test-input-stream " var x: (addr int)\n") + 1113 (write _test-input-stream " copy-to x, 0\n") + 1114 (write _test-input-stream "}\n") + 1115 # convert + 1116 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1117 (flush _test-output-buffered-file) + 1118 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1124 # check output + 1125 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/0") + 1126 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/1") + 1127 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/2") + 1128 (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") + 1129 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-compound-type-in-mem/4") + 1130 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/5") + 1131 (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") + 1132 (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") + 1133 (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") + 1134 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-compound-type-in-mem/9") + 1135 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/10") + 1136 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/11") + 1137 (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") + 1138 (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") + 1139 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-compound-type-in-mem/14") + 1140 # . epilogue + 1141 89/<- %esp 5/r32/ebp + 1142 5d/pop-to-ebp + 1143 c3/return + 1144 + 1145 test-convert-function-with-local-var-in-reg: + 1146 # . prologue + 1147 55/push-ebp + 1148 89/<- %ebp 4/r32/esp + 1149 # setup + 1150 (clear-stream _test-input-stream) + 1151 (clear-stream $_test-input-buffered-file->buffer) + 1152 (clear-stream _test-output-stream) + 1153 (clear-stream $_test-output-buffered-file->buffer) + 1154 # + 1155 (write _test-input-stream "fn foo {\n") + 1156 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1157 (write _test-input-stream " x <- increment\n") + 1158 (write _test-input-stream "}\n") + 1159 # convert + 1160 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1161 (flush _test-output-buffered-file) + 1162 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1168 # check output + 1169 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-reg/0") + 1170 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-reg/1") + 1171 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-reg/2") + 1172 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-reg/3") + 1173 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-reg/4") + 1174 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-reg/5") + 1175 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-reg/6") + 1176 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-local-var-in-reg/7") + 1177 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-local-var-in-reg/8") + 1178 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-reg/9") + 1179 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-reg/10") + 1180 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-reg/11") + 1181 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-reg/12") + 1182 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-reg/13") + 1183 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-reg/14") + 1184 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-reg/15") + 1185 # . epilogue + 1186 89/<- %esp 5/r32/ebp + 1187 5d/pop-to-ebp + 1188 c3/return + 1189 + 1190 test-convert-function-with-allocate: + 1191 # . prologue + 1192 55/push-ebp + 1193 89/<- %ebp 4/r32/esp + 1194 # setup + 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) 1199 # 1200 (write _test-input-stream "fn foo {\n") - 1201 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1202 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 1203 (write _test-input-stream " x <- increment\n") - 1204 (write _test-input-stream "}\n") - 1205 # convert - 1206 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1207 # registers except esp clobbered at this point - 1208 # restore ed - 1209 89/<- %edx 4/r32/esp - 1210 (flush _test-output-buffered-file) - 1211 (flush _test-error-buffered-file) - 1212 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1218 # check output - 1219 (check-stream-equal _test-output-stream "" "F - test-read-clobbered-reg-var: output should be empty") - 1220 (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") - 1221 # check that stop(1) was called - 1222 (check-ints-equal *(edx+4) 2 "F - test-read-clobbered-reg-var: exit status") - 1223 # don't restore from ebp - 1224 81 0/subop/add %esp 8/imm32 - 1225 # . epilogue - 1226 5d/pop-to-ebp - 1227 c3/return - 1228 - 1229 test-convert-function-call: - 1230 # . prologue - 1231 55/push-ebp - 1232 89/<- %ebp 4/r32/esp - 1233 # setup - 1234 (clear-stream _test-input-stream) - 1235 (clear-stream $_test-input-buffered-file->buffer) - 1236 (clear-stream _test-output-stream) - 1237 (clear-stream $_test-output-buffered-file->buffer) - 1238 # - 1239 (write _test-input-stream "fn main -> result/ebx: int {\n") - 1240 (write _test-input-stream " result <- foo\n") - 1241 (write _test-input-stream "}\n") - 1242 (write _test-input-stream "fn foo -> result/ebx: int {\n") - 1243 (write _test-input-stream " result <- copy 3\n") - 1244 (write _test-input-stream "}\n") - 1245 # convert - 1246 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1247 (flush _test-output-buffered-file) - 1248 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1254 # check output - 1255 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call/0") - 1256 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/1") - 1257 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/2") - 1258 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/3") - 1259 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/4") - 1260 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call/5") - 1261 (check-next-stream-line-equal _test-output-stream " (foo)" "F - test-convert-function-call/6") - 1262 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/7") - 1263 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call/8") - 1264 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/9") - 1265 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/10") - 1266 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/11") - 1267 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/12") - 1268 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call/13") - 1269 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/14") - 1270 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/15") - 1271 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/16") - 1272 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/17") - 1273 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call/18") - 1274 (check-next-stream-line-equal _test-output-stream " bb/copy-to-ebx 3/imm32" "F - test-convert-function-call/19") - 1275 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/20") - 1276 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call/21") - 1277 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/22") - 1278 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/23") - 1279 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/24") - 1280 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/25") - 1281 # . epilogue - 1282 89/<- %esp 5/r32/ebp - 1283 5d/pop-to-ebp - 1284 c3/return - 1285 - 1286 test-convert-function-call-with-incorrect-inout-type: - 1287 # . prologue - 1288 55/push-ebp - 1289 89/<- %ebp 4/r32/esp - 1290 # setup - 1291 (clear-stream _test-input-stream) - 1292 (clear-stream $_test-input-buffered-file->buffer) - 1293 (clear-stream _test-output-stream) - 1294 (clear-stream $_test-output-buffered-file->buffer) - 1295 (clear-stream _test-error-stream) - 1296 (clear-stream $_test-error-buffered-file->buffer) - 1297 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1298 68/push 0/imm32 - 1299 68/push 0/imm32 - 1300 89/<- %edx 4/r32/esp - 1301 (tailor-exit-descriptor %edx 0x10) - 1302 # - 1303 (write _test-input-stream "fn f {\n") - 1304 (write _test-input-stream " var x: int\n") - 1305 (write _test-input-stream " g x\n") - 1306 (write _test-input-stream "}\n") - 1307 (write _test-input-stream "fn g a: foo {\n") - 1308 (write _test-input-stream "}\n") - 1309 # convert - 1310 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1311 # registers except esp clobbered at this point - 1312 # restore ed - 1313 89/<- %edx 4/r32/esp - 1314 (flush _test-output-buffered-file) - 1315 (flush _test-error-buffered-file) - 1316 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1322 # check output - 1323 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-inout-type: output should be empty") - 1324 (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") - 1325 # check that stop(1) was called - 1326 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-inout-type: exit status") - 1327 # don't restore from ebp - 1328 81 0/subop/add %esp 8/imm32 - 1329 5d/pop-to-ebp - 1330 c3/return - 1331 - 1332 test-convert-function-call-with-too-few-inouts: - 1333 # . prologue - 1334 55/push-ebp - 1335 89/<- %ebp 4/r32/esp - 1336 # setup - 1337 (clear-stream _test-input-stream) - 1338 (clear-stream $_test-input-buffered-file->buffer) - 1339 (clear-stream _test-output-stream) - 1340 (clear-stream $_test-output-buffered-file->buffer) - 1341 (clear-stream _test-error-stream) - 1342 (clear-stream $_test-error-buffered-file->buffer) - 1343 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1344 68/push 0/imm32 - 1345 68/push 0/imm32 - 1346 89/<- %edx 4/r32/esp - 1347 (tailor-exit-descriptor %edx 0x10) - 1348 # - 1349 (write _test-input-stream "fn f {\n") - 1350 (write _test-input-stream " g\n") - 1351 (write _test-input-stream "}\n") - 1352 (write _test-input-stream "fn g a: int {\n") - 1353 (write _test-input-stream "}\n") - 1354 # convert - 1355 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1356 # registers except esp clobbered at this point - 1357 # restore ed - 1358 89/<- %edx 4/r32/esp - 1359 (flush _test-output-buffered-file) - 1360 (flush _test-error-buffered-file) - 1361 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1367 # check output - 1368 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-inouts: output should be empty") - 1369 (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") - 1370 # check that stop(1) was called - 1371 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-inouts: exit status") - 1372 # don't restore from ebp - 1373 81 0/subop/add %esp 8/imm32 - 1374 5d/pop-to-ebp - 1375 c3/return - 1376 - 1377 test-convert-function-call-with-too-many-inouts: - 1378 # . prologue - 1379 55/push-ebp - 1380 89/<- %ebp 4/r32/esp - 1381 # setup - 1382 (clear-stream _test-input-stream) - 1383 (clear-stream $_test-input-buffered-file->buffer) - 1384 (clear-stream _test-output-stream) - 1385 (clear-stream $_test-output-buffered-file->buffer) - 1386 (clear-stream _test-error-stream) - 1387 (clear-stream $_test-error-buffered-file->buffer) - 1388 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1389 68/push 0/imm32 - 1390 68/push 0/imm32 - 1391 89/<- %edx 4/r32/esp - 1392 (tailor-exit-descriptor %edx 0x10) - 1393 # - 1394 (write _test-input-stream "fn f {\n") - 1395 (write _test-input-stream " var x: int\n") - 1396 (write _test-input-stream " g x\n") - 1397 (write _test-input-stream "}\n") - 1398 (write _test-input-stream "fn g {\n") - 1399 (write _test-input-stream "}\n") - 1400 # convert - 1401 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1402 # registers except esp clobbered at this point - 1403 # restore ed - 1404 89/<- %edx 4/r32/esp - 1405 (flush _test-output-buffered-file) - 1406 (flush _test-error-buffered-file) - 1407 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1413 # check output - 1414 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-inouts: output should be empty") - 1415 (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") - 1416 # check that stop(1) was called - 1417 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-inouts: exit status") - 1418 # don't restore from ebp - 1419 81 0/subop/add %esp 8/imm32 - 1420 5d/pop-to-ebp - 1421 c3/return - 1422 - 1423 test-convert-function-call-with-incorrect-output-type: - 1424 # . prologue - 1425 55/push-ebp - 1426 89/<- %ebp 4/r32/esp - 1427 # setup - 1428 (clear-stream _test-input-stream) - 1429 (clear-stream $_test-input-buffered-file->buffer) - 1430 (clear-stream _test-output-stream) - 1431 (clear-stream $_test-output-buffered-file->buffer) - 1432 (clear-stream _test-error-stream) - 1433 (clear-stream $_test-error-buffered-file->buffer) - 1434 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1435 68/push 0/imm32 - 1436 68/push 0/imm32 - 1437 89/<- %edx 4/r32/esp - 1438 (tailor-exit-descriptor %edx 0x10) - 1439 # - 1440 (write _test-input-stream "fn f {\n") - 1441 (write _test-input-stream " var x/eax: int <- g\n") + 1201 (write _test-input-stream " var x/ecx: (addr handle int) <- copy 0\n") + 1202 (write _test-input-stream " allocate x\n") + 1203 (write _test-input-stream "}\n") + 1204 # convert + 1205 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1206 (flush _test-output-buffered-file) + 1207 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1213 # check output + 1214 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-allocate/0") + 1215 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-allocate/1") + 1216 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-allocate/2") + 1217 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-allocate/3") + 1218 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-allocate/4") + 1219 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-allocate/5") + 1220 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-allocate/6") + 1221 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-allocate/7") + 1222 (check-next-stream-line-equal _test-output-stream " (allocate Heap 0x00000004 %ecx)" "F - test-convert-function-with-allocate/8") # 4 = size-of(int) + 1223 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-allocate/9") + 1224 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-allocate/10") + 1225 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-allocate/11") + 1226 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-allocate/12") + 1227 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-allocate/13") + 1228 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-allocate/14") + 1229 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-allocate/15") + 1230 # . epilogue + 1231 89/<- %esp 5/r32/ebp + 1232 5d/pop-to-ebp + 1233 c3/return + 1234 + 1235 test-initializer-in-hex: + 1236 # . prologue + 1237 55/push-ebp + 1238 89/<- %ebp 4/r32/esp + 1239 # setup + 1240 (clear-stream _test-input-stream) + 1241 (clear-stream $_test-input-buffered-file->buffer) + 1242 (clear-stream _test-output-stream) + 1243 (clear-stream $_test-output-buffered-file->buffer) + 1244 (clear-stream _test-error-stream) + 1245 (clear-stream $_test-error-buffered-file->buffer) + 1246 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1247 68/push 0/imm32 + 1248 68/push 0/imm32 + 1249 89/<- %edx 4/r32/esp + 1250 (tailor-exit-descriptor %edx 0x10) + 1251 # + 1252 (write _test-input-stream "fn foo {\n") + 1253 (write _test-input-stream " var x/ecx: int <- copy 10\n") + 1254 (write _test-input-stream "}\n") + 1255 # convert + 1256 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1257 # registers except esp clobbered at this point + 1258 # restore ed + 1259 89/<- %edx 4/r32/esp + 1260 (flush _test-output-buffered-file) + 1261 (flush _test-error-buffered-file) + 1262 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1268 # check output + 1269 (check-stream-equal _test-output-stream "" "F - test-initializer-in-hex: output should be empty") + 1270 (check-next-stream-line-equal _test-error-stream "literal integers are always hex in Mu; either start '10' with a '0x' to be unambiguous, or convert it to decimal." "F - test-initializer-in-hex: error message") + 1271 # check that stop(1) was called + 1272 (check-ints-equal *(edx+4) 2 "F - test-initializer-in-hex: exit status") + 1273 # don't restore from ebp + 1274 81 0/subop/add %esp 8/imm32 + 1275 # . epilogue + 1276 5d/pop-to-ebp + 1277 c3/return + 1278 + 1279 test-convert-function-with-second-local-var-in-same-reg: + 1280 # . prologue + 1281 55/push-ebp + 1282 89/<- %ebp 4/r32/esp + 1283 # setup + 1284 (clear-stream _test-input-stream) + 1285 (clear-stream $_test-input-buffered-file->buffer) + 1286 (clear-stream _test-output-stream) + 1287 (clear-stream $_test-output-buffered-file->buffer) + 1288 # + 1289 (write _test-input-stream "fn foo {\n") + 1290 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1291 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 1292 (write _test-input-stream " y <- increment\n") + 1293 (write _test-input-stream "}\n") + 1294 # convert + 1295 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1296 (flush _test-output-buffered-file) + 1297 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1303 # check output + 1304 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-second-local-var-in-same-reg/0") + 1305 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-second-local-var-in-same-reg/1") + 1306 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/2") + 1307 (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") + 1308 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-second-local-var-in-same-reg/4") + 1309 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-second-local-var-in-same-reg/5") + 1310 (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") + 1311 (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") + 1312 (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") + 1313 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-second-local-var-in-same-reg/9") + 1314 (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") + 1315 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-second-local-var-in-same-reg/11") + 1316 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-second-local-var-in-same-reg/12") + 1317 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-second-local-var-in-same-reg/13") + 1318 (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") + 1319 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/15") + 1320 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-second-local-var-in-same-reg/16") + 1321 # . epilogue + 1322 89/<- %esp 5/r32/ebp + 1323 5d/pop-to-ebp + 1324 c3/return + 1325 + 1326 test-read-clobbered-reg-var: + 1327 # . prologue + 1328 55/push-ebp + 1329 89/<- %ebp 4/r32/esp + 1330 # setup + 1331 (clear-stream _test-input-stream) + 1332 (clear-stream $_test-input-buffered-file->buffer) + 1333 (clear-stream _test-output-stream) + 1334 (clear-stream $_test-output-buffered-file->buffer) + 1335 (clear-stream _test-error-stream) + 1336 (clear-stream $_test-error-buffered-file->buffer) + 1337 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu + 1338 68/push 0/imm32 + 1339 68/push 0/imm32 + 1340 89/<- %edx 4/r32/esp + 1341 (tailor-exit-descriptor %edx 0x10) + 1342 # + 1343 (write _test-input-stream "fn foo {\n") + 1344 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1345 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 1346 (write _test-input-stream " x <- increment\n") + 1347 (write _test-input-stream "}\n") + 1348 # convert + 1349 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1350 # registers except esp clobbered at this point + 1351 # restore ed + 1352 89/<- %edx 4/r32/esp + 1353 (flush _test-output-buffered-file) + 1354 (flush _test-error-buffered-file) + 1355 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1361 # check output + 1362 (check-stream-equal _test-output-stream "" "F - test-read-clobbered-reg-var: output should be empty") + 1363 (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") + 1364 # check that stop(1) was called + 1365 (check-ints-equal *(edx+4) 2 "F - test-read-clobbered-reg-var: exit status") + 1366 # don't restore from ebp + 1367 81 0/subop/add %esp 8/imm32 + 1368 # . epilogue + 1369 5d/pop-to-ebp + 1370 c3/return + 1371 + 1372 test-convert-function-call: + 1373 # . prologue + 1374 55/push-ebp + 1375 89/<- %ebp 4/r32/esp + 1376 # setup + 1377 (clear-stream _test-input-stream) + 1378 (clear-stream $_test-input-buffered-file->buffer) + 1379 (clear-stream _test-output-stream) + 1380 (clear-stream $_test-output-buffered-file->buffer) + 1381 # + 1382 (write _test-input-stream "fn main -> result/ebx: int {\n") + 1383 (write _test-input-stream " result <- foo\n") + 1384 (write _test-input-stream "}\n") + 1385 (write _test-input-stream "fn foo -> result/ebx: int {\n") + 1386 (write _test-input-stream " result <- copy 3\n") + 1387 (write _test-input-stream "}\n") + 1388 # convert + 1389 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1390 (flush _test-output-buffered-file) + 1391 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1397 # check output + 1398 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call/0") + 1399 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/1") + 1400 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/2") + 1401 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/3") + 1402 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/4") + 1403 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call/5") + 1404 (check-next-stream-line-equal _test-output-stream " (foo)" "F - test-convert-function-call/6") + 1405 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/7") + 1406 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call/8") + 1407 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/9") + 1408 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/10") + 1409 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/11") + 1410 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/12") + 1411 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call/13") + 1412 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/14") + 1413 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/15") + 1414 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/16") + 1415 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/17") + 1416 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call/18") + 1417 (check-next-stream-line-equal _test-output-stream " bb/copy-to-ebx 3/imm32" "F - test-convert-function-call/19") + 1418 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/20") + 1419 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call/21") + 1420 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/22") + 1421 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/23") + 1422 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/24") + 1423 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/25") + 1424 # . epilogue + 1425 89/<- %esp 5/r32/ebp + 1426 5d/pop-to-ebp + 1427 c3/return + 1428 + 1429 test-convert-function-call-with-inout-with-compound-type: + 1430 # . prologue + 1431 55/push-ebp + 1432 89/<- %ebp 4/r32/esp + 1433 # setup + 1434 (clear-stream _test-input-stream) + 1435 (clear-stream $_test-input-buffered-file->buffer) + 1436 (clear-stream _test-output-stream) + 1437 (clear-stream $_test-output-buffered-file->buffer) + 1438 # + 1439 (write _test-input-stream "fn f {\n") + 1440 (write _test-input-stream " var x: (addr int)\n") + 1441 (write _test-input-stream " g x\n") 1442 (write _test-input-stream "}\n") - 1443 (write _test-input-stream "fn g -> a/eax: foo {\n") + 1443 (write _test-input-stream "fn g a: (addr int) {\n") 1444 (write _test-input-stream "}\n") 1445 # convert - 1446 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1447 # registers except esp clobbered at this point - 1448 # restore ed - 1449 89/<- %edx 4/r32/esp - 1450 (flush _test-output-buffered-file) - 1451 (flush _test-error-buffered-file) - 1452 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1458 # check output - 1459 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-type: output should be empty") - 1460 (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") - 1461 # check that stop(1) was called - 1462 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-type: exit status") - 1463 # don't restore from ebp - 1464 81 0/subop/add %esp 8/imm32 - 1465 5d/pop-to-ebp - 1466 c3/return - 1467 - 1468 test-convert-function-call-with-too-few-outputs: - 1469 # . prologue - 1470 55/push-ebp - 1471 89/<- %ebp 4/r32/esp - 1472 # setup - 1473 (clear-stream _test-input-stream) - 1474 (clear-stream $_test-input-buffered-file->buffer) - 1475 (clear-stream _test-output-stream) - 1476 (clear-stream $_test-output-buffered-file->buffer) - 1477 (clear-stream _test-error-stream) - 1478 (clear-stream $_test-error-buffered-file->buffer) - 1479 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1480 68/push 0/imm32 - 1481 68/push 0/imm32 - 1482 89/<- %edx 4/r32/esp - 1483 (tailor-exit-descriptor %edx 0x10) - 1484 # - 1485 (write _test-input-stream "fn f {\n") - 1486 (write _test-input-stream " g\n") - 1487 (write _test-input-stream "}\n") - 1488 (write _test-input-stream "fn g -> a/eax: int {\n") - 1489 (write _test-input-stream "}\n") - 1490 # convert - 1491 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1492 # registers except esp clobbered at this point - 1493 # restore ed - 1494 89/<- %edx 4/r32/esp - 1495 (flush _test-output-buffered-file) - 1496 (flush _test-error-buffered-file) - 1497 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1503 # check output - 1504 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-outputs: output should be empty") - 1505 (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") - 1506 # check that stop(1) was called - 1507 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-outputs: exit status") - 1508 # don't restore from ebp - 1509 81 0/subop/add %esp 8/imm32 - 1510 5d/pop-to-ebp - 1511 c3/return - 1512 - 1513 test-convert-function-call-with-too-many-outputs: - 1514 # . prologue - 1515 55/push-ebp - 1516 89/<- %ebp 4/r32/esp - 1517 # setup - 1518 (clear-stream _test-input-stream) - 1519 (clear-stream $_test-input-buffered-file->buffer) - 1520 (clear-stream _test-output-stream) - 1521 (clear-stream $_test-output-buffered-file->buffer) - 1522 (clear-stream _test-error-stream) - 1523 (clear-stream $_test-error-buffered-file->buffer) - 1524 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1525 68/push 0/imm32 - 1526 68/push 0/imm32 - 1527 89/<- %edx 4/r32/esp - 1528 (tailor-exit-descriptor %edx 0x10) - 1529 # - 1530 (write _test-input-stream "fn f {\n") - 1531 (write _test-input-stream " var x/eax: int <- g\n") - 1532 (write _test-input-stream "}\n") - 1533 (write _test-input-stream "fn g {\n") - 1534 (write _test-input-stream "}\n") - 1535 # convert - 1536 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1537 # registers except esp clobbered at this point - 1538 # restore ed - 1539 89/<- %edx 4/r32/esp - 1540 (flush _test-output-buffered-file) - 1541 (flush _test-error-buffered-file) - 1542 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1548 # check output - 1549 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-outputs: output should be empty") - 1550 (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") - 1551 # check that stop(1) was called - 1552 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-outputs: exit status") - 1553 # don't restore from ebp - 1554 81 0/subop/add %esp 8/imm32 - 1555 5d/pop-to-ebp - 1556 c3/return - 1557 - 1558 test-convert-function-call-with-incorrect-output-register: - 1559 # . prologue - 1560 55/push-ebp - 1561 89/<- %ebp 4/r32/esp - 1562 # setup - 1563 (clear-stream _test-input-stream) - 1564 (clear-stream $_test-input-buffered-file->buffer) - 1565 (clear-stream _test-output-stream) - 1566 (clear-stream $_test-output-buffered-file->buffer) - 1567 (clear-stream _test-error-stream) - 1568 (clear-stream $_test-error-buffered-file->buffer) - 1569 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1570 68/push 0/imm32 - 1571 68/push 0/imm32 - 1572 89/<- %edx 4/r32/esp - 1573 (tailor-exit-descriptor %edx 0x10) - 1574 # - 1575 (write _test-input-stream "fn f {\n") - 1576 (write _test-input-stream " var x/ecx: int <- g\n") - 1577 (write _test-input-stream "}\n") - 1578 (write _test-input-stream "fn g -> a/eax: int {\n") - 1579 (write _test-input-stream "}\n") - 1580 # convert - 1581 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1582 # registers except esp clobbered at this point - 1583 # restore ed - 1584 89/<- %edx 4/r32/esp - 1585 (flush _test-output-buffered-file) - 1586 (flush _test-error-buffered-file) - 1587 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1593 # check output - 1594 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-register: output should be empty") - 1595 (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") - 1596 # check that stop(1) was called - 1597 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-register: exit status") - 1598 # don't restore from ebp - 1599 81 0/subop/add %esp 8/imm32 - 1600 5d/pop-to-ebp - 1601 c3/return - 1602 - 1603 test-convert-function-with-local-var-dereferenced: - 1604 # . prologue - 1605 55/push-ebp - 1606 89/<- %ebp 4/r32/esp - 1607 # setup - 1608 (clear-stream _test-input-stream) - 1609 (clear-stream $_test-input-buffered-file->buffer) - 1610 (clear-stream _test-output-stream) - 1611 (clear-stream $_test-output-buffered-file->buffer) - 1612 # - 1613 (write _test-input-stream "fn foo {\n") - 1614 (write _test-input-stream " var x/ecx: (addr int) <- copy 0\n") - 1615 (write _test-input-stream " increment *x\n") - 1616 (write _test-input-stream "}\n") - 1617 # convert - 1618 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1619 (flush _test-output-buffered-file) - 1620 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1626 # check output - 1627 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-dereferenced/0") - 1628 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-dereferenced/1") - 1629 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-dereferenced/2") - 1630 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-dereferenced/3") - 1631 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-dereferenced/4") - 1632 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-dereferenced/5") - 1633 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-dereferenced/6") - 1634 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-local-var-dereferenced/7") - 1635 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-with-local-var-dereferenced/8") - 1636 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-dereferenced/9") - 1637 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-dereferenced/10") - 1638 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-dereferenced/11") - 1639 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-dereferenced/12") - 1640 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-dereferenced/13") - 1641 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-dereferenced/14") - 1642 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-dereferenced/15") - 1643 # . epilogue - 1644 89/<- %esp 5/r32/ebp - 1645 5d/pop-to-ebp - 1646 c3/return - 1647 - 1648 # variables of type 'byte' are not allowed on the stack - 1649 test-convert-function-with-byte-operations: - 1650 # . prologue - 1651 55/push-ebp - 1652 89/<- %ebp 4/r32/esp - 1653 # setup - 1654 (clear-stream _test-input-stream) - 1655 (clear-stream $_test-input-buffered-file->buffer) - 1656 (clear-stream _test-output-stream) - 1657 (clear-stream $_test-output-buffered-file->buffer) - 1658 # - 1659 (write _test-input-stream "fn foo {\n") - 1660 (write _test-input-stream " var x/eax: byte <- copy 0\n") - 1661 (write _test-input-stream " var y/ecx: byte <- copy 0\n") - 1662 (write _test-input-stream " y <- copy-byte x\n") - 1663 (write _test-input-stream " var z/edx: (addr byte) <- copy 0\n") - 1664 (write _test-input-stream " y <- copy-byte *z\n") - 1665 (write _test-input-stream " copy-byte-to *z, x\n") - 1666 (write _test-input-stream "}\n") - 1667 # convert - 1668 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1669 (flush _test-output-buffered-file) - 1670 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1676 # check output - 1677 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-byte-operations/0") - 1678 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-byte-operations/1") - 1679 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-byte-operations/2") - 1680 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-byte-operations/3") - 1681 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-byte-operations/4") - 1682 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-byte-operations/5") - 1683 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-byte-operations/6") - 1684 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-with-byte-operations/7") - 1685 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-byte-operations/8") - 1686 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-byte-operations/9") - 1687 (check-next-stream-line-equal _test-output-stream " 8a/byte-> %eax 0x00000001/r32" "F - test-convert-function-with-byte-operations/10") - 1688 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-function-with-byte-operations/11") - 1689 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 0/imm32" "F - test-convert-function-with-byte-operations/12") - 1690 (check-next-stream-line-equal _test-output-stream " 8a/byte-> *edx 0x00000001/r32" "F - test-convert-function-with-byte-operations/13") - 1691 (check-next-stream-line-equal _test-output-stream " 88/byte<- *edx 0x00000000/r32" "F - test-convert-function-with-byte-operations/14") - 1692 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-function-with-byte-operations/15") - 1693 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-byte-operations/16") - 1694 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-byte-operations/17") - 1695 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-byte-operations/18") - 1696 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-byte-operations/19") - 1697 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-byte-operations/20") - 1698 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-byte-operations/21") - 1699 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-byte-operations/22") - 1700 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-byte-operations/23") - 1701 # . epilogue - 1702 89/<- %esp 5/r32/ebp - 1703 5d/pop-to-ebp - 1704 c3/return - 1705 - 1706 # variables of type 'byte' _can_ be function args. They then occupy 4 bytes. - 1707 test-copy-byte-var-from-fn-arg: - 1708 # . prologue - 1709 55/push-ebp - 1710 89/<- %ebp 4/r32/esp - 1711 # setup - 1712 (clear-stream _test-input-stream) - 1713 (clear-stream $_test-input-buffered-file->buffer) - 1714 (clear-stream _test-output-stream) - 1715 (clear-stream $_test-output-buffered-file->buffer) - 1716 # - 1717 (write _test-input-stream "fn foo x: byte, y: int {\n") - 1718 (write _test-input-stream " var a/eax: byte <- copy x\n") - 1719 (write _test-input-stream " var b/eax: int <- copy y\n") - 1720 (write _test-input-stream "}\n") - 1721 # convert - 1722 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1723 (flush _test-output-buffered-file) - 1724 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1730 # check output - 1731 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-copy-byte-from-fn-arg/0") - 1732 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-copy-byte-from-fn-arg/1") - 1733 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-copy-byte-from-fn-arg/2") - 1734 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-copy-byte-from-fn-arg/3") - 1735 (check-next-stream-line-equal _test-output-stream " {" "F - test-copy-byte-from-fn-arg/4") - 1736 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-copy-byte-from-fn-arg/5") - 1737 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-copy-byte-from-fn-arg/6") - 1738 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/7") - 1739 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x0000000c) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/8") - 1740 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-copy-byte-from-fn-arg/9") - 1741 (check-next-stream-line-equal _test-output-stream " }" "F - test-copy-byte-from-fn-arg/10") - 1742 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-copy-byte-from-fn-arg/11") - 1743 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-copy-byte-from-fn-arg/12") - 1744 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-copy-byte-from-fn-arg/13") - 1745 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-copy-byte-from-fn-arg/14") - 1746 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-copy-byte-from-fn-arg/15") - 1747 # . epilogue - 1748 89/<- %esp 5/r32/ebp - 1749 5d/pop-to-ebp - 1750 c3/return - 1751 - 1752 test-convert-compare-register-with-literal: - 1753 # . prologue - 1754 55/push-ebp - 1755 89/<- %ebp 4/r32/esp - 1756 # setup - 1757 (clear-stream _test-input-stream) - 1758 (clear-stream $_test-input-buffered-file->buffer) - 1759 (clear-stream _test-output-stream) - 1760 (clear-stream $_test-output-buffered-file->buffer) - 1761 # - 1762 (write _test-input-stream "fn foo {\n") - 1763 (write _test-input-stream " var x/ecx: int <- copy 0\n") - 1764 (write _test-input-stream " compare x, 0\n") - 1765 (write _test-input-stream "}\n") - 1766 # convert - 1767 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1768 (flush _test-output-buffered-file) - 1769 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1775 # check output - 1776 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-compare-register-with-literal/0") - 1777 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-compare-register-with-literal/1") - 1778 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-compare-register-with-literal/2") - 1779 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-compare-register-with-literal/3") - 1780 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-compare-register-with-literal/4") - 1781 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-compare-register-with-literal/5") - 1782 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") - 1783 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-compare-register-with-literal/7") - 1784 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0/imm32" "F - test-convert-compare-register-with-literal/8") - 1785 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") - 1786 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-compare-register-with-literal/10") - 1787 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-compare-register-with-literal/11") - 1788 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-compare-register-with-literal/12") - 1789 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-compare-register-with-literal/13") - 1790 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-compare-register-with-literal/14") - 1791 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-compare-register-with-literal/15") - 1792 # . epilogue - 1793 89/<- %esp 5/r32/ebp - 1794 5d/pop-to-ebp - 1795 c3/return - 1796 - 1797 test-unknown-variable: - 1798 # . prologue - 1799 55/push-ebp - 1800 89/<- %ebp 4/r32/esp - 1801 # setup - 1802 (clear-stream _test-input-stream) - 1803 (clear-stream $_test-input-buffered-file->buffer) - 1804 (clear-stream _test-output-stream) - 1805 (clear-stream $_test-output-buffered-file->buffer) - 1806 (clear-stream _test-error-stream) - 1807 (clear-stream $_test-error-buffered-file->buffer) - 1808 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1809 68/push 0/imm32 - 1810 68/push 0/imm32 - 1811 89/<- %edx 4/r32/esp - 1812 (tailor-exit-descriptor %edx 0x10) - 1813 # - 1814 (write _test-input-stream "fn foo {\n") - 1815 (write _test-input-stream " compare x, 0\n") - 1816 (write _test-input-stream "}\n") - 1817 # convert - 1818 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1819 # registers except esp clobbered at this point - 1820 # restore ed - 1821 89/<- %edx 4/r32/esp - 1822 (flush _test-output-buffered-file) - 1823 (flush _test-error-buffered-file) - 1824 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1830 # check output - 1831 (check-stream-equal _test-output-stream "" "F - test-unknown-variable: output should be empty") - 1832 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable: error message") - 1833 # check that stop(1) was called - 1834 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable: exit status") - 1835 # don't restore from ebp - 1836 81 0/subop/add %esp 8/imm32 - 1837 # . epilogue - 1838 5d/pop-to-ebp - 1839 c3/return - 1840 - 1841 test-convert-function-with-local-var-in-block: - 1842 # . prologue - 1843 55/push-ebp - 1844 89/<- %ebp 4/r32/esp - 1845 # setup - 1846 (clear-stream _test-input-stream) - 1847 (clear-stream $_test-input-buffered-file->buffer) - 1848 (clear-stream _test-output-stream) - 1849 (clear-stream $_test-output-buffered-file->buffer) - 1850 # - 1851 (write _test-input-stream "fn foo {\n") - 1852 (write _test-input-stream " {\n") - 1853 (write _test-input-stream " var x: int\n") - 1854 (write _test-input-stream " increment x\n") - 1855 (write _test-input-stream " }\n") - 1856 (write _test-input-stream "}\n") - 1857 # convert - 1858 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1859 (flush _test-output-buffered-file) - 1860 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1866 # check output - 1867 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-block/0") - 1868 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-block/1") - 1869 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-block/2") - 1870 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-block/3") - 1871 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/4") - 1872 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-block/5") - 1873 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/6") - 1874 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-local-var-in-block/7") - 1875 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-block/8") - 1876 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-block/9") - 1877 (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") - 1878 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/11") - 1879 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-local-var-in-block/12") - 1880 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/13") - 1881 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-block/14") - 1882 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-block/15") - 1883 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-block/16") - 1884 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-block/17") - 1885 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-block/18") - 1886 # . epilogue - 1887 89/<- %esp 5/r32/ebp - 1888 5d/pop-to-ebp - 1889 c3/return - 1890 - 1891 test-convert-function-with-local-var-in-named-block: - 1892 # . prologue - 1893 55/push-ebp - 1894 89/<- %ebp 4/r32/esp - 1895 # setup - 1896 (clear-stream _test-input-stream) - 1897 (clear-stream $_test-input-buffered-file->buffer) - 1898 (clear-stream _test-output-stream) - 1899 (clear-stream $_test-output-buffered-file->buffer) - 1900 # - 1901 (write _test-input-stream "fn foo {\n") - 1902 (write _test-input-stream " $bar: {\n") - 1903 (write _test-input-stream " var x: int\n") - 1904 (write _test-input-stream " increment x\n") - 1905 (write _test-input-stream " }\n") - 1906 (write _test-input-stream "}\n") - 1907 # convert - 1908 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1909 (flush _test-output-buffered-file) - 1910 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1916 # check output - 1917 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-named-block/0") - 1918 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-named-block/1") - 1919 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-named-block/2") - 1920 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-named-block/3") - 1921 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/4") - 1922 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-named-block/5") - 1923 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/6") - 1924 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-local-var-in-named-block/7") - 1925 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-named-block/8") - 1926 (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") - 1927 (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") - 1928 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/11") - 1929 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-local-var-in-named-block/12") - 1930 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/13") - 1931 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-named-block/14") - 1932 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-named-block/15") - 1933 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-named-block/16") - 1934 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-named-block/17") - 1935 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-named-block/18") - 1936 # . epilogue - 1937 89/<- %esp 5/r32/ebp - 1938 5d/pop-to-ebp - 1939 c3/return - 1940 - 1941 test-unknown-variable-in-named-block: - 1942 # . prologue - 1943 55/push-ebp - 1944 89/<- %ebp 4/r32/esp - 1945 # setup - 1946 (clear-stream _test-input-stream) - 1947 (clear-stream $_test-input-buffered-file->buffer) - 1948 (clear-stream _test-output-stream) - 1949 (clear-stream $_test-output-buffered-file->buffer) - 1950 (clear-stream _test-error-stream) - 1951 (clear-stream $_test-error-buffered-file->buffer) - 1952 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1953 68/push 0/imm32 - 1954 68/push 0/imm32 - 1955 89/<- %edx 4/r32/esp - 1956 (tailor-exit-descriptor %edx 0x10) - 1957 # - 1958 (write _test-input-stream "fn foo {\n") - 1959 (write _test-input-stream " $a: {\n") - 1960 (write _test-input-stream " compare x, 0\n") - 1961 (write _test-input-stream " }\n") - 1962 (write _test-input-stream "}\n") - 1963 # convert - 1964 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1965 # registers except esp clobbered at this point - 1966 # restore ed - 1967 89/<- %edx 4/r32/esp - 1968 (flush _test-output-buffered-file) - 1969 (flush _test-error-buffered-file) - 1970 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1976 # check output - 1977 (check-stream-equal _test-output-stream "" "F - test-unknown-variable-in-named-block: output should be empty") - 1978 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable-in-named-block: error message") - 1979 # check that stop(1) was called - 1980 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable-in-named-block: exit status") - 1981 # don't restore from ebp - 1982 81 0/subop/add %esp 8/imm32 - 1983 # . epilogue - 1984 5d/pop-to-ebp - 1985 c3/return - 1986 - 1987 test-always-shadow-outermost-reg-vars-in-function: - 1988 # . prologue - 1989 55/push-ebp - 1990 89/<- %ebp 4/r32/esp - 1991 # setup - 1992 (clear-stream _test-input-stream) - 1993 (clear-stream $_test-input-buffered-file->buffer) - 1994 (clear-stream _test-output-stream) - 1995 (clear-stream $_test-output-buffered-file->buffer) - 1996 # - 1997 (write _test-input-stream "fn foo {\n") - 1998 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1999 (write _test-input-stream "}\n") - 2000 # convert - 2001 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2002 (flush _test-output-buffered-file) - 2003 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2009 # check output - 2010 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-always-shadow-outermost-reg-vars-in-function/0") - 2011 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-always-shadow-outermost-reg-vars-in-function/1") - 2012 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/2") - 2013 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-always-shadow-outermost-reg-vars-in-function/3") - 2014 (check-next-stream-line-equal _test-output-stream " {" "F - test-always-shadow-outermost-reg-vars-in-function/4") - 2015 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-always-shadow-outermost-reg-vars-in-function/5") - 2016 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") - 2017 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-always-shadow-outermost-reg-vars-in-function/8") - 2018 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") - 2019 (check-next-stream-line-equal _test-output-stream " }" "F - test-always-shadow-outermost-reg-vars-in-function/12") - 2020 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-always-shadow-outermost-reg-vars-in-function/13") - 2021 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-always-shadow-outermost-reg-vars-in-function/14") - 2022 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-always-shadow-outermost-reg-vars-in-function/15") - 2023 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/16") - 2024 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-always-shadow-outermost-reg-vars-in-function/17") - 2025 # . epilogue - 2026 89/<- %esp 5/r32/ebp - 2027 5d/pop-to-ebp - 2028 c3/return - 2029 - 2030 _pending-test-clobber-dead-local: - 2031 # . prologue - 2032 55/push-ebp - 2033 89/<- %ebp 4/r32/esp - 2034 # setup - 2035 (clear-stream _test-input-stream) - 2036 (clear-stream $_test-input-buffered-file->buffer) - 2037 (clear-stream _test-output-stream) - 2038 (clear-stream $_test-output-buffered-file->buffer) - 2039 # - 2040 (write _test-input-stream "fn foo {\n") - 2041 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2042 (write _test-input-stream " {\n") - 2043 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2044 (write _test-input-stream " }\n") + 1446 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1447 (flush _test-output-buffered-file) + 1448 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1454 # check output + 1455 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-inout-with-compound-type/0") + 1456 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-inout-with-compound-type/1") + 1457 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-inout-with-compound-type/2") + 1458 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-inout-with-compound-type/3") + 1459 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-inout-with-compound-type/4") + 1460 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-inout-with-compound-type/5") + 1461 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-inout-with-compound-type/6") + 1462 (check-next-stream-line-equal _test-output-stream " (g *(ebp+0xfffffffc))" "F - test-convert-function-call-with-inout-with-compound-type/7") + 1463 (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") + 1464 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-inout-with-compound-type/9") + 1465 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-inout-with-compound-type/10") + 1466 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-inout-with-compound-type/11") + 1467 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-inout-with-compound-type/12") + 1468 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-inout-with-compound-type/13") + 1469 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-inout-with-compound-type/14") + 1470 (check-next-stream-line-equal _test-output-stream "g:" "F - test-convert-function-call-with-inout-with-compound-type/15") + 1471 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-inout-with-compound-type/16") + 1472 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-inout-with-compound-type/17") + 1473 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-inout-with-compound-type/18") + 1474 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-inout-with-compound-type/19") + 1475 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-inout-with-compound-type/20") + 1476 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-inout-with-compound-type/21") + 1477 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-inout-with-compound-type/22") + 1478 # . epilogue + 1479 89/<- %esp 5/r32/ebp + 1480 5d/pop-to-ebp + 1481 c3/return + 1482 + 1483 test-convert-function-call-with-inout-with-type-parameter: + 1484 # . prologue + 1485 55/push-ebp + 1486 89/<- %ebp 4/r32/esp + 1487 # setup + 1488 (clear-stream _test-input-stream) + 1489 (clear-stream $_test-input-buffered-file->buffer) + 1490 (clear-stream _test-output-stream) + 1491 (clear-stream $_test-output-buffered-file->buffer) + 1492 (clear-stream _test-error-stream) + 1493 (clear-stream $_test-error-buffered-file->buffer) + 1494 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1495 68/push 0/imm32 + 1496 68/push 0/imm32 + 1497 89/<- %edx 4/r32/esp + 1498 (tailor-exit-descriptor %edx 0x10) + 1499 # + 1500 (write _test-input-stream "fn f {\n") + 1501 (write _test-input-stream " var x: (addr int)\n") + 1502 (write _test-input-stream " g x\n") + 1503 (write _test-input-stream "}\n") + 1504 (write _test-input-stream "fn g a: (addr _) {\n") + 1505 (write _test-input-stream "}\n") + 1506 # convert + 1507 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1508 # registers except esp clobbered at this point + 1509 # restore ed + 1510 89/<- %edx 4/r32/esp + 1511 (flush _test-output-buffered-file) + 1512 (flush _test-error-buffered-file) + 1513 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1519 # no error; types matched + 1520 (check-stream-equal _test-error-stream "" "F - test-convert-function-call-with-inout-with-type-parameter: error stream should be empty") + 1521 # don't bother checking the generated code; that's in the test 'test-local-clobbered-by-fn-output' below + 1522 # don't restore from ebp + 1523 81 0/subop/add %esp 8/imm32 + 1524 # . epilogue + 1525 5d/pop-to-ebp + 1526 c3/return + 1527 + 1528 test-convert-function-call-with-incorrect-inout-type: + 1529 # . prologue + 1530 55/push-ebp + 1531 89/<- %ebp 4/r32/esp + 1532 # setup + 1533 (clear-stream _test-input-stream) + 1534 (clear-stream $_test-input-buffered-file->buffer) + 1535 (clear-stream _test-output-stream) + 1536 (clear-stream $_test-output-buffered-file->buffer) + 1537 (clear-stream _test-error-stream) + 1538 (clear-stream $_test-error-buffered-file->buffer) + 1539 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1540 68/push 0/imm32 + 1541 68/push 0/imm32 + 1542 89/<- %edx 4/r32/esp + 1543 (tailor-exit-descriptor %edx 0x10) + 1544 # + 1545 (write _test-input-stream "fn f {\n") + 1546 (write _test-input-stream " var x: int\n") + 1547 (write _test-input-stream " g x\n") + 1548 (write _test-input-stream "}\n") + 1549 (write _test-input-stream "fn g a: foo {\n") + 1550 (write _test-input-stream "}\n") + 1551 # convert + 1552 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1553 # registers except esp clobbered at this point + 1554 # restore ed + 1555 89/<- %edx 4/r32/esp + 1556 (flush _test-output-buffered-file) + 1557 (flush _test-error-buffered-file) + 1558 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1564 # check output + 1565 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-inout-type: output should be empty") + 1566 (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") + 1567 # check that stop(1) was called + 1568 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-inout-type: exit status") + 1569 # don't restore from ebp + 1570 81 0/subop/add %esp 8/imm32 + 1571 5d/pop-to-ebp + 1572 c3/return + 1573 + 1574 test-convert-function-call-with-inout-with-incorrect-compound-type: + 1575 # . prologue + 1576 55/push-ebp + 1577 89/<- %ebp 4/r32/esp + 1578 # setup + 1579 (clear-stream _test-input-stream) + 1580 (clear-stream $_test-input-buffered-file->buffer) + 1581 (clear-stream _test-output-stream) + 1582 (clear-stream $_test-output-buffered-file->buffer) + 1583 (clear-stream _test-error-stream) + 1584 (clear-stream $_test-error-buffered-file->buffer) + 1585 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1586 68/push 0/imm32 + 1587 68/push 0/imm32 + 1588 89/<- %edx 4/r32/esp + 1589 (tailor-exit-descriptor %edx 0x10) + 1590 # + 1591 (write _test-input-stream "fn f {\n") + 1592 (write _test-input-stream " var x: (addr int)\n") + 1593 (write _test-input-stream " g x\n") + 1594 (write _test-input-stream "}\n") + 1595 (write _test-input-stream "fn g a: (addr bool) {\n") + 1596 (write _test-input-stream "}\n") + 1597 # convert + 1598 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1599 # registers except esp clobbered at this point + 1600 # restore ed + 1601 89/<- %edx 4/r32/esp + 1602 (flush _test-output-buffered-file) + 1603 (flush _test-error-buffered-file) + 1604 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1610 # check output + 1611 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-inout-with-incorrect-compound-type: output should be empty") + 1612 (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") + 1613 # don't restore from ebp + 1614 81 0/subop/add %esp 8/imm32 + 1615 # . epilogue + 1616 5d/pop-to-ebp + 1617 c3/return + 1618 + 1619 test-convert-function-call-with-inout-with-multiple-type-parameters: + 1620 # . prologue + 1621 55/push-ebp + 1622 89/<- %ebp 4/r32/esp + 1623 # setup + 1624 (clear-stream _test-input-stream) + 1625 (clear-stream $_test-input-buffered-file->buffer) + 1626 (clear-stream _test-output-stream) + 1627 (clear-stream $_test-output-buffered-file->buffer) + 1628 (clear-stream _test-error-stream) + 1629 (clear-stream $_test-error-buffered-file->buffer) + 1630 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1631 68/push 0/imm32 + 1632 68/push 0/imm32 + 1633 89/<- %edx 4/r32/esp + 1634 (tailor-exit-descriptor %edx 0x10) + 1635 # + 1636 (write _test-input-stream "fn f {\n") + 1637 (write _test-input-stream " var x: (addr int)\n") + 1638 (write _test-input-stream " var y: (addr int)\n") + 1639 (write _test-input-stream " g x, y\n") + 1640 (write _test-input-stream "}\n") + 1641 (write _test-input-stream "fn g a: (addr _), b: (addr _) {\n") + 1642 (write _test-input-stream "}\n") + 1643 # convert + 1644 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1645 # registers except esp clobbered at this point + 1646 # restore ed + 1647 89/<- %edx 4/r32/esp + 1648 (flush _test-output-buffered-file) + 1649 (flush _test-error-buffered-file) + 1650 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1656 # no errors + 1657 (check-stream-equal _test-error-stream "" "F - test-convert-function-call-with-inout-with-multiple-type-parameters: error stream should be empty") + 1658 # don't bother checking the generated code + 1659 # don't restore from ebp + 1660 81 0/subop/add %esp 8/imm32 + 1661 # . epilogue + 1662 5d/pop-to-ebp + 1663 c3/return + 1664 + 1665 test-convert-function-call-with-inout-with-incompatible-type-parameters: + 1666 # . prologue + 1667 55/push-ebp + 1668 89/<- %ebp 4/r32/esp + 1669 # setup + 1670 (clear-stream _test-input-stream) + 1671 (clear-stream $_test-input-buffered-file->buffer) + 1672 (clear-stream _test-output-stream) + 1673 (clear-stream $_test-output-buffered-file->buffer) + 1674 (clear-stream _test-error-stream) + 1675 (clear-stream $_test-error-buffered-file->buffer) + 1676 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1677 68/push 0/imm32 + 1678 68/push 0/imm32 + 1679 89/<- %edx 4/r32/esp + 1680 (tailor-exit-descriptor %edx 0x10) + 1681 # + 1682 (write _test-input-stream "fn f {\n") + 1683 (write _test-input-stream " var x: (addr int)\n") + 1684 (write _test-input-stream " var y: (addr boolean)\n") + 1685 (write _test-input-stream " g x, y\n") + 1686 (write _test-input-stream "}\n") + 1687 (write _test-input-stream "fn g a: (addr _T), b: (addr _T) {\n") + 1688 (write _test-input-stream "}\n") + 1689 # convert + 1690 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1691 # registers except esp clobbered at this point + 1692 # restore ed + 1693 89/<- %edx 4/r32/esp + 1694 (flush _test-output-buffered-file) + 1695 (flush _test-error-buffered-file) + 1696 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1702 # check output + 1703 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-inout-with-incompatible-type-parameters: output should be empty") + 1704 (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") + 1705 # don't restore from ebp + 1706 81 0/subop/add %esp 8/imm32 + 1707 # . epilogue + 1708 5d/pop-to-ebp + 1709 c3/return + 1710 + 1711 test-convert-function-call-with-too-few-inouts: + 1712 # . prologue + 1713 55/push-ebp + 1714 89/<- %ebp 4/r32/esp + 1715 # setup + 1716 (clear-stream _test-input-stream) + 1717 (clear-stream $_test-input-buffered-file->buffer) + 1718 (clear-stream _test-output-stream) + 1719 (clear-stream $_test-output-buffered-file->buffer) + 1720 (clear-stream _test-error-stream) + 1721 (clear-stream $_test-error-buffered-file->buffer) + 1722 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1723 68/push 0/imm32 + 1724 68/push 0/imm32 + 1725 89/<- %edx 4/r32/esp + 1726 (tailor-exit-descriptor %edx 0x10) + 1727 # + 1728 (write _test-input-stream "fn f {\n") + 1729 (write _test-input-stream " g\n") + 1730 (write _test-input-stream "}\n") + 1731 (write _test-input-stream "fn g a: int {\n") + 1732 (write _test-input-stream "}\n") + 1733 # convert + 1734 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1735 # registers except esp clobbered at this point + 1736 # restore ed + 1737 89/<- %edx 4/r32/esp + 1738 (flush _test-output-buffered-file) + 1739 (flush _test-error-buffered-file) + 1740 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1746 # check output + 1747 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-inouts: output should be empty") + 1748 (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") + 1749 # check that stop(1) was called + 1750 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-inouts: exit status") + 1751 # don't restore from ebp + 1752 81 0/subop/add %esp 8/imm32 + 1753 5d/pop-to-ebp + 1754 c3/return + 1755 + 1756 test-convert-function-call-with-too-many-inouts: + 1757 # . prologue + 1758 55/push-ebp + 1759 89/<- %ebp 4/r32/esp + 1760 # setup + 1761 (clear-stream _test-input-stream) + 1762 (clear-stream $_test-input-buffered-file->buffer) + 1763 (clear-stream _test-output-stream) + 1764 (clear-stream $_test-output-buffered-file->buffer) + 1765 (clear-stream _test-error-stream) + 1766 (clear-stream $_test-error-buffered-file->buffer) + 1767 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1768 68/push 0/imm32 + 1769 68/push 0/imm32 + 1770 89/<- %edx 4/r32/esp + 1771 (tailor-exit-descriptor %edx 0x10) + 1772 # + 1773 (write _test-input-stream "fn f {\n") + 1774 (write _test-input-stream " var x: int\n") + 1775 (write _test-input-stream " g x\n") + 1776 (write _test-input-stream "}\n") + 1777 (write _test-input-stream "fn g {\n") + 1778 (write _test-input-stream "}\n") + 1779 # convert + 1780 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1781 # registers except esp clobbered at this point + 1782 # restore ed + 1783 89/<- %edx 4/r32/esp + 1784 (flush _test-output-buffered-file) + 1785 (flush _test-error-buffered-file) + 1786 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1792 # check output + 1793 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-inouts: output should be empty") + 1794 (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") + 1795 # check that stop(1) was called + 1796 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-inouts: exit status") + 1797 # don't restore from ebp + 1798 81 0/subop/add %esp 8/imm32 + 1799 5d/pop-to-ebp + 1800 c3/return + 1801 + 1802 test-convert-function-call-with-incorrect-output-type: + 1803 # . prologue + 1804 55/push-ebp + 1805 89/<- %ebp 4/r32/esp + 1806 # setup + 1807 (clear-stream _test-input-stream) + 1808 (clear-stream $_test-input-buffered-file->buffer) + 1809 (clear-stream _test-output-stream) + 1810 (clear-stream $_test-output-buffered-file->buffer) + 1811 (clear-stream _test-error-stream) + 1812 (clear-stream $_test-error-buffered-file->buffer) + 1813 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1814 68/push 0/imm32 + 1815 68/push 0/imm32 + 1816 89/<- %edx 4/r32/esp + 1817 (tailor-exit-descriptor %edx 0x10) + 1818 # + 1819 (write _test-input-stream "fn f {\n") + 1820 (write _test-input-stream " var x/eax: int <- g\n") + 1821 (write _test-input-stream "}\n") + 1822 (write _test-input-stream "fn g -> a/eax: foo {\n") + 1823 (write _test-input-stream "}\n") + 1824 # convert + 1825 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1826 # registers except esp clobbered at this point + 1827 # restore ed + 1828 89/<- %edx 4/r32/esp + 1829 (flush _test-output-buffered-file) + 1830 (flush _test-error-buffered-file) + 1831 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1837 # check output + 1838 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-type: output should be empty") + 1839 (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") + 1840 # check that stop(1) was called + 1841 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-type: exit status") + 1842 # don't restore from ebp + 1843 81 0/subop/add %esp 8/imm32 + 1844 5d/pop-to-ebp + 1845 c3/return + 1846 + 1847 test-convert-function-call-with-too-few-outputs: + 1848 # . prologue + 1849 55/push-ebp + 1850 89/<- %ebp 4/r32/esp + 1851 # setup + 1852 (clear-stream _test-input-stream) + 1853 (clear-stream $_test-input-buffered-file->buffer) + 1854 (clear-stream _test-output-stream) + 1855 (clear-stream $_test-output-buffered-file->buffer) + 1856 (clear-stream _test-error-stream) + 1857 (clear-stream $_test-error-buffered-file->buffer) + 1858 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1859 68/push 0/imm32 + 1860 68/push 0/imm32 + 1861 89/<- %edx 4/r32/esp + 1862 (tailor-exit-descriptor %edx 0x10) + 1863 # + 1864 (write _test-input-stream "fn f {\n") + 1865 (write _test-input-stream " g\n") + 1866 (write _test-input-stream "}\n") + 1867 (write _test-input-stream "fn g -> a/eax: int {\n") + 1868 (write _test-input-stream "}\n") + 1869 # convert + 1870 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1871 # registers except esp clobbered at this point + 1872 # restore ed + 1873 89/<- %edx 4/r32/esp + 1874 (flush _test-output-buffered-file) + 1875 (flush _test-error-buffered-file) + 1876 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1882 # check output + 1883 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-outputs: output should be empty") + 1884 (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") + 1885 # check that stop(1) was called + 1886 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-outputs: exit status") + 1887 # don't restore from ebp + 1888 81 0/subop/add %esp 8/imm32 + 1889 5d/pop-to-ebp + 1890 c3/return + 1891 + 1892 test-convert-function-call-with-too-many-outputs: + 1893 # . prologue + 1894 55/push-ebp + 1895 89/<- %ebp 4/r32/esp + 1896 # setup + 1897 (clear-stream _test-input-stream) + 1898 (clear-stream $_test-input-buffered-file->buffer) + 1899 (clear-stream _test-output-stream) + 1900 (clear-stream $_test-output-buffered-file->buffer) + 1901 (clear-stream _test-error-stream) + 1902 (clear-stream $_test-error-buffered-file->buffer) + 1903 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1904 68/push 0/imm32 + 1905 68/push 0/imm32 + 1906 89/<- %edx 4/r32/esp + 1907 (tailor-exit-descriptor %edx 0x10) + 1908 # + 1909 (write _test-input-stream "fn f {\n") + 1910 (write _test-input-stream " var x/eax: int <- g\n") + 1911 (write _test-input-stream "}\n") + 1912 (write _test-input-stream "fn g {\n") + 1913 (write _test-input-stream "}\n") + 1914 # convert + 1915 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1916 # registers except esp clobbered at this point + 1917 # restore ed + 1918 89/<- %edx 4/r32/esp + 1919 (flush _test-output-buffered-file) + 1920 (flush _test-error-buffered-file) + 1921 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1927 # check output + 1928 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-outputs: output should be empty") + 1929 (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") + 1930 # check that stop(1) was called + 1931 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-outputs: exit status") + 1932 # don't restore from ebp + 1933 81 0/subop/add %esp 8/imm32 + 1934 5d/pop-to-ebp + 1935 c3/return + 1936 + 1937 test-convert-function-call-with-incorrect-output-register: + 1938 # . prologue + 1939 55/push-ebp + 1940 89/<- %ebp 4/r32/esp + 1941 # setup + 1942 (clear-stream _test-input-stream) + 1943 (clear-stream $_test-input-buffered-file->buffer) + 1944 (clear-stream _test-output-stream) + 1945 (clear-stream $_test-output-buffered-file->buffer) + 1946 (clear-stream _test-error-stream) + 1947 (clear-stream $_test-error-buffered-file->buffer) + 1948 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1949 68/push 0/imm32 + 1950 68/push 0/imm32 + 1951 89/<- %edx 4/r32/esp + 1952 (tailor-exit-descriptor %edx 0x10) + 1953 # + 1954 (write _test-input-stream "fn f {\n") + 1955 (write _test-input-stream " var x/ecx: int <- g\n") + 1956 (write _test-input-stream "}\n") + 1957 (write _test-input-stream "fn g -> a/eax: int {\n") + 1958 (write _test-input-stream "}\n") + 1959 # convert + 1960 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1961 # registers except esp clobbered at this point + 1962 # restore ed + 1963 89/<- %edx 4/r32/esp + 1964 (flush _test-output-buffered-file) + 1965 (flush _test-error-buffered-file) + 1966 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1972 # check output + 1973 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-register: output should be empty") + 1974 (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") + 1975 # check that stop(1) was called + 1976 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-register: exit status") + 1977 # don't restore from ebp + 1978 81 0/subop/add %esp 8/imm32 + 1979 5d/pop-to-ebp + 1980 c3/return + 1981 + 1982 test-convert-function-with-local-var-dereferenced: + 1983 # . prologue + 1984 55/push-ebp + 1985 89/<- %ebp 4/r32/esp + 1986 # setup + 1987 (clear-stream _test-input-stream) + 1988 (clear-stream $_test-input-buffered-file->buffer) + 1989 (clear-stream _test-output-stream) + 1990 (clear-stream $_test-output-buffered-file->buffer) + 1991 # + 1992 (write _test-input-stream "fn foo {\n") + 1993 (write _test-input-stream " var x/ecx: (addr int) <- copy 0\n") + 1994 (write _test-input-stream " increment *x\n") + 1995 (write _test-input-stream "}\n") + 1996 # convert + 1997 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1998 (flush _test-output-buffered-file) + 1999 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2005 # check output + 2006 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-dereferenced/0") + 2007 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-dereferenced/1") + 2008 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-dereferenced/2") + 2009 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-dereferenced/3") + 2010 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-dereferenced/4") + 2011 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-dereferenced/5") + 2012 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-dereferenced/6") + 2013 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-local-var-dereferenced/7") + 2014 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-with-local-var-dereferenced/8") + 2015 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-dereferenced/9") + 2016 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-dereferenced/10") + 2017 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-dereferenced/11") + 2018 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-dereferenced/12") + 2019 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-dereferenced/13") + 2020 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-dereferenced/14") + 2021 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-dereferenced/15") + 2022 # . epilogue + 2023 89/<- %esp 5/r32/ebp + 2024 5d/pop-to-ebp + 2025 c3/return + 2026 + 2027 # variables of type 'byte' are not allowed on the stack + 2028 test-convert-function-with-byte-operations: + 2029 # . prologue + 2030 55/push-ebp + 2031 89/<- %ebp 4/r32/esp + 2032 # setup + 2033 (clear-stream _test-input-stream) + 2034 (clear-stream $_test-input-buffered-file->buffer) + 2035 (clear-stream _test-output-stream) + 2036 (clear-stream $_test-output-buffered-file->buffer) + 2037 # + 2038 (write _test-input-stream "fn foo {\n") + 2039 (write _test-input-stream " var x/eax: byte <- copy 0\n") + 2040 (write _test-input-stream " var y/ecx: byte <- copy 0\n") + 2041 (write _test-input-stream " y <- copy-byte x\n") + 2042 (write _test-input-stream " var z/edx: (addr byte) <- copy 0\n") + 2043 (write _test-input-stream " y <- copy-byte *z\n") + 2044 (write _test-input-stream " copy-byte-to *z, x\n") 2045 (write _test-input-stream "}\n") 2046 # convert - 2047 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2047 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) 2048 (flush _test-output-buffered-file) 2049 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- 2055 # check output - 2056 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-clobber-dead-local/0") - 2057 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-clobber-dead-local/1") - 2058 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-clobber-dead-local/2") - 2059 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-clobber-dead-local/3") - 2060 (check-next-stream-line-equal _test-output-stream " {" "F - test-clobber-dead-local/4") - 2061 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-clobber-dead-local/5") - 2062 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-clobber-dead-local/6") - 2063 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-clobber-dead-local/7") - 2064 (check-next-stream-line-equal _test-output-stream " {" "F - test-clobber-dead-local/8") - 2065 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-clobber-dead-local/9") - 2066 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-clobber-dead-local/10") # no push/pop here - 2067 (check-next-stream-line-equal _test-output-stream " }" "F - test-clobber-dead-local/11") - 2068 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-clobber-dead-local/12") - 2069 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-clobber-dead-local/13") - 2070 (check-next-stream-line-equal _test-output-stream " }" "F - test-clobber-dead-local/14") - 2071 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-clobber-dead-local/15") - 2072 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-clobber-dead-local/16") - 2073 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-clobber-dead-local/17") - 2074 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-clobber-dead-local/18") - 2075 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-clobber-dead-local/19") - 2076 # . epilogue - 2077 89/<- %esp 5/r32/ebp - 2078 5d/pop-to-ebp - 2079 c3/return - 2080 - 2081 test-shadow-live-local: - 2082 # . prologue - 2083 55/push-ebp - 2084 89/<- %ebp 4/r32/esp - 2085 # setup - 2086 (clear-stream _test-input-stream) - 2087 (clear-stream $_test-input-buffered-file->buffer) - 2088 (clear-stream _test-output-stream) - 2089 (clear-stream $_test-output-buffered-file->buffer) - 2090 # - 2091 (write _test-input-stream "fn foo {\n") - 2092 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2093 (write _test-input-stream " {\n") - 2094 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2095 (write _test-input-stream " }\n") - 2096 (write _test-input-stream " x <- increment\n") - 2097 (write _test-input-stream "}\n") - 2098 # convert - 2099 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2100 (flush _test-output-buffered-file) - 2101 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2107 # check output - 2108 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-live-local/0") - 2109 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-live-local/1") - 2110 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-live-local/2") - 2111 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-live-local/3") - 2112 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-local/4") - 2113 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-live-local/5") - 2114 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-local/6") - 2115 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-live-local/7") - 2116 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-local/8") - 2117 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-live-local/9") - 2118 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-local/10") - 2119 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-live-local/11") - 2120 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-local/12") - 2121 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-local/13") - 2122 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-live-local/14") - 2123 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-live-local/15") - 2124 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-local/16") - 2125 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-local/17") - 2126 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-live-local/18") - 2127 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-live-local/19") - 2128 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-live-local/20") - 2129 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-live-local/21") - 2130 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-live-local/22") - 2131 # . epilogue - 2132 89/<- %esp 5/r32/ebp - 2133 5d/pop-to-ebp - 2134 c3/return - 2135 - 2136 test-shadow-name: - 2137 # . prologue - 2138 55/push-ebp - 2139 89/<- %ebp 4/r32/esp - 2140 # setup - 2141 (clear-stream _test-input-stream) - 2142 (clear-stream $_test-input-buffered-file->buffer) - 2143 (clear-stream _test-output-stream) - 2144 (clear-stream $_test-output-buffered-file->buffer) - 2145 # - 2146 (write _test-input-stream "fn foo {\n") - 2147 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2148 (write _test-input-stream " {\n") - 2149 (write _test-input-stream " var x/edx: int <- copy 4\n") - 2150 (write _test-input-stream " }\n") - 2151 (write _test-input-stream " x <- increment\n") - 2152 (write _test-input-stream "}\n") - 2153 # convert - 2154 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2155 (flush _test-output-buffered-file) - 2156 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2162 # check output - 2163 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name/0") - 2164 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name/1") - 2165 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name/2") - 2166 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name/3") - 2167 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/4") - 2168 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name/5") - 2169 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name/6") - 2170 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name/7") - 2171 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/8") - 2172 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name/9") - 2173 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name/10") - 2174 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name/11") - 2175 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name/12") - 2176 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/13") - 2177 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name/14") - 2178 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name/15") - 2179 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name/16") - 2180 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/17") - 2181 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name/18") - 2182 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name/19") - 2183 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name/20") - 2184 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name/21") - 2185 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name/22") - 2186 # . epilogue - 2187 89/<- %esp 5/r32/ebp - 2188 5d/pop-to-ebp - 2189 c3/return - 2190 - 2191 test-shadow-name-2: - 2192 # . prologue - 2193 55/push-ebp - 2194 89/<- %ebp 4/r32/esp - 2195 # setup - 2196 (clear-stream _test-input-stream) - 2197 (clear-stream $_test-input-buffered-file->buffer) - 2198 (clear-stream _test-output-stream) - 2199 (clear-stream $_test-output-buffered-file->buffer) - 2200 # - 2201 (write _test-input-stream "fn foo {\n") - 2202 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2203 (write _test-input-stream " {\n") - 2204 (write _test-input-stream " var x/edx: int <- copy 4\n") - 2205 (write _test-input-stream " var y/ecx: int <- copy 5\n") - 2206 (write _test-input-stream " }\n") - 2207 (write _test-input-stream " x <- increment\n") - 2208 (write _test-input-stream "}\n") - 2209 # convert - 2210 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2211 (flush _test-output-buffered-file) - 2212 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2218 # check output - 2219 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name-2/0") - 2220 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name-2/1") - 2221 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name-2/2") - 2222 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name-2/3") - 2223 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/4") - 2224 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name-2/5") - 2225 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/6") - 2226 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name-2/7") - 2227 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/8") - 2228 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name-2/9") - 2229 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name-2/10") - 2230 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name-2/11") - 2231 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/12") - 2232 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 5/imm32" "F - test-shadow-name-2/13") - 2233 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/14") - 2234 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name-2/15") - 2235 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/16") - 2236 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name-2/17") - 2237 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name-2/18") - 2238 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/19") - 2239 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/20") - 2240 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name-2/21") - 2241 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name-2/22") - 2242 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name-2/23") - 2243 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name-2/24") - 2244 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name-2/25") - 2245 # . epilogue - 2246 89/<- %esp 5/r32/ebp - 2247 5d/pop-to-ebp - 2248 c3/return - 2249 - 2250 test-do-not-spill-same-register-in-block: - 2251 # . prologue - 2252 55/push-ebp - 2253 89/<- %ebp 4/r32/esp - 2254 # setup - 2255 (clear-stream _test-input-stream) - 2256 (clear-stream $_test-input-buffered-file->buffer) - 2257 (clear-stream _test-output-stream) - 2258 (clear-stream $_test-output-buffered-file->buffer) - 2259 # - 2260 (write _test-input-stream "fn foo {\n") - 2261 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2262 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2263 (write _test-input-stream " y <- increment\n") - 2264 (write _test-input-stream "}\n") - 2265 # convert - 2266 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2267 (flush _test-output-buffered-file) - 2268 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2274 # check output - 2275 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-do-not-spill-same-register-in-block/0") - 2276 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-do-not-spill-same-register-in-block/1") - 2277 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-do-not-spill-same-register-in-block/2") - 2278 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-do-not-spill-same-register-in-block/3") - 2279 (check-next-stream-line-equal _test-output-stream " {" "F - test-do-not-spill-same-register-in-block/4") - 2280 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-do-not-spill-same-register-in-block/5") - 2281 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-do-not-spill-same-register-in-block/6") - 2282 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-do-not-spill-same-register-in-block/7") - 2283 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-do-not-spill-same-register-in-block/8") - 2284 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-do-not-spill-same-register-in-block/9") - 2285 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-do-not-spill-same-register-in-block/10") - 2286 (check-next-stream-line-equal _test-output-stream " }" "F - test-do-not-spill-same-register-in-block/11") - 2287 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-do-not-spill-same-register-in-block/12") - 2288 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-do-not-spill-same-register-in-block/13") - 2289 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-do-not-spill-same-register-in-block/14") - 2290 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-do-not-spill-same-register-in-block/15") - 2291 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-do-not-spill-same-register-in-block/16") - 2292 # . epilogue - 2293 89/<- %esp 5/r32/ebp - 2294 5d/pop-to-ebp - 2295 c3/return - 2296 - 2297 test-spill-different-register-in-block: - 2298 # . prologue - 2299 55/push-ebp - 2300 89/<- %ebp 4/r32/esp - 2301 # setup - 2302 (clear-stream _test-input-stream) - 2303 (clear-stream $_test-input-buffered-file->buffer) - 2304 (clear-stream _test-output-stream) - 2305 (clear-stream $_test-output-buffered-file->buffer) - 2306 # - 2307 (write _test-input-stream "fn foo {\n") - 2308 (write _test-input-stream " var x/eax: int <- copy 3\n") - 2309 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2310 (write _test-input-stream " y <- increment\n") - 2311 (write _test-input-stream "}\n") - 2312 # convert - 2313 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2314 (flush _test-output-buffered-file) - 2315 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2321 # check output - 2322 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-spill-different-register-in-block/0") - 2323 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-spill-different-register-in-block/1") - 2324 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-spill-different-register-in-block/2") - 2325 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-spill-different-register-in-block/3") - 2326 (check-next-stream-line-equal _test-output-stream " {" "F - test-spill-different-register-in-block/4") - 2327 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-spill-different-register-in-block/5") - 2328 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-spill-different-register-in-block/6") - 2329 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-spill-different-register-in-block/7") - 2330 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-spill-different-register-in-block/8") - 2331 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-spill-different-register-in-block/9") - 2332 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-spill-different-register-in-block/10") - 2333 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-spill-different-register-in-block/11") - 2334 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-spill-different-register-in-block/12") - 2335 (check-next-stream-line-equal _test-output-stream " }" "F - test-spill-different-register-in-block/13") - 2336 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-spill-different-register-in-block/14") - 2337 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-spill-different-register-in-block/15") - 2338 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-spill-different-register-in-block/16") - 2339 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-spill-different-register-in-block/17") - 2340 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-spill-different-register-in-block/18") - 2341 # . epilogue - 2342 89/<- %esp 5/r32/ebp - 2343 5d/pop-to-ebp - 2344 c3/return - 2345 - 2346 test-shadow-live-output: - 2347 # . prologue - 2348 55/push-ebp - 2349 89/<- %ebp 4/r32/esp - 2350 # setup - 2351 (clear-stream _test-input-stream) - 2352 (clear-stream $_test-input-buffered-file->buffer) - 2353 (clear-stream _test-output-stream) - 2354 (clear-stream $_test-output-buffered-file->buffer) - 2355 # - 2356 (write _test-input-stream "fn foo -> x/ecx: int {\n") - 2357 (write _test-input-stream " x <- copy 3\n") - 2358 (write _test-input-stream " {\n") - 2359 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2360 (write _test-input-stream " }\n") - 2361 (write _test-input-stream " x <- increment\n") - 2362 (write _test-input-stream "}\n") - 2363 # convert - 2364 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2365 (flush _test-output-buffered-file) - 2366 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2372 # check output - 2373 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-live-output/0") - 2374 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-live-output/1") - 2375 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-live-output/2") - 2376 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-live-output/3") - 2377 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-output/4") - 2378 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-live-output/5") - 2379 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-live-output/7") # no push because it's an output reg - 2380 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-output/8") - 2381 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-live-output/9") - 2382 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-output/10") - 2383 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-live-output/11") - 2384 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-output/12") - 2385 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-output/13") - 2386 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-live-output/14") - 2387 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-live-output/15") - 2388 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-output/17") - 2389 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-live-output/18") - 2390 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-live-output/19") - 2391 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-live-output/20") - 2392 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-live-output/21") - 2393 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-live-output/21") - 2394 # . epilogue - 2395 89/<- %esp 5/r32/ebp - 2396 5d/pop-to-ebp - 2397 c3/return - 2398 - 2399 test-stmt-defines-output-in-same-register-as-inout: - 2400 # . prologue - 2401 55/push-ebp - 2402 89/<- %ebp 4/r32/esp - 2403 # setup - 2404 (clear-stream _test-input-stream) - 2405 (clear-stream $_test-input-buffered-file->buffer) - 2406 (clear-stream _test-output-stream) - 2407 (clear-stream $_test-output-buffered-file->buffer) - 2408 (clear-stream _test-error-stream) - 2409 (clear-stream $_test-error-buffered-file->buffer) - 2410 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 2411 68/push 0/imm32 - 2412 68/push 0/imm32 - 2413 89/<- %edx 4/r32/esp - 2414 (tailor-exit-descriptor %edx 0x10) - 2415 # - 2416 (write _test-input-stream "fn foo -> x/ecx: int {\n") - 2417 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2418 (write _test-input-stream " x <- copy y\n") # writing to a fn output is currently the only way for a statement to define a new var - 2419 (write _test-input-stream "}\n") - 2420 # convert - 2421 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 2422 # registers except esp clobbered at this point - 2423 # restore ed - 2424 89/<- %edx 4/r32/esp - 2425 (flush _test-output-buffered-file) - 2426 (flush _test-error-buffered-file) - 2427 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2433 # no error; we looked up 'y' correctly before pushing the binding for 'x' - 2434 (check-stream-equal _test-error-stream "" "F - test-stmt-defines-output-in-same-register-as-inout: error stream should be empty") - 2435 # don't bother checking the generated code; that's in the test 'test-local-clobbered-by-fn-output' below - 2436 # don't restore from ebp - 2437 81 0/subop/add %esp 8/imm32 - 2438 # . epilogue - 2439 5d/pop-to-ebp - 2440 c3/return - 2441 - 2442 test-local-clobbered-by-fn-output: - 2443 # . prologue - 2444 55/push-ebp - 2445 89/<- %ebp 4/r32/esp - 2446 # setup - 2447 (clear-stream _test-input-stream) - 2448 (clear-stream $_test-input-buffered-file->buffer) - 2449 (clear-stream _test-output-stream) - 2450 (clear-stream $_test-output-buffered-file->buffer) - 2451 # - 2452 (write _test-input-stream "fn foo -> x/ecx: int {\n") - 2453 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2454 (write _test-input-stream " x <- copy y\n") - 2455 (write _test-input-stream "}\n") - 2456 # convert - 2457 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2458 (flush _test-output-buffered-file) - 2459 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2465 # check output - 2466 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-local-clobbered-by-fn-output/0") - 2467 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-local-clobbered-by-fn-output/1") - 2468 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-local-clobbered-by-fn-output/2") - 2469 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-local-clobbered-by-fn-output/3") - 2470 (check-next-stream-line-equal _test-output-stream " {" "F - test-local-clobbered-by-fn-output/4") - 2471 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-local-clobbered-by-fn-output/5") - 2472 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-local-clobbered-by-fn-output/6") # no push because it's an output reg - 2473 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0x00000001/r32" "F - test-local-clobbered-by-fn-output/7") - 2474 (check-next-stream-line-equal _test-output-stream " }" "F - test-local-clobbered-by-fn-output/8") - 2475 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-local-clobbered-by-fn-output/9") - 2476 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-local-clobbered-by-fn-output/10") - 2477 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-local-clobbered-by-fn-output/11") - 2478 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-local-clobbered-by-fn-output/12") - 2479 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-local-clobbered-by-fn-output/13") - 2480 # . epilogue - 2481 89/<- %esp 5/r32/ebp - 2482 5d/pop-to-ebp - 2483 c3/return - 2484 - 2485 test-read-output: - 2486 # . prologue - 2487 55/push-ebp - 2488 89/<- %ebp 4/r32/esp - 2489 # setup - 2490 (clear-stream _test-input-stream) - 2491 (clear-stream $_test-input-buffered-file->buffer) - 2492 (clear-stream _test-output-stream) - 2493 (clear-stream $_test-output-buffered-file->buffer) - 2494 # - 2495 (write _test-input-stream "fn foo -> x/ecx: int {\n") - 2496 (write _test-input-stream " x <- copy 0x34\n") - 2497 (write _test-input-stream " compare x, 0x35\n") - 2498 (write _test-input-stream "}\n") - 2499 # convert - 2500 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2501 (flush _test-output-buffered-file) - 2502 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2508 # check output - 2509 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-read-output/0") - 2510 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-read-output/1") - 2511 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-read-output/2") - 2512 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-read-output/3") - 2513 (check-next-stream-line-equal _test-output-stream " {" "F - test-read-output/4") - 2514 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-read-output/5") - 2515 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x34/imm32" "F - test-read-output/6") - 2516 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0x35/imm32" "F - test-read-output/7") - 2517 (check-next-stream-line-equal _test-output-stream " }" "F - test-read-output/8") - 2518 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-read-output/9") - 2519 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-read-output/10") - 2520 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-read-output/11") - 2521 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-read-output/12") - 2522 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-read-output/13") - 2523 # . epilogue - 2524 89/<- %esp 5/r32/ebp - 2525 5d/pop-to-ebp - 2526 c3/return - 2527 - 2528 test-fn-output-written-in-inner-block: - 2529 # . prologue - 2530 55/push-ebp - 2531 89/<- %ebp 4/r32/esp - 2532 # setup - 2533 (clear-stream _test-input-stream) - 2534 (clear-stream $_test-input-buffered-file->buffer) - 2535 (clear-stream _test-output-stream) - 2536 (clear-stream $_test-output-buffered-file->buffer) - 2537 # - 2538 (write _test-input-stream "fn foo -> out/edi: int {\n") - 2539 (write _test-input-stream " var a/eax: int <- copy 3\n") # define outer local - 2540 (write _test-input-stream " {\n") - 2541 (write _test-input-stream " var a/ecx: int <- copy 4\n") # shadow outer local - 2542 (write _test-input-stream " out <- copy a\n") # write to fn output - 2543 (write _test-input-stream " }\n") - 2544 (write _test-input-stream " compare a, 0\n") # use outer local - 2545 (write _test-input-stream "}\n") - 2546 # convert - 2547 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2548 (flush _test-output-buffered-file) - 2549 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2555 # no error; defining 'out' didn't interfere with the reclamation of 'b' - 2556 # check output - 2557 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-fn-output-written-in-inner-block/0") - 2558 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-fn-output-written-in-inner-block/1") - 2559 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-fn-output-written-in-inner-block/2") - 2560 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-fn-output-written-in-inner-block/3") - 2561 (check-next-stream-line-equal _test-output-stream " {" "F - test-fn-output-written-in-inner-block/4") - 2562 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-fn-output-written-in-inner-block/5") - 2563 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-fn-output-written-in-inner-block/6") - 2564 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-fn-output-written-in-inner-block/7") - 2565 (check-next-stream-line-equal _test-output-stream " {" "F - test-fn-output-written-in-inner-block/8") - 2566 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-fn-output-written-in-inner-block/9") - 2567 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-fn-output-written-in-inner-block/10") - 2568 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-fn-output-written-in-inner-block/10") - 2569 (check-next-stream-line-equal _test-output-stream " 89/<- %edi 0x00000001/r32" "F - test-fn-output-written-in-inner-block/11") - 2570 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-fn-output-written-in-inner-block/12") - 2571 (check-next-stream-line-equal _test-output-stream " }" "F - test-fn-output-written-in-inner-block/13") - 2572 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-fn-output-written-in-inner-block/14") - 2573 (check-next-stream-line-equal _test-output-stream " 3d/compare-eax-with 0/imm32" "F - test-fn-output-written-in-inner-block/15") - 2574 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-fn-output-written-in-inner-block/16") - 2575 (check-next-stream-line-equal _test-output-stream " }" "F - test-fn-output-written-in-inner-block/17") - 2576 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-fn-output-written-in-inner-block/18") - 2577 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-fn-output-written-in-inner-block/19") - 2578 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-fn-output-written-in-inner-block/20") - 2579 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-fn-output-written-in-inner-block/21") - 2580 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-fn-output-written-in-inner-block/22") - 2581 # . epilogue - 2582 89/<- %esp 5/r32/ebp - 2583 5d/pop-to-ebp - 2584 c3/return - 2585 - 2586 test-convert-function-with-branches-in-block: - 2587 # . prologue - 2588 55/push-ebp - 2589 89/<- %ebp 4/r32/esp - 2590 # setup - 2591 (clear-stream _test-input-stream) - 2592 (clear-stream $_test-input-buffered-file->buffer) - 2593 (clear-stream _test-output-stream) - 2594 (clear-stream $_test-output-buffered-file->buffer) - 2595 # - 2596 (write _test-input-stream "fn foo x: int {\n") - 2597 (write _test-input-stream " {\n") - 2598 (write _test-input-stream " break-if->=\n") - 2599 (write _test-input-stream " loop-if-addr<\n") - 2600 (write _test-input-stream " increment x\n") - 2601 (write _test-input-stream " loop\n") - 2602 (write _test-input-stream " }\n") - 2603 (write _test-input-stream "}\n") - 2604 # convert - 2605 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2606 (flush _test-output-buffered-file) - 2607 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2613 # check output - 2614 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-block/0") - 2615 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1") - 2616 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2") - 2617 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3") - 2618 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4") - 2619 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5") - 2620 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6") - 2621 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7") - 2622 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/8") - 2623 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-block/9") - 2624 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-in-block/10") - 2625 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/11") - 2626 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/12") - 2627 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-block/13") - 2628 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-branches-in-block/14") - 2629 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/15") - 2630 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/16") - 2631 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/17") - 2632 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/18") - 2633 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/19") - 2634 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/20") - 2635 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/21") - 2636 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/22") - 2637 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/23") - 2638 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/24") - 2639 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/25") - 2640 # . epilogue - 2641 89/<- %esp 5/r32/ebp - 2642 5d/pop-to-ebp - 2643 c3/return - 2644 - 2645 test-convert-function-with-branches-in-named-block: - 2646 # . prologue - 2647 55/push-ebp - 2648 89/<- %ebp 4/r32/esp - 2649 # setup - 2650 (clear-stream _test-input-stream) - 2651 (clear-stream $_test-input-buffered-file->buffer) - 2652 (clear-stream _test-output-stream) - 2653 (clear-stream $_test-output-buffered-file->buffer) - 2654 # - 2655 (write _test-input-stream "fn foo x: int {\n") - 2656 (write _test-input-stream " $bar: {\n") - 2657 (write _test-input-stream " break-if->= $bar\n") - 2658 (write _test-input-stream " loop-if-addr< $bar\n") - 2659 (write _test-input-stream " increment x\n") - 2660 (write _test-input-stream " loop\n") - 2661 (write _test-input-stream " }\n") - 2662 (write _test-input-stream "}\n") - 2663 # convert - 2664 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2665 (flush _test-output-buffered-file) - 2666 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2672 # check output - 2673 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-named-block/0") - 2674 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-named-block/1") - 2675 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-named-block/2") - 2676 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-named-block/3") - 2677 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/4") - 2678 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-named-block/5") - 2679 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/6") - 2680 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-branches-in-named-block/7") - 2681 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/8") - 2682 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-named-block/9") - 2683 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:break/disp32" "F - test-convert-function-with-branches-in-named-block/10") - 2684 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/11") - 2685 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/12") - 2686 (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") - 2687 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:loop/disp32" "F - test-convert-function-with-branches-in-named-block/14") - 2688 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/15") - 2689 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-named-block/16") - 2690 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-named-block/17") - 2691 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/18") - 2692 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-branches-in-named-block/19") - 2693 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/20") - 2694 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-named-block/21") - 2695 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-named-block/22") - 2696 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-named-block/23") - 2697 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-named-block/24") - 2698 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-named-block/25") - 2699 # . epilogue - 2700 89/<- %esp 5/r32/ebp - 2701 5d/pop-to-ebp - 2702 c3/return - 2703 - 2704 test-convert-function-with-var-in-nested-block: - 2705 # . prologue - 2706 55/push-ebp - 2707 89/<- %ebp 4/r32/esp - 2708 # setup - 2709 (clear-stream _test-input-stream) - 2710 (clear-stream $_test-input-buffered-file->buffer) - 2711 (clear-stream _test-output-stream) - 2712 (clear-stream $_test-output-buffered-file->buffer) - 2713 # - 2714 (write _test-input-stream "fn foo x: int {\n") - 2715 (write _test-input-stream " {\n") - 2716 (write _test-input-stream " {\n") - 2717 (write _test-input-stream " var x: int\n") - 2718 (write _test-input-stream " increment x\n") - 2719 (write _test-input-stream " }\n") - 2720 (write _test-input-stream " }\n") - 2721 (write _test-input-stream "}\n") - 2722 # convert - 2723 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2724 (flush _test-output-buffered-file) - 2725 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2731 # check output - 2732 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-var-in-nested-block/0") - 2733 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-var-in-nested-block/1") - 2734 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-var-in-nested-block/2") - 2735 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-var-in-nested-block/3") - 2736 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/4") - 2737 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-var-in-nested-block/5") - 2738 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/6") - 2739 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-var-in-nested-block/7") - 2740 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/8") - 2741 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-var-in-nested-block/9") - 2742 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-var-in-nested-block/10") - 2743 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-var-in-nested-block/11") - 2744 (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") - 2745 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/13") - 2746 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-var-in-nested-block/14") - 2747 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/15") - 2748 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-var-in-nested-block/16") - 2749 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/17") - 2750 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-var-in-nested-block/18") - 2751 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-var-in-nested-block/19") - 2752 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-var-in-nested-block/20") - 2753 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-var-in-nested-block/21") - 2754 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-var-in-nested-block/22") - 2755 # . epilogue - 2756 89/<- %esp 5/r32/ebp - 2757 5d/pop-to-ebp - 2758 c3/return - 2759 - 2760 test-convert-function-with-multiple-vars-in-nested-blocks: - 2761 # . prologue - 2762 55/push-ebp - 2763 89/<- %ebp 4/r32/esp - 2764 # setup - 2765 (clear-stream _test-input-stream) - 2766 (clear-stream $_test-input-buffered-file->buffer) - 2767 (clear-stream _test-output-stream) - 2768 (clear-stream $_test-output-buffered-file->buffer) - 2769 # - 2770 (write _test-input-stream "fn foo x: int {\n") - 2771 (write _test-input-stream " {\n") - 2772 (write _test-input-stream " var x/eax: int <- copy 0\n") - 2773 (write _test-input-stream " {\n") - 2774 (write _test-input-stream " var y: int\n") - 2775 (write _test-input-stream " x <- add y\n") - 2776 (write _test-input-stream " }\n") - 2777 (write _test-input-stream " }\n") - 2778 (write _test-input-stream "}\n") - 2779 # convert - 2780 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2781 (flush _test-output-buffered-file) - 2782 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2788 # check output - 2789 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/0") - 2790 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/1") - 2791 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/2") - 2792 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/3") - 2793 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/4") - 2794 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/5") - 2795 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/6") - 2796 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/7") - 2797 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/8") - 2798 (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") - 2799 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/10") - 2800 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/11") - 2801 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/12") - 2802 (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") - 2803 (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") - 2804 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/15") - 2805 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/16") - 2806 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/17") - 2807 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/18") - 2808 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/19") - 2809 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/20") - 2810 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/21") - 2811 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/22") - 2812 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/23") - 2813 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/24") - 2814 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-multiple-vars-in-nested-blocks/25") - 2815 # . epilogue - 2816 89/<- %esp 5/r32/ebp - 2817 5d/pop-to-ebp - 2818 c3/return - 2819 - 2820 test-convert-function-with-branches-and-local-vars: - 2821 # A conditional 'break' after a 'var' in a block is converted into a - 2822 # nested block that performs all necessary cleanup before jumping. This - 2823 # results in some ugly code duplication. - 2824 # . prologue - 2825 55/push-ebp - 2826 89/<- %ebp 4/r32/esp - 2827 # setup - 2828 (clear-stream _test-input-stream) - 2829 (clear-stream $_test-input-buffered-file->buffer) - 2830 (clear-stream _test-output-stream) - 2831 (clear-stream $_test-output-buffered-file->buffer) - 2832 # - 2833 (write _test-input-stream "fn foo {\n") - 2834 (write _test-input-stream " {\n") - 2835 (write _test-input-stream " var x: int\n") - 2836 (write _test-input-stream " break-if->=\n") - 2837 (write _test-input-stream " increment x\n") - 2838 (write _test-input-stream " }\n") - 2839 (write _test-input-stream "}\n") - 2840 # convert - 2841 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2842 (flush _test-output-buffered-file) - 2843 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2849 # check output - 2850 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-local-vars/0") - 2851 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-local-vars/1") - 2852 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-local-vars/2") - 2853 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-local-vars/3") - 2854 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/4") - 2855 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-local-vars/5") - 2856 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/6") - 2857 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-local-vars/7") - 2858 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-local-vars/8") - 2859 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/9") - 2860 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-local-vars/10") - 2861 (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") - 2862 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-local-vars/12") - 2863 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/13") - 2864 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-local-vars/14") - 2865 (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") - 2866 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/16") - 2867 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-local-vars/17") - 2868 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/18") - 2869 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-local-vars/19") - 2870 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-local-vars/20") - 2871 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-local-vars/21") - 2872 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-local-vars/22") - 2873 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-local-vars/23") - 2874 # . epilogue - 2875 89/<- %esp 5/r32/ebp - 2876 5d/pop-to-ebp - 2877 c3/return - 2878 - 2879 test-convert-function-with-conditional-loops-and-local-vars: - 2880 # A conditional 'loop' after a 'var' in a block is converted into a nested - 2881 # block that performs all necessary cleanup before jumping. This results - 2882 # in some ugly code duplication. - 2883 # . prologue - 2884 55/push-ebp - 2885 89/<- %ebp 4/r32/esp - 2886 # setup - 2887 (clear-stream _test-input-stream) - 2888 (clear-stream $_test-input-buffered-file->buffer) - 2889 (clear-stream _test-output-stream) - 2890 (clear-stream $_test-output-buffered-file->buffer) - 2891 # - 2892 (write _test-input-stream "fn foo {\n") - 2893 (write _test-input-stream " {\n") - 2894 (write _test-input-stream " var x: int\n") - 2895 (write _test-input-stream " loop-if->=\n") - 2896 (write _test-input-stream " increment x\n") - 2897 (write _test-input-stream " }\n") - 2898 (write _test-input-stream "}\n") - 2899 # convert - 2900 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2901 (flush _test-output-buffered-file) - 2902 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2908 # check output - 2909 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-conditional-loops-and-local-vars/0") - 2910 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-conditional-loops-and-local-vars/1") - 2911 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/2") - 2912 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-conditional-loops-and-local-vars/3") - 2913 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/4") - 2914 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/5") - 2915 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/6") - 2916 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/7") - 2917 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/8") - 2918 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/9") - 2919 (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") - 2920 (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") - 2921 (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") - 2922 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/13") - 2923 (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") - 2924 (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") - 2925 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/16") - 2926 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/17") - 2927 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/18") - 2928 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/19") - 2929 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-conditional-loops-and-local-vars/20") - 2930 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/21") - 2931 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/22") - 2932 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-conditional-loops-and-local-vars/23") - 2933 # . epilogue - 2934 89/<- %esp 5/r32/ebp - 2935 5d/pop-to-ebp - 2936 c3/return - 2937 - 2938 test-convert-function-with-unconditional-loops-and-local-vars: - 2939 # An unconditional 'loop' after a 'var' in a block is emitted _after_ the - 2940 # regular block cleanup. Any instructions after 'loop' are dead and - 2941 # therefore skipped. - 2942 # . prologue - 2943 55/push-ebp - 2944 89/<- %ebp 4/r32/esp - 2945 # setup - 2946 (clear-stream _test-input-stream) - 2947 (clear-stream $_test-input-buffered-file->buffer) - 2948 (clear-stream _test-output-stream) - 2949 (clear-stream $_test-output-buffered-file->buffer) - 2950 # - 2951 (write _test-input-stream "fn foo {\n") - 2952 (write _test-input-stream " {\n") - 2953 (write _test-input-stream " var x: int\n") - 2954 (write _test-input-stream " loop\n") - 2955 (write _test-input-stream " increment x\n") - 2956 (write _test-input-stream " }\n") - 2957 (write _test-input-stream "}\n") - 2958 # convert - 2959 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2960 (flush _test-output-buffered-file) - 2961 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2967 # check output - 2968 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-loops-and-local-vars/0") - 2969 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-loops-and-local-vars/1") - 2970 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/2") - 2971 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-loops-and-local-vars/3") - 2972 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/4") - 2973 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/5") - 2974 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/6") - 2975 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/7") - 2976 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/8") - 2977 (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") - 2978 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-unconditional-loops-and-local-vars/10") - 2979 # not emitted: ff 0/subop/increment *(ebp+0xfffffffc) - 2980 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/11") - 2981 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/12") - 2982 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/13") - 2983 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/14") - 2984 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-loops-and-local-vars/15") - 2985 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/16") - 2986 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/17") - 2987 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-loops-and-local-vars/18") - 2988 # . epilogue - 2989 89/<- %esp 5/r32/ebp - 2990 5d/pop-to-ebp - 2991 c3/return - 2992 - 2993 test-convert-function-with-branches-and-loops-and-local-vars: - 2994 # . prologue - 2995 55/push-ebp - 2996 89/<- %ebp 4/r32/esp - 2997 # setup - 2998 (clear-stream _test-input-stream) - 2999 (clear-stream $_test-input-buffered-file->buffer) - 3000 (clear-stream _test-output-stream) - 3001 (clear-stream $_test-output-buffered-file->buffer) - 3002 # - 3003 (write _test-input-stream "fn foo {\n") - 3004 (write _test-input-stream " {\n") - 3005 (write _test-input-stream " var x: int\n") - 3006 (write _test-input-stream " break-if->=\n") - 3007 (write _test-input-stream " increment x\n") - 3008 (write _test-input-stream " loop\n") - 3009 (write _test-input-stream " }\n") - 3010 (write _test-input-stream "}\n") - 3011 # convert - 3012 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3013 (flush _test-output-buffered-file) - 3014 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3020 # check output - 3021 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-loops-and-local-vars/0") - 3022 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-loops-and-local-vars/1") - 3023 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/2") - 3024 (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") - 3025 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/4") - 3026 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/5") - 3027 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/6") - 3028 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/7") - 3029 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/8") - 3030 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/9") - 3031 (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") - 3032 (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") - 3033 (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") - 3034 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/13") - 3035 (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") - 3036 (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") - 3037 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/16") - 3038 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/17") - 3039 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/18") - 3040 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/19") - 3041 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/20") - 3042 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-loops-and-local-vars/21") - 3043 (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") - 3044 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/23") - 3045 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-loops-and-local-vars/24") - 3046 # . epilogue - 3047 89/<- %esp 5/r32/ebp - 3048 5d/pop-to-ebp - 3049 c3/return - 3050 - 3051 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars: - 3052 # . prologue - 3053 55/push-ebp - 3054 89/<- %ebp 4/r32/esp - 3055 # setup - 3056 (clear-stream _test-input-stream) - 3057 (clear-stream $_test-input-buffered-file->buffer) - 3058 (clear-stream _test-output-stream) - 3059 (clear-stream $_test-output-buffered-file->buffer) - 3060 # - 3061 (write _test-input-stream "fn foo {\n") - 3062 (write _test-input-stream " a: {\n") - 3063 (write _test-input-stream " var x: int\n") - 3064 (write _test-input-stream " {\n") - 3065 (write _test-input-stream " var y: int\n") - 3066 (write _test-input-stream " break-if->= a\n") - 3067 (write _test-input-stream " increment x\n") - 3068 (write _test-input-stream " loop\n") - 3069 (write _test-input-stream " }\n") - 3070 (write _test-input-stream " }\n") - 3071 (write _test-input-stream "}\n") - 3072 # convert - 3073 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3074 (flush _test-output-buffered-file) - 3075 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3081 # check output - 3082 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/0") - 3083 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/1") - 3084 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/2") - 3085 (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") - 3086 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/4") - 3087 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/5") - 3088 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/6") - 3089 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/7") - 3090 (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") - 3091 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/9") - 3092 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/10") - 3093 (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") - 3094 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/12") - 3095 (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") - 3096 (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") - 3097 (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") - 3098 (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") - 3099 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/17") - 3100 (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") - 3101 (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") - 3102 (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") - 3103 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/21") - 3104 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/22") - 3105 (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") - 3106 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/24") - 3107 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/25") - 3108 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/26") - 3109 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/27") - 3110 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/28") - 3111 (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") - 3112 (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") - 3113 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/31") - 3114 # . epilogue - 3115 89/<- %esp 5/r32/ebp - 3116 5d/pop-to-ebp - 3117 c3/return - 3118 - 3119 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2: - 3120 # . prologue - 3121 55/push-ebp - 3122 89/<- %ebp 4/r32/esp - 3123 # setup - 3124 (clear-stream _test-input-stream) - 3125 (clear-stream $_test-input-buffered-file->buffer) - 3126 (clear-stream _test-output-stream) - 3127 (clear-stream $_test-output-buffered-file->buffer) - 3128 # non-local conditional branch from a block without a local variable, - 3129 # unwinding a local on the stack - 3130 (write _test-input-stream "fn foo {\n") - 3131 (write _test-input-stream " a: {\n") - 3132 (write _test-input-stream " var x: int\n") - 3133 (write _test-input-stream " {\n") - 3134 (write _test-input-stream " break-if->= a\n") - 3135 (write _test-input-stream " }\n") - 3136 (write _test-input-stream " }\n") - 3137 (write _test-input-stream "}\n") - 3138 # convert - 3139 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3140 (flush _test-output-buffered-file) - 3141 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3147 # check output - 3148 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/0") - 3149 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/1") - 3150 (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") - 3151 (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") - 3152 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/4") - 3153 (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") - 3154 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/6") - 3155 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/7") - 3156 (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") - 3157 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/9") - 3158 (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") - 3159 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/11") - 3160 (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") - 3161 (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") - 3162 (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") - 3163 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/15") - 3164 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/16") - 3165 (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") - 3166 (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") - 3167 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/19") - 3168 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/20") - 3169 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/21") - 3170 (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") - 3171 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/23") - 3172 (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") - 3173 (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") - 3174 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/26") - 3175 # . epilogue - 3176 89/<- %esp 5/r32/ebp - 3177 5d/pop-to-ebp - 3178 c3/return - 3179 - 3180 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3: - 3181 # . prologue - 3182 55/push-ebp - 3183 89/<- %ebp 4/r32/esp - 3184 # setup - 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 # non-local unconditional branch from a block without a local variable, - 3190 # unwinding a local on the stack - 3191 (write _test-input-stream "fn foo {\n") - 3192 (write _test-input-stream " a: {\n") - 3193 (write _test-input-stream " var x: int\n") - 3194 (write _test-input-stream " {\n") - 3195 (write _test-input-stream " break a\n") - 3196 (write _test-input-stream " }\n") - 3197 (write _test-input-stream " }\n") - 3198 (write _test-input-stream "}\n") - 3199 # convert - 3200 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3201 (flush _test-output-buffered-file) - 3202 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3208 # check output - 3209 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/0") - 3210 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/1") - 3211 (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") - 3212 (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") - 3213 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/4") - 3214 (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") - 3215 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/6") - 3216 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/7") - 3217 (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") - 3218 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/9") - 3219 (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") - 3220 (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") - 3221 (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") - 3222 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/14") - 3223 (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") - 3224 (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") - 3225 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/17") - 3226 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/18") - 3227 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/19") - 3228 (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") - 3229 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/21") - 3230 (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") - 3231 (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") - 3232 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/24") - 3233 # . epilogue - 3234 89/<- %esp 5/r32/ebp - 3235 5d/pop-to-ebp - 3236 c3/return - 3237 - 3238 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4: - 3239 # . prologue - 3240 55/push-ebp - 3241 89/<- %ebp 4/r32/esp - 3242 # setup - 3243 (clear-stream _test-input-stream) - 3244 (clear-stream $_test-input-buffered-file->buffer) - 3245 (clear-stream _test-output-stream) - 3246 (clear-stream $_test-output-buffered-file->buffer) - 3247 # - 3248 (write _test-input-stream "fn foo {\n") - 3249 (write _test-input-stream " a: {\n") - 3250 (write _test-input-stream " var x/esi: int <- copy 0\n") - 3251 (write _test-input-stream " {\n") - 3252 (write _test-input-stream " break a\n") - 3253 (write _test-input-stream " }\n") - 3254 (write _test-input-stream " }\n") - 3255 (write _test-input-stream "}\n") - 3256 # convert - 3257 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3258 (flush _test-output-buffered-file) - 3259 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3265 # check output - 3266 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/0") - 3267 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/1") - 3268 (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") - 3269 (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") - 3270 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/4") - 3271 (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") - 3272 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/6") - 3273 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/7") - 3274 (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") - 3275 (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") - 3276 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/10") - 3277 (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") - 3278 (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") - 3279 (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") - 3280 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/14") - 3281 (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") - 3282 (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") - 3283 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/17") - 3284 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/18") - 3285 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/19") - 3286 (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") - 3287 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/21") - 3288 (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") - 3289 (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") - 3290 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/24") - 3291 # . epilogue - 3292 89/<- %esp 5/r32/ebp - 3293 5d/pop-to-ebp - 3294 c3/return - 3295 - 3296 test-convert-function-with-nonlocal-unconditional-break-and-local-vars: - 3297 # . prologue - 3298 55/push-ebp - 3299 89/<- %ebp 4/r32/esp - 3300 # setup - 3301 (clear-stream _test-input-stream) - 3302 (clear-stream $_test-input-buffered-file->buffer) - 3303 (clear-stream _test-output-stream) - 3304 (clear-stream $_test-output-buffered-file->buffer) - 3305 # - 3306 (write _test-input-stream "fn foo {\n") - 3307 (write _test-input-stream " a: {\n") - 3308 (write _test-input-stream " var x: int\n") - 3309 (write _test-input-stream " {\n") - 3310 (write _test-input-stream " var y: int\n") - 3311 (write _test-input-stream " break a\n") - 3312 (write _test-input-stream " increment x\n") - 3313 (write _test-input-stream " }\n") - 3314 (write _test-input-stream " }\n") - 3315 (write _test-input-stream "}\n") - 3316 # convert - 3317 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3318 (flush _test-output-buffered-file) - 3319 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3325 # check output - 3326 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/0") - 3327 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/1") - 3328 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/2") - 3329 (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") - 3330 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/4") - 3331 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/5") - 3332 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/6") - 3333 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/7") - 3334 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/8") - 3335 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/9") - 3336 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/10") - 3337 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/11") - 3338 (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") - 3339 (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") - 3340 (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") - 3341 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/15") - 3342 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/16") - 3343 (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") - 3344 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/18") - 3345 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/19") - 3346 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/20") - 3347 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/21") - 3348 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/22") - 3349 (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") - 3350 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/24") - 3351 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/25") - 3352 # . epilogue - 3353 89/<- %esp 5/r32/ebp - 3354 5d/pop-to-ebp - 3355 c3/return - 3356 - 3357 test-convert-function-with-unconditional-break-and-local-vars: - 3358 # . prologue - 3359 55/push-ebp - 3360 89/<- %ebp 4/r32/esp - 3361 # setup - 3362 (clear-stream _test-input-stream) - 3363 (clear-stream $_test-input-buffered-file->buffer) - 3364 (clear-stream _test-output-stream) - 3365 (clear-stream $_test-output-buffered-file->buffer) - 3366 # - 3367 (write _test-input-stream "fn foo {\n") - 3368 (write _test-input-stream " {\n") - 3369 (write _test-input-stream " var x: int\n") - 3370 (write _test-input-stream " {\n") - 3371 (write _test-input-stream " var y: int\n") - 3372 (write _test-input-stream " break\n") - 3373 (write _test-input-stream " increment x\n") - 3374 (write _test-input-stream " }\n") - 3375 (write _test-input-stream " }\n") - 3376 (write _test-input-stream "}\n") - 3377 # convert - 3378 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3379 (flush _test-output-buffered-file) - 3380 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3386 # check output - 3387 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-break-and-local-vars/0") - 3388 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-break-and-local-vars/1") - 3389 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/2") - 3390 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-break-and-local-vars/3") - 3391 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/4") - 3392 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/5") - 3393 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/6") - 3394 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/7") - 3395 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/8") - 3396 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/9") - 3397 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/10") - 3398 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/11") - 3399 (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") - 3400 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/13") - 3401 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/14") - 3402 (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") - 3403 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/16") - 3404 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/17") - 3405 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/18") - 3406 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/19") - 3407 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-break-and-local-vars/20") - 3408 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/21") - 3409 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/22") - 3410 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-break-and-local-vars/23") - 3411 # . epilogue - 3412 89/<- %esp 5/r32/ebp - 3413 5d/pop-to-ebp - 3414 c3/return - 3415 - 3416 test-convert-function-with-nonlocal-unconditional-loop-and-local-vars: - 3417 # . prologue - 3418 55/push-ebp - 3419 89/<- %ebp 4/r32/esp - 3420 # setup - 3421 (clear-stream _test-input-stream) - 3422 (clear-stream $_test-input-buffered-file->buffer) - 3423 (clear-stream _test-output-stream) - 3424 (clear-stream $_test-output-buffered-file->buffer) - 3425 # - 3426 (write _test-input-stream "fn foo {\n") - 3427 (write _test-input-stream " a: {\n") - 3428 (write _test-input-stream " var x: int\n") - 3429 (write _test-input-stream " {\n") - 3430 (write _test-input-stream " var y: int\n") - 3431 (write _test-input-stream " loop a\n") - 3432 (write _test-input-stream " increment x\n") - 3433 (write _test-input-stream " }\n") - 3434 (write _test-input-stream " }\n") - 3435 (write _test-input-stream "}\n") - 3436 # convert - 3437 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3438 (flush _test-output-buffered-file) - 3439 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3445 # check output - 3446 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/0") - 3447 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/1") - 3448 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/2") - 3449 (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") - 3450 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/4") - 3451 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/5") - 3452 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/6") - 3453 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/7") - 3454 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/8") - 3455 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/9") - 3456 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/10") - 3457 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/11") - 3458 (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") - 3459 (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") - 3460 (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") - 3461 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/15") - 3462 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/16") - 3463 (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") - 3464 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/18") - 3465 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/19") - 3466 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/20") - 3467 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/21") - 3468 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/22") - 3469 (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") - 3470 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/24") - 3471 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/25") - 3472 # . epilogue - 3473 89/<- %esp 5/r32/ebp - 3474 5d/pop-to-ebp - 3475 c3/return - 3476 - 3477 test-convert-function-with-local-array-var-in-mem: - 3478 # . prologue - 3479 55/push-ebp - 3480 89/<- %ebp 4/r32/esp - 3481 # setup - 3482 (clear-stream _test-input-stream) - 3483 (clear-stream $_test-input-buffered-file->buffer) - 3484 (clear-stream _test-output-stream) - 3485 (clear-stream $_test-output-buffered-file->buffer) - 3486 # - 3487 (write _test-input-stream "fn foo {\n") - 3488 (write _test-input-stream " var x: (array int 3)\n") - 3489 (write _test-input-stream "}\n") - 3490 # convert - 3491 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3492 (flush _test-output-buffered-file) - 3493 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3499 # check output - 3500 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-var-in-mem/0") - 3501 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-var-in-mem/1") - 3502 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-var-in-mem/2") - 3503 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-array-var-in-mem/3") - 3504 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-var-in-mem/4") - 3505 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-var-in-mem/5") - 3506 # define x - 3507 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-function-with-local-array-var-in-mem/7") - 3508 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-function-with-local-array-var-in-mem/8") - 3509 # reclaim x - 3510 (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") - 3511 # - 3512 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-var-in-mem/10") - 3513 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-var-in-mem/11") - 3514 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-var-in-mem/12") - 3515 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-array-var-in-mem/13") - 3516 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-var-in-mem/14") - 3517 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-var-in-mem/15") - 3518 # . epilogue - 3519 89/<- %esp 5/r32/ebp - 3520 5d/pop-to-ebp - 3521 c3/return - 3522 - 3523 # special-case for size(byte) when allocating array - 3524 test-convert-function-with-local-array-of-bytes-in-mem: - 3525 # . prologue - 3526 55/push-ebp - 3527 89/<- %ebp 4/r32/esp - 3528 # setup - 3529 (clear-stream _test-input-stream) - 3530 (clear-stream $_test-input-buffered-file->buffer) - 3531 (clear-stream _test-output-stream) - 3532 (clear-stream $_test-output-buffered-file->buffer) - 3533 # - 3534 (write _test-input-stream "fn foo {\n") - 3535 (write _test-input-stream " var x: (array byte 3)\n") - 3536 (write _test-input-stream "}\n") - 3537 # convert - 3538 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3539 (flush _test-output-buffered-file) - 3540 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3546 # check output - 3547 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-of-bytes-in-mem/0") - 3548 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-of-bytes-in-mem/1") - 3549 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/2") - 3550 (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") - 3551 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-of-bytes-in-mem/4") - 3552 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-of-bytes-in-mem/5") - 3553 # define x - 3554 (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") - 3555 (check-next-stream-line-equal _test-output-stream " 68/push 0x00000003/imm32" "F - test-convert-function-with-local-array-of-bytes-in-mem/8") - 3556 # reclaim x - 3557 (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") - 3558 # - 3559 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-of-bytes-in-mem/10") - 3560 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-of-bytes-in-mem/11") - 3561 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-of-bytes-in-mem/12") - 3562 (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") - 3563 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/14") - 3564 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-of-bytes-in-mem/15") - 3565 # . epilogue - 3566 89/<- %esp 5/r32/ebp - 3567 5d/pop-to-ebp - 3568 c3/return - 3569 - 3570 test-convert-address: - 3571 # . prologue - 3572 55/push-ebp - 3573 89/<- %ebp 4/r32/esp - 3574 # setup - 3575 (clear-stream _test-input-stream) - 3576 (clear-stream $_test-input-buffered-file->buffer) - 3577 (clear-stream _test-output-stream) - 3578 (clear-stream $_test-output-buffered-file->buffer) - 3579 # - 3580 (write _test-input-stream "fn foo {\n") - 3581 (write _test-input-stream " var a: int\n") - 3582 (write _test-input-stream " var b/eax: (addr int) <- address a\n") - 3583 (write _test-input-stream "}\n") - 3584 # convert - 3585 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3586 (flush _test-output-buffered-file) - 3587 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3593 # check output - 3594 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-address/0") - 3595 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-address/1") - 3596 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-address/2") - 3597 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-address/3") - 3598 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-address/4") - 3599 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-address/5") - 3600 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-address/6") - 3601 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-address/7") - 3602 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-address/8") - 3603 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-address/9") - 3604 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-address/10") - 3605 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-address/11") - 3606 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-address/12") - 3607 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-address/13") - 3608 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-address/14") - 3609 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-address/15") - 3610 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-address/16") - 3611 # . epilogue - 3612 89/<- %esp 5/r32/ebp - 3613 5d/pop-to-ebp - 3614 c3/return - 3615 - 3616 test-convert-length-of-array: - 3617 # . prologue - 3618 55/push-ebp - 3619 89/<- %ebp 4/r32/esp - 3620 # setup - 3621 (clear-stream _test-input-stream) - 3622 (clear-stream $_test-input-buffered-file->buffer) - 3623 (clear-stream _test-output-stream) - 3624 (clear-stream $_test-output-buffered-file->buffer) - 3625 # - 3626 (write _test-input-stream "fn foo a: (addr array int) {\n") - 3627 (write _test-input-stream " var b/eax: (addr array int) <- copy a\n") - 3628 (write _test-input-stream " var c/eax: int <- length b\n") - 3629 (write _test-input-stream "}\n") - 3630 # convert - 3631 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3632 (flush _test-output-buffered-file) - 3633 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3639 # check output - 3640 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array/0") - 3641 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array/1") - 3642 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array/2") - 3643 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array/3") - 3644 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array/4") - 3645 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array/5") - 3646 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array/6") - 3647 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array/7") - 3648 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array/8") - 3649 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array/9") - 3650 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array/10") - 3651 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array/11") - 3652 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array/12") - 3653 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array/13") - 3654 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array/14") - 3655 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array/15") - 3656 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array/16") - 3657 # . epilogue - 3658 89/<- %esp 5/r32/ebp - 3659 5d/pop-to-ebp - 3660 c3/return - 3661 - 3662 # special-case for size(byte) when computing array length - 3663 test-convert-length-of-array-of-bytes: - 3664 # . prologue - 3665 55/push-ebp - 3666 89/<- %ebp 4/r32/esp - 3667 # setup - 3668 (clear-stream _test-input-stream) - 3669 (clear-stream $_test-input-buffered-file->buffer) - 3670 (clear-stream _test-output-stream) - 3671 (clear-stream $_test-output-buffered-file->buffer) - 3672 # - 3673 (write _test-input-stream "fn foo a: (addr array byte) {\n") - 3674 (write _test-input-stream " var b/eax: (addr array byte) <- copy a\n") - 3675 (write _test-input-stream " var c/eax: int <- length b\n") - 3676 (write _test-input-stream "}\n") - 3677 # convert - 3678 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3679 (flush _test-output-buffered-file) - 3680 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3686 # check output - 3687 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-bytes/0") - 3688 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-bytes/1") - 3689 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-bytes/2") - 3690 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-bytes/3") - 3691 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-bytes/4") - 3692 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-bytes/5") - 3693 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-bytes/6") - 3694 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/7") - 3695 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/8") - 3696 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-bytes/9") - 3697 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-bytes/10") - 3698 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-bytes/11") - 3699 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-bytes/12") - 3700 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-bytes/13") - 3701 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-bytes/14") - 3702 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-bytes/15") - 3703 # . epilogue - 3704 89/<- %esp 5/r32/ebp - 3705 5d/pop-to-ebp - 3706 c3/return - 3707 - 3708 test-convert-length-of-array-on-stack: - 3709 # . prologue - 3710 55/push-ebp - 3711 89/<- %ebp 4/r32/esp - 3712 # setup - 3713 (clear-stream _test-input-stream) - 3714 (clear-stream $_test-input-buffered-file->buffer) - 3715 (clear-stream _test-output-stream) - 3716 (clear-stream $_test-output-buffered-file->buffer) - 3717 # - 3718 (write _test-input-stream "fn foo {\n") - 3719 (write _test-input-stream " var a: (array int 3)\n") - 3720 (write _test-input-stream " var b/eax: int <- length a\n") - 3721 (write _test-input-stream "}\n") - 3722 # convert - 3723 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3724 (flush _test-output-buffered-file) - 3725 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3731 # check output - 3732 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-on-stack/0") - 3733 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-on-stack/1") - 3734 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-on-stack/2") - 3735 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-on-stack/3") - 3736 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-on-stack/4") - 3737 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-on-stack/5") - 3738 # define x - 3739 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-length-of-array-on-stack/6") - 3740 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-length-of-array-on-stack/7") - 3741 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-on-stack/8") - 3742 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff0) 0x00000000/r32" "F - test-convert-length-of-array-on-stack/9") - 3743 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array-on-stack/10") - 3744 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-on-stack/11") - 3745 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-length-of-array-on-stack/12") - 3746 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-on-stack/13") - 3747 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-on-stack/14") - 3748 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-on-stack/15") - 3749 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-on-stack/16") - 3750 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-on-stack/17") - 3751 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-on-stack/18") - 3752 # . epilogue - 3753 89/<- %esp 5/r32/ebp - 3754 5d/pop-to-ebp - 3755 c3/return - 3756 - 3757 test-reg-var-def-with-read-of-same-register: - 3758 # . prologue - 3759 55/push-ebp - 3760 89/<- %ebp 4/r32/esp - 3761 # setup - 3762 (clear-stream _test-input-stream) - 3763 (clear-stream $_test-input-buffered-file->buffer) - 3764 (clear-stream _test-output-stream) - 3765 (clear-stream $_test-output-buffered-file->buffer) - 3766 (clear-stream _test-error-stream) - 3767 (clear-stream $_test-error-buffered-file->buffer) - 3768 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu - 3769 68/push 0/imm32 - 3770 68/push 0/imm32 - 3771 89/<- %edx 4/r32/esp - 3772 (tailor-exit-descriptor %edx 0x10) - 3773 # - 3774 (write _test-input-stream "fn foo {\n") - 3775 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 3776 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 3777 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 3778 (write _test-input-stream "}\n") - 3779 # convert - 3780 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3781 # registers except esp could be clobbered at this point (though they shouldn't be) - 3782 # restore ed - 3783 89/<- %edx 4/r32/esp - 3784 (flush _test-output-buffered-file) - 3785 (flush _test-error-buffered-file) - 3786 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3792 (check-stream-equal _test-error-stream "" "F - test-reg-var-def-with-read-of-same-register: error stream should be empty") - 3793 # check output - 3794 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-reg-var-def-with-read-of-same-register/0") - 3795 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-reg-var-def-with-read-of-same-register/1") - 3796 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-reg-var-def-with-read-of-same-register/2") - 3797 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-reg-var-def-with-read-of-same-register/3") - 3798 (check-next-stream-line-equal _test-output-stream " {" "F - test-reg-var-def-with-read-of-same-register/4") - 3799 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-reg-var-def-with-read-of-same-register/5") - 3800 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-reg-var-def-with-read-of-same-register/6") - 3801 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-reg-var-def-with-read-of-same-register/7") - 3802 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-reg-var-def-with-read-of-same-register/8") - 3803 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-reg-var-def-with-read-of-same-register/9") - 3804 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-reg-var-def-with-read-of-same-register/11") - 3805 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-reg-var-def-with-read-of-same-register/13") - 3806 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-reg-var-def-with-read-of-same-register/14") - 3807 (check-next-stream-line-equal _test-output-stream " }" "F - test-reg-var-def-with-read-of-same-register/15") - 3808 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-reg-var-def-with-read-of-same-register/16") - 3809 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-reg-var-def-with-read-of-same-register/17") - 3810 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-reg-var-def-with-read-of-same-register/18") - 3811 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-reg-var-def-with-read-of-same-register/19") - 3812 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-reg-var-def-with-read-of-same-register/20") - 3813 # don't restore from ebp - 3814 81 0/subop/add %esp 8/imm32 - 3815 # . epilogue - 3816 5d/pop-to-ebp - 3817 c3/return - 3818 - 3819 test-convert-index-into-array: - 3820 # . prologue - 3821 55/push-ebp - 3822 89/<- %ebp 4/r32/esp - 3823 # setup - 3824 (clear-stream _test-input-stream) - 3825 (clear-stream $_test-input-buffered-file->buffer) - 3826 (clear-stream _test-output-stream) - 3827 (clear-stream $_test-output-buffered-file->buffer) - 3828 # - 3829 (write _test-input-stream "fn foo {\n") - 3830 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 3831 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 3832 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 3833 (write _test-input-stream "}\n") - 3834 # convert - 3835 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3836 (flush _test-output-buffered-file) - 3837 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3843 # check output - 3844 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array/0") - 3845 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array/1") - 3846 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array/2") - 3847 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array/3") - 3848 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array/4") - 3849 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array/5") - 3850 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array/6") - 3851 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array/7") - 3852 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array/8") - 3853 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array/9") - 3854 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-convert-index-into-array/10") - 3855 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array/11") - 3856 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array/12") - 3857 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array/13") - 3858 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array/14") - 3859 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array/15") - 3860 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array/16") - 3861 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array/17") - 3862 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array/18") - 3863 # . epilogue - 3864 89/<- %esp 5/r32/ebp - 3865 5d/pop-to-ebp - 3866 c3/return - 3867 - 3868 test-convert-index-into-array-of-bytes: - 3869 # . prologue - 3870 55/push-ebp - 3871 89/<- %ebp 4/r32/esp - 3872 # setup - 3873 (clear-stream _test-input-stream) - 3874 (clear-stream $_test-input-buffered-file->buffer) - 3875 (clear-stream _test-output-stream) - 3876 (clear-stream $_test-output-buffered-file->buffer) - 3877 # - 3878 (write _test-input-stream "fn foo {\n") - 3879 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 3880 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 3881 (write _test-input-stream " var x/eax: (addr byte) <- index arr, idx\n") - 3882 (write _test-input-stream "}\n") - 3883 # convert - 3884 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3885 (flush _test-output-buffered-file) - 3886 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3892 # check output - 3893 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes/0") - 3894 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes/1") - 3895 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes/2") - 3896 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes/3") - 3897 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes/4") - 3898 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes/5") - 3899 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes/6") - 3900 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes/7") - 3901 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes/8") - 3902 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes/9") - 3903 (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/11") - 3904 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes/13") - 3905 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes/14") - 3906 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes/15") - 3907 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes/16") - 3908 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes/17") - 3909 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes/18") - 3910 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes/19") - 3911 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes/20") - 3912 # . epilogue - 3913 89/<- %esp 5/r32/ebp - 3914 5d/pop-to-ebp - 3915 c3/return - 3916 - 3917 test-convert-index-into-array-with-literal: - 3918 # . prologue - 3919 55/push-ebp - 3920 89/<- %ebp 4/r32/esp - 3921 # setup - 3922 (clear-stream _test-input-stream) - 3923 (clear-stream $_test-input-buffered-file->buffer) - 3924 (clear-stream _test-output-stream) - 3925 (clear-stream $_test-output-buffered-file->buffer) - 3926 # - 3927 (write _test-input-stream "fn foo {\n") - 3928 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 3929 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") - 3930 (write _test-input-stream "}\n") - 3931 # convert - 3932 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3933 (flush _test-output-buffered-file) - 3934 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3940 # check output - 3941 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-with-literal/0") - 3942 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-with-literal/1") - 3943 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-with-literal/2") - 3944 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-with-literal/3") - 3945 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-with-literal/4") - 3946 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5") - 3947 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6") - 3948 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7") - 3949 # 2 * 4 bytes/elem + 4 bytes for size = offset 12 - 3950 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/8") - 3951 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/9") - 3952 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/10") - 3953 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-with-literal/11") - 3954 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-with-literal/12") - 3955 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-with-literal/13") - 3956 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-with-literal/14") - 3957 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-with-literal/15") - 3958 # . epilogue - 3959 89/<- %esp 5/r32/ebp - 3960 5d/pop-to-ebp - 3961 c3/return - 3962 - 3963 test-convert-index-into-array-of-bytes-with-literal: - 3964 # . prologue - 3965 55/push-ebp - 3966 89/<- %ebp 4/r32/esp - 3967 # setup - 3968 (clear-stream _test-input-stream) - 3969 (clear-stream $_test-input-buffered-file->buffer) - 3970 (clear-stream _test-output-stream) - 3971 (clear-stream $_test-output-buffered-file->buffer) - 3972 # - 3973 (write _test-input-stream "fn foo {\n") - 3974 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 3975 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") - 3976 (write _test-input-stream "}\n") - 3977 # convert - 3978 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3979 (flush _test-output-buffered-file) - 3980 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3986 # check output - 3987 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-with-literal/0") - 3988 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-with-literal/1") - 3989 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/2") - 3990 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-with-literal/3") - 3991 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-with-literal/4") - 3992 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-with-literal/5") - 3993 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-with-literal/6") - 3994 (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") - 3995 # 2 * 1 byte/elem + 4 bytes for size = offset 6 - 3996 (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/8") - 3997 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-with-literal/9") - 3998 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-with-literal/10") - 3999 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-with-literal/11") - 4000 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-with-literal/12") - 4001 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-with-literal/13") - 4002 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/14") - 4003 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-with-literal/15") - 4004 # . epilogue - 4005 89/<- %esp 5/r32/ebp - 4006 5d/pop-to-ebp - 4007 c3/return - 4008 - 4009 test-convert-index-into-array-on-stack: - 4010 # . prologue - 4011 55/push-ebp - 4012 89/<- %ebp 4/r32/esp - 4013 # setup - 4014 (clear-stream _test-input-stream) - 4015 (clear-stream $_test-input-buffered-file->buffer) - 4016 (clear-stream _test-output-stream) - 4017 (clear-stream $_test-output-buffered-file->buffer) - 4018 # - 4019 (write _test-input-stream "fn foo {\n") - 4020 (write _test-input-stream " var arr: (array int 3)\n") - 4021 (write _test-input-stream " var idx/eax: int <- copy 2\n") - 4022 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 4023 (write _test-input-stream "}\n") - 4024 # convert - 4025 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4026 (flush _test-output-buffered-file) - 4027 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4033 # check output - 4034 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack/0") - 4035 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack/1") - 4036 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack/2") - 4037 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack/3") - 4038 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack/4") - 4039 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack/5") - 4040 # var arr - 4041 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack/6") - 4042 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack/7") - 4043 # var idx - 4044 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack/8") - 4045 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 2/imm32" "F - test-convert-index-into-array-on-stack/9") - 4046 # var x is at (ebp-0x10) + idx<<2 + 4 = ebp + idx<<2 - 0xc - 4047 (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/10") - 4048 # reclaim idx - 4049 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack/11") - 4050 # reclaim arr - 4051 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack/12") - 4052 # - 4053 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack/13") - 4054 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack/14") - 4055 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack/15") - 4056 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack/16") - 4057 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack/17") - 4058 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack/18") - 4059 # . epilogue - 4060 89/<- %esp 5/r32/ebp - 4061 5d/pop-to-ebp - 4062 c3/return - 4063 - 4064 test-convert-index-into-array-on-stack-with-literal: - 4065 # . prologue - 4066 55/push-ebp - 4067 89/<- %ebp 4/r32/esp - 4068 # setup - 4069 (clear-stream _test-input-stream) - 4070 (clear-stream $_test-input-buffered-file->buffer) - 4071 (clear-stream _test-output-stream) - 4072 (clear-stream $_test-output-buffered-file->buffer) - 4073 # - 4074 (write _test-input-stream "fn foo {\n") - 4075 (write _test-input-stream " var arr: (array int 3)\n") - 4076 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") - 4077 (write _test-input-stream "}\n") - 4078 # convert - 4079 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4080 (flush _test-output-buffered-file) - 4081 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4087 # check output - 4088 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack-with-literal/0") - 4089 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack-with-literal/1") - 4090 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack-with-literal/2") - 4091 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack-with-literal/3") - 4092 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack-with-literal/4") - 4093 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack-with-literal/5") - 4094 # var arr - 4095 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack-with-literal/6") - 4096 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack-with-literal/7") - 4097 # var x - 4098 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack-with-literal/8") - 4099 # x is at (ebp-0x10) + 4 + 2*4 = ebp-4 - 4100 (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/9") - 4101 # reclaim x - 4102 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack-with-literal/10") - 4103 # reclaim arr - 4104 (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/11") - 4105 # - 4106 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack-with-literal/12") - 4107 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack-with-literal/13") - 4108 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack-with-literal/14") - 4109 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack-with-literal/15") - 4110 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack-with-literal/16") - 4111 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack-with-literal/17") - 4112 # . epilogue - 4113 89/<- %esp 5/r32/ebp - 4114 5d/pop-to-ebp - 4115 c3/return - 4116 - 4117 test-convert-index-into-array-of-bytes-on-stack-with-literal: - 4118 # . prologue - 4119 55/push-ebp - 4120 89/<- %ebp 4/r32/esp - 4121 # setup - 4122 (clear-stream _test-input-stream) - 4123 (clear-stream $_test-input-buffered-file->buffer) - 4124 (clear-stream _test-output-stream) - 4125 (clear-stream $_test-output-buffered-file->buffer) - 4126 # - 4127 (write _test-input-stream "fn foo {\n") - 4128 (write _test-input-stream " var arr: (array byte 3)\n") - 4129 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") - 4130 (write _test-input-stream "}\n") - 4131 # convert - 4132 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4133 (flush _test-output-buffered-file) - 4134 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4140 # check output - 4141 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/0") - 4142 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/1") - 4143 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/2") - 4144 (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") - 4145 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/4") - 4146 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/5") - 4147 # var arr - 4148 (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") - 4149 (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") - 4150 # var x - 4151 (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") - 4152 # x is at (ebp-7) + 4 + 2 = ebp-1 - 4153 (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/9") - 4154 # reclaim x - 4155 (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/10") - 4156 # reclaim arr - 4157 (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/11") - 4158 # - 4159 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/12") - 4160 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/13") - 4161 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/14") - 4162 (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/15") - 4163 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/16") - 4164 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/17") - 4165 # . epilogue - 4166 89/<- %esp 5/r32/ebp - 4167 5d/pop-to-ebp - 4168 c3/return - 4169 - 4170 test-convert-index-into-array-using-offset: - 4171 # . prologue - 4172 55/push-ebp - 4173 89/<- %ebp 4/r32/esp - 4174 # setup - 4175 (clear-stream _test-input-stream) - 4176 (clear-stream $_test-input-buffered-file->buffer) - 4177 (clear-stream _test-output-stream) - 4178 (clear-stream $_test-output-buffered-file->buffer) - 4179 # - 4180 (write _test-input-stream "fn foo {\n") - 4181 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 4182 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 4183 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") - 4184 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") - 4185 (write _test-input-stream "}\n") - 4186 # convert - 4187 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4188 (flush _test-output-buffered-file) - 4189 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4195 # check output - 4196 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset/0") - 4197 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset/1") - 4198 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset/2") - 4199 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset/3") - 4200 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset/4") - 4201 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset/5") - 4202 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset/6") - 4203 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset/7") - 4204 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset/8") - 4205 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-using-offset/9") - 4206 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10") - 4207 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset/11") - 4208 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset/12") - 4209 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset/13") - 4210 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset/14") - 4211 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset/15") - 4212 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset/16") - 4213 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset/17") - 4214 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset/18") - 4215 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset/19") - 4216 # . epilogue - 4217 89/<- %esp 5/r32/ebp - 4218 5d/pop-to-ebp - 4219 c3/return - 4220 - 4221 test-convert-index-into-array-of-bytes-using-offset: - 4222 # . prologue - 4223 55/push-ebp - 4224 89/<- %ebp 4/r32/esp - 4225 # setup - 4226 (clear-stream _test-input-stream) - 4227 (clear-stream $_test-input-buffered-file->buffer) - 4228 (clear-stream _test-output-stream) - 4229 (clear-stream $_test-output-buffered-file->buffer) - 4230 # - 4231 (write _test-input-stream "fn foo {\n") - 4232 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 4233 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 4234 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") - 4235 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") - 4236 (write _test-input-stream "}\n") - 4237 # convert - 4238 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4239 (flush _test-output-buffered-file) - 4240 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4246 # check output - 4247 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset/0") - 4248 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset/1") - 4249 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/2") - 4250 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset/3") - 4251 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset/4") - 4252 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset/5") - 4253 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset/6") - 4254 (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") - 4255 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/8") - 4256 (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") - 4257 (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") - 4258 (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/11") - 4259 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/12") - 4260 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset/13") - 4261 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset/14") - 4262 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset/15") - 4263 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset/16") - 4264 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset/17") - 4265 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/18") - 4266 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset/19") - 4267 # . epilogue - 4268 89/<- %esp 5/r32/ebp - 4269 5d/pop-to-ebp - 4270 c3/return - 4271 - 4272 test-convert-index-into-array-using-offset-on-stack: - 4273 # . prologue - 4274 55/push-ebp - 4275 89/<- %ebp 4/r32/esp - 4276 # setup - 4277 (clear-stream _test-input-stream) - 4278 (clear-stream $_test-input-buffered-file->buffer) - 4279 (clear-stream _test-output-stream) - 4280 (clear-stream $_test-output-buffered-file->buffer) - 4281 # - 4282 (write _test-input-stream "fn foo {\n") - 4283 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 4284 (write _test-input-stream " var idx: int\n") - 4285 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") - 4286 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") - 4287 (write _test-input-stream "}\n") - 4288 # convert - 4289 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4290 (flush _test-output-buffered-file) - 4291 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4297 # check output - 4298 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset-on-stack/0") - 4299 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset-on-stack/1") - 4300 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset-on-stack/2") - 4301 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset-on-stack/3") - 4302 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset-on-stack/4") - 4303 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset-on-stack/5") - 4304 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset-on-stack/6") - 4305 (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") - 4306 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/8") - 4307 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset-on-stack/9") - 4308 (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") - 4309 (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/11") - 4310 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset-on-stack/12") - 4311 (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/13") - 4312 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset-on-stack/14") - 4313 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset-on-stack/15") - 4314 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset-on-stack/16") - 4315 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset-on-stack/17") - 4316 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset-on-stack/18") - 4317 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset-on-stack/19") - 4318 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset-on-stack/20") - 4319 # . epilogue - 4320 89/<- %esp 5/r32/ebp - 4321 5d/pop-to-ebp - 4322 c3/return - 4323 - 4324 test-convert-index-into-array-of-bytes-using-offset-on-stack: - 4325 # . prologue - 4326 55/push-ebp - 4327 89/<- %ebp 4/r32/esp - 4328 # setup - 4329 (clear-stream _test-input-stream) - 4330 (clear-stream $_test-input-buffered-file->buffer) - 4331 (clear-stream _test-output-stream) - 4332 (clear-stream $_test-output-buffered-file->buffer) - 4333 # - 4334 (write _test-input-stream "fn foo {\n") - 4335 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 4336 (write _test-input-stream " var idx: int\n") - 4337 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") - 4338 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") - 4339 (write _test-input-stream "}\n") - 4340 # convert - 4341 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4342 (flush _test-output-buffered-file) - 4343 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4349 # check output - 4350 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/0") - 4351 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/1") - 4352 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/2") - 4353 (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") - 4354 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/4") - 4355 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/5") - 4356 (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") - 4357 (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") - 4358 (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") - 4359 (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") - 4360 (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") - 4361 (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/11") - 4362 (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/12") - 4363 (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/13") - 4364 (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/14") - 4365 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/15") - 4366 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/16") - 4367 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/17") - 4368 (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/18") - 4369 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/19") - 4370 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/20") - 4371 # . epilogue - 4372 89/<- %esp 5/r32/ebp - 4373 5d/pop-to-ebp - 4374 c3/return - 4375 - 4376 test-convert-function-and-type-definition: - 4377 # . prologue - 4378 55/push-ebp - 4379 89/<- %ebp 4/r32/esp - 4380 # setup - 4381 (clear-stream _test-input-stream) - 4382 (clear-stream $_test-input-buffered-file->buffer) - 4383 (clear-stream _test-output-stream) - 4384 (clear-stream $_test-output-buffered-file->buffer) - 4385 # - 4386 (write _test-input-stream "fn foo a: (addr t) {\n") - 4387 (write _test-input-stream " var _a/eax: (addr t) <- copy a\n") - 4388 (write _test-input-stream " var b/ecx: (addr int) <- get _a, x\n") - 4389 (write _test-input-stream " var c/ecx: (addr int) <- get _a, y\n") - 4390 (write _test-input-stream "}\n") - 4391 (write _test-input-stream "type t {\n") - 4392 (write _test-input-stream " x: int\n") - 4393 (write _test-input-stream " y: int\n") - 4394 (write _test-input-stream "}\n") - 4395 # convert - 4396 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4397 (flush _test-output-buffered-file) - 4398 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4404 # check output - 4405 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-and-type-definition/0") - 4406 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-and-type-definition/1") - 4407 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-and-type-definition/2") - 4408 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-and-type-definition/3") - 4409 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-and-type-definition/4") - 4410 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-and-type-definition/5") - 4411 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-and-type-definition/6") - 4412 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7") - 4413 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-and-type-definition/8") - 4414 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000000) 0x00000001/r32" "F - test-convert-function-and-type-definition/9") - 4415 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000004) 0x00000001/r32" "F - test-convert-function-and-type-definition/11") - 4416 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/13") - 4417 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/14") - 4418 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-and-type-definition/15") - 4419 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-and-type-definition/16") - 4420 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-and-type-definition/17") - 4421 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-and-type-definition/18") - 4422 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-and-type-definition/19") - 4423 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-and-type-definition/20") - 4424 # . epilogue - 4425 89/<- %esp 5/r32/ebp - 4426 5d/pop-to-ebp - 4427 c3/return - 4428 - 4429 test-convert-function-with-local-var-with-user-defined-type: - 4430 # . prologue - 4431 55/push-ebp - 4432 89/<- %ebp 4/r32/esp - 4433 # setup - 4434 (clear-stream _test-input-stream) - 4435 (clear-stream $_test-input-buffered-file->buffer) - 4436 (clear-stream _test-output-stream) - 4437 (clear-stream $_test-output-buffered-file->buffer) - 4438 # - 4439 (write _test-input-stream "fn foo {\n") - 4440 (write _test-input-stream " var a: t\n") - 4441 (write _test-input-stream "}\n") - 4442 (write _test-input-stream "type t {\n") - 4443 (write _test-input-stream " x: int\n") - 4444 (write _test-input-stream " y: int\n") - 4445 (write _test-input-stream "}\n") - 4446 # convert - 4447 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4448 (flush _test-output-buffered-file) - 4449 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4455 # check output - 4456 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type/0") - 4457 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type/1") - 4458 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/2") - 4459 (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") - 4460 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type/4") - 4461 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type/5") - 4462 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/6") - 4463 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/7") - 4464 (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") - 4465 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type/9") - 4466 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type/10") - 4467 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type/11") - 4468 (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") - 4469 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/13") - 4470 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type/14") - 4471 # . epilogue - 4472 89/<- %esp 5/r32/ebp - 4473 5d/pop-to-ebp - 4474 c3/return - 4475 - 4476 test-convert-function-call-with-arg-of-user-defined-type: - 4477 # . prologue - 4478 55/push-ebp - 4479 89/<- %ebp 4/r32/esp - 4480 # setup - 4481 (clear-stream _test-input-stream) - 4482 (clear-stream $_test-input-buffered-file->buffer) - 4483 (clear-stream _test-output-stream) - 4484 (clear-stream $_test-output-buffered-file->buffer) - 4485 # - 4486 (write _test-input-stream "fn f {\n") - 4487 (write _test-input-stream " var a: t\n") - 4488 (write _test-input-stream " foo a\n") - 4489 (write _test-input-stream "}\n") - 4490 (write _test-input-stream "fn foo x: t {\n") + 2056 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-byte-operations/0") + 2057 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-byte-operations/1") + 2058 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-byte-operations/2") + 2059 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-byte-operations/3") + 2060 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-byte-operations/4") + 2061 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-byte-operations/5") + 2062 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-byte-operations/6") + 2063 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-with-byte-operations/7") + 2064 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-byte-operations/8") + 2065 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-byte-operations/9") + 2066 (check-next-stream-line-equal _test-output-stream " 8a/byte-> %eax 0x00000001/r32" "F - test-convert-function-with-byte-operations/10") + 2067 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-function-with-byte-operations/11") + 2068 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 0/imm32" "F - test-convert-function-with-byte-operations/12") + 2069 (check-next-stream-line-equal _test-output-stream " 8a/byte-> *edx 0x00000001/r32" "F - test-convert-function-with-byte-operations/13") + 2070 (check-next-stream-line-equal _test-output-stream " 88/byte<- *edx 0x00000000/r32" "F - test-convert-function-with-byte-operations/14") + 2071 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-function-with-byte-operations/15") + 2072 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-byte-operations/16") + 2073 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-byte-operations/17") + 2074 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-byte-operations/18") + 2075 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-byte-operations/19") + 2076 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-byte-operations/20") + 2077 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-byte-operations/21") + 2078 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-byte-operations/22") + 2079 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-byte-operations/23") + 2080 # . epilogue + 2081 89/<- %esp 5/r32/ebp + 2082 5d/pop-to-ebp + 2083 c3/return + 2084 + 2085 # variables of type 'byte' _can_ be function args. They then occupy 4 bytes. + 2086 test-copy-byte-var-from-fn-arg: + 2087 # . prologue + 2088 55/push-ebp + 2089 89/<- %ebp 4/r32/esp + 2090 # setup + 2091 (clear-stream _test-input-stream) + 2092 (clear-stream $_test-input-buffered-file->buffer) + 2093 (clear-stream _test-output-stream) + 2094 (clear-stream $_test-output-buffered-file->buffer) + 2095 # + 2096 (write _test-input-stream "fn foo x: byte, y: int {\n") + 2097 (write _test-input-stream " var a/eax: byte <- copy x\n") + 2098 (write _test-input-stream " var b/eax: int <- copy y\n") + 2099 (write _test-input-stream "}\n") + 2100 # convert + 2101 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2102 (flush _test-output-buffered-file) + 2103 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2109 # check output + 2110 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-copy-byte-from-fn-arg/0") + 2111 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-copy-byte-from-fn-arg/1") + 2112 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-copy-byte-from-fn-arg/2") + 2113 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-copy-byte-from-fn-arg/3") + 2114 (check-next-stream-line-equal _test-output-stream " {" "F - test-copy-byte-from-fn-arg/4") + 2115 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-copy-byte-from-fn-arg/5") + 2116 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-copy-byte-from-fn-arg/6") + 2117 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/7") + 2118 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x0000000c) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/8") + 2119 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-copy-byte-from-fn-arg/9") + 2120 (check-next-stream-line-equal _test-output-stream " }" "F - test-copy-byte-from-fn-arg/10") + 2121 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-copy-byte-from-fn-arg/11") + 2122 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-copy-byte-from-fn-arg/12") + 2123 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-copy-byte-from-fn-arg/13") + 2124 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-copy-byte-from-fn-arg/14") + 2125 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-copy-byte-from-fn-arg/15") + 2126 # . epilogue + 2127 89/<- %esp 5/r32/ebp + 2128 5d/pop-to-ebp + 2129 c3/return + 2130 + 2131 test-convert-compare-register-with-literal: + 2132 # . prologue + 2133 55/push-ebp + 2134 89/<- %ebp 4/r32/esp + 2135 # setup + 2136 (clear-stream _test-input-stream) + 2137 (clear-stream $_test-input-buffered-file->buffer) + 2138 (clear-stream _test-output-stream) + 2139 (clear-stream $_test-output-buffered-file->buffer) + 2140 # + 2141 (write _test-input-stream "fn foo {\n") + 2142 (write _test-input-stream " var x/ecx: int <- copy 0\n") + 2143 (write _test-input-stream " compare x, 0\n") + 2144 (write _test-input-stream "}\n") + 2145 # convert + 2146 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2147 (flush _test-output-buffered-file) + 2148 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2154 # check output + 2155 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-compare-register-with-literal/0") + 2156 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-compare-register-with-literal/1") + 2157 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-compare-register-with-literal/2") + 2158 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-compare-register-with-literal/3") + 2159 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-compare-register-with-literal/4") + 2160 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-compare-register-with-literal/5") + 2161 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") + 2162 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-compare-register-with-literal/7") + 2163 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0/imm32" "F - test-convert-compare-register-with-literal/8") + 2164 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") + 2165 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-compare-register-with-literal/10") + 2166 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-compare-register-with-literal/11") + 2167 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-compare-register-with-literal/12") + 2168 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-compare-register-with-literal/13") + 2169 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-compare-register-with-literal/14") + 2170 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-compare-register-with-literal/15") + 2171 # . epilogue + 2172 89/<- %esp 5/r32/ebp + 2173 5d/pop-to-ebp + 2174 c3/return + 2175 + 2176 test-unknown-variable: + 2177 # . prologue + 2178 55/push-ebp + 2179 89/<- %ebp 4/r32/esp + 2180 # setup + 2181 (clear-stream _test-input-stream) + 2182 (clear-stream $_test-input-buffered-file->buffer) + 2183 (clear-stream _test-output-stream) + 2184 (clear-stream $_test-output-buffered-file->buffer) + 2185 (clear-stream _test-error-stream) + 2186 (clear-stream $_test-error-buffered-file->buffer) + 2187 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 2188 68/push 0/imm32 + 2189 68/push 0/imm32 + 2190 89/<- %edx 4/r32/esp + 2191 (tailor-exit-descriptor %edx 0x10) + 2192 # + 2193 (write _test-input-stream "fn foo {\n") + 2194 (write _test-input-stream " compare x, 0\n") + 2195 (write _test-input-stream "}\n") + 2196 # convert + 2197 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2198 # registers except esp clobbered at this point + 2199 # restore ed + 2200 89/<- %edx 4/r32/esp + 2201 (flush _test-output-buffered-file) + 2202 (flush _test-error-buffered-file) + 2203 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 2209 # check output + 2210 (check-stream-equal _test-output-stream "" "F - test-unknown-variable: output should be empty") + 2211 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable: error message") + 2212 # check that stop(1) was called + 2213 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable: exit status") + 2214 # don't restore from ebp + 2215 81 0/subop/add %esp 8/imm32 + 2216 # . epilogue + 2217 5d/pop-to-ebp + 2218 c3/return + 2219 + 2220 test-convert-function-with-local-var-in-block: + 2221 # . prologue + 2222 55/push-ebp + 2223 89/<- %ebp 4/r32/esp + 2224 # setup + 2225 (clear-stream _test-input-stream) + 2226 (clear-stream $_test-input-buffered-file->buffer) + 2227 (clear-stream _test-output-stream) + 2228 (clear-stream $_test-output-buffered-file->buffer) + 2229 # + 2230 (write _test-input-stream "fn foo {\n") + 2231 (write _test-input-stream " {\n") + 2232 (write _test-input-stream " var x: int\n") + 2233 (write _test-input-stream " increment x\n") + 2234 (write _test-input-stream " }\n") + 2235 (write _test-input-stream "}\n") + 2236 # convert + 2237 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2238 (flush _test-output-buffered-file) + 2239 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2245 # check output + 2246 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-block/0") + 2247 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-block/1") + 2248 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-block/2") + 2249 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-block/3") + 2250 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/4") + 2251 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-block/5") + 2252 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/6") + 2253 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-local-var-in-block/7") + 2254 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-block/8") + 2255 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-block/9") + 2256 (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") + 2257 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/11") + 2258 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-local-var-in-block/12") + 2259 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/13") + 2260 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-block/14") + 2261 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-block/15") + 2262 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-block/16") + 2263 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-block/17") + 2264 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-block/18") + 2265 # . epilogue + 2266 89/<- %esp 5/r32/ebp + 2267 5d/pop-to-ebp + 2268 c3/return + 2269 + 2270 test-convert-function-with-local-var-in-named-block: + 2271 # . prologue + 2272 55/push-ebp + 2273 89/<- %ebp 4/r32/esp + 2274 # setup + 2275 (clear-stream _test-input-stream) + 2276 (clear-stream $_test-input-buffered-file->buffer) + 2277 (clear-stream _test-output-stream) + 2278 (clear-stream $_test-output-buffered-file->buffer) + 2279 # + 2280 (write _test-input-stream "fn foo {\n") + 2281 (write _test-input-stream " $bar: {\n") + 2282 (write _test-input-stream " var x: int\n") + 2283 (write _test-input-stream " increment x\n") + 2284 (write _test-input-stream " }\n") + 2285 (write _test-input-stream "}\n") + 2286 # convert + 2287 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2288 (flush _test-output-buffered-file) + 2289 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2295 # check output + 2296 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-named-block/0") + 2297 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-named-block/1") + 2298 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-named-block/2") + 2299 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-named-block/3") + 2300 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/4") + 2301 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-named-block/5") + 2302 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/6") + 2303 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-local-var-in-named-block/7") + 2304 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-named-block/8") + 2305 (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") + 2306 (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") + 2307 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/11") + 2308 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-local-var-in-named-block/12") + 2309 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/13") + 2310 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-named-block/14") + 2311 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-named-block/15") + 2312 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-named-block/16") + 2313 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-named-block/17") + 2314 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-named-block/18") + 2315 # . epilogue + 2316 89/<- %esp 5/r32/ebp + 2317 5d/pop-to-ebp + 2318 c3/return + 2319 + 2320 test-unknown-variable-in-named-block: + 2321 # . prologue + 2322 55/push-ebp + 2323 89/<- %ebp 4/r32/esp + 2324 # setup + 2325 (clear-stream _test-input-stream) + 2326 (clear-stream $_test-input-buffered-file->buffer) + 2327 (clear-stream _test-output-stream) + 2328 (clear-stream $_test-output-buffered-file->buffer) + 2329 (clear-stream _test-error-stream) + 2330 (clear-stream $_test-error-buffered-file->buffer) + 2331 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 2332 68/push 0/imm32 + 2333 68/push 0/imm32 + 2334 89/<- %edx 4/r32/esp + 2335 (tailor-exit-descriptor %edx 0x10) + 2336 # + 2337 (write _test-input-stream "fn foo {\n") + 2338 (write _test-input-stream " $a: {\n") + 2339 (write _test-input-stream " compare x, 0\n") + 2340 (write _test-input-stream " }\n") + 2341 (write _test-input-stream "}\n") + 2342 # convert + 2343 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2344 # registers except esp clobbered at this point + 2345 # restore ed + 2346 89/<- %edx 4/r32/esp + 2347 (flush _test-output-buffered-file) + 2348 (flush _test-error-buffered-file) + 2349 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 2355 # check output + 2356 (check-stream-equal _test-output-stream "" "F - test-unknown-variable-in-named-block: output should be empty") + 2357 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable-in-named-block: error message") + 2358 # check that stop(1) was called + 2359 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable-in-named-block: exit status") + 2360 # don't restore from ebp + 2361 81 0/subop/add %esp 8/imm32 + 2362 # . epilogue + 2363 5d/pop-to-ebp + 2364 c3/return + 2365 + 2366 test-always-shadow-outermost-reg-vars-in-function: + 2367 # . prologue + 2368 55/push-ebp + 2369 89/<- %ebp 4/r32/esp + 2370 # setup + 2371 (clear-stream _test-input-stream) + 2372 (clear-stream $_test-input-buffered-file->buffer) + 2373 (clear-stream _test-output-stream) + 2374 (clear-stream $_test-output-buffered-file->buffer) + 2375 # + 2376 (write _test-input-stream "fn foo {\n") + 2377 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2378 (write _test-input-stream "}\n") + 2379 # convert + 2380 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2381 (flush _test-output-buffered-file) + 2382 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2388 # check output + 2389 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-always-shadow-outermost-reg-vars-in-function/0") + 2390 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-always-shadow-outermost-reg-vars-in-function/1") + 2391 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/2") + 2392 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-always-shadow-outermost-reg-vars-in-function/3") + 2393 (check-next-stream-line-equal _test-output-stream " {" "F - test-always-shadow-outermost-reg-vars-in-function/4") + 2394 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-always-shadow-outermost-reg-vars-in-function/5") + 2395 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") + 2396 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-always-shadow-outermost-reg-vars-in-function/8") + 2397 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") + 2398 (check-next-stream-line-equal _test-output-stream " }" "F - test-always-shadow-outermost-reg-vars-in-function/12") + 2399 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-always-shadow-outermost-reg-vars-in-function/13") + 2400 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-always-shadow-outermost-reg-vars-in-function/14") + 2401 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-always-shadow-outermost-reg-vars-in-function/15") + 2402 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/16") + 2403 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-always-shadow-outermost-reg-vars-in-function/17") + 2404 # . epilogue + 2405 89/<- %esp 5/r32/ebp + 2406 5d/pop-to-ebp + 2407 c3/return + 2408 + 2409 _pending-test-clobber-dead-local: + 2410 # . prologue + 2411 55/push-ebp + 2412 89/<- %ebp 4/r32/esp + 2413 # setup + 2414 (clear-stream _test-input-stream) + 2415 (clear-stream $_test-input-buffered-file->buffer) + 2416 (clear-stream _test-output-stream) + 2417 (clear-stream $_test-output-buffered-file->buffer) + 2418 # + 2419 (write _test-input-stream "fn foo {\n") + 2420 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2421 (write _test-input-stream " {\n") + 2422 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2423 (write _test-input-stream " }\n") + 2424 (write _test-input-stream "}\n") + 2425 # convert + 2426 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2427 (flush _test-output-buffered-file) + 2428 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2434 # check output + 2435 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-clobber-dead-local/0") + 2436 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-clobber-dead-local/1") + 2437 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-clobber-dead-local/2") + 2438 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-clobber-dead-local/3") + 2439 (check-next-stream-line-equal _test-output-stream " {" "F - test-clobber-dead-local/4") + 2440 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-clobber-dead-local/5") + 2441 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-clobber-dead-local/6") + 2442 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-clobber-dead-local/7") + 2443 (check-next-stream-line-equal _test-output-stream " {" "F - test-clobber-dead-local/8") + 2444 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-clobber-dead-local/9") + 2445 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-clobber-dead-local/10") # no push/pop here + 2446 (check-next-stream-line-equal _test-output-stream " }" "F - test-clobber-dead-local/11") + 2447 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-clobber-dead-local/12") + 2448 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-clobber-dead-local/13") + 2449 (check-next-stream-line-equal _test-output-stream " }" "F - test-clobber-dead-local/14") + 2450 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-clobber-dead-local/15") + 2451 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-clobber-dead-local/16") + 2452 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-clobber-dead-local/17") + 2453 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-clobber-dead-local/18") + 2454 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-clobber-dead-local/19") + 2455 # . epilogue + 2456 89/<- %esp 5/r32/ebp + 2457 5d/pop-to-ebp + 2458 c3/return + 2459 + 2460 test-shadow-live-local: + 2461 # . prologue + 2462 55/push-ebp + 2463 89/<- %ebp 4/r32/esp + 2464 # setup + 2465 (clear-stream _test-input-stream) + 2466 (clear-stream $_test-input-buffered-file->buffer) + 2467 (clear-stream _test-output-stream) + 2468 (clear-stream $_test-output-buffered-file->buffer) + 2469 # + 2470 (write _test-input-stream "fn foo {\n") + 2471 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2472 (write _test-input-stream " {\n") + 2473 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2474 (write _test-input-stream " }\n") + 2475 (write _test-input-stream " x <- increment\n") + 2476 (write _test-input-stream "}\n") + 2477 # convert + 2478 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2479 (flush _test-output-buffered-file) + 2480 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2486 # check output + 2487 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-live-local/0") + 2488 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-live-local/1") + 2489 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-live-local/2") + 2490 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-live-local/3") + 2491 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-local/4") + 2492 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-live-local/5") + 2493 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-local/6") + 2494 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-live-local/7") + 2495 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-local/8") + 2496 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-live-local/9") + 2497 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-local/10") + 2498 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-live-local/11") + 2499 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-local/12") + 2500 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-local/13") + 2501 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-live-local/14") + 2502 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-live-local/15") + 2503 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-local/16") + 2504 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-local/17") + 2505 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-live-local/18") + 2506 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-live-local/19") + 2507 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-live-local/20") + 2508 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-live-local/21") + 2509 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-live-local/22") + 2510 # . epilogue + 2511 89/<- %esp 5/r32/ebp + 2512 5d/pop-to-ebp + 2513 c3/return + 2514 + 2515 test-shadow-name: + 2516 # . prologue + 2517 55/push-ebp + 2518 89/<- %ebp 4/r32/esp + 2519 # setup + 2520 (clear-stream _test-input-stream) + 2521 (clear-stream $_test-input-buffered-file->buffer) + 2522 (clear-stream _test-output-stream) + 2523 (clear-stream $_test-output-buffered-file->buffer) + 2524 # + 2525 (write _test-input-stream "fn foo {\n") + 2526 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2527 (write _test-input-stream " {\n") + 2528 (write _test-input-stream " var x/edx: int <- copy 4\n") + 2529 (write _test-input-stream " }\n") + 2530 (write _test-input-stream " x <- increment\n") + 2531 (write _test-input-stream "}\n") + 2532 # convert + 2533 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2534 (flush _test-output-buffered-file) + 2535 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2541 # check output + 2542 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name/0") + 2543 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name/1") + 2544 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name/2") + 2545 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name/3") + 2546 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/4") + 2547 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name/5") + 2548 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name/6") + 2549 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name/7") + 2550 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/8") + 2551 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name/9") + 2552 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name/10") + 2553 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name/11") + 2554 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name/12") + 2555 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/13") + 2556 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name/14") + 2557 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name/15") + 2558 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name/16") + 2559 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/17") + 2560 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name/18") + 2561 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name/19") + 2562 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name/20") + 2563 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name/21") + 2564 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name/22") + 2565 # . epilogue + 2566 89/<- %esp 5/r32/ebp + 2567 5d/pop-to-ebp + 2568 c3/return + 2569 + 2570 test-shadow-name-2: + 2571 # . prologue + 2572 55/push-ebp + 2573 89/<- %ebp 4/r32/esp + 2574 # setup + 2575 (clear-stream _test-input-stream) + 2576 (clear-stream $_test-input-buffered-file->buffer) + 2577 (clear-stream _test-output-stream) + 2578 (clear-stream $_test-output-buffered-file->buffer) + 2579 # + 2580 (write _test-input-stream "fn foo {\n") + 2581 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2582 (write _test-input-stream " {\n") + 2583 (write _test-input-stream " var x/edx: int <- copy 4\n") + 2584 (write _test-input-stream " var y/ecx: int <- copy 5\n") + 2585 (write _test-input-stream " }\n") + 2586 (write _test-input-stream " x <- increment\n") + 2587 (write _test-input-stream "}\n") + 2588 # convert + 2589 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2590 (flush _test-output-buffered-file) + 2591 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2597 # check output + 2598 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name-2/0") + 2599 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name-2/1") + 2600 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name-2/2") + 2601 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name-2/3") + 2602 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/4") + 2603 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name-2/5") + 2604 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/6") + 2605 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name-2/7") + 2606 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/8") + 2607 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name-2/9") + 2608 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name-2/10") + 2609 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name-2/11") + 2610 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/12") + 2611 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 5/imm32" "F - test-shadow-name-2/13") + 2612 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/14") + 2613 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name-2/15") + 2614 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/16") + 2615 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name-2/17") + 2616 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name-2/18") + 2617 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/19") + 2618 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/20") + 2619 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name-2/21") + 2620 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name-2/22") + 2621 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name-2/23") + 2622 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name-2/24") + 2623 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name-2/25") + 2624 # . epilogue + 2625 89/<- %esp 5/r32/ebp + 2626 5d/pop-to-ebp + 2627 c3/return + 2628 + 2629 test-do-not-spill-same-register-in-block: + 2630 # . prologue + 2631 55/push-ebp + 2632 89/<- %ebp 4/r32/esp + 2633 # setup + 2634 (clear-stream _test-input-stream) + 2635 (clear-stream $_test-input-buffered-file->buffer) + 2636 (clear-stream _test-output-stream) + 2637 (clear-stream $_test-output-buffered-file->buffer) + 2638 # + 2639 (write _test-input-stream "fn foo {\n") + 2640 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2641 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2642 (write _test-input-stream " y <- increment\n") + 2643 (write _test-input-stream "}\n") + 2644 # convert + 2645 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2646 (flush _test-output-buffered-file) + 2647 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2653 # check output + 2654 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-do-not-spill-same-register-in-block/0") + 2655 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-do-not-spill-same-register-in-block/1") + 2656 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-do-not-spill-same-register-in-block/2") + 2657 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-do-not-spill-same-register-in-block/3") + 2658 (check-next-stream-line-equal _test-output-stream " {" "F - test-do-not-spill-same-register-in-block/4") + 2659 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-do-not-spill-same-register-in-block/5") + 2660 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-do-not-spill-same-register-in-block/6") + 2661 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-do-not-spill-same-register-in-block/7") + 2662 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-do-not-spill-same-register-in-block/8") + 2663 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-do-not-spill-same-register-in-block/9") + 2664 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-do-not-spill-same-register-in-block/10") + 2665 (check-next-stream-line-equal _test-output-stream " }" "F - test-do-not-spill-same-register-in-block/11") + 2666 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-do-not-spill-same-register-in-block/12") + 2667 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-do-not-spill-same-register-in-block/13") + 2668 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-do-not-spill-same-register-in-block/14") + 2669 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-do-not-spill-same-register-in-block/15") + 2670 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-do-not-spill-same-register-in-block/16") + 2671 # . epilogue + 2672 89/<- %esp 5/r32/ebp + 2673 5d/pop-to-ebp + 2674 c3/return + 2675 + 2676 test-spill-different-register-in-block: + 2677 # . prologue + 2678 55/push-ebp + 2679 89/<- %ebp 4/r32/esp + 2680 # setup + 2681 (clear-stream _test-input-stream) + 2682 (clear-stream $_test-input-buffered-file->buffer) + 2683 (clear-stream _test-output-stream) + 2684 (clear-stream $_test-output-buffered-file->buffer) + 2685 # + 2686 (write _test-input-stream "fn foo {\n") + 2687 (write _test-input-stream " var x/eax: int <- copy 3\n") + 2688 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2689 (write _test-input-stream " y <- increment\n") + 2690 (write _test-input-stream "}\n") + 2691 # convert + 2692 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2693 (flush _test-output-buffered-file) + 2694 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2700 # check output + 2701 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-spill-different-register-in-block/0") + 2702 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-spill-different-register-in-block/1") + 2703 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-spill-different-register-in-block/2") + 2704 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-spill-different-register-in-block/3") + 2705 (check-next-stream-line-equal _test-output-stream " {" "F - test-spill-different-register-in-block/4") + 2706 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-spill-different-register-in-block/5") + 2707 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-spill-different-register-in-block/6") + 2708 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-spill-different-register-in-block/7") + 2709 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-spill-different-register-in-block/8") + 2710 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-spill-different-register-in-block/9") + 2711 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-spill-different-register-in-block/10") + 2712 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-spill-different-register-in-block/11") + 2713 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-spill-different-register-in-block/12") + 2714 (check-next-stream-line-equal _test-output-stream " }" "F - test-spill-different-register-in-block/13") + 2715 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-spill-different-register-in-block/14") + 2716 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-spill-different-register-in-block/15") + 2717 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-spill-different-register-in-block/16") + 2718 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-spill-different-register-in-block/17") + 2719 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-spill-different-register-in-block/18") + 2720 # . epilogue + 2721 89/<- %esp 5/r32/ebp + 2722 5d/pop-to-ebp + 2723 c3/return + 2724 + 2725 test-shadow-live-output: + 2726 # . prologue + 2727 55/push-ebp + 2728 89/<- %ebp 4/r32/esp + 2729 # setup + 2730 (clear-stream _test-input-stream) + 2731 (clear-stream $_test-input-buffered-file->buffer) + 2732 (clear-stream _test-output-stream) + 2733 (clear-stream $_test-output-buffered-file->buffer) + 2734 # + 2735 (write _test-input-stream "fn foo -> x/ecx: int {\n") + 2736 (write _test-input-stream " x <- copy 3\n") + 2737 (write _test-input-stream " {\n") + 2738 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2739 (write _test-input-stream " }\n") + 2740 (write _test-input-stream " x <- increment\n") + 2741 (write _test-input-stream "}\n") + 2742 # convert + 2743 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2744 (flush _test-output-buffered-file) + 2745 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2751 # check output + 2752 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-live-output/0") + 2753 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-live-output/1") + 2754 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-live-output/2") + 2755 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-live-output/3") + 2756 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-output/4") + 2757 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-live-output/5") + 2758 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-live-output/7") # no push because it's an output reg + 2759 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-output/8") + 2760 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-live-output/9") + 2761 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-output/10") + 2762 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-live-output/11") + 2763 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-output/12") + 2764 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-output/13") + 2765 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-live-output/14") + 2766 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-live-output/15") + 2767 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-output/17") + 2768 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-live-output/18") + 2769 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-live-output/19") + 2770 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-live-output/20") + 2771 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-live-output/21") + 2772 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-live-output/21") + 2773 # . epilogue + 2774 89/<- %esp 5/r32/ebp + 2775 5d/pop-to-ebp + 2776 c3/return + 2777 + 2778 test-stmt-defines-output-in-same-register-as-inout: + 2779 # . prologue + 2780 55/push-ebp + 2781 89/<- %ebp 4/r32/esp + 2782 # setup + 2783 (clear-stream _test-input-stream) + 2784 (clear-stream $_test-input-buffered-file->buffer) + 2785 (clear-stream _test-output-stream) + 2786 (clear-stream $_test-output-buffered-file->buffer) + 2787 (clear-stream _test-error-stream) + 2788 (clear-stream $_test-error-buffered-file->buffer) + 2789 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 2790 68/push 0/imm32 + 2791 68/push 0/imm32 + 2792 89/<- %edx 4/r32/esp + 2793 (tailor-exit-descriptor %edx 0x10) + 2794 # + 2795 (write _test-input-stream "fn foo -> x/ecx: int {\n") + 2796 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2797 (write _test-input-stream " x <- copy y\n") # writing to a fn output is currently the only way for a statement to define a new var + 2798 (write _test-input-stream "}\n") + 2799 # convert + 2800 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2801 # registers except esp clobbered at this point + 2802 # restore ed + 2803 89/<- %edx 4/r32/esp + 2804 (flush _test-output-buffered-file) + 2805 (flush _test-error-buffered-file) + 2806 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 2812 # no error; we looked up 'y' correctly before pushing the binding for 'x' + 2813 (check-stream-equal _test-error-stream "" "F - test-stmt-defines-output-in-same-register-as-inout: error stream should be empty") + 2814 # don't bother checking the generated code; that's in the test 'test-local-clobbered-by-fn-output' below + 2815 # don't restore from ebp + 2816 81 0/subop/add %esp 8/imm32 + 2817 # . epilogue + 2818 5d/pop-to-ebp + 2819 c3/return + 2820 + 2821 test-local-clobbered-by-fn-output: + 2822 # . prologue + 2823 55/push-ebp + 2824 89/<- %ebp 4/r32/esp + 2825 # setup + 2826 (clear-stream _test-input-stream) + 2827 (clear-stream $_test-input-buffered-file->buffer) + 2828 (clear-stream _test-output-stream) + 2829 (clear-stream $_test-output-buffered-file->buffer) + 2830 # + 2831 (write _test-input-stream "fn foo -> x/ecx: int {\n") + 2832 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2833 (write _test-input-stream " x <- copy y\n") + 2834 (write _test-input-stream "}\n") + 2835 # convert + 2836 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2837 (flush _test-output-buffered-file) + 2838 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2844 # check output + 2845 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-local-clobbered-by-fn-output/0") + 2846 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-local-clobbered-by-fn-output/1") + 2847 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-local-clobbered-by-fn-output/2") + 2848 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-local-clobbered-by-fn-output/3") + 2849 (check-next-stream-line-equal _test-output-stream " {" "F - test-local-clobbered-by-fn-output/4") + 2850 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-local-clobbered-by-fn-output/5") + 2851 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-local-clobbered-by-fn-output/6") # no push because it's an output reg + 2852 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0x00000001/r32" "F - test-local-clobbered-by-fn-output/7") + 2853 (check-next-stream-line-equal _test-output-stream " }" "F - test-local-clobbered-by-fn-output/8") + 2854 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-local-clobbered-by-fn-output/9") + 2855 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-local-clobbered-by-fn-output/10") + 2856 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-local-clobbered-by-fn-output/11") + 2857 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-local-clobbered-by-fn-output/12") + 2858 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-local-clobbered-by-fn-output/13") + 2859 # . epilogue + 2860 89/<- %esp 5/r32/ebp + 2861 5d/pop-to-ebp + 2862 c3/return + 2863 + 2864 test-read-output: + 2865 # . prologue + 2866 55/push-ebp + 2867 89/<- %ebp 4/r32/esp + 2868 # setup + 2869 (clear-stream _test-input-stream) + 2870 (clear-stream $_test-input-buffered-file->buffer) + 2871 (clear-stream _test-output-stream) + 2872 (clear-stream $_test-output-buffered-file->buffer) + 2873 # + 2874 (write _test-input-stream "fn foo -> x/ecx: int {\n") + 2875 (write _test-input-stream " x <- copy 0x34\n") + 2876 (write _test-input-stream " compare x, 0x35\n") + 2877 (write _test-input-stream "}\n") + 2878 # convert + 2879 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2880 (flush _test-output-buffered-file) + 2881 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2887 # check output + 2888 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-read-output/0") + 2889 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-read-output/1") + 2890 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-read-output/2") + 2891 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-read-output/3") + 2892 (check-next-stream-line-equal _test-output-stream " {" "F - test-read-output/4") + 2893 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-read-output/5") + 2894 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x34/imm32" "F - test-read-output/6") + 2895 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0x35/imm32" "F - test-read-output/7") + 2896 (check-next-stream-line-equal _test-output-stream " }" "F - test-read-output/8") + 2897 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-read-output/9") + 2898 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-read-output/10") + 2899 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-read-output/11") + 2900 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-read-output/12") + 2901 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-read-output/13") + 2902 # . epilogue + 2903 89/<- %esp 5/r32/ebp + 2904 5d/pop-to-ebp + 2905 c3/return + 2906 + 2907 test-fn-output-written-in-inner-block: + 2908 # . prologue + 2909 55/push-ebp + 2910 89/<- %ebp 4/r32/esp + 2911 # setup + 2912 (clear-stream _test-input-stream) + 2913 (clear-stream $_test-input-buffered-file->buffer) + 2914 (clear-stream _test-output-stream) + 2915 (clear-stream $_test-output-buffered-file->buffer) + 2916 # + 2917 (write _test-input-stream "fn foo -> out/edi: int {\n") + 2918 (write _test-input-stream " var a/eax: int <- copy 3\n") # define outer local + 2919 (write _test-input-stream " {\n") + 2920 (write _test-input-stream " var a/ecx: int <- copy 4\n") # shadow outer local + 2921 (write _test-input-stream " out <- copy a\n") # write to fn output + 2922 (write _test-input-stream " }\n") + 2923 (write _test-input-stream " compare a, 0\n") # use outer local + 2924 (write _test-input-stream "}\n") + 2925 # convert + 2926 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2927 (flush _test-output-buffered-file) + 2928 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2934 # no error; defining 'out' didn't interfere with the reclamation of 'b' + 2935 # check output + 2936 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-fn-output-written-in-inner-block/0") + 2937 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-fn-output-written-in-inner-block/1") + 2938 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-fn-output-written-in-inner-block/2") + 2939 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-fn-output-written-in-inner-block/3") + 2940 (check-next-stream-line-equal _test-output-stream " {" "F - test-fn-output-written-in-inner-block/4") + 2941 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-fn-output-written-in-inner-block/5") + 2942 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-fn-output-written-in-inner-block/6") + 2943 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-fn-output-written-in-inner-block/7") + 2944 (check-next-stream-line-equal _test-output-stream " {" "F - test-fn-output-written-in-inner-block/8") + 2945 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-fn-output-written-in-inner-block/9") + 2946 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-fn-output-written-in-inner-block/10") + 2947 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-fn-output-written-in-inner-block/10") + 2948 (check-next-stream-line-equal _test-output-stream " 89/<- %edi 0x00000001/r32" "F - test-fn-output-written-in-inner-block/11") + 2949 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-fn-output-written-in-inner-block/12") + 2950 (check-next-stream-line-equal _test-output-stream " }" "F - test-fn-output-written-in-inner-block/13") + 2951 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-fn-output-written-in-inner-block/14") + 2952 (check-next-stream-line-equal _test-output-stream " 3d/compare-eax-with 0/imm32" "F - test-fn-output-written-in-inner-block/15") + 2953 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-fn-output-written-in-inner-block/16") + 2954 (check-next-stream-line-equal _test-output-stream " }" "F - test-fn-output-written-in-inner-block/17") + 2955 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-fn-output-written-in-inner-block/18") + 2956 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-fn-output-written-in-inner-block/19") + 2957 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-fn-output-written-in-inner-block/20") + 2958 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-fn-output-written-in-inner-block/21") + 2959 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-fn-output-written-in-inner-block/22") + 2960 # . epilogue + 2961 89/<- %esp 5/r32/ebp + 2962 5d/pop-to-ebp + 2963 c3/return + 2964 + 2965 test-convert-function-with-branches-in-block: + 2966 # . prologue + 2967 55/push-ebp + 2968 89/<- %ebp 4/r32/esp + 2969 # setup + 2970 (clear-stream _test-input-stream) + 2971 (clear-stream $_test-input-buffered-file->buffer) + 2972 (clear-stream _test-output-stream) + 2973 (clear-stream $_test-output-buffered-file->buffer) + 2974 # + 2975 (write _test-input-stream "fn foo x: int {\n") + 2976 (write _test-input-stream " {\n") + 2977 (write _test-input-stream " break-if->=\n") + 2978 (write _test-input-stream " loop-if-addr<\n") + 2979 (write _test-input-stream " increment x\n") + 2980 (write _test-input-stream " loop\n") + 2981 (write _test-input-stream " }\n") + 2982 (write _test-input-stream "}\n") + 2983 # convert + 2984 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2985 (flush _test-output-buffered-file) + 2986 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2992 # check output + 2993 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-block/0") + 2994 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1") + 2995 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2") + 2996 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3") + 2997 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4") + 2998 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5") + 2999 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6") + 3000 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7") + 3001 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/8") + 3002 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-block/9") + 3003 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-in-block/10") + 3004 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/11") + 3005 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/12") + 3006 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-block/13") + 3007 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-branches-in-block/14") + 3008 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/15") + 3009 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/16") + 3010 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/17") + 3011 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/18") + 3012 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/19") + 3013 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/20") + 3014 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/21") + 3015 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/22") + 3016 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/23") + 3017 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/24") + 3018 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/25") + 3019 # . epilogue + 3020 89/<- %esp 5/r32/ebp + 3021 5d/pop-to-ebp + 3022 c3/return + 3023 + 3024 test-convert-function-with-branches-in-named-block: + 3025 # . prologue + 3026 55/push-ebp + 3027 89/<- %ebp 4/r32/esp + 3028 # setup + 3029 (clear-stream _test-input-stream) + 3030 (clear-stream $_test-input-buffered-file->buffer) + 3031 (clear-stream _test-output-stream) + 3032 (clear-stream $_test-output-buffered-file->buffer) + 3033 # + 3034 (write _test-input-stream "fn foo x: int {\n") + 3035 (write _test-input-stream " $bar: {\n") + 3036 (write _test-input-stream " break-if->= $bar\n") + 3037 (write _test-input-stream " loop-if-addr< $bar\n") + 3038 (write _test-input-stream " increment x\n") + 3039 (write _test-input-stream " loop\n") + 3040 (write _test-input-stream " }\n") + 3041 (write _test-input-stream "}\n") + 3042 # convert + 3043 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3044 (flush _test-output-buffered-file) + 3045 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3051 # check output + 3052 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-named-block/0") + 3053 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-named-block/1") + 3054 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-named-block/2") + 3055 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-named-block/3") + 3056 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/4") + 3057 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-named-block/5") + 3058 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/6") + 3059 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-branches-in-named-block/7") + 3060 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/8") + 3061 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-named-block/9") + 3062 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:break/disp32" "F - test-convert-function-with-branches-in-named-block/10") + 3063 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/11") + 3064 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/12") + 3065 (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") + 3066 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:loop/disp32" "F - test-convert-function-with-branches-in-named-block/14") + 3067 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/15") + 3068 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-named-block/16") + 3069 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-named-block/17") + 3070 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/18") + 3071 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-branches-in-named-block/19") + 3072 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/20") + 3073 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-named-block/21") + 3074 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-named-block/22") + 3075 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-named-block/23") + 3076 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-named-block/24") + 3077 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-named-block/25") + 3078 # . epilogue + 3079 89/<- %esp 5/r32/ebp + 3080 5d/pop-to-ebp + 3081 c3/return + 3082 + 3083 test-convert-function-with-var-in-nested-block: + 3084 # . prologue + 3085 55/push-ebp + 3086 89/<- %ebp 4/r32/esp + 3087 # setup + 3088 (clear-stream _test-input-stream) + 3089 (clear-stream $_test-input-buffered-file->buffer) + 3090 (clear-stream _test-output-stream) + 3091 (clear-stream $_test-output-buffered-file->buffer) + 3092 # + 3093 (write _test-input-stream "fn foo x: int {\n") + 3094 (write _test-input-stream " {\n") + 3095 (write _test-input-stream " {\n") + 3096 (write _test-input-stream " var x: int\n") + 3097 (write _test-input-stream " increment x\n") + 3098 (write _test-input-stream " }\n") + 3099 (write _test-input-stream " }\n") + 3100 (write _test-input-stream "}\n") + 3101 # convert + 3102 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3103 (flush _test-output-buffered-file) + 3104 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3110 # check output + 3111 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-var-in-nested-block/0") + 3112 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-var-in-nested-block/1") + 3113 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-var-in-nested-block/2") + 3114 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-var-in-nested-block/3") + 3115 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/4") + 3116 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-var-in-nested-block/5") + 3117 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/6") + 3118 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-var-in-nested-block/7") + 3119 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/8") + 3120 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-var-in-nested-block/9") + 3121 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-var-in-nested-block/10") + 3122 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-var-in-nested-block/11") + 3123 (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") + 3124 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/13") + 3125 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-var-in-nested-block/14") + 3126 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/15") + 3127 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-var-in-nested-block/16") + 3128 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/17") + 3129 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-var-in-nested-block/18") + 3130 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-var-in-nested-block/19") + 3131 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-var-in-nested-block/20") + 3132 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-var-in-nested-block/21") + 3133 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-var-in-nested-block/22") + 3134 # . epilogue + 3135 89/<- %esp 5/r32/ebp + 3136 5d/pop-to-ebp + 3137 c3/return + 3138 + 3139 test-convert-function-with-multiple-vars-in-nested-blocks: + 3140 # . prologue + 3141 55/push-ebp + 3142 89/<- %ebp 4/r32/esp + 3143 # setup + 3144 (clear-stream _test-input-stream) + 3145 (clear-stream $_test-input-buffered-file->buffer) + 3146 (clear-stream _test-output-stream) + 3147 (clear-stream $_test-output-buffered-file->buffer) + 3148 # + 3149 (write _test-input-stream "fn foo x: int {\n") + 3150 (write _test-input-stream " {\n") + 3151 (write _test-input-stream " var x/eax: int <- copy 0\n") + 3152 (write _test-input-stream " {\n") + 3153 (write _test-input-stream " var y: int\n") + 3154 (write _test-input-stream " x <- add y\n") + 3155 (write _test-input-stream " }\n") + 3156 (write _test-input-stream " }\n") + 3157 (write _test-input-stream "}\n") + 3158 # convert + 3159 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3160 (flush _test-output-buffered-file) + 3161 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3167 # check output + 3168 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/0") + 3169 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/1") + 3170 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/2") + 3171 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/3") + 3172 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/4") + 3173 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/5") + 3174 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/6") + 3175 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/7") + 3176 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/8") + 3177 (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") + 3178 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/10") + 3179 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/11") + 3180 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/12") + 3181 (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") + 3182 (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") + 3183 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/15") + 3184 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/16") + 3185 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/17") + 3186 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/18") + 3187 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/19") + 3188 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/20") + 3189 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/21") + 3190 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/22") + 3191 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/23") + 3192 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/24") + 3193 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-multiple-vars-in-nested-blocks/25") + 3194 # . epilogue + 3195 89/<- %esp 5/r32/ebp + 3196 5d/pop-to-ebp + 3197 c3/return + 3198 + 3199 test-convert-function-with-branches-and-local-vars: + 3200 # A conditional 'break' after a 'var' in a block is converted into a + 3201 # nested block that performs all necessary cleanup before jumping. This + 3202 # results in some ugly code duplication. + 3203 # . prologue + 3204 55/push-ebp + 3205 89/<- %ebp 4/r32/esp + 3206 # setup + 3207 (clear-stream _test-input-stream) + 3208 (clear-stream $_test-input-buffered-file->buffer) + 3209 (clear-stream _test-output-stream) + 3210 (clear-stream $_test-output-buffered-file->buffer) + 3211 # + 3212 (write _test-input-stream "fn foo {\n") + 3213 (write _test-input-stream " {\n") + 3214 (write _test-input-stream " var x: int\n") + 3215 (write _test-input-stream " break-if->=\n") + 3216 (write _test-input-stream " increment x\n") + 3217 (write _test-input-stream " }\n") + 3218 (write _test-input-stream "}\n") + 3219 # convert + 3220 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3221 (flush _test-output-buffered-file) + 3222 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3228 # check output + 3229 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-local-vars/0") + 3230 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-local-vars/1") + 3231 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-local-vars/2") + 3232 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-local-vars/3") + 3233 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/4") + 3234 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-local-vars/5") + 3235 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/6") + 3236 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-local-vars/7") + 3237 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-local-vars/8") + 3238 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/9") + 3239 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-local-vars/10") + 3240 (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") + 3241 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-local-vars/12") + 3242 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/13") + 3243 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-local-vars/14") + 3244 (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") + 3245 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/16") + 3246 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-local-vars/17") + 3247 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/18") + 3248 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-local-vars/19") + 3249 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-local-vars/20") + 3250 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-local-vars/21") + 3251 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-local-vars/22") + 3252 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-local-vars/23") + 3253 # . epilogue + 3254 89/<- %esp 5/r32/ebp + 3255 5d/pop-to-ebp + 3256 c3/return + 3257 + 3258 test-convert-function-with-conditional-loops-and-local-vars: + 3259 # A conditional 'loop' after a 'var' in a block is converted into a nested + 3260 # block that performs all necessary cleanup before jumping. This results + 3261 # in some ugly code duplication. + 3262 # . prologue + 3263 55/push-ebp + 3264 89/<- %ebp 4/r32/esp + 3265 # setup + 3266 (clear-stream _test-input-stream) + 3267 (clear-stream $_test-input-buffered-file->buffer) + 3268 (clear-stream _test-output-stream) + 3269 (clear-stream $_test-output-buffered-file->buffer) + 3270 # + 3271 (write _test-input-stream "fn foo {\n") + 3272 (write _test-input-stream " {\n") + 3273 (write _test-input-stream " var x: int\n") + 3274 (write _test-input-stream " loop-if->=\n") + 3275 (write _test-input-stream " increment x\n") + 3276 (write _test-input-stream " }\n") + 3277 (write _test-input-stream "}\n") + 3278 # convert + 3279 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3280 (flush _test-output-buffered-file) + 3281 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3287 # check output + 3288 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-conditional-loops-and-local-vars/0") + 3289 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-conditional-loops-and-local-vars/1") + 3290 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/2") + 3291 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-conditional-loops-and-local-vars/3") + 3292 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/4") + 3293 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/5") + 3294 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/6") + 3295 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/7") + 3296 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/8") + 3297 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/9") + 3298 (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") + 3299 (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") + 3300 (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") + 3301 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/13") + 3302 (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") + 3303 (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") + 3304 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/16") + 3305 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/17") + 3306 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/18") + 3307 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/19") + 3308 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-conditional-loops-and-local-vars/20") + 3309 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/21") + 3310 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/22") + 3311 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-conditional-loops-and-local-vars/23") + 3312 # . epilogue + 3313 89/<- %esp 5/r32/ebp + 3314 5d/pop-to-ebp + 3315 c3/return + 3316 + 3317 test-convert-function-with-unconditional-loops-and-local-vars: + 3318 # An unconditional 'loop' after a 'var' in a block is emitted _after_ the + 3319 # regular block cleanup. Any instructions after 'loop' are dead and + 3320 # therefore skipped. + 3321 # . prologue + 3322 55/push-ebp + 3323 89/<- %ebp 4/r32/esp + 3324 # setup + 3325 (clear-stream _test-input-stream) + 3326 (clear-stream $_test-input-buffered-file->buffer) + 3327 (clear-stream _test-output-stream) + 3328 (clear-stream $_test-output-buffered-file->buffer) + 3329 # + 3330 (write _test-input-stream "fn foo {\n") + 3331 (write _test-input-stream " {\n") + 3332 (write _test-input-stream " var x: int\n") + 3333 (write _test-input-stream " loop\n") + 3334 (write _test-input-stream " increment x\n") + 3335 (write _test-input-stream " }\n") + 3336 (write _test-input-stream "}\n") + 3337 # convert + 3338 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3339 (flush _test-output-buffered-file) + 3340 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3346 # check output + 3347 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-loops-and-local-vars/0") + 3348 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-loops-and-local-vars/1") + 3349 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/2") + 3350 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-loops-and-local-vars/3") + 3351 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/4") + 3352 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/5") + 3353 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/6") + 3354 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/7") + 3355 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/8") + 3356 (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") + 3357 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-unconditional-loops-and-local-vars/10") + 3358 # not emitted: ff 0/subop/increment *(ebp+0xfffffffc) + 3359 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/11") + 3360 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/12") + 3361 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/13") + 3362 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/14") + 3363 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-loops-and-local-vars/15") + 3364 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/16") + 3365 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/17") + 3366 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-loops-and-local-vars/18") + 3367 # . epilogue + 3368 89/<- %esp 5/r32/ebp + 3369 5d/pop-to-ebp + 3370 c3/return + 3371 + 3372 test-convert-function-with-branches-and-loops-and-local-vars: + 3373 # . prologue + 3374 55/push-ebp + 3375 89/<- %ebp 4/r32/esp + 3376 # setup + 3377 (clear-stream _test-input-stream) + 3378 (clear-stream $_test-input-buffered-file->buffer) + 3379 (clear-stream _test-output-stream) + 3380 (clear-stream $_test-output-buffered-file->buffer) + 3381 # + 3382 (write _test-input-stream "fn foo {\n") + 3383 (write _test-input-stream " {\n") + 3384 (write _test-input-stream " var x: int\n") + 3385 (write _test-input-stream " break-if->=\n") + 3386 (write _test-input-stream " increment x\n") + 3387 (write _test-input-stream " loop\n") + 3388 (write _test-input-stream " }\n") + 3389 (write _test-input-stream "}\n") + 3390 # convert + 3391 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3392 (flush _test-output-buffered-file) + 3393 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3399 # check output + 3400 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-loops-and-local-vars/0") + 3401 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-loops-and-local-vars/1") + 3402 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/2") + 3403 (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") + 3404 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/4") + 3405 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/5") + 3406 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/6") + 3407 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/7") + 3408 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/8") + 3409 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/9") + 3410 (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") + 3411 (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") + 3412 (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") + 3413 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/13") + 3414 (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") + 3415 (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") + 3416 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/16") + 3417 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/17") + 3418 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/18") + 3419 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/19") + 3420 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/20") + 3421 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-loops-and-local-vars/21") + 3422 (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") + 3423 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/23") + 3424 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-loops-and-local-vars/24") + 3425 # . epilogue + 3426 89/<- %esp 5/r32/ebp + 3427 5d/pop-to-ebp + 3428 c3/return + 3429 + 3430 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars: + 3431 # . prologue + 3432 55/push-ebp + 3433 89/<- %ebp 4/r32/esp + 3434 # setup + 3435 (clear-stream _test-input-stream) + 3436 (clear-stream $_test-input-buffered-file->buffer) + 3437 (clear-stream _test-output-stream) + 3438 (clear-stream $_test-output-buffered-file->buffer) + 3439 # + 3440 (write _test-input-stream "fn foo {\n") + 3441 (write _test-input-stream " a: {\n") + 3442 (write _test-input-stream " var x: int\n") + 3443 (write _test-input-stream " {\n") + 3444 (write _test-input-stream " var y: int\n") + 3445 (write _test-input-stream " break-if->= a\n") + 3446 (write _test-input-stream " increment x\n") + 3447 (write _test-input-stream " loop\n") + 3448 (write _test-input-stream " }\n") + 3449 (write _test-input-stream " }\n") + 3450 (write _test-input-stream "}\n") + 3451 # convert + 3452 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3453 (flush _test-output-buffered-file) + 3454 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3460 # check output + 3461 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/0") + 3462 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/1") + 3463 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/2") + 3464 (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") + 3465 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/4") + 3466 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/5") + 3467 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/6") + 3468 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/7") + 3469 (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") + 3470 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/9") + 3471 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/10") + 3472 (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") + 3473 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/12") + 3474 (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") + 3475 (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") + 3476 (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") + 3477 (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") + 3478 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/17") + 3479 (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") + 3480 (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") + 3481 (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") + 3482 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/21") + 3483 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/22") + 3484 (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") + 3485 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/24") + 3486 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/25") + 3487 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/26") + 3488 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/27") + 3489 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/28") + 3490 (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") + 3491 (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") + 3492 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/31") + 3493 # . epilogue + 3494 89/<- %esp 5/r32/ebp + 3495 5d/pop-to-ebp + 3496 c3/return + 3497 + 3498 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2: + 3499 # . prologue + 3500 55/push-ebp + 3501 89/<- %ebp 4/r32/esp + 3502 # setup + 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 # non-local conditional branch from a block without a local variable, + 3508 # unwinding a local on the stack + 3509 (write _test-input-stream "fn foo {\n") + 3510 (write _test-input-stream " a: {\n") + 3511 (write _test-input-stream " var x: int\n") + 3512 (write _test-input-stream " {\n") + 3513 (write _test-input-stream " break-if->= a\n") + 3514 (write _test-input-stream " }\n") + 3515 (write _test-input-stream " }\n") + 3516 (write _test-input-stream "}\n") + 3517 # convert + 3518 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3519 (flush _test-output-buffered-file) + 3520 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3526 # check output + 3527 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/0") + 3528 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/1") + 3529 (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") + 3530 (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") + 3531 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/4") + 3532 (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") + 3533 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/6") + 3534 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/7") + 3535 (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") + 3536 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/9") + 3537 (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") + 3538 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/11") + 3539 (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") + 3540 (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") + 3541 (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") + 3542 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/15") + 3543 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/16") + 3544 (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") + 3545 (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") + 3546 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/19") + 3547 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/20") + 3548 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/21") + 3549 (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") + 3550 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/23") + 3551 (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") + 3552 (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") + 3553 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/26") + 3554 # . epilogue + 3555 89/<- %esp 5/r32/ebp + 3556 5d/pop-to-ebp + 3557 c3/return + 3558 + 3559 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3: + 3560 # . prologue + 3561 55/push-ebp + 3562 89/<- %ebp 4/r32/esp + 3563 # setup + 3564 (clear-stream _test-input-stream) + 3565 (clear-stream $_test-input-buffered-file->buffer) + 3566 (clear-stream _test-output-stream) + 3567 (clear-stream $_test-output-buffered-file->buffer) + 3568 # non-local unconditional branch from a block without a local variable, + 3569 # unwinding a local on the stack + 3570 (write _test-input-stream "fn foo {\n") + 3571 (write _test-input-stream " a: {\n") + 3572 (write _test-input-stream " var x: int\n") + 3573 (write _test-input-stream " {\n") + 3574 (write _test-input-stream " break a\n") + 3575 (write _test-input-stream " }\n") + 3576 (write _test-input-stream " }\n") + 3577 (write _test-input-stream "}\n") + 3578 # convert + 3579 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3580 (flush _test-output-buffered-file) + 3581 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3587 # check output + 3588 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/0") + 3589 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/1") + 3590 (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") + 3591 (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") + 3592 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/4") + 3593 (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") + 3594 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/6") + 3595 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/7") + 3596 (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") + 3597 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/9") + 3598 (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") + 3599 (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") + 3600 (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") + 3601 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/14") + 3602 (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") + 3603 (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") + 3604 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/17") + 3605 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/18") + 3606 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/19") + 3607 (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") + 3608 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/21") + 3609 (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") + 3610 (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") + 3611 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/24") + 3612 # . epilogue + 3613 89/<- %esp 5/r32/ebp + 3614 5d/pop-to-ebp + 3615 c3/return + 3616 + 3617 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4: + 3618 # . prologue + 3619 55/push-ebp + 3620 89/<- %ebp 4/r32/esp + 3621 # setup + 3622 (clear-stream _test-input-stream) + 3623 (clear-stream $_test-input-buffered-file->buffer) + 3624 (clear-stream _test-output-stream) + 3625 (clear-stream $_test-output-buffered-file->buffer) + 3626 # + 3627 (write _test-input-stream "fn foo {\n") + 3628 (write _test-input-stream " a: {\n") + 3629 (write _test-input-stream " var x/esi: int <- copy 0\n") + 3630 (write _test-input-stream " {\n") + 3631 (write _test-input-stream " break a\n") + 3632 (write _test-input-stream " }\n") + 3633 (write _test-input-stream " }\n") + 3634 (write _test-input-stream "}\n") + 3635 # convert + 3636 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3637 (flush _test-output-buffered-file) + 3638 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3644 # check output + 3645 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/0") + 3646 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/1") + 3647 (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") + 3648 (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") + 3649 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/4") + 3650 (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") + 3651 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/6") + 3652 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/7") + 3653 (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") + 3654 (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") + 3655 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/10") + 3656 (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") + 3657 (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") + 3658 (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") + 3659 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/14") + 3660 (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") + 3661 (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") + 3662 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/17") + 3663 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/18") + 3664 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/19") + 3665 (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") + 3666 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/21") + 3667 (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") + 3668 (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") + 3669 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/24") + 3670 # . epilogue + 3671 89/<- %esp 5/r32/ebp + 3672 5d/pop-to-ebp + 3673 c3/return + 3674 + 3675 test-convert-function-with-nonlocal-unconditional-break-and-local-vars: + 3676 # . prologue + 3677 55/push-ebp + 3678 89/<- %ebp 4/r32/esp + 3679 # setup + 3680 (clear-stream _test-input-stream) + 3681 (clear-stream $_test-input-buffered-file->buffer) + 3682 (clear-stream _test-output-stream) + 3683 (clear-stream $_test-output-buffered-file->buffer) + 3684 # + 3685 (write _test-input-stream "fn foo {\n") + 3686 (write _test-input-stream " a: {\n") + 3687 (write _test-input-stream " var x: int\n") + 3688 (write _test-input-stream " {\n") + 3689 (write _test-input-stream " var y: int\n") + 3690 (write _test-input-stream " break a\n") + 3691 (write _test-input-stream " increment x\n") + 3692 (write _test-input-stream " }\n") + 3693 (write _test-input-stream " }\n") + 3694 (write _test-input-stream "}\n") + 3695 # convert + 3696 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3697 (flush _test-output-buffered-file) + 3698 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3704 # check output + 3705 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/0") + 3706 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/1") + 3707 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/2") + 3708 (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") + 3709 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/4") + 3710 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/5") + 3711 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/6") + 3712 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/7") + 3713 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/8") + 3714 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/9") + 3715 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/10") + 3716 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/11") + 3717 (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") + 3718 (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") + 3719 (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") + 3720 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/15") + 3721 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/16") + 3722 (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") + 3723 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/18") + 3724 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/19") + 3725 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/20") + 3726 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/21") + 3727 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/22") + 3728 (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") + 3729 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/24") + 3730 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/25") + 3731 # . epilogue + 3732 89/<- %esp 5/r32/ebp + 3733 5d/pop-to-ebp + 3734 c3/return + 3735 + 3736 test-convert-function-with-unconditional-break-and-local-vars: + 3737 # . prologue + 3738 55/push-ebp + 3739 89/<- %ebp 4/r32/esp + 3740 # setup + 3741 (clear-stream _test-input-stream) + 3742 (clear-stream $_test-input-buffered-file->buffer) + 3743 (clear-stream _test-output-stream) + 3744 (clear-stream $_test-output-buffered-file->buffer) + 3745 # + 3746 (write _test-input-stream "fn foo {\n") + 3747 (write _test-input-stream " {\n") + 3748 (write _test-input-stream " var x: int\n") + 3749 (write _test-input-stream " {\n") + 3750 (write _test-input-stream " var y: int\n") + 3751 (write _test-input-stream " break\n") + 3752 (write _test-input-stream " increment x\n") + 3753 (write _test-input-stream " }\n") + 3754 (write _test-input-stream " }\n") + 3755 (write _test-input-stream "}\n") + 3756 # convert + 3757 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3758 (flush _test-output-buffered-file) + 3759 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3765 # check output + 3766 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-break-and-local-vars/0") + 3767 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-break-and-local-vars/1") + 3768 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/2") + 3769 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-break-and-local-vars/3") + 3770 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/4") + 3771 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/5") + 3772 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/6") + 3773 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/7") + 3774 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/8") + 3775 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/9") + 3776 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/10") + 3777 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/11") + 3778 (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") + 3779 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/13") + 3780 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/14") + 3781 (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") + 3782 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/16") + 3783 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/17") + 3784 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/18") + 3785 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/19") + 3786 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-break-and-local-vars/20") + 3787 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/21") + 3788 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/22") + 3789 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-break-and-local-vars/23") + 3790 # . epilogue + 3791 89/<- %esp 5/r32/ebp + 3792 5d/pop-to-ebp + 3793 c3/return + 3794 + 3795 test-convert-function-with-nonlocal-unconditional-loop-and-local-vars: + 3796 # . prologue + 3797 55/push-ebp + 3798 89/<- %ebp 4/r32/esp + 3799 # setup + 3800 (clear-stream _test-input-stream) + 3801 (clear-stream $_test-input-buffered-file->buffer) + 3802 (clear-stream _test-output-stream) + 3803 (clear-stream $_test-output-buffered-file->buffer) + 3804 # + 3805 (write _test-input-stream "fn foo {\n") + 3806 (write _test-input-stream " a: {\n") + 3807 (write _test-input-stream " var x: int\n") + 3808 (write _test-input-stream " {\n") + 3809 (write _test-input-stream " var y: int\n") + 3810 (write _test-input-stream " loop a\n") + 3811 (write _test-input-stream " increment x\n") + 3812 (write _test-input-stream " }\n") + 3813 (write _test-input-stream " }\n") + 3814 (write _test-input-stream "}\n") + 3815 # convert + 3816 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3817 (flush _test-output-buffered-file) + 3818 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3824 # check output + 3825 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/0") + 3826 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/1") + 3827 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/2") + 3828 (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") + 3829 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/4") + 3830 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/5") + 3831 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/6") + 3832 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/7") + 3833 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/8") + 3834 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/9") + 3835 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/10") + 3836 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/11") + 3837 (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") + 3838 (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") + 3839 (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") + 3840 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/15") + 3841 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/16") + 3842 (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") + 3843 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/18") + 3844 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/19") + 3845 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/20") + 3846 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/21") + 3847 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/22") + 3848 (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") + 3849 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/24") + 3850 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/25") + 3851 # . epilogue + 3852 89/<- %esp 5/r32/ebp + 3853 5d/pop-to-ebp + 3854 c3/return + 3855 + 3856 test-convert-function-with-local-array-var-in-mem: + 3857 # . prologue + 3858 55/push-ebp + 3859 89/<- %ebp 4/r32/esp + 3860 # setup + 3861 (clear-stream _test-input-stream) + 3862 (clear-stream $_test-input-buffered-file->buffer) + 3863 (clear-stream _test-output-stream) + 3864 (clear-stream $_test-output-buffered-file->buffer) + 3865 # + 3866 (write _test-input-stream "fn foo {\n") + 3867 (write _test-input-stream " var x: (array int 3)\n") + 3868 (write _test-input-stream "}\n") + 3869 # convert + 3870 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3871 (flush _test-output-buffered-file) + 3872 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3878 # check output + 3879 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-var-in-mem/0") + 3880 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-var-in-mem/1") + 3881 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-var-in-mem/2") + 3882 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-array-var-in-mem/3") + 3883 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-var-in-mem/4") + 3884 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-var-in-mem/5") + 3885 # define x + 3886 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-function-with-local-array-var-in-mem/7") + 3887 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-function-with-local-array-var-in-mem/8") + 3888 # reclaim x + 3889 (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") + 3890 # + 3891 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-var-in-mem/10") + 3892 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-var-in-mem/11") + 3893 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-var-in-mem/12") + 3894 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-array-var-in-mem/13") + 3895 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-var-in-mem/14") + 3896 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-var-in-mem/15") + 3897 # . epilogue + 3898 89/<- %esp 5/r32/ebp + 3899 5d/pop-to-ebp + 3900 c3/return + 3901 + 3902 test-array-size-in-hex: + 3903 # . prologue + 3904 55/push-ebp + 3905 89/<- %ebp 4/r32/esp + 3906 # setup + 3907 (clear-stream _test-input-stream) + 3908 (clear-stream $_test-input-buffered-file->buffer) + 3909 (clear-stream _test-output-stream) + 3910 (clear-stream $_test-output-buffered-file->buffer) + 3911 (clear-stream _test-error-stream) + 3912 (clear-stream $_test-error-buffered-file->buffer) + 3913 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 3914 68/push 0/imm32 + 3915 68/push 0/imm32 + 3916 89/<- %edx 4/r32/esp + 3917 (tailor-exit-descriptor %edx 0x10) + 3918 # + 3919 (write _test-input-stream "fn foo {\n") + 3920 (write _test-input-stream " var x: (array int 10)\n") + 3921 (write _test-input-stream "}\n") + 3922 # convert + 3923 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3924 # registers except esp clobbered at this point + 3925 # restore ed + 3926 89/<- %edx 4/r32/esp + 3927 (flush _test-output-buffered-file) + 3928 (flush _test-error-buffered-file) + 3929 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 3935 # check output + 3936 (check-stream-equal _test-output-stream "" "F - test-array-size-in-hex: output should be empty") + 3937 (check-next-stream-line-equal _test-error-stream "literal integers are always hex in Mu; either start '10' with a '0x' to be unambiguous, or convert it to decimal." "F - test-array-size-in-hex: error message") + 3938 # check that stop(1) was called + 3939 (check-ints-equal *(edx+4) 2 "F - test-array-size-in-hex: exit status") + 3940 # don't restore from ebp + 3941 81 0/subop/add %esp 8/imm32 + 3942 # . epilogue + 3943 5d/pop-to-ebp + 3944 c3/return + 3945 + 3946 test-convert-function-with-populate: + 3947 # . prologue + 3948 55/push-ebp + 3949 89/<- %ebp 4/r32/esp + 3950 # setup + 3951 (clear-stream _test-input-stream) + 3952 (clear-stream $_test-input-buffered-file->buffer) + 3953 (clear-stream _test-output-stream) + 3954 (clear-stream $_test-output-buffered-file->buffer) + 3955 # + 3956 (write _test-input-stream "fn foo {\n") + 3957 (write _test-input-stream " var x/ecx: (addr handle array int) <- copy 0\n") + 3958 (write _test-input-stream " populate x, 7\n") + 3959 (write _test-input-stream "}\n") + 3960 # convert + 3961 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3962 (flush _test-output-buffered-file) + 3963 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3969 # check output + 3970 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-populate/0") + 3971 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-populate/1") + 3972 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-populate/2") + 3973 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-populate/3") + 3974 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-populate/4") + 3975 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-populate/5") + 3976 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-populate/6") + 3977 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-populate/7") + 3978 (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) + 3979 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-populate/9") + 3980 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-populate/10") + 3981 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-populate/11") + 3982 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-populate/12") + 3983 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-populate/13") + 3984 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-populate/14") + 3985 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-populate/15") + 3986 # . epilogue + 3987 89/<- %esp 5/r32/ebp + 3988 5d/pop-to-ebp + 3989 c3/return + 3990 + 3991 # special-case for size(byte) when allocating array + 3992 test-convert-function-with-local-array-of-bytes-in-mem: + 3993 # . prologue + 3994 55/push-ebp + 3995 89/<- %ebp 4/r32/esp + 3996 # setup + 3997 (clear-stream _test-input-stream) + 3998 (clear-stream $_test-input-buffered-file->buffer) + 3999 (clear-stream _test-output-stream) + 4000 (clear-stream $_test-output-buffered-file->buffer) + 4001 # + 4002 (write _test-input-stream "fn foo {\n") + 4003 (write _test-input-stream " var x: (array byte 3)\n") + 4004 (write _test-input-stream "}\n") + 4005 # convert + 4006 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4007 (flush _test-output-buffered-file) + 4008 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4014 # check output + 4015 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-of-bytes-in-mem/0") + 4016 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-of-bytes-in-mem/1") + 4017 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/2") + 4018 (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") + 4019 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-of-bytes-in-mem/4") + 4020 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-of-bytes-in-mem/5") + 4021 # define x + 4022 (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") + 4023 (check-next-stream-line-equal _test-output-stream " 68/push 0x00000003/imm32" "F - test-convert-function-with-local-array-of-bytes-in-mem/8") + 4024 # reclaim x + 4025 (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") + 4026 # + 4027 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-of-bytes-in-mem/10") + 4028 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-of-bytes-in-mem/11") + 4029 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-of-bytes-in-mem/12") + 4030 (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") + 4031 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/14") + 4032 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-of-bytes-in-mem/15") + 4033 # . epilogue + 4034 89/<- %esp 5/r32/ebp + 4035 5d/pop-to-ebp + 4036 c3/return + 4037 + 4038 test-convert-address: + 4039 # . prologue + 4040 55/push-ebp + 4041 89/<- %ebp 4/r32/esp + 4042 # setup + 4043 (clear-stream _test-input-stream) + 4044 (clear-stream $_test-input-buffered-file->buffer) + 4045 (clear-stream _test-output-stream) + 4046 (clear-stream $_test-output-buffered-file->buffer) + 4047 # + 4048 (write _test-input-stream "fn foo {\n") + 4049 (write _test-input-stream " var a: int\n") + 4050 (write _test-input-stream " var b/eax: (addr int) <- address a\n") + 4051 (write _test-input-stream "}\n") + 4052 # convert + 4053 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4054 (flush _test-output-buffered-file) + 4055 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4061 # check output + 4062 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-address/0") + 4063 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-address/1") + 4064 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-address/2") + 4065 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-address/3") + 4066 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-address/4") + 4067 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-address/5") + 4068 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-address/6") + 4069 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-address/7") + 4070 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-address/8") + 4071 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-address/9") + 4072 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-address/10") + 4073 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-address/11") + 4074 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-address/12") + 4075 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-address/13") + 4076 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-address/14") + 4077 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-address/15") + 4078 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-address/16") + 4079 # . epilogue + 4080 89/<- %esp 5/r32/ebp + 4081 5d/pop-to-ebp + 4082 c3/return + 4083 + 4084 test-convert-length-of-array: + 4085 # . prologue + 4086 55/push-ebp + 4087 89/<- %ebp 4/r32/esp + 4088 # setup + 4089 (clear-stream _test-input-stream) + 4090 (clear-stream $_test-input-buffered-file->buffer) + 4091 (clear-stream _test-output-stream) + 4092 (clear-stream $_test-output-buffered-file->buffer) + 4093 # + 4094 (write _test-input-stream "fn foo a: (addr array int) {\n") + 4095 (write _test-input-stream " var b/eax: (addr array int) <- copy a\n") + 4096 (write _test-input-stream " var c/eax: int <- length b\n") + 4097 (write _test-input-stream "}\n") + 4098 # convert + 4099 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4100 (flush _test-output-buffered-file) + 4101 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4107 # check output + 4108 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array/0") + 4109 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array/1") + 4110 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array/2") + 4111 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array/3") + 4112 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array/4") + 4113 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array/5") + 4114 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array/6") + 4115 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array/7") + 4116 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array/8") + 4117 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array/9") + 4118 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array/10") + 4119 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array/11") + 4120 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array/12") + 4121 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array/13") + 4122 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array/14") + 4123 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array/15") + 4124 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array/16") + 4125 # . epilogue + 4126 89/<- %esp 5/r32/ebp + 4127 5d/pop-to-ebp + 4128 c3/return + 4129 + 4130 # special-case for size(byte) when computing array length + 4131 test-convert-length-of-array-of-bytes: + 4132 # . prologue + 4133 55/push-ebp + 4134 89/<- %ebp 4/r32/esp + 4135 # setup + 4136 (clear-stream _test-input-stream) + 4137 (clear-stream $_test-input-buffered-file->buffer) + 4138 (clear-stream _test-output-stream) + 4139 (clear-stream $_test-output-buffered-file->buffer) + 4140 # + 4141 (write _test-input-stream "fn foo a: (addr array byte) {\n") + 4142 (write _test-input-stream " var b/eax: (addr array byte) <- copy a\n") + 4143 (write _test-input-stream " var c/eax: int <- length b\n") + 4144 (write _test-input-stream "}\n") + 4145 # convert + 4146 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4147 (flush _test-output-buffered-file) + 4148 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4154 # check output + 4155 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-bytes/0") + 4156 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-bytes/1") + 4157 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-bytes/2") + 4158 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-bytes/3") + 4159 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-bytes/4") + 4160 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-bytes/5") + 4161 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-bytes/6") + 4162 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/7") + 4163 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/8") + 4164 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-bytes/9") + 4165 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-bytes/10") + 4166 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-bytes/11") + 4167 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-bytes/12") + 4168 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-bytes/13") + 4169 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-bytes/14") + 4170 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-bytes/15") + 4171 # . epilogue + 4172 89/<- %esp 5/r32/ebp + 4173 5d/pop-to-ebp + 4174 c3/return + 4175 + 4176 test-convert-length-of-array-on-stack: + 4177 # . prologue + 4178 55/push-ebp + 4179 89/<- %ebp 4/r32/esp + 4180 # setup + 4181 (clear-stream _test-input-stream) + 4182 (clear-stream $_test-input-buffered-file->buffer) + 4183 (clear-stream _test-output-stream) + 4184 (clear-stream $_test-output-buffered-file->buffer) + 4185 # + 4186 (write _test-input-stream "fn foo {\n") + 4187 (write _test-input-stream " var a: (array int 3)\n") + 4188 (write _test-input-stream " var b/eax: int <- length a\n") + 4189 (write _test-input-stream "}\n") + 4190 # convert + 4191 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4192 (flush _test-output-buffered-file) + 4193 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4199 # check output + 4200 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-on-stack/0") + 4201 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-on-stack/1") + 4202 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-on-stack/2") + 4203 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-on-stack/3") + 4204 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-on-stack/4") + 4205 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-on-stack/5") + 4206 # define x + 4207 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-length-of-array-on-stack/6") + 4208 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-length-of-array-on-stack/7") + 4209 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-on-stack/8") + 4210 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff0) 0x00000000/r32" "F - test-convert-length-of-array-on-stack/9") + 4211 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array-on-stack/10") + 4212 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-on-stack/11") + 4213 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-length-of-array-on-stack/12") + 4214 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-on-stack/13") + 4215 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-on-stack/14") + 4216 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-on-stack/15") + 4217 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-on-stack/16") + 4218 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-on-stack/17") + 4219 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-on-stack/18") + 4220 # . epilogue + 4221 89/<- %esp 5/r32/ebp + 4222 5d/pop-to-ebp + 4223 c3/return + 4224 + 4225 test-reg-var-def-with-read-of-same-register: + 4226 # . prologue + 4227 55/push-ebp + 4228 89/<- %ebp 4/r32/esp + 4229 # setup + 4230 (clear-stream _test-input-stream) + 4231 (clear-stream $_test-input-buffered-file->buffer) + 4232 (clear-stream _test-output-stream) + 4233 (clear-stream $_test-output-buffered-file->buffer) + 4234 (clear-stream _test-error-stream) + 4235 (clear-stream $_test-error-buffered-file->buffer) + 4236 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu + 4237 68/push 0/imm32 + 4238 68/push 0/imm32 + 4239 89/<- %edx 4/r32/esp + 4240 (tailor-exit-descriptor %edx 0x10) + 4241 # + 4242 (write _test-input-stream "fn foo {\n") + 4243 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 4244 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 4245 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 4246 (write _test-input-stream "}\n") + 4247 # convert + 4248 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 4249 # registers except esp could be clobbered at this point (though they shouldn't be) + 4250 # restore ed + 4251 89/<- %edx 4/r32/esp + 4252 (flush _test-output-buffered-file) + 4253 (flush _test-error-buffered-file) + 4254 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4260 (check-stream-equal _test-error-stream "" "F - test-reg-var-def-with-read-of-same-register: error stream should be empty") + 4261 # check output + 4262 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-reg-var-def-with-read-of-same-register/0") + 4263 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-reg-var-def-with-read-of-same-register/1") + 4264 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-reg-var-def-with-read-of-same-register/2") + 4265 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-reg-var-def-with-read-of-same-register/3") + 4266 (check-next-stream-line-equal _test-output-stream " {" "F - test-reg-var-def-with-read-of-same-register/4") + 4267 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-reg-var-def-with-read-of-same-register/5") + 4268 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-reg-var-def-with-read-of-same-register/6") + 4269 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-reg-var-def-with-read-of-same-register/7") + 4270 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-reg-var-def-with-read-of-same-register/8") + 4271 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-reg-var-def-with-read-of-same-register/9") + 4272 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-reg-var-def-with-read-of-same-register/11") + 4273 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-reg-var-def-with-read-of-same-register/13") + 4274 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-reg-var-def-with-read-of-same-register/14") + 4275 (check-next-stream-line-equal _test-output-stream " }" "F - test-reg-var-def-with-read-of-same-register/15") + 4276 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-reg-var-def-with-read-of-same-register/16") + 4277 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-reg-var-def-with-read-of-same-register/17") + 4278 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-reg-var-def-with-read-of-same-register/18") + 4279 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-reg-var-def-with-read-of-same-register/19") + 4280 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-reg-var-def-with-read-of-same-register/20") + 4281 # don't restore from ebp + 4282 81 0/subop/add %esp 8/imm32 + 4283 # . epilogue + 4284 5d/pop-to-ebp + 4285 c3/return + 4286 + 4287 test-convert-index-into-array: + 4288 # . prologue + 4289 55/push-ebp + 4290 89/<- %ebp 4/r32/esp + 4291 # setup + 4292 (clear-stream _test-input-stream) + 4293 (clear-stream $_test-input-buffered-file->buffer) + 4294 (clear-stream _test-output-stream) + 4295 (clear-stream $_test-output-buffered-file->buffer) + 4296 # + 4297 (write _test-input-stream "fn foo {\n") + 4298 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 4299 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 4300 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 4301 (write _test-input-stream "}\n") + 4302 # convert + 4303 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4304 (flush _test-output-buffered-file) + 4305 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4311 # check output + 4312 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array/0") + 4313 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array/1") + 4314 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array/2") + 4315 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array/3") + 4316 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array/4") + 4317 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array/5") + 4318 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array/6") + 4319 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array/7") + 4320 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array/8") + 4321 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array/9") + 4322 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-convert-index-into-array/10") + 4323 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array/11") + 4324 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array/12") + 4325 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array/13") + 4326 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array/14") + 4327 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array/15") + 4328 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array/16") + 4329 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array/17") + 4330 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array/18") + 4331 # . epilogue + 4332 89/<- %esp 5/r32/ebp + 4333 5d/pop-to-ebp + 4334 c3/return + 4335 + 4336 test-convert-index-into-array-of-bytes: + 4337 # . prologue + 4338 55/push-ebp + 4339 89/<- %ebp 4/r32/esp + 4340 # setup + 4341 (clear-stream _test-input-stream) + 4342 (clear-stream $_test-input-buffered-file->buffer) + 4343 (clear-stream _test-output-stream) + 4344 (clear-stream $_test-output-buffered-file->buffer) + 4345 # + 4346 (write _test-input-stream "fn foo {\n") + 4347 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 4348 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 4349 (write _test-input-stream " var x/eax: (addr byte) <- index arr, idx\n") + 4350 (write _test-input-stream "}\n") + 4351 # convert + 4352 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4353 (flush _test-output-buffered-file) + 4354 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4360 # check output + 4361 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes/0") + 4362 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes/1") + 4363 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes/2") + 4364 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes/3") + 4365 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes/4") + 4366 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes/5") + 4367 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes/6") + 4368 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes/7") + 4369 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes/8") + 4370 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes/9") + 4371 (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/11") + 4372 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes/13") + 4373 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes/14") + 4374 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes/15") + 4375 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes/16") + 4376 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes/17") + 4377 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes/18") + 4378 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes/19") + 4379 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes/20") + 4380 # . epilogue + 4381 89/<- %esp 5/r32/ebp + 4382 5d/pop-to-ebp + 4383 c3/return + 4384 + 4385 test-convert-index-into-array-with-literal: + 4386 # . prologue + 4387 55/push-ebp + 4388 89/<- %ebp 4/r32/esp + 4389 # setup + 4390 (clear-stream _test-input-stream) + 4391 (clear-stream $_test-input-buffered-file->buffer) + 4392 (clear-stream _test-output-stream) + 4393 (clear-stream $_test-output-buffered-file->buffer) + 4394 # + 4395 (write _test-input-stream "fn foo {\n") + 4396 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 4397 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") + 4398 (write _test-input-stream "}\n") + 4399 # convert + 4400 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4401 (flush _test-output-buffered-file) + 4402 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4408 # check output + 4409 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-with-literal/0") + 4410 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-with-literal/1") + 4411 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-with-literal/2") + 4412 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-with-literal/3") + 4413 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-with-literal/4") + 4414 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5") + 4415 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6") + 4416 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7") + 4417 # 2 * 4 bytes/elem + 4 bytes for size = offset 12 + 4418 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/8") + 4419 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/9") + 4420 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/10") + 4421 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-with-literal/11") + 4422 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-with-literal/12") + 4423 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-with-literal/13") + 4424 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-with-literal/14") + 4425 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-with-literal/15") + 4426 # . epilogue + 4427 89/<- %esp 5/r32/ebp + 4428 5d/pop-to-ebp + 4429 c3/return + 4430 + 4431 test-convert-index-into-array-of-bytes-with-literal: + 4432 # . prologue + 4433 55/push-ebp + 4434 89/<- %ebp 4/r32/esp + 4435 # setup + 4436 (clear-stream _test-input-stream) + 4437 (clear-stream $_test-input-buffered-file->buffer) + 4438 (clear-stream _test-output-stream) + 4439 (clear-stream $_test-output-buffered-file->buffer) + 4440 # + 4441 (write _test-input-stream "fn foo {\n") + 4442 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 4443 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") + 4444 (write _test-input-stream "}\n") + 4445 # convert + 4446 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4447 (flush _test-output-buffered-file) + 4448 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4454 # check output + 4455 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-with-literal/0") + 4456 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-with-literal/1") + 4457 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/2") + 4458 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-with-literal/3") + 4459 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-with-literal/4") + 4460 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-with-literal/5") + 4461 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-with-literal/6") + 4462 (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") + 4463 # 2 * 1 byte/elem + 4 bytes for size = offset 6 + 4464 (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/8") + 4465 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-with-literal/9") + 4466 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-with-literal/10") + 4467 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-with-literal/11") + 4468 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-with-literal/12") + 4469 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-with-literal/13") + 4470 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/14") + 4471 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-with-literal/15") + 4472 # . epilogue + 4473 89/<- %esp 5/r32/ebp + 4474 5d/pop-to-ebp + 4475 c3/return + 4476 + 4477 test-convert-index-into-array-on-stack: + 4478 # . prologue + 4479 55/push-ebp + 4480 89/<- %ebp 4/r32/esp + 4481 # setup + 4482 (clear-stream _test-input-stream) + 4483 (clear-stream $_test-input-buffered-file->buffer) + 4484 (clear-stream _test-output-stream) + 4485 (clear-stream $_test-output-buffered-file->buffer) + 4486 # + 4487 (write _test-input-stream "fn foo {\n") + 4488 (write _test-input-stream " var arr: (array int 3)\n") + 4489 (write _test-input-stream " var idx/eax: int <- copy 2\n") + 4490 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") 4491 (write _test-input-stream "}\n") - 4492 (write _test-input-stream "type t {\n") - 4493 (write _test-input-stream " x: int\n") - 4494 (write _test-input-stream " y: int\n") - 4495 (write _test-input-stream "}\n") - 4496 # convert - 4497 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4498 (flush _test-output-buffered-file) - 4499 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4505 # check output - 4506 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") - 4507 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") - 4508 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") - 4509 (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") - 4510 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") - 4511 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") - 4512 # var a: t - 4513 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/6") - 4514 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") - 4515 # foo a - 4516 (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") - 4517 # - 4518 (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") - 4519 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") - 4520 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") - 4521 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") - 4522 (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") - 4523 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") - 4524 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") - 4525 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") - 4526 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") - 4527 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") - 4528 (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") - 4529 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") - 4530 (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") - 4531 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") - 4532 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") - 4533 # . epilogue - 4534 89/<- %esp 5/r32/ebp - 4535 5d/pop-to-ebp - 4536 c3/return - 4537 - 4538 test-convert-function-call-with-arg-of-user-defined-type-register-indirect: - 4539 # . prologue - 4540 55/push-ebp - 4541 89/<- %ebp 4/r32/esp - 4542 # setup - 4543 (clear-stream _test-input-stream) - 4544 (clear-stream $_test-input-buffered-file->buffer) - 4545 (clear-stream _test-output-stream) - 4546 (clear-stream $_test-output-buffered-file->buffer) - 4547 # - 4548 (write _test-input-stream "fn f {\n") - 4549 (write _test-input-stream " var a/eax: (addr t) <- copy 0\n") - 4550 (write _test-input-stream " foo *a\n") - 4551 (write _test-input-stream "}\n") - 4552 (write _test-input-stream "fn foo x: t {\n") - 4553 (write _test-input-stream "}\n") - 4554 (write _test-input-stream "type t {\n") - 4555 (write _test-input-stream " x: int\n") - 4556 (write _test-input-stream " y: int\n") - 4557 (write _test-input-stream "}\n") - 4558 # convert - 4559 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4560 (flush _test-output-buffered-file) - 4561 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4567 # check output - 4568 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") - 4569 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") - 4570 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") - 4571 (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") - 4572 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") - 4573 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") - 4574 # var a - 4575 (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") - 4576 (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") - 4577 # foo a - 4578 (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") - 4579 # - 4580 (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") - 4581 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") - 4582 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") - 4583 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") - 4584 (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") - 4585 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") - 4586 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") - 4587 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") - 4588 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") - 4589 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") - 4590 (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") - 4591 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") - 4592 (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") - 4593 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") - 4594 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") - 4595 # . epilogue - 4596 89/<- %esp 5/r32/ebp - 4597 5d/pop-to-ebp - 4598 c3/return - 4599 - 4600 # we don't have special support for call-by-reference; just explicitly create - 4601 # a new variable with the address of the arg - 4602 test-convert-function-call-with-arg-of-user-defined-type-by-reference: - 4603 # . prologue - 4604 55/push-ebp - 4605 89/<- %ebp 4/r32/esp - 4606 # setup - 4607 (clear-stream _test-input-stream) - 4608 (clear-stream $_test-input-buffered-file->buffer) - 4609 (clear-stream _test-output-stream) - 4610 (clear-stream $_test-output-buffered-file->buffer) - 4611 # - 4612 (write _test-input-stream "fn f {\n") - 4613 (write _test-input-stream " var a: t\n") - 4614 (write _test-input-stream " var b/eax: (addr t) <- address a\n") - 4615 (write _test-input-stream " foo b\n") - 4616 (write _test-input-stream "}\n") - 4617 (write _test-input-stream "fn foo x: (addr t) {\n") - 4618 (write _test-input-stream " var x/ecx: (addr int) <- copy x\n") - 4619 (write _test-input-stream " increment *x\n") - 4620 (write _test-input-stream "}\n") - 4621 (write _test-input-stream "type t {\n") - 4622 (write _test-input-stream " x: int\n") - 4623 (write _test-input-stream " y: int\n") - 4624 (write _test-input-stream "}\n") - 4625 # convert - 4626 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4627 (flush _test-output-buffered-file) - 4628 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4634 # check output - 4635 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/0") - 4636 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/1") - 4637 (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") - 4638 (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") - 4639 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/4") - 4640 (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") - 4641 # var a: t - 4642 (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") - 4643 (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") - 4644 # var b/eax: (addr t) - 4645 (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") - 4646 (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") - 4647 # foo a - 4648 (check-next-stream-line-equal _test-output-stream " (foo %eax)" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/10") - 4649 # - 4650 (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") - 4651 (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") - 4652 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/13") - 4653 (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") - 4654 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/15") - 4655 (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") - 4656 (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") - 4657 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/18") - 4658 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/19") - 4659 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/20") - 4660 (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") - 4661 (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") - 4662 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23") - 4663 (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") - 4664 (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") - 4665 (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") - 4666 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/27") - 4667 (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/28") - 4668 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29") - 4669 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/30") - 4670 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/31") - 4671 (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/32") - 4672 (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/33") - 4673 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/34") - 4674 # . epilogue - 4675 89/<- %esp 5/r32/ebp - 4676 5d/pop-to-ebp - 4677 c3/return - 4678 - 4679 test-convert-get-on-local-variable: - 4680 # . prologue - 4681 55/push-ebp - 4682 89/<- %ebp 4/r32/esp - 4683 # setup - 4684 (clear-stream _test-input-stream) - 4685 (clear-stream $_test-input-buffered-file->buffer) - 4686 (clear-stream _test-output-stream) - 4687 (clear-stream $_test-output-buffered-file->buffer) - 4688 # - 4689 (write _test-input-stream "fn foo {\n") - 4690 (write _test-input-stream " var a: t\n") - 4691 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 4692 (write _test-input-stream "}\n") - 4693 (write _test-input-stream "type t {\n") - 4694 (write _test-input-stream " x: int\n") - 4695 (write _test-input-stream " y: int\n") - 4696 (write _test-input-stream "}\n") - 4697 # convert - 4698 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4699 (flush _test-output-buffered-file) - 4700 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4706 # check output - 4707 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-local-variable/0") - 4708 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-local-variable/1") - 4709 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-local-variable/2") - 4710 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-local-variable/3") - 4711 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-local-variable/4") - 4712 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-local-variable/5") - 4713 # var a - 4714 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/6") - 4715 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/7") - 4716 # var c - 4717 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-local-variable/8") - 4718 # get - 4719 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000001/r32" "F - test-convert-get-on-local-variable/9") - 4720 # reclaim c - 4721 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-local-variable/10") - 4722 # reclaim a - 4723 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-get-on-local-variable/11") - 4724 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-local-variable/12") - 4725 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-local-variable/13") - 4726 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-local-variable/14") - 4727 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-local-variable/15") - 4728 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-local-variable/16") - 4729 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-local-variable/17") - 4730 # . epilogue - 4731 89/<- %esp 5/r32/ebp - 4732 5d/pop-to-ebp - 4733 c3/return - 4734 - 4735 test-convert-get-on-function-argument: - 4736 # . prologue - 4737 55/push-ebp - 4738 89/<- %ebp 4/r32/esp - 4739 # setup - 4740 (clear-stream _test-input-stream) - 4741 (clear-stream $_test-input-buffered-file->buffer) - 4742 (clear-stream _test-output-stream) - 4743 (clear-stream $_test-output-buffered-file->buffer) - 4744 # - 4745 (write _test-input-stream "fn foo a: t {\n") - 4746 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 4747 (write _test-input-stream "}\n") - 4748 (write _test-input-stream "type t {\n") - 4749 (write _test-input-stream " x: int\n") - 4750 (write _test-input-stream " y: int\n") - 4751 (write _test-input-stream "}\n") - 4752 # convert - 4753 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4754 (flush _test-output-buffered-file) - 4755 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4761 # check output - 4762 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument/0") - 4763 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument/1") - 4764 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument/2") - 4765 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument/3") - 4766 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument/4") - 4767 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument/5") - 4768 # var c - 4769 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument/6") - 4770 # get - 4771 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument/7") - 4772 # reclaim c - 4773 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument/8") - 4774 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument/9") - 4775 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument/10") - 4776 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument/11") - 4777 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument/12") - 4778 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument/13") - 4779 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument/14") - 4780 # . epilogue - 4781 89/<- %esp 5/r32/ebp - 4782 5d/pop-to-ebp - 4783 c3/return - 4784 - 4785 test-convert-get-on-function-argument-with-known-type: - 4786 # . prologue - 4787 55/push-ebp - 4788 89/<- %ebp 4/r32/esp - 4789 # setup - 4790 (clear-stream _test-input-stream) - 4791 (clear-stream $_test-input-buffered-file->buffer) - 4792 (clear-stream _test-output-stream) - 4793 (clear-stream $_test-output-buffered-file->buffer) - 4794 # - 4795 (write _test-input-stream "type t {\n") - 4796 (write _test-input-stream " x: int\n") - 4797 (write _test-input-stream " y: int\n") - 4798 (write _test-input-stream "}\n") - 4799 (write _test-input-stream "fn foo a: t {\n") - 4800 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 4801 (write _test-input-stream "}\n") - 4802 # convert - 4803 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4804 (flush _test-output-buffered-file) - 4805 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4811 # check output - 4812 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument-with-known-type/0") - 4813 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument-with-known-type/1") - 4814 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument-with-known-type/2") - 4815 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument-with-known-type/3") - 4816 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument-with-known-type/4") - 4817 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument-with-known-type/5") - 4818 # var c - 4819 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument-with-known-type/6") - 4820 # get - 4821 (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") - 4822 # reclaim c - 4823 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument-with-known-type/8") - 4824 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument-with-known-type/9") - 4825 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument-with-known-type/10") - 4826 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument-with-known-type/11") - 4827 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument-with-known-type/12") - 4828 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument-with-known-type/13") - 4829 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument-with-known-type/14") - 4830 # . epilogue - 4831 89/<- %esp 5/r32/ebp - 4832 5d/pop-to-ebp - 4833 c3/return - 4834 - 4835 test-add-with-too-many-inouts: - 4836 # . prologue - 4837 55/push-ebp - 4838 89/<- %ebp 4/r32/esp - 4839 # setup - 4840 (clear-stream _test-input-stream) - 4841 (clear-stream $_test-input-buffered-file->buffer) - 4842 (clear-stream _test-output-stream) - 4843 (clear-stream $_test-output-buffered-file->buffer) - 4844 (clear-stream _test-error-stream) - 4845 (clear-stream $_test-error-buffered-file->buffer) - 4846 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 4847 68/push 0/imm32 - 4848 68/push 0/imm32 - 4849 89/<- %edx 4/r32/esp - 4850 (tailor-exit-descriptor %edx 0x10) - 4851 # - 4852 (write _test-input-stream "fn foo {\n") - 4853 (write _test-input-stream " var a: int\n") - 4854 (write _test-input-stream " var b/ecx: int <- add a, 0\n") - 4855 (write _test-input-stream "}\n") - 4856 # convert - 4857 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 4858 # registers except esp clobbered at this point - 4859 # restore ed - 4860 89/<- %edx 4/r32/esp - 4861 (flush _test-output-buffered-file) - 4862 (flush _test-error-buffered-file) - 4863 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 4869 # check output - 4870 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts: output should be empty") - 4871 (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") - 4872 # check that stop(1) was called - 4873 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts: exit status") - 4874 # don't restore from ebp - 4875 81 0/subop/add %esp 8/imm32 - 4876 # . epilogue - 4877 5d/pop-to-ebp - 4878 c3/return - 4879 - 4880 test-add-with-too-many-inouts-2: - 4881 # . prologue - 4882 55/push-ebp - 4883 89/<- %ebp 4/r32/esp - 4884 # setup - 4885 (clear-stream _test-input-stream) - 4886 (clear-stream $_test-input-buffered-file->buffer) - 4887 (clear-stream _test-output-stream) - 4888 (clear-stream $_test-output-buffered-file->buffer) - 4889 (clear-stream _test-error-stream) - 4890 (clear-stream $_test-error-buffered-file->buffer) - 4891 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 4892 68/push 0/imm32 - 4893 68/push 0/imm32 - 4894 89/<- %edx 4/r32/esp - 4895 (tailor-exit-descriptor %edx 0x10) - 4896 # - 4897 (write _test-input-stream "fn foo {\n") - 4898 (write _test-input-stream " var a: int\n") - 4899 (write _test-input-stream " add-to a, 0, 1\n") - 4900 (write _test-input-stream "}\n") - 4901 # convert - 4902 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 4903 # registers except esp clobbered at this point - 4904 # restore ed - 4905 89/<- %edx 4/r32/esp - 4906 (flush _test-output-buffered-file) - 4907 (flush _test-error-buffered-file) - 4908 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 4914 # check output - 4915 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts-2: output should be empty") - 4916 (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") - 4917 # check that stop(1) was called - 4918 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts-2: exit status") - 4919 # don't restore from ebp - 4920 81 0/subop/add %esp 8/imm32 - 4921 # . epilogue - 4922 5d/pop-to-ebp - 4923 c3/return - 4924 - 4925 test-add-with-too-many-outputs: - 4926 # . prologue - 4927 55/push-ebp - 4928 89/<- %ebp 4/r32/esp - 4929 # setup - 4930 (clear-stream _test-input-stream) - 4931 (clear-stream $_test-input-buffered-file->buffer) - 4932 (clear-stream _test-output-stream) - 4933 (clear-stream $_test-output-buffered-file->buffer) - 4934 (clear-stream _test-error-stream) - 4935 (clear-stream $_test-error-buffered-file->buffer) - 4936 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 4937 68/push 0/imm32 - 4938 68/push 0/imm32 - 4939 89/<- %edx 4/r32/esp - 4940 (tailor-exit-descriptor %edx 0x10) - 4941 # - 4942 (write _test-input-stream "fn foo {\n") - 4943 (write _test-input-stream " var a/eax: int <- copy 0\n") - 4944 (write _test-input-stream " var b/ebx: int <- copy 0\n") - 4945 (write _test-input-stream " var c/ecx: int <- copy 0\n") - 4946 (write _test-input-stream " c, b <- add a\n") - 4947 (write _test-input-stream "}\n") - 4948 # convert - 4949 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 4950 # registers except esp clobbered at this point - 4951 # restore ed - 4952 89/<- %edx 4/r32/esp - 4953 (flush _test-output-buffered-file) - 4954 (flush _test-error-buffered-file) - 4955 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 4961 # check output - 4962 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-outputs: output should be empty") - 4963 (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") - 4964 # check that stop(1) was called - 4965 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-outputs: exit status") - 4966 # don't restore from ebp - 4967 81 0/subop/add %esp 8/imm32 - 4968 # . epilogue - 4969 5d/pop-to-ebp - 4970 c3/return - 4971 - 4972 test-add-with-non-number: - 4973 # . prologue - 4974 55/push-ebp - 4975 89/<- %ebp 4/r32/esp - 4976 # setup - 4977 (clear-stream _test-input-stream) - 4978 (clear-stream $_test-input-buffered-file->buffer) - 4979 (clear-stream _test-output-stream) - 4980 (clear-stream $_test-output-buffered-file->buffer) - 4981 (clear-stream _test-error-stream) - 4982 (clear-stream $_test-error-buffered-file->buffer) - 4983 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 4984 68/push 0/imm32 - 4985 68/push 0/imm32 - 4986 89/<- %edx 4/r32/esp - 4987 (tailor-exit-descriptor %edx 0x10) - 4988 # - 4989 (write _test-input-stream "fn foo {\n") - 4990 (write _test-input-stream " var a: int\n") - 4991 (write _test-input-stream " var b/ecx: (addr int) <- add a\n") - 4992 (write _test-input-stream "}\n") - 4993 # convert - 4994 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 4995 # registers except esp clobbered at this point - 4996 # restore ed - 4997 89/<- %edx 4/r32/esp - 4998 (flush _test-output-buffered-file) - 4999 (flush _test-error-buffered-file) - 5000 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5006 # check output - 5007 (check-stream-equal _test-output-stream "" "F - test-add-with-non-number: output should be empty") - 5008 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: only non-addr scalar args permitted" "F - test-add-with-non-number: error message") - 5009 # check that stop(1) was called - 5010 (check-ints-equal *(edx+4) 2 "F - test-add-with-non-number: exit status") - 5011 # don't restore from ebp - 5012 81 0/subop/add %esp 8/imm32 - 5013 # . epilogue - 5014 5d/pop-to-ebp - 5015 c3/return - 5016 - 5017 test-add-with-addr-dereferenced: - 5018 # . prologue - 5019 55/push-ebp - 5020 89/<- %ebp 4/r32/esp - 5021 # setup - 5022 (clear-stream _test-input-stream) - 5023 (clear-stream $_test-input-buffered-file->buffer) - 5024 (clear-stream _test-output-stream) - 5025 (clear-stream $_test-output-buffered-file->buffer) - 5026 # - 5027 (write _test-input-stream "fn foo {\n") - 5028 (write _test-input-stream " var a/eax: (addr int) <- copy 0\n") - 5029 (write _test-input-stream " add-to *a, 1\n") - 5030 (write _test-input-stream "}\n") - 5031 # convert - 5032 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5033 (flush _test-output-buffered-file) - 5034 # no error - 5035 # . epilogue - 5036 89/<- %esp 5/r32/ebp - 5037 5d/pop-to-ebp - 5038 c3/return - 5039 - 5040 test-get-with-wrong-field: - 5041 # . prologue - 5042 55/push-ebp - 5043 89/<- %ebp 4/r32/esp - 5044 # setup - 5045 (clear-stream _test-input-stream) - 5046 (clear-stream $_test-input-buffered-file->buffer) - 5047 (clear-stream _test-output-stream) - 5048 (clear-stream $_test-output-buffered-file->buffer) - 5049 (clear-stream _test-error-stream) - 5050 (clear-stream $_test-error-buffered-file->buffer) - 5051 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5052 68/push 0/imm32 - 5053 68/push 0/imm32 - 5054 89/<- %edx 4/r32/esp - 5055 (tailor-exit-descriptor %edx 0x10) - 5056 # - 5057 (write _test-input-stream "fn foo {\n") - 5058 (write _test-input-stream " var a: t\n") - 5059 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 5060 (write _test-input-stream "}\n") - 5061 (write _test-input-stream "type t {\n") - 5062 (write _test-input-stream " x: int\n") - 5063 (write _test-input-stream "}\n") - 5064 # convert - 5065 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5066 # registers except esp clobbered at this point - 5067 # restore ed - 5068 89/<- %edx 4/r32/esp - 5069 (flush _test-output-buffered-file) - 5070 (flush _test-error-buffered-file) - 5071 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5077 # check output - 5078 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-field: output should be empty") - 5079 (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") - 5080 # check that stop(1) was called - 5081 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-field: exit status") - 5082 # don't restore from ebp - 5083 81 0/subop/add %esp 8/imm32 - 5084 # . epilogue - 5085 5d/pop-to-ebp - 5086 c3/return - 5087 - 5088 test-get-with-wrong-base-type: - 5089 # . prologue - 5090 55/push-ebp - 5091 89/<- %ebp 4/r32/esp - 5092 # setup - 5093 (clear-stream _test-input-stream) - 5094 (clear-stream $_test-input-buffered-file->buffer) - 5095 (clear-stream _test-output-stream) - 5096 (clear-stream $_test-output-buffered-file->buffer) - 5097 (clear-stream _test-error-stream) - 5098 (clear-stream $_test-error-buffered-file->buffer) - 5099 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5100 68/push 0/imm32 - 5101 68/push 0/imm32 - 5102 89/<- %edx 4/r32/esp - 5103 (tailor-exit-descriptor %edx 0x10) - 5104 # - 5105 (write _test-input-stream "fn foo {\n") - 5106 (write _test-input-stream " var a: int\n") - 5107 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 5108 (write _test-input-stream "}\n") - 5109 # convert - 5110 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5111 # registers except esp clobbered at this point - 5112 # restore ed - 5113 89/<- %edx 4/r32/esp - 5114 (flush _test-output-buffered-file) - 5115 (flush _test-error-buffered-file) - 5116 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5122 # check output - 5123 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type: output should be empty") - 5124 (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") - 5125 # check that stop(1) was called - 5126 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type: exit status") - 5127 # don't restore from ebp - 5128 81 0/subop/add %esp 8/imm32 - 5129 # . epilogue - 5130 5d/pop-to-ebp - 5131 c3/return - 5132 - 5133 test-get-with-wrong-base-type-2: - 5134 # . prologue - 5135 55/push-ebp - 5136 89/<- %ebp 4/r32/esp - 5137 # setup - 5138 (clear-stream _test-input-stream) - 5139 (clear-stream $_test-input-buffered-file->buffer) - 5140 (clear-stream _test-output-stream) - 5141 (clear-stream $_test-output-buffered-file->buffer) - 5142 (clear-stream _test-error-stream) - 5143 (clear-stream $_test-error-buffered-file->buffer) - 5144 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5145 68/push 0/imm32 - 5146 68/push 0/imm32 - 5147 89/<- %edx 4/r32/esp - 5148 (tailor-exit-descriptor %edx 0x10) - 5149 # - 5150 (write _test-input-stream "fn foo {\n") - 5151 (write _test-input-stream " var a: (addr t)\n") - 5152 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 5153 (write _test-input-stream "}\n") - 5154 (write _test-input-stream "type t {\n") - 5155 (write _test-input-stream " x: int\n") - 5156 (write _test-input-stream "}\n") - 5157 # convert - 5158 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5159 # registers except esp clobbered at this point - 5160 # restore ed - 5161 89/<- %edx 4/r32/esp - 5162 (flush _test-output-buffered-file) - 5163 (flush _test-error-buffered-file) - 5164 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5170 # check output - 5171 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type-2: output should be empty") - 5172 (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") - 5173 # check that stop(1) was called - 5174 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type-2: exit status") - 5175 # don't restore from ebp - 5176 81 0/subop/add %esp 8/imm32 - 5177 # . epilogue - 5178 5d/pop-to-ebp - 5179 c3/return - 5180 - 5181 test-get-with-wrong-offset-type: - 5182 # . prologue - 5183 55/push-ebp - 5184 89/<- %ebp 4/r32/esp - 5185 # setup - 5186 (clear-stream _test-input-stream) - 5187 (clear-stream $_test-input-buffered-file->buffer) - 5188 (clear-stream _test-output-stream) - 5189 (clear-stream $_test-output-buffered-file->buffer) - 5190 (clear-stream _test-error-stream) - 5191 (clear-stream $_test-error-buffered-file->buffer) - 5192 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5193 68/push 0/imm32 - 5194 68/push 0/imm32 - 5195 89/<- %edx 4/r32/esp - 5196 (tailor-exit-descriptor %edx 0x10) - 5197 # - 5198 (write _test-input-stream "fn foo {\n") - 5199 (write _test-input-stream " var a: t\n") - 5200 (write _test-input-stream " var b: int\n") - 5201 (write _test-input-stream " var c/ecx: (addr int) <- get a, b\n") - 5202 (write _test-input-stream "}\n") - 5203 (write _test-input-stream "type t {\n") - 5204 (write _test-input-stream " x: int\n") - 5205 (write _test-input-stream "}\n") - 5206 # convert - 5207 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5208 # registers except esp clobbered at this point - 5209 # restore ed - 5210 89/<- %edx 4/r32/esp - 5211 (flush _test-output-buffered-file) - 5212 (flush _test-error-buffered-file) - 5213 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5219 # check output - 5220 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-offset-type: output should be empty") - 5221 (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") - 5222 # check that stop(1) was called - 5223 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-offset-type: exit status") - 5224 # don't restore from ebp - 5225 81 0/subop/add %esp 8/imm32 - 5226 # . epilogue - 5227 5d/pop-to-ebp - 5228 c3/return - 5229 - 5230 test-get-with-wrong-output-type: - 5231 # . prologue - 5232 55/push-ebp - 5233 89/<- %ebp 4/r32/esp - 5234 # setup - 5235 (clear-stream _test-input-stream) - 5236 (clear-stream $_test-input-buffered-file->buffer) - 5237 (clear-stream _test-output-stream) - 5238 (clear-stream $_test-output-buffered-file->buffer) - 5239 (clear-stream _test-error-stream) - 5240 (clear-stream $_test-error-buffered-file->buffer) - 5241 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5242 68/push 0/imm32 - 5243 68/push 0/imm32 - 5244 89/<- %edx 4/r32/esp - 5245 (tailor-exit-descriptor %edx 0x10) - 5246 # - 5247 (write _test-input-stream "fn foo {\n") - 5248 (write _test-input-stream " var a: t\n") - 5249 (write _test-input-stream " var c: (addr int)\n") - 5250 (write _test-input-stream " c <- get a, x\n") - 5251 (write _test-input-stream "}\n") - 5252 (write _test-input-stream "type t {\n") - 5253 (write _test-input-stream " x: int\n") - 5254 (write _test-input-stream "}\n") - 5255 # convert - 5256 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5257 # registers except esp clobbered at this point - 5258 # restore ed - 5259 89/<- %edx 4/r32/esp - 5260 (flush _test-output-buffered-file) - 5261 (flush _test-error-buffered-file) - 5262 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5268 # check output - 5269 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type: output should be empty") - 5270 (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") - 5271 # check that stop(1) was called - 5272 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type: exit status") - 5273 # don't restore from ebp - 5274 81 0/subop/add %esp 8/imm32 - 5275 # . epilogue - 5276 5d/pop-to-ebp - 5277 c3/return - 5278 - 5279 test-get-with-wrong-output-type-2: - 5280 # . prologue - 5281 55/push-ebp - 5282 89/<- %ebp 4/r32/esp - 5283 # setup - 5284 (clear-stream _test-input-stream) - 5285 (clear-stream $_test-input-buffered-file->buffer) - 5286 (clear-stream _test-output-stream) - 5287 (clear-stream $_test-output-buffered-file->buffer) - 5288 (clear-stream _test-error-stream) - 5289 (clear-stream $_test-error-buffered-file->buffer) - 5290 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5291 68/push 0/imm32 - 5292 68/push 0/imm32 - 5293 89/<- %edx 4/r32/esp - 5294 (tailor-exit-descriptor %edx 0x10) - 5295 # - 5296 (write _test-input-stream "fn foo {\n") - 5297 (write _test-input-stream " var a: t\n") - 5298 (write _test-input-stream " var c/ecx: int <- get a, x\n") - 5299 (write _test-input-stream "}\n") - 5300 (write _test-input-stream "type t {\n") - 5301 (write _test-input-stream " x: int\n") - 5302 (write _test-input-stream "}\n") - 5303 # convert - 5304 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5305 # registers except esp clobbered at this point - 5306 # restore ed - 5307 89/<- %edx 4/r32/esp - 5308 (flush _test-output-buffered-file) - 5309 (flush _test-error-buffered-file) - 5310 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5316 # check output - 5317 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-2: output should be empty") - 5318 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an address" "F - test-get-with-wrong-output-type-2: error message") - 5319 # check that stop(1) was called - 5320 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-2: exit status") - 5321 # don't restore from ebp - 5322 81 0/subop/add %esp 8/imm32 - 5323 # . epilogue - 5324 5d/pop-to-ebp - 5325 c3/return - 5326 - 5327 test-get-with-wrong-output-type-3: - 5328 # . prologue - 5329 55/push-ebp - 5330 89/<- %ebp 4/r32/esp - 5331 # setup - 5332 (clear-stream _test-input-stream) - 5333 (clear-stream $_test-input-buffered-file->buffer) - 5334 (clear-stream _test-output-stream) - 5335 (clear-stream $_test-output-buffered-file->buffer) - 5336 (clear-stream _test-error-stream) - 5337 (clear-stream $_test-error-buffered-file->buffer) - 5338 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5339 68/push 0/imm32 - 5340 68/push 0/imm32 - 5341 89/<- %edx 4/r32/esp - 5342 (tailor-exit-descriptor %edx 0x10) - 5343 # - 5344 (write _test-input-stream "fn foo {\n") - 5345 (write _test-input-stream " var a: t\n") - 5346 (write _test-input-stream " var c/ecx: (array int) <- get a, x\n") - 5347 (write _test-input-stream "}\n") - 5348 (write _test-input-stream "type t {\n") - 5349 (write _test-input-stream " x: int\n") - 5350 (write _test-input-stream "}\n") - 5351 # convert - 5352 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5353 # registers except esp clobbered at this point - 5354 # restore ed - 5355 89/<- %edx 4/r32/esp - 5356 (flush _test-output-buffered-file) - 5357 (flush _test-error-buffered-file) - 5358 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5364 # check output - 5365 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-3: output should be empty") - 5366 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an address" "F - test-get-with-wrong-output-type-3: error message") - 5367 # check that stop(1) was called - 5368 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-3: exit status") - 5369 # don't restore from ebp - 5370 81 0/subop/add %esp 8/imm32 - 5371 # . epilogue - 5372 5d/pop-to-ebp - 5373 c3/return - 5374 - 5375 test-get-with-wrong-output-type-4: - 5376 # . prologue - 5377 55/push-ebp - 5378 89/<- %ebp 4/r32/esp - 5379 # setup - 5380 (clear-stream _test-input-stream) - 5381 (clear-stream $_test-input-buffered-file->buffer) - 5382 (clear-stream _test-output-stream) - 5383 (clear-stream $_test-output-buffered-file->buffer) - 5384 (clear-stream _test-error-stream) - 5385 (clear-stream $_test-error-buffered-file->buffer) - 5386 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5387 68/push 0/imm32 - 5388 68/push 0/imm32 - 5389 89/<- %edx 4/r32/esp - 5390 (tailor-exit-descriptor %edx 0x10) - 5391 # - 5392 (write _test-input-stream "fn foo {\n") - 5393 (write _test-input-stream " var a: t\n") - 5394 (write _test-input-stream " var c/ecx: (addr boolean) <- get a, x\n") - 5395 (write _test-input-stream "}\n") - 5396 (write _test-input-stream "type t {\n") - 5397 (write _test-input-stream " x: int\n") - 5398 (write _test-input-stream "}\n") - 5399 # convert - 5400 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5401 # registers except esp clobbered at this point - 5402 # restore ed - 5403 89/<- %edx 4/r32/esp - 5404 (flush _test-output-buffered-file) - 5405 (flush _test-error-buffered-file) - 5406 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5412 # check output - 5413 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-4: output should be empty") - 5414 (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") - 5415 # check that stop(1) was called - 5416 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-4: exit status") - 5417 # don't restore from ebp - 5418 81 0/subop/add %esp 8/imm32 - 5419 # . epilogue - 5420 5d/pop-to-ebp - 5421 c3/return - 5422 - 5423 test-get-with-wrong-output-type-5: - 5424 # . prologue - 5425 55/push-ebp - 5426 89/<- %ebp 4/r32/esp - 5427 # setup - 5428 (clear-stream _test-input-stream) - 5429 (clear-stream $_test-input-buffered-file->buffer) - 5430 (clear-stream _test-output-stream) - 5431 (clear-stream $_test-output-buffered-file->buffer) - 5432 # - 5433 (write _test-input-stream "fn foo {\n") - 5434 (write _test-input-stream " var a: t\n") - 5435 (write _test-input-stream " var c/ecx: (addr handle int) <- get a, x\n") - 5436 (write _test-input-stream "}\n") - 5437 (write _test-input-stream "type t {\n") - 5438 (write _test-input-stream " x: (handle int)\n") - 5439 (write _test-input-stream "}\n") - 5440 # convert - 5441 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5442 (flush _test-output-buffered-file) - 5443 # no errors - 5444 # . epilogue - 5445 89/<- %esp 5/r32/ebp - 5446 5d/pop-to-ebp - 5447 c3/return - 5448 - 5449 test-get-with-too-few-inouts: - 5450 # . prologue - 5451 55/push-ebp - 5452 89/<- %ebp 4/r32/esp - 5453 # setup - 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) - 5458 (clear-stream _test-error-stream) - 5459 (clear-stream $_test-error-buffered-file->buffer) - 5460 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5461 68/push 0/imm32 - 5462 68/push 0/imm32 - 5463 89/<- %edx 4/r32/esp - 5464 (tailor-exit-descriptor %edx 0x10) - 5465 # - 5466 (write _test-input-stream "fn foo {\n") - 5467 (write _test-input-stream " var a: t\n") - 5468 (write _test-input-stream " var c/ecx: (addr int) <- get a\n") - 5469 (write _test-input-stream "}\n") - 5470 (write _test-input-stream "type t {\n") - 5471 (write _test-input-stream " x: int\n") - 5472 (write _test-input-stream "}\n") - 5473 # convert - 5474 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5475 # registers except esp clobbered at this point - 5476 # restore ed - 5477 89/<- %edx 4/r32/esp - 5478 (flush _test-output-buffered-file) - 5479 (flush _test-error-buffered-file) - 5480 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5486 # check output - 5487 (check-stream-equal _test-output-stream "" "F - test-get-with-too-few-inouts: output should be empty") - 5488 (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") - 5489 # check that stop(1) was called - 5490 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-few-inouts: exit status") - 5491 # don't restore from ebp - 5492 81 0/subop/add %esp 8/imm32 - 5493 # . epilogue - 5494 5d/pop-to-ebp - 5495 c3/return - 5496 - 5497 test-get-with-too-many-inouts: - 5498 # . prologue - 5499 55/push-ebp - 5500 89/<- %ebp 4/r32/esp - 5501 # setup - 5502 (clear-stream _test-input-stream) - 5503 (clear-stream $_test-input-buffered-file->buffer) - 5504 (clear-stream _test-output-stream) - 5505 (clear-stream $_test-output-buffered-file->buffer) - 5506 (clear-stream _test-error-stream) - 5507 (clear-stream $_test-error-buffered-file->buffer) - 5508 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5509 68/push 0/imm32 - 5510 68/push 0/imm32 - 5511 89/<- %edx 4/r32/esp - 5512 (tailor-exit-descriptor %edx 0x10) - 5513 # - 5514 (write _test-input-stream "fn foo {\n") - 5515 (write _test-input-stream " var a: t\n") - 5516 (write _test-input-stream " var c/ecx: (addr int) <- get a, x, 0\n") - 5517 (write _test-input-stream "}\n") - 5518 (write _test-input-stream "type t {\n") - 5519 (write _test-input-stream " x: int\n") - 5520 (write _test-input-stream "}\n") - 5521 # convert - 5522 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5523 # registers except esp clobbered at this point - 5524 # restore ed - 5525 89/<- %edx 4/r32/esp - 5526 (flush _test-output-buffered-file) - 5527 (flush _test-error-buffered-file) - 5528 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5534 # check output - 5535 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-inouts: output should be empty") - 5536 (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") - 5537 # check that stop(1) was called - 5538 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-inouts: exit status") - 5539 # don't restore from ebp - 5540 81 0/subop/add %esp 8/imm32 - 5541 # . epilogue - 5542 5d/pop-to-ebp - 5543 c3/return - 5544 - 5545 test-get-with-no-output: - 5546 # . prologue - 5547 55/push-ebp - 5548 89/<- %ebp 4/r32/esp - 5549 # setup - 5550 (clear-stream _test-input-stream) - 5551 (clear-stream $_test-input-buffered-file->buffer) - 5552 (clear-stream _test-output-stream) - 5553 (clear-stream $_test-output-buffered-file->buffer) - 5554 (clear-stream _test-error-stream) - 5555 (clear-stream $_test-error-buffered-file->buffer) - 5556 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5557 68/push 0/imm32 - 5558 68/push 0/imm32 - 5559 89/<- %edx 4/r32/esp - 5560 (tailor-exit-descriptor %edx 0x10) - 5561 # - 5562 (write _test-input-stream "fn foo {\n") - 5563 (write _test-input-stream " var a: t\n") - 5564 (write _test-input-stream " get a, x\n") - 5565 (write _test-input-stream "}\n") - 5566 (write _test-input-stream "type t {\n") - 5567 (write _test-input-stream " x: int\n") - 5568 (write _test-input-stream "}\n") - 5569 # convert - 5570 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5571 # registers except esp clobbered at this point - 5572 # restore ed - 5573 89/<- %edx 4/r32/esp - 5574 (flush _test-output-buffered-file) - 5575 (flush _test-error-buffered-file) - 5576 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5582 # check output - 5583 (check-stream-equal _test-output-stream "" "F - test-get-with-no-output: output should be empty") - 5584 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: must have an output" "F - test-get-with-no-output: error message") - 5585 # check that stop(1) was called - 5586 (check-ints-equal *(edx+4) 2 "F - test-get-with-no-output: exit status") - 5587 # don't restore from ebp - 5588 81 0/subop/add %esp 8/imm32 - 5589 # . epilogue - 5590 5d/pop-to-ebp - 5591 c3/return - 5592 - 5593 test-get-with-too-many-outputs: - 5594 # . prologue - 5595 55/push-ebp - 5596 89/<- %ebp 4/r32/esp - 5597 # setup - 5598 (clear-stream _test-input-stream) - 5599 (clear-stream $_test-input-buffered-file->buffer) - 5600 (clear-stream _test-output-stream) - 5601 (clear-stream $_test-output-buffered-file->buffer) - 5602 (clear-stream _test-error-stream) - 5603 (clear-stream $_test-error-buffered-file->buffer) - 5604 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 5605 68/push 0/imm32 - 5606 68/push 0/imm32 - 5607 89/<- %edx 4/r32/esp - 5608 (tailor-exit-descriptor %edx 0x10) - 5609 # - 5610 (write _test-input-stream "fn foo {\n") - 5611 (write _test-input-stream " var a: t\n") - 5612 (write _test-input-stream " var b: int\n") - 5613 (write _test-input-stream " var c/eax: (addr int) <- copy 0\n") - 5614 (write _test-input-stream " c, b <- get a, x\n") - 5615 (write _test-input-stream "}\n") - 5616 (write _test-input-stream "type t {\n") - 5617 (write _test-input-stream " x: int\n") - 5618 (write _test-input-stream "}\n") - 5619 # convert - 5620 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 5621 # registers except esp clobbered at this point - 5622 # restore ed - 5623 89/<- %edx 4/r32/esp - 5624 (flush _test-output-buffered-file) - 5625 (flush _test-error-buffered-file) - 5626 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 5632 # check output - 5633 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-outputs: output should be empty") - 5634 (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") - 5635 # check that stop(1) was called - 5636 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-outputs: exit status") - 5637 # don't restore from ebp - 5638 81 0/subop/add %esp 8/imm32 - 5639 # . epilogue - 5640 5d/pop-to-ebp - 5641 c3/return - 5642 - 5643 test-convert-array-of-user-defined-types: - 5644 # . prologue - 5645 55/push-ebp - 5646 89/<- %ebp 4/r32/esp - 5647 # setup - 5648 (clear-stream _test-input-stream) - 5649 (clear-stream $_test-input-buffered-file->buffer) - 5650 (clear-stream _test-output-stream) - 5651 (clear-stream $_test-output-buffered-file->buffer) - 5652 # - 5653 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 - 5654 (write _test-input-stream " x: int\n") - 5655 (write _test-input-stream " y: int\n") - 5656 (write _test-input-stream "}\n") - 5657 (write _test-input-stream "fn foo {\n") - 5658 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 5659 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 5660 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 5661 (write _test-input-stream "}\n") - 5662 # convert - 5663 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5664 (flush _test-output-buffered-file) - 5665 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5671 # check output - 5672 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-array-of-user-defined-types/0") - 5673 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-array-of-user-defined-types/1") - 5674 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-array-of-user-defined-types/2") - 5675 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-array-of-user-defined-types/3") - 5676 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-array-of-user-defined-types/4") - 5677 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-array-of-user-defined-types/5") - 5678 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-array-of-user-defined-types/6") - 5679 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-array-of-user-defined-types/7") - 5680 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-array-of-user-defined-types/8") - 5681 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-array-of-user-defined-types/9") - 5682 (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/11") - 5683 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-array-of-user-defined-types/13") - 5684 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-array-of-user-defined-types/14") - 5685 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-array-of-user-defined-types/15") - 5686 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-array-of-user-defined-types/16") - 5687 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-array-of-user-defined-types/17") - 5688 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-array-of-user-defined-types/18") - 5689 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-array-of-user-defined-types/19") - 5690 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-array-of-user-defined-types/20") - 5691 # . epilogue - 5692 89/<- %esp 5/r32/ebp - 5693 5d/pop-to-ebp - 5694 c3/return - 5695 - 5696 test-convert-length-of-array-of-user-defined-types-to-eax: - 5697 # . prologue - 5698 55/push-ebp - 5699 89/<- %ebp 4/r32/esp - 5700 # setup - 5701 (clear-stream _test-input-stream) - 5702 (clear-stream $_test-input-buffered-file->buffer) - 5703 (clear-stream _test-output-stream) - 5704 (clear-stream $_test-output-buffered-file->buffer) + 4492 # convert + 4493 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4494 (flush _test-output-buffered-file) + 4495 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4501 # check output + 4502 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack/0") + 4503 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack/1") + 4504 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack/2") + 4505 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack/3") + 4506 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack/4") + 4507 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack/5") + 4508 # var arr + 4509 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack/6") + 4510 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack/7") + 4511 # var idx + 4512 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack/8") + 4513 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 2/imm32" "F - test-convert-index-into-array-on-stack/9") + 4514 # var x is at (ebp-0x10) + idx<<2 + 4 = ebp + idx<<2 - 0xc + 4515 (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/10") + 4516 # reclaim idx + 4517 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack/11") + 4518 # reclaim arr + 4519 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack/12") + 4520 # + 4521 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack/13") + 4522 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack/14") + 4523 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack/15") + 4524 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack/16") + 4525 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack/17") + 4526 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack/18") + 4527 # . epilogue + 4528 89/<- %esp 5/r32/ebp + 4529 5d/pop-to-ebp + 4530 c3/return + 4531 + 4532 test-convert-index-into-array-on-stack-with-literal: + 4533 # . prologue + 4534 55/push-ebp + 4535 89/<- %ebp 4/r32/esp + 4536 # setup + 4537 (clear-stream _test-input-stream) + 4538 (clear-stream $_test-input-buffered-file->buffer) + 4539 (clear-stream _test-output-stream) + 4540 (clear-stream $_test-output-buffered-file->buffer) + 4541 # + 4542 (write _test-input-stream "fn foo {\n") + 4543 (write _test-input-stream " var arr: (array int 3)\n") + 4544 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") + 4545 (write _test-input-stream "}\n") + 4546 # convert + 4547 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4548 (flush _test-output-buffered-file) + 4549 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4555 # check output + 4556 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack-with-literal/0") + 4557 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack-with-literal/1") + 4558 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack-with-literal/2") + 4559 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack-with-literal/3") + 4560 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack-with-literal/4") + 4561 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack-with-literal/5") + 4562 # var arr + 4563 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack-with-literal/6") + 4564 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack-with-literal/7") + 4565 # var x + 4566 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack-with-literal/8") + 4567 # x is at (ebp-0x10) + 4 + 2*4 = ebp-4 + 4568 (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/9") + 4569 # reclaim x + 4570 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack-with-literal/10") + 4571 # reclaim arr + 4572 (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/11") + 4573 # + 4574 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack-with-literal/12") + 4575 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack-with-literal/13") + 4576 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack-with-literal/14") + 4577 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack-with-literal/15") + 4578 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack-with-literal/16") + 4579 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack-with-literal/17") + 4580 # . epilogue + 4581 89/<- %esp 5/r32/ebp + 4582 5d/pop-to-ebp + 4583 c3/return + 4584 + 4585 test-convert-index-into-array-of-bytes-on-stack-with-literal: + 4586 # . prologue + 4587 55/push-ebp + 4588 89/<- %ebp 4/r32/esp + 4589 # setup + 4590 (clear-stream _test-input-stream) + 4591 (clear-stream $_test-input-buffered-file->buffer) + 4592 (clear-stream _test-output-stream) + 4593 (clear-stream $_test-output-buffered-file->buffer) + 4594 # + 4595 (write _test-input-stream "fn foo {\n") + 4596 (write _test-input-stream " var arr: (array byte 3)\n") + 4597 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") + 4598 (write _test-input-stream "}\n") + 4599 # convert + 4600 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4601 (flush _test-output-buffered-file) + 4602 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4608 # check output + 4609 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/0") + 4610 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/1") + 4611 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/2") + 4612 (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") + 4613 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/4") + 4614 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/5") + 4615 # var arr + 4616 (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") + 4617 (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") + 4618 # var x + 4619 (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") + 4620 # x is at (ebp-7) + 4 + 2 = ebp-1 + 4621 (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/9") + 4622 # reclaim x + 4623 (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/10") + 4624 # reclaim arr + 4625 (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/11") + 4626 # + 4627 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/12") + 4628 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/13") + 4629 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/14") + 4630 (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/15") + 4631 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/16") + 4632 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/17") + 4633 # . epilogue + 4634 89/<- %esp 5/r32/ebp + 4635 5d/pop-to-ebp + 4636 c3/return + 4637 + 4638 test-convert-index-into-array-using-offset: + 4639 # . prologue + 4640 55/push-ebp + 4641 89/<- %ebp 4/r32/esp + 4642 # setup + 4643 (clear-stream _test-input-stream) + 4644 (clear-stream $_test-input-buffered-file->buffer) + 4645 (clear-stream _test-output-stream) + 4646 (clear-stream $_test-output-buffered-file->buffer) + 4647 # + 4648 (write _test-input-stream "fn foo {\n") + 4649 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 4650 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 4651 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") + 4652 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") + 4653 (write _test-input-stream "}\n") + 4654 # convert + 4655 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4656 (flush _test-output-buffered-file) + 4657 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4663 # check output + 4664 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset/0") + 4665 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset/1") + 4666 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset/2") + 4667 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset/3") + 4668 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset/4") + 4669 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset/5") + 4670 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset/6") + 4671 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset/7") + 4672 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset/8") + 4673 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-using-offset/9") + 4674 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10") + 4675 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset/11") + 4676 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset/12") + 4677 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset/13") + 4678 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset/14") + 4679 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset/15") + 4680 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset/16") + 4681 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset/17") + 4682 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset/18") + 4683 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset/19") + 4684 # . epilogue + 4685 89/<- %esp 5/r32/ebp + 4686 5d/pop-to-ebp + 4687 c3/return + 4688 + 4689 test-convert-index-into-array-of-bytes-using-offset: + 4690 # . prologue + 4691 55/push-ebp + 4692 89/<- %ebp 4/r32/esp + 4693 # setup + 4694 (clear-stream _test-input-stream) + 4695 (clear-stream $_test-input-buffered-file->buffer) + 4696 (clear-stream _test-output-stream) + 4697 (clear-stream $_test-output-buffered-file->buffer) + 4698 # + 4699 (write _test-input-stream "fn foo {\n") + 4700 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 4701 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 4702 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") + 4703 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") + 4704 (write _test-input-stream "}\n") + 4705 # convert + 4706 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4707 (flush _test-output-buffered-file) + 4708 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4714 # check output + 4715 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset/0") + 4716 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset/1") + 4717 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/2") + 4718 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset/3") + 4719 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset/4") + 4720 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset/5") + 4721 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset/6") + 4722 (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") + 4723 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/8") + 4724 (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") + 4725 (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") + 4726 (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/11") + 4727 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/12") + 4728 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset/13") + 4729 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset/14") + 4730 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset/15") + 4731 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset/16") + 4732 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset/17") + 4733 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/18") + 4734 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset/19") + 4735 # . epilogue + 4736 89/<- %esp 5/r32/ebp + 4737 5d/pop-to-ebp + 4738 c3/return + 4739 + 4740 test-convert-index-into-array-using-offset-on-stack: + 4741 # . prologue + 4742 55/push-ebp + 4743 89/<- %ebp 4/r32/esp + 4744 # setup + 4745 (clear-stream _test-input-stream) + 4746 (clear-stream $_test-input-buffered-file->buffer) + 4747 (clear-stream _test-output-stream) + 4748 (clear-stream $_test-output-buffered-file->buffer) + 4749 # + 4750 (write _test-input-stream "fn foo {\n") + 4751 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 4752 (write _test-input-stream " var idx: int\n") + 4753 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") + 4754 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") + 4755 (write _test-input-stream "}\n") + 4756 # convert + 4757 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4758 (flush _test-output-buffered-file) + 4759 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4765 # check output + 4766 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset-on-stack/0") + 4767 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset-on-stack/1") + 4768 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset-on-stack/2") + 4769 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset-on-stack/3") + 4770 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset-on-stack/4") + 4771 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset-on-stack/5") + 4772 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset-on-stack/6") + 4773 (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") + 4774 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/8") + 4775 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset-on-stack/9") + 4776 (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") + 4777 (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/11") + 4778 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset-on-stack/12") + 4779 (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/13") + 4780 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset-on-stack/14") + 4781 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset-on-stack/15") + 4782 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset-on-stack/16") + 4783 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset-on-stack/17") + 4784 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset-on-stack/18") + 4785 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset-on-stack/19") + 4786 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset-on-stack/20") + 4787 # . epilogue + 4788 89/<- %esp 5/r32/ebp + 4789 5d/pop-to-ebp + 4790 c3/return + 4791 + 4792 test-convert-index-into-array-of-bytes-using-offset-on-stack: + 4793 # . prologue + 4794 55/push-ebp + 4795 89/<- %ebp 4/r32/esp + 4796 # setup + 4797 (clear-stream _test-input-stream) + 4798 (clear-stream $_test-input-buffered-file->buffer) + 4799 (clear-stream _test-output-stream) + 4800 (clear-stream $_test-output-buffered-file->buffer) + 4801 # + 4802 (write _test-input-stream "fn foo {\n") + 4803 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 4804 (write _test-input-stream " var idx: int\n") + 4805 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") + 4806 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") + 4807 (write _test-input-stream "}\n") + 4808 # convert + 4809 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4810 (flush _test-output-buffered-file) + 4811 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4817 # check output + 4818 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/0") + 4819 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/1") + 4820 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/2") + 4821 (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") + 4822 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/4") + 4823 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/5") + 4824 (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") + 4825 (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") + 4826 (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") + 4827 (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") + 4828 (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") + 4829 (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/11") + 4830 (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/12") + 4831 (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/13") + 4832 (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/14") + 4833 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/15") + 4834 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/16") + 4835 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/17") + 4836 (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/18") + 4837 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/19") + 4838 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/20") + 4839 # . epilogue + 4840 89/<- %esp 5/r32/ebp + 4841 5d/pop-to-ebp + 4842 c3/return + 4843 + 4844 test-convert-function-and-type-definition: + 4845 # . prologue + 4846 55/push-ebp + 4847 89/<- %ebp 4/r32/esp + 4848 # setup + 4849 (clear-stream _test-input-stream) + 4850 (clear-stream $_test-input-buffered-file->buffer) + 4851 (clear-stream _test-output-stream) + 4852 (clear-stream $_test-output-buffered-file->buffer) + 4853 # + 4854 (write _test-input-stream "fn foo a: (addr t) {\n") + 4855 (write _test-input-stream " var _a/eax: (addr t) <- copy a\n") + 4856 (write _test-input-stream " var b/ecx: (addr int) <- get _a, x\n") + 4857 (write _test-input-stream " var c/ecx: (addr int) <- get _a, y\n") + 4858 (write _test-input-stream "}\n") + 4859 (write _test-input-stream "type t {\n") + 4860 (write _test-input-stream " x: int\n") + 4861 (write _test-input-stream " y: int\n") + 4862 (write _test-input-stream "}\n") + 4863 # convert + 4864 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4865 (flush _test-output-buffered-file) + 4866 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4872 # check output + 4873 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-and-type-definition/0") + 4874 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-and-type-definition/1") + 4875 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-and-type-definition/2") + 4876 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-and-type-definition/3") + 4877 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-and-type-definition/4") + 4878 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-and-type-definition/5") + 4879 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-and-type-definition/6") + 4880 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7") + 4881 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-and-type-definition/8") + 4882 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000000) 0x00000001/r32" "F - test-convert-function-and-type-definition/9") + 4883 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000004) 0x00000001/r32" "F - test-convert-function-and-type-definition/11") + 4884 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/13") + 4885 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/14") + 4886 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-and-type-definition/15") + 4887 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-and-type-definition/16") + 4888 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-and-type-definition/17") + 4889 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-and-type-definition/18") + 4890 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-and-type-definition/19") + 4891 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-and-type-definition/20") + 4892 # . epilogue + 4893 89/<- %esp 5/r32/ebp + 4894 5d/pop-to-ebp + 4895 c3/return + 4896 + 4897 test-type-definition-with-array: + 4898 # . prologue + 4899 55/push-ebp + 4900 89/<- %ebp 4/r32/esp + 4901 # setup + 4902 (clear-stream _test-input-stream) + 4903 (clear-stream $_test-input-buffered-file->buffer) + 4904 (clear-stream _test-output-stream) + 4905 (clear-stream $_test-output-buffered-file->buffer) + 4906 (clear-stream _test-error-stream) + 4907 (clear-stream $_test-error-buffered-file->buffer) + 4908 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 4909 68/push 0/imm32 + 4910 68/push 0/imm32 + 4911 89/<- %edx 4/r32/esp + 4912 (tailor-exit-descriptor %edx 0x10) + 4913 # + 4914 (write _test-input-stream "type t {\n") + 4915 (write _test-input-stream " a: (array int 3)\n") + 4916 (write _test-input-stream "}\n") + 4917 # convert + 4918 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 4919 # registers except esp clobbered at this point + 4920 # restore ed + 4921 89/<- %edx 4/r32/esp + 4922 (flush _test-output-buffered-file) + 4923 (flush _test-error-buffered-file) + 4924 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 4930 # check output + 4931 (check-stream-equal _test-output-stream "" "F - test-type-definition-with-array: output should be empty") + 4932 (check-next-stream-line-equal _test-error-stream "type t: invalid type 'array'" "F - test-type-definition-with-array: error message") + 4933 # check that stop(1) was called + 4934 (check-ints-equal *(edx+4) 2 "F - test-type-definition-with-array: exit status") + 4935 # don't restore from ebp + 4936 81 0/subop/add %esp 8/imm32 + 4937 # . epilogue + 4938 5d/pop-to-ebp + 4939 c3/return + 4940 + 4941 test-type-definition-with-addr: + 4942 # . prologue + 4943 55/push-ebp + 4944 89/<- %ebp 4/r32/esp + 4945 # setup + 4946 (clear-stream _test-input-stream) + 4947 (clear-stream $_test-input-buffered-file->buffer) + 4948 (clear-stream _test-output-stream) + 4949 (clear-stream $_test-output-buffered-file->buffer) + 4950 (clear-stream _test-error-stream) + 4951 (clear-stream $_test-error-buffered-file->buffer) + 4952 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 4953 68/push 0/imm32 + 4954 68/push 0/imm32 + 4955 89/<- %edx 4/r32/esp + 4956 (tailor-exit-descriptor %edx 0x10) + 4957 # + 4958 (write _test-input-stream "type t {\n") + 4959 (write _test-input-stream " a: (addr int)\n") + 4960 (write _test-input-stream "}\n") + 4961 # convert + 4962 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 4963 # registers except esp clobbered at this point + 4964 # restore ed + 4965 89/<- %edx 4/r32/esp + 4966 (flush _test-output-buffered-file) + 4967 (flush _test-error-buffered-file) + 4968 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 4974 # check output + 4975 (check-stream-equal _test-output-stream "" "F - test-type-definition-with-addr: output should be empty") + 4976 (check-next-stream-line-equal _test-error-stream "type t: invalid type 'addr'" "F - test-type-definition-with-addr: error message") + 4977 # check that stop(1) was called + 4978 (check-ints-equal *(edx+4) 2 "F - test-type-definition-with-addr: exit status") + 4979 # don't restore from ebp + 4980 81 0/subop/add %esp 8/imm32 + 4981 # . epilogue + 4982 5d/pop-to-ebp + 4983 c3/return + 4984 + 4985 test-convert-function-with-local-var-with-user-defined-type: + 4986 # . prologue + 4987 55/push-ebp + 4988 89/<- %ebp 4/r32/esp + 4989 # setup + 4990 (clear-stream _test-input-stream) + 4991 (clear-stream $_test-input-buffered-file->buffer) + 4992 (clear-stream _test-output-stream) + 4993 (clear-stream $_test-output-buffered-file->buffer) + 4994 # + 4995 (write _test-input-stream "fn foo {\n") + 4996 (write _test-input-stream " var a: t\n") + 4997 (write _test-input-stream "}\n") + 4998 (write _test-input-stream "type t {\n") + 4999 (write _test-input-stream " x: int\n") + 5000 (write _test-input-stream " y: int\n") + 5001 (write _test-input-stream "}\n") + 5002 # convert + 5003 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5004 (flush _test-output-buffered-file) + 5005 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5011 # check output + 5012 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type/0") + 5013 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type/1") + 5014 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/2") + 5015 (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") + 5016 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type/4") + 5017 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type/5") + 5018 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/6") + 5019 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/7") + 5020 (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") + 5021 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type/9") + 5022 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type/10") + 5023 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type/11") + 5024 (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") + 5025 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/13") + 5026 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type/14") + 5027 # . epilogue + 5028 89/<- %esp 5/r32/ebp + 5029 5d/pop-to-ebp + 5030 c3/return + 5031 + 5032 test-convert-function-call-with-arg-of-user-defined-type: + 5033 # . prologue + 5034 55/push-ebp + 5035 89/<- %ebp 4/r32/esp + 5036 # setup + 5037 (clear-stream _test-input-stream) + 5038 (clear-stream $_test-input-buffered-file->buffer) + 5039 (clear-stream _test-output-stream) + 5040 (clear-stream $_test-output-buffered-file->buffer) + 5041 # + 5042 (write _test-input-stream "fn f {\n") + 5043 (write _test-input-stream " var a: t\n") + 5044 (write _test-input-stream " foo a\n") + 5045 (write _test-input-stream "}\n") + 5046 (write _test-input-stream "fn foo x: t {\n") + 5047 (write _test-input-stream "}\n") + 5048 (write _test-input-stream "type t {\n") + 5049 (write _test-input-stream " x: int\n") + 5050 (write _test-input-stream " y: int\n") + 5051 (write _test-input-stream "}\n") + 5052 # convert + 5053 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5054 (flush _test-output-buffered-file) + 5055 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5061 # check output + 5062 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") + 5063 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") + 5064 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") + 5065 (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") + 5066 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") + 5067 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") + 5068 # var a: t + 5069 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/6") + 5070 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") + 5071 # foo a + 5072 (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") + 5073 # + 5074 (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") + 5075 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") + 5076 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") + 5077 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") + 5078 (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") + 5079 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") + 5080 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") + 5081 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") + 5082 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") + 5083 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") + 5084 (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") + 5085 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") + 5086 (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") + 5087 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") + 5088 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") + 5089 # . epilogue + 5090 89/<- %esp 5/r32/ebp + 5091 5d/pop-to-ebp + 5092 c3/return + 5093 + 5094 test-convert-function-call-with-arg-of-user-defined-type-register-indirect: + 5095 # . prologue + 5096 55/push-ebp + 5097 89/<- %ebp 4/r32/esp + 5098 # setup + 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) + 5103 # + 5104 (write _test-input-stream "fn f {\n") + 5105 (write _test-input-stream " var a/eax: (addr t) <- copy 0\n") + 5106 (write _test-input-stream " foo *a\n") + 5107 (write _test-input-stream "}\n") + 5108 (write _test-input-stream "fn foo x: t {\n") + 5109 (write _test-input-stream "}\n") + 5110 (write _test-input-stream "type t {\n") + 5111 (write _test-input-stream " x: int\n") + 5112 (write _test-input-stream " y: int\n") + 5113 (write _test-input-stream "}\n") + 5114 # convert + 5115 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5116 (flush _test-output-buffered-file) + 5117 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5123 # check output + 5124 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") + 5125 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") + 5126 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") + 5127 (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") + 5128 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") + 5129 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") + 5130 # var a + 5131 (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") + 5132 (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") + 5133 # foo a + 5134 (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") + 5135 # + 5136 (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") + 5137 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") + 5138 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") + 5139 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") + 5140 (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") + 5141 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") + 5142 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") + 5143 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") + 5144 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") + 5145 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") + 5146 (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") + 5147 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") + 5148 (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") + 5149 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") + 5150 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") + 5151 # . epilogue + 5152 89/<- %esp 5/r32/ebp + 5153 5d/pop-to-ebp + 5154 c3/return + 5155 + 5156 # we don't have special support for call-by-reference; just explicitly create + 5157 # a new variable with the address of the arg + 5158 test-convert-function-call-with-arg-of-user-defined-type-by-reference: + 5159 # . prologue + 5160 55/push-ebp + 5161 89/<- %ebp 4/r32/esp + 5162 # setup + 5163 (clear-stream _test-input-stream) + 5164 (clear-stream $_test-input-buffered-file->buffer) + 5165 (clear-stream _test-output-stream) + 5166 (clear-stream $_test-output-buffered-file->buffer) + 5167 # + 5168 (write _test-input-stream "fn f {\n") + 5169 (write _test-input-stream " var a: t\n") + 5170 (write _test-input-stream " var b/eax: (addr t) <- address a\n") + 5171 (write _test-input-stream " foo b\n") + 5172 (write _test-input-stream "}\n") + 5173 (write _test-input-stream "fn foo x: (addr t) {\n") + 5174 (write _test-input-stream " var x/ecx: (addr int) <- copy x\n") + 5175 (write _test-input-stream " increment *x\n") + 5176 (write _test-input-stream "}\n") + 5177 (write _test-input-stream "type t {\n") + 5178 (write _test-input-stream " x: int\n") + 5179 (write _test-input-stream " y: int\n") + 5180 (write _test-input-stream "}\n") + 5181 # convert + 5182 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5183 (flush _test-output-buffered-file) + 5184 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5190 # check output + 5191 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/0") + 5192 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/1") + 5193 (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") + 5194 (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") + 5195 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/4") + 5196 (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") + 5197 # var a: t + 5198 (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") + 5199 (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") + 5200 # var b/eax: (addr t) + 5201 (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") + 5202 (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") + 5203 # foo a + 5204 (check-next-stream-line-equal _test-output-stream " (foo %eax)" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/10") + 5205 # + 5206 (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") + 5207 (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") + 5208 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/13") + 5209 (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") + 5210 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/15") + 5211 (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") + 5212 (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") + 5213 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/18") + 5214 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/19") + 5215 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/20") + 5216 (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") + 5217 (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") + 5218 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23") + 5219 (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") + 5220 (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") + 5221 (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") + 5222 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/27") + 5223 (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/28") + 5224 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29") + 5225 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/30") + 5226 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/31") + 5227 (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/32") + 5228 (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/33") + 5229 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/34") + 5230 # . epilogue + 5231 89/<- %esp 5/r32/ebp + 5232 5d/pop-to-ebp + 5233 c3/return + 5234 + 5235 test-convert-get-on-local-variable: + 5236 # . prologue + 5237 55/push-ebp + 5238 89/<- %ebp 4/r32/esp + 5239 # setup + 5240 (clear-stream _test-input-stream) + 5241 (clear-stream $_test-input-buffered-file->buffer) + 5242 (clear-stream _test-output-stream) + 5243 (clear-stream $_test-output-buffered-file->buffer) + 5244 # + 5245 (write _test-input-stream "fn foo {\n") + 5246 (write _test-input-stream " var a: t\n") + 5247 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5248 (write _test-input-stream "}\n") + 5249 (write _test-input-stream "type t {\n") + 5250 (write _test-input-stream " x: int\n") + 5251 (write _test-input-stream " y: int\n") + 5252 (write _test-input-stream "}\n") + 5253 # convert + 5254 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5255 (flush _test-output-buffered-file) + 5256 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5262 # check output + 5263 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-local-variable/0") + 5264 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-local-variable/1") + 5265 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-local-variable/2") + 5266 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-local-variable/3") + 5267 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-local-variable/4") + 5268 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-local-variable/5") + 5269 # var a + 5270 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/6") + 5271 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/7") + 5272 # var c + 5273 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-local-variable/8") + 5274 # get + 5275 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000001/r32" "F - test-convert-get-on-local-variable/9") + 5276 # reclaim c + 5277 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-local-variable/10") + 5278 # reclaim a + 5279 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-get-on-local-variable/11") + 5280 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-local-variable/12") + 5281 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-local-variable/13") + 5282 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-local-variable/14") + 5283 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-local-variable/15") + 5284 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-local-variable/16") + 5285 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-local-variable/17") + 5286 # . epilogue + 5287 89/<- %esp 5/r32/ebp + 5288 5d/pop-to-ebp + 5289 c3/return + 5290 + 5291 test-convert-get-on-function-argument: + 5292 # . prologue + 5293 55/push-ebp + 5294 89/<- %ebp 4/r32/esp + 5295 # setup + 5296 (clear-stream _test-input-stream) + 5297 (clear-stream $_test-input-buffered-file->buffer) + 5298 (clear-stream _test-output-stream) + 5299 (clear-stream $_test-output-buffered-file->buffer) + 5300 # + 5301 (write _test-input-stream "fn foo a: t {\n") + 5302 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5303 (write _test-input-stream "}\n") + 5304 (write _test-input-stream "type t {\n") + 5305 (write _test-input-stream " x: int\n") + 5306 (write _test-input-stream " y: int\n") + 5307 (write _test-input-stream "}\n") + 5308 # convert + 5309 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5310 (flush _test-output-buffered-file) + 5311 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5317 # check output + 5318 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument/0") + 5319 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument/1") + 5320 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument/2") + 5321 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument/3") + 5322 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument/4") + 5323 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument/5") + 5324 # var c + 5325 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument/6") + 5326 # get + 5327 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument/7") + 5328 # reclaim c + 5329 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument/8") + 5330 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument/9") + 5331 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument/10") + 5332 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument/11") + 5333 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument/12") + 5334 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument/13") + 5335 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument/14") + 5336 # . epilogue + 5337 89/<- %esp 5/r32/ebp + 5338 5d/pop-to-ebp + 5339 c3/return + 5340 + 5341 test-convert-get-on-function-argument-with-known-type: + 5342 # . prologue + 5343 55/push-ebp + 5344 89/<- %ebp 4/r32/esp + 5345 # setup + 5346 (clear-stream _test-input-stream) + 5347 (clear-stream $_test-input-buffered-file->buffer) + 5348 (clear-stream _test-output-stream) + 5349 (clear-stream $_test-output-buffered-file->buffer) + 5350 # + 5351 (write _test-input-stream "type t {\n") + 5352 (write _test-input-stream " x: int\n") + 5353 (write _test-input-stream " y: int\n") + 5354 (write _test-input-stream "}\n") + 5355 (write _test-input-stream "fn foo a: t {\n") + 5356 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5357 (write _test-input-stream "}\n") + 5358 # convert + 5359 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5360 (flush _test-output-buffered-file) + 5361 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5367 # check output + 5368 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument-with-known-type/0") + 5369 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument-with-known-type/1") + 5370 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument-with-known-type/2") + 5371 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument-with-known-type/3") + 5372 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument-with-known-type/4") + 5373 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument-with-known-type/5") + 5374 # var c + 5375 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument-with-known-type/6") + 5376 # get + 5377 (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") + 5378 # reclaim c + 5379 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument-with-known-type/8") + 5380 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument-with-known-type/9") + 5381 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument-with-known-type/10") + 5382 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument-with-known-type/11") + 5383 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument-with-known-type/12") + 5384 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument-with-known-type/13") + 5385 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument-with-known-type/14") + 5386 # . epilogue + 5387 89/<- %esp 5/r32/ebp + 5388 5d/pop-to-ebp + 5389 c3/return + 5390 + 5391 test-add-with-too-many-inouts: + 5392 # . prologue + 5393 55/push-ebp + 5394 89/<- %ebp 4/r32/esp + 5395 # setup + 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) + 5400 (clear-stream _test-error-stream) + 5401 (clear-stream $_test-error-buffered-file->buffer) + 5402 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5403 68/push 0/imm32 + 5404 68/push 0/imm32 + 5405 89/<- %edx 4/r32/esp + 5406 (tailor-exit-descriptor %edx 0x10) + 5407 # + 5408 (write _test-input-stream "fn foo {\n") + 5409 (write _test-input-stream " var a: int\n") + 5410 (write _test-input-stream " var b/ecx: int <- add a, 0\n") + 5411 (write _test-input-stream "}\n") + 5412 # convert + 5413 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5414 # registers except esp clobbered at this point + 5415 # restore ed + 5416 89/<- %edx 4/r32/esp + 5417 (flush _test-output-buffered-file) + 5418 (flush _test-error-buffered-file) + 5419 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5425 # check output + 5426 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts: output should be empty") + 5427 (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") + 5428 # check that stop(1) was called + 5429 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts: exit status") + 5430 # don't restore from ebp + 5431 81 0/subop/add %esp 8/imm32 + 5432 # . epilogue + 5433 5d/pop-to-ebp + 5434 c3/return + 5435 + 5436 test-add-with-too-many-inouts-2: + 5437 # . prologue + 5438 55/push-ebp + 5439 89/<- %ebp 4/r32/esp + 5440 # setup + 5441 (clear-stream _test-input-stream) + 5442 (clear-stream $_test-input-buffered-file->buffer) + 5443 (clear-stream _test-output-stream) + 5444 (clear-stream $_test-output-buffered-file->buffer) + 5445 (clear-stream _test-error-stream) + 5446 (clear-stream $_test-error-buffered-file->buffer) + 5447 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5448 68/push 0/imm32 + 5449 68/push 0/imm32 + 5450 89/<- %edx 4/r32/esp + 5451 (tailor-exit-descriptor %edx 0x10) + 5452 # + 5453 (write _test-input-stream "fn foo {\n") + 5454 (write _test-input-stream " var a: int\n") + 5455 (write _test-input-stream " add-to a, 0, 1\n") + 5456 (write _test-input-stream "}\n") + 5457 # convert + 5458 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5459 # registers except esp clobbered at this point + 5460 # restore ed + 5461 89/<- %edx 4/r32/esp + 5462 (flush _test-output-buffered-file) + 5463 (flush _test-error-buffered-file) + 5464 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5470 # check output + 5471 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts-2: output should be empty") + 5472 (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") + 5473 # check that stop(1) was called + 5474 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts-2: exit status") + 5475 # don't restore from ebp + 5476 81 0/subop/add %esp 8/imm32 + 5477 # . epilogue + 5478 5d/pop-to-ebp + 5479 c3/return + 5480 + 5481 test-add-with-too-many-outputs: + 5482 # . prologue + 5483 55/push-ebp + 5484 89/<- %ebp 4/r32/esp + 5485 # setup + 5486 (clear-stream _test-input-stream) + 5487 (clear-stream $_test-input-buffered-file->buffer) + 5488 (clear-stream _test-output-stream) + 5489 (clear-stream $_test-output-buffered-file->buffer) + 5490 (clear-stream _test-error-stream) + 5491 (clear-stream $_test-error-buffered-file->buffer) + 5492 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5493 68/push 0/imm32 + 5494 68/push 0/imm32 + 5495 89/<- %edx 4/r32/esp + 5496 (tailor-exit-descriptor %edx 0x10) + 5497 # + 5498 (write _test-input-stream "fn foo {\n") + 5499 (write _test-input-stream " var a/eax: int <- copy 0\n") + 5500 (write _test-input-stream " var b/ebx: int <- copy 0\n") + 5501 (write _test-input-stream " var c/ecx: int <- copy 0\n") + 5502 (write _test-input-stream " c, b <- add a\n") + 5503 (write _test-input-stream "}\n") + 5504 # convert + 5505 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5506 # registers except esp clobbered at this point + 5507 # restore ed + 5508 89/<- %edx 4/r32/esp + 5509 (flush _test-output-buffered-file) + 5510 (flush _test-error-buffered-file) + 5511 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5517 # check output + 5518 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-outputs: output should be empty") + 5519 (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") + 5520 # check that stop(1) was called + 5521 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-outputs: exit status") + 5522 # don't restore from ebp + 5523 81 0/subop/add %esp 8/imm32 + 5524 # . epilogue + 5525 5d/pop-to-ebp + 5526 c3/return + 5527 + 5528 test-add-with-non-number: + 5529 # . prologue + 5530 55/push-ebp + 5531 89/<- %ebp 4/r32/esp + 5532 # setup + 5533 (clear-stream _test-input-stream) + 5534 (clear-stream $_test-input-buffered-file->buffer) + 5535 (clear-stream _test-output-stream) + 5536 (clear-stream $_test-output-buffered-file->buffer) + 5537 (clear-stream _test-error-stream) + 5538 (clear-stream $_test-error-buffered-file->buffer) + 5539 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5540 68/push 0/imm32 + 5541 68/push 0/imm32 + 5542 89/<- %edx 4/r32/esp + 5543 (tailor-exit-descriptor %edx 0x10) + 5544 # + 5545 (write _test-input-stream "fn foo {\n") + 5546 (write _test-input-stream " var a: int\n") + 5547 (write _test-input-stream " var b/ecx: (addr int) <- add a\n") + 5548 (write _test-input-stream "}\n") + 5549 # convert + 5550 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5551 # registers except esp clobbered at this point + 5552 # restore ed + 5553 89/<- %edx 4/r32/esp + 5554 (flush _test-output-buffered-file) + 5555 (flush _test-error-buffered-file) + 5556 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5562 # check output + 5563 (check-stream-equal _test-output-stream "" "F - test-add-with-non-number: output should be empty") + 5564 (check-next-stream-line-equal _test-error-stream "fn foo: stmt add: only non-addr scalar args permitted" "F - test-add-with-non-number: error message") + 5565 # check that stop(1) was called + 5566 (check-ints-equal *(edx+4) 2 "F - test-add-with-non-number: exit status") + 5567 # don't restore from ebp + 5568 81 0/subop/add %esp 8/imm32 + 5569 # . epilogue + 5570 5d/pop-to-ebp + 5571 c3/return + 5572 + 5573 test-add-with-addr-dereferenced: + 5574 # . prologue + 5575 55/push-ebp + 5576 89/<- %ebp 4/r32/esp + 5577 # setup + 5578 (clear-stream _test-input-stream) + 5579 (clear-stream $_test-input-buffered-file->buffer) + 5580 (clear-stream _test-output-stream) + 5581 (clear-stream $_test-output-buffered-file->buffer) + 5582 # + 5583 (write _test-input-stream "fn foo {\n") + 5584 (write _test-input-stream " var a/eax: (addr int) <- copy 0\n") + 5585 (write _test-input-stream " add-to *a, 1\n") + 5586 (write _test-input-stream "}\n") + 5587 # convert + 5588 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5589 (flush _test-output-buffered-file) + 5590 # no error + 5591 # . epilogue + 5592 89/<- %esp 5/r32/ebp + 5593 5d/pop-to-ebp + 5594 c3/return + 5595 + 5596 test-get-with-wrong-field: + 5597 # . prologue + 5598 55/push-ebp + 5599 89/<- %ebp 4/r32/esp + 5600 # setup + 5601 (clear-stream _test-input-stream) + 5602 (clear-stream $_test-input-buffered-file->buffer) + 5603 (clear-stream _test-output-stream) + 5604 (clear-stream $_test-output-buffered-file->buffer) + 5605 (clear-stream _test-error-stream) + 5606 (clear-stream $_test-error-buffered-file->buffer) + 5607 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5608 68/push 0/imm32 + 5609 68/push 0/imm32 + 5610 89/<- %edx 4/r32/esp + 5611 (tailor-exit-descriptor %edx 0x10) + 5612 # + 5613 (write _test-input-stream "fn foo {\n") + 5614 (write _test-input-stream " var a: t\n") + 5615 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5616 (write _test-input-stream "}\n") + 5617 (write _test-input-stream "type t {\n") + 5618 (write _test-input-stream " x: int\n") + 5619 (write _test-input-stream "}\n") + 5620 # convert + 5621 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5622 # registers except esp clobbered at this point + 5623 # restore ed + 5624 89/<- %edx 4/r32/esp + 5625 (flush _test-output-buffered-file) + 5626 (flush _test-error-buffered-file) + 5627 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5633 # check output + 5634 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-field: output should be empty") + 5635 (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") + 5636 # check that stop(1) was called + 5637 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-field: exit status") + 5638 # don't restore from ebp + 5639 81 0/subop/add %esp 8/imm32 + 5640 # . epilogue + 5641 5d/pop-to-ebp + 5642 c3/return + 5643 + 5644 test-get-with-wrong-base-type: + 5645 # . prologue + 5646 55/push-ebp + 5647 89/<- %ebp 4/r32/esp + 5648 # setup + 5649 (clear-stream _test-input-stream) + 5650 (clear-stream $_test-input-buffered-file->buffer) + 5651 (clear-stream _test-output-stream) + 5652 (clear-stream $_test-output-buffered-file->buffer) + 5653 (clear-stream _test-error-stream) + 5654 (clear-stream $_test-error-buffered-file->buffer) + 5655 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5656 68/push 0/imm32 + 5657 68/push 0/imm32 + 5658 89/<- %edx 4/r32/esp + 5659 (tailor-exit-descriptor %edx 0x10) + 5660 # + 5661 (write _test-input-stream "fn foo {\n") + 5662 (write _test-input-stream " var a: int\n") + 5663 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5664 (write _test-input-stream "}\n") + 5665 # convert + 5666 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5667 # registers except esp clobbered at this point + 5668 # restore ed + 5669 89/<- %edx 4/r32/esp + 5670 (flush _test-output-buffered-file) + 5671 (flush _test-error-buffered-file) + 5672 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5678 # check output + 5679 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type: output should be empty") + 5680 (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") + 5681 # check that stop(1) was called + 5682 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type: exit status") + 5683 # don't restore from ebp + 5684 81 0/subop/add %esp 8/imm32 + 5685 # . epilogue + 5686 5d/pop-to-ebp + 5687 c3/return + 5688 + 5689 test-get-with-wrong-base-type-2: + 5690 # . prologue + 5691 55/push-ebp + 5692 89/<- %ebp 4/r32/esp + 5693 # setup + 5694 (clear-stream _test-input-stream) + 5695 (clear-stream $_test-input-buffered-file->buffer) + 5696 (clear-stream _test-output-stream) + 5697 (clear-stream $_test-output-buffered-file->buffer) + 5698 (clear-stream _test-error-stream) + 5699 (clear-stream $_test-error-buffered-file->buffer) + 5700 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5701 68/push 0/imm32 + 5702 68/push 0/imm32 + 5703 89/<- %edx 4/r32/esp + 5704 (tailor-exit-descriptor %edx 0x10) 5705 # - 5706 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 - 5707 (write _test-input-stream " x: int\n") - 5708 (write _test-input-stream " y: int\n") - 5709 (write _test-input-stream " z: int\n") - 5710 (write _test-input-stream "}\n") - 5711 (write _test-input-stream "fn foo {\n") - 5712 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 5713 (write _test-input-stream " var x/eax: (addr t) <- length arr\n") - 5714 (write _test-input-stream "}\n") - 5715 # convert - 5716 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5717 (flush _test-output-buffered-file) - 5718 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5724 # check output - 5725 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/0") - 5726 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/1") - 5727 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/2") - 5728 (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") - 5729 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-eax/4") - 5730 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/5") - 5731 # var arr - 5732 (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") - 5733 (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") - 5734 # length instruction - 5735 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/8") - 5736 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/9") - 5737 (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") - 5738 (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") - 5739 (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") - 5740 (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") - 5741 (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") - 5742 (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") - 5743 # reclaim arr - 5744 (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") - 5745 # - 5746 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-eax/17") - 5747 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/18") - 5748 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/19") - 5749 (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") - 5750 (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") - 5751 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-eax/22") - 5752 # . epilogue - 5753 89/<- %esp 5/r32/ebp - 5754 5d/pop-to-ebp - 5755 c3/return - 5756 - 5757 test-convert-length-of-array-of-user-defined-types-to-ecx: - 5758 # . prologue - 5759 55/push-ebp - 5760 89/<- %ebp 4/r32/esp - 5761 # setup - 5762 (clear-stream _test-input-stream) - 5763 (clear-stream $_test-input-buffered-file->buffer) - 5764 (clear-stream _test-output-stream) - 5765 (clear-stream $_test-output-buffered-file->buffer) - 5766 # - 5767 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 - 5768 (write _test-input-stream " x: int\n") - 5769 (write _test-input-stream " y: int\n") - 5770 (write _test-input-stream " z: int\n") - 5771 (write _test-input-stream "}\n") - 5772 (write _test-input-stream "fn foo {\n") - 5773 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 5774 (write _test-input-stream " var x/ecx: (addr t) <- length arr\n") - 5775 (write _test-input-stream "}\n") - 5776 # convert - 5777 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5778 (flush _test-output-buffered-file) - 5779 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5785 # check output - 5786 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/0") - 5787 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/1") - 5788 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/2") - 5789 (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") - 5790 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/4") - 5791 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/5") - 5792 # var a - 5793 (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") - 5794 (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") - 5795 # var x - 5796 (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") - 5797 # length instruction - 5798 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/9") - 5799 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/10") - 5800 (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") - 5801 (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") - 5802 (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") - 5803 (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") - 5804 (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") - 5805 (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") - 5806 (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") - 5807 # reclaim x - 5808 (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") - 5809 # reclaim a - 5810 (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") - 5811 # - 5812 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/20") - 5813 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/21") - 5814 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/22") - 5815 (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") - 5816 (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") - 5817 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/25") - 5818 # . epilogue - 5819 89/<- %esp 5/r32/ebp - 5820 5d/pop-to-ebp - 5821 c3/return - 5822 - 5823 test-convert-length-of-array-of-user-defined-types-to-edx: - 5824 # . prologue - 5825 55/push-ebp - 5826 89/<- %ebp 4/r32/esp - 5827 # setup - 5828 (clear-stream _test-input-stream) - 5829 (clear-stream $_test-input-buffered-file->buffer) - 5830 (clear-stream _test-output-stream) - 5831 (clear-stream $_test-output-buffered-file->buffer) - 5832 # - 5833 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 - 5834 (write _test-input-stream " x: int\n") - 5835 (write _test-input-stream " y: int\n") - 5836 (write _test-input-stream " z: int\n") - 5837 (write _test-input-stream "}\n") - 5838 (write _test-input-stream "fn foo {\n") - 5839 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 5840 (write _test-input-stream " var x/edx: (addr t) <- length arr\n") - 5841 (write _test-input-stream "}\n") - 5842 # convert - 5843 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5844 (flush _test-output-buffered-file) - 5845 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5851 # check output - 5852 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/0") - 5853 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/1") - 5854 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/2") - 5855 (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") - 5856 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-edx/4") - 5857 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/5") - 5858 # var a - 5859 (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") - 5860 (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") - 5861 # var x - 5862 (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") - 5863 # length instruction - 5864 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/9") - 5865 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/10") - 5866 (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") - 5867 (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") - 5868 (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") - 5869 (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") - 5870 (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") - 5871 (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") - 5872 (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") - 5873 # reclaim x - 5874 (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") - 5875 # reclaim a - 5876 (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") - 5877 # - 5878 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-edx/20") - 5879 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/21") - 5880 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/22") - 5881 (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") - 5882 (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") - 5883 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-edx/25") - 5884 # . epilogue - 5885 89/<- %esp 5/r32/ebp - 5886 5d/pop-to-ebp - 5887 c3/return - 5888 - 5889 test-convert-length-of-array-of-user-defined-types: - 5890 # . prologue - 5891 55/push-ebp - 5892 89/<- %ebp 4/r32/esp - 5893 # setup - 5894 (clear-stream _test-input-stream) - 5895 (clear-stream $_test-input-buffered-file->buffer) - 5896 (clear-stream _test-output-stream) - 5897 (clear-stream $_test-output-buffered-file->buffer) - 5898 # - 5899 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 - 5900 (write _test-input-stream " x: int\n") - 5901 (write _test-input-stream " y: int\n") - 5902 (write _test-input-stream " z: int\n") + 5706 (write _test-input-stream "fn foo {\n") + 5707 (write _test-input-stream " var a: (addr t)\n") + 5708 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5709 (write _test-input-stream "}\n") + 5710 (write _test-input-stream "type t {\n") + 5711 (write _test-input-stream " x: int\n") + 5712 (write _test-input-stream "}\n") + 5713 # convert + 5714 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5715 # registers except esp clobbered at this point + 5716 # restore ed + 5717 89/<- %edx 4/r32/esp + 5718 (flush _test-output-buffered-file) + 5719 (flush _test-error-buffered-file) + 5720 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5726 # check output + 5727 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type-2: output should be empty") + 5728 (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") + 5729 # check that stop(1) was called + 5730 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type-2: exit status") + 5731 # don't restore from ebp + 5732 81 0/subop/add %esp 8/imm32 + 5733 # . epilogue + 5734 5d/pop-to-ebp + 5735 c3/return + 5736 + 5737 test-get-with-wrong-offset-type: + 5738 # . prologue + 5739 55/push-ebp + 5740 89/<- %ebp 4/r32/esp + 5741 # setup + 5742 (clear-stream _test-input-stream) + 5743 (clear-stream $_test-input-buffered-file->buffer) + 5744 (clear-stream _test-output-stream) + 5745 (clear-stream $_test-output-buffered-file->buffer) + 5746 (clear-stream _test-error-stream) + 5747 (clear-stream $_test-error-buffered-file->buffer) + 5748 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5749 68/push 0/imm32 + 5750 68/push 0/imm32 + 5751 89/<- %edx 4/r32/esp + 5752 (tailor-exit-descriptor %edx 0x10) + 5753 # + 5754 (write _test-input-stream "fn foo {\n") + 5755 (write _test-input-stream " var a: t\n") + 5756 (write _test-input-stream " var b: int\n") + 5757 (write _test-input-stream " var c/ecx: (addr int) <- get a, b\n") + 5758 (write _test-input-stream "}\n") + 5759 (write _test-input-stream "type t {\n") + 5760 (write _test-input-stream " x: int\n") + 5761 (write _test-input-stream "}\n") + 5762 # convert + 5763 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5764 # registers except esp clobbered at this point + 5765 # restore ed + 5766 89/<- %edx 4/r32/esp + 5767 (flush _test-output-buffered-file) + 5768 (flush _test-error-buffered-file) + 5769 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5775 # check output + 5776 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-offset-type: output should be empty") + 5777 (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") + 5778 # check that stop(1) was called + 5779 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-offset-type: exit status") + 5780 # don't restore from ebp + 5781 81 0/subop/add %esp 8/imm32 + 5782 # . epilogue + 5783 5d/pop-to-ebp + 5784 c3/return + 5785 + 5786 test-get-with-wrong-output-type: + 5787 # . prologue + 5788 55/push-ebp + 5789 89/<- %ebp 4/r32/esp + 5790 # setup + 5791 (clear-stream _test-input-stream) + 5792 (clear-stream $_test-input-buffered-file->buffer) + 5793 (clear-stream _test-output-stream) + 5794 (clear-stream $_test-output-buffered-file->buffer) + 5795 (clear-stream _test-error-stream) + 5796 (clear-stream $_test-error-buffered-file->buffer) + 5797 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5798 68/push 0/imm32 + 5799 68/push 0/imm32 + 5800 89/<- %edx 4/r32/esp + 5801 (tailor-exit-descriptor %edx 0x10) + 5802 # + 5803 (write _test-input-stream "fn foo {\n") + 5804 (write _test-input-stream " var a: t\n") + 5805 (write _test-input-stream " var c: (addr int)\n") + 5806 (write _test-input-stream " c <- get a, x\n") + 5807 (write _test-input-stream "}\n") + 5808 (write _test-input-stream "type t {\n") + 5809 (write _test-input-stream " x: int\n") + 5810 (write _test-input-stream "}\n") + 5811 # convert + 5812 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5813 # registers except esp clobbered at this point + 5814 # restore ed + 5815 89/<- %edx 4/r32/esp + 5816 (flush _test-output-buffered-file) + 5817 (flush _test-error-buffered-file) + 5818 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5824 # check output + 5825 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type: output should be empty") + 5826 (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") + 5827 # check that stop(1) was called + 5828 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type: exit status") + 5829 # don't restore from ebp + 5830 81 0/subop/add %esp 8/imm32 + 5831 # . epilogue + 5832 5d/pop-to-ebp + 5833 c3/return + 5834 + 5835 test-get-with-wrong-output-type-2: + 5836 # . prologue + 5837 55/push-ebp + 5838 89/<- %ebp 4/r32/esp + 5839 # setup + 5840 (clear-stream _test-input-stream) + 5841 (clear-stream $_test-input-buffered-file->buffer) + 5842 (clear-stream _test-output-stream) + 5843 (clear-stream $_test-output-buffered-file->buffer) + 5844 (clear-stream _test-error-stream) + 5845 (clear-stream $_test-error-buffered-file->buffer) + 5846 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5847 68/push 0/imm32 + 5848 68/push 0/imm32 + 5849 89/<- %edx 4/r32/esp + 5850 (tailor-exit-descriptor %edx 0x10) + 5851 # + 5852 (write _test-input-stream "fn foo {\n") + 5853 (write _test-input-stream " var a: t\n") + 5854 (write _test-input-stream " var c/ecx: int <- get a, x\n") + 5855 (write _test-input-stream "}\n") + 5856 (write _test-input-stream "type t {\n") + 5857 (write _test-input-stream " x: int\n") + 5858 (write _test-input-stream "}\n") + 5859 # convert + 5860 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5861 # registers except esp clobbered at this point + 5862 # restore ed + 5863 89/<- %edx 4/r32/esp + 5864 (flush _test-output-buffered-file) + 5865 (flush _test-error-buffered-file) + 5866 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5872 # check output + 5873 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-2: output should be empty") + 5874 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an address" "F - test-get-with-wrong-output-type-2: error message") + 5875 # check that stop(1) was called + 5876 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-2: exit status") + 5877 # don't restore from ebp + 5878 81 0/subop/add %esp 8/imm32 + 5879 # . epilogue + 5880 5d/pop-to-ebp + 5881 c3/return + 5882 + 5883 test-get-with-wrong-output-type-3: + 5884 # . prologue + 5885 55/push-ebp + 5886 89/<- %ebp 4/r32/esp + 5887 # setup + 5888 (clear-stream _test-input-stream) + 5889 (clear-stream $_test-input-buffered-file->buffer) + 5890 (clear-stream _test-output-stream) + 5891 (clear-stream $_test-output-buffered-file->buffer) + 5892 (clear-stream _test-error-stream) + 5893 (clear-stream $_test-error-buffered-file->buffer) + 5894 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5895 68/push 0/imm32 + 5896 68/push 0/imm32 + 5897 89/<- %edx 4/r32/esp + 5898 (tailor-exit-descriptor %edx 0x10) + 5899 # + 5900 (write _test-input-stream "fn foo {\n") + 5901 (write _test-input-stream " var a: t\n") + 5902 (write _test-input-stream " var c/ecx: (array int) <- get a, x\n") 5903 (write _test-input-stream "}\n") - 5904 (write _test-input-stream "fn foo {\n") - 5905 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 5906 (write _test-input-stream " var x/ebx: (addr t) <- length arr\n") - 5907 (write _test-input-stream "}\n") - 5908 # convert - 5909 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5910 (flush _test-output-buffered-file) - 5911 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5917 # check output - 5918 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types/0") - 5919 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types/1") - 5920 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types/2") - 5921 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types/3") - 5922 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types/4") - 5923 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types/5") - 5924 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types/6") - 5925 (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") - 5926 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-length-of-array-of-user-defined-types/8") - 5927 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types/9") - 5928 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types/10") - 5929 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types/11") - 5930 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types/12") - 5931 (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") - 5932 (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") - 5933 (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") - 5934 (check-next-stream-line-equal _test-output-stream " 89/<- %ebx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types/16") - 5935 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types/17") - 5936 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types/18") - 5937 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types/19") - 5938 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ebx" "F - test-convert-length-of-array-of-user-defined-types/20") - 5939 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types/21") - 5940 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types/22") - 5941 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types/23") - 5942 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types/24") - 5943 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types/25") - 5944 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types/26") - 5945 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types/27") - 5946 # . epilogue - 5947 89/<- %esp 5/r32/ebp - 5948 5d/pop-to-ebp - 5949 c3/return - 5950 - 5951 ####################################################### - 5952 # Parsing - 5953 ####################################################### - 5954 - 5955 == data - 5956 - 5957 # Global state added to each var record when parsing a function - 5958 Next-block-index: # (addr int) - 5959 1/imm32 - 5960 - 5961 Curr-block-depth: # (addr int) - 5962 1/imm32 - 5963 - 5964 == code - 5965 - 5966 parse-mu: # in: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) - 5967 # pseudocode - 5968 # var curr-function: (addr handle function) = Program->functions - 5969 # var curr-signature: (addr handle function) = Program->signatures - 5970 # var curr-type: (addr handle typeinfo) = Program->types - 5971 # var line: (stream byte 512) - 5972 # var word-slice: slice - 5973 # while true # line loop - 5974 # clear-stream(line) - 5975 # read-line-buffered(in, line) - 5976 # if (line->write == 0) break # end of file - 5977 # word-slice = next-mu-token(line) - 5978 # if slice-empty?(word-slice) # end of line - 5979 # continue - 5980 # else if slice-starts-with?(word-slice, "#") # comment - 5981 # continue # end of line - 5982 # else if slice-equal?(word-slice, "fn") - 5983 # var new-function: (handle function) = allocate(function) - 5984 # var vars: (stack live-var 256) - 5985 # populate-mu-function-header(line, new-function, vars) - 5986 # populate-mu-function-body(in, new-function, vars) - 5987 # assert(vars->top == 0) - 5988 # *curr-function = new-function - 5989 # curr-function = &new-function->next - 5990 # else if slice-equal?(word-slice, "sig") - 5991 # var new-function: (handle function) = allocate(function) - 5992 # populate-mu-function-signature(line, new-function) - 5993 # *curr-signature = new-function - 5994 # curr-signature = &new-function->next - 5995 # else if slice-equal?(word-slice, "type") - 5996 # word-slice = next-mu-token(line) - 5997 # type-id = pos-or-insert-slice(Type-id, word-slice) - 5998 # var new-type: (handle typeinfo) = find-or-create-typeinfo(type-id) - 5999 # assert(next-word(line) == "{") - 6000 # populate-mu-type(in, new-type) - 6001 # else - 6002 # abort() - 6003 # - 6004 # . prologue - 6005 55/push-ebp - 6006 89/<- %ebp 4/r32/esp - 6007 # var curr-signature: (addr handle function) at *(ebp-4) - 6008 68/push _Program-signatures/imm32 - 6009 # . save registers - 6010 50/push-eax - 6011 51/push-ecx - 6012 52/push-edx - 6013 53/push-ebx - 6014 56/push-esi - 6015 57/push-edi - 6016 # var line/ecx: (stream byte 512) - 6017 81 5/subop/subtract %esp 0x200/imm32 - 6018 68/push 0x200/imm32/size - 6019 68/push 0/imm32/read - 6020 68/push 0/imm32/write - 6021 89/<- %ecx 4/r32/esp - 6022 # var word-slice/edx: slice - 6023 68/push 0/imm32/end - 6024 68/push 0/imm32/start - 6025 89/<- %edx 4/r32/esp - 6026 # var curr-function/edi: (addr handle function) - 6027 bf/copy-to-edi _Program-functions/imm32 - 6028 # var vars/ebx: (stack live-var 256) - 6029 81 5/subop/subtract %esp 0xc00/imm32 - 6030 68/push 0xc00/imm32/size - 6031 68/push 0/imm32/top - 6032 89/<- %ebx 4/r32/esp - 6033 { - 6034 $parse-mu:line-loop: - 6035 (clear-stream %ecx) - 6036 (read-line-buffered *(ebp+8) %ecx) - 6037 # if (line->write == 0) break - 6038 81 7/subop/compare *ecx 0/imm32 - 6039 0f 84/jump-if-= break/disp32 - 6040 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ - 6046 (next-mu-token %ecx %edx) - 6047 # if slice-empty?(word-slice) continue - 6048 (slice-empty? %edx) # => eax - 6049 3d/compare-eax-and 0/imm32/false - 6050 0f 85/jump-if-!= loop/disp32 - 6051 # if (*word-slice->start == "#") continue - 6052 # . eax = *word-slice->start - 6053 8b/-> *edx 0/r32/eax - 6054 8a/copy-byte *eax 0/r32/AL - 6055 81 4/subop/and %eax 0xff/imm32 - 6056 # . if (eax == '#') continue - 6057 3d/compare-eax-and 0x23/imm32/hash - 6058 0f 84/jump-if-= loop/disp32 - 6059 # if (slice-equal?(word-slice, "fn")) parse a function - 6060 { - 6061 $parse-mu:fn: - 6062 (slice-equal? %edx "fn") # => eax - 6063 3d/compare-eax-and 0/imm32/false - 6064 0f 84/jump-if-= break/disp32 - 6065 # var new-function/esi: (handle function) - 6066 68/push 0/imm32 - 6067 68/push 0/imm32 - 6068 89/<- %esi 4/r32/esp - 6069 # populate-mu-function(line, in, vars, new-function) - 6070 (allocate Heap *Function-size %esi) - 6071 # var new-function-addr/eax: (addr function) - 6072 (lookup *esi *(esi+4)) # => eax - 6073 # initialize vars - 6074 (clear-stack %ebx) - 6075 # - 6076 (populate-mu-function-header %ecx %eax %ebx *(ebp+0xc) *(ebp+0x10)) - 6077 (populate-mu-function-body *(ebp+8) %eax %ebx *(ebp+0xc) *(ebp+0x10)) - 6078 # *curr-function = new-function - 6079 8b/-> *esi 0/r32/eax - 6080 89/<- *edi 0/r32/eax - 6081 8b/-> *(esi+4) 0/r32/eax - 6082 89/<- *(edi+4) 0/r32/eax - 6083 # curr-function = &new-function->next - 6084 # . var tmp/eax: (addr function) = lookup(new-function) - 6085 (lookup *esi *(esi+4)) # => eax - 6086 # . curr-function = &tmp->next - 6087 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next - 6088 # reclaim new-function - 6089 81 0/subop/add %esp 8/imm32 - 6090 # - 6091 e9/jump $parse-mu:line-loop/disp32 - 6092 } - 6093 # if (slice-equal?(word-slice, "sig")) parse a function signature - 6094 # Function signatures are for providing types to SubX functions. - 6095 { - 6096 $parse-mu:sig: - 6097 (slice-equal? %edx "sig") # => eax - 6098 3d/compare-eax-and 0/imm32/false - 6099 0f 84/jump-if-= break/disp32 - 6100 # edi = curr-function - 6101 57/push-edi - 6102 $bb: - 6103 8b/-> *(ebp-4) 7/r32/edi - 6104 # var new-function/esi: (handle function) - 6105 68/push 0/imm32 - 6106 68/push 0/imm32 - 6107 89/<- %esi 4/r32/esp - 6108 # populate-mu-function(line, in, vars, new-function) - 6109 (allocate Heap *Function-size %esi) - 6110 # var new-function-addr/eax: (addr function) - 6111 (lookup *esi *(esi+4)) # => eax - 6112 # - 6113 (populate-mu-function-signature %ecx %eax *(ebp+0xc) *(ebp+0x10)) - 6114 # *curr-signature = new-function - 6115 8b/-> *esi 0/r32/eax - 6116 89/<- *edi 0/r32/eax - 6117 8b/-> *(esi+4) 0/r32/eax - 6118 89/<- *(edi+4) 0/r32/eax - 6119 # curr-signature = &new-function->next - 6120 # . var tmp/eax: (addr function) = lookup(new-function) - 6121 (lookup *esi *(esi+4)) # => eax - 6122 # . curr-function = &tmp->next - 6123 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next - 6124 # reclaim new-function - 6125 81 0/subop/add %esp 8/imm32 - 6126 # save curr-function - 6127 89/<- *(ebp-4) 7/r32/edi - 6128 # restore edi - 6129 5f/pop-to-edi - 6130 # - 6131 e9/jump $parse-mu:line-loop/disp32 - 6132 } - 6133 # if (slice-equal?(word-slice, "type")) parse a type (struct/record) definition - 6134 { - 6135 $parse-mu:type: - 6136 (slice-equal? %edx "type") # => eax - 6137 3d/compare-eax-and 0/imm32 - 6138 0f 84/jump-if-= break/disp32 - 6139 (next-mu-token %ecx %edx) - 6140 # var type-id/eax: int - 6141 (pos-or-insert-slice Type-id %edx) # => eax - 6142 # spill - 6143 51/push-ecx - 6144 # var new-type/ecx: (handle typeinfo) - 6145 68/push 0/imm32 - 6146 68/push 0/imm32 - 6147 89/<- %ecx 4/r32/esp - 6148 (find-or-create-typeinfo %eax %ecx) - 6149 # - 6150 (lookup *ecx *(ecx+4)) # => eax - 6151 # TODO: ensure that 'line' has nothing else but '{' - 6152 #? (dump-typeinfos "=== aaa\n") - 6153 (populate-mu-type *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) # => eax - 6154 #? (dump-typeinfos "=== zzz\n") - 6155 # reclaim new-type - 6156 81 0/subop/add %esp 8/imm32 - 6157 # restore - 6158 59/pop-to-ecx - 6159 e9/jump $parse-mu:line-loop/disp32 - 6160 } - 6161 # otherwise abort - 6162 e9/jump $parse-mu:error1/disp32 - 6163 } # end line loop - 6164 $parse-mu:end: - 6165 # . reclaim locals - 6166 81 0/subop/add %esp 0x20c/imm32 # line - 6167 81 0/subop/add %esp 0xc08/imm32 # vars - 6168 81 0/subop/add %esp 8/imm32 - 6169 # . restore registers - 6170 5f/pop-to-edi - 6171 5e/pop-to-esi - 6172 5b/pop-to-ebx - 6173 5a/pop-to-edx - 6174 59/pop-to-ecx - 6175 58/pop-to-eax - 6176 # . reclaim local - 6177 81 0/subop/add %esp 4/imm32 - 6178 # . epilogue - 6179 89/<- %esp 5/r32/ebp - 6180 5d/pop-to-ebp - 6181 c3/return - 6182 - 6183 $parse-mu:error1: - 6184 # error("unexpected top-level command: " word-slice "\n") - 6185 (write-buffered *(ebp+0xc) "unexpected top-level command: ") - 6186 (write-slice-buffered *(ebp+0xc) %edx) - 6187 (write-buffered *(ebp+0xc) "\n") - 6188 (flush *(ebp+0xc)) - 6189 (stop *(ebp+0x10) 1) - 6190 # never gets here - 6191 - 6192 $parse-mu:error2: - 6193 # error(vars->top " vars not reclaimed after fn '" new-function->name "'\n") - 6194 (write-int32-hex-buffered *(ebp+0xc) *ebx) - 6195 (write-buffered *(ebp+0xc) " vars not reclaimed after fn '") - 6196 (write-slice-buffered *(ebp+0xc) *eax) # Function-name - 6197 (write-buffered *(ebp+0xc) "'\n") - 6198 (flush *(ebp+0xc)) - 6199 (stop *(ebp+0x10) 1) - 6200 # never gets here - 6201 - 6202 # scenarios considered: - 6203 # ✗ fn foo # no block - 6204 # ✓ fn foo { - 6205 # ✗ fn foo { { - 6206 # ✗ fn foo { } - 6207 # ✗ fn foo { } { - 6208 # ✗ fn foo x { - 6209 # ✗ fn foo x: { - 6210 # ✓ fn foo x: int { - 6211 # ✓ fn foo x: int { - 6212 # ✓ fn foo x: int -> y/eax: int { - 6213 # TODO: - 6214 # disallow outputs of type `(... addr ...)` - 6215 # disallow inputs of type `(... addr ... addr ...)` - 6216 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) - 6217 # pseudocode: - 6218 # var word-slice: slice - 6219 # next-mu-token(first-line, word-slice) - 6220 # assert(word-slice not in '{' '}' '->') - 6221 # out->name = slice-to-string(word-slice) - 6222 # ## inouts - 6223 # while true - 6224 # word-slice = next-mu-token(first-line) - 6225 # if (word-slice == '{') goto done - 6226 # if (word-slice == '->') break - 6227 # assert(word-slice != '}') - 6228 # var v: (handle var) = parse-var-with-type(word-slice, first-line) - 6229 # assert(v->register == null) - 6230 # # v->block-depth is implicitly 0 - 6231 # out->inouts = append(v, out->inouts) - 6232 # push(vars, {v, false}) - 6233 # ## outputs - 6234 # while true - 6235 # word-slice = next-mu-token(first-line) - 6236 # if (word-slice == '{') break - 6237 # assert(word-slice not in '}' '->') - 6238 # var v: (handle var) = parse-var-with-type(word-slice, first-line) - 6239 # assert(v->register != null) - 6240 # out->outputs = append(v, out->outputs) - 6241 # done: - 6242 # - 6243 # . prologue - 6244 55/push-ebp - 6245 89/<- %ebp 4/r32/esp - 6246 # . save registers - 6247 50/push-eax - 6248 51/push-ecx - 6249 52/push-edx - 6250 53/push-ebx - 6251 57/push-edi - 6252 # edi = out - 6253 8b/-> *(ebp+0xc) 7/r32/edi - 6254 # var word-slice/ecx: slice - 6255 68/push 0/imm32/end - 6256 68/push 0/imm32/start - 6257 89/<- %ecx 4/r32/esp - 6258 # var v/ebx: (handle var) - 6259 68/push 0/imm32 - 6260 68/push 0/imm32 - 6261 89/<- %ebx 4/r32/esp - 6262 # read function name - 6263 (next-mu-token *(ebp+8) %ecx) - 6264 # error checking - 6265 # if (word-slice == '{') abort - 6266 (slice-equal? %ecx "{") # => eax - 6267 3d/compare-eax-and 0/imm32/false - 6268 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 6269 # if (word-slice == '->') abort - 6270 (slice-equal? %ecx "->") # => eax - 6271 3d/compare-eax-and 0/imm32/false - 6272 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 6273 # if (word-slice == '}') abort - 6274 (slice-equal? %ecx "}") # => eax - 6275 3d/compare-eax-and 0/imm32/false - 6276 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 6277 # save function name - 6278 (slice-to-string Heap %ecx %edi) # Function-name - 6279 # save function inouts - 6280 { - 6281 $populate-mu-function-header:check-for-inout: - 6282 (next-mu-token *(ebp+8) %ecx) - 6283 # if (word-slice == '{') goto done - 6284 (slice-equal? %ecx "{") # => eax - 6285 3d/compare-eax-and 0/imm32/false - 6286 0f 85/jump-if-!= $populate-mu-function-header:done/disp32 - 6287 # if (word-slice == '->') break - 6288 (slice-equal? %ecx "->") # => eax - 6289 3d/compare-eax-and 0/imm32/false - 6290 0f 85/jump-if-!= break/disp32 - 6291 # if (word-slice == '}') abort - 6292 (slice-equal? %ecx "}") # => eax - 6293 3d/compare-eax-and 0/imm32/false - 6294 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 6295 # v = parse-var-with-type(word-slice, first-line) - 6296 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x14) *(ebp+0x18)) - 6297 # assert(v->register == null) - 6298 # . eax: (addr var) = lookup(v) - 6299 (lookup *ebx *(ebx+4)) # => eax - 6300 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 6301 0f 85/jump-if-!= $populate-mu-function-header:error2/disp32 - 6302 # v->block-depth is implicitly 0 - 6303 # - 6304 # out->inouts = append(v, out->inouts) - 6305 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts - 6306 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts - 6307 # push(vars, {v, false}) - 6308 (push *(ebp+0x10) *ebx) - 6309 (push *(ebp+0x10) *(ebx+4)) - 6310 (push *(ebp+0x10) 0) # false - 6311 # - 6312 e9/jump loop/disp32 - 6313 } - 6314 # save function outputs - 6315 { - 6316 $populate-mu-function-header:check-for-out: - 6317 (next-mu-token *(ebp+8) %ecx) - 6318 # if (word-slice == '{') break - 6319 (slice-equal? %ecx "{") # => eax - 6320 3d/compare-eax-and 0/imm32/false - 6321 0f 85/jump-if-!= break/disp32 - 6322 # if (word-slice == '->') abort - 6323 (slice-equal? %ecx "->") # => eax - 6324 3d/compare-eax-and 0/imm32/false - 6325 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 6326 # if (word-slice == '}') abort - 6327 (slice-equal? %ecx "}") # => eax - 6328 3d/compare-eax-and 0/imm32/false - 6329 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 6330 # v = parse-var-with-type(word-slice, first-line) - 6331 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x14) *(ebp+0x18)) - 6332 # assert(var->register != null) - 6333 # . eax: (addr var) = lookup(v) - 6334 (lookup *ebx *(ebx+4)) # => eax - 6335 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 6336 0f 84/jump-if-= $populate-mu-function-header:error3/disp32 - 6337 # out->outputs = append(v, out->outputs) - 6338 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs - 6339 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs - 6340 # - 6341 e9/jump loop/disp32 - 6342 } - 6343 $populate-mu-function-header:done: - 6344 (check-no-tokens-left *(ebp+8)) - 6345 $populate-mu-function-header:end: - 6346 # . reclaim locals - 6347 81 0/subop/add %esp 0x10/imm32 - 6348 # . restore registers - 6349 5f/pop-to-edi - 6350 5b/pop-to-ebx - 6351 5a/pop-to-edx - 6352 59/pop-to-ecx - 6353 58/pop-to-eax - 6354 # . epilogue - 6355 89/<- %esp 5/r32/ebp - 6356 5d/pop-to-ebp - 6357 c3/return - 6358 - 6359 $populate-mu-function-header:error1: - 6360 # error("function header not in form 'fn <name> {'") - 6361 (write-buffered *(ebp+0x14) "function header not in form 'fn <name> [inouts] [-> outputs] {' -- '") - 6362 (flush *(ebp+0x14)) - 6363 (rewind-stream *(ebp+8)) - 6364 (write-stream-data *(ebp+0x14) *(ebp+8)) - 6365 (write-buffered *(ebp+0x14) "'\n") - 6366 (flush *(ebp+0x14)) - 6367 (stop *(ebp+0x18) 1) - 6368 # never gets here - 6369 - 6370 $populate-mu-function-header:error2: - 6371 # error("fn " fn ": function inout '" var "' cannot be in a register") - 6372 (write-buffered *(ebp+0x14) "fn ") - 6373 50/push-eax - 6374 (lookup *edi *(edi+4)) # Function-name Function-name => eax - 6375 (write-buffered *(ebp+0x14) %eax) - 6376 58/pop-to-eax - 6377 (write-buffered *(ebp+0x14) ": function inout '") - 6378 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 6379 (write-buffered *(ebp+0x10) %eax) - 6380 (write-buffered *(ebp+0x14) "' cannot be in a register") - 6381 (flush *(ebp+0x14)) - 6382 (stop *(ebp+0x18) 1) - 6383 # never gets here - 6384 - 6385 $populate-mu-function-header:error3: - 6386 # error("fn " fn ": function output '" var "' must be in a register") - 6387 (write-buffered *(ebp+0x14) "fn ") - 6388 50/push-eax - 6389 (lookup *edi *(edi+4)) # Function-name Function-name => eax - 6390 (write-buffered *(ebp+0x14) %eax) - 6391 58/pop-to-eax - 6392 (write-buffered *(ebp+0x14) ": function output '") - 6393 (lookup *ebx *(ebx+4)) # => eax - 6394 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 6395 (write-buffered *(ebp+0x14) %eax) - 6396 (write-buffered *(ebp+0x14) "' must be in a register, in instruction '") - 6397 (rewind-stream *(ebp+8)) - 6398 (write-stream-data *(ebp+0x14) *(ebp+8)) - 6399 (write-buffered *(ebp+0x14) "'\n") - 6400 (flush *(ebp+0x14)) - 6401 (stop *(ebp+0x18) 1) - 6402 # never gets here - 6403 - 6404 # scenarios considered: - 6405 # ✓ fn foo - 6406 # ✗ fn foo { - 6407 # ✓ fn foo x - 6408 # ✓ fn foo x: int - 6409 # ✓ fn foo x: int -> y/eax: int - 6410 # TODO: - 6411 # disallow outputs of type `(... addr ...)` - 6412 # disallow inputs of type `(... addr ... addr ...)` - 6413 populate-mu-function-signature: # first-line: (addr stream byte), out: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) - 6414 # pseudocode: - 6415 # var word-slice: slice - 6416 # next-mu-token(first-line, word-slice) - 6417 # assert(word-slice not in '{' '}' '->') - 6418 # out->name = slice-to-string(word-slice) - 6419 # ## inouts - 6420 # while true - 6421 # word-slice = next-mu-token(first-line) - 6422 # if slice-empty?(word-slice) break - 6423 # if (word-slice == '->') break - 6424 # assert(word-slice not in '{' '}') - 6425 # var v: (handle var) = parse-var-with-type(word-slice, first-line) - 6426 # assert(v->register == null) - 6427 # # v->block-depth is implicitly 0 - 6428 # out->inouts = append(v, out->inouts) - 6429 # ## outputs - 6430 # while true - 6431 # word-slice = next-mu-token(first-line) - 6432 # if slice-empty?(word-slice) break - 6433 # assert(word-slice not in '{' '}' '->') - 6434 # var v: (handle var) = parse-var-with-type(word-slice, first-line) - 6435 # assert(v->register != null) - 6436 # out->outputs = append(v, out->outputs) - 6437 # - 6438 # . prologue - 6439 55/push-ebp - 6440 89/<- %ebp 4/r32/esp - 6441 # . save registers - 6442 50/push-eax - 6443 51/push-ecx - 6444 52/push-edx - 6445 53/push-ebx - 6446 57/push-edi - 6447 # edi = out - 6448 8b/-> *(ebp+0xc) 7/r32/edi - 6449 # var word-slice/ecx: slice - 6450 68/push 0/imm32/end - 6451 68/push 0/imm32/start - 6452 89/<- %ecx 4/r32/esp - 6453 # var v/ebx: (handle var) - 6454 68/push 0/imm32 - 6455 68/push 0/imm32 - 6456 89/<- %ebx 4/r32/esp - 6457 # read function name - 6458 (next-mu-token *(ebp+8) %ecx) - 6459 # error checking - 6460 # if (word-slice == '{') abort - 6461 (slice-equal? %ecx "{") # => eax - 6462 3d/compare-eax-and 0/imm32/false - 6463 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 6464 # if (word-slice == '->') abort - 6465 (slice-equal? %ecx "->") # => eax - 6466 3d/compare-eax-and 0/imm32/false - 6467 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 6468 # if (word-slice == '}') abort - 6469 (slice-equal? %ecx "}") # => eax - 6470 3d/compare-eax-and 0/imm32/false - 6471 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 6472 # save function name - 6473 (slice-to-string Heap %ecx %edi) # Function-name - 6474 # save function inouts - 6475 { - 6476 $populate-mu-function-signature:check-for-inout: - 6477 (next-mu-token *(ebp+8) %ecx) - 6478 (slice-empty? %ecx) # => eax - 6479 3d/compare-eax-and 0/imm32/false - 6480 0f 85/jump-if-!= break/disp32 - 6481 # if (word-slice == '->') break - 6482 (slice-equal? %ecx "->") # => eax - 6483 3d/compare-eax-and 0/imm32/false - 6484 0f 85/jump-if-!= break/disp32 - 6485 # if (word-slice == '{') abort - 6486 (slice-equal? %ecx "{") # => eax - 6487 3d/compare-eax-and 0/imm32/false - 6488 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 6489 # if (word-slice == '}') abort - 6490 (slice-equal? %ecx "}") # => eax - 6491 3d/compare-eax-and 0/imm32/false - 6492 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 6493 # v = parse-var-with-type(word-slice, first-line) - 6494 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x10) *(ebp+0x14)) - 6495 # assert(v->register == null) - 6496 # . eax: (addr var) = lookup(v) - 6497 (lookup *ebx *(ebx+4)) # => eax - 6498 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 6499 0f 85/jump-if-!= $populate-mu-function-signature:error2/disp32 - 6500 # v->block-depth is implicitly 0 - 6501 # - 6502 # out->inouts = append(v, out->inouts) - 6503 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts - 6504 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts - 6505 # - 6506 e9/jump loop/disp32 - 6507 } - 6508 # save function outputs - 6509 { - 6510 $populate-mu-function-signature:check-for-out: - 6511 (next-mu-token *(ebp+8) %ecx) - 6512 (slice-empty? %ecx) # => eax - 6513 3d/compare-eax-and 0/imm32/false - 6514 0f 85/jump-if-!= break/disp32 - 6515 # if (word-slice == '{') abort - 6516 (slice-equal? %ecx "{") # => eax - 6517 3d/compare-eax-and 0/imm32/false - 6518 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 6519 # if (word-slice == '->') abort - 6520 (slice-equal? %ecx "->") # => eax - 6521 3d/compare-eax-and 0/imm32/false - 6522 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 6523 # if (word-slice == '}') abort - 6524 (slice-equal? %ecx "}") # => eax - 6525 3d/compare-eax-and 0/imm32/false - 6526 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 - 6527 # v = parse-var-with-type(word-slice, first-line) - 6528 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x10) *(ebp+0x14)) - 6529 # assert(var->register != null) - 6530 # . eax: (addr var) = lookup(v) - 6531 (lookup *ebx *(ebx+4)) # => eax - 6532 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 6533 0f 84/jump-if-= $populate-mu-function-signature:error3/disp32 - 6534 # out->outputs = append(v, out->outputs) - 6535 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs - 6536 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs - 6537 # - 6538 e9/jump loop/disp32 - 6539 } - 6540 $populate-mu-function-signature:done: - 6541 (check-no-tokens-left *(ebp+8)) - 6542 $populate-mu-function-signature:end: - 6543 # . reclaim locals - 6544 81 0/subop/add %esp 0x10/imm32 - 6545 # . restore registers - 6546 5f/pop-to-edi - 6547 5b/pop-to-ebx - 6548 5a/pop-to-edx - 6549 59/pop-to-ecx - 6550 58/pop-to-eax - 6551 # . epilogue - 6552 89/<- %esp 5/r32/ebp - 6553 5d/pop-to-ebp - 6554 c3/return - 6555 - 6556 $populate-mu-function-signature:error1: - 6557 # error("function signature not in form 'fn <name> {'") - 6558 (write-buffered *(ebp+0x10) "function signature not in form 'fn <name> [inouts] [-> outputs] {' -- '") - 6559 (flush *(ebp+0x10)) - 6560 (rewind-stream *(ebp+8)) - 6561 (write-stream-data *(ebp+0x10) *(ebp+8)) - 6562 (write-buffered *(ebp+0x10) "'\n") - 6563 (flush *(ebp+0x10)) - 6564 (stop *(ebp+0x14) 1) - 6565 # never gets here - 6566 - 6567 $populate-mu-function-signature:error2: - 6568 # error("fn " fn ": function inout '" var "' cannot be in a register") - 6569 (write-buffered *(ebp+0x10) "fn ") - 6570 50/push-eax - 6571 (lookup *edi *(edi+4)) # Function-name Function-name => eax - 6572 (write-buffered *(ebp+0x10) %eax) - 6573 58/pop-to-eax - 6574 (write-buffered *(ebp+0x10) ": function inout '") - 6575 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 6576 (write-buffered *(ebp+0x10) %eax) - 6577 (write-buffered *(ebp+0x10) "' cannot be in a register") - 6578 (flush *(ebp+0x10)) - 6579 (stop *(ebp+0x14) 1) - 6580 # never gets here - 6581 - 6582 $populate-mu-function-signature:error3: - 6583 # error("fn " fn ": function output '" var "' must be in a register") - 6584 (write-buffered *(ebp+0x10) "fn ") - 6585 50/push-eax - 6586 (lookup *edi *(edi+4)) # Function-name Function-name => eax - 6587 (write-buffered *(ebp+0x10) %eax) - 6588 58/pop-to-eax - 6589 (write-buffered *(ebp+0x10) ": function output '") - 6590 (lookup *ebx *(ebx+4)) # => eax - 6591 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 6592 (write-buffered *(ebp+0x10) %eax) - 6593 (write-buffered *(ebp+0x10) "' must be in a register, in instruction '") - 6594 (rewind-stream *(ebp+8)) - 6595 (write-stream-data *(ebp+0x10) *(ebp+8)) - 6596 (write-buffered *(ebp+0x10) "'\n") - 6597 (flush *(ebp+0x10)) - 6598 (stop *(ebp+0x14) 1) - 6599 # never gets here - 6600 - 6601 test-function-header-with-arg: - 6602 # . prologue - 6603 55/push-ebp - 6604 89/<- %ebp 4/r32/esp - 6605 # setup - 6606 (clear-stream _test-input-stream) - 6607 (write _test-input-stream "foo n: int {\n") - 6608 # var result/ecx: function - 6609 2b/subtract *Function-size 4/r32/esp - 6610 89/<- %ecx 4/r32/esp - 6611 (zero-out %ecx *Function-size) - 6612 # var vars/ebx: (stack live-var 16) - 6613 81 5/subop/subtract %esp 0xc0/imm32 - 6614 68/push 0xc0/imm32/size - 6615 68/push 0/imm32/top - 6616 89/<- %ebx 4/r32/esp - 6617 # convert - 6618 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) - 6619 # check result->name - 6620 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 6621 (check-strings-equal %eax "foo" "F - test-function-header-with-arg/name") - 6622 # var v/edx: (addr var) = result->inouts->value - 6623 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 6624 (lookup *eax *(eax+4)) # List-value List-value => eax - 6625 89/<- %edx 0/r32/eax - 6626 # check v->name - 6627 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 6628 (check-strings-equal %eax "n" "F - test-function-header-with-arg/inout:0") - 6629 # check v->type - 6630 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 6631 (check-ints-equal *eax 1 "F - test-function-header-with-arg/inout:0/type:0") # Type-tree-is-atom - 6632 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-arg/inout:0/type:1") # Type-tree-value - 6633 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-arg/inout:0/type:2") # Type-tree-right - 6634 # . epilogue - 6635 89/<- %esp 5/r32/ebp - 6636 5d/pop-to-ebp - 6637 c3/return - 6638 - 6639 test-function-header-with-multiple-args: - 6640 # . prologue - 6641 55/push-ebp - 6642 89/<- %ebp 4/r32/esp - 6643 # setup - 6644 (clear-stream _test-input-stream) - 6645 (write _test-input-stream "foo a: int, b: int c: int {\n") - 6646 # result/ecx: function - 6647 2b/subtract *Function-size 4/r32/esp - 6648 89/<- %ecx 4/r32/esp - 6649 (zero-out %ecx *Function-size) - 6650 # var vars/ebx: (stack live-var 16) - 6651 81 5/subop/subtract %esp 0xc0/imm32 - 6652 68/push 0xc0/imm32/size - 6653 68/push 0/imm32/top - 6654 89/<- %ebx 4/r32/esp - 6655 # convert - 6656 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) - 6657 # check result->name - 6658 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 6659 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args/name") - 6660 # var inouts/edx: (addr list var) = lookup(result->inouts) - 6661 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 6662 89/<- %edx 0/r32/eax - 6663 $test-function-header-with-multiple-args:inout0: - 6664 # var v/ebx: (addr var) = lookup(inouts->value) - 6665 (lookup *edx *(edx+4)) # List-value List-value => eax - 6666 89/<- %ebx 0/r32/eax - 6667 # check v->name - 6668 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 6669 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name - 6670 # check v->type - 6671 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 6672 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:0/type:0") # Type-tree-is-atom - 6673 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:0/type:1") # Type-tree-value - 6674 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:0/type:2") # Type-tree-right - 6675 $test-function-header-with-multiple-args:inout1: - 6676 # inouts = lookup(inouts->next) - 6677 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 6678 89/<- %edx 0/r32/eax - 6679 # v = lookup(inouts->value) - 6680 (lookup *edx *(edx+4)) # List-value List-value => eax - 6681 89/<- %ebx 0/r32/eax - 6682 # check v->name - 6683 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 6684 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name - 6685 # check v->type - 6686 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 6687 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:1/type:0") # Type-tree-is-atom - 6688 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:1/type:1") # Type-tree-value - 6689 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:1/type:2") # Type-tree-right - 6690 $test-function-header-with-multiple-args:inout2: - 6691 # inouts = lookup(inouts->next) - 6692 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 6693 89/<- %edx 0/r32/eax - 6694 # v = lookup(inouts->value) - 6695 (lookup *edx *(edx+4)) # List-value List-value => eax - 6696 89/<- %ebx 0/r32/eax - 6697 # check v->name - 6698 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 6699 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name - 6700 # check v->type - 6701 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 6702 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:2/type:0") # Type-tree-is-atom - 6703 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:2/type:1") # Type-tree-value - 6704 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:2/type:2") # Type-tree-right - 6705 # . epilogue - 6706 89/<- %esp 5/r32/ebp - 6707 5d/pop-to-ebp - 6708 c3/return - 6709 - 6710 test-function-header-with-multiple-args-and-outputs: - 6711 # . prologue - 6712 55/push-ebp - 6713 89/<- %ebp 4/r32/esp - 6714 # setup - 6715 (clear-stream _test-input-stream) - 6716 (write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx: int {\n") - 6717 # result/ecx: function - 6718 2b/subtract *Function-size 4/r32/esp - 6719 89/<- %ecx 4/r32/esp - 6720 (zero-out %ecx *Function-size) - 6721 # var vars/ebx: (stack live-var 16) - 6722 81 5/subop/subtract %esp 0xc0/imm32 - 6723 68/push 0xc0/imm32/size - 6724 68/push 0/imm32/top - 6725 89/<- %ebx 4/r32/esp - 6726 # convert - 6727 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) - 6728 # check result->name - 6729 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 6730 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args-and-outputs/name") - 6731 # var inouts/edx: (addr list var) = lookup(result->inouts) - 6732 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 6733 89/<- %edx 0/r32/eax - 6734 $test-function-header-with-multiple-args-and-outputs:inout0: - 6735 # var v/ebx: (addr var) = lookup(inouts->value) - 6736 (lookup *edx *(edx+4)) # List-value List-value => eax - 6737 89/<- %ebx 0/r32/eax - 6738 # check v->name - 6739 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 6740 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args-and-outputs/inout:0") - 6741 # check v->type - 6742 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 6743 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:0") # Type-tree-is-atom - 6744 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:1") # Type-tree-value - 6745 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:2") # Type-tree-right - 6746 $test-function-header-with-multiple-args-and-outputs:inout1: - 6747 # inouts = lookup(inouts->next) - 6748 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 6749 89/<- %edx 0/r32/eax - 6750 # v = lookup(inouts->value) - 6751 (lookup *edx *(edx+4)) # List-value List-value => eax - 6752 89/<- %ebx 0/r32/eax - 6753 # check v->name - 6754 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 6755 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args-and-outputs/inout:1") - 6756 # check v->type - 6757 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 6758 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:0") # Type-tree-is-atom - 6759 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:1") # Type-tree-value - 6760 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:2") # Type-tree-right - 6761 $test-function-header-with-multiple-args-and-outputs:inout2: - 6762 # inouts = lookup(inouts->next) - 6763 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 6764 89/<- %edx 0/r32/eax - 6765 # v = lookup(inouts->value) - 6766 (lookup *edx *(edx+4)) # List-value List-value => eax - 6767 89/<- %ebx 0/r32/eax - 6768 # check v->name - 6769 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 6770 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args-and-outputs/inout:2") - 6771 # check v->type - 6772 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 6773 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:0") # Type-tree-is-atom - 6774 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:1") # Type-tree-value - 6775 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:2") # Type-tree-right - 6776 $test-function-header-with-multiple-args-and-outputs:out0: - 6777 # var outputs/edx: (addr list var) = lookup(result->outputs) - 6778 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax - 6779 89/<- %edx 0/r32/eax - 6780 # v = lookup(outputs->value) - 6781 (lookup *edx *(edx+4)) # List-value List-value => eax - 6782 89/<- %ebx 0/r32/eax - 6783 # check v->name - 6784 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 6785 (check-strings-equal %eax "x" "F - test-function-header-with-multiple-args-and-outputs/output:0") - 6786 # check v->register - 6787 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax - 6788 (check-strings-equal %eax "ecx" "F - test-function-header-with-multiple-args-and-outputs/output:0/register") - 6789 # check v->type - 6790 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 6791 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:0") # Type-tree-is-atom - 6792 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:1") # Type-tree-value - 6793 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:2") # Type-tree-right - 6794 $test-function-header-with-multiple-args-and-outputs:out1: - 6795 # outputs = lookup(outputs->next) - 6796 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 6797 89/<- %edx 0/r32/eax - 6798 # v = lookup(inouts->value) - 6799 (lookup *edx *(edx+4)) # List-value List-value => eax - 6800 89/<- %ebx 0/r32/eax - 6801 # check v->name - 6802 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 6803 (check-strings-equal %eax "y" "F - test-function-header-with-multiple-args-and-outputs/output:1") - 6804 # check v->register - 6805 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax - 6806 (check-strings-equal %eax "edx" "F - test-function-header-with-multiple-args-and-outputs/output:1/register") - 6807 # check v->type - 6808 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 6809 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:0") # Type-tree-is-atom - 6810 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:1") # Type-tree-value - 6811 (check-ints-equal *(eax+0c) 0 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:2") # Type-tree-right - 6812 # . epilogue - 6813 89/<- %esp 5/r32/ebp - 6814 5d/pop-to-ebp - 6815 c3/return - 6816 - 6817 # format for variables with types - 6818 # x: int - 6819 # x: int, - 6820 # x/eax: int - 6821 # x/eax: int, - 6822 # ignores at most one trailing comma - 6823 # WARNING: modifies name - 6824 parse-var-with-type: # name: (addr slice), first-line: (addr stream byte), out: (addr handle var), err: (addr buffered-file), ed: (addr exit-descriptor) - 6825 # pseudocode: - 6826 # var s: slice - 6827 # if (!slice-ends-with(name, ":")) - 6828 # abort - 6829 # --name->end to skip ':' - 6830 # next-token-from-slice(name->start, name->end, '/', s) - 6831 # new-var-from-slice(s, out) - 6832 # ## register - 6833 # next-token-from-slice(s->end, name->end, '/', s) - 6834 # if (!slice-empty?(s)) - 6835 # out->register = slice-to-string(s) - 6836 # ## type - 6837 # var type: (handle type-tree) = parse-type(first-line) - 6838 # out->type = type - 6839 # - 6840 # . prologue - 6841 55/push-ebp - 6842 89/<- %ebp 4/r32/esp - 6843 # . save registers - 6844 50/push-eax - 6845 51/push-ecx - 6846 52/push-edx - 6847 53/push-ebx - 6848 56/push-esi - 6849 57/push-edi - 6850 # esi = name - 6851 8b/-> *(ebp+8) 6/r32/esi - 6852 # if (!slice-ends-with?(name, ":")) abort - 6853 8b/-> *(esi+4) 1/r32/ecx # Slice-end - 6854 49/decrement-ecx - 6855 8a/copy-byte *ecx 1/r32/CL - 6856 81 4/subop/and %ecx 0xff/imm32 - 6857 81 7/subop/compare %ecx 0x3a/imm32/colon - 6858 0f 85/jump-if-!= $parse-var-with-type:abort/disp32 - 6859 # --name->end to skip ':' - 6860 ff 1/subop/decrement *(esi+4) - 6861 # var s/ecx: slice - 6862 68/push 0/imm32/end - 6863 68/push 0/imm32/start - 6864 89/<- %ecx 4/r32/esp - 6865 $parse-var-with-type:parse-name: - 6866 (next-token-from-slice *esi *(esi+4) 0x2f %ecx) # Slice-start, Slice-end, '/' - 6867 $parse-var-with-type:create-var: - 6868 # new-var-from-slice(s, out) - 6869 (new-var-from-slice Heap %ecx *(ebp+0x10)) - 6870 # save out->register - 6871 $parse-var-with-type:save-register: - 6872 # . var out-addr/edi: (addr var) = lookup(*out) - 6873 8b/-> *(ebp+0x10) 7/r32/edi - 6874 (lookup *edi *(edi+4)) # => eax - 6875 89/<- %edi 0/r32/eax - 6876 # . s = next-token(...) - 6877 (next-token-from-slice *(ecx+4) *(esi+4) 0x2f %ecx) # s->end, name->end, '/' - 6878 # . if (!slice-empty?(s)) out->register = slice-to-string(s) - 6879 { - 6880 $parse-var-with-type:write-register: - 6881 (slice-empty? %ecx) # => eax - 6882 3d/compare-eax-and 0/imm32/false - 6883 75/jump-if-!= break/disp8 - 6884 # out->register = slice-to-string(s) - 6885 8d/copy-address *(edi+0x18) 0/r32/eax # Var-register - 6886 (slice-to-string Heap %ecx %eax) - 6887 } - 6888 $parse-var-with-type:save-type: - 6889 8d/copy-address *(edi+8) 0/r32/eax # Var-type - 6890 (parse-type Heap *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) - 6891 $parse-var-with-type:end: - 6892 # . reclaim locals - 6893 81 0/subop/add %esp 8/imm32 - 6894 # . restore registers - 6895 5f/pop-to-edi - 6896 5e/pop-to-esi - 6897 5b/pop-to-ebx - 6898 5a/pop-to-edx - 6899 59/pop-to-ecx - 6900 58/pop-to-eax - 6901 # . epilogue - 6902 89/<- %esp 5/r32/ebp - 6903 5d/pop-to-ebp - 6904 c3/return - 6905 - 6906 $parse-var-with-type:abort: - 6907 # error("var should have form 'name: type' in '" line "'\n") - 6908 (write-buffered *(ebp+0x14) "var should have form 'name: type' in '") - 6909 (flush *(ebp+0x14)) - 6910 (rewind-stream *(ebp+0xc)) - 6911 (write-stream-data *(ebp+0x14) *(ebp+0xc)) - 6912 (write-buffered *(ebp+0x14) "'\n") - 6913 (flush *(ebp+0x14)) - 6914 (stop *(ebp+0x18) 1) - 6915 # never gets here - 6916 - 6917 parse-type: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) - 6918 # pseudocode: - 6919 # var s: slice = next-mu-token(in) - 6920 # assert s != "" - 6921 # assert s != "->" - 6922 # assert s != "{" - 6923 # assert s != "}" - 6924 # if s == ")" - 6925 # return - 6926 # out = allocate(Type-tree) - 6927 # if s != "(" - 6928 # HACK: if s is an int, parse and return it - 6929 # out->left-is-atom? = true - 6930 # out->value = pos-or-insert-slice(Type-id, s) - 6931 # return - 6932 # out->left = parse-type(ad, in) - 6933 # out->right = parse-type-tree(ad, in) - 6934 # - 6935 # . prologue - 6936 55/push-ebp - 6937 89/<- %ebp 4/r32/esp - 6938 # . save registers - 6939 50/push-eax - 6940 51/push-ecx - 6941 52/push-edx - 6942 # clear out - 6943 (zero-out *(ebp+0x10) *Handle-size) - 6944 # var s/ecx: slice - 6945 68/push 0/imm32 - 6946 68/push 0/imm32 - 6947 89/<- %ecx 4/r32/esp - 6948 # s = next-mu-token(in) - 6949 (next-mu-token *(ebp+0xc) %ecx) - 6950 #? (write-buffered Stderr "tok: ") - 6951 #? (write-slice-buffered Stderr %ecx) - 6952 #? (write-buffered Stderr "$\n") - 6953 #? (flush Stderr) - 6954 # assert s != "" - 6955 (slice-equal? %ecx "") # => eax - 6956 3d/compare-eax-and 0/imm32/false - 6957 0f 85/jump-if-!= $parse-type:abort/disp32 - 6958 # assert s != "{" - 6959 (slice-equal? %ecx "{") # => eax - 6960 3d/compare-eax-and 0/imm32/false - 6961 0f 85/jump-if-!= $parse-type:abort/disp32 - 6962 # assert s != "}" - 6963 (slice-equal? %ecx "}") # => eax - 6964 3d/compare-eax-and 0/imm32/false - 6965 0f 85/jump-if-!= $parse-type:abort/disp32 - 6966 # assert s != "->" - 6967 (slice-equal? %ecx "->") # => eax - 6968 3d/compare-eax-and 0/imm32/false - 6969 0f 85/jump-if-!= $parse-type:abort/disp32 - 6970 # if (s == ")") return - 6971 (slice-equal? %ecx ")") # => eax - 6972 3d/compare-eax-and 0/imm32/false - 6973 0f 85/jump-if-!= $parse-type:end/disp32 - 6974 # out = new tree - 6975 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10)) - 6976 # var out-addr/edx: (addr type-tree) = lookup(*out) - 6977 8b/-> *(ebp+0x10) 2/r32/edx - 6978 (lookup *edx *(edx+4)) # => eax - 6979 89/<- %edx 0/r32/eax - 6980 { - 6981 # if (s != "(") break - 6982 (slice-equal? %ecx "(") # => eax - 6983 3d/compare-eax-and 0/imm32/false - 6984 75/jump-if-!= break/disp8 - 6985 # if s is a number, store it in the type's size field - 6986 { - 6987 $parse-type:check-for-int: - 6988 (is-hex-int? %ecx) # => eax - 6989 3d/compare-eax-and 0/imm32/false - 6990 74/jump-if-= break/disp8 - 6991 $parse-type:int: - 6992 (parse-hex-int-from-slice %ecx) # => eax - 6993 c7 0/subop/copy *(edx+4) 9/imm32/type-id-array-capacity # Type-tree-value - 6994 89/<- *(edx+8) 0/r32/eax # Type-tree-value-size - 6995 e9/jump $parse-type:end/disp32 - 6996 } - 6997 $parse-type:atom: - 6998 # out->left-is-atom? = true - 6999 c7 0/subop/copy *edx 1/imm32/true # Type-tree-is-atom - 7000 # out->value = pos-or-insert-slice(Type-id, s) - 7001 (pos-or-insert-slice Type-id %ecx) # => eax - 7002 89/<- *(edx+4) 0/r32/eax # Type-tree-value - 7003 e9/jump $parse-type:end/disp32 - 7004 } - 7005 $parse-type:non-atom: - 7006 # otherwise s == "(" - 7007 # out->left = parse-type(ad, in) - 7008 8d/copy-address *(edx+4) 0/r32/eax # Type-tree-left - 7009 (parse-type *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) - 7010 # out->right = parse-type-tree(ad, in) - 7011 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right - 7012 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) - 7013 $parse-type:end: - 7014 # . reclaim locals - 7015 81 0/subop/add %esp 8/imm32 - 7016 # . restore registers - 7017 5a/pop-to-edx - 7018 59/pop-to-ecx - 7019 58/pop-to-eax - 7020 # . epilogue - 7021 89/<- %esp 5/r32/ebp - 7022 5d/pop-to-ebp - 7023 c3/return - 7024 - 7025 $parse-type:abort: - 7026 # error("unexpected token when parsing type: '" s "'\n") - 7027 (write-buffered *(ebp+0x14) "unexpected token when parsing type: '") - 7028 (write-slice-buffered *(ebp+0x14) %ecx) - 7029 (write-buffered *(ebp+0x14) "'\n") - 7030 (flush *(ebp+0x14)) - 7031 (stop *(ebp+0x18) 1) - 7032 # never gets here - 7033 - 7034 parse-type-tree: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) - 7035 # pseudocode: - 7036 # var tmp: (handle type-tree) = parse-type(ad, in) - 7037 # if tmp == 0 - 7038 # return 0 - 7039 # out = allocate(Type-tree) - 7040 # out->left = tmp - 7041 # out->right = parse-type-tree(ad, in) - 7042 # - 7043 # . prologue - 7044 55/push-ebp - 7045 89/<- %ebp 4/r32/esp - 7046 # . save registers - 7047 50/push-eax - 7048 51/push-ecx - 7049 52/push-edx - 7050 # - 7051 (zero-out *(ebp+0x10) *Handle-size) - 7052 # var tmp/ecx: (handle type-tree) - 7053 68/push 0/imm32 - 7054 68/push 0/imm32 - 7055 89/<- %ecx 4/r32/esp - 7056 # tmp = parse-type(ad, in) - 7057 (parse-type *(ebp+8) *(ebp+0xc) %ecx *(ebp+0x14) *(ebp+0x18)) - 7058 # if (tmp == 0) return - 7059 81 7/subop/compare *ecx 0/imm32 - 7060 74/jump-if-= $parse-type-tree:end/disp8 - 7061 # out = new tree - 7062 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10)) - 7063 # var out-addr/edx: (addr tree) = lookup(*out) - 7064 8b/-> *(ebp+0x10) 2/r32/edx - 7065 (lookup *edx *(edx+4)) # => eax - 7066 89/<- %edx 0/r32/eax - 7067 # out->left = tmp - 7068 8b/-> *ecx 0/r32/eax - 7069 89/<- *(edx+4) 0/r32/eax # Type-tree-left - 7070 8b/-> *(ecx+4) 0/r32/eax - 7071 89/<- *(edx+8) 0/r32/eax # Type-tree-left - 7072 # out->right = parse-type-tree(ad, in) - 7073 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right - 7074 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) - 7075 $parse-type-tree:end: - 7076 # . reclaim locals - 7077 81 0/subop/add %esp 8/imm32 - 7078 # . restore registers - 7079 5a/pop-to-edx - 7080 59/pop-to-ecx - 7081 58/pop-to-eax - 7082 # . epilogue - 7083 89/<- %esp 5/r32/ebp - 7084 5d/pop-to-ebp - 7085 c3/return - 7086 - 7087 next-mu-token: # in: (addr stream byte), out: (addr slice) - 7088 # pseudocode: - 7089 # start: - 7090 # skip-chars-matching-whitespace(in) - 7091 # if in->read >= in->write # end of in - 7092 # out = {0, 0} - 7093 # return - 7094 # out->start = &in->data[in->read] - 7095 # var curr-byte/eax: byte = in->data[in->read] - 7096 # if curr->byte == ',' # comment token - 7097 # ++in->read - 7098 # goto start - 7099 # if curr-byte == '#' # comment - 7100 # goto done # treat as eof - 7101 # if curr-byte == '"' # string literal - 7102 # skip-string(in) - 7103 # goto done # no metadata - 7104 # if curr-byte == '(' - 7105 # ++in->read - 7106 # goto done - 7107 # if curr-byte == ')' - 7108 # ++in->read - 7109 # goto done - 7110 # # read a word - 7111 # while true - 7112 # if in->read >= in->write - 7113 # break - 7114 # curr-byte = in->data[in->read] - 7115 # if curr-byte == ' ' - 7116 # break - 7117 # if curr-byte == '\r' - 7118 # break - 7119 # if curr-byte == '\n' - 7120 # break - 7121 # if curr-byte == '(' - 7122 # break - 7123 # if curr-byte == ')' - 7124 # break - 7125 # if curr-byte == ',' - 7126 # break - 7127 # ++in->read - 7128 # done: - 7129 # out->end = &in->data[in->read] - 7130 # - 7131 # . prologue - 7132 55/push-ebp - 7133 89/<- %ebp 4/r32/esp - 7134 # . save registers - 7135 50/push-eax - 7136 51/push-ecx - 7137 56/push-esi - 7138 57/push-edi - 7139 # esi = in - 7140 8b/-> *(ebp+8) 6/r32/esi - 7141 # edi = out - 7142 8b/-> *(ebp+0xc) 7/r32/edi - 7143 $next-mu-token:start: - 7144 (skip-chars-matching-whitespace %esi) - 7145 $next-mu-token:check0: - 7146 # if (in->read >= in->write) return out = {0, 0} - 7147 # . ecx = in->read - 7148 8b/-> *(esi+4) 1/r32/ecx - 7149 # . if (ecx >= in->write) return out = {0, 0} - 7150 3b/compare<- *esi 1/r32/ecx - 7151 c7 0/subop/copy *edi 0/imm32 - 7152 c7 0/subop/copy *(edi+4) 0/imm32 - 7153 0f 8d/jump-if->= $next-mu-token:end/disp32 - 7154 # out->start = &in->data[in->read] - 7155 8d/copy-address *(esi+ecx+0xc) 0/r32/eax - 7156 89/<- *edi 0/r32/eax - 7157 # var curr-byte/eax: byte = in->data[in->read] - 7158 31/xor-with %eax 0/r32/eax - 7159 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 7160 { - 7161 $next-mu-token:check-for-comma: - 7162 # if (curr-byte != ',') break - 7163 3d/compare-eax-and 0x2c/imm32/comma - 7164 75/jump-if-!= break/disp8 - 7165 # ++in->read - 7166 ff 0/subop/increment *(esi+4) - 7167 # restart - 7168 e9/jump $next-mu-token:start/disp32 - 7169 } - 7170 { - 7171 $next-mu-token:check-for-comment: - 7172 # if (curr-byte != '#') break - 7173 3d/compare-eax-and 0x23/imm32/pound - 7174 75/jump-if-!= break/disp8 - 7175 # return eof - 7176 e9/jump $next-mu-token:done/disp32 - 7177 } - 7178 { - 7179 $next-mu-token:check-for-string-literal: - 7180 # if (curr-byte != '"') break - 7181 3d/compare-eax-and 0x22/imm32/dquote - 7182 75/jump-if-!= break/disp8 - 7183 (skip-string %esi) - 7184 # return - 7185 e9/jump $next-mu-token:done/disp32 - 7186 } - 7187 { - 7188 $next-mu-token:check-for-open-paren: - 7189 # if (curr-byte != '(') break - 7190 3d/compare-eax-and 0x28/imm32/open-paren - 7191 75/jump-if-!= break/disp8 - 7192 # ++in->read - 7193 ff 0/subop/increment *(esi+4) - 7194 # return - 7195 e9/jump $next-mu-token:done/disp32 - 7196 } - 7197 { - 7198 $next-mu-token:check-for-close-paren: - 7199 # if (curr-byte != ')') break - 7200 3d/compare-eax-and 0x29/imm32/close-paren - 7201 75/jump-if-!= break/disp8 - 7202 # ++in->read - 7203 ff 0/subop/increment *(esi+4) - 7204 # return - 7205 e9/jump $next-mu-token:done/disp32 - 7206 } - 7207 { - 7208 $next-mu-token:regular-word-without-metadata: - 7209 # if (in->read >= in->write) break - 7210 # . ecx = in->read - 7211 8b/-> *(esi+4) 1/r32/ecx - 7212 # . if (ecx >= in->write) break - 7213 3b/compare<- *esi 1/r32/ecx - 7214 7d/jump-if->= break/disp8 - 7215 # var c/eax: byte = in->data[in->read] - 7216 31/xor-with %eax 0/r32/eax - 7217 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 7218 # if (c == ' ') break - 7219 3d/compare-eax-and 0x20/imm32/space - 7220 74/jump-if-= break/disp8 - 7221 # if (c == '\r') break - 7222 3d/compare-eax-and 0xd/imm32/carriage-return - 7223 74/jump-if-= break/disp8 - 7224 # if (c == '\n') break - 7225 3d/compare-eax-and 0xa/imm32/newline - 7226 74/jump-if-= break/disp8 - 7227 # if (c == '(') break - 7228 3d/compare-eax-and 0x28/imm32/open-paren - 7229 0f 84/jump-if-= break/disp32 - 7230 # if (c == ')') break - 7231 3d/compare-eax-and 0x29/imm32/close-paren - 7232 0f 84/jump-if-= break/disp32 - 7233 # if (c == ',') break - 7234 3d/compare-eax-and 0x2c/imm32/comma - 7235 0f 84/jump-if-= break/disp32 - 7236 # ++in->read - 7237 ff 0/subop/increment *(esi+4) - 7238 # - 7239 e9/jump loop/disp32 - 7240 } - 7241 $next-mu-token:done: - 7242 # out->end = &in->data[in->read] - 7243 8b/-> *(esi+4) 1/r32/ecx - 7244 8d/copy-address *(esi+ecx+0xc) 0/r32/eax - 7245 89/<- *(edi+4) 0/r32/eax - 7246 $next-mu-token:end: - 7247 # . restore registers - 7248 5f/pop-to-edi - 7249 5e/pop-to-esi - 7250 59/pop-to-ecx - 7251 58/pop-to-eax - 7252 # . epilogue - 7253 89/<- %esp 5/r32/ebp - 7254 5d/pop-to-ebp - 7255 c3/return - 7256 - 7257 pos-or-insert-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int - 7258 # . prologue - 7259 55/push-ebp - 7260 89/<- %ebp 4/r32/esp - 7261 # if (pos-slice(arr, s) != -1) return it - 7262 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax - 7263 3d/compare-eax-and -1/imm32 - 7264 75/jump-if-!= $pos-or-insert-slice:end/disp8 - 7265 $pos-or-insert-slice:insert: - 7266 # var s2/eax: (handle array byte) - 7267 68/push 0/imm32 - 7268 68/push 0/imm32 - 7269 89/<- %eax 4/r32/esp - 7270 (slice-to-string Heap *(ebp+0xc) %eax) - 7271 # throw away alloc-id - 7272 (lookup *eax *(eax+4)) # => eax - 7273 (write-int *(ebp+8) %eax) - 7274 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax - 7275 $pos-or-insert-slice:end: - 7276 # . reclaim locals - 7277 81 0/subop/add %esp 8/imm32 - 7278 # . epilogue - 7279 89/<- %esp 5/r32/ebp - 7280 5d/pop-to-ebp - 7281 c3/return - 7282 - 7283 # return the index in an array of strings matching 's', -1 if not found - 7284 # index is denominated in elements, not bytes - 7285 pos-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int - 7286 # . prologue - 7287 55/push-ebp - 7288 89/<- %ebp 4/r32/esp - 7289 # . save registers - 7290 51/push-ecx - 7291 52/push-edx - 7292 53/push-ebx - 7293 56/push-esi - 7294 #? (write-buffered Stderr "pos-slice: ") - 7295 #? (write-slice-buffered Stderr *(ebp+0xc)) - 7296 #? (write-buffered Stderr "\n") - 7297 #? (flush Stderr) - 7298 # esi = arr - 7299 8b/-> *(ebp+8) 6/r32/esi - 7300 # var index/ecx: int = 0 - 7301 b9/copy-to-ecx 0/imm32 - 7302 # var curr/edx: (addr (addr array byte)) = arr->data - 7303 8d/copy-address *(esi+0xc) 2/r32/edx - 7304 # var max/ebx: (addr (addr array byte)) = &arr->data[arr->write] - 7305 8b/-> *esi 3/r32/ebx - 7306 8d/copy-address *(esi+ebx+0xc) 3/r32/ebx - 7307 { - 7308 #? (write-buffered Stderr " ") - 7309 #? (write-int32-hex-buffered Stderr %ecx) - 7310 #? (write-buffered Stderr "\n") - 7311 #? (flush Stderr) - 7312 # if (curr >= max) return -1 - 7313 39/compare %edx 3/r32/ebx - 7314 b8/copy-to-eax -1/imm32 - 7315 73/jump-if-addr>= $pos-slice:end/disp8 - 7316 # if (slice-equal?(s, *curr)) break - 7317 (slice-equal? *(ebp+0xc) *edx) # => eax - 7318 3d/compare-eax-and 0/imm32/false - 7319 75/jump-if-!= break/disp8 - 7320 # ++index - 7321 41/increment-ecx - 7322 # curr += 4 - 7323 81 0/subop/add %edx 4/imm32 - 7324 # - 7325 eb/jump loop/disp8 - 7326 } - 7327 # return index - 7328 89/<- %eax 1/r32/ecx - 7329 $pos-slice:end: - 7330 #? (write-buffered Stderr "=> ") - 7331 #? (write-int32-hex-buffered Stderr %eax) - 7332 #? (write-buffered Stderr "\n") - 7333 # . restore registers - 7334 5e/pop-to-esi - 7335 5b/pop-to-ebx - 7336 5a/pop-to-edx - 7337 59/pop-to-ecx - 7338 # . epilogue - 7339 89/<- %esp 5/r32/ebp - 7340 5d/pop-to-ebp - 7341 c3/return - 7342 - 7343 test-parse-var-with-type: - 7344 # . prologue - 7345 55/push-ebp - 7346 89/<- %ebp 4/r32/esp - 7347 # (eax..ecx) = "x:" - 7348 b8/copy-to-eax "x:"/imm32 - 7349 8b/-> *eax 1/r32/ecx - 7350 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7351 05/add-to-eax 4/imm32 - 7352 # var slice/ecx: slice = {eax, ecx} - 7353 51/push-ecx - 7354 50/push-eax - 7355 89/<- %ecx 4/r32/esp - 7356 # _test-input-stream contains "int" - 7357 (clear-stream _test-input-stream) - 7358 (write _test-input-stream "int") - 7359 # var v/edx: (handle var) - 7360 68/push 0/imm32 - 7361 68/push 0/imm32 - 7362 89/<- %edx 4/r32/esp - 7363 # - 7364 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 7365 # var v-addr/edx: (addr var) = lookup(v) - 7366 (lookup *edx *(edx+4)) # => eax - 7367 89/<- %edx 0/r32/eax - 7368 # check v-addr->name - 7369 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 7370 (check-strings-equal %eax "x" "F - test-parse-var-with-type/name") - 7371 # check v-addr->type - 7372 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 7373 (check-ints-equal *eax 1 "F - test-parse-var-with-type/type:0") # Type-tree-is-atom - 7374 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type/type:1") # Type-tree-value - 7375 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type/type:2") # Type-tree-right - 7376 # . epilogue - 7377 89/<- %esp 5/r32/ebp - 7378 5d/pop-to-ebp - 7379 c3/return - 7380 - 7381 test-parse-var-with-type-and-register: - 7382 # . prologue - 7383 55/push-ebp - 7384 89/<- %ebp 4/r32/esp - 7385 # (eax..ecx) = "x/eax:" - 7386 b8/copy-to-eax "x/eax:"/imm32 - 7387 8b/-> *eax 1/r32/ecx - 7388 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7389 05/add-to-eax 4/imm32 - 7390 # var slice/ecx: slice = {eax, ecx} - 7391 51/push-ecx - 7392 50/push-eax - 7393 89/<- %ecx 4/r32/esp - 7394 # _test-input-stream contains "int" - 7395 (clear-stream _test-input-stream) - 7396 (write _test-input-stream "int") - 7397 # var v/edx: (handle var) - 7398 68/push 0/imm32 - 7399 68/push 0/imm32 - 7400 89/<- %edx 4/r32/esp - 7401 # - 7402 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 7403 # var v-addr/edx: (addr var) = lookup(v) - 7404 (lookup *edx *(edx+4)) # => eax - 7405 89/<- %edx 0/r32/eax - 7406 # check v-addr->name - 7407 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 7408 (check-strings-equal %eax "x" "F - test-parse-var-with-type-and-register/name") - 7409 # check v-addr->register - 7410 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax - 7411 (check-strings-equal %eax "eax" "F - test-parse-var-with-type-and-register/register") - 7412 # check v-addr->type - 7413 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 7414 (check-ints-equal *eax 1 "F - test-parse-var-with-type-and-register/type:0") # Type-tree-is-atom - 7415 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type-and-register/type:1") # Type-tree-left - 7416 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type-and-register/type:2") # Type-tree-right - 7417 # . epilogue - 7418 89/<- %esp 5/r32/ebp - 7419 5d/pop-to-ebp - 7420 c3/return - 7421 - 7422 test-parse-var-with-trailing-characters: - 7423 # . prologue - 7424 55/push-ebp - 7425 89/<- %ebp 4/r32/esp - 7426 # (eax..ecx) = "x:" - 7427 b8/copy-to-eax "x:"/imm32 - 7428 8b/-> *eax 1/r32/ecx - 7429 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7430 05/add-to-eax 4/imm32 - 7431 # var slice/ecx: slice = {eax, ecx} - 7432 51/push-ecx - 7433 50/push-eax - 7434 89/<- %ecx 4/r32/esp - 7435 # _test-input-stream contains "int," - 7436 (clear-stream _test-input-stream) - 7437 (write _test-input-stream "int,") - 7438 # var v/edx: (handle var) - 7439 68/push 0/imm32 - 7440 68/push 0/imm32 - 7441 89/<- %edx 4/r32/esp - 7442 # - 7443 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 7444 # var v-addr/edx: (addr var) = lookup(v) - 7445 (lookup *edx *(edx+4)) # => eax - 7446 89/<- %edx 0/r32/eax - 7447 # check v-addr->name - 7448 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 7449 (check-strings-equal %eax "x" "F - test-parse-var-with-trailing-characters/name") - 7450 # check v-addr->register - 7451 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-trailing-characters/register") # Var-register - 7452 # check v-addr->type - 7453 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 7454 (check-ints-equal *eax 1 "F - test-parse-var-with-trailing-characters/type:0") # Type-tree-is-atom - 7455 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-left - 7456 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-right - 7457 # . epilogue - 7458 89/<- %esp 5/r32/ebp - 7459 5d/pop-to-ebp - 7460 c3/return - 7461 - 7462 test-parse-var-with-register-and-trailing-characters: - 7463 # . prologue - 7464 55/push-ebp - 7465 89/<- %ebp 4/r32/esp - 7466 # (eax..ecx) = "x/eax:" - 7467 b8/copy-to-eax "x/eax:"/imm32 - 7468 8b/-> *eax 1/r32/ecx - 7469 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7470 05/add-to-eax 4/imm32 - 7471 # var slice/ecx: slice = {eax, ecx} - 7472 51/push-ecx - 7473 50/push-eax - 7474 89/<- %ecx 4/r32/esp - 7475 # _test-input-stream contains "int," - 7476 (clear-stream _test-input-stream) - 7477 (write _test-input-stream "int,") - 7478 # var v/edx: (handle var) - 7479 68/push 0/imm32 - 7480 68/push 0/imm32 - 7481 89/<- %edx 4/r32/esp - 7482 # - 7483 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 7484 # var v-addr/edx: (addr var) = lookup(v) - 7485 (lookup *edx *(edx+4)) # => eax - 7486 89/<- %edx 0/r32/eax - 7487 # check v-addr->name - 7488 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 7489 (check-strings-equal %eax "x" "F - test-parse-var-with-register-and-trailing-characters/name") - 7490 # check v-addr->register - 7491 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax - 7492 (check-strings-equal %eax "eax" "F - test-parse-var-with-register-and-trailing-characters/register") - 7493 # check v-addr->type - 7494 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 7495 (check-ints-equal *eax 1 "F - test-parse-var-with-register-and-trailing-characters/type:0") # Type-tree-is-atom - 7496 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-register-and-trailing-characters/type:1") # Type-tree-left - 7497 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-register-and-trailing-characters/type:2") # Type-tree-right - 7498 # . epilogue - 7499 89/<- %esp 5/r32/ebp - 7500 5d/pop-to-ebp - 7501 c3/return - 7502 - 7503 test-parse-var-with-compound-type: - 7504 # . prologue - 7505 55/push-ebp - 7506 89/<- %ebp 4/r32/esp - 7507 # (eax..ecx) = "x:" - 7508 b8/copy-to-eax "x:"/imm32 - 7509 8b/-> *eax 1/r32/ecx - 7510 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7511 05/add-to-eax 4/imm32 - 7512 # var slice/ecx: slice = {eax, ecx} - 7513 51/push-ecx - 7514 50/push-eax - 7515 89/<- %ecx 4/r32/esp - 7516 # _test-input-stream contains "(addr int)" - 7517 (clear-stream _test-input-stream) - 7518 (write _test-input-stream "(addr int)") - 7519 # var v/edx: (handle var) - 7520 68/push 0/imm32 - 7521 68/push 0/imm32 - 7522 89/<- %edx 4/r32/esp - 7523 # - 7524 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 7525 # var v-addr/edx: (addr var) = lookup(v) - 7526 (lookup *edx *(edx+4)) # => eax - 7527 89/<- %edx 0/r32/eax - 7528 # check v-addr->name - 7529 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 7530 (check-strings-equal %eax "x" "F - test-parse-var-with-compound-type/name") - 7531 # check v-addr->register - 7532 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-compound-type/register") # Var-register - 7533 # - check v-addr->type - 7534 # var type/edx: (addr type-tree) = var->type - 7535 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 7536 89/<- %edx 0/r32/eax - 7537 # type is a non-atom - 7538 (check-ints-equal *edx 0 "F - test-parse-var-with-compound-type/type:0") # Type-tree-is-atom - 7539 # type->left == atom(addr) - 7540 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax - 7541 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:1") # Type-tree-is-atom - 7542 (check-ints-equal *(eax+4) 2 "F - test-parse-var-with-compound-type/type:2") # Type-tree-value - 7543 # type->right->left == atom(int) - 7544 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax - 7545 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax - 7546 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:3") # Type-tree-is-atom - 7547 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-compound-type/type:4") # Type-tree-value - 7548 # type->right->right == null - 7549 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-compound-type/type:5") # Type-tree-right - 7550 # . epilogue - 7551 89/<- %esp 5/r32/ebp - 7552 5d/pop-to-ebp - 7553 c3/return - 7554 - 7555 # identifier starts with a letter or '$' or '_' - 7556 # no constraints at the moment on later letters - 7557 # all we really want to do so far is exclude '{', '}' and '->' - 7558 is-identifier?: # in: (addr slice) -> result/eax: boolean - 7559 # . prologue - 7560 55/push-ebp - 7561 89/<- %ebp 4/r32/esp - 7562 # if (slice-empty?(in)) return false - 7563 (slice-empty? *(ebp+8)) # => eax - 7564 3d/compare-eax-and 0/imm32/false - 7565 75/jump-if-!= $is-identifier?:false/disp8 - 7566 # var c/eax: byte = *in->start - 7567 8b/-> *(ebp+8) 0/r32/eax - 7568 8b/-> *eax 0/r32/eax - 7569 8a/copy-byte *eax 0/r32/AL - 7570 81 4/subop/and %eax 0xff/imm32 - 7571 # if (c == '$') return true - 7572 3d/compare-eax-and 0x24/imm32/$ - 7573 74/jump-if-= $is-identifier?:true/disp8 - 7574 # if (c == '_') return true - 7575 3d/compare-eax-and 0x5f/imm32/_ - 7576 74/jump-if-= $is-identifier?:true/disp8 - 7577 # drop case - 7578 25/and-eax-with 0x5f/imm32 - 7579 # if (c < 'A') return false - 7580 3d/compare-eax-and 0x41/imm32/A - 7581 7c/jump-if-< $is-identifier?:false/disp8 - 7582 # if (c > 'Z') return false - 7583 3d/compare-eax-and 0x5a/imm32/Z - 7584 7f/jump-if-> $is-identifier?:false/disp8 - 7585 # otherwise return true - 7586 $is-identifier?:true: - 7587 b8/copy-to-eax 1/imm32/true - 7588 eb/jump $is-identifier?:end/disp8 - 7589 $is-identifier?:false: - 7590 b8/copy-to-eax 0/imm32/false - 7591 $is-identifier?:end: - 7592 # . epilogue - 7593 89/<- %esp 5/r32/ebp - 7594 5d/pop-to-ebp - 7595 c3/return - 7596 - 7597 test-is-identifier-dollar: - 7598 # . prologue - 7599 55/push-ebp - 7600 89/<- %ebp 4/r32/esp - 7601 # (eax..ecx) = "$a" - 7602 b8/copy-to-eax "$a"/imm32 - 7603 8b/-> *eax 1/r32/ecx - 7604 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7605 05/add-to-eax 4/imm32 - 7606 # var slice/ecx: slice = {eax, ecx} - 7607 51/push-ecx - 7608 50/push-eax - 7609 89/<- %ecx 4/r32/esp - 7610 # - 7611 (is-identifier? %ecx) - 7612 (check-ints-equal %eax 1 "F - test-is-identifier-dollar") - 7613 # . epilogue - 7614 89/<- %esp 5/r32/ebp - 7615 5d/pop-to-ebp - 7616 c3/return - 7617 - 7618 test-is-identifier-underscore: - 7619 # . prologue - 7620 55/push-ebp - 7621 89/<- %ebp 4/r32/esp - 7622 # (eax..ecx) = "_a" - 7623 b8/copy-to-eax "_a"/imm32 - 7624 8b/-> *eax 1/r32/ecx - 7625 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7626 05/add-to-eax 4/imm32 - 7627 # var slice/ecx: slice = {eax, ecx} - 7628 51/push-ecx - 7629 50/push-eax - 7630 89/<- %ecx 4/r32/esp - 7631 # - 7632 (is-identifier? %ecx) - 7633 (check-ints-equal %eax 1 "F - test-is-identifier-underscore") - 7634 # . epilogue - 7635 89/<- %esp 5/r32/ebp - 7636 5d/pop-to-ebp - 7637 c3/return - 7638 - 7639 test-is-identifier-a: - 7640 # . prologue - 7641 55/push-ebp - 7642 89/<- %ebp 4/r32/esp - 7643 # (eax..ecx) = "a$" - 7644 b8/copy-to-eax "a$"/imm32 - 7645 8b/-> *eax 1/r32/ecx - 7646 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7647 05/add-to-eax 4/imm32 - 7648 # var slice/ecx: slice = {eax, ecx} - 7649 51/push-ecx - 7650 50/push-eax - 7651 89/<- %ecx 4/r32/esp - 7652 # - 7653 (is-identifier? %ecx) - 7654 (check-ints-equal %eax 1 "F - test-is-identifier-a") - 7655 # . epilogue - 7656 89/<- %esp 5/r32/ebp - 7657 5d/pop-to-ebp - 7658 c3/return - 7659 - 7660 test-is-identifier-z: - 7661 # . prologue - 7662 55/push-ebp - 7663 89/<- %ebp 4/r32/esp - 7664 # (eax..ecx) = "z$" - 7665 b8/copy-to-eax "z$"/imm32 - 7666 8b/-> *eax 1/r32/ecx - 7667 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7668 05/add-to-eax 4/imm32 - 7669 # var slice/ecx: slice = {eax, ecx} - 7670 51/push-ecx - 7671 50/push-eax - 7672 89/<- %ecx 4/r32/esp - 7673 # - 7674 (is-identifier? %ecx) - 7675 (check-ints-equal %eax 1 "F - test-is-identifier-z") - 7676 # . epilogue - 7677 89/<- %esp 5/r32/ebp - 7678 5d/pop-to-ebp - 7679 c3/return - 7680 - 7681 test-is-identifier-A: - 7682 # . prologue - 7683 55/push-ebp - 7684 89/<- %ebp 4/r32/esp - 7685 # (eax..ecx) = "A$" - 7686 b8/copy-to-eax "A$"/imm32 - 7687 8b/-> *eax 1/r32/ecx - 7688 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7689 05/add-to-eax 4/imm32 - 7690 # var slice/ecx: slice = {eax, ecx} - 7691 51/push-ecx - 7692 50/push-eax - 7693 89/<- %ecx 4/r32/esp - 7694 # - 7695 (is-identifier? %ecx) - 7696 (check-ints-equal %eax 1 "F - test-is-identifier-A") - 7697 # . epilogue - 7698 89/<- %esp 5/r32/ebp - 7699 5d/pop-to-ebp - 7700 c3/return - 7701 - 7702 test-is-identifier-Z: - 7703 # . prologue - 7704 55/push-ebp - 7705 89/<- %ebp 4/r32/esp - 7706 # (eax..ecx) = "Z$" - 7707 b8/copy-to-eax "Z$"/imm32 - 7708 8b/-> *eax 1/r32/ecx - 7709 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7710 05/add-to-eax 4/imm32 - 7711 # var slice/ecx: slice = {eax, ecx} - 7712 51/push-ecx - 7713 50/push-eax - 7714 89/<- %ecx 4/r32/esp - 7715 # - 7716 (is-identifier? %ecx) - 7717 (check-ints-equal %eax 1 "F - test-is-identifier-Z") - 7718 # . epilogue - 7719 89/<- %esp 5/r32/ebp - 7720 5d/pop-to-ebp - 7721 c3/return - 7722 - 7723 test-is-identifier-at: - 7724 # character before 'A' is invalid - 7725 # . prologue - 7726 55/push-ebp - 7727 89/<- %ebp 4/r32/esp - 7728 # (eax..ecx) = "@a" - 7729 b8/copy-to-eax "@a"/imm32 - 7730 8b/-> *eax 1/r32/ecx - 7731 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7732 05/add-to-eax 4/imm32 - 7733 # var slice/ecx: slice = {eax, ecx} - 7734 51/push-ecx - 7735 50/push-eax - 7736 89/<- %ecx 4/r32/esp - 7737 # - 7738 (is-identifier? %ecx) - 7739 (check-ints-equal %eax 0 "F - test-is-identifier-@") - 7740 # . epilogue - 7741 89/<- %esp 5/r32/ebp - 7742 5d/pop-to-ebp - 7743 c3/return - 7744 - 7745 test-is-identifier-square-bracket: - 7746 # character after 'Z' is invalid - 7747 # . prologue - 7748 55/push-ebp - 7749 89/<- %ebp 4/r32/esp - 7750 # (eax..ecx) = "[a" - 7751 b8/copy-to-eax "[a"/imm32 - 7752 8b/-> *eax 1/r32/ecx - 7753 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7754 05/add-to-eax 4/imm32 - 7755 # var slice/ecx: slice = {eax, ecx} - 7756 51/push-ecx - 7757 50/push-eax - 7758 89/<- %ecx 4/r32/esp - 7759 # - 7760 (is-identifier? %ecx) - 7761 (check-ints-equal %eax 0 "F - test-is-identifier-@") - 7762 # . epilogue - 7763 89/<- %esp 5/r32/ebp - 7764 5d/pop-to-ebp - 7765 c3/return - 7766 - 7767 test-is-identifier-backtick: - 7768 # character before 'a' is invalid - 7769 # . prologue - 7770 55/push-ebp - 7771 89/<- %ebp 4/r32/esp - 7772 # (eax..ecx) = "`a" - 7773 b8/copy-to-eax "`a"/imm32 - 7774 8b/-> *eax 1/r32/ecx - 7775 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7776 05/add-to-eax 4/imm32 - 7777 # var slice/ecx: slice = {eax, ecx} - 7778 51/push-ecx - 7779 50/push-eax - 7780 89/<- %ecx 4/r32/esp - 7781 # - 7782 (is-identifier? %ecx) - 7783 (check-ints-equal %eax 0 "F - test-is-identifier-backtick") - 7784 # . epilogue - 7785 89/<- %esp 5/r32/ebp - 7786 5d/pop-to-ebp - 7787 c3/return - 7788 - 7789 test-is-identifier-curly-brace-open: - 7790 # character after 'z' is invalid; also used for blocks - 7791 # . prologue - 7792 55/push-ebp - 7793 89/<- %ebp 4/r32/esp - 7794 # (eax..ecx) = "{a" - 7795 b8/copy-to-eax "{a"/imm32 - 7796 8b/-> *eax 1/r32/ecx - 7797 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7798 05/add-to-eax 4/imm32 - 7799 # var slice/ecx: slice = {eax, ecx} - 7800 51/push-ecx - 7801 50/push-eax - 7802 89/<- %ecx 4/r32/esp - 7803 # - 7804 (is-identifier? %ecx) - 7805 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-open") - 7806 # . epilogue - 7807 89/<- %esp 5/r32/ebp - 7808 5d/pop-to-ebp - 7809 c3/return - 7810 - 7811 test-is-identifier-curly-brace-close: - 7812 # . prologue - 7813 55/push-ebp - 7814 89/<- %ebp 4/r32/esp - 7815 # (eax..ecx) = "}a" - 7816 b8/copy-to-eax "}a"/imm32 - 7817 8b/-> *eax 1/r32/ecx - 7818 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7819 05/add-to-eax 4/imm32 - 7820 # var slice/ecx: slice = {eax, ecx} - 7821 51/push-ecx - 7822 50/push-eax - 7823 89/<- %ecx 4/r32/esp - 7824 # - 7825 (is-identifier? %ecx) - 7826 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-close") - 7827 # . epilogue - 7828 89/<- %esp 5/r32/ebp - 7829 5d/pop-to-ebp - 7830 c3/return - 7831 - 7832 test-is-identifier-hyphen: - 7833 # disallow leading '-' since '->' has special meaning - 7834 # . prologue - 7835 55/push-ebp - 7836 89/<- %ebp 4/r32/esp - 7837 # (eax..ecx) = "-a" - 7838 b8/copy-to-eax "-a"/imm32 - 7839 8b/-> *eax 1/r32/ecx - 7840 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 7841 05/add-to-eax 4/imm32 - 7842 # var slice/ecx: slice = {eax, ecx} - 7843 51/push-ecx - 7844 50/push-eax - 7845 89/<- %ecx 4/r32/esp - 7846 # - 7847 (is-identifier? %ecx) - 7848 (check-ints-equal %eax 0 "F - test-is-identifier-hyphen") - 7849 # . epilogue - 7850 89/<- %esp 5/r32/ebp - 7851 5d/pop-to-ebp - 7852 c3/return - 7853 - 7854 populate-mu-function-body: # in: (addr buffered-file), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) - 7855 # . prologue - 7856 55/push-ebp - 7857 89/<- %ebp 4/r32/esp - 7858 # . save registers - 7859 50/push-eax - 7860 56/push-esi - 7861 57/push-edi - 7862 # esi = in - 7863 8b/-> *(ebp+8) 6/r32/esi - 7864 # edi = out - 7865 8b/-> *(ebp+0xc) 7/r32/edi - 7866 # initialize some global state - 7867 c7 0/subop/copy *Curr-block-depth 1/imm32 - 7868 # parse-mu-block(in, vars, out, out->body) - 7869 8d/copy-address *(edi+0x18) 0/r32/eax # Function-body - 7870 (parse-mu-block %esi *(ebp+0x10) %edi %eax *(ebp+0x14) *(ebp+0x18)) - 7871 $populate-mu-function-body:end: - 7872 # . restore registers - 7873 5f/pop-to-edi - 7874 5e/pop-to-esi - 7875 58/pop-to-eax - 7876 # . epilogue - 7877 89/<- %esp 5/r32/ebp - 7878 5d/pop-to-ebp - 7879 c3/return - 7880 - 7881 # parses a block, assuming that the leading '{' has already been read by the caller - 7882 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) - 7883 # pseudocode: - 7884 # var line: (stream byte 512) - 7885 # var word-slice: slice - 7886 # allocate(Heap, Stmt-size, out) - 7887 # var out-addr: (addr block) = lookup(*out) - 7888 # out-addr->tag = 0/block - 7889 # out-addr->var = some unique name - 7890 # push(vars, {out-addr->var, false}) - 7891 # while true # line loop - 7892 # clear-stream(line) - 7893 # read-line-buffered(in, line) - 7894 # if (line->write == 0) break # end of file - 7895 # word-slice = next-mu-token(line) - 7896 # if slice-empty?(word-slice) # end of line - 7897 # continue - 7898 # else if slice-starts-with?(word-slice, "#") - 7899 # continue - 7900 # else if slice-equal?(word-slice, "{") - 7901 # assert(no-tokens-in(line)) - 7902 # block = parse-mu-block(in, vars, fn) - 7903 # append-to-block(out-addr, block) - 7904 # else if slice-equal?(word-slice, "}") - 7905 # break - 7906 # else if slice-ends-with?(word-slice, ":") - 7907 # # TODO: error-check the rest of 'line' - 7908 # --word-slice->end to skip ':' - 7909 # named-block = parse-mu-named-block(word-slice, in, vars, fn) - 7910 # append-to-block(out-addr, named-block) - 7911 # else if slice-equal?(word-slice, "var") - 7912 # var-def = parse-mu-var-def(line, vars, fn) - 7913 # append-to-block(out-addr, var-def) - 7914 # else - 7915 # stmt = parse-mu-stmt(line, vars, fn) - 7916 # append-to-block(out-addr, stmt) - 7917 # pop(vars) - 7918 # - 7919 # . prologue - 7920 55/push-ebp - 7921 89/<- %ebp 4/r32/esp - 7922 # . save registers - 7923 50/push-eax - 7924 51/push-ecx - 7925 52/push-edx - 7926 53/push-ebx - 7927 57/push-edi - 7928 # var line/ecx: (stream byte 512) - 7929 81 5/subop/subtract %esp 0x200/imm32 - 7930 68/push 0x200/imm32/size - 7931 68/push 0/imm32/read - 7932 68/push 0/imm32/write - 7933 89/<- %ecx 4/r32/esp - 7934 # var word-slice/edx: slice - 7935 68/push 0/imm32/end - 7936 68/push 0/imm32/start - 7937 89/<- %edx 4/r32/esp - 7938 # allocate into out - 7939 (allocate Heap *Stmt-size *(ebp+0x14)) - 7940 # var out-addr/edi: (addr block) = lookup(*out) - 7941 8b/-> *(ebp+0x14) 7/r32/edi - 7942 (lookup *edi *(edi+4)) # => eax - 7943 89/<- %edi 0/r32/eax - 7944 # out-addr->tag is 0 (block) by default - 7945 # set out-addr->var - 7946 8d/copy-address *(edi+0xc) 0/r32/eax # Block-var - 7947 (new-block-name *(ebp+0x10) %eax) - 7948 # push(vars, out-addr->var) - 7949 (push *(ebp+0xc) *(edi+0xc)) # Block-var - 7950 (push *(ebp+0xc) *(edi+0x10)) # Block-var - 7951 (push *(ebp+0xc) 0) # false - 7952 # increment *Curr-block-depth - 7953 ff 0/subop/increment *Curr-block-depth - 7954 { - 7955 $parse-mu-block:line-loop: - 7956 # line = read-line-buffered(in) - 7957 (clear-stream %ecx) - 7958 (read-line-buffered *(ebp+8) %ecx) - 7959 #? (write-buffered Stderr "line: ") - 7960 #? (write-stream-data Stderr %ecx) - 7961 #? #? (write-buffered Stderr Newline) # line has its own newline - 7962 #? (flush Stderr) - 7963 #? (rewind-stream %ecx) - 7964 # if (line->write == 0) break - 7965 81 7/subop/compare *ecx 0/imm32 - 7966 0f 84/jump-if-= break/disp32 - 7967 #? (write-buffered Stderr "vars:\n") - 7968 #? (dump-vars *(ebp+0xc)) - 7969 # word-slice = next-mu-token(line) - 7970 (next-mu-token %ecx %edx) - 7971 #? (write-buffered Stderr "word: ") - 7972 #? (write-slice-buffered Stderr %edx) - 7973 #? (write-buffered Stderr Newline) - 7974 #? (flush Stderr) - 7975 # if slice-empty?(word-slice) continue - 7976 (slice-empty? %edx) - 7977 3d/compare-eax-and 0/imm32/false - 7978 0f 85/jump-if-!= loop/disp32 - 7979 # if (slice-starts-with?(word-slice, '#') continue - 7980 # . eax = *word-slice->start - 7981 8b/-> *edx 0/r32/eax - 7982 8a/copy-byte *eax 0/r32/AL - 7983 81 4/subop/and %eax 0xff/imm32 - 7984 # . if (eax == '#') continue - 7985 3d/compare-eax-and 0x23/imm32/hash - 7986 0f 84/jump-if-= loop/disp32 - 7987 # if slice-equal?(word-slice, "{") - 7988 { - 7989 $parse-mu-block:check-for-block: - 7990 (slice-equal? %edx "{") - 7991 3d/compare-eax-and 0/imm32/false - 7992 74/jump-if-= break/disp8 - 7993 (check-no-tokens-left %ecx) - 7994 # parse new block and append - 7995 # . var tmp/eax: (handle block) - 7996 68/push 0/imm32 - 7997 68/push 0/imm32 - 7998 89/<- %eax 4/r32/esp - 7999 # . - 8000 (parse-mu-block *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) - 8001 (append-to-block Heap %edi *eax *(eax+4)) - 8002 # . reclaim tmp - 8003 81 0/subop/add %esp 8/imm32 - 8004 # . - 8005 e9/jump $parse-mu-block:line-loop/disp32 - 8006 } - 8007 # if slice-equal?(word-slice, "}") break - 8008 $parse-mu-block:check-for-end: - 8009 (slice-equal? %edx "}") - 8010 3d/compare-eax-and 0/imm32/false - 8011 0f 85/jump-if-!= break/disp32 - 8012 # if slice-ends-with?(word-slice, ":") parse named block and append - 8013 { - 8014 $parse-mu-block:check-for-named-block: - 8015 # . eax = *(word-slice->end-1) - 8016 8b/-> *(edx+4) 0/r32/eax - 8017 48/decrement-eax - 8018 8a/copy-byte *eax 0/r32/AL - 8019 81 4/subop/and %eax 0xff/imm32 - 8020 # . if (eax != ':') break - 8021 3d/compare-eax-and 0x3a/imm32/colon - 8022 0f 85/jump-if-!= break/disp32 - 8023 # TODO: error-check the rest of 'line' - 8024 # - 8025 # skip ':' - 8026 ff 1/subop/decrement *(edx+4) # Slice-end - 8027 # var tmp/eax: (handle block) - 8028 68/push 0/imm32 - 8029 68/push 0/imm32 - 8030 89/<- %eax 4/r32/esp - 8031 # - 8032 (parse-mu-named-block %edx *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) - 8033 (append-to-block Heap %edi *eax *(eax+4)) - 8034 # reclaim tmp - 8035 81 0/subop/add %esp 8/imm32 - 8036 # - 8037 e9/jump $parse-mu-block:line-loop/disp32 - 8038 } - 8039 # if slice-equal?(word-slice, "var") - 8040 { - 8041 $parse-mu-block:check-for-var: - 8042 (slice-equal? %edx "var") - 8043 3d/compare-eax-and 0/imm32/false - 8044 74/jump-if-= break/disp8 - 8045 # var tmp/eax: (handle block) - 8046 68/push 0/imm32 - 8047 68/push 0/imm32 - 8048 89/<- %eax 4/r32/esp - 8049 # - 8050 (parse-mu-var-def %ecx *(ebp+0xc) %eax *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) - 8051 (append-to-block Heap %edi *eax *(eax+4)) - 8052 # reclaim tmp - 8053 81 0/subop/add %esp 8/imm32 - 8054 # - 8055 e9/jump $parse-mu-block:line-loop/disp32 - 8056 } - 8057 $parse-mu-block:regular-stmt: - 8058 # otherwise - 8059 # var tmp/eax: (handle block) - 8060 68/push 0/imm32 - 8061 68/push 0/imm32 - 8062 89/<- %eax 4/r32/esp - 8063 # - 8064 (parse-mu-stmt %ecx *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) - 8065 (append-to-block Heap %edi *eax *(eax+4)) - 8066 # reclaim tmp - 8067 81 0/subop/add %esp 8/imm32 - 8068 # - 8069 e9/jump loop/disp32 - 8070 } # end line loop - 8071 (clean-up-blocks *(ebp+0xc) *Curr-block-depth *(ebp+0x10)) - 8072 # decrement *Curr-block-depth - 8073 ff 1/subop/decrement *Curr-block-depth - 8074 # pop(vars) - 8075 (pop *(ebp+0xc)) # => eax - 8076 (pop *(ebp+0xc)) # => eax - 8077 (pop *(ebp+0xc)) # => eax - 8078 $parse-mu-block:end: - 8079 # . reclaim locals - 8080 81 0/subop/add %esp 0x214/imm32 - 8081 # . restore registers - 8082 5f/pop-to-edi - 8083 5b/pop-to-ebx - 8084 5a/pop-to-edx - 8085 59/pop-to-ecx - 8086 58/pop-to-eax - 8087 # . epilogue - 8088 89/<- %esp 5/r32/ebp - 8089 5d/pop-to-ebp - 8090 c3/return - 8091 - 8092 $parse-mu-block:abort: - 8093 # error("'{' or '}' should be on its own line, but got '") - 8094 (write-buffered *(ebp+0x18) "'{' or '}' should be on its own line, but got '") - 8095 (rewind-stream %ecx) - 8096 (write-stream-data *(ebp+0x18) %ecx) - 8097 (write-buffered *(ebp+0x18) "'\n") - 8098 (flush *(ebp+0x18)) - 8099 (stop *(ebp+0x1c) 1) - 8100 # never gets here - 8101 - 8102 new-block-name: # fn: (addr function), out: (addr handle var) - 8103 # . prologue - 8104 55/push-ebp - 8105 89/<- %ebp 4/r32/esp - 8106 # . save registers - 8107 50/push-eax - 8108 51/push-ecx - 8109 52/push-edx - 8110 # var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:' - 8111 8b/-> *(ebp+8) 0/r32/eax - 8112 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 8113 8b/-> *eax 0/r32/eax # String-size - 8114 05/add-to-eax 0xd/imm32 # 10 + 2 for '$:' - 8115 89/<- %ecx 0/r32/eax - 8116 # var name/edx: (stream byte n) - 8117 29/subtract-from %esp 1/r32/ecx - 8118 ff 6/subop/push %ecx - 8119 68/push 0/imm32/read - 8120 68/push 0/imm32/write - 8121 89/<- %edx 4/r32/esp - 8122 (clear-stream %edx) - 8123 # eax = fn->name - 8124 8b/-> *(ebp+8) 0/r32/eax - 8125 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 8126 # construct result using Next-block-index (and increment it) - 8127 (write %edx "$") - 8128 (write %edx %eax) - 8129 (write %edx ":") - 8130 (write-int32-hex %edx *Next-block-index) - 8131 ff 0/subop/increment *Next-block-index - 8132 # var s/eax: slice = {name->data, name->data + name->write} (clobbering edx) - 8133 # . eax = name->write - 8134 8b/-> *edx 0/r32/eax - 8135 # . edx = name->data - 8136 8d/copy-address *(edx+0xc) 2/r32/edx - 8137 # . eax = name->write + name->data - 8138 01/add-to %eax 2/r32/edx - 8139 # . push {edx, eax} - 8140 ff 6/subop/push %eax - 8141 ff 6/subop/push %edx - 8142 89/<- %eax 4/r32/esp - 8143 # out = new literal(s) - 8144 (new-literal Heap %eax *(ebp+0xc)) - 8145 #? 8b/-> *(ebp+0xc) 0/r32/eax - 8146 #? (write-buffered Stderr "type allocid in caller after new-literal: ") - 8147 #? (write-int32-hex-buffered Stderr *(eax+8)) - 8148 #? (write-buffered Stderr " for var ") - 8149 #? (write-int32-hex-buffered Stderr %eax) - 8150 #? (write-buffered Stderr Newline) - 8151 #? (flush Stderr) - 8152 $new-block-name:end: - 8153 # . reclaim locals - 8154 81 0/subop/add %ecx 0xc/imm32 # name.{read/write/len} - 8155 81 0/subop/add %ecx 8/imm32 # slice - 8156 01/add-to %esp 1/r32/ecx - 8157 # . restore registers - 8158 5a/pop-to-edx - 8159 59/pop-to-ecx - 8160 58/pop-to-eax - 8161 # . epilogue - 8162 89/<- %esp 5/r32/ebp - 8163 5d/pop-to-ebp - 8164 c3/return - 8165 - 8166 check-no-tokens-left: # line: (addr stream byte) - 8167 # . prologue - 8168 55/push-ebp - 8169 89/<- %ebp 4/r32/esp - 8170 # . save registers - 8171 50/push-eax - 8172 51/push-ecx - 8173 # var s/ecx: slice - 8174 68/push 0/imm32/end - 8175 68/push 0/imm32/start - 8176 89/<- %ecx 4/r32/esp - 8177 # - 8178 (next-mu-token *(ebp+8) %ecx) - 8179 # if slice-empty?(s) return - 8180 (slice-empty? %ecx) - 8181 3d/compare-eax-and 0/imm32/false - 8182 75/jump-if-!= $check-no-tokens-left:end/disp8 - 8183 # if (slice-starts-with?(s, '#') return - 8184 # . eax = *s->start - 8185 8b/-> *edx 0/r32/eax - 8186 8a/copy-byte *eax 0/r32/AL - 8187 81 4/subop/and %eax 0xff/imm32 - 8188 # . if (eax == '#') continue - 8189 3d/compare-eax-and 0x23/imm32/hash - 8190 74/jump-if-= $check-no-tokens-left:end/disp8 - 8191 # abort - 8192 (write-buffered Stderr "'{' or '}' should be on its own line, but got '") - 8193 (rewind-stream %ecx) - 8194 (write-stream 2 %ecx) - 8195 (write-buffered Stderr "'\n") - 8196 (flush Stderr) - 8197 # . syscall(exit, 1) - 8198 bb/copy-to-ebx 1/imm32 - 8199 e8/call syscall_exit/disp32 - 8200 # never gets here - 8201 $check-no-tokens-left:end: - 8202 # . reclaim locals - 8203 81 0/subop/add %esp 8/imm32 - 8204 # . restore registers - 8205 59/pop-to-ecx - 8206 58/pop-to-eax - 8207 # . epilogue - 8208 89/<- %esp 5/r32/ebp - 8209 5d/pop-to-ebp - 8210 c3/return - 8211 - 8212 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) - 8213 # pseudocode: - 8214 # var v: (handle var) - 8215 # new-literal(name, v) - 8216 # push(vars, {v, false}) - 8217 # parse-mu-block(in, vars, fn, out) - 8218 # pop(vars) - 8219 # out->tag = block - 8220 # out->var = v - 8221 # - 8222 # . prologue - 8223 55/push-ebp - 8224 89/<- %ebp 4/r32/esp - 8225 # . save registers - 8226 50/push-eax - 8227 51/push-ecx - 8228 57/push-edi - 8229 # var v/ecx: (handle var) - 8230 68/push 0/imm32 - 8231 68/push 0/imm32 - 8232 89/<- %ecx 4/r32/esp - 8233 # - 8234 (new-literal Heap *(ebp+8) %ecx) - 8235 # push(vars, v) - 8236 (push *(ebp+0x10) *ecx) - 8237 (push *(ebp+0x10) *(ecx+4)) - 8238 (push *(ebp+0x10) 0) # false + 5904 (write _test-input-stream "type t {\n") + 5905 (write _test-input-stream " x: int\n") + 5906 (write _test-input-stream "}\n") + 5907 # convert + 5908 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5909 # registers except esp clobbered at this point + 5910 # restore ed + 5911 89/<- %edx 4/r32/esp + 5912 (flush _test-output-buffered-file) + 5913 (flush _test-error-buffered-file) + 5914 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5920 # check output + 5921 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-3: output should be empty") + 5922 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: output must be an address" "F - test-get-with-wrong-output-type-3: error message") + 5923 # check that stop(1) was called + 5924 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-3: exit status") + 5925 # don't restore from ebp + 5926 81 0/subop/add %esp 8/imm32 + 5927 # . epilogue + 5928 5d/pop-to-ebp + 5929 c3/return + 5930 + 5931 test-get-with-wrong-output-type-4: + 5932 # . prologue + 5933 55/push-ebp + 5934 89/<- %ebp 4/r32/esp + 5935 # setup + 5936 (clear-stream _test-input-stream) + 5937 (clear-stream $_test-input-buffered-file->buffer) + 5938 (clear-stream _test-output-stream) + 5939 (clear-stream $_test-output-buffered-file->buffer) + 5940 (clear-stream _test-error-stream) + 5941 (clear-stream $_test-error-buffered-file->buffer) + 5942 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5943 68/push 0/imm32 + 5944 68/push 0/imm32 + 5945 89/<- %edx 4/r32/esp + 5946 (tailor-exit-descriptor %edx 0x10) + 5947 # + 5948 (write _test-input-stream "fn foo {\n") + 5949 (write _test-input-stream " var a: t\n") + 5950 (write _test-input-stream " var c/ecx: (addr boolean) <- get a, x\n") + 5951 (write _test-input-stream "}\n") + 5952 (write _test-input-stream "type t {\n") + 5953 (write _test-input-stream " x: int\n") + 5954 (write _test-input-stream "}\n") + 5955 # convert + 5956 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5957 # registers except esp clobbered at this point + 5958 # restore ed + 5959 89/<- %edx 4/r32/esp + 5960 (flush _test-output-buffered-file) + 5961 (flush _test-error-buffered-file) + 5962 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5968 # check output + 5969 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-4: output should be empty") + 5970 (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") + 5971 # check that stop(1) was called + 5972 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-4: exit status") + 5973 # don't restore from ebp + 5974 81 0/subop/add %esp 8/imm32 + 5975 # . epilogue + 5976 5d/pop-to-ebp + 5977 c3/return + 5978 + 5979 test-get-with-wrong-output-type-5: + 5980 # . prologue + 5981 55/push-ebp + 5982 89/<- %ebp 4/r32/esp + 5983 # setup + 5984 (clear-stream _test-input-stream) + 5985 (clear-stream $_test-input-buffered-file->buffer) + 5986 (clear-stream _test-output-stream) + 5987 (clear-stream $_test-output-buffered-file->buffer) + 5988 # + 5989 (write _test-input-stream "fn foo {\n") + 5990 (write _test-input-stream " var a: t\n") + 5991 (write _test-input-stream " var c/ecx: (addr handle int) <- get a, x\n") + 5992 (write _test-input-stream "}\n") + 5993 (write _test-input-stream "type t {\n") + 5994 (write _test-input-stream " x: (handle int)\n") + 5995 (write _test-input-stream "}\n") + 5996 # convert + 5997 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5998 (flush _test-output-buffered-file) + 5999 # no errors + 6000 # . epilogue + 6001 89/<- %esp 5/r32/ebp + 6002 5d/pop-to-ebp + 6003 c3/return + 6004 + 6005 test-get-with-too-few-inouts: + 6006 # . prologue + 6007 55/push-ebp + 6008 89/<- %ebp 4/r32/esp + 6009 # setup + 6010 (clear-stream _test-input-stream) + 6011 (clear-stream $_test-input-buffered-file->buffer) + 6012 (clear-stream _test-output-stream) + 6013 (clear-stream $_test-output-buffered-file->buffer) + 6014 (clear-stream _test-error-stream) + 6015 (clear-stream $_test-error-buffered-file->buffer) + 6016 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6017 68/push 0/imm32 + 6018 68/push 0/imm32 + 6019 89/<- %edx 4/r32/esp + 6020 (tailor-exit-descriptor %edx 0x10) + 6021 # + 6022 (write _test-input-stream "fn foo {\n") + 6023 (write _test-input-stream " var a: t\n") + 6024 (write _test-input-stream " var c/ecx: (addr int) <- get a\n") + 6025 (write _test-input-stream "}\n") + 6026 (write _test-input-stream "type t {\n") + 6027 (write _test-input-stream " x: int\n") + 6028 (write _test-input-stream "}\n") + 6029 # convert + 6030 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6031 # registers except esp clobbered at this point + 6032 # restore ed + 6033 89/<- %edx 4/r32/esp + 6034 (flush _test-output-buffered-file) + 6035 (flush _test-error-buffered-file) + 6036 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6042 # check output + 6043 (check-stream-equal _test-output-stream "" "F - test-get-with-too-few-inouts: output should be empty") + 6044 (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") + 6045 # check that stop(1) was called + 6046 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-few-inouts: exit status") + 6047 # don't restore from ebp + 6048 81 0/subop/add %esp 8/imm32 + 6049 # . epilogue + 6050 5d/pop-to-ebp + 6051 c3/return + 6052 + 6053 test-get-with-too-many-inouts: + 6054 # . prologue + 6055 55/push-ebp + 6056 89/<- %ebp 4/r32/esp + 6057 # setup + 6058 (clear-stream _test-input-stream) + 6059 (clear-stream $_test-input-buffered-file->buffer) + 6060 (clear-stream _test-output-stream) + 6061 (clear-stream $_test-output-buffered-file->buffer) + 6062 (clear-stream _test-error-stream) + 6063 (clear-stream $_test-error-buffered-file->buffer) + 6064 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6065 68/push 0/imm32 + 6066 68/push 0/imm32 + 6067 89/<- %edx 4/r32/esp + 6068 (tailor-exit-descriptor %edx 0x10) + 6069 # + 6070 (write _test-input-stream "fn foo {\n") + 6071 (write _test-input-stream " var a: t\n") + 6072 (write _test-input-stream " var c/ecx: (addr int) <- get a, x, 0\n") + 6073 (write _test-input-stream "}\n") + 6074 (write _test-input-stream "type t {\n") + 6075 (write _test-input-stream " x: int\n") + 6076 (write _test-input-stream "}\n") + 6077 # convert + 6078 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6079 # registers except esp clobbered at this point + 6080 # restore ed + 6081 89/<- %edx 4/r32/esp + 6082 (flush _test-output-buffered-file) + 6083 (flush _test-error-buffered-file) + 6084 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6090 # check output + 6091 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-inouts: output should be empty") + 6092 (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") + 6093 # check that stop(1) was called + 6094 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-inouts: exit status") + 6095 # don't restore from ebp + 6096 81 0/subop/add %esp 8/imm32 + 6097 # . epilogue + 6098 5d/pop-to-ebp + 6099 c3/return + 6100 + 6101 test-get-with-no-output: + 6102 # . prologue + 6103 55/push-ebp + 6104 89/<- %ebp 4/r32/esp + 6105 # setup + 6106 (clear-stream _test-input-stream) + 6107 (clear-stream $_test-input-buffered-file->buffer) + 6108 (clear-stream _test-output-stream) + 6109 (clear-stream $_test-output-buffered-file->buffer) + 6110 (clear-stream _test-error-stream) + 6111 (clear-stream $_test-error-buffered-file->buffer) + 6112 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6113 68/push 0/imm32 + 6114 68/push 0/imm32 + 6115 89/<- %edx 4/r32/esp + 6116 (tailor-exit-descriptor %edx 0x10) + 6117 # + 6118 (write _test-input-stream "fn foo {\n") + 6119 (write _test-input-stream " var a: t\n") + 6120 (write _test-input-stream " get a, x\n") + 6121 (write _test-input-stream "}\n") + 6122 (write _test-input-stream "type t {\n") + 6123 (write _test-input-stream " x: int\n") + 6124 (write _test-input-stream "}\n") + 6125 # convert + 6126 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6127 # registers except esp clobbered at this point + 6128 # restore ed + 6129 89/<- %edx 4/r32/esp + 6130 (flush _test-output-buffered-file) + 6131 (flush _test-error-buffered-file) + 6132 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6138 # check output + 6139 (check-stream-equal _test-output-stream "" "F - test-get-with-no-output: output should be empty") + 6140 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: must have an output" "F - test-get-with-no-output: error message") + 6141 # check that stop(1) was called + 6142 (check-ints-equal *(edx+4) 2 "F - test-get-with-no-output: exit status") + 6143 # don't restore from ebp + 6144 81 0/subop/add %esp 8/imm32 + 6145 # . epilogue + 6146 5d/pop-to-ebp + 6147 c3/return + 6148 + 6149 test-get-with-too-many-outputs: + 6150 # . prologue + 6151 55/push-ebp + 6152 89/<- %ebp 4/r32/esp + 6153 # setup + 6154 (clear-stream _test-input-stream) + 6155 (clear-stream $_test-input-buffered-file->buffer) + 6156 (clear-stream _test-output-stream) + 6157 (clear-stream $_test-output-buffered-file->buffer) + 6158 (clear-stream _test-error-stream) + 6159 (clear-stream $_test-error-buffered-file->buffer) + 6160 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 6161 68/push 0/imm32 + 6162 68/push 0/imm32 + 6163 89/<- %edx 4/r32/esp + 6164 (tailor-exit-descriptor %edx 0x10) + 6165 # + 6166 (write _test-input-stream "fn foo {\n") + 6167 (write _test-input-stream " var a: t\n") + 6168 (write _test-input-stream " var b: int\n") + 6169 (write _test-input-stream " var c/eax: (addr int) <- copy 0\n") + 6170 (write _test-input-stream " c, b <- get a, x\n") + 6171 (write _test-input-stream "}\n") + 6172 (write _test-input-stream "type t {\n") + 6173 (write _test-input-stream " x: int\n") + 6174 (write _test-input-stream "}\n") + 6175 # convert + 6176 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 6177 # registers except esp clobbered at this point + 6178 # restore ed + 6179 89/<- %edx 4/r32/esp + 6180 (flush _test-output-buffered-file) + 6181 (flush _test-error-buffered-file) + 6182 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 6188 # check output + 6189 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-outputs: output should be empty") + 6190 (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") + 6191 # check that stop(1) was called + 6192 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-outputs: exit status") + 6193 # don't restore from ebp + 6194 81 0/subop/add %esp 8/imm32 + 6195 # . epilogue + 6196 5d/pop-to-ebp + 6197 c3/return + 6198 + 6199 test-convert-array-of-user-defined-types: + 6200 # . prologue + 6201 55/push-ebp + 6202 89/<- %ebp 4/r32/esp + 6203 # setup + 6204 (clear-stream _test-input-stream) + 6205 (clear-stream $_test-input-buffered-file->buffer) + 6206 (clear-stream _test-output-stream) + 6207 (clear-stream $_test-output-buffered-file->buffer) + 6208 # + 6209 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 + 6210 (write _test-input-stream " x: int\n") + 6211 (write _test-input-stream " y: int\n") + 6212 (write _test-input-stream "}\n") + 6213 (write _test-input-stream "fn foo {\n") + 6214 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 6215 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 6216 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 6217 (write _test-input-stream "}\n") + 6218 # convert + 6219 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6220 (flush _test-output-buffered-file) + 6221 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6227 # check output + 6228 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-array-of-user-defined-types/0") + 6229 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-array-of-user-defined-types/1") + 6230 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-array-of-user-defined-types/2") + 6231 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-array-of-user-defined-types/3") + 6232 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-array-of-user-defined-types/4") + 6233 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-array-of-user-defined-types/5") + 6234 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-array-of-user-defined-types/6") + 6235 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-array-of-user-defined-types/7") + 6236 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-array-of-user-defined-types/8") + 6237 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-array-of-user-defined-types/9") + 6238 (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/11") + 6239 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-array-of-user-defined-types/13") + 6240 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-array-of-user-defined-types/14") + 6241 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-array-of-user-defined-types/15") + 6242 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-array-of-user-defined-types/16") + 6243 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-array-of-user-defined-types/17") + 6244 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-array-of-user-defined-types/18") + 6245 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-array-of-user-defined-types/19") + 6246 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-array-of-user-defined-types/20") + 6247 # . epilogue + 6248 89/<- %esp 5/r32/ebp + 6249 5d/pop-to-ebp + 6250 c3/return + 6251 + 6252 test-convert-length-of-array-of-user-defined-types-to-eax: + 6253 # . prologue + 6254 55/push-ebp + 6255 89/<- %ebp 4/r32/esp + 6256 # setup + 6257 (clear-stream _test-input-stream) + 6258 (clear-stream $_test-input-buffered-file->buffer) + 6259 (clear-stream _test-output-stream) + 6260 (clear-stream $_test-output-buffered-file->buffer) + 6261 # + 6262 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 + 6263 (write _test-input-stream " x: int\n") + 6264 (write _test-input-stream " y: int\n") + 6265 (write _test-input-stream " z: int\n") + 6266 (write _test-input-stream "}\n") + 6267 (write _test-input-stream "fn foo {\n") + 6268 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 6269 (write _test-input-stream " var x/eax: (addr t) <- length arr\n") + 6270 (write _test-input-stream "}\n") + 6271 # convert + 6272 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6273 (flush _test-output-buffered-file) + 6274 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6280 # check output + 6281 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/0") + 6282 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/1") + 6283 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/2") + 6284 (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") + 6285 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-eax/4") + 6286 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/5") + 6287 # var arr + 6288 (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") + 6289 (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") + 6290 # length instruction + 6291 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/8") + 6292 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/9") + 6293 (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") + 6294 (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") + 6295 (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") + 6296 (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") + 6297 (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") + 6298 (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") + 6299 # reclaim arr + 6300 (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") + 6301 # + 6302 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-eax/17") + 6303 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/18") + 6304 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/19") + 6305 (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") + 6306 (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") + 6307 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-eax/22") + 6308 # . epilogue + 6309 89/<- %esp 5/r32/ebp + 6310 5d/pop-to-ebp + 6311 c3/return + 6312 + 6313 test-convert-length-of-array-of-user-defined-types-to-ecx: + 6314 # . prologue + 6315 55/push-ebp + 6316 89/<- %ebp 4/r32/esp + 6317 # setup + 6318 (clear-stream _test-input-stream) + 6319 (clear-stream $_test-input-buffered-file->buffer) + 6320 (clear-stream _test-output-stream) + 6321 (clear-stream $_test-output-buffered-file->buffer) + 6322 # + 6323 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 + 6324 (write _test-input-stream " x: int\n") + 6325 (write _test-input-stream " y: int\n") + 6326 (write _test-input-stream " z: int\n") + 6327 (write _test-input-stream "}\n") + 6328 (write _test-input-stream "fn foo {\n") + 6329 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 6330 (write _test-input-stream " var x/ecx: (addr t) <- length arr\n") + 6331 (write _test-input-stream "}\n") + 6332 # convert + 6333 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6334 (flush _test-output-buffered-file) + 6335 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6341 # check output + 6342 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/0") + 6343 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/1") + 6344 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/2") + 6345 (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") + 6346 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/4") + 6347 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/5") + 6348 # var a + 6349 (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") + 6350 (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") + 6351 # var x + 6352 (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") + 6353 # length instruction + 6354 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/9") + 6355 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/10") + 6356 (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") + 6357 (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") + 6358 (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") + 6359 (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") + 6360 (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") + 6361 (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") + 6362 (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") + 6363 # reclaim x + 6364 (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") + 6365 # reclaim a + 6366 (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") + 6367 # + 6368 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/20") + 6369 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/21") + 6370 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/22") + 6371 (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") + 6372 (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") + 6373 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/25") + 6374 # . epilogue + 6375 89/<- %esp 5/r32/ebp + 6376 5d/pop-to-ebp + 6377 c3/return + 6378 + 6379 test-convert-length-of-array-of-user-defined-types-to-edx: + 6380 # . prologue + 6381 55/push-ebp + 6382 89/<- %ebp 4/r32/esp + 6383 # setup + 6384 (clear-stream _test-input-stream) + 6385 (clear-stream $_test-input-buffered-file->buffer) + 6386 (clear-stream _test-output-stream) + 6387 (clear-stream $_test-output-buffered-file->buffer) + 6388 # + 6389 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 + 6390 (write _test-input-stream " x: int\n") + 6391 (write _test-input-stream " y: int\n") + 6392 (write _test-input-stream " z: int\n") + 6393 (write _test-input-stream "}\n") + 6394 (write _test-input-stream "fn foo {\n") + 6395 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 6396 (write _test-input-stream " var x/edx: (addr t) <- length arr\n") + 6397 (write _test-input-stream "}\n") + 6398 # convert + 6399 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6400 (flush _test-output-buffered-file) + 6401 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6407 # check output + 6408 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/0") + 6409 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/1") + 6410 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/2") + 6411 (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") + 6412 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-edx/4") + 6413 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/5") + 6414 # var a + 6415 (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") + 6416 (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") + 6417 # var x + 6418 (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") + 6419 # length instruction + 6420 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/9") + 6421 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/10") + 6422 (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") + 6423 (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") + 6424 (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") + 6425 (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") + 6426 (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") + 6427 (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") + 6428 (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") + 6429 # reclaim x + 6430 (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") + 6431 # reclaim a + 6432 (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") + 6433 # + 6434 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-edx/20") + 6435 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/21") + 6436 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/22") + 6437 (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") + 6438 (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") + 6439 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-edx/25") + 6440 # . epilogue + 6441 89/<- %esp 5/r32/ebp + 6442 5d/pop-to-ebp + 6443 c3/return + 6444 + 6445 test-convert-length-of-array-of-user-defined-types: + 6446 # . prologue + 6447 55/push-ebp + 6448 89/<- %ebp 4/r32/esp + 6449 # setup + 6450 (clear-stream _test-input-stream) + 6451 (clear-stream $_test-input-buffered-file->buffer) + 6452 (clear-stream _test-output-stream) + 6453 (clear-stream $_test-output-buffered-file->buffer) + 6454 # + 6455 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 + 6456 (write _test-input-stream " x: int\n") + 6457 (write _test-input-stream " y: int\n") + 6458 (write _test-input-stream " z: int\n") + 6459 (write _test-input-stream "}\n") + 6460 (write _test-input-stream "fn foo {\n") + 6461 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 6462 (write _test-input-stream " var x/ebx: (addr t) <- length arr\n") + 6463 (write _test-input-stream "}\n") + 6464 # convert + 6465 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 6466 (flush _test-output-buffered-file) + 6467 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 6473 # check output + 6474 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types/0") + 6475 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types/1") + 6476 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types/2") + 6477 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types/3") + 6478 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types/4") + 6479 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types/5") + 6480 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types/6") + 6481 (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") + 6482 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-length-of-array-of-user-defined-types/8") + 6483 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types/9") + 6484 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types/10") + 6485 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types/11") + 6486 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types/12") + 6487 (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") + 6488 (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") + 6489 (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") + 6490 (check-next-stream-line-equal _test-output-stream " 89/<- %ebx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types/16") + 6491 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types/17") + 6492 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types/18") + 6493 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types/19") + 6494 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ebx" "F - test-convert-length-of-array-of-user-defined-types/20") + 6495 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types/21") + 6496 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types/22") + 6497 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types/23") + 6498 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types/24") + 6499 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types/25") + 6500 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types/26") + 6501 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types/27") + 6502 # . epilogue + 6503 89/<- %esp 5/r32/ebp + 6504 5d/pop-to-ebp + 6505 c3/return + 6506 + 6507 ####################################################### + 6508 # Parsing + 6509 ####################################################### + 6510 + 6511 == data + 6512 + 6513 # Global state added to each var record when parsing a function + 6514 Next-block-index: # (addr int) + 6515 1/imm32 + 6516 + 6517 Curr-block-depth: # (addr int) + 6518 1/imm32 + 6519 + 6520 == code + 6521 + 6522 parse-mu: # in: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) + 6523 # pseudocode + 6524 # var curr-function: (addr handle function) = Program->functions + 6525 # var curr-signature: (addr handle function) = Program->signatures + 6526 # var curr-type: (addr handle typeinfo) = Program->types + 6527 # var line: (stream byte 512) + 6528 # var word-slice: slice + 6529 # while true # line loop + 6530 # clear-stream(line) + 6531 # read-line-buffered(in, line) + 6532 # if (line->write == 0) break # end of file + 6533 # word-slice = next-mu-token(line) + 6534 # if slice-empty?(word-slice) # end of line + 6535 # continue + 6536 # else if slice-starts-with?(word-slice, "#") # comment + 6537 # continue # end of line + 6538 # else if slice-equal?(word-slice, "fn") + 6539 # var new-function: (handle function) = allocate(function) + 6540 # var vars: (stack live-var 256) + 6541 # populate-mu-function-header(line, new-function, vars) + 6542 # populate-mu-function-body(in, new-function, vars) + 6543 # assert(vars->top == 0) + 6544 # *curr-function = new-function + 6545 # curr-function = &new-function->next + 6546 # else if slice-equal?(word-slice, "sig") + 6547 # var new-function: (handle function) = allocate(function) + 6548 # populate-mu-function-signature(line, new-function) + 6549 # *curr-signature = new-function + 6550 # curr-signature = &new-function->next + 6551 # else if slice-equal?(word-slice, "type") + 6552 # word-slice = next-mu-token(line) + 6553 # type-id = pos-or-insert-slice(Type-id, word-slice) + 6554 # var new-type: (handle typeinfo) = find-or-create-typeinfo(type-id) + 6555 # assert(next-word(line) == "{") + 6556 # populate-mu-type(in, new-type) + 6557 # else + 6558 # abort() + 6559 # + 6560 # . prologue + 6561 55/push-ebp + 6562 89/<- %ebp 4/r32/esp + 6563 # var curr-signature: (addr handle function) at *(ebp-4) + 6564 68/push _Program-signatures/imm32 + 6565 # . save registers + 6566 50/push-eax + 6567 51/push-ecx + 6568 52/push-edx + 6569 53/push-ebx + 6570 56/push-esi + 6571 57/push-edi + 6572 # var line/ecx: (stream byte 512) + 6573 81 5/subop/subtract %esp 0x200/imm32 + 6574 68/push 0x200/imm32/size + 6575 68/push 0/imm32/read + 6576 68/push 0/imm32/write + 6577 89/<- %ecx 4/r32/esp + 6578 # var word-slice/edx: slice + 6579 68/push 0/imm32/end + 6580 68/push 0/imm32/start + 6581 89/<- %edx 4/r32/esp + 6582 # var curr-function/edi: (addr handle function) + 6583 bf/copy-to-edi _Program-functions/imm32 + 6584 # var vars/ebx: (stack live-var 256) + 6585 81 5/subop/subtract %esp 0xc00/imm32 + 6586 68/push 0xc00/imm32/size + 6587 68/push 0/imm32/top + 6588 89/<- %ebx 4/r32/esp + 6589 { + 6590 $parse-mu:line-loop: + 6591 (clear-stream %ecx) + 6592 (read-line-buffered *(ebp+8) %ecx) + 6593 # if (line->write == 0) break + 6594 81 7/subop/compare *ecx 0/imm32 + 6595 0f 84/jump-if-= break/disp32 + 6596 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ + 6602 (next-mu-token %ecx %edx) + 6603 # if slice-empty?(word-slice) continue + 6604 (slice-empty? %edx) # => eax + 6605 3d/compare-eax-and 0/imm32/false + 6606 0f 85/jump-if-!= loop/disp32 + 6607 # if (*word-slice->start == "#") continue + 6608 # . eax = *word-slice->start + 6609 8b/-> *edx 0/r32/eax + 6610 8a/copy-byte *eax 0/r32/AL + 6611 81 4/subop/and %eax 0xff/imm32 + 6612 # . if (eax == '#') continue + 6613 3d/compare-eax-and 0x23/imm32/hash + 6614 0f 84/jump-if-= loop/disp32 + 6615 # if (slice-equal?(word-slice, "fn")) parse a function + 6616 { + 6617 $parse-mu:fn: + 6618 (slice-equal? %edx "fn") # => eax + 6619 3d/compare-eax-and 0/imm32/false + 6620 0f 84/jump-if-= break/disp32 + 6621 # var new-function/esi: (handle function) + 6622 68/push 0/imm32 + 6623 68/push 0/imm32 + 6624 89/<- %esi 4/r32/esp + 6625 # populate-mu-function(line, in, vars, new-function) + 6626 (allocate Heap *Function-size %esi) + 6627 # var new-function-addr/eax: (addr function) + 6628 (lookup *esi *(esi+4)) # => eax + 6629 # initialize vars + 6630 (clear-stack %ebx) + 6631 # + 6632 (populate-mu-function-header %ecx %eax %ebx *(ebp+0xc) *(ebp+0x10)) + 6633 (populate-mu-function-body *(ebp+8) %eax %ebx *(ebp+0xc) *(ebp+0x10)) + 6634 # *curr-function = new-function + 6635 8b/-> *esi 0/r32/eax + 6636 89/<- *edi 0/r32/eax + 6637 8b/-> *(esi+4) 0/r32/eax + 6638 89/<- *(edi+4) 0/r32/eax + 6639 # curr-function = &new-function->next + 6640 # . var tmp/eax: (addr function) = lookup(new-function) + 6641 (lookup *esi *(esi+4)) # => eax + 6642 # . curr-function = &tmp->next + 6643 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next + 6644 # reclaim new-function + 6645 81 0/subop/add %esp 8/imm32 + 6646 # + 6647 e9/jump $parse-mu:line-loop/disp32 + 6648 } + 6649 # if (slice-equal?(word-slice, "sig")) parse a function signature + 6650 # Function signatures are for providing types to SubX functions. + 6651 { + 6652 $parse-mu:sig: + 6653 (slice-equal? %edx "sig") # => eax + 6654 3d/compare-eax-and 0/imm32/false + 6655 0f 84/jump-if-= break/disp32 + 6656 # edi = curr-function + 6657 57/push-edi + 6658 8b/-> *(ebp-4) 7/r32/edi + 6659 # var new-function/esi: (handle function) + 6660 68/push 0/imm32 + 6661 68/push 0/imm32 + 6662 89/<- %esi 4/r32/esp + 6663 # populate-mu-function(line, in, vars, new-function) + 6664 (allocate Heap *Function-size %esi) + 6665 # var new-function-addr/eax: (addr function) + 6666 (lookup *esi *(esi+4)) # => eax + 6667 # + 6668 (populate-mu-function-signature %ecx %eax *(ebp+0xc) *(ebp+0x10)) + 6669 # *curr-signature = new-function + 6670 8b/-> *esi 0/r32/eax + 6671 89/<- *edi 0/r32/eax + 6672 8b/-> *(esi+4) 0/r32/eax + 6673 89/<- *(edi+4) 0/r32/eax + 6674 # curr-signature = &new-function->next + 6675 # . var tmp/eax: (addr function) = lookup(new-function) + 6676 (lookup *esi *(esi+4)) # => eax + 6677 # . curr-function = &tmp->next + 6678 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next + 6679 # reclaim new-function + 6680 81 0/subop/add %esp 8/imm32 + 6681 # save curr-function + 6682 89/<- *(ebp-4) 7/r32/edi + 6683 # restore edi + 6684 5f/pop-to-edi + 6685 # + 6686 e9/jump $parse-mu:line-loop/disp32 + 6687 } + 6688 # if (slice-equal?(word-slice, "type")) parse a type (struct/record) definition + 6689 { + 6690 $parse-mu:type: + 6691 (slice-equal? %edx "type") # => eax + 6692 3d/compare-eax-and 0/imm32 + 6693 0f 84/jump-if-= break/disp32 + 6694 (next-mu-token %ecx %edx) + 6695 # var type-id/eax: int + 6696 (pos-or-insert-slice Type-id %edx) # => eax + 6697 # spill + 6698 51/push-ecx + 6699 # var new-type/ecx: (handle typeinfo) + 6700 68/push 0/imm32 + 6701 68/push 0/imm32 + 6702 89/<- %ecx 4/r32/esp + 6703 (find-or-create-typeinfo %eax %ecx) + 6704 # + 6705 (lookup *ecx *(ecx+4)) # => eax + 6706 # TODO: ensure that 'line' has nothing else but '{' + 6707 #? (dump-typeinfos "=== aaa\n") + 6708 (populate-mu-type *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) # => eax + 6709 #? (dump-typeinfos "=== zzz\n") + 6710 # reclaim new-type + 6711 81 0/subop/add %esp 8/imm32 + 6712 # restore + 6713 59/pop-to-ecx + 6714 e9/jump $parse-mu:line-loop/disp32 + 6715 } + 6716 # otherwise abort + 6717 e9/jump $parse-mu:error1/disp32 + 6718 } # end line loop + 6719 $parse-mu:end: + 6720 # . reclaim locals + 6721 81 0/subop/add %esp 0x20c/imm32 # line + 6722 81 0/subop/add %esp 0xc08/imm32 # vars + 6723 81 0/subop/add %esp 8/imm32 + 6724 # . restore registers + 6725 5f/pop-to-edi + 6726 5e/pop-to-esi + 6727 5b/pop-to-ebx + 6728 5a/pop-to-edx + 6729 59/pop-to-ecx + 6730 58/pop-to-eax + 6731 # . reclaim local + 6732 81 0/subop/add %esp 4/imm32 + 6733 # . epilogue + 6734 89/<- %esp 5/r32/ebp + 6735 5d/pop-to-ebp + 6736 c3/return + 6737 + 6738 $parse-mu:error1: + 6739 # error("unexpected top-level command: " word-slice "\n") + 6740 (write-buffered *(ebp+0xc) "unexpected top-level command: ") + 6741 (write-slice-buffered *(ebp+0xc) %edx) + 6742 (write-buffered *(ebp+0xc) "\n") + 6743 (flush *(ebp+0xc)) + 6744 (stop *(ebp+0x10) 1) + 6745 # never gets here + 6746 + 6747 $parse-mu:error2: + 6748 # error(vars->top " vars not reclaimed after fn '" new-function->name "'\n") + 6749 (write-int32-hex-buffered *(ebp+0xc) *ebx) + 6750 (write-buffered *(ebp+0xc) " vars not reclaimed after fn '") + 6751 (write-slice-buffered *(ebp+0xc) *eax) # Function-name + 6752 (write-buffered *(ebp+0xc) "'\n") + 6753 (flush *(ebp+0xc)) + 6754 (stop *(ebp+0x10) 1) + 6755 # never gets here + 6756 + 6757 # scenarios considered: + 6758 # ✗ fn foo # no block + 6759 # ✓ fn foo { + 6760 # ✗ fn foo { { + 6761 # ✗ fn foo { } + 6762 # ✗ fn foo { } { + 6763 # ✗ fn foo x { + 6764 # ✗ fn foo x: { + 6765 # ✓ fn foo x: int { + 6766 # ✓ fn foo x: int { + 6767 # ✓ fn foo x: int -> y/eax: int { + 6768 # TODO: + 6769 # disallow outputs of type `(... addr ...)` + 6770 # disallow inputs of type `(... addr ... addr ...)` + 6771 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) + 6772 # pseudocode: + 6773 # var word-slice: slice + 6774 # next-mu-token(first-line, word-slice) + 6775 # assert(word-slice not in '{' '}' '->') + 6776 # out->name = slice-to-string(word-slice) + 6777 # ## inouts + 6778 # while true + 6779 # word-slice = next-mu-token(first-line) + 6780 # if (word-slice == '{') goto done + 6781 # if (word-slice == '->') break + 6782 # assert(word-slice != '}') + 6783 # var v: (handle var) = parse-var-with-type(word-slice, first-line) + 6784 # assert(v->register == null) + 6785 # # v->block-depth is implicitly 0 + 6786 # out->inouts = append(v, out->inouts) + 6787 # push(vars, {v, false}) + 6788 # ## outputs + 6789 # while true + 6790 # word-slice = next-mu-token(first-line) + 6791 # if (word-slice == '{') break + 6792 # assert(word-slice not in '}' '->') + 6793 # var v: (handle var) = parse-var-with-type(word-slice, first-line) + 6794 # assert(v->register != null) + 6795 # out->outputs = append(v, out->outputs) + 6796 # done: + 6797 # + 6798 # . prologue + 6799 55/push-ebp + 6800 89/<- %ebp 4/r32/esp + 6801 # . save registers + 6802 50/push-eax + 6803 51/push-ecx + 6804 52/push-edx + 6805 53/push-ebx + 6806 57/push-edi + 6807 # edi = out + 6808 8b/-> *(ebp+0xc) 7/r32/edi + 6809 # var word-slice/ecx: slice + 6810 68/push 0/imm32/end + 6811 68/push 0/imm32/start + 6812 89/<- %ecx 4/r32/esp + 6813 # var v/ebx: (handle var) + 6814 68/push 0/imm32 + 6815 68/push 0/imm32 + 6816 89/<- %ebx 4/r32/esp + 6817 # read function name + 6818 (next-mu-token *(ebp+8) %ecx) + 6819 # error checking + 6820 # if (word-slice == '{') abort + 6821 (slice-equal? %ecx "{") # => eax + 6822 3d/compare-eax-and 0/imm32/false + 6823 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 6824 # if (word-slice == '->') abort + 6825 (slice-equal? %ecx "->") # => eax + 6826 3d/compare-eax-and 0/imm32/false + 6827 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 6828 # if (word-slice == '}') abort + 6829 (slice-equal? %ecx "}") # => eax + 6830 3d/compare-eax-and 0/imm32/false + 6831 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 6832 # save function name + 6833 (slice-to-string Heap %ecx %edi) # Function-name + 6834 # save function inouts + 6835 { + 6836 $populate-mu-function-header:check-for-inout: + 6837 (next-mu-token *(ebp+8) %ecx) + 6838 # if (word-slice == '{') goto done + 6839 (slice-equal? %ecx "{") # => eax + 6840 3d/compare-eax-and 0/imm32/false + 6841 0f 85/jump-if-!= $populate-mu-function-header:done/disp32 + 6842 # if (word-slice == '->') break + 6843 (slice-equal? %ecx "->") # => eax + 6844 3d/compare-eax-and 0/imm32/false + 6845 0f 85/jump-if-!= break/disp32 + 6846 # if (word-slice == '}') abort + 6847 (slice-equal? %ecx "}") # => eax + 6848 3d/compare-eax-and 0/imm32/false + 6849 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 6850 # v = parse-var-with-type(word-slice, first-line) + 6851 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x14) *(ebp+0x18)) + 6852 # assert(v->register == null) + 6853 # . eax: (addr var) = lookup(v) + 6854 (lookup *ebx *(ebx+4)) # => eax + 6855 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 6856 0f 85/jump-if-!= $populate-mu-function-header:error2/disp32 + 6857 # v->block-depth is implicitly 0 + 6858 # + 6859 # out->inouts = append(v, out->inouts) + 6860 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts + 6861 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts + 6862 # push(vars, {v, false}) + 6863 (push *(ebp+0x10) *ebx) + 6864 (push *(ebp+0x10) *(ebx+4)) + 6865 (push *(ebp+0x10) 0) # false + 6866 # + 6867 e9/jump loop/disp32 + 6868 } + 6869 # save function outputs + 6870 { + 6871 $populate-mu-function-header:check-for-out: + 6872 (next-mu-token *(ebp+8) %ecx) + 6873 # if (word-slice == '{') break + 6874 (slice-equal? %ecx "{") # => eax + 6875 3d/compare-eax-and 0/imm32/false + 6876 0f 85/jump-if-!= break/disp32 + 6877 # if (word-slice == '->') abort + 6878 (slice-equal? %ecx "->") # => eax + 6879 3d/compare-eax-and 0/imm32/false + 6880 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 6881 # if (word-slice == '}') abort + 6882 (slice-equal? %ecx "}") # => eax + 6883 3d/compare-eax-and 0/imm32/false + 6884 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 6885 # v = parse-var-with-type(word-slice, first-line) + 6886 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x14) *(ebp+0x18)) + 6887 # assert(var->register != null) + 6888 # . eax: (addr var) = lookup(v) + 6889 (lookup *ebx *(ebx+4)) # => eax + 6890 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 6891 0f 84/jump-if-= $populate-mu-function-header:error3/disp32 + 6892 # out->outputs = append(v, out->outputs) + 6893 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs + 6894 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs + 6895 # + 6896 e9/jump loop/disp32 + 6897 } + 6898 $populate-mu-function-header:done: + 6899 (check-no-tokens-left *(ebp+8)) + 6900 $populate-mu-function-header:end: + 6901 # . reclaim locals + 6902 81 0/subop/add %esp 0x10/imm32 + 6903 # . restore registers + 6904 5f/pop-to-edi + 6905 5b/pop-to-ebx + 6906 5a/pop-to-edx + 6907 59/pop-to-ecx + 6908 58/pop-to-eax + 6909 # . epilogue + 6910 89/<- %esp 5/r32/ebp + 6911 5d/pop-to-ebp + 6912 c3/return + 6913 + 6914 $populate-mu-function-header:error1: + 6915 # error("function header not in form 'fn <name> {'") + 6916 (write-buffered *(ebp+0x14) "function header not in form 'fn <name> [inouts] [-> outputs] {' -- '") + 6917 (flush *(ebp+0x14)) + 6918 (rewind-stream *(ebp+8)) + 6919 (write-stream-data *(ebp+0x14) *(ebp+8)) + 6920 (write-buffered *(ebp+0x14) "'\n") + 6921 (flush *(ebp+0x14)) + 6922 (stop *(ebp+0x18) 1) + 6923 # never gets here + 6924 + 6925 $populate-mu-function-header:error2: + 6926 # error("fn " fn ": function inout '" var "' cannot be in a register") + 6927 (write-buffered *(ebp+0x14) "fn ") + 6928 50/push-eax + 6929 (lookup *edi *(edi+4)) # Function-name Function-name => eax + 6930 (write-buffered *(ebp+0x14) %eax) + 6931 58/pop-to-eax + 6932 (write-buffered *(ebp+0x14) ": function inout '") + 6933 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 6934 (write-buffered *(ebp+0x10) %eax) + 6935 (write-buffered *(ebp+0x14) "' cannot be in a register") + 6936 (flush *(ebp+0x14)) + 6937 (stop *(ebp+0x18) 1) + 6938 # never gets here + 6939 + 6940 $populate-mu-function-header:error3: + 6941 # error("fn " fn ": function output '" var "' must be in a register") + 6942 (write-buffered *(ebp+0x14) "fn ") + 6943 50/push-eax + 6944 (lookup *edi *(edi+4)) # Function-name Function-name => eax + 6945 (write-buffered *(ebp+0x14) %eax) + 6946 58/pop-to-eax + 6947 (write-buffered *(ebp+0x14) ": function output '") + 6948 (lookup *ebx *(ebx+4)) # => eax + 6949 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 6950 (write-buffered *(ebp+0x14) %eax) + 6951 (write-buffered *(ebp+0x14) "' must be in a register, in instruction '") + 6952 (rewind-stream *(ebp+8)) + 6953 (write-stream-data *(ebp+0x14) *(ebp+8)) + 6954 (write-buffered *(ebp+0x14) "'\n") + 6955 (flush *(ebp+0x14)) + 6956 (stop *(ebp+0x18) 1) + 6957 # never gets here + 6958 + 6959 # scenarios considered: + 6960 # ✓ fn foo + 6961 # ✗ fn foo { + 6962 # ✓ fn foo x + 6963 # ✓ fn foo x: int + 6964 # ✓ fn foo x: int -> y/eax: int + 6965 # TODO: + 6966 # disallow outputs of type `(... addr ...)` + 6967 # disallow inputs of type `(... addr ... addr ...)` + 6968 populate-mu-function-signature: # first-line: (addr stream byte), out: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) + 6969 # pseudocode: + 6970 # var word-slice: slice + 6971 # next-mu-token(first-line, word-slice) + 6972 # assert(word-slice not in '{' '}' '->') + 6973 # out->name = slice-to-string(word-slice) + 6974 # ## inouts + 6975 # while true + 6976 # word-slice = next-mu-token(first-line) + 6977 # if slice-empty?(word-slice) break + 6978 # if (word-slice == '->') break + 6979 # assert(word-slice not in '{' '}') + 6980 # var v: (handle var) = parse-var-with-type(word-slice, first-line) + 6981 # assert(v->register == null) + 6982 # # v->block-depth is implicitly 0 + 6983 # out->inouts = append(v, out->inouts) + 6984 # ## outputs + 6985 # while true + 6986 # word-slice = next-mu-token(first-line) + 6987 # if slice-empty?(word-slice) break + 6988 # assert(word-slice not in '{' '}' '->') + 6989 # var v: (handle var) = parse-var-with-type(word-slice, first-line) + 6990 # assert(v->register != null) + 6991 # out->outputs = append(v, out->outputs) + 6992 # + 6993 # . prologue + 6994 55/push-ebp + 6995 89/<- %ebp 4/r32/esp + 6996 # . save registers + 6997 50/push-eax + 6998 51/push-ecx + 6999 52/push-edx + 7000 53/push-ebx + 7001 57/push-edi + 7002 # edi = out + 7003 8b/-> *(ebp+0xc) 7/r32/edi + 7004 # var word-slice/ecx: slice + 7005 68/push 0/imm32/end + 7006 68/push 0/imm32/start + 7007 89/<- %ecx 4/r32/esp + 7008 # var v/ebx: (handle var) + 7009 68/push 0/imm32 + 7010 68/push 0/imm32 + 7011 89/<- %ebx 4/r32/esp + 7012 # read function name + 7013 (next-mu-token *(ebp+8) %ecx) + 7014 # error checking + 7015 # if (word-slice == '{') abort + 7016 (slice-equal? %ecx "{") # => eax + 7017 3d/compare-eax-and 0/imm32/false + 7018 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 7019 # if (word-slice == '->') abort + 7020 (slice-equal? %ecx "->") # => eax + 7021 3d/compare-eax-and 0/imm32/false + 7022 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 7023 # if (word-slice == '}') abort + 7024 (slice-equal? %ecx "}") # => eax + 7025 3d/compare-eax-and 0/imm32/false + 7026 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 7027 # save function name + 7028 (slice-to-string Heap %ecx %edi) # Function-name + 7029 # save function inouts + 7030 { + 7031 $populate-mu-function-signature:check-for-inout: + 7032 (next-mu-token *(ebp+8) %ecx) + 7033 (slice-empty? %ecx) # => eax + 7034 3d/compare-eax-and 0/imm32/false + 7035 0f 85/jump-if-!= break/disp32 + 7036 # if (word-slice == '->') break + 7037 (slice-equal? %ecx "->") # => eax + 7038 3d/compare-eax-and 0/imm32/false + 7039 0f 85/jump-if-!= break/disp32 + 7040 # if (word-slice == '{') abort + 7041 (slice-equal? %ecx "{") # => eax + 7042 3d/compare-eax-and 0/imm32/false + 7043 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 7044 # if (word-slice == '}') abort + 7045 (slice-equal? %ecx "}") # => eax + 7046 3d/compare-eax-and 0/imm32/false + 7047 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 7048 # v = parse-var-with-type(word-slice, first-line) + 7049 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x10) *(ebp+0x14)) + 7050 # assert(v->register == null) + 7051 # . eax: (addr var) = lookup(v) + 7052 (lookup *ebx *(ebx+4)) # => eax + 7053 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 7054 0f 85/jump-if-!= $populate-mu-function-signature:error2/disp32 + 7055 # v->block-depth is implicitly 0 + 7056 # + 7057 # out->inouts = append(v, out->inouts) + 7058 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts + 7059 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts + 7060 # + 7061 e9/jump loop/disp32 + 7062 } + 7063 # save function outputs + 7064 { + 7065 $populate-mu-function-signature:check-for-out: + 7066 (next-mu-token *(ebp+8) %ecx) + 7067 (slice-empty? %ecx) # => eax + 7068 3d/compare-eax-and 0/imm32/false + 7069 0f 85/jump-if-!= break/disp32 + 7070 # if (word-slice == '{') abort + 7071 (slice-equal? %ecx "{") # => eax + 7072 3d/compare-eax-and 0/imm32/false + 7073 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 7074 # if (word-slice == '->') abort + 7075 (slice-equal? %ecx "->") # => eax + 7076 3d/compare-eax-and 0/imm32/false + 7077 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 7078 # if (word-slice == '}') abort + 7079 (slice-equal? %ecx "}") # => eax + 7080 3d/compare-eax-and 0/imm32/false + 7081 0f 85/jump-if-!= $populate-mu-function-signature:error1/disp32 + 7082 # v = parse-var-with-type(word-slice, first-line) + 7083 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x10) *(ebp+0x14)) + 7084 # assert(var->register != null) + 7085 # . eax: (addr var) = lookup(v) + 7086 (lookup *ebx *(ebx+4)) # => eax + 7087 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 7088 0f 84/jump-if-= $populate-mu-function-signature:error3/disp32 + 7089 # out->outputs = append(v, out->outputs) + 7090 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs + 7091 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs + 7092 # + 7093 e9/jump loop/disp32 + 7094 } + 7095 $populate-mu-function-signature:done: + 7096 (check-no-tokens-left *(ebp+8)) + 7097 $populate-mu-function-signature:end: + 7098 # . reclaim locals + 7099 81 0/subop/add %esp 0x10/imm32 + 7100 # . restore registers + 7101 5f/pop-to-edi + 7102 5b/pop-to-ebx + 7103 5a/pop-to-edx + 7104 59/pop-to-ecx + 7105 58/pop-to-eax + 7106 # . epilogue + 7107 89/<- %esp 5/r32/ebp + 7108 5d/pop-to-ebp + 7109 c3/return + 7110 + 7111 $populate-mu-function-signature:error1: + 7112 # error("function signature not in form 'fn <name> {'") + 7113 (write-buffered *(ebp+0x10) "function signature not in form 'fn <name> [inouts] [-> outputs] {' -- '") + 7114 (flush *(ebp+0x10)) + 7115 (rewind-stream *(ebp+8)) + 7116 (write-stream-data *(ebp+0x10) *(ebp+8)) + 7117 (write-buffered *(ebp+0x10) "'\n") + 7118 (flush *(ebp+0x10)) + 7119 (stop *(ebp+0x14) 1) + 7120 # never gets here + 7121 + 7122 $populate-mu-function-signature:error2: + 7123 # error("fn " fn ": function inout '" var "' cannot be in a register") + 7124 (write-buffered *(ebp+0x10) "fn ") + 7125 50/push-eax + 7126 (lookup *edi *(edi+4)) # Function-name Function-name => eax + 7127 (write-buffered *(ebp+0x10) %eax) + 7128 58/pop-to-eax + 7129 (write-buffered *(ebp+0x10) ": function inout '") + 7130 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 7131 (write-buffered *(ebp+0x10) %eax) + 7132 (write-buffered *(ebp+0x10) "' cannot be in a register") + 7133 (flush *(ebp+0x10)) + 7134 (stop *(ebp+0x14) 1) + 7135 # never gets here + 7136 + 7137 $populate-mu-function-signature:error3: + 7138 # error("fn " fn ": function output '" var "' must be in a register") + 7139 (write-buffered *(ebp+0x10) "fn ") + 7140 50/push-eax + 7141 (lookup *edi *(edi+4)) # Function-name Function-name => eax + 7142 (write-buffered *(ebp+0x10) %eax) + 7143 58/pop-to-eax + 7144 (write-buffered *(ebp+0x10) ": function output '") + 7145 (lookup *ebx *(ebx+4)) # => eax + 7146 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 7147 (write-buffered *(ebp+0x10) %eax) + 7148 (write-buffered *(ebp+0x10) "' must be in a register, in instruction '") + 7149 (rewind-stream *(ebp+8)) + 7150 (write-stream-data *(ebp+0x10) *(ebp+8)) + 7151 (write-buffered *(ebp+0x10) "'\n") + 7152 (flush *(ebp+0x10)) + 7153 (stop *(ebp+0x14) 1) + 7154 # never gets here + 7155 + 7156 test-function-header-with-arg: + 7157 # . prologue + 7158 55/push-ebp + 7159 89/<- %ebp 4/r32/esp + 7160 # setup + 7161 (clear-stream _test-input-stream) + 7162 (write _test-input-stream "foo n: int {\n") + 7163 # var result/ecx: function + 7164 2b/subtract *Function-size 4/r32/esp + 7165 89/<- %ecx 4/r32/esp + 7166 (zero-out %ecx *Function-size) + 7167 # var vars/ebx: (stack live-var 16) + 7168 81 5/subop/subtract %esp 0xc0/imm32 + 7169 68/push 0xc0/imm32/size + 7170 68/push 0/imm32/top + 7171 89/<- %ebx 4/r32/esp + 7172 # convert + 7173 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) + 7174 # check result->name + 7175 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 7176 (check-strings-equal %eax "foo" "F - test-function-header-with-arg/name") + 7177 # var v/edx: (addr var) = result->inouts->value + 7178 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 7179 (lookup *eax *(eax+4)) # List-value List-value => eax + 7180 89/<- %edx 0/r32/eax + 7181 # check v->name + 7182 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 7183 (check-strings-equal %eax "n" "F - test-function-header-with-arg/inout:0") + 7184 # check v->type + 7185 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 7186 (check-ints-equal *eax 1 "F - test-function-header-with-arg/inout:0/type:0") # Type-tree-is-atom + 7187 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-arg/inout:0/type:1") # Type-tree-value + 7188 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-arg/inout:0/type:2") # Type-tree-right + 7189 # . epilogue + 7190 89/<- %esp 5/r32/ebp + 7191 5d/pop-to-ebp + 7192 c3/return + 7193 + 7194 test-function-header-with-multiple-args: + 7195 # . prologue + 7196 55/push-ebp + 7197 89/<- %ebp 4/r32/esp + 7198 # setup + 7199 (clear-stream _test-input-stream) + 7200 (write _test-input-stream "foo a: int, b: int c: int {\n") + 7201 # result/ecx: function + 7202 2b/subtract *Function-size 4/r32/esp + 7203 89/<- %ecx 4/r32/esp + 7204 (zero-out %ecx *Function-size) + 7205 # var vars/ebx: (stack live-var 16) + 7206 81 5/subop/subtract %esp 0xc0/imm32 + 7207 68/push 0xc0/imm32/size + 7208 68/push 0/imm32/top + 7209 89/<- %ebx 4/r32/esp + 7210 # convert + 7211 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) + 7212 # check result->name + 7213 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 7214 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args/name") + 7215 # var inouts/edx: (addr list var) = lookup(result->inouts) + 7216 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 7217 89/<- %edx 0/r32/eax + 7218 $test-function-header-with-multiple-args:inout0: + 7219 # var v/ebx: (addr var) = lookup(inouts->value) + 7220 (lookup *edx *(edx+4)) # List-value List-value => eax + 7221 89/<- %ebx 0/r32/eax + 7222 # check v->name + 7223 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 7224 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name + 7225 # check v->type + 7226 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 7227 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:0/type:0") # Type-tree-is-atom + 7228 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:0/type:1") # Type-tree-value + 7229 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:0/type:2") # Type-tree-right + 7230 $test-function-header-with-multiple-args:inout1: + 7231 # inouts = lookup(inouts->next) + 7232 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 7233 89/<- %edx 0/r32/eax + 7234 # v = lookup(inouts->value) + 7235 (lookup *edx *(edx+4)) # List-value List-value => eax + 7236 89/<- %ebx 0/r32/eax + 7237 # check v->name + 7238 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 7239 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name + 7240 # check v->type + 7241 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 7242 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:1/type:0") # Type-tree-is-atom + 7243 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:1/type:1") # Type-tree-value + 7244 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:1/type:2") # Type-tree-right + 7245 $test-function-header-with-multiple-args:inout2: + 7246 # inouts = lookup(inouts->next) + 7247 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 7248 89/<- %edx 0/r32/eax + 7249 # v = lookup(inouts->value) + 7250 (lookup *edx *(edx+4)) # List-value List-value => eax + 7251 89/<- %ebx 0/r32/eax + 7252 # check v->name + 7253 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 7254 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name + 7255 # check v->type + 7256 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 7257 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:2/type:0") # Type-tree-is-atom + 7258 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:2/type:1") # Type-tree-value + 7259 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:2/type:2") # Type-tree-right + 7260 # . epilogue + 7261 89/<- %esp 5/r32/ebp + 7262 5d/pop-to-ebp + 7263 c3/return + 7264 + 7265 test-function-header-with-multiple-args-and-outputs: + 7266 # . prologue + 7267 55/push-ebp + 7268 89/<- %ebp 4/r32/esp + 7269 # setup + 7270 (clear-stream _test-input-stream) + 7271 (write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx: int {\n") + 7272 # result/ecx: function + 7273 2b/subtract *Function-size 4/r32/esp + 7274 89/<- %ecx 4/r32/esp + 7275 (zero-out %ecx *Function-size) + 7276 # var vars/ebx: (stack live-var 16) + 7277 81 5/subop/subtract %esp 0xc0/imm32 + 7278 68/push 0xc0/imm32/size + 7279 68/push 0/imm32/top + 7280 89/<- %ebx 4/r32/esp + 7281 # convert + 7282 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) + 7283 # check result->name + 7284 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 7285 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args-and-outputs/name") + 7286 # var inouts/edx: (addr list var) = lookup(result->inouts) + 7287 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 7288 89/<- %edx 0/r32/eax + 7289 $test-function-header-with-multiple-args-and-outputs:inout0: + 7290 # var v/ebx: (addr var) = lookup(inouts->value) + 7291 (lookup *edx *(edx+4)) # List-value List-value => eax + 7292 89/<- %ebx 0/r32/eax + 7293 # check v->name + 7294 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 7295 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args-and-outputs/inout:0") + 7296 # check v->type + 7297 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 7298 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:0") # Type-tree-is-atom + 7299 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:1") # Type-tree-value + 7300 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:2") # Type-tree-right + 7301 $test-function-header-with-multiple-args-and-outputs:inout1: + 7302 # inouts = lookup(inouts->next) + 7303 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 7304 89/<- %edx 0/r32/eax + 7305 # v = lookup(inouts->value) + 7306 (lookup *edx *(edx+4)) # List-value List-value => eax + 7307 89/<- %ebx 0/r32/eax + 7308 # check v->name + 7309 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 7310 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args-and-outputs/inout:1") + 7311 # check v->type + 7312 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 7313 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:0") # Type-tree-is-atom + 7314 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:1") # Type-tree-value + 7315 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:2") # Type-tree-right + 7316 $test-function-header-with-multiple-args-and-outputs:inout2: + 7317 # inouts = lookup(inouts->next) + 7318 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 7319 89/<- %edx 0/r32/eax + 7320 # v = lookup(inouts->value) + 7321 (lookup *edx *(edx+4)) # List-value List-value => eax + 7322 89/<- %ebx 0/r32/eax + 7323 # check v->name + 7324 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 7325 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args-and-outputs/inout:2") + 7326 # check v->type + 7327 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 7328 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:0") # Type-tree-is-atom + 7329 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:1") # Type-tree-value + 7330 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:2") # Type-tree-right + 7331 $test-function-header-with-multiple-args-and-outputs:out0: + 7332 # var outputs/edx: (addr list var) = lookup(result->outputs) + 7333 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax + 7334 89/<- %edx 0/r32/eax + 7335 # v = lookup(outputs->value) + 7336 (lookup *edx *(edx+4)) # List-value List-value => eax + 7337 89/<- %ebx 0/r32/eax + 7338 # check v->name + 7339 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 7340 (check-strings-equal %eax "x" "F - test-function-header-with-multiple-args-and-outputs/output:0") + 7341 # check v->register + 7342 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax + 7343 (check-strings-equal %eax "ecx" "F - test-function-header-with-multiple-args-and-outputs/output:0/register") + 7344 # check v->type + 7345 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 7346 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:0") # Type-tree-is-atom + 7347 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:1") # Type-tree-value + 7348 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:2") # Type-tree-right + 7349 $test-function-header-with-multiple-args-and-outputs:out1: + 7350 # outputs = lookup(outputs->next) + 7351 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 7352 89/<- %edx 0/r32/eax + 7353 # v = lookup(inouts->value) + 7354 (lookup *edx *(edx+4)) # List-value List-value => eax + 7355 89/<- %ebx 0/r32/eax + 7356 # check v->name + 7357 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 7358 (check-strings-equal %eax "y" "F - test-function-header-with-multiple-args-and-outputs/output:1") + 7359 # check v->register + 7360 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax + 7361 (check-strings-equal %eax "edx" "F - test-function-header-with-multiple-args-and-outputs/output:1/register") + 7362 # check v->type + 7363 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 7364 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:0") # Type-tree-is-atom + 7365 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:1") # Type-tree-value + 7366 (check-ints-equal *(eax+0c) 0 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:2") # Type-tree-right + 7367 # . epilogue + 7368 89/<- %esp 5/r32/ebp + 7369 5d/pop-to-ebp + 7370 c3/return + 7371 + 7372 # format for variables with types + 7373 # x: int + 7374 # x: int, + 7375 # x/eax: int + 7376 # x/eax: int, + 7377 # ignores at most one trailing comma + 7378 # WARNING: modifies name + 7379 parse-var-with-type: # name: (addr slice), first-line: (addr stream byte), out: (addr handle var), err: (addr buffered-file), ed: (addr exit-descriptor) + 7380 # pseudocode: + 7381 # var s: slice + 7382 # if (!slice-ends-with(name, ":")) + 7383 # abort + 7384 # --name->end to skip ':' + 7385 # next-token-from-slice(name->start, name->end, '/', s) + 7386 # new-var-from-slice(s, out) + 7387 # ## register + 7388 # next-token-from-slice(s->end, name->end, '/', s) + 7389 # if (!slice-empty?(s)) + 7390 # out->register = slice-to-string(s) + 7391 # ## type + 7392 # var type: (handle type-tree) = parse-type(first-line) + 7393 # out->type = type + 7394 # + 7395 # . prologue + 7396 55/push-ebp + 7397 89/<- %ebp 4/r32/esp + 7398 # . save registers + 7399 50/push-eax + 7400 51/push-ecx + 7401 52/push-edx + 7402 53/push-ebx + 7403 56/push-esi + 7404 57/push-edi + 7405 # esi = name + 7406 8b/-> *(ebp+8) 6/r32/esi + 7407 # if (!slice-ends-with?(name, ":")) abort + 7408 8b/-> *(esi+4) 1/r32/ecx # Slice-end + 7409 49/decrement-ecx + 7410 8a/copy-byte *ecx 1/r32/CL + 7411 81 4/subop/and %ecx 0xff/imm32 + 7412 81 7/subop/compare %ecx 0x3a/imm32/colon + 7413 0f 85/jump-if-!= $parse-var-with-type:abort/disp32 + 7414 # --name->end to skip ':' + 7415 ff 1/subop/decrement *(esi+4) + 7416 # var s/ecx: slice + 7417 68/push 0/imm32/end + 7418 68/push 0/imm32/start + 7419 89/<- %ecx 4/r32/esp + 7420 $parse-var-with-type:parse-name: + 7421 (next-token-from-slice *esi *(esi+4) 0x2f %ecx) # Slice-start, Slice-end, '/' + 7422 $parse-var-with-type:create-var: + 7423 # new-var-from-slice(s, out) + 7424 (new-var-from-slice Heap %ecx *(ebp+0x10)) + 7425 # save out->register + 7426 $parse-var-with-type:save-register: + 7427 # . var out-addr/edi: (addr var) = lookup(*out) + 7428 8b/-> *(ebp+0x10) 7/r32/edi + 7429 (lookup *edi *(edi+4)) # => eax + 7430 89/<- %edi 0/r32/eax + 7431 # . s = next-token(...) + 7432 (next-token-from-slice *(ecx+4) *(esi+4) 0x2f %ecx) # s->end, name->end, '/' + 7433 # . if (!slice-empty?(s)) out->register = slice-to-string(s) + 7434 { + 7435 $parse-var-with-type:write-register: + 7436 (slice-empty? %ecx) # => eax + 7437 3d/compare-eax-and 0/imm32/false + 7438 75/jump-if-!= break/disp8 + 7439 # out->register = slice-to-string(s) + 7440 8d/copy-address *(edi+0x18) 0/r32/eax # Var-register + 7441 (slice-to-string Heap %ecx %eax) + 7442 } + 7443 $parse-var-with-type:save-type: + 7444 8d/copy-address *(edi+8) 0/r32/eax # Var-type + 7445 (parse-type Heap *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) + 7446 $parse-var-with-type:end: + 7447 # . reclaim locals + 7448 81 0/subop/add %esp 8/imm32 + 7449 # . restore registers + 7450 5f/pop-to-edi + 7451 5e/pop-to-esi + 7452 5b/pop-to-ebx + 7453 5a/pop-to-edx + 7454 59/pop-to-ecx + 7455 58/pop-to-eax + 7456 # . epilogue + 7457 89/<- %esp 5/r32/ebp + 7458 5d/pop-to-ebp + 7459 c3/return + 7460 + 7461 $parse-var-with-type:abort: + 7462 # error("var should have form 'name: type' in '" line "'\n") + 7463 (write-buffered *(ebp+0x14) "var should have form 'name: type' in '") + 7464 (flush *(ebp+0x14)) + 7465 (rewind-stream *(ebp+0xc)) + 7466 (write-stream-data *(ebp+0x14) *(ebp+0xc)) + 7467 (write-buffered *(ebp+0x14) "'\n") + 7468 (flush *(ebp+0x14)) + 7469 (stop *(ebp+0x18) 1) + 7470 # never gets here + 7471 + 7472 parse-type: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) + 7473 # pseudocode: + 7474 # var s: slice = next-mu-token(in) + 7475 # assert s != "" + 7476 # assert s != "->" + 7477 # assert s != "{" + 7478 # assert s != "}" + 7479 # if s == ")" + 7480 # return + 7481 # out = allocate(Type-tree) + 7482 # if s != "(" + 7483 # HACK: if s is an int, parse and return it + 7484 # out->is-atom? = true + 7485 # if (s[0] == "_") + 7486 # out->value = type-parameter + 7487 # out->parameter-name = slice-to-string(ad, s) + 7488 # else + 7489 # out->value = pos-or-insert-slice(Type-id, s) + 7490 # return + 7491 # out->left = parse-type(ad, in) + 7492 # out->right = parse-type-tree(ad, in) + 7493 # + 7494 # . prologue + 7495 55/push-ebp + 7496 89/<- %ebp 4/r32/esp + 7497 # . save registers + 7498 50/push-eax + 7499 51/push-ecx + 7500 52/push-edx + 7501 # clear out + 7502 (zero-out *(ebp+0x10) *Handle-size) + 7503 # var s/ecx: slice + 7504 68/push 0/imm32 + 7505 68/push 0/imm32 + 7506 89/<- %ecx 4/r32/esp + 7507 # s = next-mu-token(in) + 7508 (next-mu-token *(ebp+0xc) %ecx) + 7509 #? (write-buffered Stderr "tok: ") + 7510 #? (write-slice-buffered Stderr %ecx) + 7511 #? (write-buffered Stderr "$\n") + 7512 #? (flush Stderr) + 7513 # assert s != "" + 7514 (slice-equal? %ecx "") # => eax + 7515 3d/compare-eax-and 0/imm32/false + 7516 0f 85/jump-if-!= $parse-type:abort/disp32 + 7517 # assert s != "{" + 7518 (slice-equal? %ecx "{") # => eax + 7519 3d/compare-eax-and 0/imm32/false + 7520 0f 85/jump-if-!= $parse-type:abort/disp32 + 7521 # assert s != "}" + 7522 (slice-equal? %ecx "}") # => eax + 7523 3d/compare-eax-and 0/imm32/false + 7524 0f 85/jump-if-!= $parse-type:abort/disp32 + 7525 # assert s != "->" + 7526 (slice-equal? %ecx "->") # => eax + 7527 3d/compare-eax-and 0/imm32/false + 7528 0f 85/jump-if-!= $parse-type:abort/disp32 + 7529 # if (s == ")") return + 7530 (slice-equal? %ecx ")") # => eax + 7531 3d/compare-eax-and 0/imm32/false + 7532 0f 85/jump-if-!= $parse-type:end/disp32 + 7533 # out = new tree + 7534 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10)) + 7535 # var out-addr/edx: (addr type-tree) = lookup(*out) + 7536 8b/-> *(ebp+0x10) 2/r32/edx + 7537 (lookup *edx *(edx+4)) # => eax + 7538 89/<- %edx 0/r32/eax + 7539 { + 7540 # if (s != "(") break + 7541 (slice-equal? %ecx "(") # => eax + 7542 3d/compare-eax-and 0/imm32/false + 7543 0f 85/jump-if-!= break/disp32 + 7544 # if s is a number, store it in the type's size field + 7545 { + 7546 $parse-type:check-for-int: + 7547 # var tmp/eax: byte = *s->slice + 7548 8b/-> *ecx 0/r32/eax + 7549 8a/copy-byte *eax 0/r32/AL + 7550 81 4/subop/and %eax 0xff/imm32 + 7551 # TODO: raise an error on `var x: (array int a)` + 7552 (is-decimal-digit? %eax) # => eax + 7553 3d/compare-eax-and 0/imm32/false + 7554 74/jump-if-= break/disp8 + 7555 # + 7556 (is-hex-int? %ecx) # => eax + 7557 3d/compare-eax-and 0/imm32/false + 7558 74/jump-if-= break/disp8 + 7559 $parse-type:int: + 7560 (check-mu-hex-int %ecx *(ebp+0x14) *(ebp+0x18)) + 7561 (parse-hex-int-from-slice %ecx) # => eax + 7562 c7 0/subop/copy *(edx+4) 9/imm32/type-id-array-capacity # Type-tree-value + 7563 89/<- *(edx+8) 0/r32/eax # Type-tree-value-size + 7564 e9/jump $parse-type:end/disp32 + 7565 } + 7566 $parse-type:atom: + 7567 # out->is-atom? = true + 7568 c7 0/subop/copy *edx 1/imm32/true # Type-tree-is-atom + 7569 { + 7570 $parse-type:check-for-type-parameter: + 7571 # var tmp/eax: byte = *s->slice + 7572 8b/-> *ecx 0/r32/eax + 7573 8a/copy-byte *eax 0/r32/AL + 7574 81 4/subop/and %eax 0xff/imm32 + 7575 # if (tmp != '_') break + 7576 3d/compare-eax-and 0x5f/imm32/_ + 7577 75/jump-if-!= break/disp8 + 7578 $parse-type:type-parameter: + 7579 # out->value = type-parameter + 7580 c7 0/subop/copy *(edx+4) 0xa/imm32/type-parameter # Type-tree-value + 7581 # out->parameter-name = slice-to-string(ad, s) + 7582 8d/copy-address *(edx+8) 0/r32/eax # Type-tree-parameter-name + 7583 (slice-to-string *(ebp+8) %ecx %eax) + 7584 e9/jump $parse-type:end/disp32 + 7585 } + 7586 $parse-type:non-type-parameter: + 7587 # out->value = pos-or-insert-slice(Type-id, s) + 7588 (pos-or-insert-slice Type-id %ecx) # => eax + 7589 89/<- *(edx+4) 0/r32/eax # Type-tree-value + 7590 e9/jump $parse-type:end/disp32 + 7591 } + 7592 $parse-type:non-atom: + 7593 # otherwise s == "(" + 7594 # out->left = parse-type(ad, in) + 7595 8d/copy-address *(edx+4) 0/r32/eax # Type-tree-left + 7596 (parse-type *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) + 7597 # out->right = parse-type-tree(ad, in) + 7598 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right + 7599 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) + 7600 $parse-type:end: + 7601 # . reclaim locals + 7602 81 0/subop/add %esp 8/imm32 + 7603 # . restore registers + 7604 5a/pop-to-edx + 7605 59/pop-to-ecx + 7606 58/pop-to-eax + 7607 # . epilogue + 7608 89/<- %esp 5/r32/ebp + 7609 5d/pop-to-ebp + 7610 c3/return + 7611 + 7612 $parse-type:abort: + 7613 # error("unexpected token when parsing type: '" s "'\n") + 7614 (write-buffered *(ebp+0x14) "unexpected token when parsing type: '") + 7615 (write-slice-buffered *(ebp+0x14) %ecx) + 7616 (write-buffered *(ebp+0x14) "'\n") + 7617 (flush *(ebp+0x14)) + 7618 (stop *(ebp+0x18) 1) + 7619 # never gets here + 7620 + 7621 parse-type-tree: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle type-tree), err: (addr buffered-file), ed: (addr exit-descriptor) + 7622 # pseudocode: + 7623 # var tmp: (handle type-tree) = parse-type(ad, in) + 7624 # if tmp == 0 + 7625 # return 0 + 7626 # out = allocate(Type-tree) + 7627 # out->left = tmp + 7628 # out->right = parse-type-tree(ad, in) + 7629 # + 7630 # . prologue + 7631 55/push-ebp + 7632 89/<- %ebp 4/r32/esp + 7633 # . save registers + 7634 50/push-eax + 7635 51/push-ecx + 7636 52/push-edx + 7637 # + 7638 (zero-out *(ebp+0x10) *Handle-size) + 7639 # var tmp/ecx: (handle type-tree) + 7640 68/push 0/imm32 + 7641 68/push 0/imm32 + 7642 89/<- %ecx 4/r32/esp + 7643 # tmp = parse-type(ad, in) + 7644 (parse-type *(ebp+8) *(ebp+0xc) %ecx *(ebp+0x14) *(ebp+0x18)) + 7645 # if (tmp == 0) return + 7646 81 7/subop/compare *ecx 0/imm32 + 7647 74/jump-if-= $parse-type-tree:end/disp8 + 7648 # out = new tree + 7649 (allocate *(ebp+8) *Type-tree-size *(ebp+0x10)) + 7650 # var out-addr/edx: (addr tree) = lookup(*out) + 7651 8b/-> *(ebp+0x10) 2/r32/edx + 7652 (lookup *edx *(edx+4)) # => eax + 7653 89/<- %edx 0/r32/eax + 7654 # out->left = tmp + 7655 8b/-> *ecx 0/r32/eax + 7656 89/<- *(edx+4) 0/r32/eax # Type-tree-left + 7657 8b/-> *(ecx+4) 0/r32/eax + 7658 89/<- *(edx+8) 0/r32/eax # Type-tree-left + 7659 # out->right = parse-type-tree(ad, in) + 7660 8d/copy-address *(edx+0xc) 0/r32/eax # Type-tree-right + 7661 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) + 7662 $parse-type-tree:end: + 7663 # . reclaim locals + 7664 81 0/subop/add %esp 8/imm32 + 7665 # . restore registers + 7666 5a/pop-to-edx + 7667 59/pop-to-ecx + 7668 58/pop-to-eax + 7669 # . epilogue + 7670 89/<- %esp 5/r32/ebp + 7671 5d/pop-to-ebp + 7672 c3/return + 7673 + 7674 next-mu-token: # in: (addr stream byte), out: (addr slice) + 7675 # pseudocode: + 7676 # start: + 7677 # skip-chars-matching-whitespace(in) + 7678 # if in->read >= in->write # end of in + 7679 # out = {0, 0} + 7680 # return + 7681 # out->start = &in->data[in->read] + 7682 # var curr-byte/eax: byte = in->data[in->read] + 7683 # if curr->byte == ',' # comment token + 7684 # ++in->read + 7685 # goto start + 7686 # if curr-byte == '#' # comment + 7687 # goto done # treat as eof + 7688 # if curr-byte == '"' # string literal + 7689 # skip-string(in) + 7690 # goto done # no metadata + 7691 # if curr-byte == '(' + 7692 # ++in->read + 7693 # goto done + 7694 # if curr-byte == ')' + 7695 # ++in->read + 7696 # goto done + 7697 # # read a word + 7698 # while true + 7699 # if in->read >= in->write + 7700 # break + 7701 # curr-byte = in->data[in->read] + 7702 # if curr-byte == ' ' + 7703 # break + 7704 # if curr-byte == '\r' + 7705 # break + 7706 # if curr-byte == '\n' + 7707 # break + 7708 # if curr-byte == '(' + 7709 # break + 7710 # if curr-byte == ')' + 7711 # break + 7712 # if curr-byte == ',' + 7713 # break + 7714 # ++in->read + 7715 # done: + 7716 # out->end = &in->data[in->read] + 7717 # + 7718 # . prologue + 7719 55/push-ebp + 7720 89/<- %ebp 4/r32/esp + 7721 # . save registers + 7722 50/push-eax + 7723 51/push-ecx + 7724 56/push-esi + 7725 57/push-edi + 7726 # esi = in + 7727 8b/-> *(ebp+8) 6/r32/esi + 7728 # edi = out + 7729 8b/-> *(ebp+0xc) 7/r32/edi + 7730 $next-mu-token:start: + 7731 (skip-chars-matching-whitespace %esi) + 7732 $next-mu-token:check0: + 7733 # if (in->read >= in->write) return out = {0, 0} + 7734 # . ecx = in->read + 7735 8b/-> *(esi+4) 1/r32/ecx + 7736 # . if (ecx >= in->write) return out = {0, 0} + 7737 3b/compare<- *esi 1/r32/ecx + 7738 c7 0/subop/copy *edi 0/imm32 + 7739 c7 0/subop/copy *(edi+4) 0/imm32 + 7740 0f 8d/jump-if->= $next-mu-token:end/disp32 + 7741 # out->start = &in->data[in->read] + 7742 8d/copy-address *(esi+ecx+0xc) 0/r32/eax + 7743 89/<- *edi 0/r32/eax + 7744 # var curr-byte/eax: byte = in->data[in->read] + 7745 31/xor-with %eax 0/r32/eax + 7746 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 7747 { + 7748 $next-mu-token:check-for-comma: + 7749 # if (curr-byte != ',') break + 7750 3d/compare-eax-and 0x2c/imm32/comma + 7751 75/jump-if-!= break/disp8 + 7752 # ++in->read + 7753 ff 0/subop/increment *(esi+4) + 7754 # restart + 7755 e9/jump $next-mu-token:start/disp32 + 7756 } + 7757 { + 7758 $next-mu-token:check-for-comment: + 7759 # if (curr-byte != '#') break + 7760 3d/compare-eax-and 0x23/imm32/pound + 7761 75/jump-if-!= break/disp8 + 7762 # return eof + 7763 e9/jump $next-mu-token:done/disp32 + 7764 } + 7765 { + 7766 $next-mu-token:check-for-string-literal: + 7767 # if (curr-byte != '"') break + 7768 3d/compare-eax-and 0x22/imm32/dquote + 7769 75/jump-if-!= break/disp8 + 7770 (skip-string %esi) + 7771 # return + 7772 e9/jump $next-mu-token:done/disp32 + 7773 } + 7774 { + 7775 $next-mu-token:check-for-open-paren: + 7776 # if (curr-byte != '(') break + 7777 3d/compare-eax-and 0x28/imm32/open-paren + 7778 75/jump-if-!= break/disp8 + 7779 # ++in->read + 7780 ff 0/subop/increment *(esi+4) + 7781 # return + 7782 e9/jump $next-mu-token:done/disp32 + 7783 } + 7784 { + 7785 $next-mu-token:check-for-close-paren: + 7786 # if (curr-byte != ')') break + 7787 3d/compare-eax-and 0x29/imm32/close-paren + 7788 75/jump-if-!= break/disp8 + 7789 # ++in->read + 7790 ff 0/subop/increment *(esi+4) + 7791 # return + 7792 e9/jump $next-mu-token:done/disp32 + 7793 } + 7794 { + 7795 $next-mu-token:regular-word-without-metadata: + 7796 # if (in->read >= in->write) break + 7797 # . ecx = in->read + 7798 8b/-> *(esi+4) 1/r32/ecx + 7799 # . if (ecx >= in->write) break + 7800 3b/compare<- *esi 1/r32/ecx + 7801 7d/jump-if->= break/disp8 + 7802 # var c/eax: byte = in->data[in->read] + 7803 31/xor-with %eax 0/r32/eax + 7804 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 7805 # if (c == ' ') break + 7806 3d/compare-eax-and 0x20/imm32/space + 7807 74/jump-if-= break/disp8 + 7808 # if (c == '\r') break + 7809 3d/compare-eax-and 0xd/imm32/carriage-return + 7810 74/jump-if-= break/disp8 + 7811 # if (c == '\n') break + 7812 3d/compare-eax-and 0xa/imm32/newline + 7813 74/jump-if-= break/disp8 + 7814 # if (c == '(') break + 7815 3d/compare-eax-and 0x28/imm32/open-paren + 7816 0f 84/jump-if-= break/disp32 + 7817 # if (c == ')') break + 7818 3d/compare-eax-and 0x29/imm32/close-paren + 7819 0f 84/jump-if-= break/disp32 + 7820 # if (c == ',') break + 7821 3d/compare-eax-and 0x2c/imm32/comma + 7822 0f 84/jump-if-= break/disp32 + 7823 # ++in->read + 7824 ff 0/subop/increment *(esi+4) + 7825 # + 7826 e9/jump loop/disp32 + 7827 } + 7828 $next-mu-token:done: + 7829 # out->end = &in->data[in->read] + 7830 8b/-> *(esi+4) 1/r32/ecx + 7831 8d/copy-address *(esi+ecx+0xc) 0/r32/eax + 7832 89/<- *(edi+4) 0/r32/eax + 7833 $next-mu-token:end: + 7834 # . restore registers + 7835 5f/pop-to-edi + 7836 5e/pop-to-esi + 7837 59/pop-to-ecx + 7838 58/pop-to-eax + 7839 # . epilogue + 7840 89/<- %esp 5/r32/ebp + 7841 5d/pop-to-ebp + 7842 c3/return + 7843 + 7844 pos-or-insert-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int + 7845 # . prologue + 7846 55/push-ebp + 7847 89/<- %ebp 4/r32/esp + 7848 # if (pos-slice(arr, s) != -1) return it + 7849 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax + 7850 3d/compare-eax-and -1/imm32 + 7851 75/jump-if-!= $pos-or-insert-slice:end/disp8 + 7852 $pos-or-insert-slice:insert: + 7853 # var s2/eax: (handle array byte) + 7854 68/push 0/imm32 + 7855 68/push 0/imm32 + 7856 89/<- %eax 4/r32/esp + 7857 (slice-to-string Heap *(ebp+0xc) %eax) + 7858 # throw away alloc-id + 7859 (lookup *eax *(eax+4)) # => eax + 7860 (write-int *(ebp+8) %eax) + 7861 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax + 7862 $pos-or-insert-slice:end: + 7863 # . reclaim locals + 7864 81 0/subop/add %esp 8/imm32 + 7865 # . epilogue + 7866 89/<- %esp 5/r32/ebp + 7867 5d/pop-to-ebp + 7868 c3/return + 7869 + 7870 # return the index in an array of strings matching 's', -1 if not found + 7871 # index is denominated in elements, not bytes + 7872 pos-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int + 7873 # . prologue + 7874 55/push-ebp + 7875 89/<- %ebp 4/r32/esp + 7876 # . save registers + 7877 51/push-ecx + 7878 52/push-edx + 7879 53/push-ebx + 7880 56/push-esi + 7881 #? (write-buffered Stderr "pos-slice: ") + 7882 #? (write-slice-buffered Stderr *(ebp+0xc)) + 7883 #? (write-buffered Stderr "\n") + 7884 #? (flush Stderr) + 7885 # esi = arr + 7886 8b/-> *(ebp+8) 6/r32/esi + 7887 # var index/ecx: int = 0 + 7888 b9/copy-to-ecx 0/imm32 + 7889 # var curr/edx: (addr (addr array byte)) = arr->data + 7890 8d/copy-address *(esi+0xc) 2/r32/edx + 7891 # var max/ebx: (addr (addr array byte)) = &arr->data[arr->write] + 7892 8b/-> *esi 3/r32/ebx + 7893 8d/copy-address *(esi+ebx+0xc) 3/r32/ebx + 7894 { + 7895 #? (write-buffered Stderr " ") + 7896 #? (write-int32-hex-buffered Stderr %ecx) + 7897 #? (write-buffered Stderr "\n") + 7898 #? (flush Stderr) + 7899 # if (curr >= max) return -1 + 7900 39/compare %edx 3/r32/ebx + 7901 b8/copy-to-eax -1/imm32 + 7902 73/jump-if-addr>= $pos-slice:end/disp8 + 7903 # if (slice-equal?(s, *curr)) break + 7904 (slice-equal? *(ebp+0xc) *edx) # => eax + 7905 3d/compare-eax-and 0/imm32/false + 7906 75/jump-if-!= break/disp8 + 7907 # ++index + 7908 41/increment-ecx + 7909 # curr += 4 + 7910 81 0/subop/add %edx 4/imm32 + 7911 # + 7912 eb/jump loop/disp8 + 7913 } + 7914 # return index + 7915 89/<- %eax 1/r32/ecx + 7916 $pos-slice:end: + 7917 #? (write-buffered Stderr "=> ") + 7918 #? (write-int32-hex-buffered Stderr %eax) + 7919 #? (write-buffered Stderr "\n") + 7920 # . restore registers + 7921 5e/pop-to-esi + 7922 5b/pop-to-ebx + 7923 5a/pop-to-edx + 7924 59/pop-to-ecx + 7925 # . epilogue + 7926 89/<- %esp 5/r32/ebp + 7927 5d/pop-to-ebp + 7928 c3/return + 7929 + 7930 test-parse-var-with-type: + 7931 # . prologue + 7932 55/push-ebp + 7933 89/<- %ebp 4/r32/esp + 7934 # (eax..ecx) = "x:" + 7935 b8/copy-to-eax "x:"/imm32 + 7936 8b/-> *eax 1/r32/ecx + 7937 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7938 05/add-to-eax 4/imm32 + 7939 # var slice/ecx: slice = {eax, ecx} + 7940 51/push-ecx + 7941 50/push-eax + 7942 89/<- %ecx 4/r32/esp + 7943 # _test-input-stream contains "int" + 7944 (clear-stream _test-input-stream) + 7945 (write _test-input-stream "int") + 7946 # var v/edx: (handle var) + 7947 68/push 0/imm32 + 7948 68/push 0/imm32 + 7949 89/<- %edx 4/r32/esp + 7950 # + 7951 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 7952 # var v-addr/edx: (addr var) = lookup(v) + 7953 (lookup *edx *(edx+4)) # => eax + 7954 89/<- %edx 0/r32/eax + 7955 # check v-addr->name + 7956 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 7957 (check-strings-equal %eax "x" "F - test-parse-var-with-type/name") + 7958 # check v-addr->type + 7959 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 7960 (check-ints-equal *eax 1 "F - test-parse-var-with-type/type:0") # Type-tree-is-atom + 7961 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type/type:1") # Type-tree-value + 7962 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type/type:2") # Type-tree-right + 7963 # . epilogue + 7964 89/<- %esp 5/r32/ebp + 7965 5d/pop-to-ebp + 7966 c3/return + 7967 + 7968 test-parse-var-with-type-and-register: + 7969 # . prologue + 7970 55/push-ebp + 7971 89/<- %ebp 4/r32/esp + 7972 # (eax..ecx) = "x/eax:" + 7973 b8/copy-to-eax "x/eax:"/imm32 + 7974 8b/-> *eax 1/r32/ecx + 7975 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7976 05/add-to-eax 4/imm32 + 7977 # var slice/ecx: slice = {eax, ecx} + 7978 51/push-ecx + 7979 50/push-eax + 7980 89/<- %ecx 4/r32/esp + 7981 # _test-input-stream contains "int" + 7982 (clear-stream _test-input-stream) + 7983 (write _test-input-stream "int") + 7984 # var v/edx: (handle var) + 7985 68/push 0/imm32 + 7986 68/push 0/imm32 + 7987 89/<- %edx 4/r32/esp + 7988 # + 7989 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 7990 # var v-addr/edx: (addr var) = lookup(v) + 7991 (lookup *edx *(edx+4)) # => eax + 7992 89/<- %edx 0/r32/eax + 7993 # check v-addr->name + 7994 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 7995 (check-strings-equal %eax "x" "F - test-parse-var-with-type-and-register/name") + 7996 # check v-addr->register + 7997 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax + 7998 (check-strings-equal %eax "eax" "F - test-parse-var-with-type-and-register/register") + 7999 # check v-addr->type + 8000 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 8001 (check-ints-equal *eax 1 "F - test-parse-var-with-type-and-register/type:0") # Type-tree-is-atom + 8002 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type-and-register/type:1") # Type-tree-left + 8003 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type-and-register/type:2") # Type-tree-right + 8004 # . epilogue + 8005 89/<- %esp 5/r32/ebp + 8006 5d/pop-to-ebp + 8007 c3/return + 8008 + 8009 test-parse-var-with-trailing-characters: + 8010 # . prologue + 8011 55/push-ebp + 8012 89/<- %ebp 4/r32/esp + 8013 # (eax..ecx) = "x:" + 8014 b8/copy-to-eax "x:"/imm32 + 8015 8b/-> *eax 1/r32/ecx + 8016 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8017 05/add-to-eax 4/imm32 + 8018 # var slice/ecx: slice = {eax, ecx} + 8019 51/push-ecx + 8020 50/push-eax + 8021 89/<- %ecx 4/r32/esp + 8022 # _test-input-stream contains "int," + 8023 (clear-stream _test-input-stream) + 8024 (write _test-input-stream "int,") + 8025 # var v/edx: (handle var) + 8026 68/push 0/imm32 + 8027 68/push 0/imm32 + 8028 89/<- %edx 4/r32/esp + 8029 # + 8030 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 8031 # var v-addr/edx: (addr var) = lookup(v) + 8032 (lookup *edx *(edx+4)) # => eax + 8033 89/<- %edx 0/r32/eax + 8034 # check v-addr->name + 8035 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 8036 (check-strings-equal %eax "x" "F - test-parse-var-with-trailing-characters/name") + 8037 # check v-addr->register + 8038 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-trailing-characters/register") # Var-register + 8039 # check v-addr->type + 8040 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 8041 (check-ints-equal *eax 1 "F - test-parse-var-with-trailing-characters/type:0") # Type-tree-is-atom + 8042 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-left + 8043 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-trailing-characters/type:1") # Type-tree-right + 8044 # . epilogue + 8045 89/<- %esp 5/r32/ebp + 8046 5d/pop-to-ebp + 8047 c3/return + 8048 + 8049 test-parse-var-with-register-and-trailing-characters: + 8050 # . prologue + 8051 55/push-ebp + 8052 89/<- %ebp 4/r32/esp + 8053 # (eax..ecx) = "x/eax:" + 8054 b8/copy-to-eax "x/eax:"/imm32 + 8055 8b/-> *eax 1/r32/ecx + 8056 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8057 05/add-to-eax 4/imm32 + 8058 # var slice/ecx: slice = {eax, ecx} + 8059 51/push-ecx + 8060 50/push-eax + 8061 89/<- %ecx 4/r32/esp + 8062 # _test-input-stream contains "int," + 8063 (clear-stream _test-input-stream) + 8064 (write _test-input-stream "int,") + 8065 # var v/edx: (handle var) + 8066 68/push 0/imm32 + 8067 68/push 0/imm32 + 8068 89/<- %edx 4/r32/esp + 8069 # + 8070 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 8071 # var v-addr/edx: (addr var) = lookup(v) + 8072 (lookup *edx *(edx+4)) # => eax + 8073 89/<- %edx 0/r32/eax + 8074 # check v-addr->name + 8075 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 8076 (check-strings-equal %eax "x" "F - test-parse-var-with-register-and-trailing-characters/name") + 8077 # check v-addr->register + 8078 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax + 8079 (check-strings-equal %eax "eax" "F - test-parse-var-with-register-and-trailing-characters/register") + 8080 # check v-addr->type + 8081 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 8082 (check-ints-equal *eax 1 "F - test-parse-var-with-register-and-trailing-characters/type:0") # Type-tree-is-atom + 8083 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-register-and-trailing-characters/type:1") # Type-tree-left + 8084 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-register-and-trailing-characters/type:2") # Type-tree-right + 8085 # . epilogue + 8086 89/<- %esp 5/r32/ebp + 8087 5d/pop-to-ebp + 8088 c3/return + 8089 + 8090 test-parse-var-with-compound-type: + 8091 # . prologue + 8092 55/push-ebp + 8093 89/<- %ebp 4/r32/esp + 8094 # (eax..ecx) = "x:" + 8095 b8/copy-to-eax "x:"/imm32 + 8096 8b/-> *eax 1/r32/ecx + 8097 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8098 05/add-to-eax 4/imm32 + 8099 # var slice/ecx: slice = {eax, ecx} + 8100 51/push-ecx + 8101 50/push-eax + 8102 89/<- %ecx 4/r32/esp + 8103 # _test-input-stream contains "(addr int)" + 8104 (clear-stream _test-input-stream) + 8105 (write _test-input-stream "(addr int)") + 8106 # var v/edx: (handle var) + 8107 68/push 0/imm32 + 8108 68/push 0/imm32 + 8109 89/<- %edx 4/r32/esp + 8110 # + 8111 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 8112 # var v-addr/edx: (addr var) = lookup(v) + 8113 (lookup *edx *(edx+4)) # => eax + 8114 89/<- %edx 0/r32/eax + 8115 # check v-addr->name + 8116 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 8117 (check-strings-equal %eax "x" "F - test-parse-var-with-compound-type/name") + 8118 # check v-addr->register + 8119 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-compound-type/register") # Var-register + 8120 # - check v-addr->type + 8121 # var type/edx: (addr type-tree) = var->type + 8122 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 8123 89/<- %edx 0/r32/eax + 8124 # type is a non-atom + 8125 (check-ints-equal *edx 0 "F - test-parse-var-with-compound-type/type:0") # Type-tree-is-atom + 8126 # type->left == atom(addr) + 8127 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax + 8128 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:1") # Type-tree-is-atom + 8129 (check-ints-equal *(eax+4) 2 "F - test-parse-var-with-compound-type/type:2") # Type-tree-value + 8130 # type->right->left == atom(int) + 8131 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax + 8132 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax + 8133 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:3") # Type-tree-is-atom + 8134 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-compound-type/type:4") # Type-tree-value + 8135 # type->right->right == null + 8136 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-compound-type/type:5") # Type-tree-right + 8137 # . epilogue + 8138 89/<- %esp 5/r32/ebp + 8139 5d/pop-to-ebp + 8140 c3/return + 8141 + 8142 # identifier starts with a letter or '$' or '_' + 8143 # no constraints at the moment on later letters + 8144 # all we really want to do so far is exclude '{', '}' and '->' + 8145 is-identifier?: # in: (addr slice) -> result/eax: boolean + 8146 # . prologue + 8147 55/push-ebp + 8148 89/<- %ebp 4/r32/esp + 8149 # if (slice-empty?(in)) return false + 8150 (slice-empty? *(ebp+8)) # => eax + 8151 3d/compare-eax-and 0/imm32/false + 8152 75/jump-if-!= $is-identifier?:false/disp8 + 8153 # var c/eax: byte = *in->start + 8154 8b/-> *(ebp+8) 0/r32/eax + 8155 8b/-> *eax 0/r32/eax + 8156 8a/copy-byte *eax 0/r32/AL + 8157 81 4/subop/and %eax 0xff/imm32 + 8158 # if (c == '$') return true + 8159 3d/compare-eax-and 0x24/imm32/$ + 8160 74/jump-if-= $is-identifier?:true/disp8 + 8161 # if (c == '_') return true + 8162 3d/compare-eax-and 0x5f/imm32/_ + 8163 74/jump-if-= $is-identifier?:true/disp8 + 8164 # drop case + 8165 25/and-eax-with 0x5f/imm32 + 8166 # if (c < 'A') return false + 8167 3d/compare-eax-and 0x41/imm32/A + 8168 7c/jump-if-< $is-identifier?:false/disp8 + 8169 # if (c > 'Z') return false + 8170 3d/compare-eax-and 0x5a/imm32/Z + 8171 7f/jump-if-> $is-identifier?:false/disp8 + 8172 # otherwise return true + 8173 $is-identifier?:true: + 8174 b8/copy-to-eax 1/imm32/true + 8175 eb/jump $is-identifier?:end/disp8 + 8176 $is-identifier?:false: + 8177 b8/copy-to-eax 0/imm32/false + 8178 $is-identifier?:end: + 8179 # . epilogue + 8180 89/<- %esp 5/r32/ebp + 8181 5d/pop-to-ebp + 8182 c3/return + 8183 + 8184 test-is-identifier-dollar: + 8185 # . prologue + 8186 55/push-ebp + 8187 89/<- %ebp 4/r32/esp + 8188 # (eax..ecx) = "$a" + 8189 b8/copy-to-eax "$a"/imm32 + 8190 8b/-> *eax 1/r32/ecx + 8191 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8192 05/add-to-eax 4/imm32 + 8193 # var slice/ecx: slice = {eax, ecx} + 8194 51/push-ecx + 8195 50/push-eax + 8196 89/<- %ecx 4/r32/esp + 8197 # + 8198 (is-identifier? %ecx) + 8199 (check-ints-equal %eax 1 "F - test-is-identifier-dollar") + 8200 # . epilogue + 8201 89/<- %esp 5/r32/ebp + 8202 5d/pop-to-ebp + 8203 c3/return + 8204 + 8205 test-is-identifier-underscore: + 8206 # . prologue + 8207 55/push-ebp + 8208 89/<- %ebp 4/r32/esp + 8209 # (eax..ecx) = "_a" + 8210 b8/copy-to-eax "_a"/imm32 + 8211 8b/-> *eax 1/r32/ecx + 8212 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8213 05/add-to-eax 4/imm32 + 8214 # var slice/ecx: slice = {eax, ecx} + 8215 51/push-ecx + 8216 50/push-eax + 8217 89/<- %ecx 4/r32/esp + 8218 # + 8219 (is-identifier? %ecx) + 8220 (check-ints-equal %eax 1 "F - test-is-identifier-underscore") + 8221 # . epilogue + 8222 89/<- %esp 5/r32/ebp + 8223 5d/pop-to-ebp + 8224 c3/return + 8225 + 8226 test-is-identifier-a: + 8227 # . prologue + 8228 55/push-ebp + 8229 89/<- %ebp 4/r32/esp + 8230 # (eax..ecx) = "a$" + 8231 b8/copy-to-eax "a$"/imm32 + 8232 8b/-> *eax 1/r32/ecx + 8233 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8234 05/add-to-eax 4/imm32 + 8235 # var slice/ecx: slice = {eax, ecx} + 8236 51/push-ecx + 8237 50/push-eax + 8238 89/<- %ecx 4/r32/esp 8239 # - 8240 (parse-mu-block *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20)) - 8241 # pop v off vars - 8242 (pop *(ebp+0x10)) # => eax - 8243 (pop *(ebp+0x10)) # => eax - 8244 (pop *(ebp+0x10)) # => eax - 8245 # var out-addr/edi: (addr stmt) = lookup(*out) - 8246 8b/-> *(ebp+0x18) 7/r32/edi - 8247 (lookup *edi *(edi+4)) # => eax - 8248 89/<- %edi 0/r32/eax - 8249 # out-addr->tag = named-block - 8250 c7 0/subop/copy *edi 0/imm32/block # Stmt-tag - 8251 # out-addr->var = v - 8252 8b/-> *ecx 0/r32/eax - 8253 89/<- *(edi+0xc) 0/r32/eax # Block-var - 8254 8b/-> *(ecx+4) 0/r32/eax - 8255 89/<- *(edi+0x10) 0/r32/eax # Block-var - 8256 $parse-mu-named-block:end: - 8257 # . reclaim locals - 8258 81 0/subop/add %esp 8/imm32 - 8259 # . restore registers - 8260 5f/pop-to-edi - 8261 59/pop-to-ecx - 8262 58/pop-to-eax + 8240 (is-identifier? %ecx) + 8241 (check-ints-equal %eax 1 "F - test-is-identifier-a") + 8242 # . epilogue + 8243 89/<- %esp 5/r32/ebp + 8244 5d/pop-to-ebp + 8245 c3/return + 8246 + 8247 test-is-identifier-z: + 8248 # . prologue + 8249 55/push-ebp + 8250 89/<- %ebp 4/r32/esp + 8251 # (eax..ecx) = "z$" + 8252 b8/copy-to-eax "z$"/imm32 + 8253 8b/-> *eax 1/r32/ecx + 8254 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8255 05/add-to-eax 4/imm32 + 8256 # var slice/ecx: slice = {eax, ecx} + 8257 51/push-ecx + 8258 50/push-eax + 8259 89/<- %ecx 4/r32/esp + 8260 # + 8261 (is-identifier? %ecx) + 8262 (check-ints-equal %eax 1 "F - test-is-identifier-z") 8263 # . epilogue 8264 89/<- %esp 5/r32/ebp 8265 5d/pop-to-ebp 8266 c3/return 8267 - 8268 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) + 8268 test-is-identifier-A: 8269 # . prologue 8270 55/push-ebp 8271 89/<- %ebp 4/r32/esp - 8272 # . save registers - 8273 50/push-eax - 8274 51/push-ecx - 8275 52/push-edx - 8276 53/push-ebx - 8277 57/push-edi - 8278 # edi = out - 8279 8b/-> *(ebp+0x10) 7/r32/edi - 8280 # var word-slice/ecx: slice - 8281 68/push 0/imm32/end - 8282 68/push 0/imm32/start - 8283 89/<- %ecx 4/r32/esp - 8284 # var v/edx: (handle var) - 8285 68/push 0/imm32 - 8286 68/push 0/imm32 - 8287 89/<- %edx 4/r32/esp - 8288 # v = parse-var-with-type(next-mu-token(line)) - 8289 (next-mu-token *(ebp+8) %ecx) - 8290 (parse-var-with-type %ecx *(ebp+8) %edx *(ebp+0x18) *(ebp+0x1c)) - 8291 # var v-addr/eax: (addr var) - 8292 (lookup *edx *(edx+4)) # => eax - 8293 # v->block-depth = *Curr-block-depth - 8294 8b/-> *Curr-block-depth 3/r32/ebx - 8295 89/<- *(eax+0x10) 3/r32/ebx # Var-block-depth - 8296 # either v has no register and there's no more to this line - 8297 8b/-> *(eax+0x18) 0/r32/eax # Var-register - 8298 3d/compare-eax-and 0/imm32 - 8299 { - 8300 75/jump-if-!= break/disp8 - 8301 # TODO: disallow vars of type 'byte' on the stack - 8302 # ensure that there's nothing else on this line - 8303 (next-mu-token *(ebp+8) %ecx) - 8304 (slice-empty? %ecx) # => eax - 8305 3d/compare-eax-and 0/imm32/false - 8306 0f 84/jump-if-= $parse-mu-var-def:error2/disp32 - 8307 # - 8308 (new-var-def Heap *edx *(edx+4) %edi) - 8309 e9/jump $parse-mu-var-def:update-vars/disp32 - 8310 } - 8311 # or v has a register and there's more to this line - 8312 { - 8313 0f 84/jump-if-= break/disp32 - 8314 # TODO: disallow vars of type 'byte' in registers 'esi' or 'edi' - 8315 # TODO: vars of type 'byte' should only be initialized by clearing to 0 - 8316 # ensure that the next word is '<-' - 8317 (next-mu-token *(ebp+8) %ecx) - 8318 (slice-equal? %ecx "<-") # => eax - 8319 3d/compare-eax-and 0/imm32/false - 8320 0f 84/jump-if-= $parse-mu-var-def:error1/disp32 - 8321 # - 8322 (new-reg-var-def Heap *edx *(edx+4) %edi) - 8323 (lookup *edi *(edi+4)) # => eax - 8324 (add-operation-and-inputs-to-stmt %eax *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 8325 } - 8326 $parse-mu-var-def:update-vars: - 8327 # push 'v' at end of function - 8328 (push *(ebp+0xc) *edx) - 8329 (push *(ebp+0xc) *(edx+4)) - 8330 (push *(ebp+0xc) 0) # Live-var-register-spilled is unused during parsing - 8331 $parse-mu-var-def:end: - 8332 # . reclaim locals - 8333 81 0/subop/add %esp 0x10/imm32 - 8334 # . restore registers - 8335 5f/pop-to-edi - 8336 5b/pop-to-ebx - 8337 5a/pop-to-edx - 8338 59/pop-to-ecx - 8339 58/pop-to-eax - 8340 # . epilogue - 8341 89/<- %esp 5/r32/ebp - 8342 5d/pop-to-ebp - 8343 c3/return - 8344 - 8345 $parse-mu-var-def:error1: - 8346 (rewind-stream *(ebp+8)) - 8347 # error("register variable requires a valid instruction to initialize but got '" line "'\n") - 8348 (write-buffered *(ebp+0x18) "register variable requires a valid instruction to initialize but got '") - 8349 (flush *(ebp+0x18)) - 8350 (write-stream-data *(ebp+0x18) *(ebp+8)) - 8351 (write-buffered *(ebp+0x18) "'\n") - 8352 (flush *(ebp+0x18)) - 8353 (stop *(ebp+0x1c) 1) - 8354 # never gets here - 8355 - 8356 $parse-mu-var-def:error2: - 8357 (rewind-stream *(ebp+8)) - 8358 # error("fn " fn ": var " var ": variables on the stack can't take an initializer\n") - 8359 (write-buffered *(ebp+0x18) "fn ") - 8360 8b/-> *(ebp+0x14) 0/r32/eax - 8361 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 8362 (write-buffered *(ebp+0x18) %eax) - 8363 (write-buffered *(ebp+0x18) ": var ") - 8364 # var v-addr/eax: (addr var) = lookup(v) - 8365 (lookup *edx *(edx+4)) # => eax - 8366 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 8367 (write-buffered *(ebp+0x18) %eax) - 8368 (write-buffered *(ebp+0x18) ": variables on the stack can't take an initializer\n") - 8369 (flush *(ebp+0x18)) - 8370 (stop *(ebp+0x1c) 1) - 8371 # never gets here - 8372 - 8373 test-parse-mu-var-def: - 8374 # 'var n: int' - 8375 # . prologue - 8376 55/push-ebp - 8377 89/<- %ebp 4/r32/esp - 8378 # setup - 8379 (clear-stream _test-input-stream) - 8380 (write _test-input-stream "n: int\n") # caller has consumed the 'var' - 8381 c7 0/subop/copy *Curr-block-depth 1/imm32 - 8382 # var out/esi: (handle stmt) - 8383 68/push 0/imm32 - 8384 68/push 0/imm32 - 8385 89/<- %esi 4/r32/esp - 8386 # var vars/ecx: (stack (addr var) 16) - 8387 81 5/subop/subtract %esp 0xc0/imm32 - 8388 68/push 0xc0/imm32/size - 8389 68/push 0/imm32/top - 8390 89/<- %ecx 4/r32/esp - 8391 (clear-stack %ecx) - 8392 # convert - 8393 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) - 8394 # var out-addr/esi: (addr stmt) - 8395 (lookup *esi *(esi+4)) # => eax - 8396 89/<- %esi 0/r32/eax - 8397 # - 8398 (check-ints-equal *esi 2 "F - test-parse-mu-var-def/tag") # Stmt-tag is var-def - 8399 # var v/ecx: (addr var) = lookup(out->var) - 8400 (lookup *(esi+4) *(esi+8)) # Vardef-var Vardef-var => eax - 8401 89/<- %ecx 0/r32/eax - 8402 # v->name - 8403 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 8404 (check-strings-equal %eax "n" "F - test-parse-mu-var-def/var-name") - 8405 # v->register - 8406 (check-ints-equal *(ecx+0x18) 0 "F - test-parse-mu-var-def/var-register") # Var-register - 8407 # v->block-depth - 8408 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-var-def/output-block-depth") # Var-block-depth - 8409 # v->type == int - 8410 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 8411 (check-ints-equal *eax 1 "F - test-parse-mu-var-def/var-type:0") # Type-tree-is-atom - 8412 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-var-def/var-type:1") # Type-tree-value - 8413 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-var-def/var-type:2") # Type-tree-right + 8272 # (eax..ecx) = "A$" + 8273 b8/copy-to-eax "A$"/imm32 + 8274 8b/-> *eax 1/r32/ecx + 8275 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8276 05/add-to-eax 4/imm32 + 8277 # var slice/ecx: slice = {eax, ecx} + 8278 51/push-ecx + 8279 50/push-eax + 8280 89/<- %ecx 4/r32/esp + 8281 # + 8282 (is-identifier? %ecx) + 8283 (check-ints-equal %eax 1 "F - test-is-identifier-A") + 8284 # . epilogue + 8285 89/<- %esp 5/r32/ebp + 8286 5d/pop-to-ebp + 8287 c3/return + 8288 + 8289 test-is-identifier-Z: + 8290 # . prologue + 8291 55/push-ebp + 8292 89/<- %ebp 4/r32/esp + 8293 # (eax..ecx) = "Z$" + 8294 b8/copy-to-eax "Z$"/imm32 + 8295 8b/-> *eax 1/r32/ecx + 8296 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8297 05/add-to-eax 4/imm32 + 8298 # var slice/ecx: slice = {eax, ecx} + 8299 51/push-ecx + 8300 50/push-eax + 8301 89/<- %ecx 4/r32/esp + 8302 # + 8303 (is-identifier? %ecx) + 8304 (check-ints-equal %eax 1 "F - test-is-identifier-Z") + 8305 # . epilogue + 8306 89/<- %esp 5/r32/ebp + 8307 5d/pop-to-ebp + 8308 c3/return + 8309 + 8310 test-is-identifier-at: + 8311 # character before 'A' is invalid + 8312 # . prologue + 8313 55/push-ebp + 8314 89/<- %ebp 4/r32/esp + 8315 # (eax..ecx) = "@a" + 8316 b8/copy-to-eax "@a"/imm32 + 8317 8b/-> *eax 1/r32/ecx + 8318 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8319 05/add-to-eax 4/imm32 + 8320 # var slice/ecx: slice = {eax, ecx} + 8321 51/push-ecx + 8322 50/push-eax + 8323 89/<- %ecx 4/r32/esp + 8324 # + 8325 (is-identifier? %ecx) + 8326 (check-ints-equal %eax 0 "F - test-is-identifier-@") + 8327 # . epilogue + 8328 89/<- %esp 5/r32/ebp + 8329 5d/pop-to-ebp + 8330 c3/return + 8331 + 8332 test-is-identifier-square-bracket: + 8333 # character after 'Z' is invalid + 8334 # . prologue + 8335 55/push-ebp + 8336 89/<- %ebp 4/r32/esp + 8337 # (eax..ecx) = "[a" + 8338 b8/copy-to-eax "[a"/imm32 + 8339 8b/-> *eax 1/r32/ecx + 8340 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8341 05/add-to-eax 4/imm32 + 8342 # var slice/ecx: slice = {eax, ecx} + 8343 51/push-ecx + 8344 50/push-eax + 8345 89/<- %ecx 4/r32/esp + 8346 # + 8347 (is-identifier? %ecx) + 8348 (check-ints-equal %eax 0 "F - test-is-identifier-@") + 8349 # . epilogue + 8350 89/<- %esp 5/r32/ebp + 8351 5d/pop-to-ebp + 8352 c3/return + 8353 + 8354 test-is-identifier-backtick: + 8355 # character before 'a' is invalid + 8356 # . prologue + 8357 55/push-ebp + 8358 89/<- %ebp 4/r32/esp + 8359 # (eax..ecx) = "`a" + 8360 b8/copy-to-eax "`a"/imm32 + 8361 8b/-> *eax 1/r32/ecx + 8362 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8363 05/add-to-eax 4/imm32 + 8364 # var slice/ecx: slice = {eax, ecx} + 8365 51/push-ecx + 8366 50/push-eax + 8367 89/<- %ecx 4/r32/esp + 8368 # + 8369 (is-identifier? %ecx) + 8370 (check-ints-equal %eax 0 "F - test-is-identifier-backtick") + 8371 # . epilogue + 8372 89/<- %esp 5/r32/ebp + 8373 5d/pop-to-ebp + 8374 c3/return + 8375 + 8376 test-is-identifier-curly-brace-open: + 8377 # character after 'z' is invalid; also used for blocks + 8378 # . prologue + 8379 55/push-ebp + 8380 89/<- %ebp 4/r32/esp + 8381 # (eax..ecx) = "{a" + 8382 b8/copy-to-eax "{a"/imm32 + 8383 8b/-> *eax 1/r32/ecx + 8384 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8385 05/add-to-eax 4/imm32 + 8386 # var slice/ecx: slice = {eax, ecx} + 8387 51/push-ecx + 8388 50/push-eax + 8389 89/<- %ecx 4/r32/esp + 8390 # + 8391 (is-identifier? %ecx) + 8392 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-open") + 8393 # . epilogue + 8394 89/<- %esp 5/r32/ebp + 8395 5d/pop-to-ebp + 8396 c3/return + 8397 + 8398 test-is-identifier-curly-brace-close: + 8399 # . prologue + 8400 55/push-ebp + 8401 89/<- %ebp 4/r32/esp + 8402 # (eax..ecx) = "}a" + 8403 b8/copy-to-eax "}a"/imm32 + 8404 8b/-> *eax 1/r32/ecx + 8405 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8406 05/add-to-eax 4/imm32 + 8407 # var slice/ecx: slice = {eax, ecx} + 8408 51/push-ecx + 8409 50/push-eax + 8410 89/<- %ecx 4/r32/esp + 8411 # + 8412 (is-identifier? %ecx) + 8413 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-close") 8414 # . epilogue 8415 89/<- %esp 5/r32/ebp 8416 5d/pop-to-ebp 8417 c3/return 8418 - 8419 test-parse-mu-reg-var-def: - 8420 # 'var n/eax: int <- copy 0' + 8419 test-is-identifier-hyphen: + 8420 # disallow leading '-' since '->' has special meaning 8421 # . prologue 8422 55/push-ebp 8423 89/<- %ebp 4/r32/esp - 8424 # setup - 8425 (clear-stream _test-input-stream) - 8426 (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var' - 8427 c7 0/subop/copy *Curr-block-depth 1/imm32 - 8428 # var out/esi: (handle stmt) - 8429 68/push 0/imm32 - 8430 68/push 0/imm32 - 8431 89/<- %esi 4/r32/esp - 8432 # var vars/ecx: (stack (addr var) 16) - 8433 81 5/subop/subtract %esp 0xc0/imm32 - 8434 68/push 0xc0/imm32/size - 8435 68/push 0/imm32/top - 8436 89/<- %ecx 4/r32/esp - 8437 (clear-stack %ecx) - 8438 # convert - 8439 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) - 8440 # var out-addr/esi: (addr stmt) - 8441 (lookup *esi *(esi+4)) # => eax - 8442 89/<- %esi 0/r32/eax - 8443 # - 8444 (check-ints-equal *esi 3 "F - test-parse-mu-reg-var-def/tag") # Stmt-tag is reg-var-def - 8445 # var v/ecx: (addr var) = lookup(out->outputs->value) - 8446 # . eax: (addr stmt-var) = lookup(out->outputs) - 8447 (lookup *(esi+0x14) *(esi+0x18)) # Regvardef-outputs Regvardef-outputs => eax - 8448 # . - 8449 (check-ints-equal *(eax+8) 0 "F - test-parse-mu-reg-var-def/single-output") # Stmt-var-next - 8450 # . eax: (addr var) = lookup(eax->value) - 8451 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 8452 # . ecx = eax - 8453 89/<- %ecx 0/r32/eax - 8454 # v->name - 8455 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 8456 (check-strings-equal %eax "n" "F - test-parse-mu-reg-var-def/output-name") # Var-name - 8457 # v->register - 8458 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax - 8459 (check-strings-equal %eax "eax" "F - test-parse-mu-reg-var-def/output-register") - 8460 # v->block-depth - 8461 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-reg-var-def/output-block-depth") # Var-block-depth - 8462 # v->type == int - 8463 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 8464 (check-ints-equal *eax 1 "F - test-parse-mu-reg-var-def/output-type:0") # Type-tree-is-atom - 8465 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-reg-var-def/output-type:1") # Type-tree-value - 8466 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-reg-var-def/output-type:2") # Type-tree-right - 8467 # . epilogue - 8468 89/<- %esp 5/r32/ebp - 8469 5d/pop-to-ebp - 8470 c3/return - 8471 - 8472 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) - 8473 # Carefully push any outputs on the vars stack _after_ reading the inputs - 8474 # that may conflict with them. - 8475 # - 8476 # The only situation in which outputs are pushed here (when it's not a - 8477 # 'var' vardef stmt), and so can possibly conflict with inputs, is if the - 8478 # output is a function output. - 8479 # - 8480 # pseudocode: - 8481 # var name: slice - 8482 # allocate(Heap, Stmt-size, out) - 8483 # var out-addr: (addr stmt) = lookup(*out) - 8484 # out-addr->tag = stmt - 8485 # if stmt-has-outputs?(line) - 8486 # while true - 8487 # name = next-mu-token(line) - 8488 # if (name == '<-') break - 8489 # assert(is-identifier?(name)) - 8490 # var v: (handle var) = lookup-var-or-find-in-fn-outputs(name, vars, fn) - 8491 # out-addr->outputs = append(v, out-addr->outputs) - 8492 # add-operation-and-inputs-to-stmt(out-addr, line, vars) - 8493 # for output in stmt->outputs: - 8494 # maybe-define-var(output, vars) - 8495 # - 8496 # . prologue - 8497 55/push-ebp - 8498 89/<- %ebp 4/r32/esp - 8499 # . save registers - 8500 50/push-eax - 8501 51/push-ecx - 8502 52/push-edx - 8503 53/push-ebx - 8504 57/push-edi - 8505 # var name/ecx: slice - 8506 68/push 0/imm32/end - 8507 68/push 0/imm32/start - 8508 89/<- %ecx 4/r32/esp - 8509 # var is-deref?/edx: boolean = false - 8510 ba/copy-to-edx 0/imm32/false - 8511 # var v: (handle var) - 8512 68/push 0/imm32 - 8513 68/push 0/imm32 - 8514 89/<- %ebx 4/r32/esp - 8515 # - 8516 (allocate Heap *Stmt-size *(ebp+0x14)) - 8517 # var out-addr/edi: (addr stmt) = lookup(*out) - 8518 8b/-> *(ebp+0x14) 7/r32/edi - 8519 (lookup *edi *(edi+4)) # => eax - 8520 89/<- %edi 0/r32/eax - 8521 # out-addr->tag = 1/stmt - 8522 c7 0/subop/copy *edi 1/imm32/stmt1 # Stmt-tag - 8523 { - 8524 (stmt-has-outputs? *(ebp+8)) - 8525 3d/compare-eax-and 0/imm32/false - 8526 0f 84/jump-if-= break/disp32 - 8527 { - 8528 $parse-mu-stmt:read-outputs: - 8529 # name = next-mu-token(line) - 8530 (next-mu-token *(ebp+8) %ecx) - 8531 # if slice-empty?(word-slice) break - 8532 (slice-empty? %ecx) # => eax - 8533 3d/compare-eax-and 0/imm32/false - 8534 0f 85/jump-if-!= break/disp32 - 8535 # if (name == "<-") break - 8536 (slice-equal? %ecx "<-") # => eax - 8537 3d/compare-eax-and 0/imm32/false - 8538 0f 85/jump-if-!= break/disp32 - 8539 # is-deref? = false - 8540 ba/copy-to-edx 0/imm32/false - 8541 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? - 8542 8b/-> *ecx 0/r32/eax # Slice-start - 8543 8a/copy-byte *eax 0/r32/AL - 8544 81 4/subop/and %eax 0xff/imm32 - 8545 3d/compare-eax-and 0x2a/imm32/asterisk - 8546 { - 8547 75/jump-if-!= break/disp8 - 8548 ff 0/subop/increment *ecx - 8549 ba/copy-to-edx 1/imm32/true - 8550 } - 8551 # assert(is-identifier?(name)) - 8552 (is-identifier? %ecx) # => eax - 8553 3d/compare-eax-and 0/imm32/false - 8554 0f 84/jump-if-= $parse-mu-stmt:abort/disp32 - 8555 # - 8556 (lookup-var-or-find-in-fn-outputs %ecx *(ebp+0xc) *(ebp+0x10) %ebx *(ebp+0x18) *(ebp+0x1c)) - 8557 8d/copy-address *(edi+0x14) 0/r32/eax # Stmt1-outputs - 8558 (append-stmt-var Heap *ebx *(ebx+4) *(edi+0x14) *(edi+0x18) %edx %eax) # Stmt1-outputs - 8559 # - 8560 e9/jump loop/disp32 - 8561 } - 8562 } - 8563 (add-operation-and-inputs-to-stmt %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) - 8564 $parse-mu-stmt:define-outputs: - 8565 # var output/edi: (addr stmt-var) = lookup(out-addr->outputs) - 8566 (lookup *(edi+0x14) *(edi+0x18)) # Stmt1-outputs Stmt1-outputs => eax - 8567 89/<- %edi 0/r32/eax - 8568 { - 8569 $parse-mu-stmt:define-outputs-loop: - 8570 # if (output == null) break - 8571 81 7/subop/compare %edi 0/imm32 - 8572 74/jump-if-= break/disp8 - 8573 # - 8574 (maybe-define-var *edi *(edi+4) *(ebp+0xc)) # if output is a deref, then it's already been defined, - 8575 # and must be in vars. This call will be a no-op, but safe. - 8576 # output = output->next - 8577 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax - 8578 89/<- %edi 0/r32/eax - 8579 # - 8580 eb/jump loop/disp8 - 8581 } - 8582 $parse-mu-stmt:end: - 8583 # . reclaim locals - 8584 81 0/subop/add %esp 0x10/imm32 - 8585 # . restore registers - 8586 5f/pop-to-edi - 8587 5b/pop-to-ebx - 8588 5a/pop-to-edx - 8589 59/pop-to-ecx - 8590 58/pop-to-eax - 8591 # . epilogue - 8592 89/<- %esp 5/r32/ebp - 8593 5d/pop-to-ebp - 8594 c3/return - 8595 - 8596 $parse-mu-stmt:abort: - 8597 # error("invalid identifier '" name "'\n") - 8598 (write-buffered *(ebp+0x18) "invalid identifier '") - 8599 (write-slice-buffered *(ebp+0x18) %ecx) - 8600 (write-buffered *(ebp+0x18) "'\n") - 8601 (flush *(ebp+0x18)) - 8602 (stop *(ebp+0x1c) 1) - 8603 # never gets here - 8604 - 8605 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) - 8606 # pseudocode: - 8607 # stmt->name = slice-to-string(next-mu-token(line)) - 8608 # while true - 8609 # name = next-mu-token(line) - 8610 # v = lookup-var-or-literal(name) - 8611 # stmt->inouts = append(v, stmt->inouts) - 8612 # - 8613 # . prologue - 8614 55/push-ebp - 8615 89/<- %ebp 4/r32/esp - 8616 # . save registers - 8617 50/push-eax - 8618 51/push-ecx - 8619 52/push-edx - 8620 53/push-ebx - 8621 56/push-esi - 8622 57/push-edi - 8623 # edi = stmt - 8624 8b/-> *(ebp+8) 7/r32/edi - 8625 # var name/ecx: slice - 8626 68/push 0/imm32/end - 8627 68/push 0/imm32/start - 8628 89/<- %ecx 4/r32/esp - 8629 # var is-deref?/edx: boolean = false - 8630 ba/copy-to-edx 0/imm32/false - 8631 # var v/esi: (handle var) - 8632 68/push 0/imm32 - 8633 68/push 0/imm32 - 8634 89/<- %esi 4/r32/esp - 8635 $add-operation-and-inputs-to-stmt:read-operation: - 8636 (next-mu-token *(ebp+0xc) %ecx) - 8637 8d/copy-address *(edi+4) 0/r32/eax # Stmt1-operation or Regvardef-operationStmt1-operation or Regvardef-operation - 8638 (slice-to-string Heap %ecx %eax) - 8639 # var is-get?/ebx: boolean = (name == "get") - 8640 (slice-equal? %ecx "get") # => eax - 8641 89/<- %ebx 0/r32/eax - 8642 { - 8643 $add-operation-and-inputs-to-stmt:read-inouts: - 8644 # name = next-mu-token(line) - 8645 (next-mu-token *(ebp+0xc) %ecx) - 8646 # if slice-empty?(word-slice) break - 8647 (slice-empty? %ecx) # => eax - 8648 3d/compare-eax-and 0/imm32/false - 8649 0f 85/jump-if-!= break/disp32 - 8650 # if (name == "<-") abort - 8651 (slice-equal? %ecx "<-") - 8652 3d/compare-eax-and 0/imm32/false - 8653 0f 85/jump-if-!= $add-operation-and-inputs-to-stmt:abort/disp32 - 8654 # if (is-get? && second operand) lookup or create offset - 8655 { - 8656 81 7/subop/compare %ebx 0/imm32/false - 8657 74/jump-if-= break/disp8 - 8658 (lookup *(edi+0xc) *(edi+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 8659 3d/compare-eax-and 0/imm32 - 8660 74/jump-if-= break/disp8 - 8661 (lookup-or-create-constant %eax %ecx %esi) - 8662 #? (lookup *esi *(esi+4)) - 8663 #? (write-buffered Stderr "creating new output var ") - 8664 #? (write-int32-hex-buffered Stderr %eax) - 8665 #? (write-buffered Stderr " for field called ") - 8666 #? (write-slice-buffered Stderr %ecx) - 8667 #? (write-buffered Stderr "; var name ") - 8668 #? (lookup *eax *(eax+4)) # Var-name - 8669 #? (write-buffered Stderr %eax) - 8670 #? (write-buffered Stderr Newline) - 8671 #? (flush Stderr) - 8672 e9/jump $add-operation-and-inputs-to-stmt:save-var/disp32 - 8673 } - 8674 # is-deref? = false - 8675 ba/copy-to-edx 0/imm32/false - 8676 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? - 8677 8b/-> *ecx 0/r32/eax # Slice-start - 8678 8a/copy-byte *eax 0/r32/AL - 8679 81 4/subop/and %eax 0xff/imm32 - 8680 3d/compare-eax-and 0x2a/imm32/asterisk - 8681 { - 8682 75/jump-if-!= break/disp8 - 8683 $add-operation-and-inputs-to-stmt:inout-is-deref: - 8684 ff 0/subop/increment *ecx - 8685 ba/copy-to-edx 1/imm32/true - 8686 } - 8687 (lookup-var-or-literal %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 8688 $add-operation-and-inputs-to-stmt:save-var: - 8689 8d/copy-address *(edi+0xc) 0/r32/eax - 8690 (append-stmt-var Heap *esi *(esi+4) *(edi+0xc) *(edi+0x10) %edx %eax) # Stmt1-inouts or Regvardef-inouts - 8691 # - 8692 e9/jump loop/disp32 - 8693 } - 8694 $add-operation-and-inputs-to-stmt:end: - 8695 # . reclaim locals - 8696 81 0/subop/add %esp 0x10/imm32 - 8697 # . restore registers - 8698 5f/pop-to-edi - 8699 5e/pop-to-esi - 8700 5b/pop-to-ebx - 8701 5a/pop-to-edx - 8702 59/pop-to-ecx - 8703 58/pop-to-eax - 8704 # . epilogue - 8705 89/<- %esp 5/r32/ebp - 8706 5d/pop-to-ebp - 8707 c3/return - 8708 - 8709 $add-operation-and-inputs-to-stmt:abort: - 8710 # error("fn ___: invalid identifier in '" line "'\n") - 8711 (write-buffered *(ebp+0x18) "fn ") - 8712 8b/-> *(ebp+0x14) 0/r32/eax - 8713 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 8714 (write-buffered *(ebp+0x18) %eax) - 8715 (rewind-stream *(ebp+0xc)) - 8716 (write-buffered *(ebp+0x18) ": invalid identifier in '") - 8717 (write-stream-data *(ebp+0x18) *(ebp+0xc)) - 8718 (write-buffered *(ebp+0x18) "'\n") - 8719 (flush *(ebp+0x18)) - 8720 (stop *(ebp+0x1c) 1) - 8721 # never gets here - 8722 - 8723 stmt-has-outputs?: # line: (addr stream byte) -> result/eax: boolean - 8724 # . prologue - 8725 55/push-ebp - 8726 89/<- %ebp 4/r32/esp - 8727 # . save registers - 8728 51/push-ecx - 8729 # var word-slice/ecx: slice - 8730 68/push 0/imm32/end - 8731 68/push 0/imm32/start - 8732 89/<- %ecx 4/r32/esp - 8733 # result = false - 8734 b8/copy-to-eax 0/imm32/false - 8735 (rewind-stream *(ebp+8)) - 8736 { - 8737 (next-mu-token *(ebp+8) %ecx) - 8738 # if slice-empty?(word-slice) break - 8739 (slice-empty? %ecx) - 8740 3d/compare-eax-and 0/imm32/false - 8741 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) - 8742 0f 85/jump-if-!= break/disp32 - 8743 # if slice-starts-with?(word-slice, '#') break - 8744 # . eax = *word-slice->start - 8745 8b/-> *ecx 0/r32/eax - 8746 8a/copy-byte *eax 0/r32/AL - 8747 81 4/subop/and %eax 0xff/imm32 - 8748 # . if (eax == '#') break - 8749 3d/compare-eax-and 0x23/imm32/hash - 8750 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) - 8751 0f 84/jump-if-= break/disp32 - 8752 # if slice-equal?(word-slice, '<-') return true - 8753 (slice-equal? %ecx "<-") - 8754 3d/compare-eax-and 0/imm32/false - 8755 74/jump-if-= loop/disp8 - 8756 b8/copy-to-eax 1/imm32/true - 8757 } - 8758 $stmt-has-outputs:end: - 8759 (rewind-stream *(ebp+8)) - 8760 # . reclaim locals - 8761 81 0/subop/add %esp 8/imm32 - 8762 # . restore registers - 8763 59/pop-to-ecx - 8764 # . epilogue - 8765 89/<- %esp 5/r32/ebp - 8766 5d/pop-to-ebp - 8767 c3/return - 8768 - 8769 # if 'name' starts with a digit, create a new literal var for it - 8770 # otherwise return first 'name' from the top (back) of 'vars' and abort if not found - 8771 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) - 8772 # . prologue - 8773 55/push-ebp - 8774 89/<- %ebp 4/r32/esp - 8775 # . save registers - 8776 50/push-eax - 8777 51/push-ecx - 8778 56/push-esi - 8779 # esi = name - 8780 8b/-> *(ebp+8) 6/r32/esi - 8781 # if slice-empty?(name) abort - 8782 (slice-empty? %esi) # => eax - 8783 3d/compare-eax-and 0/imm32/false - 8784 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32 - 8785 # var c/ecx: byte = *name->start - 8786 8b/-> *esi 1/r32/ecx - 8787 8a/copy-byte *ecx 1/r32/CL - 8788 81 4/subop/and %ecx 0xff/imm32 - 8789 # if is-decimal-digit?(c) return new var(name) - 8790 { - 8791 (is-decimal-digit? %ecx) # => eax - 8792 3d/compare-eax-and 0/imm32/false - 8793 74/jump-if-= break/disp8 - 8794 $lookup-var-or-literal:literal: - 8795 (new-literal-integer Heap %esi *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) - 8796 eb/jump $lookup-var-or-literal:end/disp8 - 8797 } - 8798 # else if (c == '"') return new var(name) - 8799 { - 8800 81 7/subop/compare %ecx 0x22/imm32/dquote - 8801 75/jump-if-!= break/disp8 - 8802 $lookup-var-or-literal:literal-string: - 8803 (new-literal Heap %esi *(ebp+0x10)) - 8804 eb/jump $lookup-var-or-literal:end/disp8 - 8805 } - 8806 # otherwise return lookup-var(name, vars) - 8807 { - 8808 $lookup-var-or-literal:var: - 8809 (lookup-var %esi *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 8810 } - 8811 $lookup-var-or-literal:end: - 8812 # . restore registers - 8813 5e/pop-to-esi - 8814 59/pop-to-ecx - 8815 58/pop-to-eax - 8816 # . epilogue - 8817 89/<- %esp 5/r32/ebp - 8818 5d/pop-to-ebp - 8819 c3/return - 8820 - 8821 $lookup-var-or-literal:abort: - 8822 (write-buffered *(ebp+0x18) "fn ") - 8823 8b/-> *(ebp+0x14) 0/r32/eax - 8824 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 8825 (write-buffered *(ebp+0x18) %eax) - 8826 (write-buffered *(ebp+0x18) ": empty variable!") - 8827 (flush *(ebp+0x18)) - 8828 (stop *(ebp+0x1c) 1) - 8829 # never gets here - 8830 - 8831 # return first 'name' from the top (back) of 'vars' and abort if not found - 8832 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) - 8833 # . prologue - 8834 55/push-ebp - 8835 89/<- %ebp 4/r32/esp - 8836 # . save registers - 8837 50/push-eax - 8838 # - 8839 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 8840 # if (*out == 0) abort - 8841 8b/-> *(ebp+0x10) 0/r32/eax - 8842 81 7/subop/compare *eax 0/imm32 - 8843 74/jump-if-= $lookup-var:abort/disp8 - 8844 $lookup-var:end: - 8845 # . restore registers - 8846 58/pop-to-eax - 8847 # . epilogue - 8848 89/<- %esp 5/r32/ebp - 8849 5d/pop-to-ebp - 8850 c3/return - 8851 - 8852 $lookup-var:abort: - 8853 (write-buffered *(ebp+0x18) "fn ") - 8854 8b/-> *(ebp+0x14) 0/r32/eax - 8855 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 8856 (write-buffered *(ebp+0x18) %eax) - 8857 (write-buffered *(ebp+0x18) ": unknown variable '") - 8858 (write-slice-buffered *(ebp+0x18) *(ebp+8)) - 8859 (write-buffered *(ebp+0x18) "'\n") - 8860 (flush *(ebp+0x18)) - 8861 (stop *(ebp+0x1c) 1) - 8862 # never gets here - 8863 - 8864 # return first 'name' from the top (back) of 'vars', and 0/null if not found - 8865 # ensure that 'name' if in a register is the topmost variable in that register - 8866 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) - 8867 # pseudocode: - 8868 # var curr: (addr handle var) = &vars->data[vars->top - 12] - 8869 # var min = vars->data - 8870 # while curr >= min - 8871 # var v: (handle var) = *curr - 8872 # if v->name == name - 8873 # return - 8874 # curr -= 12 - 8875 # - 8876 # . prologue - 8877 55/push-ebp - 8878 89/<- %ebp 4/r32/esp - 8879 # . save registers - 8880 50/push-eax - 8881 51/push-ecx - 8882 52/push-edx - 8883 53/push-ebx - 8884 56/push-esi - 8885 57/push-edi - 8886 # clear out - 8887 (zero-out *(ebp+0x10) *Handle-size) - 8888 # esi = vars - 8889 8b/-> *(ebp+0xc) 6/r32/esi - 8890 # ebx = vars->top - 8891 8b/-> *esi 3/r32/ebx - 8892 # if (vars->top > vars->size) abort - 8893 3b/compare<- *(esi+4) 0/r32/eax - 8894 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 - 8895 # var min/edx: (addr handle var) = vars->data - 8896 8d/copy-address *(esi+8) 2/r32/edx - 8897 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] - 8898 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 - 8899 # var var-in-reg/edi: 8 addrs - 8900 68/push 0/imm32 - 8901 68/push 0/imm32 - 8902 68/push 0/imm32 - 8903 68/push 0/imm32 - 8904 68/push 0/imm32 - 8905 68/push 0/imm32 - 8906 68/push 0/imm32 - 8907 68/push 0/imm32 - 8908 89/<- %edi 4/r32/esp - 8909 { - 8910 $lookup-var-helper:loop: - 8911 # if (curr < min) return - 8912 39/compare %ebx 2/r32/edx - 8913 0f 82/jump-if-addr< break/disp32 - 8914 # var v/ecx: (addr var) = lookup(*curr) - 8915 (lookup *ebx *(ebx+4)) # => eax - 8916 89/<- %ecx 0/r32/eax - 8917 # var vn/eax: (addr array byte) = lookup(v->name) - 8918 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 8919 # if (vn == name) return curr - 8920 (slice-equal? *(ebp+8) %eax) # => eax - 8921 3d/compare-eax-and 0/imm32/false - 8922 { - 8923 74/jump-if-= break/disp8 - 8924 $lookup-var-helper:found: - 8925 # var vr/eax: (addr array byte) = lookup(v->register) - 8926 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax - 8927 3d/compare-eax-and 0/imm32 - 8928 { - 8929 74/jump-if-= break/disp8 - 8930 $lookup-var-helper:found-register: - 8931 # var reg/eax: int = get(Registers, vr) - 8932 (get Mu-registers %eax 0xc "Mu-registers") # => eax - 8933 8b/-> *eax 0/r32/eax - 8934 # if (var-in-reg[reg]) error - 8935 8b/-> *(edi+eax<<2) 0/r32/eax - 8936 3d/compare-eax-and 0/imm32 - 8937 0f 85/jump-if-!= $lookup-var-helper:error2/disp32 - 8938 } - 8939 $lookup-var-helper:return: - 8940 # esi = out - 8941 8b/-> *(ebp+0x10) 6/r32/esi - 8942 # *out = *curr - 8943 8b/-> *ebx 0/r32/eax - 8944 89/<- *esi 0/r32/eax - 8945 8b/-> *(ebx+4) 0/r32/eax - 8946 89/<- *(esi+4) 0/r32/eax - 8947 # return - 8948 eb/jump $lookup-var-helper:end/disp8 - 8949 } - 8950 # 'name' not yet found; update var-in-reg if v in register - 8951 # . var vr/eax: (addr array byte) = lookup(v->register) - 8952 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax - 8953 # . if (var == 0) continue - 8954 3d/compare-eax-and 0/imm32 - 8955 74/jump-if-= $lookup-var-helper:continue/disp8 - 8956 # . var reg/eax: int = get(Registers, vr) - 8957 (get Mu-registers %eax 0xc "Mu-registers") # => eax - 8958 8b/-> *eax 0/r32/eax - 8959 # . if (var-in-reg[reg] == 0) var-in-reg[reg] = v - 8960 81 7/subop/compare *(edi+eax<<2) 0/imm32 - 8961 75/jump-if-!= $lookup-var-helper:continue/disp8 - 8962 89/<- *(edi+eax<<2) 1/r32/ecx - 8963 $lookup-var-helper:continue: - 8964 # curr -= 12 - 8965 81 5/subop/subtract %ebx 0xc/imm32 - 8966 e9/jump loop/disp32 - 8967 } - 8968 $lookup-var-helper:end: - 8969 # . reclaim locals - 8970 81 0/subop/add %esp 0x20/imm32 - 8971 # . restore registers - 8972 5f/pop-to-edi - 8973 5e/pop-to-esi - 8974 5b/pop-to-ebx - 8975 5a/pop-to-edx - 8976 59/pop-to-ecx - 8977 58/pop-to-eax - 8978 # . epilogue - 8979 89/<- %esp 5/r32/ebp - 8980 5d/pop-to-ebp - 8981 c3/return - 8982 - 8983 $lookup-var-helper:error1: - 8984 (write-buffered *(ebp+0x18) "fn ") - 8985 8b/-> *(ebp+0x14) 0/r32/eax - 8986 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 8987 (write-buffered *(ebp+0x18) %eax) - 8988 (write-buffered *(ebp+0x18) ": malformed stack when looking up '") - 8989 (write-slice-buffered *(ebp+0x18) *(ebp+8)) - 8990 (write-buffered *(ebp+0x18) "'\n") - 8991 (flush *(ebp+0x18)) - 8992 (stop *(ebp+0x1c) 1) - 8993 # never gets here - 8994 - 8995 $lookup-var-helper:error2: - 8996 # eax contains the conflicting var at this point - 8997 (write-buffered *(ebp+0x18) "fn ") - 8998 50/push-eax - 8999 8b/-> *(ebp+0x14) 0/r32/eax - 9000 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 9001 (write-buffered *(ebp+0x18) %eax) - 9002 58/pop-eax - 9003 (write-buffered *(ebp+0x18) ": register ") - 9004 50/push-eax - 9005 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax - 9006 (write-buffered *(ebp+0x18) %eax) - 9007 58/pop-to-eax - 9008 (write-buffered *(ebp+0x18) " reads var '") - 9009 (write-slice-buffered *(ebp+0x18) *(ebp+8)) - 9010 (write-buffered *(ebp+0x18) "' after writing var '") - 9011 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 9012 (write-buffered *(ebp+0x18) %eax) - 9013 (write-buffered *(ebp+0x18) "'\n") - 9014 (flush *(ebp+0x18)) - 9015 (stop *(ebp+0x1c) 1) - 9016 # never gets here - 9017 - 9018 dump-vars: # vars: (addr stack live-var) - 9019 # pseudocode: - 9020 # var curr: (addr handle var) = &vars->data[vars->top - 12] - 9021 # var min = vars->data - 9022 # while curr >= min - 9023 # var v: (handle var) = *curr - 9024 # print v - 9025 # curr -= 12 - 9026 # - 9027 # . prologue - 9028 55/push-ebp - 9029 89/<- %ebp 4/r32/esp - 9030 # . save registers - 9031 52/push-edx - 9032 53/push-ebx - 9033 56/push-esi - 9034 # esi = vars - 9035 8b/-> *(ebp+8) 6/r32/esi - 9036 # ebx = vars->top - 9037 8b/-> *esi 3/r32/ebx - 9038 # var min/edx: (addr handle var) = vars->data - 9039 8d/copy-address *(esi+8) 2/r32/edx - 9040 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] - 9041 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 - 9042 { - 9043 $dump-vars:loop: - 9044 # if (curr < min) return - 9045 39/compare %ebx 2/r32/edx - 9046 0f 82/jump-if-addr< break/disp32 - 9047 # - 9048 (write-buffered Stderr " var@") - 9049 (dump-var 2 %ebx) - 9050 # curr -= 12 - 9051 81 5/subop/subtract %ebx 0xc/imm32 - 9052 e9/jump loop/disp32 - 9053 } - 9054 $dump-vars:end: - 9055 # . restore registers - 9056 5e/pop-to-esi - 9057 5b/pop-to-ebx - 9058 5a/pop-to-edx - 9059 # . epilogue - 9060 89/<- %esp 5/r32/ebp - 9061 5d/pop-to-ebp - 9062 c3/return - 9063 - 9064 == data - 9065 # Like Registers, but no esp or ebp - 9066 Mu-registers: # (addr stream {(handle array byte), int}) - 9067 # a table is a stream - 9068 0x48/imm32/write - 9069 0/imm32/read - 9070 0x48/imm32/length - 9071 # data - 9072 # it is perfectly ok to use fake alloc-ids -- as long as you never try to reclaim them - 9073 0x11/imm32/alloc-id $Mu-register-eax/imm32 0/imm32 - 9074 0x11/imm32/alloc-id $Mu-register-ecx/imm32 1/imm32 - 9075 0x11/imm32/alloc-id $Mu-register-edx/imm32 2/imm32 - 9076 0x11/imm32/alloc-id $Mu-register-ebx/imm32 3/imm32 - 9077 0x11/imm32/alloc-id $Mu-register-esi/imm32 6/imm32 - 9078 0x11/imm32/alloc-id $Mu-register-edi/imm32 7/imm32 - 9079 - 9080 $Mu-register-eax: - 9081 0x11/imm32/alloc-id - 9082 3/imm32/size - 9083 0x65/e 0x61/a 0x78/x - 9084 - 9085 $Mu-register-ecx: - 9086 0x11/imm32/alloc-id - 9087 3/imm32/size - 9088 0x65/e 0x63/c 0x78/x - 9089 - 9090 $Mu-register-edx: - 9091 0x11/imm32/alloc-id - 9092 3/imm32/size - 9093 0x65/e 0x64/d 0x78/x - 9094 - 9095 $Mu-register-ebx: - 9096 0x11/imm32/alloc-id - 9097 3/imm32/size - 9098 0x65/e 0x62/b 0x78/x - 9099 - 9100 $Mu-register-esi: - 9101 0x11/imm32/alloc-id - 9102 3/imm32/size - 9103 0x65/e 0x73/s 0x69/i - 9104 - 9105 $Mu-register-edi: - 9106 0x11/imm32/alloc-id - 9107 3/imm32/size - 9108 0x65/e 0x64/d 0x69/i - 9109 - 9110 == code - 9111 - 9112 # return first 'name' from the top (back) of 'vars' and create a new var for a fn output if not found - 9113 lookup-var-or-find-in-fn-outputs: # name: (addr slice), vars: (addr stack live-var), fn: (addr function), out: (addr handle var), err: (addr buffered-file), ed: (addr exit-descriptor) - 9114 # . prologue - 9115 55/push-ebp - 9116 89/<- %ebp 4/r32/esp - 9117 # . save registers - 9118 50/push-eax - 9119 # - 9120 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) # arg order slightly different; 'fn' is deemphasized - 9121 { - 9122 # if (out != 0) return - 9123 8b/-> *(ebp+0x14) 0/r32/eax - 9124 81 7/subop/compare *eax 0/imm32 - 9125 75/jump-if-!= break/disp8 - 9126 # if name is one of fn's outputs, return it - 9127 (find-in-function-outputs *(ebp+0x10) *(ebp+8) *(ebp+0x14)) - 9128 8b/-> *(ebp+0x14) 0/r32/eax - 9129 81 7/subop/compare *eax 0/imm32 - 9130 # otherwise abort - 9131 0f 84/jump-if-= $lookup-or-define-var:abort/disp32 - 9132 } - 9133 $lookup-or-define-var:end: - 9134 # . restore registers - 9135 58/pop-to-eax - 9136 # . epilogue - 9137 89/<- %esp 5/r32/ebp - 9138 5d/pop-to-ebp - 9139 c3/return - 9140 - 9141 $lookup-or-define-var:abort: - 9142 (write-buffered *(ebp+0x18) "unknown variable '") - 9143 (write-slice-buffered *(ebp+0x18) *(ebp+8)) - 9144 (write-buffered *(ebp+0x18) "'\n") - 9145 (flush *(ebp+0x18)) - 9146 (stop *(ebp+0x1c) 1) - 9147 # never gets here - 9148 - 9149 find-in-function-outputs: # fn: (addr function), name: (addr slice), out: (addr handle var) - 9150 # . prologue - 9151 55/push-ebp - 9152 89/<- %ebp 4/r32/esp - 9153 # . save registers - 9154 50/push-eax - 9155 51/push-ecx - 9156 # var curr/ecx: (addr list var) = lookup(fn->outputs) - 9157 8b/-> *(ebp+8) 1/r32/ecx - 9158 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax - 9159 89/<- %ecx 0/r32/eax - 9160 # while curr != null - 9161 { - 9162 81 7/subop/compare %ecx 0/imm32 - 9163 74/jump-if-= break/disp8 - 9164 # var v/eax: (addr var) = lookup(curr->value) - 9165 (lookup *ecx *(ecx+4)) # List-value List-value => eax - 9166 # var s/eax: (addr array byte) = lookup(v->name) - 9167 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 9168 # if (s == name) return curr->value - 9169 (slice-equal? *(ebp+0xc) %eax) # => eax - 9170 3d/compare-eax-and 0/imm32/false - 9171 { - 9172 74/jump-if-= break/disp8 - 9173 # var edi = out - 9174 57/push-edi - 9175 8b/-> *(ebp+0x10) 7/r32/edi - 9176 # *out = curr->value - 9177 8b/-> *ecx 0/r32/eax - 9178 89/<- *edi 0/r32/eax - 9179 8b/-> *(ecx+4) 0/r32/eax - 9180 89/<- *(edi+4) 0/r32/eax - 9181 # - 9182 5f/pop-to-edi - 9183 eb/jump $find-in-function-outputs:end/disp8 - 9184 } - 9185 # curr = curr->next - 9186 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax - 9187 89/<- %ecx 0/r32/eax - 9188 # - 9189 eb/jump loop/disp8 - 9190 } - 9191 b8/copy-to-eax 0/imm32 - 9192 $find-in-function-outputs:end: - 9193 # . restore registers - 9194 59/pop-to-ecx - 9195 58/pop-to-eax - 9196 # . epilogue - 9197 89/<- %esp 5/r32/ebp - 9198 5d/pop-to-ebp - 9199 c3/return - 9200 - 9201 # push 'out' to 'vars' if not already there; it's assumed to be a fn output - 9202 maybe-define-var: # out: (handle var), vars: (addr stack live-var) - 9203 # . prologue - 9204 55/push-ebp - 9205 89/<- %ebp 4/r32/esp - 9206 # . save registers - 9207 50/push-eax - 9208 # var out-addr/eax: (addr var) - 9209 (lookup *(ebp+8) *(ebp+0xc)) # => eax - 9210 # - 9211 (binding-exists? %eax *(ebp+0x10)) # => eax - 9212 3d/compare-eax-and 0/imm32/false - 9213 75/jump-if-!= $maybe-define-var:end/disp8 - 9214 # otherwise update vars - 9215 (push *(ebp+0x10) *(ebp+8)) - 9216 (push *(ebp+0x10) *(ebp+0xc)) - 9217 (push *(ebp+0x10) 0) # 'out' is always a fn output; never spill it - 9218 $maybe-define-var:end: - 9219 # . restore registers - 9220 58/pop-to-eax - 9221 # . epilogue - 9222 89/<- %esp 5/r32/ebp - 9223 5d/pop-to-ebp - 9224 c3/return - 9225 - 9226 # simpler version of lookup-var-helper - 9227 binding-exists?: # target: (addr var), vars: (addr stack live-var) -> result/eax: boolean - 9228 # pseudocode: - 9229 # var curr: (addr handle var) = &vars->data[vars->top - 12] - 9230 # var min = vars->data - 9231 # while curr >= min - 9232 # var v: (handle var) = *curr - 9233 # if v->name == target->name - 9234 # return true - 9235 # curr -= 12 - 9236 # return false - 9237 # - 9238 # . prologue - 9239 55/push-ebp - 9240 89/<- %ebp 4/r32/esp - 9241 # . save registers - 9242 51/push-ecx - 9243 52/push-edx - 9244 56/push-esi - 9245 # var target-name/ecx: (addr array byte) = lookup(target->name) - 9246 8b/-> *(ebp+8) 0/r32/eax - 9247 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 9248 89/<- %ecx 0/r32/eax - 9249 # esi = vars - 9250 8b/-> *(ebp+0xc) 6/r32/esi - 9251 # eax = vars->top - 9252 8b/-> *esi 0/r32/eax - 9253 # var min/edx: (addr handle var) = vars->data - 9254 8d/copy-address *(esi+8) 2/r32/edx - 9255 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] - 9256 8d/copy-address *(esi+eax-4) 6/r32/esi # vars + 8 + vars->type - 12 - 9257 { - 9258 $binding-exists?:loop: - 9259 # if (curr < min) return - 9260 39/compare %esi 2/r32/edx - 9261 0f 82/jump-if-addr< break/disp32 - 9262 # var v/eax: (addr var) = lookup(*curr) - 9263 (lookup *esi *(esi+4)) # => eax - 9264 # var vn/eax: (addr array byte) = lookup(v->name) - 9265 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 9266 # if (vn == target-name) return true - 9267 (string-equal? %ecx %eax) # => eax - 9268 3d/compare-eax-and 0/imm32/false - 9269 75/jump-if-!= $binding-exists?:end/disp8 # eax already contains true - 9270 # curr -= 12 - 9271 81 5/subop/subtract %esi 0xc/imm32 - 9272 e9/jump loop/disp32 - 9273 } - 9274 b8/copy-to-eax 0/imm32/false - 9275 $binding-exists?:end: - 9276 # . restore registers - 9277 5e/pop-to-esi - 9278 5a/pop-to-edx - 9279 59/pop-to-ecx - 9280 # . epilogue - 9281 89/<- %esp 5/r32/ebp - 9282 5d/pop-to-ebp - 9283 c3/return - 9284 - 9285 test-parse-mu-stmt: - 9286 # . prologue - 9287 55/push-ebp - 9288 89/<- %ebp 4/r32/esp - 9289 # setup - 9290 (clear-stream _test-input-stream) - 9291 (write _test-input-stream "increment n\n") - 9292 # var vars/ecx: (stack (addr var) 16) - 9293 81 5/subop/subtract %esp 0xc0/imm32 - 9294 68/push 0xc0/imm32/size - 9295 68/push 0/imm32/top - 9296 89/<- %ecx 4/r32/esp - 9297 (clear-stack %ecx) - 9298 # var v/edx: (handle var) - 9299 68/push 0/imm32 - 9300 68/push 0/imm32 - 9301 89/<- %edx 4/r32/esp - 9302 # var s/eax: (handle array byte) - 9303 68/push 0/imm32 - 9304 68/push 0/imm32 - 9305 89/<- %eax 4/r32/esp - 9306 # v = new var("n") - 9307 (copy-array Heap "n" %eax) - 9308 (new-var Heap *eax *(eax+4) %edx) - 9309 # - 9310 (push %ecx *edx) - 9311 (push %ecx *(edx+4)) - 9312 (push %ecx 0) - 9313 # var out/eax: (handle stmt) - 9314 68/push 0/imm32 - 9315 68/push 0/imm32 - 9316 89/<- %eax 4/r32/esp - 9317 # convert - 9318 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) - 9319 # var out-addr/edx: (addr stmt) = lookup(*out) - 9320 (lookup *eax *(eax+4)) # => eax - 9321 89/<- %edx 0/r32/eax - 9322 # out->tag - 9323 (check-ints-equal *edx 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 - 9324 # out->operation - 9325 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax - 9326 (check-strings-equal %eax "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation - 9327 # out->inouts->value->name - 9328 # . eax = out->inouts - 9329 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 9330 # . eax = out->inouts->value - 9331 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9332 # . eax = out->inouts->value->name - 9333 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 9334 # . - 9335 (check-strings-equal %eax "n" "F - test-parse-mu-stmt/inout:0") - 9336 # . epilogue - 9337 89/<- %esp 5/r32/ebp - 9338 5d/pop-to-ebp - 9339 c3/return - 9340 - 9341 test-parse-mu-stmt-with-comma: - 9342 # . prologue - 9343 55/push-ebp - 9344 89/<- %ebp 4/r32/esp - 9345 # setup - 9346 (clear-stream _test-input-stream) - 9347 (write _test-input-stream "copy-to n, 3\n") - 9348 # var vars/ecx: (stack (addr var) 16) - 9349 81 5/subop/subtract %esp 0xc0/imm32 - 9350 68/push 0xc0/imm32/size - 9351 68/push 0/imm32/top - 9352 89/<- %ecx 4/r32/esp - 9353 (clear-stack %ecx) - 9354 # var v/edx: (handle var) - 9355 68/push 0/imm32 - 9356 68/push 0/imm32 - 9357 89/<- %edx 4/r32/esp - 9358 # var s/eax: (handle array byte) - 9359 68/push 0/imm32 - 9360 68/push 0/imm32 - 9361 89/<- %eax 4/r32/esp - 9362 # v = new var("n") - 9363 (copy-array Heap "n" %eax) - 9364 (new-var Heap *eax *(eax+4) %edx) - 9365 # - 9366 (push %ecx *edx) - 9367 (push %ecx *(edx+4)) - 9368 (push %ecx 0) - 9369 # var out/eax: (handle stmt) - 9370 68/push 0/imm32 - 9371 68/push 0/imm32 - 9372 89/<- %eax 4/r32/esp - 9373 # convert - 9374 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) - 9375 # var out-addr/edx: (addr stmt) = lookup(*out) - 9376 (lookup *eax *(eax+4)) # => eax - 9377 89/<- %edx 0/r32/eax - 9378 # out->tag - 9379 (check-ints-equal *edx 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1 - 9380 # out->operation - 9381 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax - 9382 (check-strings-equal %eax "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation - 9383 # out->inouts->value->name - 9384 # . eax = out->inouts - 9385 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 9386 # . eax = out->inouts->value - 9387 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9388 # . eax = out->inouts->value->name - 9389 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 9390 # . - 9391 (check-strings-equal %eax "n" "F - test-parse-mu-stmt-with-comma/inout:0") - 9392 # . epilogue - 9393 89/<- %esp 5/r32/ebp - 9394 5d/pop-to-ebp - 9395 c3/return - 9396 - 9397 new-var: # ad: (addr allocation-descriptor), name: (handle array byte), out: (addr handle var) - 9398 # . prologue - 9399 55/push-ebp - 9400 89/<- %ebp 4/r32/esp - 9401 # . save registers - 9402 50/push-eax - 9403 51/push-ecx - 9404 # ecx = out - 9405 8b/-> *(ebp+0x14) 1/r32/ecx - 9406 # - 9407 (allocate *(ebp+8) *Var-size %ecx) - 9408 # var out-addr/eax: (addr var) - 9409 (lookup *ecx *(ecx+4)) # => eax - 9410 # out-addr->name = name - 9411 8b/-> *(ebp+0xc) 1/r32/ecx - 9412 89/<- *eax 1/r32/ecx # Var-name - 9413 8b/-> *(ebp+0x10) 1/r32/ecx - 9414 89/<- *(eax+4) 1/r32/ecx # Var-name - 9415 #? (write-buffered Stderr "var ") - 9416 #? (lookup *(ebp+0xc) *(ebp+0x10)) - 9417 #? (write-buffered Stderr %eax) - 9418 #? (write-buffered Stderr " at ") - 9419 #? 8b/-> *(ebp+0x14) 1/r32/ecx - 9420 #? (lookup *ecx *(ecx+4)) # => eax - 9421 #? (write-int32-hex-buffered Stderr %eax) - 9422 #? (write-buffered Stderr Newline) - 9423 #? (flush Stderr) - 9424 $new-var:end: - 9425 # . restore registers - 9426 59/pop-to-ecx - 9427 58/pop-to-eax - 9428 # . epilogue - 9429 89/<- %esp 5/r32/ebp - 9430 5d/pop-to-ebp - 9431 c3/return - 9432 - 9433 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) - 9434 # . prologue - 9435 55/push-ebp - 9436 89/<- %ebp 4/r32/esp - 9437 # . save registers - 9438 50/push-eax - 9439 51/push-ecx - 9440 # if (!is-hex-int?(name)) abort - 9441 (is-hex-int? *(ebp+0xc)) # => eax - 9442 3d/compare-eax-and 0/imm32/false - 9443 0f 84/jump-if-= $new-literal-integer:abort/disp32 - 9444 # out = new var(s) - 9445 (new-var-from-slice *(ebp+8) *(ebp+0xc) *(ebp+0x10)) - 9446 # var out-addr/ecx: (addr var) = lookup(*out) - 9447 8b/-> *(ebp+0x10) 0/r32/eax - 9448 (lookup *eax *(eax+4)) # => eax - 9449 89/<- %ecx 0/r32/eax - 9450 # out-addr->block-depth = *Curr-block-depth - 9451 8b/-> *Curr-block-depth 0/r32/eax - 9452 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth - 9453 # out-addr->type = new tree() - 9454 8d/copy-address *(ecx+8) 0/r32/eax # Var-type - 9455 (allocate *(ebp+8) *Type-tree-size %eax) - 9456 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 9457 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom - 9458 # nothing else to do; default type is 'literal' - 9459 $new-literal-integer:end: - 9460 # . reclaim locals - 9461 81 0/subop/add %esp 8/imm32 - 9462 # . restore registers - 9463 59/pop-to-ecx - 9464 58/pop-to-eax - 9465 # . epilogue - 9466 89/<- %esp 5/r32/ebp - 9467 5d/pop-to-ebp - 9468 c3/return - 9469 - 9470 $new-literal-integer:abort: - 9471 (write-buffered *(ebp+0x18) "fn ") - 9472 8b/-> *(ebp+0x14) 0/r32/eax - 9473 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 9474 (write-buffered *(ebp+0x18) %eax) - 9475 (write-buffered *(ebp+0x18) ": variable cannot begin with a digit '") - 9476 (write-slice-buffered *(ebp+0x18) *(ebp+0xc)) - 9477 (write-buffered *(ebp+0x18) "'\n") - 9478 (flush *(ebp+0x18)) - 9479 (stop *(ebp+0x1c) 1) - 9480 # never gets here - 9481 - 9482 new-literal: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) - 9483 # . prologue - 9484 55/push-ebp - 9485 89/<- %ebp 4/r32/esp - 9486 # . save registers - 9487 50/push-eax - 9488 51/push-ecx - 9489 # var s/ecx: (handle array byte) + 8424 # (eax..ecx) = "-a" + 8425 b8/copy-to-eax "-a"/imm32 + 8426 8b/-> *eax 1/r32/ecx + 8427 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 8428 05/add-to-eax 4/imm32 + 8429 # var slice/ecx: slice = {eax, ecx} + 8430 51/push-ecx + 8431 50/push-eax + 8432 89/<- %ecx 4/r32/esp + 8433 # + 8434 (is-identifier? %ecx) + 8435 (check-ints-equal %eax 0 "F - test-is-identifier-hyphen") + 8436 # . epilogue + 8437 89/<- %esp 5/r32/ebp + 8438 5d/pop-to-ebp + 8439 c3/return + 8440 + 8441 populate-mu-function-body: # in: (addr buffered-file), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) + 8442 # . prologue + 8443 55/push-ebp + 8444 89/<- %ebp 4/r32/esp + 8445 # . save registers + 8446 50/push-eax + 8447 56/push-esi + 8448 57/push-edi + 8449 # esi = in + 8450 8b/-> *(ebp+8) 6/r32/esi + 8451 # edi = out + 8452 8b/-> *(ebp+0xc) 7/r32/edi + 8453 # initialize some global state + 8454 c7 0/subop/copy *Curr-block-depth 1/imm32 + 8455 # parse-mu-block(in, vars, out, out->body) + 8456 8d/copy-address *(edi+0x18) 0/r32/eax # Function-body + 8457 (parse-mu-block %esi *(ebp+0x10) %edi %eax *(ebp+0x14) *(ebp+0x18)) + 8458 $populate-mu-function-body:end: + 8459 # . restore registers + 8460 5f/pop-to-edi + 8461 5e/pop-to-esi + 8462 58/pop-to-eax + 8463 # . epilogue + 8464 89/<- %esp 5/r32/ebp + 8465 5d/pop-to-ebp + 8466 c3/return + 8467 + 8468 # parses a block, assuming that the leading '{' has already been read by the caller + 8469 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) + 8470 # pseudocode: + 8471 # var line: (stream byte 512) + 8472 # var word-slice: slice + 8473 # allocate(Heap, Stmt-size, out) + 8474 # var out-addr: (addr block) = lookup(*out) + 8475 # out-addr->tag = 0/block + 8476 # out-addr->var = some unique name + 8477 # push(vars, {out-addr->var, false}) + 8478 # while true # line loop + 8479 # clear-stream(line) + 8480 # read-line-buffered(in, line) + 8481 # if (line->write == 0) break # end of file + 8482 # word-slice = next-mu-token(line) + 8483 # if slice-empty?(word-slice) # end of line + 8484 # continue + 8485 # else if slice-starts-with?(word-slice, "#") + 8486 # continue + 8487 # else if slice-equal?(word-slice, "{") + 8488 # assert(no-tokens-in(line)) + 8489 # block = parse-mu-block(in, vars, fn) + 8490 # append-to-block(out-addr, block) + 8491 # else if slice-equal?(word-slice, "}") + 8492 # break + 8493 # else if slice-ends-with?(word-slice, ":") + 8494 # # TODO: error-check the rest of 'line' + 8495 # --word-slice->end to skip ':' + 8496 # named-block = parse-mu-named-block(word-slice, in, vars, fn) + 8497 # append-to-block(out-addr, named-block) + 8498 # else if slice-equal?(word-slice, "var") + 8499 # var-def = parse-mu-var-def(line, vars, fn) + 8500 # append-to-block(out-addr, var-def) + 8501 # else + 8502 # stmt = parse-mu-stmt(line, vars, fn) + 8503 # append-to-block(out-addr, stmt) + 8504 # pop(vars) + 8505 # + 8506 # . prologue + 8507 55/push-ebp + 8508 89/<- %ebp 4/r32/esp + 8509 # . save registers + 8510 50/push-eax + 8511 51/push-ecx + 8512 52/push-edx + 8513 53/push-ebx + 8514 57/push-edi + 8515 # var line/ecx: (stream byte 512) + 8516 81 5/subop/subtract %esp 0x200/imm32 + 8517 68/push 0x200/imm32/size + 8518 68/push 0/imm32/read + 8519 68/push 0/imm32/write + 8520 89/<- %ecx 4/r32/esp + 8521 # var word-slice/edx: slice + 8522 68/push 0/imm32/end + 8523 68/push 0/imm32/start + 8524 89/<- %edx 4/r32/esp + 8525 # allocate into out + 8526 (allocate Heap *Stmt-size *(ebp+0x14)) + 8527 # var out-addr/edi: (addr block) = lookup(*out) + 8528 8b/-> *(ebp+0x14) 7/r32/edi + 8529 (lookup *edi *(edi+4)) # => eax + 8530 89/<- %edi 0/r32/eax + 8531 # out-addr->tag is 0 (block) by default + 8532 # set out-addr->var + 8533 8d/copy-address *(edi+0xc) 0/r32/eax # Block-var + 8534 (new-block-name *(ebp+0x10) %eax) + 8535 # push(vars, out-addr->var) + 8536 (push *(ebp+0xc) *(edi+0xc)) # Block-var + 8537 (push *(ebp+0xc) *(edi+0x10)) # Block-var + 8538 (push *(ebp+0xc) 0) # false + 8539 # increment *Curr-block-depth + 8540 ff 0/subop/increment *Curr-block-depth + 8541 { + 8542 $parse-mu-block:line-loop: + 8543 # line = read-line-buffered(in) + 8544 (clear-stream %ecx) + 8545 (read-line-buffered *(ebp+8) %ecx) + 8546 #? (write-buffered Stderr "line: ") + 8547 #? (write-stream-data Stderr %ecx) + 8548 #? #? (write-buffered Stderr Newline) # line has its own newline + 8549 #? (flush Stderr) + 8550 #? (rewind-stream %ecx) + 8551 # if (line->write == 0) break + 8552 81 7/subop/compare *ecx 0/imm32 + 8553 0f 84/jump-if-= break/disp32 + 8554 #? (write-buffered Stderr "vars:\n") + 8555 #? (dump-vars *(ebp+0xc)) + 8556 # word-slice = next-mu-token(line) + 8557 (next-mu-token %ecx %edx) + 8558 #? (write-buffered Stderr "word: ") + 8559 #? (write-slice-buffered Stderr %edx) + 8560 #? (write-buffered Stderr Newline) + 8561 #? (flush Stderr) + 8562 # if slice-empty?(word-slice) continue + 8563 (slice-empty? %edx) + 8564 3d/compare-eax-and 0/imm32/false + 8565 0f 85/jump-if-!= loop/disp32 + 8566 # if (slice-starts-with?(word-slice, '#') continue + 8567 # . eax = *word-slice->start + 8568 8b/-> *edx 0/r32/eax + 8569 8a/copy-byte *eax 0/r32/AL + 8570 81 4/subop/and %eax 0xff/imm32 + 8571 # . if (eax == '#') continue + 8572 3d/compare-eax-and 0x23/imm32/hash + 8573 0f 84/jump-if-= loop/disp32 + 8574 # if slice-equal?(word-slice, "{") + 8575 { + 8576 $parse-mu-block:check-for-block: + 8577 (slice-equal? %edx "{") + 8578 3d/compare-eax-and 0/imm32/false + 8579 74/jump-if-= break/disp8 + 8580 (check-no-tokens-left %ecx) + 8581 # parse new block and append + 8582 # . var tmp/eax: (handle block) + 8583 68/push 0/imm32 + 8584 68/push 0/imm32 + 8585 89/<- %eax 4/r32/esp + 8586 # . + 8587 (parse-mu-block *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) + 8588 (append-to-block Heap %edi *eax *(eax+4)) + 8589 # . reclaim tmp + 8590 81 0/subop/add %esp 8/imm32 + 8591 # . + 8592 e9/jump $parse-mu-block:line-loop/disp32 + 8593 } + 8594 # if slice-equal?(word-slice, "}") break + 8595 $parse-mu-block:check-for-end: + 8596 (slice-equal? %edx "}") + 8597 3d/compare-eax-and 0/imm32/false + 8598 0f 85/jump-if-!= break/disp32 + 8599 # if slice-ends-with?(word-slice, ":") parse named block and append + 8600 { + 8601 $parse-mu-block:check-for-named-block: + 8602 # . eax = *(word-slice->end-1) + 8603 8b/-> *(edx+4) 0/r32/eax + 8604 48/decrement-eax + 8605 8a/copy-byte *eax 0/r32/AL + 8606 81 4/subop/and %eax 0xff/imm32 + 8607 # . if (eax != ':') break + 8608 3d/compare-eax-and 0x3a/imm32/colon + 8609 0f 85/jump-if-!= break/disp32 + 8610 # TODO: error-check the rest of 'line' + 8611 # + 8612 # skip ':' + 8613 ff 1/subop/decrement *(edx+4) # Slice-end + 8614 # var tmp/eax: (handle block) + 8615 68/push 0/imm32 + 8616 68/push 0/imm32 + 8617 89/<- %eax 4/r32/esp + 8618 # + 8619 (parse-mu-named-block %edx *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) + 8620 (append-to-block Heap %edi *eax *(eax+4)) + 8621 # reclaim tmp + 8622 81 0/subop/add %esp 8/imm32 + 8623 # + 8624 e9/jump $parse-mu-block:line-loop/disp32 + 8625 } + 8626 # if slice-equal?(word-slice, "var") + 8627 { + 8628 $parse-mu-block:check-for-var: + 8629 (slice-equal? %edx "var") + 8630 3d/compare-eax-and 0/imm32/false + 8631 74/jump-if-= break/disp8 + 8632 # var tmp/eax: (handle block) + 8633 68/push 0/imm32 + 8634 68/push 0/imm32 + 8635 89/<- %eax 4/r32/esp + 8636 # + 8637 (parse-mu-var-def %ecx *(ebp+0xc) %eax *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) + 8638 (append-to-block Heap %edi *eax *(eax+4)) + 8639 # reclaim tmp + 8640 81 0/subop/add %esp 8/imm32 + 8641 # + 8642 e9/jump $parse-mu-block:line-loop/disp32 + 8643 } + 8644 $parse-mu-block:regular-stmt: + 8645 # otherwise + 8646 # var tmp/eax: (handle block) + 8647 68/push 0/imm32 + 8648 68/push 0/imm32 + 8649 89/<- %eax 4/r32/esp + 8650 # + 8651 (parse-mu-stmt %ecx *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) + 8652 (append-to-block Heap %edi *eax *(eax+4)) + 8653 # reclaim tmp + 8654 81 0/subop/add %esp 8/imm32 + 8655 # + 8656 e9/jump loop/disp32 + 8657 } # end line loop + 8658 (clean-up-blocks *(ebp+0xc) *Curr-block-depth *(ebp+0x10)) + 8659 # decrement *Curr-block-depth + 8660 ff 1/subop/decrement *Curr-block-depth + 8661 # pop(vars) + 8662 (pop *(ebp+0xc)) # => eax + 8663 (pop *(ebp+0xc)) # => eax + 8664 (pop *(ebp+0xc)) # => eax + 8665 $parse-mu-block:end: + 8666 # . reclaim locals + 8667 81 0/subop/add %esp 0x214/imm32 + 8668 # . restore registers + 8669 5f/pop-to-edi + 8670 5b/pop-to-ebx + 8671 5a/pop-to-edx + 8672 59/pop-to-ecx + 8673 58/pop-to-eax + 8674 # . epilogue + 8675 89/<- %esp 5/r32/ebp + 8676 5d/pop-to-ebp + 8677 c3/return + 8678 + 8679 $parse-mu-block:abort: + 8680 # error("'{' or '}' should be on its own line, but got '") + 8681 (write-buffered *(ebp+0x18) "'{' or '}' should be on its own line, but got '") + 8682 (rewind-stream %ecx) + 8683 (write-stream-data *(ebp+0x18) %ecx) + 8684 (write-buffered *(ebp+0x18) "'\n") + 8685 (flush *(ebp+0x18)) + 8686 (stop *(ebp+0x1c) 1) + 8687 # never gets here + 8688 + 8689 new-block-name: # fn: (addr function), out: (addr handle var) + 8690 # . prologue + 8691 55/push-ebp + 8692 89/<- %ebp 4/r32/esp + 8693 # . save registers + 8694 50/push-eax + 8695 51/push-ecx + 8696 52/push-edx + 8697 # var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:' + 8698 8b/-> *(ebp+8) 0/r32/eax + 8699 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 8700 8b/-> *eax 0/r32/eax # String-size + 8701 05/add-to-eax 0xd/imm32 # 10 + 2 for '$:' + 8702 89/<- %ecx 0/r32/eax + 8703 # var name/edx: (stream byte n) + 8704 29/subtract-from %esp 1/r32/ecx + 8705 ff 6/subop/push %ecx + 8706 68/push 0/imm32/read + 8707 68/push 0/imm32/write + 8708 89/<- %edx 4/r32/esp + 8709 (clear-stream %edx) + 8710 # eax = fn->name + 8711 8b/-> *(ebp+8) 0/r32/eax + 8712 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 8713 # construct result using Next-block-index (and increment it) + 8714 (write %edx "$") + 8715 (write %edx %eax) + 8716 (write %edx ":") + 8717 (write-int32-hex %edx *Next-block-index) + 8718 ff 0/subop/increment *Next-block-index + 8719 # var s/eax: slice = {name->data, name->data + name->write} (clobbering edx) + 8720 # . eax = name->write + 8721 8b/-> *edx 0/r32/eax + 8722 # . edx = name->data + 8723 8d/copy-address *(edx+0xc) 2/r32/edx + 8724 # . eax = name->write + name->data + 8725 01/add-to %eax 2/r32/edx + 8726 # . push {edx, eax} + 8727 ff 6/subop/push %eax + 8728 ff 6/subop/push %edx + 8729 89/<- %eax 4/r32/esp + 8730 # out = new literal(s) + 8731 (new-literal Heap %eax *(ebp+0xc)) + 8732 #? 8b/-> *(ebp+0xc) 0/r32/eax + 8733 #? (write-buffered Stderr "type allocid in caller after new-literal: ") + 8734 #? (write-int32-hex-buffered Stderr *(eax+8)) + 8735 #? (write-buffered Stderr " for var ") + 8736 #? (write-int32-hex-buffered Stderr %eax) + 8737 #? (write-buffered Stderr Newline) + 8738 #? (flush Stderr) + 8739 $new-block-name:end: + 8740 # . reclaim locals + 8741 81 0/subop/add %ecx 0xc/imm32 # name.{read/write/len} + 8742 81 0/subop/add %ecx 8/imm32 # slice + 8743 01/add-to %esp 1/r32/ecx + 8744 # . restore registers + 8745 5a/pop-to-edx + 8746 59/pop-to-ecx + 8747 58/pop-to-eax + 8748 # . epilogue + 8749 89/<- %esp 5/r32/ebp + 8750 5d/pop-to-ebp + 8751 c3/return + 8752 + 8753 check-no-tokens-left: # line: (addr stream byte) + 8754 # . prologue + 8755 55/push-ebp + 8756 89/<- %ebp 4/r32/esp + 8757 # . save registers + 8758 50/push-eax + 8759 51/push-ecx + 8760 # var s/ecx: slice + 8761 68/push 0/imm32/end + 8762 68/push 0/imm32/start + 8763 89/<- %ecx 4/r32/esp + 8764 # + 8765 (next-mu-token *(ebp+8) %ecx) + 8766 # if slice-empty?(s) return + 8767 (slice-empty? %ecx) + 8768 3d/compare-eax-and 0/imm32/false + 8769 75/jump-if-!= $check-no-tokens-left:end/disp8 + 8770 # if (slice-starts-with?(s, '#') return + 8771 # . eax = *s->start + 8772 8b/-> *edx 0/r32/eax + 8773 8a/copy-byte *eax 0/r32/AL + 8774 81 4/subop/and %eax 0xff/imm32 + 8775 # . if (eax == '#') continue + 8776 3d/compare-eax-and 0x23/imm32/hash + 8777 74/jump-if-= $check-no-tokens-left:end/disp8 + 8778 # abort + 8779 (write-buffered Stderr "'{' or '}' should be on its own line, but got '") + 8780 (rewind-stream %ecx) + 8781 (write-stream 2 %ecx) + 8782 (write-buffered Stderr "'\n") + 8783 (flush Stderr) + 8784 # . syscall(exit, 1) + 8785 bb/copy-to-ebx 1/imm32 + 8786 e8/call syscall_exit/disp32 + 8787 # never gets here + 8788 $check-no-tokens-left:end: + 8789 # . reclaim locals + 8790 81 0/subop/add %esp 8/imm32 + 8791 # . restore registers + 8792 59/pop-to-ecx + 8793 58/pop-to-eax + 8794 # . epilogue + 8795 89/<- %esp 5/r32/ebp + 8796 5d/pop-to-ebp + 8797 c3/return + 8798 + 8799 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) + 8800 # pseudocode: + 8801 # var v: (handle var) + 8802 # new-literal(name, v) + 8803 # push(vars, {v, false}) + 8804 # parse-mu-block(in, vars, fn, out) + 8805 # pop(vars) + 8806 # out->tag = block + 8807 # out->var = v + 8808 # + 8809 # . prologue + 8810 55/push-ebp + 8811 89/<- %ebp 4/r32/esp + 8812 # . save registers + 8813 50/push-eax + 8814 51/push-ecx + 8815 57/push-edi + 8816 # var v/ecx: (handle var) + 8817 68/push 0/imm32 + 8818 68/push 0/imm32 + 8819 89/<- %ecx 4/r32/esp + 8820 # + 8821 (new-literal Heap *(ebp+8) %ecx) + 8822 # push(vars, v) + 8823 (push *(ebp+0x10) *ecx) + 8824 (push *(ebp+0x10) *(ecx+4)) + 8825 (push *(ebp+0x10) 0) # false + 8826 # + 8827 (parse-mu-block *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20)) + 8828 # pop v off vars + 8829 (pop *(ebp+0x10)) # => eax + 8830 (pop *(ebp+0x10)) # => eax + 8831 (pop *(ebp+0x10)) # => eax + 8832 # var out-addr/edi: (addr stmt) = lookup(*out) + 8833 8b/-> *(ebp+0x18) 7/r32/edi + 8834 (lookup *edi *(edi+4)) # => eax + 8835 89/<- %edi 0/r32/eax + 8836 # out-addr->tag = named-block + 8837 c7 0/subop/copy *edi 0/imm32/block # Stmt-tag + 8838 # out-addr->var = v + 8839 8b/-> *ecx 0/r32/eax + 8840 89/<- *(edi+0xc) 0/r32/eax # Block-var + 8841 8b/-> *(ecx+4) 0/r32/eax + 8842 89/<- *(edi+0x10) 0/r32/eax # Block-var + 8843 $parse-mu-named-block:end: + 8844 # . reclaim locals + 8845 81 0/subop/add %esp 8/imm32 + 8846 # . restore registers + 8847 5f/pop-to-edi + 8848 59/pop-to-ecx + 8849 58/pop-to-eax + 8850 # . epilogue + 8851 89/<- %esp 5/r32/ebp + 8852 5d/pop-to-ebp + 8853 c3/return + 8854 + 8855 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) + 8856 # . prologue + 8857 55/push-ebp + 8858 89/<- %ebp 4/r32/esp + 8859 # . save registers + 8860 50/push-eax + 8861 51/push-ecx + 8862 52/push-edx + 8863 53/push-ebx + 8864 57/push-edi + 8865 # edi = out + 8866 8b/-> *(ebp+0x10) 7/r32/edi + 8867 # var word-slice/ecx: slice + 8868 68/push 0/imm32/end + 8869 68/push 0/imm32/start + 8870 89/<- %ecx 4/r32/esp + 8871 # var v/edx: (handle var) + 8872 68/push 0/imm32 + 8873 68/push 0/imm32 + 8874 89/<- %edx 4/r32/esp + 8875 # v = parse-var-with-type(next-mu-token(line)) + 8876 (next-mu-token *(ebp+8) %ecx) + 8877 (parse-var-with-type %ecx *(ebp+8) %edx *(ebp+0x18) *(ebp+0x1c)) + 8878 # var v-addr/eax: (addr var) + 8879 (lookup *edx *(edx+4)) # => eax + 8880 # v->block-depth = *Curr-block-depth + 8881 8b/-> *Curr-block-depth 3/r32/ebx + 8882 89/<- *(eax+0x10) 3/r32/ebx # Var-block-depth + 8883 # either v has no register and there's no more to this line + 8884 8b/-> *(eax+0x18) 0/r32/eax # Var-register + 8885 3d/compare-eax-and 0/imm32 + 8886 { + 8887 75/jump-if-!= break/disp8 + 8888 # TODO: disallow vars of type 'byte' on the stack + 8889 # ensure that there's nothing else on this line + 8890 (next-mu-token *(ebp+8) %ecx) + 8891 (slice-empty? %ecx) # => eax + 8892 3d/compare-eax-and 0/imm32/false + 8893 0f 84/jump-if-= $parse-mu-var-def:error2/disp32 + 8894 # + 8895 (new-var-def Heap *edx *(edx+4) %edi) + 8896 e9/jump $parse-mu-var-def:update-vars/disp32 + 8897 } + 8898 # or v has a register and there's more to this line + 8899 { + 8900 0f 84/jump-if-= break/disp32 + 8901 # TODO: disallow vars of type 'byte' in registers 'esi' or 'edi' + 8902 # TODO: vars of type 'byte' should only be initialized by clearing to 0 + 8903 # ensure that the next word is '<-' + 8904 (next-mu-token *(ebp+8) %ecx) + 8905 (slice-equal? %ecx "<-") # => eax + 8906 3d/compare-eax-and 0/imm32/false + 8907 0f 84/jump-if-= $parse-mu-var-def:error1/disp32 + 8908 # + 8909 (new-reg-var-def Heap *edx *(edx+4) %edi) + 8910 (lookup *edi *(edi+4)) # => eax + 8911 (add-operation-and-inputs-to-stmt %eax *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) + 8912 } + 8913 $parse-mu-var-def:update-vars: + 8914 # push 'v' at end of function + 8915 (push *(ebp+0xc) *edx) + 8916 (push *(ebp+0xc) *(edx+4)) + 8917 (push *(ebp+0xc) 0) # Live-var-register-spilled is unused during parsing + 8918 $parse-mu-var-def:end: + 8919 # . reclaim locals + 8920 81 0/subop/add %esp 0x10/imm32 + 8921 # . restore registers + 8922 5f/pop-to-edi + 8923 5b/pop-to-ebx + 8924 5a/pop-to-edx + 8925 59/pop-to-ecx + 8926 58/pop-to-eax + 8927 # . epilogue + 8928 89/<- %esp 5/r32/ebp + 8929 5d/pop-to-ebp + 8930 c3/return + 8931 + 8932 $parse-mu-var-def:error1: + 8933 (rewind-stream *(ebp+8)) + 8934 # error("register variable requires a valid instruction to initialize but got '" line "'\n") + 8935 (write-buffered *(ebp+0x18) "register variable requires a valid instruction to initialize but got '") + 8936 (flush *(ebp+0x18)) + 8937 (write-stream-data *(ebp+0x18) *(ebp+8)) + 8938 (write-buffered *(ebp+0x18) "'\n") + 8939 (flush *(ebp+0x18)) + 8940 (stop *(ebp+0x1c) 1) + 8941 # never gets here + 8942 + 8943 $parse-mu-var-def:error2: + 8944 (rewind-stream *(ebp+8)) + 8945 # error("fn " fn ": var " var ": variables on the stack can't take an initializer\n") + 8946 (write-buffered *(ebp+0x18) "fn ") + 8947 8b/-> *(ebp+0x14) 0/r32/eax + 8948 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 8949 (write-buffered *(ebp+0x18) %eax) + 8950 (write-buffered *(ebp+0x18) ": var ") + 8951 # var v-addr/eax: (addr var) = lookup(v) + 8952 (lookup *edx *(edx+4)) # => eax + 8953 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 8954 (write-buffered *(ebp+0x18) %eax) + 8955 (write-buffered *(ebp+0x18) ": variables on the stack can't take an initializer\n") + 8956 (flush *(ebp+0x18)) + 8957 (stop *(ebp+0x1c) 1) + 8958 # never gets here + 8959 + 8960 test-parse-mu-var-def: + 8961 # 'var n: int' + 8962 # . prologue + 8963 55/push-ebp + 8964 89/<- %ebp 4/r32/esp + 8965 # setup + 8966 (clear-stream _test-input-stream) + 8967 (write _test-input-stream "n: int\n") # caller has consumed the 'var' + 8968 c7 0/subop/copy *Curr-block-depth 1/imm32 + 8969 # var out/esi: (handle stmt) + 8970 68/push 0/imm32 + 8971 68/push 0/imm32 + 8972 89/<- %esi 4/r32/esp + 8973 # var vars/ecx: (stack (addr var) 16) + 8974 81 5/subop/subtract %esp 0xc0/imm32 + 8975 68/push 0xc0/imm32/size + 8976 68/push 0/imm32/top + 8977 89/<- %ecx 4/r32/esp + 8978 (clear-stack %ecx) + 8979 # convert + 8980 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) + 8981 # var out-addr/esi: (addr stmt) + 8982 (lookup *esi *(esi+4)) # => eax + 8983 89/<- %esi 0/r32/eax + 8984 # + 8985 (check-ints-equal *esi 2 "F - test-parse-mu-var-def/tag") # Stmt-tag is var-def + 8986 # var v/ecx: (addr var) = lookup(out->var) + 8987 (lookup *(esi+4) *(esi+8)) # Vardef-var Vardef-var => eax + 8988 89/<- %ecx 0/r32/eax + 8989 # v->name + 8990 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax + 8991 (check-strings-equal %eax "n" "F - test-parse-mu-var-def/var-name") + 8992 # v->register + 8993 (check-ints-equal *(ecx+0x18) 0 "F - test-parse-mu-var-def/var-register") # Var-register + 8994 # v->block-depth + 8995 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-var-def/output-block-depth") # Var-block-depth + 8996 # v->type == int + 8997 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 8998 (check-ints-equal *eax 1 "F - test-parse-mu-var-def/var-type:0") # Type-tree-is-atom + 8999 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-var-def/var-type:1") # Type-tree-value + 9000 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-var-def/var-type:2") # Type-tree-right + 9001 # . epilogue + 9002 89/<- %esp 5/r32/ebp + 9003 5d/pop-to-ebp + 9004 c3/return + 9005 + 9006 test-parse-mu-reg-var-def: + 9007 # 'var n/eax: int <- copy 0' + 9008 # . prologue + 9009 55/push-ebp + 9010 89/<- %ebp 4/r32/esp + 9011 # setup + 9012 (clear-stream _test-input-stream) + 9013 (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var' + 9014 c7 0/subop/copy *Curr-block-depth 1/imm32 + 9015 # var out/esi: (handle stmt) + 9016 68/push 0/imm32 + 9017 68/push 0/imm32 + 9018 89/<- %esi 4/r32/esp + 9019 # var vars/ecx: (stack (addr var) 16) + 9020 81 5/subop/subtract %esp 0xc0/imm32 + 9021 68/push 0xc0/imm32/size + 9022 68/push 0/imm32/top + 9023 89/<- %ecx 4/r32/esp + 9024 (clear-stack %ecx) + 9025 # convert + 9026 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) + 9027 # var out-addr/esi: (addr stmt) + 9028 (lookup *esi *(esi+4)) # => eax + 9029 89/<- %esi 0/r32/eax + 9030 # + 9031 (check-ints-equal *esi 3 "F - test-parse-mu-reg-var-def/tag") # Stmt-tag is reg-var-def + 9032 # var v/ecx: (addr var) = lookup(out->outputs->value) + 9033 # . eax: (addr stmt-var) = lookup(out->outputs) + 9034 (lookup *(esi+0x14) *(esi+0x18)) # Regvardef-outputs Regvardef-outputs => eax + 9035 # . + 9036 (check-ints-equal *(eax+8) 0 "F - test-parse-mu-reg-var-def/single-output") # Stmt-var-next + 9037 # . eax: (addr var) = lookup(eax->value) + 9038 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9039 # . ecx = eax + 9040 89/<- %ecx 0/r32/eax + 9041 # v->name + 9042 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax + 9043 (check-strings-equal %eax "n" "F - test-parse-mu-reg-var-def/output-name") # Var-name + 9044 # v->register + 9045 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax + 9046 (check-strings-equal %eax "eax" "F - test-parse-mu-reg-var-def/output-register") + 9047 # v->block-depth + 9048 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-reg-var-def/output-block-depth") # Var-block-depth + 9049 # v->type == int + 9050 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 9051 (check-ints-equal *eax 1 "F - test-parse-mu-reg-var-def/output-type:0") # Type-tree-is-atom + 9052 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-reg-var-def/output-type:1") # Type-tree-value + 9053 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-reg-var-def/output-type:2") # Type-tree-right + 9054 # . epilogue + 9055 89/<- %esp 5/r32/ebp + 9056 5d/pop-to-ebp + 9057 c3/return + 9058 + 9059 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) + 9060 # Carefully push any outputs on the vars stack _after_ reading the inputs + 9061 # that may conflict with them. + 9062 # + 9063 # The only situation in which outputs are pushed here (when it's not a + 9064 # 'var' vardef stmt), and so can possibly conflict with inputs, is if the + 9065 # output is a function output. + 9066 # + 9067 # pseudocode: + 9068 # var name: slice + 9069 # allocate(Heap, Stmt-size, out) + 9070 # var out-addr: (addr stmt) = lookup(*out) + 9071 # out-addr->tag = stmt + 9072 # if stmt-has-outputs?(line) + 9073 # while true + 9074 # name = next-mu-token(line) + 9075 # if (name == '<-') break + 9076 # assert(is-identifier?(name)) + 9077 # var v: (handle var) = lookup-var-or-find-in-fn-outputs(name, vars, fn) + 9078 # out-addr->outputs = append(v, out-addr->outputs) + 9079 # add-operation-and-inputs-to-stmt(out-addr, line, vars) + 9080 # for output in stmt->outputs: + 9081 # maybe-define-var(output, vars) + 9082 # + 9083 # . prologue + 9084 55/push-ebp + 9085 89/<- %ebp 4/r32/esp + 9086 # . save registers + 9087 50/push-eax + 9088 51/push-ecx + 9089 52/push-edx + 9090 53/push-ebx + 9091 57/push-edi + 9092 # var name/ecx: slice + 9093 68/push 0/imm32/end + 9094 68/push 0/imm32/start + 9095 89/<- %ecx 4/r32/esp + 9096 # var is-deref?/edx: boolean = false + 9097 ba/copy-to-edx 0/imm32/false + 9098 # var v: (handle var) + 9099 68/push 0/imm32 + 9100 68/push 0/imm32 + 9101 89/<- %ebx 4/r32/esp + 9102 # + 9103 (allocate Heap *Stmt-size *(ebp+0x14)) + 9104 # var out-addr/edi: (addr stmt) = lookup(*out) + 9105 8b/-> *(ebp+0x14) 7/r32/edi + 9106 (lookup *edi *(edi+4)) # => eax + 9107 89/<- %edi 0/r32/eax + 9108 # out-addr->tag = 1/stmt + 9109 c7 0/subop/copy *edi 1/imm32/stmt1 # Stmt-tag + 9110 { + 9111 (stmt-has-outputs? *(ebp+8)) + 9112 3d/compare-eax-and 0/imm32/false + 9113 0f 84/jump-if-= break/disp32 + 9114 { + 9115 $parse-mu-stmt:read-outputs: + 9116 # name = next-mu-token(line) + 9117 (next-mu-token *(ebp+8) %ecx) + 9118 # if slice-empty?(word-slice) break + 9119 (slice-empty? %ecx) # => eax + 9120 3d/compare-eax-and 0/imm32/false + 9121 0f 85/jump-if-!= break/disp32 + 9122 # if (name == "<-") break + 9123 (slice-equal? %ecx "<-") # => eax + 9124 3d/compare-eax-and 0/imm32/false + 9125 0f 85/jump-if-!= break/disp32 + 9126 # is-deref? = false + 9127 ba/copy-to-edx 0/imm32/false + 9128 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? + 9129 8b/-> *ecx 0/r32/eax # Slice-start + 9130 8a/copy-byte *eax 0/r32/AL + 9131 81 4/subop/and %eax 0xff/imm32 + 9132 3d/compare-eax-and 0x2a/imm32/asterisk + 9133 { + 9134 75/jump-if-!= break/disp8 + 9135 ff 0/subop/increment *ecx + 9136 ba/copy-to-edx 1/imm32/true + 9137 } + 9138 # assert(is-identifier?(name)) + 9139 (is-identifier? %ecx) # => eax + 9140 3d/compare-eax-and 0/imm32/false + 9141 0f 84/jump-if-= $parse-mu-stmt:abort/disp32 + 9142 # + 9143 (lookup-var-or-find-in-fn-outputs %ecx *(ebp+0xc) *(ebp+0x10) %ebx *(ebp+0x18) *(ebp+0x1c)) + 9144 8d/copy-address *(edi+0x14) 0/r32/eax # Stmt1-outputs + 9145 (append-stmt-var Heap *ebx *(ebx+4) *(edi+0x14) *(edi+0x18) %edx %eax) # Stmt1-outputs + 9146 # + 9147 e9/jump loop/disp32 + 9148 } + 9149 } + 9150 (add-operation-and-inputs-to-stmt %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) + 9151 $parse-mu-stmt:define-outputs: + 9152 # var output/edi: (addr stmt-var) = lookup(out-addr->outputs) + 9153 (lookup *(edi+0x14) *(edi+0x18)) # Stmt1-outputs Stmt1-outputs => eax + 9154 89/<- %edi 0/r32/eax + 9155 { + 9156 $parse-mu-stmt:define-outputs-loop: + 9157 # if (output == null) break + 9158 81 7/subop/compare %edi 0/imm32 + 9159 74/jump-if-= break/disp8 + 9160 # + 9161 (maybe-define-var *edi *(edi+4) *(ebp+0xc)) # if output is a deref, then it's already been defined, + 9162 # and must be in vars. This call will be a no-op, but safe. + 9163 # output = output->next + 9164 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax + 9165 89/<- %edi 0/r32/eax + 9166 # + 9167 eb/jump loop/disp8 + 9168 } + 9169 $parse-mu-stmt:end: + 9170 # . reclaim locals + 9171 81 0/subop/add %esp 0x10/imm32 + 9172 # . restore registers + 9173 5f/pop-to-edi + 9174 5b/pop-to-ebx + 9175 5a/pop-to-edx + 9176 59/pop-to-ecx + 9177 58/pop-to-eax + 9178 # . epilogue + 9179 89/<- %esp 5/r32/ebp + 9180 5d/pop-to-ebp + 9181 c3/return + 9182 + 9183 $parse-mu-stmt:abort: + 9184 # error("invalid identifier '" name "'\n") + 9185 (write-buffered *(ebp+0x18) "invalid identifier '") + 9186 (write-slice-buffered *(ebp+0x18) %ecx) + 9187 (write-buffered *(ebp+0x18) "'\n") + 9188 (flush *(ebp+0x18)) + 9189 (stop *(ebp+0x1c) 1) + 9190 # never gets here + 9191 + 9192 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) + 9193 # pseudocode: + 9194 # stmt->name = slice-to-string(next-mu-token(line)) + 9195 # while true + 9196 # name = next-mu-token(line) + 9197 # v = lookup-var-or-literal(name) + 9198 # stmt->inouts = append(v, stmt->inouts) + 9199 # + 9200 # . prologue + 9201 55/push-ebp + 9202 89/<- %ebp 4/r32/esp + 9203 # . save registers + 9204 50/push-eax + 9205 51/push-ecx + 9206 52/push-edx + 9207 53/push-ebx + 9208 56/push-esi + 9209 57/push-edi + 9210 # edi = stmt + 9211 8b/-> *(ebp+8) 7/r32/edi + 9212 # var name/ecx: slice + 9213 68/push 0/imm32/end + 9214 68/push 0/imm32/start + 9215 89/<- %ecx 4/r32/esp + 9216 # var is-deref?/edx: boolean = false + 9217 ba/copy-to-edx 0/imm32/false + 9218 # var v/esi: (handle var) + 9219 68/push 0/imm32 + 9220 68/push 0/imm32 + 9221 89/<- %esi 4/r32/esp + 9222 $add-operation-and-inputs-to-stmt:read-operation: + 9223 (next-mu-token *(ebp+0xc) %ecx) + 9224 8d/copy-address *(edi+4) 0/r32/eax # Stmt1-operation or Regvardef-operationStmt1-operation or Regvardef-operation + 9225 (slice-to-string Heap %ecx %eax) + 9226 # var is-get?/ebx: boolean = (name == "get") + 9227 (slice-equal? %ecx "get") # => eax + 9228 89/<- %ebx 0/r32/eax + 9229 { + 9230 $add-operation-and-inputs-to-stmt:read-inouts: + 9231 # name = next-mu-token(line) + 9232 (next-mu-token *(ebp+0xc) %ecx) + 9233 # if slice-empty?(word-slice) break + 9234 (slice-empty? %ecx) # => eax + 9235 3d/compare-eax-and 0/imm32/false + 9236 0f 85/jump-if-!= break/disp32 + 9237 # if (name == "<-") abort + 9238 (slice-equal? %ecx "<-") + 9239 3d/compare-eax-and 0/imm32/false + 9240 0f 85/jump-if-!= $add-operation-and-inputs-to-stmt:abort/disp32 + 9241 # if (is-get? && second operand) lookup or create offset + 9242 { + 9243 81 7/subop/compare %ebx 0/imm32/false + 9244 74/jump-if-= break/disp8 + 9245 (lookup *(edi+0xc) *(edi+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 9246 3d/compare-eax-and 0/imm32 + 9247 74/jump-if-= break/disp8 + 9248 (lookup-or-create-constant %eax %ecx %esi) + 9249 #? (lookup *esi *(esi+4)) + 9250 #? (write-buffered Stderr "creating new output var ") + 9251 #? (write-int32-hex-buffered Stderr %eax) + 9252 #? (write-buffered Stderr " for field called ") + 9253 #? (write-slice-buffered Stderr %ecx) + 9254 #? (write-buffered Stderr "; var name ") + 9255 #? (lookup *eax *(eax+4)) # Var-name + 9256 #? (write-buffered Stderr %eax) + 9257 #? (write-buffered Stderr Newline) + 9258 #? (flush Stderr) + 9259 e9/jump $add-operation-and-inputs-to-stmt:save-var/disp32 + 9260 } + 9261 # is-deref? = false + 9262 ba/copy-to-edx 0/imm32/false + 9263 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? + 9264 8b/-> *ecx 0/r32/eax # Slice-start + 9265 8a/copy-byte *eax 0/r32/AL + 9266 81 4/subop/and %eax 0xff/imm32 + 9267 3d/compare-eax-and 0x2a/imm32/asterisk + 9268 { + 9269 75/jump-if-!= break/disp8 + 9270 $add-operation-and-inputs-to-stmt:inout-is-deref: + 9271 ff 0/subop/increment *ecx + 9272 ba/copy-to-edx 1/imm32/true + 9273 } + 9274 (lookup-var-or-literal %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) + 9275 $add-operation-and-inputs-to-stmt:save-var: + 9276 8d/copy-address *(edi+0xc) 0/r32/eax + 9277 (append-stmt-var Heap *esi *(esi+4) *(edi+0xc) *(edi+0x10) %edx %eax) # Stmt1-inouts or Regvardef-inouts + 9278 # + 9279 e9/jump loop/disp32 + 9280 } + 9281 $add-operation-and-inputs-to-stmt:end: + 9282 # . reclaim locals + 9283 81 0/subop/add %esp 0x10/imm32 + 9284 # . restore registers + 9285 5f/pop-to-edi + 9286 5e/pop-to-esi + 9287 5b/pop-to-ebx + 9288 5a/pop-to-edx + 9289 59/pop-to-ecx + 9290 58/pop-to-eax + 9291 # . epilogue + 9292 89/<- %esp 5/r32/ebp + 9293 5d/pop-to-ebp + 9294 c3/return + 9295 + 9296 $add-operation-and-inputs-to-stmt:abort: + 9297 # error("fn ___: invalid identifier in '" line "'\n") + 9298 (write-buffered *(ebp+0x18) "fn ") + 9299 8b/-> *(ebp+0x14) 0/r32/eax + 9300 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 9301 (write-buffered *(ebp+0x18) %eax) + 9302 (rewind-stream *(ebp+0xc)) + 9303 (write-buffered *(ebp+0x18) ": invalid identifier in '") + 9304 (write-stream-data *(ebp+0x18) *(ebp+0xc)) + 9305 (write-buffered *(ebp+0x18) "'\n") + 9306 (flush *(ebp+0x18)) + 9307 (stop *(ebp+0x1c) 1) + 9308 # never gets here + 9309 + 9310 stmt-has-outputs?: # line: (addr stream byte) -> result/eax: boolean + 9311 # . prologue + 9312 55/push-ebp + 9313 89/<- %ebp 4/r32/esp + 9314 # . save registers + 9315 51/push-ecx + 9316 # var word-slice/ecx: slice + 9317 68/push 0/imm32/end + 9318 68/push 0/imm32/start + 9319 89/<- %ecx 4/r32/esp + 9320 # result = false + 9321 b8/copy-to-eax 0/imm32/false + 9322 (rewind-stream *(ebp+8)) + 9323 { + 9324 (next-mu-token *(ebp+8) %ecx) + 9325 # if slice-empty?(word-slice) break + 9326 (slice-empty? %ecx) + 9327 3d/compare-eax-and 0/imm32/false + 9328 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) + 9329 0f 85/jump-if-!= break/disp32 + 9330 # if slice-starts-with?(word-slice, '#') break + 9331 # . eax = *word-slice->start + 9332 8b/-> *ecx 0/r32/eax + 9333 8a/copy-byte *eax 0/r32/AL + 9334 81 4/subop/and %eax 0xff/imm32 + 9335 # . if (eax == '#') break + 9336 3d/compare-eax-and 0x23/imm32/hash + 9337 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) + 9338 0f 84/jump-if-= break/disp32 + 9339 # if slice-equal?(word-slice, '<-') return true + 9340 (slice-equal? %ecx "<-") + 9341 3d/compare-eax-and 0/imm32/false + 9342 74/jump-if-= loop/disp8 + 9343 b8/copy-to-eax 1/imm32/true + 9344 } + 9345 $stmt-has-outputs:end: + 9346 (rewind-stream *(ebp+8)) + 9347 # . reclaim locals + 9348 81 0/subop/add %esp 8/imm32 + 9349 # . restore registers + 9350 59/pop-to-ecx + 9351 # . epilogue + 9352 89/<- %esp 5/r32/ebp + 9353 5d/pop-to-ebp + 9354 c3/return + 9355 + 9356 # if 'name' starts with a digit, create a new literal var for it + 9357 # otherwise return first 'name' from the top (back) of 'vars' and abort if not found + 9358 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) + 9359 # . prologue + 9360 55/push-ebp + 9361 89/<- %ebp 4/r32/esp + 9362 # . save registers + 9363 50/push-eax + 9364 51/push-ecx + 9365 56/push-esi + 9366 # esi = name + 9367 8b/-> *(ebp+8) 6/r32/esi + 9368 # if slice-empty?(name) abort + 9369 (slice-empty? %esi) # => eax + 9370 3d/compare-eax-and 0/imm32/false + 9371 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32 + 9372 # var c/ecx: byte = *name->start + 9373 8b/-> *esi 1/r32/ecx + 9374 8a/copy-byte *ecx 1/r32/CL + 9375 81 4/subop/and %ecx 0xff/imm32 + 9376 # if is-decimal-digit?(c) return new var(name) + 9377 { + 9378 (is-decimal-digit? %ecx) # => eax + 9379 3d/compare-eax-and 0/imm32/false + 9380 74/jump-if-= break/disp8 + 9381 $lookup-var-or-literal:literal: + 9382 (new-literal-integer Heap %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) + 9383 eb/jump $lookup-var-or-literal:end/disp8 + 9384 } + 9385 # else if (c == '"') return new var(name) + 9386 { + 9387 81 7/subop/compare %ecx 0x22/imm32/dquote + 9388 75/jump-if-!= break/disp8 + 9389 $lookup-var-or-literal:literal-string: + 9390 (new-literal Heap %esi *(ebp+0x10)) + 9391 eb/jump $lookup-var-or-literal:end/disp8 + 9392 } + 9393 # otherwise return lookup-var(name, vars) + 9394 { + 9395 $lookup-var-or-literal:var: + 9396 (lookup-var %esi *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) + 9397 } + 9398 $lookup-var-or-literal:end: + 9399 # . restore registers + 9400 5e/pop-to-esi + 9401 59/pop-to-ecx + 9402 58/pop-to-eax + 9403 # . epilogue + 9404 89/<- %esp 5/r32/ebp + 9405 5d/pop-to-ebp + 9406 c3/return + 9407 + 9408 $lookup-var-or-literal:abort: + 9409 (write-buffered *(ebp+0x18) "fn ") + 9410 8b/-> *(ebp+0x14) 0/r32/eax + 9411 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 9412 (write-buffered *(ebp+0x18) %eax) + 9413 (write-buffered *(ebp+0x18) ": empty variable!") + 9414 (flush *(ebp+0x18)) + 9415 (stop *(ebp+0x1c) 1) + 9416 # never gets here + 9417 + 9418 # return first 'name' from the top (back) of 'vars' and abort if not found + 9419 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) + 9420 # . prologue + 9421 55/push-ebp + 9422 89/<- %ebp 4/r32/esp + 9423 # . save registers + 9424 50/push-eax + 9425 # + 9426 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) + 9427 # if (*out == 0) abort + 9428 8b/-> *(ebp+0x10) 0/r32/eax + 9429 81 7/subop/compare *eax 0/imm32 + 9430 74/jump-if-= $lookup-var:abort/disp8 + 9431 $lookup-var:end: + 9432 # . restore registers + 9433 58/pop-to-eax + 9434 # . epilogue + 9435 89/<- %esp 5/r32/ebp + 9436 5d/pop-to-ebp + 9437 c3/return + 9438 + 9439 $lookup-var:abort: + 9440 (write-buffered *(ebp+0x18) "fn ") + 9441 8b/-> *(ebp+0x14) 0/r32/eax + 9442 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 9443 (write-buffered *(ebp+0x18) %eax) + 9444 (write-buffered *(ebp+0x18) ": unknown variable '") + 9445 (write-slice-buffered *(ebp+0x18) *(ebp+8)) + 9446 (write-buffered *(ebp+0x18) "'\n") + 9447 (flush *(ebp+0x18)) + 9448 (stop *(ebp+0x1c) 1) + 9449 # never gets here + 9450 + 9451 # return first 'name' from the top (back) of 'vars', and 0/null if not found + 9452 # ensure that 'name' if in a register is the topmost variable in that register + 9453 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) + 9454 # pseudocode: + 9455 # var curr: (addr handle var) = &vars->data[vars->top - 12] + 9456 # var min = vars->data + 9457 # while curr >= min + 9458 # var v: (handle var) = *curr + 9459 # if v->name == name + 9460 # return + 9461 # curr -= 12 + 9462 # + 9463 # . prologue + 9464 55/push-ebp + 9465 89/<- %ebp 4/r32/esp + 9466 # . save registers + 9467 50/push-eax + 9468 51/push-ecx + 9469 52/push-edx + 9470 53/push-ebx + 9471 56/push-esi + 9472 57/push-edi + 9473 # clear out + 9474 (zero-out *(ebp+0x10) *Handle-size) + 9475 # esi = vars + 9476 8b/-> *(ebp+0xc) 6/r32/esi + 9477 # ebx = vars->top + 9478 8b/-> *esi 3/r32/ebx + 9479 # if (vars->top > vars->size) abort + 9480 3b/compare<- *(esi+4) 0/r32/eax + 9481 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 + 9482 # var min/edx: (addr handle var) = vars->data + 9483 8d/copy-address *(esi+8) 2/r32/edx + 9484 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] + 9485 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 + 9486 # var var-in-reg/edi: 8 addrs + 9487 68/push 0/imm32 + 9488 68/push 0/imm32 + 9489 68/push 0/imm32 9490 68/push 0/imm32 9491 68/push 0/imm32 - 9492 89/<- %ecx 4/r32/esp - 9493 # s = slice-to-string(name) - 9494 (slice-to-string Heap *(ebp+0xc) %ecx) - 9495 # allocate to out - 9496 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) - 9497 # var out-addr/ecx: (addr var) = lookup(*out) - 9498 8b/-> *(ebp+0x10) 1/r32/ecx - 9499 (lookup *ecx *(ecx+4)) # => eax - 9500 89/<- %ecx 0/r32/eax - 9501 # out-addr->block-depth = *Curr-block-depth - 9502 8b/-> *Curr-block-depth 0/r32/eax - 9503 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth - 9504 # out-addr->type/eax = new type - 9505 8d/copy-address *(ecx+8) 0/r32/eax # Var-type - 9506 (allocate *(ebp+8) *Type-tree-size %eax) - 9507 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 9508 # nothing else to do; default type is 'literal' - 9509 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom - 9510 $new-literal:end: - 9511 # . reclaim locals - 9512 81 0/subop/add %esp 8/imm32 - 9513 # . restore registers - 9514 59/pop-to-ecx - 9515 58/pop-to-eax - 9516 # . epilogue - 9517 89/<- %esp 5/r32/ebp - 9518 5d/pop-to-ebp - 9519 c3/return - 9520 - 9521 new-var-from-slice: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) - 9522 # . prologue - 9523 55/push-ebp - 9524 89/<- %ebp 4/r32/esp - 9525 # . save registers - 9526 51/push-ecx - 9527 # var tmp/ecx: (handle array byte) - 9528 68/push 0/imm32 - 9529 68/push 0/imm32 - 9530 89/<- %ecx 4/r32/esp - 9531 # tmp = slice-to-string(name) - 9532 (slice-to-string Heap *(ebp+0xc) %ecx) - 9533 # out = new-var(tmp) - 9534 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) - 9535 $new-var-from-slice:end: - 9536 # . reclaim locals - 9537 81 0/subop/add %esp 8/imm32 - 9538 # . restore registers - 9539 59/pop-to-ecx - 9540 # . epilogue - 9541 89/<- %esp 5/r32/ebp - 9542 5d/pop-to-ebp - 9543 c3/return - 9544 - 9545 new-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) - 9546 # . prologue - 9547 55/push-ebp - 9548 89/<- %ebp 4/r32/esp - 9549 # . save registers - 9550 50/push-eax - 9551 51/push-ecx - 9552 # - 9553 (allocate *(ebp+8) *Stmt-size *(ebp+0x14)) - 9554 # var out-addr/eax: (addr stmt) = lookup(*out) - 9555 8b/-> *(ebp+0x14) 0/r32/eax - 9556 (lookup *eax *(eax+4)) # => eax - 9557 # out-addr->tag = stmt - 9558 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag - 9559 # result->var = var - 9560 8b/-> *(ebp+0xc) 1/r32/ecx - 9561 89/<- *(eax+4) 1/r32/ecx # Vardef-var - 9562 8b/-> *(ebp+0x10) 1/r32/ecx - 9563 89/<- *(eax+8) 1/r32/ecx # Vardef-var - 9564 $new-var-def:end: - 9565 # . restore registers - 9566 59/pop-to-ecx - 9567 58/pop-to-eax - 9568 # . epilogue - 9569 89/<- %esp 5/r32/ebp - 9570 5d/pop-to-ebp - 9571 c3/return - 9572 - 9573 new-reg-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) - 9574 # . prologue - 9575 55/push-ebp - 9576 89/<- %ebp 4/r32/esp - 9577 # . save registers - 9578 50/push-eax - 9579 # eax = out - 9580 8b/-> *(ebp+0x14) 0/r32/eax - 9581 # - 9582 (allocate *(ebp+8) *Stmt-size %eax) - 9583 # var out-addr/eax: (addr stmt) = lookup(*out) - 9584 (lookup *eax *(eax+4)) # => eax - 9585 # set tag - 9586 c7 0/subop/copy *eax 3/imm32/tag/var-in-register # Stmt-tag - 9587 # set output - 9588 8d/copy-address *(eax+0x14) 0/r32/eax # Regvardef-outputs - 9589 (append-stmt-var Heap *(ebp+0xc) *(ebp+0x10) 0 0 0 %eax) - 9590 $new-reg-var-def:end: - 9591 # . restore registers - 9592 58/pop-to-eax - 9593 # . epilogue - 9594 89/<- %esp 5/r32/ebp - 9595 5d/pop-to-ebp - 9596 c3/return - 9597 - 9598 append-list: # ad: (addr allocation-descriptor), value: (handle _type), list: (handle list _type), out: (addr handle list _type) - 9599 # . prologue - 9600 55/push-ebp - 9601 89/<- %ebp 4/r32/esp - 9602 # . save registers - 9603 50/push-eax - 9604 51/push-ecx - 9605 57/push-edi - 9606 # edi = out - 9607 8b/-> *(ebp+0x1c) 7/r32/edi - 9608 # *out = new list - 9609 (allocate *(ebp+8) *List-size %edi) - 9610 # var out-addr/edi: (addr list _type) = lookup(*out) - 9611 (lookup *edi *(edi+4)) # => eax - 9612 89/<- %edi 0/r32/eax - 9613 # out-addr->value = value - 9614 8b/-> *(ebp+0xc) 0/r32/eax - 9615 89/<- *edi 0/r32/eax # List-value - 9616 8b/-> *(ebp+0x10) 0/r32/eax - 9617 89/<- *(edi+4) 0/r32/eax # List-value - 9618 # if (list == null) return - 9619 81 7/subop/compare *(ebp+0x14) 0/imm32 - 9620 74/jump-if-= $append-list:end/disp8 - 9621 # otherwise append - 9622 $append-list:non-empty-list: - 9623 # var curr/eax: (addr list _type) = lookup(list) - 9624 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax - 9625 # while (curr->next != null) curr = curr->next - 9626 { - 9627 81 7/subop/compare *(eax+8) 0/imm32 # List-next - 9628 74/jump-if-= break/disp8 - 9629 # curr = lookup(curr->next) - 9630 (lookup *(eax+8) *(eax+0xc)) # List-next, List-next => eax - 9631 # - 9632 eb/jump loop/disp8 - 9633 } - 9634 # edi = out - 9635 8b/-> *(ebp+0x1c) 7/r32/edi - 9636 # curr->next = out - 9637 8b/-> *edi 1/r32/ecx - 9638 89/<- *(eax+8) 1/r32/ecx # List-next - 9639 8b/-> *(edi+4) 1/r32/ecx - 9640 89/<- *(eax+0xc) 1/r32/ecx # List-next - 9641 # out = list - 9642 8b/-> *(ebp+0x14) 1/r32/ecx - 9643 89/<- *edi 1/r32/ecx - 9644 8b/-> *(ebp+0x18) 1/r32/ecx - 9645 89/<- *(edi+4) 1/r32/ecx - 9646 $append-list:end: - 9647 # . restore registers - 9648 5f/pop-to-edi - 9649 59/pop-to-ecx - 9650 58/pop-to-eax - 9651 # . epilogue - 9652 89/<- %esp 5/r32/ebp - 9653 5d/pop-to-ebp - 9654 c3/return - 9655 - 9656 append-stmt-var: # ad: (addr allocation-descriptor), v: (handle var), vars: (handle stmt-var), is-deref?: boolean, out: (addr handle stmt-var) - 9657 # . prologue - 9658 55/push-ebp - 9659 89/<- %ebp 4/r32/esp - 9660 # . save registers - 9661 50/push-eax - 9662 51/push-ecx - 9663 57/push-edi - 9664 # edi = out - 9665 8b/-> *(ebp+0x20) 7/r32/edi - 9666 # out = new stmt-var - 9667 (allocate *(ebp+8) *Stmt-var-size %edi) - 9668 # var out-addr/ecx: (addr stmt-var) = lookup(*out) - 9669 (lookup *edi *(edi+4)) # => eax - 9670 89/<- %ecx 0/r32/eax - 9671 # out-addr->value = v - 9672 8b/-> *(ebp+0xc) 0/r32/eax - 9673 89/<- *ecx 0/r32/eax # Stmt-var-value - 9674 8b/-> *(ebp+0x10) 0/r32/eax - 9675 89/<- *(ecx+4) 0/r32/eax # Stmt-var-value - 9676 # out-addr->is-deref? = is-deref? - 9677 8b/-> *(ebp+0x1c) 0/r32/eax - 9678 89/<- *(ecx+0x10) 0/r32/eax # Stmt-var-is-deref - 9679 # if (vars == null) return result - 9680 81 7/subop/compare *(ebp+0x14) 0/imm32/null - 9681 74/jump-if-= $append-stmt-var:end/disp8 - 9682 # otherwise append - 9683 # var curr/eax: (addr stmt-var) = lookup(vars) - 9684 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax - 9685 # while (curr->next != null) curr = curr->next - 9686 { - 9687 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next - 9688 74/jump-if-= break/disp8 - 9689 # curr = lookup(curr->next) - 9690 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next, Stmt-var-next => eax - 9691 # - 9692 eb/jump loop/disp8 - 9693 } - 9694 # curr->next = out - 9695 8b/-> *edi 1/r32/ecx - 9696 89/<- *(eax+8) 1/r32/ecx # Stmt-var-next - 9697 8b/-> *(edi+4) 1/r32/ecx - 9698 89/<- *(eax+0xc) 1/r32/ecx # Stmt-var-next - 9699 # out = vars - 9700 8b/-> *(ebp+0x14) 1/r32/ecx - 9701 89/<- *edi 1/r32/ecx - 9702 8b/-> *(ebp+0x18) 1/r32/ecx - 9703 89/<- *(edi+4) 1/r32/ecx - 9704 $append-stmt-var:end: - 9705 # . restore registers - 9706 5f/pop-to-edi - 9707 59/pop-to-ecx - 9708 58/pop-to-eax - 9709 # . epilogue - 9710 89/<- %esp 5/r32/ebp - 9711 5d/pop-to-ebp - 9712 c3/return - 9713 - 9714 append-to-block: # ad: (addr allocation-descriptor), block: (addr block), x: (handle stmt) - 9715 # . prologue - 9716 55/push-ebp - 9717 89/<- %ebp 4/r32/esp - 9718 # . save registers - 9719 50/push-eax - 9720 56/push-esi - 9721 # esi = block - 9722 8b/-> *(ebp+0xc) 6/r32/esi - 9723 # block->stmts = append(x, block->stmts) - 9724 8d/copy-address *(esi+4) 0/r32/eax # Block-stmts - 9725 (append-list *(ebp+8) *(ebp+0x10) *(ebp+0x14) *(esi+4) *(esi+8) %eax) # ad, x, x, Block-stmts, Block-stmts - 9726 $append-to-block:end: - 9727 # . restore registers - 9728 5e/pop-to-esi - 9729 58/pop-to-eax - 9730 # . epilogue - 9731 89/<- %esp 5/r32/ebp - 9732 5d/pop-to-ebp - 9733 c3/return - 9734 - 9735 ## Parsing types - 9736 # We need to create metadata on user-defined types, and we need to use this - 9737 # metadata as we parse instructions. - 9738 # However, we also want to allow types to be used before their definitions. - 9739 # This means we can't ever assume any type data structures exist. - 9740 - 9741 lookup-or-create-constant: # container: (addr stmt-var), field-name: (addr slice), out: (addr handle var) - 9742 # . prologue - 9743 55/push-ebp - 9744 89/<- %ebp 4/r32/esp - 9745 # . save registers - 9746 50/push-eax - 9747 56/push-esi - 9748 # var container-type/esi: type-id - 9749 (container-type *(ebp+8)) # => eax - 9750 89/<- %esi 0/r32/eax - 9751 # var tmp/eax: (handle typeinfo) = find-or-create-typeinfo(container-type) - 9752 68/push 0/imm32 - 9753 68/push 0/imm32 - 9754 89/<- %eax 4/r32/esp - 9755 (find-or-create-typeinfo %esi %eax) - 9756 # var tmp-addr/eax: (addr typeinfo) = lookup(tmp) - 9757 (lookup *eax *(eax+4)) # => eax - 9758 # result = find-or-create-typeinfo-output-var(typeinfo, field-name) - 9759 #? (write-buffered Stderr "constant: ") - 9760 #? (write-slice-buffered Stderr *(ebp+0xc)) - 9761 #? (write-buffered Stderr Newline) - 9762 #? (flush Stderr) - 9763 (find-or-create-typeinfo-output-var %eax *(ebp+0xc) *(ebp+0x10)) - 9764 #? 8b/-> *(ebp+0x10) 0/r32/eax - 9765 #? (write-buffered Stderr "@") - 9766 #? (lookup *eax *(eax+4)) - 9767 #? (write-int32-hex-buffered Stderr %eax) - 9768 #? (lookup *eax *(eax+4)) - 9769 #? (write-buffered Stderr %eax) - 9770 #? (write-buffered Stderr Newline) - 9771 #? (flush Stderr) - 9772 #? (write-buffered Stderr "offset: ") - 9773 #? 8b/-> *(eax+0x14) 0/r32/eax - 9774 #? (write-int32-hex-buffered Stderr %eax) - 9775 #? (write-buffered Stderr Newline) - 9776 #? (flush Stderr) - 9777 $lookup-or-create-constant:end: - 9778 # . reclaim locals - 9779 81 0/subop/add %esp 8/imm32 + 9492 68/push 0/imm32 + 9493 68/push 0/imm32 + 9494 68/push 0/imm32 + 9495 89/<- %edi 4/r32/esp + 9496 { + 9497 $lookup-var-helper:loop: + 9498 # if (curr < min) return + 9499 39/compare %ebx 2/r32/edx + 9500 0f 82/jump-if-addr< break/disp32 + 9501 # var v/ecx: (addr var) = lookup(*curr) + 9502 (lookup *ebx *(ebx+4)) # => eax + 9503 89/<- %ecx 0/r32/eax + 9504 # var vn/eax: (addr array byte) = lookup(v->name) + 9505 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax + 9506 # if (vn == name) return curr + 9507 (slice-equal? *(ebp+8) %eax) # => eax + 9508 3d/compare-eax-and 0/imm32/false + 9509 { + 9510 74/jump-if-= break/disp8 + 9511 $lookup-var-helper:found: + 9512 # var vr/eax: (addr array byte) = lookup(v->register) + 9513 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax + 9514 3d/compare-eax-and 0/imm32 + 9515 { + 9516 74/jump-if-= break/disp8 + 9517 $lookup-var-helper:found-register: + 9518 # var reg/eax: int = get(Registers, vr) + 9519 (get Mu-registers %eax 0xc "Mu-registers") # => eax + 9520 8b/-> *eax 0/r32/eax + 9521 # if (var-in-reg[reg]) error + 9522 8b/-> *(edi+eax<<2) 0/r32/eax + 9523 3d/compare-eax-and 0/imm32 + 9524 0f 85/jump-if-!= $lookup-var-helper:error2/disp32 + 9525 } + 9526 $lookup-var-helper:return: + 9527 # esi = out + 9528 8b/-> *(ebp+0x10) 6/r32/esi + 9529 # *out = *curr + 9530 8b/-> *ebx 0/r32/eax + 9531 89/<- *esi 0/r32/eax + 9532 8b/-> *(ebx+4) 0/r32/eax + 9533 89/<- *(esi+4) 0/r32/eax + 9534 # return + 9535 eb/jump $lookup-var-helper:end/disp8 + 9536 } + 9537 # 'name' not yet found; update var-in-reg if v in register + 9538 # . var vr/eax: (addr array byte) = lookup(v->register) + 9539 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax + 9540 # . if (var == 0) continue + 9541 3d/compare-eax-and 0/imm32 + 9542 74/jump-if-= $lookup-var-helper:continue/disp8 + 9543 # . var reg/eax: int = get(Registers, vr) + 9544 (get Mu-registers %eax 0xc "Mu-registers") # => eax + 9545 8b/-> *eax 0/r32/eax + 9546 # . if (var-in-reg[reg] == 0) var-in-reg[reg] = v + 9547 81 7/subop/compare *(edi+eax<<2) 0/imm32 + 9548 75/jump-if-!= $lookup-var-helper:continue/disp8 + 9549 89/<- *(edi+eax<<2) 1/r32/ecx + 9550 $lookup-var-helper:continue: + 9551 # curr -= 12 + 9552 81 5/subop/subtract %ebx 0xc/imm32 + 9553 e9/jump loop/disp32 + 9554 } + 9555 $lookup-var-helper:end: + 9556 # . reclaim locals + 9557 81 0/subop/add %esp 0x20/imm32 + 9558 # . restore registers + 9559 5f/pop-to-edi + 9560 5e/pop-to-esi + 9561 5b/pop-to-ebx + 9562 5a/pop-to-edx + 9563 59/pop-to-ecx + 9564 58/pop-to-eax + 9565 # . epilogue + 9566 89/<- %esp 5/r32/ebp + 9567 5d/pop-to-ebp + 9568 c3/return + 9569 + 9570 $lookup-var-helper:error1: + 9571 (write-buffered *(ebp+0x18) "fn ") + 9572 8b/-> *(ebp+0x14) 0/r32/eax + 9573 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 9574 (write-buffered *(ebp+0x18) %eax) + 9575 (write-buffered *(ebp+0x18) ": malformed stack when looking up '") + 9576 (write-slice-buffered *(ebp+0x18) *(ebp+8)) + 9577 (write-buffered *(ebp+0x18) "'\n") + 9578 (flush *(ebp+0x18)) + 9579 (stop *(ebp+0x1c) 1) + 9580 # never gets here + 9581 + 9582 $lookup-var-helper:error2: + 9583 # eax contains the conflicting var at this point + 9584 (write-buffered *(ebp+0x18) "fn ") + 9585 50/push-eax + 9586 8b/-> *(ebp+0x14) 0/r32/eax + 9587 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 9588 (write-buffered *(ebp+0x18) %eax) + 9589 58/pop-eax + 9590 (write-buffered *(ebp+0x18) ": register ") + 9591 50/push-eax + 9592 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax + 9593 (write-buffered *(ebp+0x18) %eax) + 9594 58/pop-to-eax + 9595 (write-buffered *(ebp+0x18) " reads var '") + 9596 (write-slice-buffered *(ebp+0x18) *(ebp+8)) + 9597 (write-buffered *(ebp+0x18) "' after writing var '") + 9598 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 9599 (write-buffered *(ebp+0x18) %eax) + 9600 (write-buffered *(ebp+0x18) "'\n") + 9601 (flush *(ebp+0x18)) + 9602 (stop *(ebp+0x1c) 1) + 9603 # never gets here + 9604 + 9605 dump-vars: # vars: (addr stack live-var) + 9606 # pseudocode: + 9607 # var curr: (addr handle var) = &vars->data[vars->top - 12] + 9608 # var min = vars->data + 9609 # while curr >= min + 9610 # var v: (handle var) = *curr + 9611 # print v + 9612 # curr -= 12 + 9613 # + 9614 # . prologue + 9615 55/push-ebp + 9616 89/<- %ebp 4/r32/esp + 9617 # . save registers + 9618 52/push-edx + 9619 53/push-ebx + 9620 56/push-esi + 9621 # esi = vars + 9622 8b/-> *(ebp+8) 6/r32/esi + 9623 # ebx = vars->top + 9624 8b/-> *esi 3/r32/ebx + 9625 # var min/edx: (addr handle var) = vars->data + 9626 8d/copy-address *(esi+8) 2/r32/edx + 9627 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] + 9628 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 + 9629 { + 9630 $dump-vars:loop: + 9631 # if (curr < min) return + 9632 39/compare %ebx 2/r32/edx + 9633 0f 82/jump-if-addr< break/disp32 + 9634 # + 9635 (write-buffered Stderr " var@") + 9636 (dump-var 2 %ebx) + 9637 # curr -= 12 + 9638 81 5/subop/subtract %ebx 0xc/imm32 + 9639 e9/jump loop/disp32 + 9640 } + 9641 $dump-vars:end: + 9642 # . restore registers + 9643 5e/pop-to-esi + 9644 5b/pop-to-ebx + 9645 5a/pop-to-edx + 9646 # . epilogue + 9647 89/<- %esp 5/r32/ebp + 9648 5d/pop-to-ebp + 9649 c3/return + 9650 + 9651 == data + 9652 # Like Registers, but no esp or ebp + 9653 Mu-registers: # (addr stream {(handle array byte), int}) + 9654 # a table is a stream + 9655 0x48/imm32/write + 9656 0/imm32/read + 9657 0x48/imm32/length + 9658 # data + 9659 # it is perfectly ok to use fake alloc-ids -- as long as you never try to reclaim them + 9660 0x11/imm32/alloc-id $Mu-register-eax/imm32 0/imm32 + 9661 0x11/imm32/alloc-id $Mu-register-ecx/imm32 1/imm32 + 9662 0x11/imm32/alloc-id $Mu-register-edx/imm32 2/imm32 + 9663 0x11/imm32/alloc-id $Mu-register-ebx/imm32 3/imm32 + 9664 0x11/imm32/alloc-id $Mu-register-esi/imm32 6/imm32 + 9665 0x11/imm32/alloc-id $Mu-register-edi/imm32 7/imm32 + 9666 + 9667 $Mu-register-eax: + 9668 0x11/imm32/alloc-id + 9669 3/imm32/size + 9670 0x65/e 0x61/a 0x78/x + 9671 + 9672 $Mu-register-ecx: + 9673 0x11/imm32/alloc-id + 9674 3/imm32/size + 9675 0x65/e 0x63/c 0x78/x + 9676 + 9677 $Mu-register-edx: + 9678 0x11/imm32/alloc-id + 9679 3/imm32/size + 9680 0x65/e 0x64/d 0x78/x + 9681 + 9682 $Mu-register-ebx: + 9683 0x11/imm32/alloc-id + 9684 3/imm32/size + 9685 0x65/e 0x62/b 0x78/x + 9686 + 9687 $Mu-register-esi: + 9688 0x11/imm32/alloc-id + 9689 3/imm32/size + 9690 0x65/e 0x73/s 0x69/i + 9691 + 9692 $Mu-register-edi: + 9693 0x11/imm32/alloc-id + 9694 3/imm32/size + 9695 0x65/e 0x64/d 0x69/i + 9696 + 9697 == code + 9698 + 9699 # return first 'name' from the top (back) of 'vars' and create a new var for a fn output if not found + 9700 lookup-var-or-find-in-fn-outputs: # name: (addr slice), vars: (addr stack live-var), fn: (addr function), out: (addr handle var), err: (addr buffered-file), ed: (addr exit-descriptor) + 9701 # . prologue + 9702 55/push-ebp + 9703 89/<- %ebp 4/r32/esp + 9704 # . save registers + 9705 50/push-eax + 9706 # + 9707 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) # arg order slightly different; 'fn' is deemphasized + 9708 { + 9709 # if (out != 0) return + 9710 8b/-> *(ebp+0x14) 0/r32/eax + 9711 81 7/subop/compare *eax 0/imm32 + 9712 75/jump-if-!= break/disp8 + 9713 # if name is one of fn's outputs, return it + 9714 (find-in-function-outputs *(ebp+0x10) *(ebp+8) *(ebp+0x14)) + 9715 8b/-> *(ebp+0x14) 0/r32/eax + 9716 81 7/subop/compare *eax 0/imm32 + 9717 # otherwise abort + 9718 0f 84/jump-if-= $lookup-or-define-var:abort/disp32 + 9719 } + 9720 $lookup-or-define-var:end: + 9721 # . restore registers + 9722 58/pop-to-eax + 9723 # . epilogue + 9724 89/<- %esp 5/r32/ebp + 9725 5d/pop-to-ebp + 9726 c3/return + 9727 + 9728 $lookup-or-define-var:abort: + 9729 (write-buffered *(ebp+0x18) "unknown variable '") + 9730 (write-slice-buffered *(ebp+0x18) *(ebp+8)) + 9731 (write-buffered *(ebp+0x18) "'\n") + 9732 (flush *(ebp+0x18)) + 9733 (stop *(ebp+0x1c) 1) + 9734 # never gets here + 9735 + 9736 find-in-function-outputs: # fn: (addr function), name: (addr slice), out: (addr handle var) + 9737 # . prologue + 9738 55/push-ebp + 9739 89/<- %ebp 4/r32/esp + 9740 # . save registers + 9741 50/push-eax + 9742 51/push-ecx + 9743 # var curr/ecx: (addr list var) = lookup(fn->outputs) + 9744 8b/-> *(ebp+8) 1/r32/ecx + 9745 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax + 9746 89/<- %ecx 0/r32/eax + 9747 # while curr != null + 9748 { + 9749 81 7/subop/compare %ecx 0/imm32 + 9750 74/jump-if-= break/disp8 + 9751 # var v/eax: (addr var) = lookup(curr->value) + 9752 (lookup *ecx *(ecx+4)) # List-value List-value => eax + 9753 # var s/eax: (addr array byte) = lookup(v->name) + 9754 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 9755 # if (s == name) return curr->value + 9756 (slice-equal? *(ebp+0xc) %eax) # => eax + 9757 3d/compare-eax-and 0/imm32/false + 9758 { + 9759 74/jump-if-= break/disp8 + 9760 # var edi = out + 9761 57/push-edi + 9762 8b/-> *(ebp+0x10) 7/r32/edi + 9763 # *out = curr->value + 9764 8b/-> *ecx 0/r32/eax + 9765 89/<- *edi 0/r32/eax + 9766 8b/-> *(ecx+4) 0/r32/eax + 9767 89/<- *(edi+4) 0/r32/eax + 9768 # + 9769 5f/pop-to-edi + 9770 eb/jump $find-in-function-outputs:end/disp8 + 9771 } + 9772 # curr = curr->next + 9773 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax + 9774 89/<- %ecx 0/r32/eax + 9775 # + 9776 eb/jump loop/disp8 + 9777 } + 9778 b8/copy-to-eax 0/imm32 + 9779 $find-in-function-outputs:end: 9780 # . restore registers - 9781 5e/pop-to-esi + 9781 59/pop-to-ecx 9782 58/pop-to-eax 9783 # . epilogue 9784 89/<- %esp 5/r32/ebp 9785 5d/pop-to-ebp 9786 c3/return 9787 - 9788 # if addr var: - 9789 # container->var->type->right->left->value - 9790 # otherwise - 9791 # container->var->type->value - 9792 container-type: # container: (addr stmt-var) -> result/eax: type-id - 9793 # . prologue - 9794 55/push-ebp - 9795 89/<- %ebp 4/r32/esp - 9796 # - 9797 8b/-> *(ebp+8) 0/r32/eax - 9798 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 9799 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax - 9800 { - 9801 81 7/subop/compare *(eax+8) 0/imm32 # Type-tree-right - 9802 74/jump-if-= break/disp8 - 9803 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax - 9804 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax - 9805 } - 9806 8b/-> *(eax+4) 0/r32/eax # Type-tree-value - 9807 $container-type:end: + 9788 # push 'out' to 'vars' if not already there; it's assumed to be a fn output + 9789 maybe-define-var: # out: (handle var), vars: (addr stack live-var) + 9790 # . prologue + 9791 55/push-ebp + 9792 89/<- %ebp 4/r32/esp + 9793 # . save registers + 9794 50/push-eax + 9795 # var out-addr/eax: (addr var) + 9796 (lookup *(ebp+8) *(ebp+0xc)) # => eax + 9797 # + 9798 (binding-exists? %eax *(ebp+0x10)) # => eax + 9799 3d/compare-eax-and 0/imm32/false + 9800 75/jump-if-!= $maybe-define-var:end/disp8 + 9801 # otherwise update vars + 9802 (push *(ebp+0x10) *(ebp+8)) + 9803 (push *(ebp+0x10) *(ebp+0xc)) + 9804 (push *(ebp+0x10) 0) # 'out' is always a fn output; never spill it + 9805 $maybe-define-var:end: + 9806 # . restore registers + 9807 58/pop-to-eax 9808 # . epilogue 9809 89/<- %esp 5/r32/ebp 9810 5d/pop-to-ebp 9811 c3/return 9812 - 9813 is-container?: # t: type-id -> result/eax: boolean - 9814 # . prologue - 9815 55/push-ebp - 9816 89/<- %ebp 4/r32/esp - 9817 # - 9818 8b/-> *(ebp+8) 0/r32/eax - 9819 c1/shift 4/subop/left %eax 2/imm8 - 9820 3b/compare 0/r32/eax *Primitive-type-ids - 9821 0f 9d/set-if->= %al - 9822 81 4/subop/and %eax 0xff/imm32 - 9823 $is-container?:end: - 9824 # . epilogue - 9825 89/<- %esp 5/r32/ebp - 9826 5d/pop-to-ebp - 9827 c3/return - 9828 - 9829 find-or-create-typeinfo: # t: type-id, out: (addr handle typeinfo) - 9830 # . prologue - 9831 55/push-ebp - 9832 89/<- %ebp 4/r32/esp - 9833 # . save registers - 9834 50/push-eax - 9835 51/push-ecx - 9836 52/push-edx - 9837 57/push-edi - 9838 # edi = out - 9839 8b/-> *(ebp+0xc) 7/r32/edi - 9840 # var fields/ecx: (handle table (handle array byte) (handle typeinfo-entry)) - 9841 68/push 0/imm32 - 9842 68/push 0/imm32 - 9843 89/<- %ecx 4/r32/esp - 9844 # find-typeinfo(t, out) - 9845 (find-typeinfo *(ebp+8) %edi) - 9846 { - 9847 # if (*out != 0) break - 9848 81 7/subop/compare *edi 0/imm32 - 9849 0f 85/jump-if-!= break/disp32 - 9850 $find-or-create-typeinfo:create: - 9851 # *out = allocate - 9852 (allocate Heap *Typeinfo-size %edi) - 9853 # var tmp/eax: (addr typeinfo) = lookup(*out) - 9854 (lookup *edi *(edi+4)) # => eax - 9855 #? (write-buffered Stderr "created typeinfo at ") - 9856 #? (write-int32-hex-buffered Stderr %eax) - 9857 #? (write-buffered Stderr " for type-id ") - 9858 #? (write-int32-hex-buffered Stderr *(ebp+8)) - 9859 #? (write-buffered Stderr Newline) - 9860 #? (flush Stderr) - 9861 # tmp->id = t - 9862 8b/-> *(ebp+8) 2/r32/edx - 9863 89/<- *eax 2/r32/edx # Typeinfo-id - 9864 # tmp->fields = new table - 9865 # . fields = new table - 9866 (new-stream Heap 0x40 *Typeinfo-fields-row-size %ecx) - 9867 # . tmp->fields = fields - 9868 8b/-> *ecx 2/r32/edx - 9869 89/<- *(eax+4) 2/r32/edx # Typeinfo-fields - 9870 8b/-> *(ecx+4) 2/r32/edx - 9871 89/<- *(eax+8) 2/r32/edx # Typeinfo-fields - 9872 # tmp->next = Program->types - 9873 8b/-> *_Program-types 1/r32/ecx - 9874 89/<- *(eax+0x10) 1/r32/ecx # Typeinfo-next - 9875 8b/-> *_Program-types->payload 1/r32/ecx - 9876 89/<- *(eax+0x14) 1/r32/ecx # Typeinfo-next - 9877 # Program->types = out - 9878 8b/-> *edi 1/r32/ecx - 9879 89/<- *_Program-types 1/r32/ecx - 9880 8b/-> *(edi+4) 1/r32/ecx - 9881 89/<- *_Program-types->payload 1/r32/ecx - 9882 } - 9883 $find-or-create-typeinfo:end: - 9884 # . reclaim locals - 9885 81 0/subop/add %esp 8/imm32 - 9886 # . restore registers - 9887 5f/pop-to-edi - 9888 5a/pop-to-edx - 9889 59/pop-to-ecx - 9890 58/pop-to-eax - 9891 # . epilogue - 9892 89/<- %esp 5/r32/ebp - 9893 5d/pop-to-ebp - 9894 c3/return - 9895 - 9896 find-typeinfo: # t: type-id, out: (addr handle typeinfo) - 9897 # . prologue - 9898 55/push-ebp - 9899 89/<- %ebp 4/r32/esp - 9900 # . save registers - 9901 50/push-eax - 9902 51/push-ecx - 9903 52/push-edx - 9904 57/push-edi - 9905 # ecx = t - 9906 8b/-> *(ebp+8) 1/r32/ecx - 9907 # edi = out - 9908 8b/-> *(ebp+0xc) 7/r32/edi - 9909 # *out = Program->types - 9910 8b/-> *_Program-types 0/r32/eax - 9911 89/<- *edi 0/r32/eax - 9912 8b/-> *_Program-types->payload 0/r32/eax - 9913 89/<- *(edi+4) 0/r32/eax - 9914 { - 9915 $find-typeinfo:loop: - 9916 # if (*out == 0) break - 9917 81 7/subop/compare *edi 0/imm32 - 9918 74/jump-if-= break/disp8 - 9919 $find-typeinfo:check: - 9920 # var tmp/eax: (addr typeinfo) = lookup(*out) - 9921 (lookup *edi *(edi+4)) # => eax - 9922 # if (tmp->id == t) break - 9923 39/compare *eax 1/r32/ecx # Typeinfo-id - 9924 74/jump-if-= break/disp8 - 9925 $find-typeinfo:continue: - 9926 # *out = tmp->next - 9927 8b/-> *(eax+0x10) 2/r32/edx # Typeinfo-next - 9928 89/<- *edi 2/r32/edx - 9929 8b/-> *(eax+0x14) 2/r32/edx # Typeinfo-next - 9930 89/<- *(edi+4) 2/r32/edx - 9931 # - 9932 eb/jump loop/disp8 - 9933 } - 9934 $find-typeinfo:end: - 9935 # . restore registers - 9936 5f/pop-to-edi - 9937 5a/pop-to-edx - 9938 59/pop-to-ecx - 9939 58/pop-to-eax - 9940 # . epilogue - 9941 89/<- %esp 5/r32/ebp - 9942 5d/pop-to-ebp - 9943 c3/return - 9944 - 9945 find-or-create-typeinfo-output-var: # T: (addr typeinfo), f: (addr slice), out: (addr handle var) - 9946 # . prologue - 9947 55/push-ebp - 9948 89/<- %ebp 4/r32/esp - 9949 # . save registers - 9950 50/push-eax - 9951 52/push-edx - 9952 57/push-edi - 9953 # var dest/edi: (handle typeinfo-entry) - 9954 68/push 0/imm32 - 9955 68/push 0/imm32 - 9956 89/<- %edi 4/r32/esp - 9957 # find-or-create-typeinfo-fields(T, f, dest) - 9958 (find-or-create-typeinfo-fields *(ebp+8) *(ebp+0xc) %edi) - 9959 # var dest-addr/edi: (addr typeinfo-entry) = lookup(dest) - 9960 (lookup *edi *(edi+4)) # => eax - 9961 89/<- %edi 0/r32/eax - 9962 # if dest-addr->output-var doesn't exist, create it - 9963 { - 9964 81 7/subop/compare *(edi+0xc) 0/imm32 # Typeinfo-entry-output-var - 9965 0f 85/jump-if-!= break/disp32 - 9966 # dest-addr->output-var = new var(dummy name, type, -1 offset) - 9967 # . var name/eax: (handle array byte) = "field" - 9968 68/push 0/imm32 - 9969 68/push 0/imm32 - 9970 89/<- %eax 4/r32/esp - 9971 (slice-to-string Heap *(ebp+0xc) %eax) - 9972 # . new var - 9973 8d/copy-address *(edi+0xc) 2/r32/edx - 9974 (new-var Heap *eax *(eax+4) %edx) - 9975 # . reclaim name - 9976 81 0/subop/add %esp 8/imm32 - 9977 # var result/edx: (addr var) = lookup(dest-addr->output-var) - 9978 (lookup *(edi+0xc) *(edi+0x10)) # => eax - 9979 89/<- %edx 0/r32/eax - 9980 # result->type = new constant type - 9981 8d/copy-address *(edx+8) 0/r32/eax # Var-type - 9982 (allocate Heap *Type-tree-size %eax) - 9983 (lookup *(edx+8) *(edx+0xc)) # => eax - 9984 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom - 9985 c7 0/subop/copy *(eax+4) 6/imm32/constant # Type-tree-value - 9986 c7 0/subop/copy *(eax+8) 0/imm32 # Type-tree-left - 9987 c7 0/subop/copy *(eax+0xc) 0/imm32 # Type-tree-right - 9988 c7 0/subop/copy *(eax+0x10) 0/imm32 # Type-tree-right - 9989 # result->offset isn't filled out yet - 9990 c7 0/subop/copy *(edx+0x14) -1/imm32/uninitialized # Var-offset - 9991 } - 9992 # out = dest-addr->output-var - 9993 8b/-> *(ebp+0x10) 2/r32/edx - 9994 8b/-> *(edi+0xc) 0/r32/eax # Typeinfo-entry-output-var - 9995 89/<- *edx 0/r32/eax - 9996 8b/-> *(edi+0x10) 0/r32/eax # Typeinfo-entry-output-var - 9997 89/<- *(edx+4) 0/r32/eax - 9998 $find-or-create-typeinfo-output-var:end: - 9999 # . reclaim locals -10000 81 0/subop/add %esp 8/imm32 -10001 # . restore registers -10002 5f/pop-to-edi -10003 5a/pop-to-edx -10004 58/pop-to-eax -10005 # . epilogue -10006 89/<- %esp 5/r32/ebp -10007 5d/pop-to-ebp -10008 c3/return -10009 -10010 find-or-create-typeinfo-fields: # T: (addr typeinfo), f: (addr slice), out: (addr handle typeinfo-entry) -10011 # . prologue -10012 55/push-ebp -10013 89/<- %ebp 4/r32/esp -10014 # . save registers -10015 50/push-eax -10016 56/push-esi -10017 57/push-edi -10018 # eax = lookup(T->fields) -10019 8b/-> *(ebp+8) 0/r32/eax -10020 (lookup *(eax+4) *(eax+8)) # Typeinfo-fields Typeinfo-fields => eax -10021 # edi = out -10022 8b/-> *(ebp+0x10) 7/r32/edi -10023 # var src/esi: (addr handle typeinfo-entry) = get-or-insert-slice(T->fields, f) -10024 (get-or-insert-slice %eax *(ebp+0xc) *Typeinfo-fields-row-size Heap) # => eax -10025 89/<- %esi 0/r32/eax -10026 # if src doesn't exist, allocate it -10027 { -10028 81 7/subop/compare *esi 0/imm32 -10029 75/jump-if-!= break/disp8 -10030 (allocate Heap *Typeinfo-entry-size %esi) -10031 #? (write-buffered Stderr "handle at ") -10032 #? (write-int32-hex-buffered Stderr %esi) -10033 #? (write-buffered Stderr ": ") -10034 #? (write-int32-hex-buffered Stderr *esi) -10035 #? (write-buffered Stderr " ") -10036 #? (write-int32-hex-buffered Stderr *(esi+4)) -10037 #? (write-buffered Stderr Newline) -10038 #? (flush Stderr) -10039 #? (lookup *esi *(esi+4)) -10040 #? (write-buffered Stderr "created typeinfo fields at ") -10041 #? (write-int32-hex-buffered Stderr %esi) -10042 #? (write-buffered Stderr " for ") -10043 #? (write-int32-hex-buffered Stderr *(ebp+8)) -10044 #? (write-buffered Stderr Newline) -10045 #? (flush Stderr) -10046 } -10047 # *out = src -10048 # . *edi = *src -10049 8b/-> *esi 0/r32/eax -10050 89/<- *edi 0/r32/eax -10051 8b/-> *(esi+4) 0/r32/eax -10052 89/<- *(edi+4) 0/r32/eax -10053 $find-or-create-typeinfo-fields:end: -10054 # . restore registers -10055 5f/pop-to-edi -10056 5e/pop-to-esi -10057 58/pop-to-eax -10058 # . epilogue -10059 89/<- %esp 5/r32/ebp -10060 5d/pop-to-ebp -10061 c3/return -10062 -10063 populate-mu-type: # in: (addr stream byte), t: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) -10064 # pseudocode: -10065 # var line: (stream byte 512) -10066 # curr-index = 0 -10067 # while true -10068 # clear-stream(line) -10069 # read-line-buffered(in, line) -10070 # if line->write == 0 -10071 # abort -10072 # word-slice = next-mu-token(line) -10073 # if slice-empty?(word-slice) # end of line -10074 # continue -10075 # if slice-equal?(word-slice, "}") -10076 # break -10077 # var v: (handle var) = parse-var-with-type(word-slice, line) -10078 # var r: (handle typeinfo-fields) = find-or-create-typeinfo-fields(t, word-slice/v->name) -10079 # TODO: ensure that r->first is null -10080 # r->index = curr-index -10081 # curr-index++ -10082 # r->input-var = v -10083 # if r->output-var == 0 -10084 # r->output-var = new literal -10085 # TODO: ensure nothing else in line -10086 # t->total-size-in-bytes = -2 (not yet initialized) -10087 # -10088 # . prologue -10089 55/push-ebp -10090 89/<- %ebp 4/r32/esp -10091 # var curr-index: int at *(ebp-4) -10092 68/push 0/imm32 -10093 # . save registers -10094 50/push-eax -10095 51/push-ecx -10096 52/push-edx -10097 53/push-ebx -10098 56/push-esi -10099 57/push-edi -10100 # edi = t -10101 8b/-> *(ebp+0xc) 7/r32/edi -10102 # var line/ecx: (stream byte 512) -10103 81 5/subop/subtract %esp 0x200/imm32 -10104 68/push 0x200/imm32/size -10105 68/push 0/imm32/read -10106 68/push 0/imm32/write -10107 89/<- %ecx 4/r32/esp -10108 # var word-slice/edx: slice -10109 68/push 0/imm32/end -10110 68/push 0/imm32/start -10111 89/<- %edx 4/r32/esp -10112 # var v/esi: (handle var) -10113 68/push 0/imm32 -10114 68/push 0/imm32 -10115 89/<- %esi 4/r32/esp -10116 # var r/ebx: (handle typeinfo-entry) -10117 68/push 0/imm32 -10118 68/push 0/imm32 -10119 89/<- %ebx 4/r32/esp -10120 { -10121 $populate-mu-type:line-loop: -10122 (clear-stream %ecx) -10123 (read-line-buffered *(ebp+8) %ecx) -10124 # if (line->write == 0) abort -10125 81 7/subop/compare *ecx 0/imm32 -10126 0f 84/jump-if-= $populate-mu-type:abort/disp32 -10127 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ -10133 (next-mu-token %ecx %edx) -10134 # if slice-empty?(word-slice) continue -10135 (slice-empty? %edx) # => eax -10136 3d/compare-eax-and 0/imm32 -10137 0f 85/jump-if-!= loop/disp32 -10138 # if slice-equal?(word-slice, "}") break -10139 (slice-equal? %edx "}") -10140 3d/compare-eax-and 0/imm32 -10141 0f 85/jump-if-!= break/disp32 -10142 $populate-mu-type:parse-element: -10143 # v = parse-var-with-type(word-slice, first-line) -10144 # must do this first to strip the trailing ':' from word-slice before -10145 # using it in find-or-create-typeinfo-fields below -10146 # TODO: clean up that mutation in parse-var-with-type -10147 (parse-var-with-type %edx %ecx %esi *(ebp+0x10) *(ebp+0x14)) # => eax -10148 # var tmp/ecx -10149 51/push-ecx -10150 $populate-mu-type:create-typeinfo-fields: -10151 # var r/ebx: (handle typeinfo-entry) -10152 (find-or-create-typeinfo-fields %edi %edx %ebx) -10153 # r->index = curr-index -10154 (lookup *ebx *(ebx+4)) # => eax -10155 8b/-> *(ebp-4) 1/r32/ecx -10156 #? (write-buffered Stderr "saving index ") -10157 #? (write-int32-hex-buffered Stderr %ecx) -10158 #? (write-buffered Stderr " at ") -10159 #? (write-int32-hex-buffered Stderr %edi) -10160 #? (write-buffered Stderr Newline) -10161 #? (flush Stderr) -10162 89/<- *(eax+8) 1/r32/ecx # Typeinfo-entry-index -10163 # ++curr-index -10164 ff 0/subop/increment *(ebp-4) -10165 $populate-mu-type:set-input-type: -10166 # r->input-var = v -10167 8b/-> *esi 1/r32/ecx -10168 89/<- *eax 1/r32/ecx # Typeinfo-entry-input-var -10169 8b/-> *(esi+4) 1/r32/ecx -10170 89/<- *(eax+4) 1/r32/ecx # Typeinfo-entry-input-var -10171 59/pop-to-ecx -10172 { -10173 $populate-mu-type:create-output-type: -10174 # if (r->output-var == 0) create a new var with some placeholder data -10175 81 7/subop/compare *(eax+0xc) 0/imm32 # Typeinfo-entry-output-var -10176 75/jump-if-!= break/disp8 -10177 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var -10178 (new-literal Heap %edx %eax) -10179 } -10180 e9/jump loop/disp32 -10181 } -10182 $populate-mu-type:invalidate-total-size-in-bytes: -10183 # Offsets and total size may not be accurate here since we may not yet -10184 # have encountered the element types. -10185 # We'll recompute them separately after parsing the entire program. -10186 c7 0/subop/copy *(edi+0xc) -2/imm32/uninitialized # Typeinfo-total-size-in-bytes -10187 $populate-mu-type:end: -10188 # . reclaim locals -10189 81 0/subop/add %esp 0x224/imm32 -10190 # . restore registers -10191 5f/pop-to-edi -10192 5e/pop-to-esi -10193 5b/pop-to-ebx -10194 5a/pop-to-edx -10195 59/pop-to-ecx -10196 58/pop-to-eax -10197 # reclaim curr-index -10198 81 0/subop/add %esp 4/imm32 -10199 # . epilogue -10200 89/<- %esp 5/r32/ebp -10201 5d/pop-to-ebp -10202 c3/return -10203 -10204 $populate-mu-type:abort: -10205 # error("unexpected top-level command: " word-slice "\n") -10206 (write-buffered *(ebp+0x10) "incomplete type definition '") -10207 (type-name *edi) # Typeinfo-id => eax -10208 (write-buffered *(ebp+0x10) %eax) -10209 (write-buffered *(ebp+0x10) "\n") -10210 (flush *(ebp+0x10)) -10211 (stop *(ebp+0x14) 1) -10212 # never gets here -10213 -10214 type-name: # index: int -> result/eax: (addr array byte) -10215 # . prologue -10216 55/push-ebp -10217 89/<- %ebp 4/r32/esp -10218 # -10219 (index Type-id *(ebp+8)) -10220 $type-name:end: -10221 # . epilogue -10222 89/<- %esp 5/r32/ebp -10223 5d/pop-to-ebp -10224 c3/return -10225 -10226 index: # arr: (addr stream (handle array byte)), index: int -> result/eax: (addr array byte) -10227 # . prologue -10228 55/push-ebp -10229 89/<- %ebp 4/r32/esp -10230 # . save registers -10231 56/push-esi -10232 # TODO: bounds-check index -10233 # esi = arr -10234 8b/-> *(ebp+8) 6/r32/esi -10235 # eax = index -10236 8b/-> *(ebp+0xc) 0/r32/eax -10237 # eax = *(arr + 12 + index) -10238 8b/-> *(esi+eax+0xc) 0/r32/eax -10239 $index:end: -10240 # . restore registers -10241 5e/pop-to-esi -10242 # . epilogue -10243 89/<- %esp 5/r32/ebp -10244 5d/pop-to-ebp -10245 c3/return -10246 -10247 ####################################################### -10248 # Compute type sizes -10249 ####################################################### -10250 -10251 # Compute the sizes of all user-defined types. -10252 # We'll need the sizes of their elements, which may be other user-defined -10253 # types, which we will compute as needed. -10254 -10255 # Initially, all user-defined types have their sizes set to -2 (invalid) -10256 populate-mu-type-sizes: # err: (addr buffered-file), ed: (addr exit-descriptor) -10257 # . prologue -10258 55/push-ebp -10259 89/<- %ebp 4/r32/esp -10260 $populate-mu-type-sizes:total-sizes: -10261 # var curr/eax: (addr typeinfo) = lookup(Program->types) -10262 (lookup *_Program-types *_Program-types->payload) # => eax -10263 { -10264 # if (curr == null) break -10265 3d/compare-eax-and 0/imm32/null -10266 74/jump-if-= break/disp8 -10267 (populate-mu-type-sizes-in-type %eax *(ebp+8) *(ebp+0xc)) -10268 # curr = lookup(curr->next) -10269 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax -10270 eb/jump loop/disp8 -10271 } -10272 $populate-mu-type-sizes:offsets: -10273 # curr = *Program->types -10274 (lookup *_Program-types *_Program-types->payload) # => eax -10275 { -10276 # if (curr == null) break -10277 3d/compare-eax-and 0/imm32/null -10278 74/jump-if-= break/disp8 -10279 (populate-mu-type-offsets %eax *(ebp+8) *(ebp+0xc)) -10280 # curr = curr->next -10281 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax -10282 eb/jump loop/disp8 -10283 } -10284 $populate-mu-type-sizes:end: -10285 # . epilogue -10286 89/<- %esp 5/r32/ebp -10287 5d/pop-to-ebp -10288 c3/return -10289 -10290 # compute sizes of all fields, recursing as necessary -10291 # sum up all their sizes to arrive at total size -10292 # fields may be out of order, but that doesn't affect the answer -10293 populate-mu-type-sizes-in-type: # T: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) -10294 # . prologue -10295 55/push-ebp -10296 89/<- %ebp 4/r32/esp -10297 # . save registers -10298 50/push-eax -10299 51/push-ecx -10300 52/push-edx -10301 56/push-esi -10302 57/push-edi -10303 # esi = T -10304 8b/-> *(ebp+8) 6/r32/esi -10305 # if T is already computed, return -10306 81 7/subop/compare *(esi+0xc) 0/imm32 # Typeinfo-total-size-in-bytes -10307 0f 8d/jump-if->= $populate-mu-type-sizes-in-type:end/disp32 -10308 # if T is being computed, abort -10309 81 7/subop/compare *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes -10310 0f 84/jump-if-= $populate-mu-type-sizes-in-type:abort/disp32 -10311 # tag T (-2 to -1) to avoid infinite recursion -10312 c7 0/subop/copy *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes -10313 # var total-size/edi: int = 0 -10314 bf/copy-to-edi 0/imm32 -10315 # - for every field, if it's a user-defined type, compute its size -10316 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) -10317 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax -10318 89/<- %ecx 0/r32/eax -10319 # var table-size/edx: int = table->write -10320 8b/-> *ecx 2/r32/edx # stream-write -10321 # var curr/ecx: (addr table_row) = table->data -10322 8d/copy-address *(ecx+0xc) 1/r32/ecx -10323 # var max/edx: (addr table_row) = table->data + table->write -10324 8d/copy-address *(ecx+edx) 2/r32/edx -10325 { -10326 $populate-mu-type-sizes-in-type:loop: -10327 # if (curr >= max) break -10328 39/compare %ecx 2/r32/edx -10329 73/jump-if-addr>= break/disp8 -10330 # var t/eax: (addr typeinfo-entry) = lookup(curr->value) -10331 (lookup *(ecx+8) *(ecx+0xc)) # => eax -10332 # if (t->input-var == 0) silently ignore it; we'll emit a nice error message while type-checking -10333 81 7/subop/compare *eax 0/imm32 # Typeinfo-entry-input-var -10334 74/jump-if-= $populate-mu-type-sizes-in-type:end/disp8 -10335 # compute size of t->input-var -10336 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax -10337 (compute-size-of-var %eax) # => eax -10338 # result += eax -10339 01/add-to %edi 0/r32/eax -10340 # curr += row-size -10341 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size -10342 # -10343 eb/jump loop/disp8 -10344 } -10345 # - save result -10346 89/<- *(esi+0xc) 7/r32/edi # Typeinfo-total-size-in-bytes -10347 $populate-mu-type-sizes-in-type:end: -10348 # . restore registers -10349 5f/pop-to-edi -10350 5e/pop-to-esi -10351 5a/pop-to-edx -10352 59/pop-to-ecx -10353 58/pop-to-eax -10354 # . epilogue -10355 89/<- %esp 5/r32/ebp -10356 5d/pop-to-ebp -10357 c3/return -10358 -10359 $populate-mu-type-sizes-in-type:abort: -10360 (write-buffered *(ebp+0xc) "cycle in type definitions\n") -10361 (flush *(ebp+0xc)) -10362 (stop *(ebp+0x10) 1) -10363 # never gets here -10364 -10365 # Analogous to size-of, except we need to compute what size-of can just read -10366 # off the right data structures. -10367 compute-size-of-var: # in: (addr var) -> result/eax: int -10368 # . prologue -10369 55/push-ebp -10370 89/<- %ebp 4/r32/esp -10371 # . push registers -10372 51/push-ecx -10373 # var t/ecx: (addr type-tree) = lookup(v->type) -10374 8b/-> *(ebp+8) 1/r32/ecx -10375 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -10376 89/<- %ecx 0/r32/eax -10377 # if (t->is-atom == false) t = lookup(t->left) -10378 { -10379 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -10380 75/jump-if-!= break/disp8 -10381 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -10382 89/<- %ecx 0/r32/eax -10383 } -10384 # TODO: ensure t is an atom -10385 (compute-size-of-type-id *(ecx+4)) # Type-tree-value => eax -10386 $compute-size-of-var:end: -10387 # . restore registers -10388 59/pop-to-ecx -10389 # . epilogue -10390 89/<- %esp 5/r32/ebp -10391 5d/pop-to-ebp -10392 c3/return -10393 -10394 compute-size-of-type-id: # t: type-id -> result/eax: int -10395 # . prologue -10396 55/push-ebp -10397 89/<- %ebp 4/r32/esp -10398 # . save registers -10399 51/push-ecx -10400 # var out/ecx: (handle typeinfo) -10401 68/push 0/imm32 -10402 68/push 0/imm32 -10403 89/<- %ecx 4/r32/esp -10404 # eax = t -10405 8b/-> *(ebp+8) 0/r32/eax -10406 # if t is a literal, return 0 -10407 3d/compare-eax-and 0/imm32/literal -10408 0f 84/jump-if-= $compute-size-of-type-id:end/disp32 # eax changes type from type-id to int -10409 # if t is a byte, return 4 (because we don't really support non-multiples of 4) -10410 3d/compare-eax-and 8/imm32/byte -10411 { -10412 75/jump-if-!= break/disp8 -10413 b8/copy-to-eax 4/imm32 -10414 eb/jump $compute-size-of-type-id:end/disp8 -10415 } -10416 # if t is a handle, return 8 -10417 3d/compare-eax-and 4/imm32/handle -10418 { -10419 75/jump-if-!= break/disp8 -10420 b8/copy-to-eax 8/imm32 -10421 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int -10422 } -10423 # if t is a user-defined type, compute its size -10424 # TODO: support non-atom type -10425 (find-typeinfo %eax %ecx) -10426 { -10427 81 7/subop/compare *ecx 0/imm32 -10428 74/jump-if-= break/disp8 -10429 $compute-size-of-type-id:user-defined: -10430 (populate-mu-type-sizes %eax) -10431 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes -10432 eb/jump $compute-size-of-type-id:end/disp8 -10433 } -10434 # otherwise return the word size -10435 b8/copy-to-eax 4/imm32 -10436 $compute-size-of-type-id:end: -10437 # . reclaim locals -10438 81 0/subop/add %esp 8/imm32 -10439 # . restore registers -10440 59/pop-to-ecx -10441 # . epilogue -10442 89/<- %esp 5/r32/ebp -10443 5d/pop-to-ebp -10444 c3/return -10445 -10446 # at this point we have total sizes for all user-defined types -10447 # compute offsets for each element -10448 # complication: fields may be out of order -10449 populate-mu-type-offsets: # in: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) -10450 # . prologue -10451 55/push-ebp -10452 89/<- %ebp 4/r32/esp -10453 # . save registers -10454 50/push-eax -10455 51/push-ecx -10456 52/push-edx -10457 53/push-ebx -10458 56/push-esi -10459 57/push-edi -10460 #? (dump-typeinfos "aaa\n") -10461 # var curr-offset/edi: int = 0 -10462 bf/copy-to-edi 0/imm32 -10463 # var table/ecx: (addr table string_key (handle typeinfo-entry)) = lookup(in->fields) -10464 8b/-> *(ebp+8) 1/r32/ecx -10465 (lookup *(ecx+4) *(ecx+8)) # Typeinfo-fields Typeinfo-fields => eax -10466 89/<- %ecx 0/r32/eax -10467 # var num-elems/edx: int = table->write / Typeinfo-fields-row-size -10468 8b/-> *ecx 2/r32/edx # stream-write -10469 c1 5/subop/shift-right-logical %edx 4/imm8 -10470 # var i/ebx: int = 0 -10471 bb/copy-to-ebx 0/imm32 -10472 { -10473 $populate-mu-type-offsets:loop: -10474 39/compare %ebx 2/r32/edx -10475 0f 8d/jump-if->= break/disp32 -10476 #? (write-buffered Stderr "looking up index ") -10477 #? (write-int32-hex-buffered Stderr %ebx) -10478 #? (write-buffered Stderr " in ") -10479 #? (write-int32-hex-buffered Stderr *(ebp+8)) -10480 #? (write-buffered Stderr Newline) -10481 #? (flush Stderr) -10482 # var v/esi: (addr typeinfo-entry) -10483 (locate-typeinfo-entry-with-index %ecx %ebx *(ebp+0xc) *(ebp+0x10)) # => eax -10484 89/<- %esi 0/r32/eax -10485 # if v is null, silently move on; we'll emit a nice error message while type-checking -10486 81 7/subop/compare %esi 0/imm32 # Typeinfo-entry-input-var -10487 74/jump-if-= $populate-mu-type-offsets:end/disp8 -10488 # if (v->input-var == 0) silently ignore v; we'll emit a nice error message while type-checking -10489 81 7/subop/compare *esi 0/imm32 # Typeinfo-entry-input-var -10490 74/jump-if-= $populate-mu-type-offsets:end/disp8 -10491 # v->output-var->offset = curr-offset -10492 # . eax: (addr var) -10493 (lookup *(esi+0xc) *(esi+0x10)) # Typeinfo-entry-output-var Typeinfo-entry-output-var => eax -10494 89/<- *(eax+0x14) 7/r32/edi # Var-offset -10495 # curr-offset += size-of(v->input-var) -10496 (lookup *esi *(esi+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax -10497 (size-of %eax) # => eax -10498 01/add-to %edi 0/r32/eax -10499 # ++i -10500 43/increment-ebx -10501 e9/jump loop/disp32 -10502 } -10503 $populate-mu-type-offsets:end: -10504 # . restore registers -10505 5f/pop-to-edi -10506 5e/pop-to-esi -10507 5b/pop-to-ebx -10508 5a/pop-to-edx -10509 59/pop-to-ecx -10510 58/pop-to-eax -10511 # . epilogue -10512 89/<- %esp 5/r32/ebp -10513 5d/pop-to-ebp -10514 c3/return -10515 -10516 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) -10517 # . prologue -10518 55/push-ebp -10519 89/<- %ebp 4/r32/esp -10520 # . save registers -10521 51/push-ecx -10522 52/push-edx -10523 53/push-ebx -10524 56/push-esi -10525 57/push-edi -10526 # esi = table -10527 8b/-> *(ebp+8) 6/r32/esi -10528 # var curr/ecx: (addr row (handle array byte) (handle typeinfo-entry)) = table->data -10529 8d/copy-address *(esi+0xc) 1/r32/ecx -10530 # var max/edx: (addr byte) = &table->data[table->write] -10531 8b/-> *esi 2/r32/edx -10532 8d/copy-address *(ecx+edx) 2/r32/edx -10533 { -10534 $locate-typeinfo-entry-with-index:loop: -10535 39/compare %ecx 2/r32/edx -10536 73/jump-if-addr>= break/disp8 -10537 # var v/eax: (addr typeinfo-entry) -10538 (lookup *(ecx+8) *(ecx+0xc)) # => eax -10539 # if (v->index == idx) return v -10540 8b/-> *(eax+8) 3/r32/ebx # Typeinfo-entry-index -10541 #? (write-buffered Stderr "comparing ") -10542 #? (write-int32-hex-buffered Stderr %ebx) -10543 #? (write-buffered Stderr " and ") -10544 #? (write-int32-hex-buffered Stderr *(ebp+0xc)) -10545 #? (write-buffered Stderr Newline) -10546 #? (flush Stderr) -10547 39/compare *(ebp+0xc) 3/r32/ebx -10548 74/jump-if-= $locate-typeinfo-entry-with-index:end/disp8 -10549 # curr += Typeinfo-entry-size -10550 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-entry-size -10551 # -10552 eb/jump loop/disp8 -10553 } -10554 # return 0 -10555 b8/copy-to-eax 0/imm32 -10556 $locate-typeinfo-entry-with-index:end: -10557 #? (write-buffered Stderr "returning ") -10558 #? (write-int32-hex-buffered Stderr %eax) -10559 #? (write-buffered Stderr Newline) -10560 #? (flush Stderr) -10561 # . restore registers -10562 5f/pop-to-edi -10563 5e/pop-to-esi -10564 5b/pop-to-ebx -10565 5a/pop-to-edx -10566 59/pop-to-ecx -10567 # . epilogue -10568 89/<- %esp 5/r32/ebp -10569 5d/pop-to-ebp -10570 c3/return -10571 -10572 dump-typeinfos: # hdr: (addr array byte) -10573 # . prologue -10574 55/push-ebp -10575 89/<- %ebp 4/r32/esp -10576 # . save registers -10577 50/push-eax -10578 # -10579 (write-buffered Stderr *(ebp+8)) -10580 (flush Stderr) -10581 # var curr/eax: (addr typeinfo) = lookup(Program->types) -10582 (lookup *_Program-types *_Program-types->payload) # => eax -10583 { -10584 # if (curr == null) break -10585 3d/compare-eax-and 0/imm32 -10586 74/jump-if-= break/disp8 -10587 (write-buffered Stderr "---\n") -10588 (flush Stderr) -10589 (dump-typeinfo %eax) -10590 # curr = lookup(curr->next) -10591 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax -10592 eb/jump loop/disp8 -10593 } -10594 $dump-typeinfos:end: -10595 # . restore registers -10596 58/pop-to-eax -10597 # . epilogue -10598 89/<- %esp 5/r32/ebp -10599 5d/pop-to-ebp -10600 c3/return -10601 -10602 dump-typeinfo: # in: (addr typeinfo) -10603 # . prologue -10604 55/push-ebp -10605 89/<- %ebp 4/r32/esp -10606 # . save registers -10607 50/push-eax -10608 51/push-ecx -10609 52/push-edx -10610 53/push-ebx -10611 56/push-esi -10612 57/push-edi -10613 # esi = in -10614 8b/-> *(ebp+8) 6/r32/esi -10615 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) -10616 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax -10617 89/<- %ecx 0/r32/eax -10618 (write-buffered Stderr "id:") -10619 (write-int32-hex-buffered Stderr *esi) -10620 (write-buffered Stderr "\n") -10621 (write-buffered Stderr "fields @ ") -10622 (write-int32-hex-buffered Stderr %ecx) -10623 (write-buffered Stderr Newline) -10624 (flush Stderr) -10625 (write-buffered Stderr " write: ") -10626 (write-int32-hex-buffered Stderr *ecx) -10627 (write-buffered Stderr Newline) -10628 (flush Stderr) -10629 (write-buffered Stderr " read: ") -10630 (write-int32-hex-buffered Stderr *(ecx+4)) -10631 (write-buffered Stderr Newline) -10632 (flush Stderr) -10633 (write-buffered Stderr " size: ") -10634 (write-int32-hex-buffered Stderr *(ecx+8)) -10635 (write-buffered Stderr Newline) -10636 (flush Stderr) -10637 # var table-size/edx: int = table->write -10638 8b/-> *ecx 2/r32/edx # stream-write -10639 # var curr/ecx: (addr table_row) = table->data -10640 8d/copy-address *(ecx+0xc) 1/r32/ecx -10641 # var max/edx: (addr table_row) = table->data + table->write -10642 8d/copy-address *(ecx+edx) 2/r32/edx -10643 { -10644 $dump-typeinfo:loop: -10645 # if (curr >= max) break -10646 39/compare %ecx 2/r32/edx -10647 0f 83/jump-if-addr>= break/disp32 -10648 (write-buffered Stderr " row:\n") -10649 (write-buffered Stderr " key: ") -10650 (write-int32-hex-buffered Stderr *ecx) -10651 (write-buffered Stderr ",") -10652 (write-int32-hex-buffered Stderr *(ecx+4)) -10653 (write-buffered Stderr " = '") -10654 (lookup *ecx *(ecx+4)) -10655 (write-buffered Stderr %eax) -10656 (write-buffered Stderr "' @ ") -10657 (write-int32-hex-buffered Stderr %eax) -10658 (write-buffered Stderr Newline) -10659 (flush Stderr) -10660 (write-buffered Stderr " value: ") -10661 (write-int32-hex-buffered Stderr *(ecx+8)) -10662 (write-buffered Stderr ",") -10663 (write-int32-hex-buffered Stderr *(ecx+0xc)) -10664 (write-buffered Stderr " = typeinfo-entry@") -10665 (lookup *(ecx+8) *(ecx+0xc)) -10666 (write-int32-hex-buffered Stderr %eax) -10667 (write-buffered Stderr Newline) -10668 (flush Stderr) -10669 (write-buffered Stderr " input var@") -10670 (dump-var 5 %eax) -10671 (lookup *(ecx+8) *(ecx+0xc)) -10672 (write-buffered Stderr " index: ") -10673 (write-int32-hex-buffered Stderr *(eax+8)) -10674 (write-buffered Stderr Newline) -10675 (flush Stderr) -10676 (write-buffered Stderr " output var@") -10677 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var -10678 (dump-var 5 %eax) -10679 (flush Stderr) -10680 # curr += row-size -10681 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size -10682 # -10683 e9/jump loop/disp32 -10684 } -10685 $dump-typeinfo:end: + 9813 # simpler version of lookup-var-helper + 9814 binding-exists?: # target: (addr var), vars: (addr stack live-var) -> result/eax: boolean + 9815 # pseudocode: + 9816 # var curr: (addr handle var) = &vars->data[vars->top - 12] + 9817 # var min = vars->data + 9818 # while curr >= min + 9819 # var v: (handle var) = *curr + 9820 # if v->name == target->name + 9821 # return true + 9822 # curr -= 12 + 9823 # return false + 9824 # + 9825 # . prologue + 9826 55/push-ebp + 9827 89/<- %ebp 4/r32/esp + 9828 # . save registers + 9829 51/push-ecx + 9830 52/push-edx + 9831 56/push-esi + 9832 # var target-name/ecx: (addr array byte) = lookup(target->name) + 9833 8b/-> *(ebp+8) 0/r32/eax + 9834 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 9835 89/<- %ecx 0/r32/eax + 9836 # esi = vars + 9837 8b/-> *(ebp+0xc) 6/r32/esi + 9838 # eax = vars->top + 9839 8b/-> *esi 0/r32/eax + 9840 # var min/edx: (addr handle var) = vars->data + 9841 8d/copy-address *(esi+8) 2/r32/edx + 9842 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] + 9843 8d/copy-address *(esi+eax-4) 6/r32/esi # vars + 8 + vars->type - 12 + 9844 { + 9845 $binding-exists?:loop: + 9846 # if (curr < min) return + 9847 39/compare %esi 2/r32/edx + 9848 0f 82/jump-if-addr< break/disp32 + 9849 # var v/eax: (addr var) = lookup(*curr) + 9850 (lookup *esi *(esi+4)) # => eax + 9851 # var vn/eax: (addr array byte) = lookup(v->name) + 9852 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 9853 # if (vn == target-name) return true + 9854 (string-equal? %ecx %eax) # => eax + 9855 3d/compare-eax-and 0/imm32/false + 9856 75/jump-if-!= $binding-exists?:end/disp8 # eax already contains true + 9857 # curr -= 12 + 9858 81 5/subop/subtract %esi 0xc/imm32 + 9859 e9/jump loop/disp32 + 9860 } + 9861 b8/copy-to-eax 0/imm32/false + 9862 $binding-exists?:end: + 9863 # . restore registers + 9864 5e/pop-to-esi + 9865 5a/pop-to-edx + 9866 59/pop-to-ecx + 9867 # . epilogue + 9868 89/<- %esp 5/r32/ebp + 9869 5d/pop-to-ebp + 9870 c3/return + 9871 + 9872 test-parse-mu-stmt: + 9873 # . prologue + 9874 55/push-ebp + 9875 89/<- %ebp 4/r32/esp + 9876 # setup + 9877 (clear-stream _test-input-stream) + 9878 (write _test-input-stream "increment n\n") + 9879 # var vars/ecx: (stack (addr var) 16) + 9880 81 5/subop/subtract %esp 0xc0/imm32 + 9881 68/push 0xc0/imm32/size + 9882 68/push 0/imm32/top + 9883 89/<- %ecx 4/r32/esp + 9884 (clear-stack %ecx) + 9885 # var v/edx: (handle var) + 9886 68/push 0/imm32 + 9887 68/push 0/imm32 + 9888 89/<- %edx 4/r32/esp + 9889 # var s/eax: (handle array byte) + 9890 68/push 0/imm32 + 9891 68/push 0/imm32 + 9892 89/<- %eax 4/r32/esp + 9893 # v = new var("n") + 9894 (copy-array Heap "n" %eax) + 9895 (new-var Heap *eax *(eax+4) %edx) + 9896 # + 9897 (push %ecx *edx) + 9898 (push %ecx *(edx+4)) + 9899 (push %ecx 0) + 9900 # var out/eax: (handle stmt) + 9901 68/push 0/imm32 + 9902 68/push 0/imm32 + 9903 89/<- %eax 4/r32/esp + 9904 # convert + 9905 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) + 9906 # var out-addr/edx: (addr stmt) = lookup(*out) + 9907 (lookup *eax *(eax+4)) # => eax + 9908 89/<- %edx 0/r32/eax + 9909 # out->tag + 9910 (check-ints-equal *edx 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 + 9911 # out->operation + 9912 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax + 9913 (check-strings-equal %eax "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation + 9914 # out->inouts->value->name + 9915 # . eax = out->inouts + 9916 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 9917 # . eax = out->inouts->value + 9918 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9919 # . eax = out->inouts->value->name + 9920 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 9921 # . + 9922 (check-strings-equal %eax "n" "F - test-parse-mu-stmt/inout:0") + 9923 # . epilogue + 9924 89/<- %esp 5/r32/ebp + 9925 5d/pop-to-ebp + 9926 c3/return + 9927 + 9928 test-parse-mu-stmt-with-comma: + 9929 # . prologue + 9930 55/push-ebp + 9931 89/<- %ebp 4/r32/esp + 9932 # setup + 9933 (clear-stream _test-input-stream) + 9934 (write _test-input-stream "copy-to n, 3\n") + 9935 # var vars/ecx: (stack (addr var) 16) + 9936 81 5/subop/subtract %esp 0xc0/imm32 + 9937 68/push 0xc0/imm32/size + 9938 68/push 0/imm32/top + 9939 89/<- %ecx 4/r32/esp + 9940 (clear-stack %ecx) + 9941 # var v/edx: (handle var) + 9942 68/push 0/imm32 + 9943 68/push 0/imm32 + 9944 89/<- %edx 4/r32/esp + 9945 # var s/eax: (handle array byte) + 9946 68/push 0/imm32 + 9947 68/push 0/imm32 + 9948 89/<- %eax 4/r32/esp + 9949 # v = new var("n") + 9950 (copy-array Heap "n" %eax) + 9951 (new-var Heap *eax *(eax+4) %edx) + 9952 # + 9953 (push %ecx *edx) + 9954 (push %ecx *(edx+4)) + 9955 (push %ecx 0) + 9956 # var out/eax: (handle stmt) + 9957 68/push 0/imm32 + 9958 68/push 0/imm32 + 9959 89/<- %eax 4/r32/esp + 9960 # convert + 9961 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) + 9962 # var out-addr/edx: (addr stmt) = lookup(*out) + 9963 (lookup *eax *(eax+4)) # => eax + 9964 89/<- %edx 0/r32/eax + 9965 # out->tag + 9966 (check-ints-equal *edx 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1 + 9967 # out->operation + 9968 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax + 9969 (check-strings-equal %eax "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation + 9970 # out->inouts->value->name + 9971 # . eax = out->inouts + 9972 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 9973 # . eax = out->inouts->value + 9974 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9975 # . eax = out->inouts->value->name + 9976 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 9977 # . + 9978 (check-strings-equal %eax "n" "F - test-parse-mu-stmt-with-comma/inout:0") + 9979 # . epilogue + 9980 89/<- %esp 5/r32/ebp + 9981 5d/pop-to-ebp + 9982 c3/return + 9983 + 9984 new-var: # ad: (addr allocation-descriptor), name: (handle array byte), out: (addr handle var) + 9985 # . prologue + 9986 55/push-ebp + 9987 89/<- %ebp 4/r32/esp + 9988 # . save registers + 9989 50/push-eax + 9990 51/push-ecx + 9991 # ecx = out + 9992 8b/-> *(ebp+0x14) 1/r32/ecx + 9993 # + 9994 (allocate *(ebp+8) *Var-size %ecx) + 9995 # var out-addr/eax: (addr var) + 9996 (lookup *ecx *(ecx+4)) # => eax + 9997 # out-addr->name = name + 9998 8b/-> *(ebp+0xc) 1/r32/ecx + 9999 89/<- *eax 1/r32/ecx # Var-name +10000 8b/-> *(ebp+0x10) 1/r32/ecx +10001 89/<- *(eax+4) 1/r32/ecx # Var-name +10002 #? (write-buffered Stderr "var ") +10003 #? (lookup *(ebp+0xc) *(ebp+0x10)) +10004 #? (write-buffered Stderr %eax) +10005 #? (write-buffered Stderr " at ") +10006 #? 8b/-> *(ebp+0x14) 1/r32/ecx +10007 #? (lookup *ecx *(ecx+4)) # => eax +10008 #? (write-int32-hex-buffered Stderr %eax) +10009 #? (write-buffered Stderr Newline) +10010 #? (flush Stderr) +10011 $new-var:end: +10012 # . restore registers +10013 59/pop-to-ecx +10014 58/pop-to-eax +10015 # . epilogue +10016 89/<- %esp 5/r32/ebp +10017 5d/pop-to-ebp +10018 c3/return +10019 +10020 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) +10021 # . prologue +10022 55/push-ebp +10023 89/<- %ebp 4/r32/esp +10024 # . save registers +10025 50/push-eax +10026 51/push-ecx +10027 # if (!is-hex-int?(name)) abort +10028 (is-hex-int? *(ebp+0xc)) # => eax +10029 3d/compare-eax-and 0/imm32/false +10030 0f 84/jump-if-= $new-literal-integer:abort/disp32 +10031 # a little more error-checking +10032 (check-mu-hex-int *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c)) +10033 # out = new var(s) +10034 (new-var-from-slice *(ebp+8) *(ebp+0xc) *(ebp+0x10)) +10035 # var out-addr/ecx: (addr var) = lookup(*out) +10036 8b/-> *(ebp+0x10) 0/r32/eax +10037 (lookup *eax *(eax+4)) # => eax +10038 89/<- %ecx 0/r32/eax +10039 # out-addr->block-depth = *Curr-block-depth +10040 8b/-> *Curr-block-depth 0/r32/eax +10041 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +10042 # out-addr->type = new tree() +10043 8d/copy-address *(ecx+8) 0/r32/eax # Var-type +10044 (allocate *(ebp+8) *Type-tree-size %eax) +10045 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +10046 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom +10047 # nothing else to do; default type is 'literal' +10048 $new-literal-integer:end: +10049 # . reclaim locals +10050 81 0/subop/add %esp 8/imm32 +10051 # . restore registers +10052 59/pop-to-ecx +10053 58/pop-to-eax +10054 # . epilogue +10055 89/<- %esp 5/r32/ebp +10056 5d/pop-to-ebp +10057 c3/return +10058 +10059 $new-literal-integer:abort: +10060 (write-buffered *(ebp+0x18) "fn ") +10061 8b/-> *(ebp+0x14) 0/r32/eax +10062 (lookup *eax *(eax+4)) # Function-name Function-name => eax +10063 (write-buffered *(ebp+0x18) %eax) +10064 (write-buffered *(ebp+0x18) ": variable '") +10065 (write-slice-buffered *(ebp+0x18) *(ebp+0xc)) +10066 (write-buffered *(ebp+0x18) "' cannot begin with a digit (or do you have a typo in a number?)\n") +10067 (flush *(ebp+0x18)) +10068 (stop *(ebp+0x1c) 1) +10069 # never gets here +10070 +10071 # precondition: name is a valid hex integer; require a '0x' prefix +10072 check-mu-hex-int: # name: (addr slice), err: (addr buffered-file), ed: (addr exit-descriptor) +10073 # . prologue +10074 55/push-ebp +10075 89/<- %ebp 4/r32/esp +10076 # . save registers +10077 50/push-eax +10078 51/push-ecx +10079 52/push-edx +10080 # +10081 8b/-> *(ebp+8) 1/r32/ecx +10082 # var start/ecx: (addr byte) = name->start +10083 8b/-> *(ecx+4) 2/r32/edx +10084 # var end/ecx: (addr byte) = name->end +10085 8b/-> *ecx 1/r32/ecx +10086 # var len/eax: int = name->end - name->start +10087 89/<- %eax 2/r32/edx +10088 29/subtract-from %eax 1/r32/ecx +10089 # if (len <= 1) return +10090 3d/compare-eax-with 1/imm32 +10091 0f 8e/jump-if-<= $check-mu-hex-int:end/disp32 +10092 $check-mu-hex-int:length->-1: +10093 # if slice-starts-with?("0x") return +10094 (slice-starts-with? *(ebp+8) "0x") # => eax +10095 3d/compare-eax-with 0/imm32/false +10096 75/jump-if-!= $check-mu-hex-int:end/disp8 +10097 $check-mu-hex-int:abort: +10098 # otherwise abort +10099 (write-buffered *(ebp+0xc) "literal integers are always hex in Mu; either start '") +10100 (write-slice-buffered *(ebp+0xc) *(ebp+8)) +10101 (write-buffered *(ebp+0xc) "' with a '0x' to be unambiguous, or convert it to decimal.\n") +10102 (flush *(ebp+0xc)) +10103 (stop *(ebp+0x10) 1) +10104 $check-mu-hex-int:end: +10105 # . restore registers +10106 5a/pop-to-edx +10107 59/pop-to-ecx +10108 58/pop-to-eax +10109 # . epilogue +10110 89/<- %esp 5/r32/ebp +10111 5d/pop-to-ebp +10112 c3/return +10113 +10114 new-literal: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) +10115 # . prologue +10116 55/push-ebp +10117 89/<- %ebp 4/r32/esp +10118 # . save registers +10119 50/push-eax +10120 51/push-ecx +10121 # var s/ecx: (handle array byte) +10122 68/push 0/imm32 +10123 68/push 0/imm32 +10124 89/<- %ecx 4/r32/esp +10125 # s = slice-to-string(name) +10126 (slice-to-string Heap *(ebp+0xc) %ecx) +10127 # allocate to out +10128 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) +10129 # var out-addr/ecx: (addr var) = lookup(*out) +10130 8b/-> *(ebp+0x10) 1/r32/ecx +10131 (lookup *ecx *(ecx+4)) # => eax +10132 89/<- %ecx 0/r32/eax +10133 # out-addr->block-depth = *Curr-block-depth +10134 8b/-> *Curr-block-depth 0/r32/eax +10135 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +10136 # out-addr->type/eax = new type +10137 8d/copy-address *(ecx+8) 0/r32/eax # Var-type +10138 (allocate *(ebp+8) *Type-tree-size %eax) +10139 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +10140 # nothing else to do; default type is 'literal' +10141 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom +10142 $new-literal:end: +10143 # . reclaim locals +10144 81 0/subop/add %esp 8/imm32 +10145 # . restore registers +10146 59/pop-to-ecx +10147 58/pop-to-eax +10148 # . epilogue +10149 89/<- %esp 5/r32/ebp +10150 5d/pop-to-ebp +10151 c3/return +10152 +10153 new-var-from-slice: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) +10154 # . prologue +10155 55/push-ebp +10156 89/<- %ebp 4/r32/esp +10157 # . save registers +10158 51/push-ecx +10159 # var tmp/ecx: (handle array byte) +10160 68/push 0/imm32 +10161 68/push 0/imm32 +10162 89/<- %ecx 4/r32/esp +10163 # tmp = slice-to-string(name) +10164 (slice-to-string Heap *(ebp+0xc) %ecx) +10165 # out = new-var(tmp) +10166 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) +10167 $new-var-from-slice:end: +10168 # . reclaim locals +10169 81 0/subop/add %esp 8/imm32 +10170 # . restore registers +10171 59/pop-to-ecx +10172 # . epilogue +10173 89/<- %esp 5/r32/ebp +10174 5d/pop-to-ebp +10175 c3/return +10176 +10177 new-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) +10178 # . prologue +10179 55/push-ebp +10180 89/<- %ebp 4/r32/esp +10181 # . save registers +10182 50/push-eax +10183 51/push-ecx +10184 # +10185 (allocate *(ebp+8) *Stmt-size *(ebp+0x14)) +10186 # var out-addr/eax: (addr stmt) = lookup(*out) +10187 8b/-> *(ebp+0x14) 0/r32/eax +10188 (lookup *eax *(eax+4)) # => eax +10189 # out-addr->tag = stmt +10190 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag +10191 # result->var = var +10192 8b/-> *(ebp+0xc) 1/r32/ecx +10193 89/<- *(eax+4) 1/r32/ecx # Vardef-var +10194 8b/-> *(ebp+0x10) 1/r32/ecx +10195 89/<- *(eax+8) 1/r32/ecx # Vardef-var +10196 $new-var-def:end: +10197 # . restore registers +10198 59/pop-to-ecx +10199 58/pop-to-eax +10200 # . epilogue +10201 89/<- %esp 5/r32/ebp +10202 5d/pop-to-ebp +10203 c3/return +10204 +10205 new-reg-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) +10206 # . prologue +10207 55/push-ebp +10208 89/<- %ebp 4/r32/esp +10209 # . save registers +10210 50/push-eax +10211 # eax = out +10212 8b/-> *(ebp+0x14) 0/r32/eax +10213 # +10214 (allocate *(ebp+8) *Stmt-size %eax) +10215 # var out-addr/eax: (addr stmt) = lookup(*out) +10216 (lookup *eax *(eax+4)) # => eax +10217 # set tag +10218 c7 0/subop/copy *eax 3/imm32/tag/var-in-register # Stmt-tag +10219 # set output +10220 8d/copy-address *(eax+0x14) 0/r32/eax # Regvardef-outputs +10221 (append-stmt-var Heap *(ebp+0xc) *(ebp+0x10) 0 0 0 %eax) +10222 $new-reg-var-def:end: +10223 # . restore registers +10224 58/pop-to-eax +10225 # . epilogue +10226 89/<- %esp 5/r32/ebp +10227 5d/pop-to-ebp +10228 c3/return +10229 +10230 append-list: # ad: (addr allocation-descriptor), value: (handle _type), list: (handle list _type), out: (addr handle list _type) +10231 # . prologue +10232 55/push-ebp +10233 89/<- %ebp 4/r32/esp +10234 # . save registers +10235 50/push-eax +10236 51/push-ecx +10237 57/push-edi +10238 # edi = out +10239 8b/-> *(ebp+0x1c) 7/r32/edi +10240 # *out = new list +10241 (allocate *(ebp+8) *List-size %edi) +10242 # var out-addr/edi: (addr list _type) = lookup(*out) +10243 (lookup *edi *(edi+4)) # => eax +10244 89/<- %edi 0/r32/eax +10245 # out-addr->value = value +10246 8b/-> *(ebp+0xc) 0/r32/eax +10247 89/<- *edi 0/r32/eax # List-value +10248 8b/-> *(ebp+0x10) 0/r32/eax +10249 89/<- *(edi+4) 0/r32/eax # List-value +10250 # if (list == null) return +10251 81 7/subop/compare *(ebp+0x14) 0/imm32 +10252 74/jump-if-= $append-list:end/disp8 +10253 # otherwise append +10254 $append-list:non-empty-list: +10255 # var curr/eax: (addr list _type) = lookup(list) +10256 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax +10257 # while (curr->next != null) curr = curr->next +10258 { +10259 81 7/subop/compare *(eax+8) 0/imm32 # List-next +10260 74/jump-if-= break/disp8 +10261 # curr = lookup(curr->next) +10262 (lookup *(eax+8) *(eax+0xc)) # List-next, List-next => eax +10263 # +10264 eb/jump loop/disp8 +10265 } +10266 # edi = out +10267 8b/-> *(ebp+0x1c) 7/r32/edi +10268 # curr->next = out +10269 8b/-> *edi 1/r32/ecx +10270 89/<- *(eax+8) 1/r32/ecx # List-next +10271 8b/-> *(edi+4) 1/r32/ecx +10272 89/<- *(eax+0xc) 1/r32/ecx # List-next +10273 # out = list +10274 8b/-> *(ebp+0x14) 1/r32/ecx +10275 89/<- *edi 1/r32/ecx +10276 8b/-> *(ebp+0x18) 1/r32/ecx +10277 89/<- *(edi+4) 1/r32/ecx +10278 $append-list:end: +10279 # . restore registers +10280 5f/pop-to-edi +10281 59/pop-to-ecx +10282 58/pop-to-eax +10283 # . epilogue +10284 89/<- %esp 5/r32/ebp +10285 5d/pop-to-ebp +10286 c3/return +10287 +10288 append-stmt-var: # ad: (addr allocation-descriptor), v: (handle var), vars: (handle stmt-var), is-deref?: boolean, out: (addr handle stmt-var) +10289 # . prologue +10290 55/push-ebp +10291 89/<- %ebp 4/r32/esp +10292 # . save registers +10293 50/push-eax +10294 51/push-ecx +10295 57/push-edi +10296 # edi = out +10297 8b/-> *(ebp+0x20) 7/r32/edi +10298 # out = new stmt-var +10299 (allocate *(ebp+8) *Stmt-var-size %edi) +10300 # var out-addr/ecx: (addr stmt-var) = lookup(*out) +10301 (lookup *edi *(edi+4)) # => eax +10302 89/<- %ecx 0/r32/eax +10303 # out-addr->value = v +10304 8b/-> *(ebp+0xc) 0/r32/eax +10305 89/<- *ecx 0/r32/eax # Stmt-var-value +10306 8b/-> *(ebp+0x10) 0/r32/eax +10307 89/<- *(ecx+4) 0/r32/eax # Stmt-var-value +10308 # out-addr->is-deref? = is-deref? +10309 8b/-> *(ebp+0x1c) 0/r32/eax +10310 89/<- *(ecx+0x10) 0/r32/eax # Stmt-var-is-deref +10311 # if (vars == null) return result +10312 81 7/subop/compare *(ebp+0x14) 0/imm32/null +10313 74/jump-if-= $append-stmt-var:end/disp8 +10314 # otherwise append +10315 # var curr/eax: (addr stmt-var) = lookup(vars) +10316 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax +10317 # while (curr->next != null) curr = curr->next +10318 { +10319 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next +10320 74/jump-if-= break/disp8 +10321 # curr = lookup(curr->next) +10322 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next, Stmt-var-next => eax +10323 # +10324 eb/jump loop/disp8 +10325 } +10326 # curr->next = out +10327 8b/-> *edi 1/r32/ecx +10328 89/<- *(eax+8) 1/r32/ecx # Stmt-var-next +10329 8b/-> *(edi+4) 1/r32/ecx +10330 89/<- *(eax+0xc) 1/r32/ecx # Stmt-var-next +10331 # out = vars +10332 8b/-> *(ebp+0x14) 1/r32/ecx +10333 89/<- *edi 1/r32/ecx +10334 8b/-> *(ebp+0x18) 1/r32/ecx +10335 89/<- *(edi+4) 1/r32/ecx +10336 $append-stmt-var:end: +10337 # . restore registers +10338 5f/pop-to-edi +10339 59/pop-to-ecx +10340 58/pop-to-eax +10341 # . epilogue +10342 89/<- %esp 5/r32/ebp +10343 5d/pop-to-ebp +10344 c3/return +10345 +10346 append-to-block: # ad: (addr allocation-descriptor), block: (addr block), x: (handle stmt) +10347 # . prologue +10348 55/push-ebp +10349 89/<- %ebp 4/r32/esp +10350 # . save registers +10351 50/push-eax +10352 56/push-esi +10353 # esi = block +10354 8b/-> *(ebp+0xc) 6/r32/esi +10355 # block->stmts = append(x, block->stmts) +10356 8d/copy-address *(esi+4) 0/r32/eax # Block-stmts +10357 (append-list *(ebp+8) *(ebp+0x10) *(ebp+0x14) *(esi+4) *(esi+8) %eax) # ad, x, x, Block-stmts, Block-stmts +10358 $append-to-block:end: +10359 # . restore registers +10360 5e/pop-to-esi +10361 58/pop-to-eax +10362 # . epilogue +10363 89/<- %esp 5/r32/ebp +10364 5d/pop-to-ebp +10365 c3/return +10366 +10367 ## Parsing types +10368 # We need to create metadata on user-defined types, and we need to use this +10369 # metadata as we parse instructions. +10370 # However, we also want to allow types to be used before their definitions. +10371 # This means we can't ever assume any type data structures exist. +10372 +10373 lookup-or-create-constant: # container: (addr stmt-var), field-name: (addr slice), out: (addr handle var) +10374 # . prologue +10375 55/push-ebp +10376 89/<- %ebp 4/r32/esp +10377 # . save registers +10378 50/push-eax +10379 56/push-esi +10380 # var container-type/esi: type-id +10381 (container-type *(ebp+8)) # => eax +10382 89/<- %esi 0/r32/eax +10383 # var tmp/eax: (handle typeinfo) = find-or-create-typeinfo(container-type) +10384 68/push 0/imm32 +10385 68/push 0/imm32 +10386 89/<- %eax 4/r32/esp +10387 (find-or-create-typeinfo %esi %eax) +10388 # var tmp-addr/eax: (addr typeinfo) = lookup(tmp) +10389 (lookup *eax *(eax+4)) # => eax +10390 # result = find-or-create-typeinfo-output-var(typeinfo, field-name) +10391 #? (write-buffered Stderr "constant: ") +10392 #? (write-slice-buffered Stderr *(ebp+0xc)) +10393 #? (write-buffered Stderr Newline) +10394 #? (flush Stderr) +10395 (find-or-create-typeinfo-output-var %eax *(ebp+0xc) *(ebp+0x10)) +10396 #? 8b/-> *(ebp+0x10) 0/r32/eax +10397 #? (write-buffered Stderr "@") +10398 #? (lookup *eax *(eax+4)) +10399 #? (write-int32-hex-buffered Stderr %eax) +10400 #? (lookup *eax *(eax+4)) +10401 #? (write-buffered Stderr %eax) +10402 #? (write-buffered Stderr Newline) +10403 #? (flush Stderr) +10404 #? (write-buffered Stderr "offset: ") +10405 #? 8b/-> *(eax+0x14) 0/r32/eax +10406 #? (write-int32-hex-buffered Stderr %eax) +10407 #? (write-buffered Stderr Newline) +10408 #? (flush Stderr) +10409 $lookup-or-create-constant:end: +10410 # . reclaim locals +10411 81 0/subop/add %esp 8/imm32 +10412 # . restore registers +10413 5e/pop-to-esi +10414 58/pop-to-eax +10415 # . epilogue +10416 89/<- %esp 5/r32/ebp +10417 5d/pop-to-ebp +10418 c3/return +10419 +10420 # if addr var: +10421 # container->var->type->right->left->value +10422 # otherwise +10423 # container->var->type->value +10424 container-type: # container: (addr stmt-var) -> result/eax: type-id +10425 # . prologue +10426 55/push-ebp +10427 89/<- %ebp 4/r32/esp +10428 # +10429 8b/-> *(ebp+8) 0/r32/eax +10430 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +10431 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +10432 { +10433 81 7/subop/compare *(eax+8) 0/imm32 # Type-tree-right +10434 74/jump-if-= break/disp8 +10435 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +10436 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +10437 } +10438 8b/-> *(eax+4) 0/r32/eax # Type-tree-value +10439 $container-type:end: +10440 # . epilogue +10441 89/<- %esp 5/r32/ebp +10442 5d/pop-to-ebp +10443 c3/return +10444 +10445 is-container?: # t: type-id -> result/eax: boolean +10446 # . prologue +10447 55/push-ebp +10448 89/<- %ebp 4/r32/esp +10449 # +10450 8b/-> *(ebp+8) 0/r32/eax +10451 c1/shift 4/subop/left %eax 2/imm8 +10452 3b/compare 0/r32/eax *Primitive-type-ids +10453 0f 9d/set-if->= %al +10454 81 4/subop/and %eax 0xff/imm32 +10455 $is-container?:end: +10456 # . epilogue +10457 89/<- %esp 5/r32/ebp +10458 5d/pop-to-ebp +10459 c3/return +10460 +10461 find-or-create-typeinfo: # t: type-id, out: (addr handle typeinfo) +10462 # . prologue +10463 55/push-ebp +10464 89/<- %ebp 4/r32/esp +10465 # . save registers +10466 50/push-eax +10467 51/push-ecx +10468 52/push-edx +10469 57/push-edi +10470 # edi = out +10471 8b/-> *(ebp+0xc) 7/r32/edi +10472 # var fields/ecx: (handle table (handle array byte) (handle typeinfo-entry)) +10473 68/push 0/imm32 +10474 68/push 0/imm32 +10475 89/<- %ecx 4/r32/esp +10476 # find-typeinfo(t, out) +10477 (find-typeinfo *(ebp+8) %edi) +10478 { +10479 # if (*out != 0) break +10480 81 7/subop/compare *edi 0/imm32 +10481 0f 85/jump-if-!= break/disp32 +10482 $find-or-create-typeinfo:create: +10483 # *out = allocate +10484 (allocate Heap *Typeinfo-size %edi) +10485 # var tmp/eax: (addr typeinfo) = lookup(*out) +10486 (lookup *edi *(edi+4)) # => eax +10487 #? (write-buffered Stderr "created typeinfo at ") +10488 #? (write-int32-hex-buffered Stderr %eax) +10489 #? (write-buffered Stderr " for type-id ") +10490 #? (write-int32-hex-buffered Stderr *(ebp+8)) +10491 #? (write-buffered Stderr Newline) +10492 #? (flush Stderr) +10493 # tmp->id = t +10494 8b/-> *(ebp+8) 2/r32/edx +10495 89/<- *eax 2/r32/edx # Typeinfo-id +10496 # tmp->fields = new table +10497 # . fields = new table +10498 (new-stream Heap 0x40 *Typeinfo-fields-row-size %ecx) +10499 # . tmp->fields = fields +10500 8b/-> *ecx 2/r32/edx +10501 89/<- *(eax+4) 2/r32/edx # Typeinfo-fields +10502 8b/-> *(ecx+4) 2/r32/edx +10503 89/<- *(eax+8) 2/r32/edx # Typeinfo-fields +10504 # tmp->next = Program->types +10505 8b/-> *_Program-types 1/r32/ecx +10506 89/<- *(eax+0x10) 1/r32/ecx # Typeinfo-next +10507 8b/-> *_Program-types->payload 1/r32/ecx +10508 89/<- *(eax+0x14) 1/r32/ecx # Typeinfo-next +10509 # Program->types = out +10510 8b/-> *edi 1/r32/ecx +10511 89/<- *_Program-types 1/r32/ecx +10512 8b/-> *(edi+4) 1/r32/ecx +10513 89/<- *_Program-types->payload 1/r32/ecx +10514 } +10515 $find-or-create-typeinfo:end: +10516 # . reclaim locals +10517 81 0/subop/add %esp 8/imm32 +10518 # . restore registers +10519 5f/pop-to-edi +10520 5a/pop-to-edx +10521 59/pop-to-ecx +10522 58/pop-to-eax +10523 # . epilogue +10524 89/<- %esp 5/r32/ebp +10525 5d/pop-to-ebp +10526 c3/return +10527 +10528 find-typeinfo: # t: type-id, out: (addr handle typeinfo) +10529 # . prologue +10530 55/push-ebp +10531 89/<- %ebp 4/r32/esp +10532 # . save registers +10533 50/push-eax +10534 51/push-ecx +10535 52/push-edx +10536 57/push-edi +10537 # ecx = t +10538 8b/-> *(ebp+8) 1/r32/ecx +10539 # edi = out +10540 8b/-> *(ebp+0xc) 7/r32/edi +10541 # *out = Program->types +10542 8b/-> *_Program-types 0/r32/eax +10543 89/<- *edi 0/r32/eax +10544 8b/-> *_Program-types->payload 0/r32/eax +10545 89/<- *(edi+4) 0/r32/eax +10546 { +10547 $find-typeinfo:loop: +10548 # if (*out == 0) break +10549 81 7/subop/compare *edi 0/imm32 +10550 74/jump-if-= break/disp8 +10551 $find-typeinfo:check: +10552 # var tmp/eax: (addr typeinfo) = lookup(*out) +10553 (lookup *edi *(edi+4)) # => eax +10554 # if (tmp->id == t) break +10555 39/compare *eax 1/r32/ecx # Typeinfo-id +10556 74/jump-if-= break/disp8 +10557 $find-typeinfo:continue: +10558 # *out = tmp->next +10559 8b/-> *(eax+0x10) 2/r32/edx # Typeinfo-next +10560 89/<- *edi 2/r32/edx +10561 8b/-> *(eax+0x14) 2/r32/edx # Typeinfo-next +10562 89/<- *(edi+4) 2/r32/edx +10563 # +10564 eb/jump loop/disp8 +10565 } +10566 $find-typeinfo:end: +10567 # . restore registers +10568 5f/pop-to-edi +10569 5a/pop-to-edx +10570 59/pop-to-ecx +10571 58/pop-to-eax +10572 # . epilogue +10573 89/<- %esp 5/r32/ebp +10574 5d/pop-to-ebp +10575 c3/return +10576 +10577 find-or-create-typeinfo-output-var: # T: (addr typeinfo), f: (addr slice), out: (addr handle var) +10578 # . prologue +10579 55/push-ebp +10580 89/<- %ebp 4/r32/esp +10581 # . save registers +10582 50/push-eax +10583 52/push-edx +10584 57/push-edi +10585 # var dest/edi: (handle typeinfo-entry) +10586 68/push 0/imm32 +10587 68/push 0/imm32 +10588 89/<- %edi 4/r32/esp +10589 # find-or-create-typeinfo-fields(T, f, dest) +10590 (find-or-create-typeinfo-fields *(ebp+8) *(ebp+0xc) %edi) +10591 # var dest-addr/edi: (addr typeinfo-entry) = lookup(dest) +10592 (lookup *edi *(edi+4)) # => eax +10593 89/<- %edi 0/r32/eax +10594 # if dest-addr->output-var doesn't exist, create it +10595 { +10596 81 7/subop/compare *(edi+0xc) 0/imm32 # Typeinfo-entry-output-var +10597 0f 85/jump-if-!= break/disp32 +10598 # dest-addr->output-var = new var(dummy name, type, -1 offset) +10599 # . var name/eax: (handle array byte) = "field" +10600 68/push 0/imm32 +10601 68/push 0/imm32 +10602 89/<- %eax 4/r32/esp +10603 (slice-to-string Heap *(ebp+0xc) %eax) +10604 # . new var +10605 8d/copy-address *(edi+0xc) 2/r32/edx +10606 (new-var Heap *eax *(eax+4) %edx) +10607 # . reclaim name +10608 81 0/subop/add %esp 8/imm32 +10609 # var result/edx: (addr var) = lookup(dest-addr->output-var) +10610 (lookup *(edi+0xc) *(edi+0x10)) # => eax +10611 89/<- %edx 0/r32/eax +10612 # result->type = new constant type +10613 8d/copy-address *(edx+8) 0/r32/eax # Var-type +10614 (allocate Heap *Type-tree-size %eax) +10615 (lookup *(edx+8) *(edx+0xc)) # => eax +10616 c7 0/subop/copy *eax 1/imm32/true # Type-tree-is-atom +10617 c7 0/subop/copy *(eax+4) 6/imm32/constant # Type-tree-value +10618 c7 0/subop/copy *(eax+8) 0/imm32 # Type-tree-left +10619 c7 0/subop/copy *(eax+0xc) 0/imm32 # Type-tree-right +10620 c7 0/subop/copy *(eax+0x10) 0/imm32 # Type-tree-right +10621 # result->offset isn't filled out yet +10622 c7 0/subop/copy *(edx+0x14) -1/imm32/uninitialized # Var-offset +10623 } +10624 # out = dest-addr->output-var +10625 8b/-> *(ebp+0x10) 2/r32/edx +10626 8b/-> *(edi+0xc) 0/r32/eax # Typeinfo-entry-output-var +10627 89/<- *edx 0/r32/eax +10628 8b/-> *(edi+0x10) 0/r32/eax # Typeinfo-entry-output-var +10629 89/<- *(edx+4) 0/r32/eax +10630 $find-or-create-typeinfo-output-var:end: +10631 # . reclaim locals +10632 81 0/subop/add %esp 8/imm32 +10633 # . restore registers +10634 5f/pop-to-edi +10635 5a/pop-to-edx +10636 58/pop-to-eax +10637 # . epilogue +10638 89/<- %esp 5/r32/ebp +10639 5d/pop-to-ebp +10640 c3/return +10641 +10642 find-or-create-typeinfo-fields: # T: (addr typeinfo), f: (addr slice), out: (addr handle typeinfo-entry) +10643 # . prologue +10644 55/push-ebp +10645 89/<- %ebp 4/r32/esp +10646 # . save registers +10647 50/push-eax +10648 56/push-esi +10649 57/push-edi +10650 # eax = lookup(T->fields) +10651 8b/-> *(ebp+8) 0/r32/eax +10652 (lookup *(eax+4) *(eax+8)) # Typeinfo-fields Typeinfo-fields => eax +10653 # edi = out +10654 8b/-> *(ebp+0x10) 7/r32/edi +10655 # var src/esi: (addr handle typeinfo-entry) = get-or-insert-slice(T->fields, f) +10656 (get-or-insert-slice %eax *(ebp+0xc) *Typeinfo-fields-row-size Heap) # => eax +10657 89/<- %esi 0/r32/eax +10658 # if src doesn't exist, allocate it +10659 { +10660 81 7/subop/compare *esi 0/imm32 +10661 75/jump-if-!= break/disp8 +10662 (allocate Heap *Typeinfo-entry-size %esi) +10663 #? (write-buffered Stderr "handle at ") +10664 #? (write-int32-hex-buffered Stderr %esi) +10665 #? (write-buffered Stderr ": ") +10666 #? (write-int32-hex-buffered Stderr *esi) +10667 #? (write-buffered Stderr " ") +10668 #? (write-int32-hex-buffered Stderr *(esi+4)) +10669 #? (write-buffered Stderr Newline) +10670 #? (flush Stderr) +10671 #? (lookup *esi *(esi+4)) +10672 #? (write-buffered Stderr "created typeinfo fields at ") +10673 #? (write-int32-hex-buffered Stderr %esi) +10674 #? (write-buffered Stderr " for ") +10675 #? (write-int32-hex-buffered Stderr *(ebp+8)) +10676 #? (write-buffered Stderr Newline) +10677 #? (flush Stderr) +10678 } +10679 # *out = src +10680 # . *edi = *src +10681 8b/-> *esi 0/r32/eax +10682 89/<- *edi 0/r32/eax +10683 8b/-> *(esi+4) 0/r32/eax +10684 89/<- *(edi+4) 0/r32/eax +10685 $find-or-create-typeinfo-fields:end: 10686 # . restore registers 10687 5f/pop-to-edi 10688 5e/pop-to-esi -10689 5b/pop-to-ebx -10690 5a/pop-to-edx -10691 59/pop-to-ecx -10692 58/pop-to-eax -10693 # . epilogue -10694 89/<- %esp 5/r32/ebp -10695 5d/pop-to-ebp -10696 c3/return -10697 -10698 dump-var: # indent: int, v: (addr handle var) -10699 # . prologue -10700 55/push-ebp -10701 89/<- %ebp 4/r32/esp -10702 # . save registers -10703 50/push-eax -10704 53/push-ebx -10705 # eax = v -10706 8b/-> *(ebp+0xc) 0/r32/eax -10707 # -10708 (write-int32-hex-buffered Stderr *eax) -10709 (write-buffered Stderr ",") -10710 (write-int32-hex-buffered Stderr *(eax+4)) -10711 (write-buffered Stderr "->") -10712 (lookup *eax *(eax+4)) -10713 (write-int32-hex-buffered Stderr %eax) -10714 (write-buffered Stderr Newline) -10715 (flush Stderr) -10716 { -10717 3d/compare-eax-and 0/imm32 -10718 0f 84/jump-if-= break/disp32 -10719 (emit-indent Stderr *(ebp+8)) -10720 (write-buffered Stderr "name: ") -10721 89/<- %ebx 0/r32/eax -10722 (write-int32-hex-buffered Stderr *ebx) # Var-name -10723 (write-buffered Stderr ",") -10724 (write-int32-hex-buffered Stderr *(ebx+4)) # Var-name -10725 (write-buffered Stderr "->") -10726 (lookup *ebx *(ebx+4)) # Var-name -10727 (write-int32-hex-buffered Stderr %eax) -10728 { -10729 3d/compare-eax-and 0/imm32 -10730 74/jump-if-= break/disp8 -10731 (write-buffered Stderr Space) -10732 (write-buffered Stderr %eax) -10733 } -10734 (write-buffered Stderr Newline) -10735 (flush Stderr) -10736 (emit-indent Stderr *(ebp+8)) -10737 (write-buffered Stderr "block depth: ") -10738 (write-int32-hex-buffered Stderr *(ebx+0x10)) # Var-block-depth -10739 (write-buffered Stderr Newline) -10740 (flush Stderr) -10741 (emit-indent Stderr *(ebp+8)) -10742 (write-buffered Stderr "stack offset: ") -10743 (write-int32-hex-buffered Stderr *(ebx+0x14)) # Var-offset -10744 (write-buffered Stderr Newline) -10745 (flush Stderr) -10746 (emit-indent Stderr *(ebp+8)) -10747 (write-buffered Stderr "reg: ") -10748 (write-int32-hex-buffered Stderr *(ebx+0x18)) # Var-register -10749 (write-buffered Stderr ",") -10750 (write-int32-hex-buffered Stderr *(ebx+0x1c)) # Var-register -10751 (write-buffered Stderr "->") -10752 (flush Stderr) -10753 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register -10754 (write-int32-hex-buffered Stderr %eax) -10755 { -10756 3d/compare-eax-and 0/imm32 -10757 74/jump-if-= break/disp8 -10758 (write-buffered Stderr Space) -10759 (write-buffered Stderr %eax) -10760 } -10761 (write-buffered Stderr Newline) -10762 (flush Stderr) -10763 } -10764 $dump-var:end: -10765 # . restore registers -10766 5b/pop-to-ebx -10767 58/pop-to-eax -10768 # . epilogue -10769 89/<- %esp 5/r32/ebp -10770 5d/pop-to-ebp -10771 c3/return -10772 -10773 ####################################################### -10774 # Type-checking -10775 ####################################################### -10776 -10777 check-mu-types: # err: (addr buffered-file), ed: (addr exit-descriptor) -10778 # . prologue -10779 55/push-ebp -10780 89/<- %ebp 4/r32/esp -10781 # . save registers -10782 50/push-eax -10783 # var curr/eax: (addr function) = lookup(Program->functions) -10784 (lookup *_Program-functions *_Program-functions->payload) # => eax -10785 { -10786 $check-mu-types:loop: -10787 # if (curr == null) break -10788 3d/compare-eax-and 0/imm32 -10789 0f 84/jump-if-= break/disp32 -10790 +-- 8 lines: #? # dump curr->name ------------------------------------------------------------------------------------------------------------------------------------------------ -10798 (check-mu-function %eax *(ebp+8) *(ebp+0xc)) -10799 # curr = lookup(curr->next) -10800 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax -10801 e9/jump loop/disp32 -10802 } -10803 $check-mu-types:end: -10804 # . restore registers -10805 58/pop-to-eax -10806 # . epilogue -10807 89/<- %esp 5/r32/ebp -10808 5d/pop-to-ebp -10809 c3/return -10810 -10811 check-mu-function: # fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -10812 # . prologue -10813 55/push-ebp -10814 89/<- %ebp 4/r32/esp -10815 # . save registers -10816 50/push-eax -10817 # eax = f -10818 8b/-> *(ebp+8) 0/r32/eax -10819 # TODO: anything to check in header? -10820 # var body/eax: (addr block) = lookup(f->body) -10821 (lookup *(eax+0x18) *(eax+0x1c)) # Function-body Function-body => eax -10822 (check-mu-block %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10)) -10823 $check-mu-function:end: -10824 # . restore registers -10825 58/pop-to-eax -10826 # . epilogue -10827 89/<- %esp 5/r32/ebp -10828 5d/pop-to-ebp -10829 c3/return -10830 -10831 check-mu-block: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -10832 # . prologue -10833 55/push-ebp -10834 89/<- %ebp 4/r32/esp -10835 # . save registers -10836 50/push-eax -10837 # eax = block -10838 8b/-> *(ebp+8) 0/r32/eax -10839 # var stmts/eax: (addr list stmt) = lookup(block->statements) -10840 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax -10841 # -10842 { -10843 $check-mu-block:check-empty: -10844 3d/compare-eax-and 0/imm32 -10845 0f 84/jump-if-= break/disp32 -10846 # emit block->statements -10847 (check-mu-stmt-list %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -10848 } -10849 $check-mu-block:end: -10850 # . restore registers -10851 58/pop-to-eax -10852 # . epilogue -10853 89/<- %esp 5/r32/ebp -10854 5d/pop-to-ebp -10855 c3/return -10856 -10857 check-mu-stmt-list: # stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -10858 # . prologue -10859 55/push-ebp -10860 89/<- %ebp 4/r32/esp -10861 # . save registers -10862 50/push-eax -10863 56/push-esi -10864 # esi = stmts -10865 8b/-> *(ebp+8) 6/r32/esi -10866 { -10867 $check-mu-stmt-list:loop: -10868 81 7/subop/compare %esi 0/imm32 -10869 0f 84/jump-if-= break/disp32 -10870 # var curr-stmt/eax: (addr stmt) = lookup(stmts->value) -10871 (lookup *esi *(esi+4)) # List-value List-value => eax -10872 { -10873 $check-mu-stmt-list:check-for-block: -10874 81 7/subop/compare *eax 0/imm32/block # Stmt-tag -10875 75/jump-if-!= break/disp8 -10876 $check-mu-stmt-list:block: -10877 (check-mu-block %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -10878 eb/jump $check-mu-stmt-list:continue/disp8 -10879 } -10880 { -10881 $check-mu-stmt-list:check-for-stmt1: -10882 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag -10883 0f 85/jump-if-!= break/disp32 -10884 $check-mu-stmt-list:stmt1: -10885 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -10886 eb/jump $check-mu-stmt-list:continue/disp8 -10887 } -10888 { -10889 $check-mu-stmt-list:check-for-reg-var-def: -10890 81 7/subop/compare *eax 3/imm32/reg-var-def # Stmt-tag -10891 0f 85/jump-if-!= break/disp32 -10892 $check-mu-stmt-list:reg-var-def: -10893 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -10894 eb/jump $check-mu-stmt-list:continue/disp8 -10895 } -10896 $check-mu-stmt-list:continue: -10897 # TODO: raise an error on unrecognized Stmt-tag -10898 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax -10899 89/<- %esi 0/r32/eax -10900 e9/jump loop/disp32 -10901 } -10902 $check-mu-stmt-list:end: -10903 # . restore registers -10904 5e/pop-to-esi -10905 58/pop-to-eax -10906 # . epilogue -10907 89/<- %esp 5/r32/ebp -10908 5d/pop-to-ebp -10909 c3/return -10910 -10911 check-mu-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -10912 # . prologue -10913 55/push-ebp -10914 89/<- %ebp 4/r32/esp -10915 # . save registers -10916 50/push-eax -10917 # - if stmt's operation matches a primitive, check against it -10918 (has-primitive-name? *(ebp+8)) # => eax -10919 3d/compare-eax-and 0/imm32/false -10920 { -10921 74/jump-if-= break/disp8 -10922 (check-mu-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -10923 e9/jump $check-mu-stmt:end/disp32 -10924 } -10925 # - otherwise find a function to check against -10926 # var f/eax: (addr function) = lookup(*Program->functions) -10927 (lookup *_Program-functions *_Program-functions->payload) # => eax -10928 (find-matching-function %eax *(ebp+8)) # => eax -10929 3d/compare-eax-and 0/imm32 -10930 { +10689 58/pop-to-eax +10690 # . epilogue +10691 89/<- %esp 5/r32/ebp +10692 5d/pop-to-ebp +10693 c3/return +10694 +10695 populate-mu-type: # in: (addr stream byte), t: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) +10696 # pseudocode: +10697 # var line: (stream byte 512) +10698 # curr-index = 0 +10699 # while true +10700 # clear-stream(line) +10701 # read-line-buffered(in, line) +10702 # if line->write == 0 +10703 # abort +10704 # word-slice = next-mu-token(line) +10705 # if slice-empty?(word-slice) # end of line +10706 # continue +10707 # if slice-equal?(word-slice, "}") +10708 # break +10709 # var v: (handle var) = parse-var-with-type(word-slice, line) +10710 # var r: (handle typeinfo-fields) = find-or-create-typeinfo-fields(t, word-slice/v->name) +10711 # TODO: ensure that r->first is null +10712 # r->index = curr-index +10713 # curr-index++ +10714 # r->input-var = v +10715 # if r->output-var == 0 +10716 # r->output-var = new literal +10717 # TODO: ensure nothing else in line +10718 # t->total-size-in-bytes = -2 (not yet initialized) +10719 # +10720 # . prologue +10721 55/push-ebp +10722 89/<- %ebp 4/r32/esp +10723 # var curr-index: int at *(ebp-4) +10724 68/push 0/imm32 +10725 # . save registers +10726 50/push-eax +10727 51/push-ecx +10728 52/push-edx +10729 53/push-ebx +10730 56/push-esi +10731 57/push-edi +10732 # edi = t +10733 8b/-> *(ebp+0xc) 7/r32/edi +10734 # var line/ecx: (stream byte 512) +10735 81 5/subop/subtract %esp 0x200/imm32 +10736 68/push 0x200/imm32/size +10737 68/push 0/imm32/read +10738 68/push 0/imm32/write +10739 89/<- %ecx 4/r32/esp +10740 # var word-slice/edx: slice +10741 68/push 0/imm32/end +10742 68/push 0/imm32/start +10743 89/<- %edx 4/r32/esp +10744 # var v/esi: (handle var) +10745 68/push 0/imm32 +10746 68/push 0/imm32 +10747 89/<- %esi 4/r32/esp +10748 # var r/ebx: (handle typeinfo-entry) +10749 68/push 0/imm32 +10750 68/push 0/imm32 +10751 89/<- %ebx 4/r32/esp +10752 { +10753 $populate-mu-type:line-loop: +10754 (clear-stream %ecx) +10755 (read-line-buffered *(ebp+8) %ecx) +10756 # if (line->write == 0) abort +10757 81 7/subop/compare *ecx 0/imm32 +10758 0f 84/jump-if-= $populate-mu-type:error1/disp32 +10759 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ +10765 (next-mu-token %ecx %edx) +10766 # if slice-empty?(word-slice) continue +10767 (slice-empty? %edx) # => eax +10768 3d/compare-eax-and 0/imm32 +10769 0f 85/jump-if-!= loop/disp32 +10770 # if slice-equal?(word-slice, "}") break +10771 (slice-equal? %edx "}") +10772 3d/compare-eax-and 0/imm32 +10773 0f 85/jump-if-!= break/disp32 +10774 $populate-mu-type:parse-element: +10775 # v = parse-var-with-type(word-slice, first-line) +10776 # must do this first to strip the trailing ':' from word-slice before +10777 # using it in find-or-create-typeinfo-fields below +10778 # TODO: clean up that mutation in parse-var-with-type +10779 (parse-var-with-type %edx %ecx %esi *(ebp+0x10) *(ebp+0x14)) +10780 # if v is an addr, abort +10781 (lookup *esi *(esi+4)) # => eax +10782 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +10783 (is-mu-addr-type? %eax) # => eax +10784 3d/compare-eax-and 0/imm32/false +10785 0f 85/jump-if-!= $populate-mu-type:error2/disp32 +10786 # if v is an array, abort (we could support it, but initialization gets complex) +10787 (lookup *esi *(esi+4)) # => eax +10788 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +10789 (is-mu-array-type? %eax) # => eax +10790 3d/compare-eax-and 0/imm32/false +10791 0f 85/jump-if-!= $populate-mu-type:error3/disp32 +10792 # var tmp/ecx +10793 51/push-ecx +10794 $populate-mu-type:create-typeinfo-fields: +10795 # var r/ebx: (handle typeinfo-entry) +10796 (find-or-create-typeinfo-fields %edi %edx %ebx) +10797 # r->index = curr-index +10798 (lookup *ebx *(ebx+4)) # => eax +10799 8b/-> *(ebp-4) 1/r32/ecx +10800 #? (write-buffered Stderr "saving index ") +10801 #? (write-int32-hex-buffered Stderr %ecx) +10802 #? (write-buffered Stderr " at ") +10803 #? (write-int32-hex-buffered Stderr %edi) +10804 #? (write-buffered Stderr Newline) +10805 #? (flush Stderr) +10806 89/<- *(eax+8) 1/r32/ecx # Typeinfo-entry-index +10807 # ++curr-index +10808 ff 0/subop/increment *(ebp-4) +10809 $populate-mu-type:set-input-type: +10810 # r->input-var = v +10811 8b/-> *esi 1/r32/ecx +10812 89/<- *eax 1/r32/ecx # Typeinfo-entry-input-var +10813 8b/-> *(esi+4) 1/r32/ecx +10814 89/<- *(eax+4) 1/r32/ecx # Typeinfo-entry-input-var +10815 # restore line +10816 59/pop-to-ecx +10817 { +10818 $populate-mu-type:create-output-type: +10819 # if (r->output-var == 0) create a new var with some placeholder data +10820 81 7/subop/compare *(eax+0xc) 0/imm32 # Typeinfo-entry-output-var +10821 75/jump-if-!= break/disp8 +10822 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var +10823 (new-literal Heap %edx %eax) +10824 } +10825 e9/jump loop/disp32 +10826 } +10827 $populate-mu-type:invalidate-total-size-in-bytes: +10828 # Offsets and total size may not be accurate here since we may not yet +10829 # have encountered the element types. +10830 # We'll recompute them separately after parsing the entire program. +10831 c7 0/subop/copy *(edi+0xc) -2/imm32/uninitialized # Typeinfo-total-size-in-bytes +10832 $populate-mu-type:end: +10833 # . reclaim locals +10834 81 0/subop/add %esp 0x224/imm32 +10835 # . restore registers +10836 5f/pop-to-edi +10837 5e/pop-to-esi +10838 5b/pop-to-ebx +10839 5a/pop-to-edx +10840 59/pop-to-ecx +10841 58/pop-to-eax +10842 # reclaim curr-index +10843 81 0/subop/add %esp 4/imm32 +10844 # . epilogue +10845 89/<- %esp 5/r32/ebp +10846 5d/pop-to-ebp +10847 c3/return +10848 +10849 $populate-mu-type:error1: +10850 # error("incomplete type definition '" t->name "'\n") +10851 (write-buffered *(ebp+0x10) "incomplete type definition '") +10852 (type-name *edi) # Typeinfo-id => eax +10853 (write-buffered *(ebp+0x10) %eax) +10854 (write-buffered *(ebp+0x10) "\n") +10855 (flush *(ebp+0x10)) +10856 (stop *(ebp+0x14) 1) +10857 # never gets here +10858 +10859 $populate-mu-type:error2: +10860 # error("type " t->name ": invalid type 'addr'\n") +10861 (write-buffered *(ebp+0x10) "type ") +10862 (type-name *edi) # Typeinfo-id => eax +10863 (write-buffered *(ebp+0x10) %eax) +10864 (write-buffered *(ebp+0x10) ": invalid type 'addr'\n") +10865 (flush *(ebp+0x10)) +10866 (stop *(ebp+0x14) 1) +10867 # never gets here +10868 +10869 $populate-mu-type:error3: +10870 # error("type " t->name ": invalid type 'array'\n") +10871 (write-buffered *(ebp+0x10) "type ") +10872 (type-name *edi) # Typeinfo-id => eax +10873 (write-buffered *(ebp+0x10) %eax) +10874 (write-buffered *(ebp+0x10) ": invalid type 'array'\n") +10875 (flush *(ebp+0x10)) +10876 (stop *(ebp+0x14) 1) +10877 # never gets here +10878 +10879 type-name: # index: int -> result/eax: (addr array byte) +10880 # . prologue +10881 55/push-ebp +10882 89/<- %ebp 4/r32/esp +10883 # +10884 (index Type-id *(ebp+8)) +10885 $type-name:end: +10886 # . epilogue +10887 89/<- %esp 5/r32/ebp +10888 5d/pop-to-ebp +10889 c3/return +10890 +10891 index: # arr: (addr stream (handle array byte)), index: int -> result/eax: (addr array byte) +10892 # . prologue +10893 55/push-ebp +10894 89/<- %ebp 4/r32/esp +10895 # . save registers +10896 56/push-esi +10897 # TODO: bounds-check index +10898 # esi = arr +10899 8b/-> *(ebp+8) 6/r32/esi +10900 # eax = index +10901 8b/-> *(ebp+0xc) 0/r32/eax +10902 # eax = *(arr + 12 + index) +10903 8b/-> *(esi+eax<<2+0xc) 0/r32/eax +10904 $index:end: +10905 # . restore registers +10906 5e/pop-to-esi +10907 # . epilogue +10908 89/<- %esp 5/r32/ebp +10909 5d/pop-to-ebp +10910 c3/return +10911 +10912 ####################################################### +10913 # Compute type sizes +10914 ####################################################### +10915 +10916 # Compute the sizes of all user-defined types. +10917 # We'll need the sizes of their elements, which may be other user-defined +10918 # types, which we will compute as needed. +10919 +10920 # Initially, all user-defined types have their sizes set to -2 (invalid) +10921 populate-mu-type-sizes: # err: (addr buffered-file), ed: (addr exit-descriptor) +10922 # . prologue +10923 55/push-ebp +10924 89/<- %ebp 4/r32/esp +10925 $populate-mu-type-sizes:total-sizes: +10926 # var curr/eax: (addr typeinfo) = lookup(Program->types) +10927 (lookup *_Program-types *_Program-types->payload) # => eax +10928 { +10929 # if (curr == null) break +10930 3d/compare-eax-and 0/imm32/null 10931 74/jump-if-= break/disp8 -10932 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -10933 eb/jump $check-mu-stmt:end/disp8 -10934 } -10935 # var f/eax: (addr function) = lookup(*Program->signatures) -10936 (lookup *_Program-signatures *_Program-signatures->payload) # => eax -10937 (find-matching-function %eax *(ebp+8)) # => eax -10938 3d/compare-eax-and 0/imm32 -10939 { -10940 74/jump-if-= break/disp8 -10941 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -10942 eb/jump $check-mu-stmt:end/disp8 -10943 } -10944 # - otherwise abort -10945 e9/jump $check-mu-stmt:unknown-call/disp32 -10946 $check-mu-stmt:end: -10947 # . restore registers -10948 58/pop-to-eax -10949 # . epilogue -10950 89/<- %esp 5/r32/ebp -10951 5d/pop-to-ebp -10952 c3/return -10953 -10954 $check-mu-stmt:unknown-call: -10955 (write-buffered *(ebp+0x10) "unknown function '") -10956 8b/-> *(ebp+8) 0/r32/eax -10957 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -10958 (write-buffered *(ebp+0x10) %eax) -10959 (write-buffered *(ebp+0x10) "'\n") -10960 (flush *(ebp+0x10)) -10961 (stop *(ebp+0x14) 1) -10962 # never gets here -10963 -10964 has-primitive-name?: # stmt: (addr stmt) -> result/eax: boolean -10965 # . prologue -10966 55/push-ebp -10967 89/<- %ebp 4/r32/esp -10968 # . save registers -10969 51/push-ecx -10970 56/push-esi -10971 # var name/esi: (addr array byte) = lookup(stmt->operation) -10972 8b/-> *(ebp+8) 6/r32/esi -10973 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax -10974 89/<- %esi 0/r32/eax -10975 # if (name == "get") return true -10976 (string-equal? %esi "get") # => eax -10977 3d/compare-eax-and 0/imm32/false -10978 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -10979 # if (name == "index") return true -10980 (string-equal? %esi "index") # => eax -10981 3d/compare-eax-and 0/imm32/false -10982 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -10983 # if (name == "length") return true -10984 (string-equal? %esi "length") # => eax -10985 3d/compare-eax-and 0/imm32/false -10986 0f 85/jump-if-!= $has-primitive-name?:end/disp32 -10987 # if (name == "compute-offset") return true -10988 (string-equal? %esi "compute-offset") # => eax -10989 3d/compare-eax-and 0/imm32/false -10990 75/jump-if-!= $has-primitive-name?:end/disp8 -10991 # if (name == "lookup") return true -10992 (string-equal? %esi "lookup") # => eax -10993 3d/compare-eax-and 0/imm32/false -10994 75/jump-if-!= $has-primitive-name?:end/disp8 -10995 # var curr/ecx: (addr primitive) = Primitives -10996 b9/copy-to-ecx Primitives/imm32 -10997 { -10998 $has-primitive-name?:loop: -10999 # if (curr == null) break -11000 81 7/subop/compare %ecx 0/imm32 -11001 74/jump-if-= break/disp8 -11002 # if (primitive->name == name) return true -11003 (lookup *ecx *(ecx+4)) # Primitive-name Primitive-name => eax -11004 (string-equal? %esi %eax) # => eax -11005 3d/compare-eax-and 0/imm32/false -11006 75/jump-if-!= $has-primitive-name?:end/disp8 -11007 $has-primitive-name?:next-primitive: -11008 # curr = curr->next -11009 (lookup *(ecx+0x34) *(ecx+0x38)) # Primitive-next Primitive-next => eax -11010 89/<- %ecx 0/r32/eax -11011 # -11012 e9/jump loop/disp32 -11013 } -11014 # return null -11015 b8/copy-to-eax 0/imm32 -11016 $has-primitive-name?:end: -11017 # . restore registers -11018 5e/pop-to-esi -11019 59/pop-to-ecx -11020 # . epilogue -11021 89/<- %esp 5/r32/ebp -11022 5d/pop-to-ebp -11023 c3/return -11024 -11025 check-mu-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11026 # . prologue -11027 55/push-ebp -11028 89/<- %ebp 4/r32/esp -11029 # . save registers -11030 50/push-eax -11031 51/push-ecx -11032 # var op/ecx: (addr array byte) = lookup(stmt->operation) -11033 8b/-> *(ebp+8) 0/r32/eax -11034 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -11035 89/<- %ecx 0/r32/eax -11036 # if (op == "copy") check-mu-copy-stmt -11037 { -11038 (string-equal? %ecx "copy") # => eax -11039 3d/compare-eax-and 0/imm32/false -11040 74/jump-if-= break/disp8 -11041 (check-mu-copy-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11042 e9/jump $check-mu-primitive:end/disp32 -11043 } -11044 # if (op == "copy-to") check-mu-copy-to-stmt -11045 { -11046 (string-equal? %ecx "copy-to") # => eax -11047 3d/compare-eax-and 0/imm32/false -11048 74/jump-if-= break/disp8 -11049 (check-mu-copy-to-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11050 e9/jump $check-mu-primitive:end/disp32 -11051 } -11052 # if (op == "compare") check-mu-compare-stmt -11053 { -11054 (string-equal? %ecx "compare") # => eax -11055 3d/compare-eax-and 0/imm32/false -11056 74/jump-if-= break/disp8 -11057 (check-mu-compare-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11058 e9/jump $check-mu-primitive:end/disp32 -11059 } -11060 # if (op == "address") check-mu-address-stmt -11061 { -11062 (string-equal? %ecx "address") # => eax -11063 3d/compare-eax-and 0/imm32/false -11064 74/jump-if-= break/disp8 -11065 (check-mu-address-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11066 e9/jump $check-mu-primitive:end/disp32 -11067 } -11068 # if (op == "get") check-mu-get-stmt -11069 { -11070 (string-equal? %ecx "get") # => eax -11071 3d/compare-eax-and 0/imm32/false -11072 74/jump-if-= break/disp8 -11073 (check-mu-get-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11074 e9/jump $check-mu-primitive:end/disp32 -11075 } -11076 # if (op == "index") check-mu-index-stmt -11077 { -11078 (string-equal? %ecx "index") # => eax -11079 3d/compare-eax-and 0/imm32/false -11080 74/jump-if-= break/disp8 -11081 (check-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11082 e9/jump $check-mu-primitive:end/disp32 -11083 } -11084 # if (op == "length") check-mu-length-stmt -11085 { -11086 (string-equal? %ecx "length") # => eax -11087 3d/compare-eax-and 0/imm32/false -11088 74/jump-if-= break/disp8 -11089 (check-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11090 e9/jump $check-mu-primitive:end/disp32 -11091 } -11092 # if (op == "compute-offset") check-mu-compute-offset-stmt -11093 { -11094 (string-equal? %ecx "compute-offset") # => eax -11095 3d/compare-eax-and 0/imm32/false -11096 74/jump-if-= break/disp8 -11097 (check-mu-compute-offset-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11098 e9/jump $check-mu-primitive:end/disp32 -11099 } -11100 # if (op == "lookup") check-mu-lookup-stmt -11101 { -11102 (string-equal? %ecx "lookup") # => eax -11103 3d/compare-eax-and 0/imm32/false -11104 74/jump-if-= break/disp8 -11105 (check-mu-lookup-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11106 e9/jump $check-mu-primitive:end/disp32 -11107 } -11108 # otherwise check-numberlike-stmt -11109 (check-mu-numberlike-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11110 $check-mu-primitive:end: -11111 # . restore registers -11112 59/pop-to-ecx -11113 58/pop-to-eax -11114 # . epilogue -11115 89/<- %esp 5/r32/ebp -11116 5d/pop-to-ebp -11117 c3/return -11118 -11119 # by default, Mu primitives should only operate on 'number-like' types -11120 check-mu-numberlike-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11121 # . prologue -11122 55/push-ebp -11123 89/<- %ebp 4/r32/esp -11124 # . save registers -11125 50/push-eax -11126 51/push-ecx -11127 56/push-esi -11128 # esi = stmt -11129 8b/-> *(ebp+8) 6/r32/esi -11130 # var gas/ecx: int = 2 -11131 b9/copy-to-ecx 2/imm32 -11132 # - check at most 1 output -11133 # var output/eax: (addr stmt-var) = stmt->outputs -11134 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -11135 { -11136 3d/compare-eax-and 0/imm32 -11137 74/jump-if-= break/disp8 -11138 $check-mu-numberlike-primitive:output: -11139 (check-mu-numberlike-output %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11140 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -11141 3d/compare-eax-and 0/imm32 -11142 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-outputs/disp32 -11143 # check output is in a register -11144 # --gas -11145 49/decrement-ecx -11146 } -11147 # - check first inout -11148 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -11149 { -11150 3d/compare-eax-and 0/imm32 -11151 0f 84/jump-if-= $check-mu-numberlike-primitive:end/disp32 -11152 $check-mu-numberlike-primitive:first-inout: -11153 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11154 # --gas -11155 49/decrement-ecx -11156 } -11157 # - check second inout -11158 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -11159 { -11160 3d/compare-eax-and 0/imm32 -11161 74/jump-if-= $check-mu-numberlike-primitive:end/disp8 -11162 $check-mu-numberlike-primitive:second-inout: -11163 # is a second inout allowed? -11164 81 7/subop/compare %ecx 0/imm32 -11165 0f 84/jump-if-= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 -11166 $check-mu-numberlike-primitive:second-inout-permitted: -11167 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -11168 } -11169 $check-mu-numberlike-primitive:third-inout: -11170 # if there's a third arg, raise an error -11171 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next -11172 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 -11173 $check-mu-numberlike-primitive:end: -11174 # . restore registers -11175 5e/pop-to-esi -11176 59/pop-to-ecx -11177 58/pop-to-eax -11178 # . epilogue -11179 89/<- %esp 5/r32/ebp -11180 5d/pop-to-ebp -11181 c3/return -11182 -11183 $check-mu-numberlike-primitive:error-too-many-inouts: -11184 (write-buffered *(ebp+0x10) "fn ") -11185 8b/-> *(ebp+0xc) 0/r32/eax -11186 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11187 (write-buffered *(ebp+0x10) %eax) -11188 (write-buffered *(ebp+0x10) ": stmt ") -11189 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax -11190 (write-buffered *(ebp+0x10) %eax) -11191 (write-buffered *(ebp+0x10) ": too many inouts; most primitives support at most two arguments, across inouts and outputs\n") -11192 (flush *(ebp+0x10)) -11193 (stop *(ebp+0x14) 1) -11194 # never gets here -11195 -11196 $check-mu-numberlike-primitive:error-too-many-outputs: -11197 (write-buffered *(ebp+0x10) "fn ") -11198 8b/-> *(ebp+0xc) 0/r32/eax -11199 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11200 (write-buffered *(ebp+0x10) %eax) -11201 (write-buffered *(ebp+0x10) ": stmt ") -11202 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax -11203 (write-buffered *(ebp+0x10) %eax) -11204 (write-buffered *(ebp+0x10) ": too many outputs; most primitives support at most one output\n") -11205 (flush *(ebp+0x10)) -11206 (stop *(ebp+0x14) 1) -11207 # never gets here -11208 -11209 check-mu-numberlike-arg: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11210 # . prologue -11211 55/push-ebp -11212 89/<- %ebp 4/r32/esp -11213 # . save registers -11214 50/push-eax -11215 56/push-esi -11216 # var t/esi: (addr type-tree) = lookup(v->value->type) -11217 8b/-> *(ebp+8) 0/r32/eax -11218 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -11219 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -11220 89/<- %esi 0/r32/eax -11221 $check-mu-numberlike-arg:check-literal: -11222 # if t is an int, return -11223 (is-simple-mu-type? %esi 0) # literal => eax -11224 3d/compare-eax-and 0/imm32/false -11225 75/jump-if-!= $check-mu-numberlike-arg:end/disp8 -11226 $check-mu-numberlike-arg:check-addr: -11227 # if t is an addr and v is dereferenced, return -11228 { -11229 (is-mu-addr-type? %esi) # => eax -11230 3d/compare-eax-and 0/imm32/false -11231 74/jump-if-= break/disp8 -11232 8b/-> *(ebp+8) 0/r32/eax -11233 8b/-> *(eax+0x10) 0/r32/eax -11234 3d/compare-eax-and 0/imm32/false -11235 75/jump-if-!= $check-mu-numberlike-arg:end/disp8 -11236 } -11237 $check-mu-numberlike-arg:output-checks: -11238 (check-mu-numberlike-output *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) -11239 $check-mu-numberlike-arg:end: -11240 # . restore registers -11241 5e/pop-to-esi -11242 58/pop-to-eax -11243 # . epilogue -11244 89/<- %esp 5/r32/ebp -11245 5d/pop-to-ebp -11246 c3/return -11247 -11248 check-mu-numberlike-output: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11249 # . prologue -11250 55/push-ebp -11251 89/<- %ebp 4/r32/esp -11252 # . save registers -11253 50/push-eax -11254 56/push-esi -11255 # var t/esi: (addr type-tree) = lookup(v->value->type) -11256 8b/-> *(ebp+8) 0/r32/eax -11257 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -11258 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -11259 89/<- %esi 0/r32/eax -11260 $check-mu-numberlike-output:check-int: -11261 # if t is an int, return -11262 (is-simple-mu-type? %esi 1) # int => eax -11263 3d/compare-eax-and 0/imm32/false -11264 75/jump-if-!= $check-mu-numberlike-output:end/disp8 -11265 $check-mu-numberlike-output:check-boolean: -11266 # if t is a boolean, return -11267 (is-simple-mu-type? %esi 5) # boolean => eax -11268 3d/compare-eax-and 0/imm32/false -11269 75/jump-if-!= $check-mu-numberlike-output:end/disp8 -11270 $check-mu-numberlike-output:check-byte: -11271 # if t is a byte, return -11272 (is-simple-mu-type? %esi 8) # byte => eax -11273 3d/compare-eax-and 0/imm32/false -11274 75/jump-if-!= $check-mu-numberlike-output:end/disp8 -11275 e9/jump $check-mu-numberlike-output:fail/disp32 -11276 $check-mu-numberlike-output:end: -11277 # . restore registers -11278 5e/pop-to-esi -11279 58/pop-to-eax -11280 # . epilogue -11281 89/<- %esp 5/r32/ebp -11282 5d/pop-to-ebp -11283 c3/return -11284 -11285 $check-mu-numberlike-output:fail: -11286 # otherwise raise an error -11287 (write-buffered *(ebp+0x14) "fn ") -11288 8b/-> *(ebp+0x10) 0/r32/eax -11289 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11290 (write-buffered *(ebp+0x14) %eax) -11291 (write-buffered *(ebp+0x14) ": stmt ") -11292 8b/-> *(ebp+0xc) 0/r32/eax -11293 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -11294 (write-buffered *(ebp+0x14) %eax) -11295 (write-buffered *(ebp+0x14) ": only non-addr scalar args permitted\n") -11296 (flush *(ebp+0x14)) -11297 (stop *(ebp+0x18) 1) -11298 # never gets here -11299 -11300 check-mu-copy-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11301 # . prologue -11302 55/push-ebp -11303 89/<- %ebp 4/r32/esp -11304 # . save registers -11305 $check-mu-copy-stmt:end: -11306 # . restore registers -11307 # . epilogue -11308 89/<- %esp 5/r32/ebp -11309 5d/pop-to-ebp -11310 c3/return -11311 -11312 check-mu-copy-to-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11313 # . prologue -11314 55/push-ebp -11315 89/<- %ebp 4/r32/esp -11316 # . save registers -11317 $check-mu-copy-to-stmt:end: -11318 # . restore registers -11319 # . epilogue -11320 89/<- %esp 5/r32/ebp -11321 5d/pop-to-ebp -11322 c3/return -11323 -11324 check-mu-compare-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11325 # . prologue -11326 55/push-ebp -11327 89/<- %ebp 4/r32/esp -11328 # . save registers -11329 $check-mu-compare-stmt:end: -11330 # . restore registers -11331 # . epilogue -11332 89/<- %esp 5/r32/ebp -11333 5d/pop-to-ebp -11334 c3/return -11335 -11336 check-mu-address-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11337 # . prologue -11338 55/push-ebp -11339 89/<- %ebp 4/r32/esp -11340 # . save registers -11341 $check-mu-address-stmt:end: -11342 # . restore registers -11343 # . epilogue -11344 89/<- %esp 5/r32/ebp -11345 5d/pop-to-ebp -11346 c3/return -11347 -11348 check-mu-get-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11349 # . prologue -11350 55/push-ebp -11351 89/<- %ebp 4/r32/esp -11352 # . save registers -11353 50/push-eax -11354 51/push-ecx -11355 52/push-edx -11356 53/push-ebx -11357 56/push-esi -11358 57/push-edi -11359 # esi = stmt -11360 8b/-> *(ebp+8) 6/r32/esi -11361 # - check for 0 inouts -11362 # var base/ecx: (addr var) = stmt->inouts->value -11363 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -11364 3d/compare-eax-and 0/imm32/false -11365 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 -11366 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -11367 89/<- %ecx 0/r32/eax -11368 $check-mu-get-stmt:check-base: -11369 # - check base type -11370 # if it's an 'addr', check that it's in a register -11371 # var base-type/ebx: (addr type-tree) = lookup(base->type) -11372 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -11373 89/<- %ebx 0/r32/eax -11374 { -11375 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom -11376 0f 85/jump-if-!= break/disp32 -11377 $check-mu-get-stmt:base-is-compound: -11378 # if (type->left != addr) break -11379 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -11380 (is-simple-mu-type? %eax 2) # => eax -11381 3d/compare-eax-and 0/imm32/false -11382 74/jump-if-= break/disp8 -11383 $check-mu-get-stmt:base-is-addr: -11384 # now check for register -11385 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -11386 0f 84/jump-if-= $check-mu-get-stmt:error-base-type-addr-but-not-register/disp32 -11387 $check-mu-get-stmt:base-is-addr-in-register: -11388 # type->left is now an addr; skip it -11389 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -11390 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right -11391 0f 85/jump-if-!= $check-mu-get-stmt:error-bad-base/disp32 -11392 $check-mu-get-stmt:base-is-addr-to-atom-in-register: -11393 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -11394 89/<- %ebx 0/r32/eax -11395 } -11396 $check-mu-get-stmt:check-base-typeinfo: -11397 # ensure type is a container -11398 # var base-type-id/ebx: type-id = base-type->value -11399 8b/-> *(ebx+4) 3/r32/ebx # Type-tree-value -11400 (is-container? %ebx) # => eax -11401 3d/compare-eax-and 0/imm32/false -11402 0f 84/jump-if-= $check-mu-get-stmt:error-bad-base/disp32 -11403 # var base-typeinfo/edx: (addr typeinfo) = find-typeinfo(base-type-id) -11404 # . var container/ecx: (handle typeinfo) -11405 68/push 0/imm32 -11406 68/push 0/imm32 -11407 89/<- %ecx 4/r32/esp -11408 # . -11409 (find-typeinfo %ebx %ecx) -11410 (lookup *ecx *(ecx+4)) # => eax -11411 # . reclaim container -11412 81 0/subop/add %esp 8/imm32 -11413 # . -11414 89/<- %edx 0/r32/eax -11415 # var offset/ecx: (addr stmt-var) = stmt->inouts->next -11416 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -11417 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -11418 89/<- %ecx 0/r32/eax -11419 # - check for 1 inout -11420 3d/compare-eax-and 0/imm32/false -11421 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 -11422 # var offset/ecx: (addr var) = lookup(offset->value) -11423 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -11424 89/<- %ecx 0/r32/eax -11425 # - check for valid field -11426 81 7/subop/compare *(ecx+0x14) -1/imm32/uninitialized # Var-offset -11427 0f 84/jump-if-= $check-mu-get-stmt:error-bad-field/disp32 -11428 # - check for too many inouts -11429 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -11430 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -11431 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -11432 3d/compare-eax-and 0/imm32/false -11433 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-inouts/disp32 -11434 # var output/edi: (addr var) = stmt->outputs->value -11435 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -11436 # - check for 0 outputs -11437 3d/compare-eax-and 0/imm32/false -11438 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-outputs/disp32 -11439 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -11440 89/<- %edi 0/r32/eax -11441 $check-mu-get-stmt:check-output-type: -11442 # - check output type -11443 # must be in register -11444 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -11445 3d/compare-eax-and 0/imm32 -11446 0f 84/jump-if-= $check-mu-get-stmt:error-output-not-in-register/disp32 -11447 # must have a non-atomic type -11448 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -11449 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -11450 0f 85/jump-if-!= $check-mu-get-stmt:error-output-type-not-address/disp32 -11451 # type must start with (addr ...) -11452 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -11453 (is-simple-mu-type? %eax 2) # => eax -11454 3d/compare-eax-and 0/imm32/false -11455 0f 84/jump-if-= $check-mu-get-stmt:error-output-type-not-address/disp32 -11456 $check-mu-get-stmt:check-output-type-match: -11457 # payload of addr type must match 'type' definition -11458 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -11459 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -11460 # if (payload->right == null) payload = payload->left -11461 81 7/subop/compare *(eax+0xc) 0/imm32/null # Type-tree-right -11462 { -11463 75/jump-if-!= break/disp8 -11464 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -11465 } -11466 89/<- %edi 0/r32/eax -11467 # . var output-name/ecx: (addr array byte) -11468 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -11469 89/<- %ecx 0/r32/eax -11470 # . var base-typeinfo-entry/eax: (addr handle typeinfo-entry) -11471 (lookup *(edx+4) *(edx+8)) # Typeinfo-fields Typeinfo-fields => eax -11472 (get %eax %ecx 0x10) # => eax -11473 # . -11474 (lookup *eax *(eax+4)) # => eax -11475 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax -11476 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -11477 # . -11478 (type-equal? %edi %eax) # => eax -11479 3d/compare-eax-and 0/imm32/false -11480 0f 84/jump-if-= $check-mu-get-stmt:error-bad-output-type/disp32 -11481 # - check for too many outputs -11482 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -11483 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -11484 3d/compare-eax-and 0/imm32/false -11485 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-outputs/disp32 -11486 $check-mu-get-stmt:end: -11487 # . restore registers -11488 5f/pop-to-edi -11489 5e/pop-to-esi -11490 5b/pop-to-ebx -11491 5a/pop-to-edx -11492 59/pop-to-ecx -11493 58/pop-to-eax -11494 # . epilogue -11495 89/<- %esp 5/r32/ebp -11496 5d/pop-to-ebp -11497 c3/return -11498 -11499 $check-mu-get-stmt:error-too-few-inouts: -11500 (write-buffered *(ebp+0x10) "fn ") -11501 8b/-> *(ebp+0xc) 0/r32/eax -11502 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11503 (write-buffered *(ebp+0x10) %eax) -11504 (write-buffered *(ebp+0x10) ": stmt get: too few inouts (2 required)\n") -11505 (flush *(ebp+0x10)) -11506 (stop *(ebp+0x14) 1) -11507 # never gets here -11508 -11509 $check-mu-get-stmt:error-too-many-inouts: -11510 (write-buffered *(ebp+0x10) "fn ") -11511 8b/-> *(ebp+0xc) 0/r32/eax -11512 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11513 (write-buffered *(ebp+0x10) %eax) -11514 (write-buffered *(ebp+0x10) ": stmt get: too many inouts (2 required)\n") -11515 (flush *(ebp+0x10)) -11516 (stop *(ebp+0x14) 1) -11517 # never gets here -11518 -11519 $check-mu-get-stmt:error-too-few-outputs: -11520 (write-buffered *(ebp+0x10) "fn ") -11521 8b/-> *(ebp+0xc) 0/r32/eax -11522 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11523 (write-buffered *(ebp+0x10) %eax) -11524 (write-buffered *(ebp+0x10) ": stmt get: must have an output\n") -11525 (flush *(ebp+0x10)) -11526 (stop *(ebp+0x14) 1) -11527 # never gets here -11528 -11529 $check-mu-get-stmt:error-too-many-outputs: -11530 (write-buffered *(ebp+0x10) "fn ") -11531 8b/-> *(ebp+0xc) 0/r32/eax -11532 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11533 (write-buffered *(ebp+0x10) %eax) -11534 (write-buffered *(ebp+0x10) ": stmt get: too many outputs (1 required)\n") -11535 (flush *(ebp+0x10)) -11536 (stop *(ebp+0x14) 1) -11537 # never gets here -11538 -11539 $check-mu-get-stmt:error-bad-base: -11540 # error("fn " fn ": stmt get: var '" base->name "' must have a 'type' definition\n") -11541 (write-buffered *(ebp+0x10) "fn ") -11542 8b/-> *(ebp+0xc) 0/r32/eax -11543 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11544 (write-buffered *(ebp+0x10) %eax) -11545 (write-buffered *(ebp+0x10) ": stmt get: var '") -11546 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -11547 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -11548 (lookup *eax *(eax+4)) # Var-name Var-name => eax -11549 (write-buffered *(ebp+0x10) %eax) -11550 (write-buffered *(ebp+0x10) "' must have a 'type' definition\n") -11551 (flush *(ebp+0x10)) -11552 (stop *(ebp+0x14) 1) -11553 # never gets here -11554 -11555 $check-mu-get-stmt:error-base-type-addr-but-not-register: -11556 (write-buffered *(ebp+0x10) "fn ") -11557 8b/-> *(ebp+0xc) 0/r32/eax -11558 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11559 (write-buffered *(ebp+0x10) %eax) -11560 (write-buffered *(ebp+0x10) ": stmt get: var '") -11561 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -11562 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -11563 (lookup *eax *(eax+4)) # Var-name Var-name => eax -11564 (write-buffered *(ebp+0x10) %eax) -11565 (write-buffered *(ebp+0x10) "' is an 'addr' type, and so must live in a register\n") -11566 (flush *(ebp+0x10)) -11567 (stop *(ebp+0x14) 1) -11568 # never gets here -11569 -11570 $check-mu-get-stmt:error-bad-field: -11571 # error("fn " fn ": stmt get: type " type " has no member called '" curr->name "'\n") -11572 (write-buffered *(ebp+0x10) "fn ") -11573 8b/-> *(ebp+0xc) 0/r32/eax -11574 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11575 (write-buffered *(ebp+0x10) %eax) -11576 (write-buffered *(ebp+0x10) ": stmt get: type '") -11577 # . write(Type-id->data[tmp]) -11578 bf/copy-to-edi Type-id/imm32 -11579 (write-buffered *(ebp+0x10) *(edi+ebx<<2+0xc)) -11580 # . -11581 (write-buffered *(ebp+0x10) "' has no member called '") -11582 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -11583 (write-buffered *(ebp+0x10) %eax) -11584 (write-buffered *(ebp+0x10) "'\n") -11585 (flush *(ebp+0x10)) -11586 (stop *(ebp+0x14) 1) -11587 # never gets here -11588 -11589 $check-mu-get-stmt:error-output-not-in-register: -11590 (write-buffered *(ebp+0x10) "fn ") -11591 8b/-> *(ebp+0xc) 0/r32/eax -11592 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11593 (write-buffered *(ebp+0x10) %eax) -11594 (write-buffered *(ebp+0x10) ": stmt get: output '") -11595 (lookup *edi *(edi+4)) # Var-name Var-name => eax -11596 (write-buffered *(ebp+0x10) %eax) -11597 (write-buffered *(ebp+0x10) "' is not in a register\n") -11598 (flush *(ebp+0x10)) -11599 (stop *(ebp+0x14) 1) -11600 # never gets here -11601 -11602 $check-mu-get-stmt:error-output-type-not-address: -11603 (write-buffered *(ebp+0x10) "fn ") -11604 8b/-> *(ebp+0xc) 0/r32/eax -11605 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11606 (write-buffered *(ebp+0x10) %eax) -11607 (write-buffered *(ebp+0x10) ": stmt get: output must be an address\n") -11608 (flush *(ebp+0x10)) -11609 (stop *(ebp+0x14) 1) -11610 # never gets here -11611 -11612 $check-mu-get-stmt:error-bad-output-type: -11613 (write-buffered *(ebp+0x10) "fn ") -11614 8b/-> *(ebp+0xc) 0/r32/eax -11615 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11616 (write-buffered *(ebp+0x10) %eax) -11617 (write-buffered *(ebp+0x10) ": stmt get: wrong output type for member '") -11618 (write-buffered *(ebp+0x10) %ecx) -11619 (write-buffered *(ebp+0x10) "' of type '") -11620 bf/copy-to-edi Type-id/imm32 -11621 (write-buffered *(ebp+0x10) *(edi+ebx<<2+0xc)) -11622 (write-buffered *(ebp+0x10) "'\n") -11623 (flush *(ebp+0x10)) -11624 (stop *(ebp+0x14) 1) -11625 # never gets here -11626 -11627 check-mu-index-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11628 # . prologue -11629 55/push-ebp -11630 89/<- %ebp 4/r32/esp -11631 # . save registers -11632 $check-mu-index-stmt:end: -11633 # . restore registers -11634 # . epilogue -11635 89/<- %esp 5/r32/ebp -11636 5d/pop-to-ebp -11637 c3/return -11638 -11639 check-mu-length-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11640 # . prologue -11641 55/push-ebp -11642 89/<- %ebp 4/r32/esp -11643 # . save registers -11644 $check-mu-length-stmt:end: -11645 # . restore registers -11646 # . epilogue -11647 89/<- %esp 5/r32/ebp -11648 5d/pop-to-ebp -11649 c3/return -11650 -11651 check-mu-compute-offset-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11652 # . prologue -11653 55/push-ebp -11654 89/<- %ebp 4/r32/esp -11655 # . save registers -11656 $check-mu-compute-offset-stmt:end: -11657 # . restore registers -11658 # . epilogue -11659 89/<- %esp 5/r32/ebp -11660 5d/pop-to-ebp -11661 c3/return -11662 -11663 check-mu-lookup-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11664 # . prologue -11665 55/push-ebp -11666 89/<- %ebp 4/r32/esp -11667 # . save registers -11668 $check-mu-lookup-stmt:end: -11669 # . restore registers -11670 # . epilogue -11671 89/<- %esp 5/r32/ebp -11672 5d/pop-to-ebp -11673 c3/return -11674 -11675 check-mu-call: # stmt: (addr stmt), callee: (addr function), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -11676 # . prologue -11677 55/push-ebp -11678 89/<- %ebp 4/r32/esp -11679 # . save registers -11680 50/push-eax -11681 51/push-ecx -11682 52/push-edx -11683 53/push-ebx -11684 56/push-esi -11685 57/push-edi -11686 # esi = stmt -11687 8b/-> *(ebp+8) 6/r32/esi -11688 # edi = callee -11689 8b/-> *(ebp+0xc) 7/r32/edi -11690 # var inouts/ecx: (addr stmt-var) = lookup(stmt->inouts) -11691 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -11692 89/<- %ecx 0/r32/eax -11693 # var expected/edx: (addr list var) = lookup(f->inouts) -11694 (lookup *(edi+8) *(edi+0xc)) # Function-inouts Function-inouts => eax -11695 89/<- %edx 0/r32/eax -11696 { -11697 $check-mu-call:check-for-inouts: -11698 # if (inouts == 0) break -11699 81 7/subop/compare %ecx 0/imm32 -11700 0f 84/jump-if-= break/disp32 -11701 # if (expected == 0) error -11702 81 7/subop/compare %edx 0/imm32 -11703 0f 84/jump-if-= break/disp32 -11704 $check-mu-call:check-inout-type: -11705 # var v/eax: (addr v) = lookup(inouts->value) -11706 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -11707 # var t/ebx: (addr type-tree) = lookup(v->type) -11708 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -11709 89/<- %ebx 0/r32/eax -11710 # if (inouts->is-deref?) t = t->right # TODO: check that t->left is an addr -11711 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -11712 { -11713 74/jump-if-= break/disp8 -11714 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -11715 89/<- %ebx 0/r32/eax -11716 # if t->right is null, t = t->left -11717 81 7/subop/compare *(ebx+0xc) 0/imm32 # Type-tree-right -11718 75/jump-if-!= break/disp8 -11719 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax -11720 89/<- %ebx 0/r32/eax -11721 } -11722 # var v2/eax: (addr v) = lookup(expected->value) -11723 (lookup *edx *(edx+4)) # List-value List-value => eax -11724 # var t2/eax: (addr type-tree) = lookup(v2->type) -11725 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -11726 # if (t != t2) error -11727 (type-match? %eax %ebx) # => eax +10932 (populate-mu-type-sizes-in-type %eax *(ebp+8) *(ebp+0xc)) +10933 # curr = lookup(curr->next) +10934 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax +10935 eb/jump loop/disp8 +10936 } +10937 $populate-mu-type-sizes:offsets: +10938 # curr = *Program->types +10939 (lookup *_Program-types *_Program-types->payload) # => eax +10940 { +10941 # if (curr == null) break +10942 3d/compare-eax-and 0/imm32/null +10943 74/jump-if-= break/disp8 +10944 (populate-mu-type-offsets %eax *(ebp+8) *(ebp+0xc)) +10945 # curr = curr->next +10946 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax +10947 eb/jump loop/disp8 +10948 } +10949 $populate-mu-type-sizes:end: +10950 # . epilogue +10951 89/<- %esp 5/r32/ebp +10952 5d/pop-to-ebp +10953 c3/return +10954 +10955 # compute sizes of all fields, recursing as necessary +10956 # sum up all their sizes to arrive at total size +10957 # fields may be out of order, but that doesn't affect the answer +10958 populate-mu-type-sizes-in-type: # T: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) +10959 # . prologue +10960 55/push-ebp +10961 89/<- %ebp 4/r32/esp +10962 # . save registers +10963 50/push-eax +10964 51/push-ecx +10965 52/push-edx +10966 56/push-esi +10967 57/push-edi +10968 # esi = T +10969 8b/-> *(ebp+8) 6/r32/esi +10970 # if T is already computed, return +10971 81 7/subop/compare *(esi+0xc) 0/imm32 # Typeinfo-total-size-in-bytes +10972 0f 8d/jump-if->= $populate-mu-type-sizes-in-type:end/disp32 +10973 # if T is being computed, abort +10974 81 7/subop/compare *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes +10975 0f 84/jump-if-= $populate-mu-type-sizes-in-type:abort/disp32 +10976 # tag T (-2 to -1) to avoid infinite recursion +10977 c7 0/subop/copy *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes +10978 # var total-size/edi: int = 0 +10979 bf/copy-to-edi 0/imm32 +10980 # - for every field, if it's a user-defined type, compute its size +10981 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) +10982 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax +10983 89/<- %ecx 0/r32/eax +10984 # var table-size/edx: int = table->write +10985 8b/-> *ecx 2/r32/edx # stream-write +10986 # var curr/ecx: (addr table_row) = table->data +10987 8d/copy-address *(ecx+0xc) 1/r32/ecx +10988 # var max/edx: (addr table_row) = table->data + table->write +10989 8d/copy-address *(ecx+edx) 2/r32/edx +10990 { +10991 $populate-mu-type-sizes-in-type:loop: +10992 # if (curr >= max) break +10993 39/compare %ecx 2/r32/edx +10994 73/jump-if-addr>= break/disp8 +10995 # var t/eax: (addr typeinfo-entry) = lookup(curr->value) +10996 (lookup *(ecx+8) *(ecx+0xc)) # => eax +10997 # if (t->input-var == 0) silently ignore it; we'll emit a nice error message while type-checking +10998 81 7/subop/compare *eax 0/imm32 # Typeinfo-entry-input-var +10999 74/jump-if-= $populate-mu-type-sizes-in-type:end/disp8 +11000 # compute size of t->input-var +11001 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax +11002 (compute-size-of-var %eax) # => eax +11003 # result += eax +11004 01/add-to %edi 0/r32/eax +11005 # curr += row-size +11006 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size +11007 # +11008 eb/jump loop/disp8 +11009 } +11010 # - save result +11011 89/<- *(esi+0xc) 7/r32/edi # Typeinfo-total-size-in-bytes +11012 $populate-mu-type-sizes-in-type:end: +11013 # . restore registers +11014 5f/pop-to-edi +11015 5e/pop-to-esi +11016 5a/pop-to-edx +11017 59/pop-to-ecx +11018 58/pop-to-eax +11019 # . epilogue +11020 89/<- %esp 5/r32/ebp +11021 5d/pop-to-ebp +11022 c3/return +11023 +11024 $populate-mu-type-sizes-in-type:abort: +11025 (write-buffered *(ebp+0xc) "cycle in type definitions\n") +11026 (flush *(ebp+0xc)) +11027 (stop *(ebp+0x10) 1) +11028 # never gets here +11029 +11030 # Analogous to size-of, except we need to compute what size-of can just read +11031 # off the right data structures. +11032 compute-size-of-var: # in: (addr var) -> result/eax: int +11033 # . prologue +11034 55/push-ebp +11035 89/<- %ebp 4/r32/esp +11036 # . push registers +11037 51/push-ecx +11038 # var t/ecx: (addr type-tree) = lookup(v->type) +11039 8b/-> *(ebp+8) 1/r32/ecx +11040 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +11041 89/<- %ecx 0/r32/eax +11042 # if (t->is-atom == false) t = lookup(t->left) +11043 { +11044 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +11045 75/jump-if-!= break/disp8 +11046 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +11047 89/<- %ecx 0/r32/eax +11048 } +11049 # TODO: ensure t is an atom +11050 (compute-size-of-type-id *(ecx+4)) # Type-tree-value => eax +11051 $compute-size-of-var:end: +11052 # . restore registers +11053 59/pop-to-ecx +11054 # . epilogue +11055 89/<- %esp 5/r32/ebp +11056 5d/pop-to-ebp +11057 c3/return +11058 +11059 compute-size-of-type-id: # t: type-id -> result/eax: int +11060 # . prologue +11061 55/push-ebp +11062 89/<- %ebp 4/r32/esp +11063 # . save registers +11064 51/push-ecx +11065 # var out/ecx: (handle typeinfo) +11066 68/push 0/imm32 +11067 68/push 0/imm32 +11068 89/<- %ecx 4/r32/esp +11069 # eax = t +11070 8b/-> *(ebp+8) 0/r32/eax +11071 # if t is a literal, return 0 +11072 3d/compare-eax-and 0/imm32/literal +11073 0f 84/jump-if-= $compute-size-of-type-id:end/disp32 # eax changes type from type-id to int +11074 # if t is a byte, return 4 (because we don't really support non-multiples of 4) +11075 3d/compare-eax-and 8/imm32/byte +11076 { +11077 75/jump-if-!= break/disp8 +11078 b8/copy-to-eax 4/imm32 +11079 eb/jump $compute-size-of-type-id:end/disp8 +11080 } +11081 # if t is a handle, return 8 +11082 3d/compare-eax-and 4/imm32/handle +11083 { +11084 75/jump-if-!= break/disp8 +11085 b8/copy-to-eax 8/imm32 +11086 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int +11087 } +11088 # if t is a user-defined type, compute its size +11089 # TODO: support non-atom type +11090 (find-typeinfo %eax %ecx) +11091 { +11092 81 7/subop/compare *ecx 0/imm32 +11093 74/jump-if-= break/disp8 +11094 $compute-size-of-type-id:user-defined: +11095 (populate-mu-type-sizes %eax) +11096 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes +11097 eb/jump $compute-size-of-type-id:end/disp8 +11098 } +11099 # otherwise return the word size +11100 b8/copy-to-eax 4/imm32 +11101 $compute-size-of-type-id:end: +11102 # . reclaim locals +11103 81 0/subop/add %esp 8/imm32 +11104 # . restore registers +11105 59/pop-to-ecx +11106 # . epilogue +11107 89/<- %esp 5/r32/ebp +11108 5d/pop-to-ebp +11109 c3/return +11110 +11111 # at this point we have total sizes for all user-defined types +11112 # compute offsets for each element +11113 # complication: fields may be out of order +11114 populate-mu-type-offsets: # in: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) +11115 # . prologue +11116 55/push-ebp +11117 89/<- %ebp 4/r32/esp +11118 # . save registers +11119 50/push-eax +11120 51/push-ecx +11121 52/push-edx +11122 53/push-ebx +11123 56/push-esi +11124 57/push-edi +11125 #? (dump-typeinfos "aaa\n") +11126 # var curr-offset/edi: int = 0 +11127 bf/copy-to-edi 0/imm32 +11128 # var table/ecx: (addr table string_key (handle typeinfo-entry)) = lookup(in->fields) +11129 8b/-> *(ebp+8) 1/r32/ecx +11130 (lookup *(ecx+4) *(ecx+8)) # Typeinfo-fields Typeinfo-fields => eax +11131 89/<- %ecx 0/r32/eax +11132 # var num-elems/edx: int = table->write / Typeinfo-fields-row-size +11133 8b/-> *ecx 2/r32/edx # stream-write +11134 c1 5/subop/shift-right-logical %edx 4/imm8 +11135 # var i/ebx: int = 0 +11136 bb/copy-to-ebx 0/imm32 +11137 { +11138 $populate-mu-type-offsets:loop: +11139 39/compare %ebx 2/r32/edx +11140 0f 8d/jump-if->= break/disp32 +11141 #? (write-buffered Stderr "looking up index ") +11142 #? (write-int32-hex-buffered Stderr %ebx) +11143 #? (write-buffered Stderr " in ") +11144 #? (write-int32-hex-buffered Stderr *(ebp+8)) +11145 #? (write-buffered Stderr Newline) +11146 #? (flush Stderr) +11147 # var v/esi: (addr typeinfo-entry) +11148 (locate-typeinfo-entry-with-index %ecx %ebx *(ebp+0xc) *(ebp+0x10)) # => eax +11149 89/<- %esi 0/r32/eax +11150 # if v is null, silently move on; we'll emit a nice error message while type-checking +11151 81 7/subop/compare %esi 0/imm32 # Typeinfo-entry-input-var +11152 74/jump-if-= $populate-mu-type-offsets:end/disp8 +11153 # if (v->input-var == 0) silently ignore v; we'll emit a nice error message while type-checking +11154 81 7/subop/compare *esi 0/imm32 # Typeinfo-entry-input-var +11155 74/jump-if-= $populate-mu-type-offsets:end/disp8 +11156 # v->output-var->offset = curr-offset +11157 # . eax: (addr var) +11158 (lookup *(esi+0xc) *(esi+0x10)) # Typeinfo-entry-output-var Typeinfo-entry-output-var => eax +11159 89/<- *(eax+0x14) 7/r32/edi # Var-offset +11160 # curr-offset += size-of(v->input-var) +11161 (lookup *esi *(esi+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax +11162 (size-of %eax) # => eax +11163 01/add-to %edi 0/r32/eax +11164 # ++i +11165 43/increment-ebx +11166 e9/jump loop/disp32 +11167 } +11168 $populate-mu-type-offsets:end: +11169 # . restore registers +11170 5f/pop-to-edi +11171 5e/pop-to-esi +11172 5b/pop-to-ebx +11173 5a/pop-to-edx +11174 59/pop-to-ecx +11175 58/pop-to-eax +11176 # . epilogue +11177 89/<- %esp 5/r32/ebp +11178 5d/pop-to-ebp +11179 c3/return +11180 +11181 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) +11182 # . prologue +11183 55/push-ebp +11184 89/<- %ebp 4/r32/esp +11185 # . save registers +11186 51/push-ecx +11187 52/push-edx +11188 53/push-ebx +11189 56/push-esi +11190 57/push-edi +11191 # esi = table +11192 8b/-> *(ebp+8) 6/r32/esi +11193 # var curr/ecx: (addr row (handle array byte) (handle typeinfo-entry)) = table->data +11194 8d/copy-address *(esi+0xc) 1/r32/ecx +11195 # var max/edx: (addr byte) = &table->data[table->write] +11196 8b/-> *esi 2/r32/edx +11197 8d/copy-address *(ecx+edx) 2/r32/edx +11198 { +11199 $locate-typeinfo-entry-with-index:loop: +11200 39/compare %ecx 2/r32/edx +11201 73/jump-if-addr>= break/disp8 +11202 # var v/eax: (addr typeinfo-entry) +11203 (lookup *(ecx+8) *(ecx+0xc)) # => eax +11204 # if (v->index == idx) return v +11205 8b/-> *(eax+8) 3/r32/ebx # Typeinfo-entry-index +11206 #? (write-buffered Stderr "comparing ") +11207 #? (write-int32-hex-buffered Stderr %ebx) +11208 #? (write-buffered Stderr " and ") +11209 #? (write-int32-hex-buffered Stderr *(ebp+0xc)) +11210 #? (write-buffered Stderr Newline) +11211 #? (flush Stderr) +11212 39/compare *(ebp+0xc) 3/r32/ebx +11213 74/jump-if-= $locate-typeinfo-entry-with-index:end/disp8 +11214 # curr += Typeinfo-entry-size +11215 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-entry-size +11216 # +11217 eb/jump loop/disp8 +11218 } +11219 # return 0 +11220 b8/copy-to-eax 0/imm32 +11221 $locate-typeinfo-entry-with-index:end: +11222 #? (write-buffered Stderr "returning ") +11223 #? (write-int32-hex-buffered Stderr %eax) +11224 #? (write-buffered Stderr Newline) +11225 #? (flush Stderr) +11226 # . restore registers +11227 5f/pop-to-edi +11228 5e/pop-to-esi +11229 5b/pop-to-ebx +11230 5a/pop-to-edx +11231 59/pop-to-ecx +11232 # . epilogue +11233 89/<- %esp 5/r32/ebp +11234 5d/pop-to-ebp +11235 c3/return +11236 +11237 dump-typeinfos: # hdr: (addr array byte) +11238 # . prologue +11239 55/push-ebp +11240 89/<- %ebp 4/r32/esp +11241 # . save registers +11242 50/push-eax +11243 # +11244 (write-buffered Stderr *(ebp+8)) +11245 (flush Stderr) +11246 # var curr/eax: (addr typeinfo) = lookup(Program->types) +11247 (lookup *_Program-types *_Program-types->payload) # => eax +11248 { +11249 # if (curr == null) break +11250 3d/compare-eax-and 0/imm32 +11251 74/jump-if-= break/disp8 +11252 (write-buffered Stderr "---\n") +11253 (flush Stderr) +11254 (dump-typeinfo %eax) +11255 # curr = lookup(curr->next) +11256 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax +11257 eb/jump loop/disp8 +11258 } +11259 $dump-typeinfos:end: +11260 # . restore registers +11261 58/pop-to-eax +11262 # . epilogue +11263 89/<- %esp 5/r32/ebp +11264 5d/pop-to-ebp +11265 c3/return +11266 +11267 dump-typeinfo: # in: (addr typeinfo) +11268 # . prologue +11269 55/push-ebp +11270 89/<- %ebp 4/r32/esp +11271 # . save registers +11272 50/push-eax +11273 51/push-ecx +11274 52/push-edx +11275 53/push-ebx +11276 56/push-esi +11277 57/push-edi +11278 # esi = in +11279 8b/-> *(ebp+8) 6/r32/esi +11280 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) +11281 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax +11282 89/<- %ecx 0/r32/eax +11283 (write-buffered Stderr "id:") +11284 (write-int32-hex-buffered Stderr *esi) +11285 (write-buffered Stderr "\n") +11286 (write-buffered Stderr "fields @ ") +11287 (write-int32-hex-buffered Stderr %ecx) +11288 (write-buffered Stderr Newline) +11289 (flush Stderr) +11290 (write-buffered Stderr " write: ") +11291 (write-int32-hex-buffered Stderr *ecx) +11292 (write-buffered Stderr Newline) +11293 (flush Stderr) +11294 (write-buffered Stderr " read: ") +11295 (write-int32-hex-buffered Stderr *(ecx+4)) +11296 (write-buffered Stderr Newline) +11297 (flush Stderr) +11298 (write-buffered Stderr " size: ") +11299 (write-int32-hex-buffered Stderr *(ecx+8)) +11300 (write-buffered Stderr Newline) +11301 (flush Stderr) +11302 # var table-size/edx: int = table->write +11303 8b/-> *ecx 2/r32/edx # stream-write +11304 # var curr/ecx: (addr table_row) = table->data +11305 8d/copy-address *(ecx+0xc) 1/r32/ecx +11306 # var max/edx: (addr table_row) = table->data + table->write +11307 8d/copy-address *(ecx+edx) 2/r32/edx +11308 { +11309 $dump-typeinfo:loop: +11310 # if (curr >= max) break +11311 39/compare %ecx 2/r32/edx +11312 0f 83/jump-if-addr>= break/disp32 +11313 (write-buffered Stderr " row:\n") +11314 (write-buffered Stderr " key: ") +11315 (write-int32-hex-buffered Stderr *ecx) +11316 (write-buffered Stderr ",") +11317 (write-int32-hex-buffered Stderr *(ecx+4)) +11318 (write-buffered Stderr " = '") +11319 (lookup *ecx *(ecx+4)) +11320 (write-buffered Stderr %eax) +11321 (write-buffered Stderr "' @ ") +11322 (write-int32-hex-buffered Stderr %eax) +11323 (write-buffered Stderr Newline) +11324 (flush Stderr) +11325 (write-buffered Stderr " value: ") +11326 (write-int32-hex-buffered Stderr *(ecx+8)) +11327 (write-buffered Stderr ",") +11328 (write-int32-hex-buffered Stderr *(ecx+0xc)) +11329 (write-buffered Stderr " = typeinfo-entry@") +11330 (lookup *(ecx+8) *(ecx+0xc)) +11331 (write-int32-hex-buffered Stderr %eax) +11332 (write-buffered Stderr Newline) +11333 (flush Stderr) +11334 (write-buffered Stderr " input var@") +11335 (dump-var 5 %eax) +11336 (lookup *(ecx+8) *(ecx+0xc)) +11337 (write-buffered Stderr " index: ") +11338 (write-int32-hex-buffered Stderr *(eax+8)) +11339 (write-buffered Stderr Newline) +11340 (flush Stderr) +11341 (write-buffered Stderr " output var@") +11342 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var +11343 (dump-var 5 %eax) +11344 (flush Stderr) +11345 # curr += row-size +11346 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size +11347 # +11348 e9/jump loop/disp32 +11349 } +11350 $dump-typeinfo:end: +11351 # . restore registers +11352 5f/pop-to-edi +11353 5e/pop-to-esi +11354 5b/pop-to-ebx +11355 5a/pop-to-edx +11356 59/pop-to-ecx +11357 58/pop-to-eax +11358 # . epilogue +11359 89/<- %esp 5/r32/ebp +11360 5d/pop-to-ebp +11361 c3/return +11362 +11363 dump-var: # indent: int, v: (addr handle var) +11364 # . prologue +11365 55/push-ebp +11366 89/<- %ebp 4/r32/esp +11367 # . save registers +11368 50/push-eax +11369 53/push-ebx +11370 # eax = v +11371 8b/-> *(ebp+0xc) 0/r32/eax +11372 # +11373 (write-int32-hex-buffered Stderr *eax) +11374 (write-buffered Stderr ",") +11375 (write-int32-hex-buffered Stderr *(eax+4)) +11376 (write-buffered Stderr "->") +11377 (lookup *eax *(eax+4)) +11378 (write-int32-hex-buffered Stderr %eax) +11379 (write-buffered Stderr Newline) +11380 (flush Stderr) +11381 { +11382 3d/compare-eax-and 0/imm32 +11383 0f 84/jump-if-= break/disp32 +11384 (emit-indent Stderr *(ebp+8)) +11385 (write-buffered Stderr "name: ") +11386 89/<- %ebx 0/r32/eax +11387 (write-int32-hex-buffered Stderr *ebx) # Var-name +11388 (write-buffered Stderr ",") +11389 (write-int32-hex-buffered Stderr *(ebx+4)) # Var-name +11390 (write-buffered Stderr "->") +11391 (lookup *ebx *(ebx+4)) # Var-name +11392 (write-int32-hex-buffered Stderr %eax) +11393 { +11394 3d/compare-eax-and 0/imm32 +11395 74/jump-if-= break/disp8 +11396 (write-buffered Stderr Space) +11397 (write-buffered Stderr %eax) +11398 } +11399 (write-buffered Stderr Newline) +11400 (flush Stderr) +11401 (emit-indent Stderr *(ebp+8)) +11402 (write-buffered Stderr "block depth: ") +11403 (write-int32-hex-buffered Stderr *(ebx+0x10)) # Var-block-depth +11404 (write-buffered Stderr Newline) +11405 (flush Stderr) +11406 (emit-indent Stderr *(ebp+8)) +11407 (write-buffered Stderr "stack offset: ") +11408 (write-int32-hex-buffered Stderr *(ebx+0x14)) # Var-offset +11409 (write-buffered Stderr Newline) +11410 (flush Stderr) +11411 (emit-indent Stderr *(ebp+8)) +11412 (write-buffered Stderr "reg: ") +11413 (write-int32-hex-buffered Stderr *(ebx+0x18)) # Var-register +11414 (write-buffered Stderr ",") +11415 (write-int32-hex-buffered Stderr *(ebx+0x1c)) # Var-register +11416 (write-buffered Stderr "->") +11417 (flush Stderr) +11418 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register +11419 (write-int32-hex-buffered Stderr %eax) +11420 { +11421 3d/compare-eax-and 0/imm32 +11422 74/jump-if-= break/disp8 +11423 (write-buffered Stderr Space) +11424 (write-buffered Stderr %eax) +11425 } +11426 (write-buffered Stderr Newline) +11427 (flush Stderr) +11428 } +11429 $dump-var:end: +11430 # . restore registers +11431 5b/pop-to-ebx +11432 58/pop-to-eax +11433 # . epilogue +11434 89/<- %esp 5/r32/ebp +11435 5d/pop-to-ebp +11436 c3/return +11437 +11438 ####################################################### +11439 # Type-checking +11440 ####################################################### +11441 +11442 check-mu-types: # err: (addr buffered-file), ed: (addr exit-descriptor) +11443 # . prologue +11444 55/push-ebp +11445 89/<- %ebp 4/r32/esp +11446 # . save registers +11447 50/push-eax +11448 # var curr/eax: (addr function) = lookup(Program->functions) +11449 (lookup *_Program-functions *_Program-functions->payload) # => eax +11450 { +11451 $check-mu-types:loop: +11452 # if (curr == null) break +11453 3d/compare-eax-and 0/imm32 +11454 0f 84/jump-if-= break/disp32 +11455 +-- 8 lines: #? # dump curr->name ------------------------------------------------------------------------------------------------------------------------------------------------ +11463 (check-mu-function %eax *(ebp+8) *(ebp+0xc)) +11464 # curr = lookup(curr->next) +11465 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax +11466 e9/jump loop/disp32 +11467 } +11468 $check-mu-types:end: +11469 # . restore registers +11470 58/pop-to-eax +11471 # . epilogue +11472 89/<- %esp 5/r32/ebp +11473 5d/pop-to-ebp +11474 c3/return +11475 +11476 check-mu-function: # fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11477 # . prologue +11478 55/push-ebp +11479 89/<- %ebp 4/r32/esp +11480 # . save registers +11481 50/push-eax +11482 # eax = f +11483 8b/-> *(ebp+8) 0/r32/eax +11484 # TODO: anything to check in header? +11485 # var body/eax: (addr block) = lookup(f->body) +11486 (lookup *(eax+0x18) *(eax+0x1c)) # Function-body Function-body => eax +11487 (check-mu-block %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10)) +11488 $check-mu-function:end: +11489 # . restore registers +11490 58/pop-to-eax +11491 # . epilogue +11492 89/<- %esp 5/r32/ebp +11493 5d/pop-to-ebp +11494 c3/return +11495 +11496 check-mu-block: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11497 # . prologue +11498 55/push-ebp +11499 89/<- %ebp 4/r32/esp +11500 # . save registers +11501 50/push-eax +11502 # eax = block +11503 8b/-> *(ebp+8) 0/r32/eax +11504 # var stmts/eax: (addr list stmt) = lookup(block->statements) +11505 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax +11506 # +11507 { +11508 $check-mu-block:check-empty: +11509 3d/compare-eax-and 0/imm32 +11510 0f 84/jump-if-= break/disp32 +11511 # emit block->statements +11512 (check-mu-stmt-list %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11513 } +11514 $check-mu-block:end: +11515 # . restore registers +11516 58/pop-to-eax +11517 # . epilogue +11518 89/<- %esp 5/r32/ebp +11519 5d/pop-to-ebp +11520 c3/return +11521 +11522 check-mu-stmt-list: # stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11523 # . prologue +11524 55/push-ebp +11525 89/<- %ebp 4/r32/esp +11526 # . save registers +11527 50/push-eax +11528 56/push-esi +11529 # esi = stmts +11530 8b/-> *(ebp+8) 6/r32/esi +11531 { +11532 $check-mu-stmt-list:loop: +11533 81 7/subop/compare %esi 0/imm32 +11534 0f 84/jump-if-= break/disp32 +11535 # var curr-stmt/eax: (addr stmt) = lookup(stmts->value) +11536 (lookup *esi *(esi+4)) # List-value List-value => eax +11537 { +11538 $check-mu-stmt-list:check-for-block: +11539 81 7/subop/compare *eax 0/imm32/block # Stmt-tag +11540 75/jump-if-!= break/disp8 +11541 $check-mu-stmt-list:block: +11542 (check-mu-block %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11543 eb/jump $check-mu-stmt-list:continue/disp8 +11544 } +11545 { +11546 $check-mu-stmt-list:check-for-stmt1: +11547 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag +11548 0f 85/jump-if-!= break/disp32 +11549 $check-mu-stmt-list:stmt1: +11550 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11551 eb/jump $check-mu-stmt-list:continue/disp8 +11552 } +11553 { +11554 $check-mu-stmt-list:check-for-reg-var-def: +11555 81 7/subop/compare *eax 3/imm32/reg-var-def # Stmt-tag +11556 0f 85/jump-if-!= break/disp32 +11557 $check-mu-stmt-list:reg-var-def: +11558 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11559 eb/jump $check-mu-stmt-list:continue/disp8 +11560 } +11561 $check-mu-stmt-list:continue: +11562 # TODO: raise an error on unrecognized Stmt-tag +11563 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax +11564 89/<- %esi 0/r32/eax +11565 e9/jump loop/disp32 +11566 } +11567 $check-mu-stmt-list:end: +11568 # . restore registers +11569 5e/pop-to-esi +11570 58/pop-to-eax +11571 # . epilogue +11572 89/<- %esp 5/r32/ebp +11573 5d/pop-to-ebp +11574 c3/return +11575 +11576 check-mu-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11577 # . prologue +11578 55/push-ebp +11579 89/<- %ebp 4/r32/esp +11580 # . save registers +11581 50/push-eax +11582 # - if stmt's operation matches a primitive, check against it +11583 (has-primitive-name? *(ebp+8)) # => eax +11584 3d/compare-eax-and 0/imm32/false +11585 { +11586 74/jump-if-= break/disp8 +11587 (check-mu-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11588 e9/jump $check-mu-stmt:end/disp32 +11589 } +11590 # - otherwise find a function to check against +11591 # var f/eax: (addr function) = lookup(*Program->functions) +11592 (lookup *_Program-functions *_Program-functions->payload) # => eax +11593 (find-matching-function %eax *(ebp+8)) # => eax +11594 3d/compare-eax-and 0/imm32 +11595 { +11596 74/jump-if-= break/disp8 +11597 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11598 eb/jump $check-mu-stmt:end/disp8 +11599 } +11600 # var f/eax: (addr function) = lookup(*Program->signatures) +11601 (lookup *_Program-signatures *_Program-signatures->payload) # => eax +11602 (find-matching-function %eax *(ebp+8)) # => eax +11603 3d/compare-eax-and 0/imm32 +11604 { +11605 74/jump-if-= break/disp8 +11606 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11607 eb/jump $check-mu-stmt:end/disp8 +11608 } +11609 # - otherwise abort +11610 e9/jump $check-mu-stmt:unknown-call/disp32 +11611 $check-mu-stmt:end: +11612 # . restore registers +11613 58/pop-to-eax +11614 # . epilogue +11615 89/<- %esp 5/r32/ebp +11616 5d/pop-to-ebp +11617 c3/return +11618 +11619 $check-mu-stmt:unknown-call: +11620 (write-buffered *(ebp+0x10) "unknown function '") +11621 8b/-> *(ebp+8) 0/r32/eax +11622 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +11623 (write-buffered *(ebp+0x10) %eax) +11624 (write-buffered *(ebp+0x10) "'\n") +11625 (flush *(ebp+0x10)) +11626 (stop *(ebp+0x14) 1) +11627 # never gets here +11628 +11629 has-primitive-name?: # stmt: (addr stmt) -> result/eax: boolean +11630 # . prologue +11631 55/push-ebp +11632 89/<- %ebp 4/r32/esp +11633 # . save registers +11634 51/push-ecx +11635 56/push-esi +11636 # var name/esi: (addr array byte) = lookup(stmt->operation) +11637 8b/-> *(ebp+8) 6/r32/esi +11638 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +11639 89/<- %esi 0/r32/eax +11640 # if (name == "get") return true +11641 (string-equal? %esi "get") # => eax +11642 3d/compare-eax-and 0/imm32/false +11643 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +11644 # if (name == "index") return true +11645 (string-equal? %esi "index") # => eax +11646 3d/compare-eax-and 0/imm32/false +11647 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +11648 # if (name == "length") return true +11649 (string-equal? %esi "length") # => eax +11650 3d/compare-eax-and 0/imm32/false +11651 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +11652 # if (name == "compute-offset") return true +11653 (string-equal? %esi "compute-offset") # => eax +11654 3d/compare-eax-and 0/imm32/false +11655 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +11656 # if (name == "lookup") return true +11657 (string-equal? %esi "lookup") # => eax +11658 3d/compare-eax-and 0/imm32/false +11659 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +11660 # if (name == "allocate") return true +11661 (string-equal? %esi "allocate") # => eax +11662 3d/compare-eax-and 0/imm32/false +11663 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +11664 # if (name == "populate") return true +11665 (string-equal? %esi "populate") # => eax +11666 3d/compare-eax-and 0/imm32/false +11667 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +11668 # var curr/ecx: (addr primitive) = Primitives +11669 b9/copy-to-ecx Primitives/imm32 +11670 { +11671 $has-primitive-name?:loop: +11672 # if (curr == null) break +11673 81 7/subop/compare %ecx 0/imm32 +11674 74/jump-if-= break/disp8 +11675 # if (primitive->name == name) return true +11676 (lookup *ecx *(ecx+4)) # Primitive-name Primitive-name => eax +11677 (string-equal? %esi %eax) # => eax +11678 3d/compare-eax-and 0/imm32/false +11679 75/jump-if-!= $has-primitive-name?:end/disp8 +11680 $has-primitive-name?:next-primitive: +11681 # curr = curr->next +11682 (lookup *(ecx+0x38) *(ecx+0x3c)) # Primitive-next Primitive-next => eax +11683 89/<- %ecx 0/r32/eax +11684 # +11685 e9/jump loop/disp32 +11686 } +11687 # return null +11688 b8/copy-to-eax 0/imm32 +11689 $has-primitive-name?:end: +11690 # . restore registers +11691 5e/pop-to-esi +11692 59/pop-to-ecx +11693 # . epilogue +11694 89/<- %esp 5/r32/ebp +11695 5d/pop-to-ebp +11696 c3/return +11697 +11698 check-mu-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11699 # . prologue +11700 55/push-ebp +11701 89/<- %ebp 4/r32/esp +11702 # . save registers +11703 50/push-eax +11704 51/push-ecx +11705 # var op/ecx: (addr array byte) = lookup(stmt->operation) +11706 8b/-> *(ebp+8) 0/r32/eax +11707 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +11708 89/<- %ecx 0/r32/eax +11709 # if (op == "copy") check-mu-copy-stmt +11710 { +11711 (string-equal? %ecx "copy") # => eax +11712 3d/compare-eax-and 0/imm32/false +11713 74/jump-if-= break/disp8 +11714 (check-mu-copy-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11715 e9/jump $check-mu-primitive:end/disp32 +11716 } +11717 # if (op == "copy-to") check-mu-copy-to-stmt +11718 { +11719 (string-equal? %ecx "copy-to") # => eax +11720 3d/compare-eax-and 0/imm32/false +11721 74/jump-if-= break/disp8 +11722 (check-mu-copy-to-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11723 e9/jump $check-mu-primitive:end/disp32 +11724 } +11725 # if (op == "compare") check-mu-compare-stmt +11726 { +11727 (string-equal? %ecx "compare") # => eax 11728 3d/compare-eax-and 0/imm32/false -11729 { -11730 0f 85/jump-if-!= break/disp32 -11731 (write-buffered *(ebp+0x14) "fn ") -11732 8b/-> *(ebp+0x10) 0/r32/eax -11733 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11734 (write-buffered *(ebp+0x14) %eax) -11735 (write-buffered *(ebp+0x14) ": call ") -11736 (lookup *edi *(edi+4)) # Function-name Function-name => eax -11737 (write-buffered *(ebp+0x14) %eax) -11738 (write-buffered *(ebp+0x14) ": type for inout '") -11739 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -11740 (lookup *eax *(eax+4)) # Var-name Var-name => eax -11741 (write-buffered *(ebp+0x14) %eax) -11742 (write-buffered *(ebp+0x14) "' is not right\n") -11743 (flush *(ebp+0x14)) -11744 (stop *(ebp+0x18) 1) -11745 } -11746 $check-mu-call:continue-to-next-inout: -11747 # inouts = lookup(inouts->next) -11748 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -11749 89/<- %ecx 0/r32/eax -11750 # expected = lookup(expected->next) -11751 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax -11752 89/<- %edx 0/r32/eax -11753 # -11754 e9/jump loop/disp32 -11755 } -11756 $check-mu-call:check-inout-count: -11757 # if (inouts == expected) proceed -11758 39/compare %ecx 2/r32/edx -11759 { -11760 0f 84/jump-if-= break/disp32 -11761 # exactly one of the two is null -11762 # if (inouts == 0) error("too many inouts") -11763 { -11764 81 7/subop/compare %ecx 0/imm32 -11765 0f 84/jump-if-= break/disp32 -11766 (write-buffered *(ebp+0x14) "fn ") -11767 8b/-> *(ebp+0x10) 0/r32/eax -11768 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11769 (write-buffered *(ebp+0x14) %eax) -11770 (write-buffered *(ebp+0x14) ": call ") -11771 (lookup *edi *(edi+4)) # Function-name Function-name => eax -11772 (write-buffered *(ebp+0x14) %eax) -11773 (write-buffered *(ebp+0x14) ": too many inouts\n") -11774 (flush *(ebp+0x14)) -11775 (stop *(ebp+0x18) 1) -11776 } -11777 # if (expected == 0) error("too few inouts") -11778 { -11779 81 7/subop/compare %edx 0/imm32 -11780 0f 84/jump-if-= break/disp32 -11781 (write-buffered *(ebp+0x14) "fn ") -11782 8b/-> *(ebp+0x10) 0/r32/eax -11783 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11784 (write-buffered *(ebp+0x14) %eax) -11785 (write-buffered *(ebp+0x14) ": call ") -11786 (lookup *edi *(edi+4)) # Function-name Function-name => eax -11787 (write-buffered *(ebp+0x14) %eax) -11788 (write-buffered *(ebp+0x14) ": too few inouts\n") -11789 (flush *(ebp+0x14)) -11790 (stop *(ebp+0x18) 1) -11791 } -11792 } -11793 $check-mu-call:check-outputs: -11794 # var outputs/ecx: (addr stmt-var) = lookup(stmt->outputs) -11795 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -11796 89/<- %ecx 0/r32/eax -11797 # var expected/edx: (addr list var) = lookup(f->outputs) -11798 (lookup *(edi+0x10) *(edi+0x14)) # Function-outputs Function-outputs => eax -11799 89/<- %edx 0/r32/eax -11800 { -11801 $check-mu-call:check-for-outputs: -11802 # if (outputs == 0) break -11803 81 7/subop/compare %ecx 0/imm32 -11804 0f 84/jump-if-= break/disp32 -11805 # if (expected == 0) error -11806 81 7/subop/compare %edx 0/imm32 -11807 0f 84/jump-if-= break/disp32 -11808 $check-mu-call:check-output-type: -11809 # var v/eax: (addr v) = lookup(outputs->value) -11810 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -11811 # var t/ebx: (addr type-tree) = lookup(v->type) -11812 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -11813 89/<- %ebx 0/r32/eax -11814 # if (outputs->is-deref?) t = t->right # TODO: check that t->left is an addr -11815 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -11816 { -11817 74/jump-if-= break/disp8 -11818 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax -11819 89/<- %ebx 0/r32/eax -11820 } -11821 # var v2/eax: (addr v) = lookup(expected->value) -11822 (lookup *edx *(edx+4)) # List-value List-value => eax -11823 # var t2/eax: (addr type-tree) = lookup(v2->type) -11824 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -11825 # if (t != t2) error -11826 (type-equal? %eax %ebx) # => eax -11827 3d/compare-eax-and 0/imm32/false -11828 { -11829 0f 85/jump-if-!= break/disp32 -11830 (write-buffered *(ebp+0x14) "fn ") -11831 8b/-> *(ebp+0x10) 0/r32/eax -11832 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11833 (write-buffered *(ebp+0x14) %eax) -11834 (write-buffered *(ebp+0x14) ": call ") -11835 (lookup *edi *(edi+4)) # Function-name Function-name => eax -11836 (write-buffered *(ebp+0x14) %eax) -11837 (write-buffered *(ebp+0x14) ": type for output '") -11838 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -11839 (lookup *eax *(eax+4)) # Var-name Var-name => eax -11840 (write-buffered *(ebp+0x14) %eax) -11841 (write-buffered *(ebp+0x14) "' is not right\n") -11842 (flush *(ebp+0x14)) -11843 (stop *(ebp+0x18) 1) -11844 } -11845 $check-mu-call:check-output-register: -11846 # var v/eax: (addr v) = lookup(outputs->value) -11847 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -11848 # var r/ebx: (addr array byte) = lookup(v->register) -11849 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax -11850 89/<- %ebx 0/r32/eax -11851 # var v2/eax: (addr v) = lookup(expected->value) -11852 (lookup *edx *(edx+4)) # Stmt-var-value Stmt-var-value => eax -11853 # var r2/eax: (addr array byte) = lookup(v2->register) -11854 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax -11855 # if (r != r2) error -11856 (string-equal? %eax %ebx) # => eax -11857 3d/compare-eax-and 0/imm32/false -11858 { -11859 0f 85/jump-if-!= break/disp32 -11860 (write-buffered *(ebp+0x14) "fn ") -11861 8b/-> *(ebp+0x10) 0/r32/eax -11862 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11863 (write-buffered *(ebp+0x14) %eax) -11864 (write-buffered *(ebp+0x14) ": call ") -11865 (lookup *edi *(edi+4)) # Function-name Function-name => eax -11866 (write-buffered *(ebp+0x14) %eax) -11867 (write-buffered *(ebp+0x14) ": register for output '") -11868 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -11869 (lookup *eax *(eax+4)) # Var-name Var-name => eax -11870 (write-buffered *(ebp+0x14) %eax) -11871 (write-buffered *(ebp+0x14) "' is not right\n") -11872 (flush *(ebp+0x14)) -11873 (stop *(ebp+0x18) 1) -11874 } -11875 $check-mu-call:continue-to-next-output: -11876 # outputs = lookup(outputs->next) -11877 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -11878 89/<- %ecx 0/r32/eax -11879 # expected = lookup(expected->next) -11880 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax -11881 89/<- %edx 0/r32/eax -11882 # -11883 e9/jump loop/disp32 -11884 } -11885 $check-mu-call:check-output-count: -11886 # if (outputs == expected) proceed -11887 39/compare %ecx 2/r32/edx -11888 { -11889 0f 84/jump-if-= break/disp32 -11890 # exactly one of the two is null -11891 # if (outputs == 0) error("too many outputs") -11892 { -11893 81 7/subop/compare %ecx 0/imm32 -11894 0f 84/jump-if-= break/disp32 -11895 (write-buffered *(ebp+0x14) "fn ") -11896 8b/-> *(ebp+0x10) 0/r32/eax -11897 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11898 (write-buffered *(ebp+0x14) %eax) -11899 (write-buffered *(ebp+0x14) ": call ") -11900 (lookup *edi *(edi+4)) # Function-name Function-name => eax -11901 (write-buffered *(ebp+0x14) %eax) -11902 (write-buffered *(ebp+0x14) ": too many outputs\n") -11903 (flush *(ebp+0x14)) -11904 (stop *(ebp+0x18) 1) -11905 } -11906 # if (expected == 0) error("too few outputs") -11907 { -11908 81 7/subop/compare %edx 0/imm32 -11909 0f 84/jump-if-= break/disp32 -11910 (write-buffered *(ebp+0x14) "fn ") -11911 8b/-> *(ebp+0x10) 0/r32/eax -11912 (lookup *eax *(eax+4)) # Function-name Function-name => eax -11913 (write-buffered *(ebp+0x14) %eax) -11914 (write-buffered *(ebp+0x14) ": call ") -11915 (lookup *edi *(edi+4)) # Function-name Function-name => eax -11916 (write-buffered *(ebp+0x14) %eax) -11917 (write-buffered *(ebp+0x14) ": too few outputs\n") -11918 (flush *(ebp+0x14)) -11919 (stop *(ebp+0x18) 1) -11920 } -11921 } -11922 $check-mu-call:end: -11923 # . restore registers -11924 5f/pop-to-edi -11925 5e/pop-to-esi -11926 5b/pop-to-ebx -11927 5a/pop-to-edx -11928 59/pop-to-ecx -11929 58/pop-to-eax -11930 # . epilogue -11931 89/<- %esp 5/r32/ebp -11932 5d/pop-to-ebp -11933 c3/return -11934 -11935 # like type-equal? but takes literals into account -11936 type-match?: # def: (addr type-tree), call: (addr type-tree) -> result/eax: boolean -11937 # . prologue -11938 55/push-ebp -11939 89/<- %ebp 4/r32/esp -11940 # if (call == literal) return true # TODO: more precise -11941 (is-simple-mu-type? *(ebp+0xc) 0) # literal => eax -11942 3d/compare-eax-and 0/imm32/false -11943 b8/copy-to-eax 1/imm32/true -11944 75/jump-if-!= $type-match?:end/disp8 -11945 $type-match?:baseline: -11946 # otherwise fall back -11947 (type-equal? *(ebp+8) *(ebp+0xc)) # => eax -11948 $type-match?:end: -11949 # . epilogue -11950 89/<- %esp 5/r32/ebp -11951 5d/pop-to-ebp -11952 c3/return -11953 -11954 size-of: # v: (addr var) -> result/eax: int -11955 # . prologue -11956 55/push-ebp -11957 89/<- %ebp 4/r32/esp -11958 # . save registers -11959 51/push-ecx -11960 # var t/ecx: (addr type-tree) = lookup(v->type) -11961 8b/-> *(ebp+8) 1/r32/ecx -11962 #? (write-buffered Stderr "size-of ") -11963 #? (write-int32-hex-buffered Stderr %ecx) -11964 #? (write-buffered Stderr Newline) -11965 #? (write-buffered Stderr "type allocid: ") -11966 #? (write-int32-hex-buffered Stderr *(ecx+8)) -11967 #? (write-buffered Stderr Newline) -11968 #? (flush Stderr) -11969 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -11970 89/<- %ecx 0/r32/eax -11971 # if is-mu-array?(t) return size-of-array(t) -11972 { -11973 (is-mu-array? %ecx) # => eax -11974 3d/compare-eax-and 0/imm32/false -11975 74/jump-if-= break/disp8 -11976 (size-of-array %ecx) # => eax -11977 eb/jump $size-of:end/disp8 -11978 } -11979 # if (!t->is-atom?) t = lookup(t->left) -11980 { -11981 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -11982 75/jump-if-!= break/disp8 -11983 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -11984 89/<- %ecx 0/r32/eax -11985 } -11986 # TODO: assert t->is-atom? -11987 (size-of-type-id *(ecx+4)) # Type-tree-value => eax -11988 $size-of:end: -11989 # . restore registers -11990 59/pop-to-ecx -11991 # . epilogue -11992 89/<- %esp 5/r32/ebp -11993 5d/pop-to-ebp -11994 c3/return -11995 -11996 size-of-deref: # v: (addr var) -> result/eax: int -11997 # . prologue -11998 55/push-ebp -11999 89/<- %ebp 4/r32/esp -12000 # . save registers -12001 51/push-ecx -12002 # var t/ecx: (addr type-tree) = lookup(v->type) -12003 8b/-> *(ebp+8) 1/r32/ecx -12004 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -12005 89/<- %ecx 0/r32/eax -12006 # TODO: assert(t is an addr) -12007 # t = lookup(t->right) -12008 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -12009 89/<- %ecx 0/r32/eax -12010 # if is-mu-array?(t) return size-of-array(t) -12011 { -12012 (is-mu-array? %ecx) # => eax -12013 3d/compare-eax-and 0/imm32/false -12014 74/jump-if-= break/disp8 -12015 (size-of-array %ecx) # => eax -12016 eb/jump $size-of:end/disp8 -12017 } -12018 # if (!t->is-atom?) t = lookup(t->left) -12019 { -12020 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -12021 75/jump-if-!= break/disp8 -12022 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -12023 89/<- %ecx 0/r32/eax -12024 } -12025 # TODO: assert t->is-atom? -12026 (size-of-type-id *(ecx+4)) # Type-tree-value => eax -12027 $size-of-deref:end: -12028 # . restore registers -12029 59/pop-to-ecx -12030 # . epilogue -12031 89/<- %esp 5/r32/ebp -12032 5d/pop-to-ebp -12033 c3/return -12034 -12035 is-mu-array?: # t: (addr type-tree) -> result/eax: boolean -12036 # . prologue -12037 55/push-ebp -12038 89/<- %ebp 4/r32/esp -12039 # . save registers -12040 51/push-ecx -12041 # ecx = t -12042 8b/-> *(ebp+8) 1/r32/ecx -12043 # if t->is-atom?, return false -12044 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom -12045 75/jump-if-!= $is-mu-array?:return-false/disp8 -12046 # if !t->left->is-atom?, return false -12047 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -12048 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -12049 74/jump-if-= $is-mu-array?:return-false/disp8 -12050 # return t->left->value == array -12051 81 7/subop/compare *(eax+4) 3/imm32/array-type-id # Type-tree-value -12052 0f 94/set-if-= %al -12053 81 4/subop/and %eax 0xff/imm32 -12054 eb/jump $is-mu-array?:end/disp8 -12055 $is-mu-array?:return-false: -12056 b8/copy-to-eax 0/imm32/false -12057 $is-mu-array?:end: -12058 # . restore registers -12059 59/pop-to-ecx -12060 # . epilogue -12061 89/<- %esp 5/r32/ebp -12062 5d/pop-to-ebp -12063 c3/return -12064 -12065 size-of-array: # a: (addr type-tree) -> result/eax: int -12066 # . prologue -12067 55/push-ebp -12068 89/<- %ebp 4/r32/esp -12069 # . save registers -12070 51/push-ecx -12071 52/push-edx -12072 # -12073 8b/-> *(ebp+8) 1/r32/ecx -12074 # TODO: assert that a->left is 'array' -12075 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -12076 89/<- %ecx 0/r32/eax -12077 # var elem-type/edx: type-id = a->right->left->value -12078 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -12079 8b/-> *(eax+4) 2/r32/edx # Type-tree-value -12080 # TODO: assert that a->right->right->left->value == size -12081 # var array-size/ecx: int = a->right->right->left->value-size -12082 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -12083 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -12084 8b/-> *(eax+8) 1/r32/ecx # Type-tree-value-size -12085 # return array-size * size-of(elem-type) -12086 (size-of-type-id-as-array-element %edx) # => eax -12087 f7 4/subop/multiply-into-eax %ecx -12088 05/add-to-eax 4/imm32 # for array size -12089 $size-of-array:end: -12090 # . restore registers -12091 5a/pop-to-edx -12092 59/pop-to-ecx -12093 # . epilogue -12094 89/<- %esp 5/r32/ebp -12095 5d/pop-to-ebp -12096 c3/return -12097 -12098 size-of-type-id: # t: type-id -> result/eax: int -12099 # . prologue -12100 55/push-ebp -12101 89/<- %ebp 4/r32/esp -12102 # . save registers -12103 51/push-ecx -12104 # var out/ecx: (handle typeinfo) -12105 68/push 0/imm32 -12106 68/push 0/imm32 -12107 89/<- %ecx 4/r32/esp -12108 # eax = t -12109 8b/-> *(ebp+8) 0/r32/eax -12110 # if t is a literal, return 0 -12111 3d/compare-eax-and 0/imm32 -12112 0f 84/jump-if-= $size-of-type-id:end/disp32 # eax changes type from type-id to int -12113 # if t is a byte, return 4 (because we don't really support non-multiples of 4) -12114 3d/compare-eax-and 8/imm32/byte -12115 { -12116 75/jump-if-!= break/disp8 -12117 b8/copy-to-eax 4/imm32 -12118 eb/jump $size-of-type-id:end/disp8 -12119 } -12120 # if t is a handle, return 8 -12121 3d/compare-eax-and 4/imm32/handle -12122 { -12123 75/jump-if-!= break/disp8 -12124 b8/copy-to-eax 8/imm32 -12125 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int -12126 } -12127 # if t is a user-defined type, return its size -12128 # TODO: support non-atom type -12129 (find-typeinfo %eax %ecx) -12130 { -12131 81 7/subop/compare *ecx 0/imm32 -12132 74/jump-if-= break/disp8 -12133 $size-of-type-id:user-defined: -12134 (lookup *ecx *(ecx+4)) # => eax -12135 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes -12136 eb/jump $size-of-type-id:end/disp8 -12137 } -12138 # otherwise return the word size -12139 b8/copy-to-eax 4/imm32 -12140 $size-of-type-id:end: -12141 # . reclaim locals -12142 81 0/subop/add %esp 8/imm32 -12143 # . restore registers -12144 59/pop-to-ecx -12145 # . epilogue -12146 89/<- %esp 5/r32/ebp -12147 5d/pop-to-ebp -12148 c3/return -12149 -12150 type-equal?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean -12151 # . prologue -12152 55/push-ebp -12153 89/<- %ebp 4/r32/esp -12154 # . save registers -12155 51/push-ecx -12156 52/push-edx -12157 53/push-ebx -12158 # ecx = a -12159 8b/-> *(ebp+8) 1/r32/ecx -12160 # edx = b -12161 8b/-> *(ebp+0xc) 2/r32/edx -12162 $type-equal?:compare-addr: -12163 # if (a == b) return true -12164 8b/-> %ecx 0/r32/eax # Var-type -12165 39/compare %edx 0/r32/eax # Var-type -12166 b8/copy-to-eax 1/imm32/true -12167 0f 84/jump-if-= $type-equal?:end/disp32 -12168 $type-equal?:compare-atom-state: -12169 # if (a->is-atom? != b->is-atom?) return false -12170 8b/-> *ecx 3/r32/ebx # Type-tree-value -12171 39/compare *edx 3/r32/ebx # Type-tree-value -12172 b8/copy-to-eax 0/imm32/false -12173 0f 85/jump-if-!= $type-equal?:end/disp32 -12174 # if a->is-atom? return (a->value == b->value) -12175 { -12176 $type-equal?:check-atom: -12177 81 7/subop/compare %ebx 0/imm32/false -12178 74/jump-if-= break/disp8 -12179 $type-equal?:is-atom: -12180 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value -12181 39/compare *(edx+4) 0/r32/eax # Type-tree-value -12182 0f 94/set-if-= %al -12183 81 4/subop/and %eax 0xff/imm32 -12184 e9/jump $type-equal?:end/disp32 -12185 } -12186 $type-equal?:check-left: -12187 # if (!type-equal?(a->left, b->left)) return false -12188 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax -12189 89/<- %ebx 0/r32/eax -12190 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax -12191 (type-equal? %eax %ebx) # => eax -12192 3d/compare-eax-and 0/imm32/false -12193 74/jump-if-= $type-equal?:end/disp8 -12194 $type-equal?:check-right: -12195 # return type-equal?(a->right, b->right) -12196 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax -12197 89/<- %ebx 0/r32/eax -12198 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax -12199 (type-equal? %eax %ebx) # => eax -12200 $type-equal?:end: -12201 # . restore registers -12202 5b/pop-to-ebx -12203 5a/pop-to-edx -12204 59/pop-to-ecx -12205 # . epilogue -12206 89/<- %esp 5/r32/ebp -12207 5d/pop-to-ebp -12208 c3/return -12209 -12210 ####################################################### -12211 # Code-generation -12212 ####################################################### -12213 -12214 == data -12215 -12216 # Global state added to each var record when performing code-generation. -12217 Curr-local-stack-offset: # (addr int) -12218 0/imm32 -12219 -12220 == code -12221 -12222 emit-subx: # out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) -12223 # . prologue -12224 55/push-ebp -12225 89/<- %ebp 4/r32/esp -12226 # . save registers -12227 50/push-eax -12228 # var curr/eax: (addr function) = *Program->functions -12229 (lookup *_Program-functions *_Program-functions->payload) # => eax -12230 { -12231 # if (curr == null) break -12232 3d/compare-eax-and 0/imm32 -12233 0f 84/jump-if-= break/disp32 -12234 (emit-subx-function *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) -12235 # curr = lookup(curr->next) -12236 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax -12237 e9/jump loop/disp32 -12238 } -12239 $emit-subx:end: -12240 # . restore registers -12241 58/pop-to-eax -12242 # . epilogue -12243 89/<- %esp 5/r32/ebp -12244 5d/pop-to-ebp -12245 c3/return -12246 -12247 emit-subx-function: # out: (addr buffered-file), f: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -12248 # . prologue -12249 55/push-ebp -12250 89/<- %ebp 4/r32/esp -12251 # some preprocessing -12252 (populate-mu-type-offsets-in-inouts *(ebp+0xc)) -12253 # . save registers -12254 50/push-eax -12255 51/push-ecx -12256 52/push-edx -12257 # initialize some global state -12258 c7 0/subop/copy *Curr-block-depth 1/imm32 # Important: keep this in sync with the parse phase -12259 c7 0/subop/copy *Curr-local-stack-offset 0/imm32 -12260 # ecx = f -12261 8b/-> *(ebp+0xc) 1/r32/ecx -12262 # var vars/edx: (stack (addr var) 256) -12263 81 5/subop/subtract %esp 0xc00/imm32 -12264 68/push 0xc00/imm32/size -12265 68/push 0/imm32/top -12266 89/<- %edx 4/r32/esp -12267 # var name/eax: (addr array byte) = lookup(f->name) -12268 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax -12269 # -12270 (write-buffered *(ebp+8) %eax) -12271 (write-buffered *(ebp+8) ":\n") -12272 (emit-subx-prologue *(ebp+8)) -12273 # var body/eax: (addr block) = lookup(f->body) -12274 (lookup *(ecx+0x18) *(ecx+0x1c)) # Function-body Function-body => eax -12275 # -12276 (emit-subx-block *(ebp+8) %eax %edx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -12277 (emit-subx-epilogue *(ebp+8)) -12278 # TODO: validate that *Curr-block-depth and *Curr-local-stack-offset have -12279 # been cleaned up -12280 $emit-subx-function:end: -12281 # . reclaim locals -12282 81 0/subop/add %esp 0xc08/imm32 -12283 # . restore registers -12284 5a/pop-to-edx -12285 59/pop-to-ecx -12286 58/pop-to-eax -12287 # . epilogue -12288 89/<- %esp 5/r32/ebp -12289 5d/pop-to-ebp -12290 c3/return -12291 -12292 populate-mu-type-offsets-in-inouts: # f: (addr function) -12293 # . prologue -12294 55/push-ebp -12295 89/<- %ebp 4/r32/esp -12296 # . save registers -12297 50/push-eax -12298 51/push-ecx -12299 52/push-edx -12300 53/push-ebx -12301 57/push-edi -12302 # var next-offset/edx: int = 8 -12303 ba/copy-to-edx 8/imm32 -12304 # var curr/ecx: (addr list var) = lookup(f->inouts) -12305 8b/-> *(ebp+8) 1/r32/ecx -12306 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax -12307 89/<- %ecx 0/r32/eax -12308 { -12309 $populate-mu-type-offsets-in-inouts:loop: -12310 81 7/subop/compare %ecx 0/imm32 -12311 74/jump-if-= break/disp8 -12312 # var v/ebx: (addr var) = lookup(curr->value) -12313 (lookup *ecx *(ecx+4)) # List-value List-value => eax -12314 89/<- %ebx 0/r32/eax -12315 #? (lookup *ebx *(ebx+4)) -12316 #? (write-buffered Stderr "setting offset of fn inout ") -12317 #? (write-buffered Stderr %eax) -12318 #? (write-buffered Stderr "@") -12319 #? (write-int32-hex-buffered Stderr %ebx) -12320 #? (write-buffered Stderr " to ") -12321 #? (write-int32-hex-buffered Stderr %edx) -12322 #? (write-buffered Stderr Newline) -12323 #? (flush Stderr) -12324 # v->offset = next-offset -12325 89/<- *(ebx+0x14) 2/r32/edx # Var-offset -12326 # next-offset += size-of(v) -12327 (size-of %ebx) # => eax -12328 01/add-to %edx 0/r32/eax -12329 # curr = lookup(curr->next) -12330 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -12331 89/<- %ecx 0/r32/eax -12332 # -12333 eb/jump loop/disp8 -12334 } -12335 $populate-mu-type-offsets-in-inouts:end: -12336 # . restore registers -12337 5f/pop-to-edi -12338 5b/pop-to-ebx -12339 5a/pop-to-edx -12340 59/pop-to-ecx -12341 58/pop-to-eax -12342 # . epilogue -12343 89/<- %esp 5/r32/ebp -12344 5d/pop-to-ebp -12345 c3/return -12346 -12347 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) -12348 # . prologue -12349 55/push-ebp -12350 89/<- %ebp 4/r32/esp -12351 # . save registers -12352 50/push-eax -12353 51/push-ecx -12354 53/push-ebx -12355 56/push-esi -12356 # esi = stmts -12357 8b/-> *(ebp+0xc) 6/r32/esi -12358 # -12359 { -12360 $emit-subx-stmt-list:loop: -12361 81 7/subop/compare %esi 0/imm32 -12362 0f 84/jump-if-= break/disp32 -12363 # var curr-stmt/ecx: (addr stmt) = lookup(stmts->value) -12364 (lookup *esi *(esi+4)) # List-value List-value => eax -12365 89/<- %ecx 0/r32/eax -12366 { -12367 $emit-subx-stmt-list:check-for-block: -12368 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag -12369 75/jump-if-!= break/disp8 -12370 $emit-subx-stmt-list:block: -12371 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -12372 } -12373 { -12374 $emit-subx-stmt-list:check-for-stmt: -12375 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag -12376 0f 85/jump-if-!= break/disp32 -12377 $emit-subx-stmt-list:stmt1: -12378 { -12379 (is-mu-branch? %ecx) # => eax -12380 3d/compare-eax-and 0/imm32/false -12381 0f 84/jump-if-= break/disp32 -12382 $emit-subx-stmt-list:branch-stmt: -12383 +-- 27 lines: # unconditional loops ----------------------------------------------------------------------------------------------------------------------------------------------------- -12410 +-- 16 lines: # unconditional breaks ---------------------------------------------------------------------------------------------------------------------------------------------------- -12426 +-- 38 lines: # simple conditional branches without a target ---------------------------------------------------------------------------------------------------------------------------- -12464 +-- 19 lines: # conditional branches with an explicit target ---------------------------------------------------------------------------------------------------------------------------- -12483 } -12484 $emit-subx-stmt-list:1-to-1: -12485 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x18) *(ebp+0x1c)) -12486 e9/jump $emit-subx-stmt-list:continue/disp32 -12487 } -12488 { -12489 $emit-subx-stmt-list:check-for-var-def: -12490 81 7/subop/compare *ecx 2/imm32/var-def # Stmt-tag -12491 75/jump-if-!= break/disp8 -12492 $emit-subx-stmt-list:var-def: -12493 (emit-subx-var-def *(ebp+8) %ecx) -12494 (push *(ebp+0x10) *(ecx+4)) # Vardef-var -12495 (push *(ebp+0x10) *(ecx+8)) # Vardef-var -12496 (push *(ebp+0x10) 0) # Live-var-register-spilled = 0 for vars on the stack -12497 # -12498 eb/jump $emit-subx-stmt-list:continue/disp8 +11729 74/jump-if-= break/disp8 +11730 (check-mu-compare-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11731 e9/jump $check-mu-primitive:end/disp32 +11732 } +11733 # if (op == "address") check-mu-address-stmt +11734 { +11735 (string-equal? %ecx "address") # => eax +11736 3d/compare-eax-and 0/imm32/false +11737 74/jump-if-= break/disp8 +11738 (check-mu-address-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11739 e9/jump $check-mu-primitive:end/disp32 +11740 } +11741 # if (op == "get") check-mu-get-stmt +11742 { +11743 (string-equal? %ecx "get") # => eax +11744 3d/compare-eax-and 0/imm32/false +11745 74/jump-if-= break/disp8 +11746 (check-mu-get-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11747 e9/jump $check-mu-primitive:end/disp32 +11748 } +11749 # if (op == "index") check-mu-index-stmt +11750 { +11751 (string-equal? %ecx "index") # => eax +11752 3d/compare-eax-and 0/imm32/false +11753 74/jump-if-= break/disp8 +11754 (check-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11755 e9/jump $check-mu-primitive:end/disp32 +11756 } +11757 # if (op == "length") check-mu-length-stmt +11758 { +11759 (string-equal? %ecx "length") # => eax +11760 3d/compare-eax-and 0/imm32/false +11761 74/jump-if-= break/disp8 +11762 (check-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11763 e9/jump $check-mu-primitive:end/disp32 +11764 } +11765 # if (op == "compute-offset") check-mu-compute-offset-stmt +11766 { +11767 (string-equal? %ecx "compute-offset") # => eax +11768 3d/compare-eax-and 0/imm32/false +11769 74/jump-if-= break/disp8 +11770 (check-mu-compute-offset-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11771 e9/jump $check-mu-primitive:end/disp32 +11772 } +11773 # if (op == "lookup") check-mu-lookup-stmt +11774 { +11775 (string-equal? %ecx "lookup") # => eax +11776 3d/compare-eax-and 0/imm32/false +11777 74/jump-if-= break/disp8 +11778 (check-mu-lookup-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11779 e9/jump $check-mu-primitive:end/disp32 +11780 } +11781 # if (op == "allocate") check-mu-allocate-stmt +11782 { +11783 (string-equal? %ecx "allocate") # => eax +11784 3d/compare-eax-and 0/imm32/false +11785 74/jump-if-= break/disp8 +11786 (check-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11787 e9/jump $check-mu-primitive:end/disp32 +11788 } +11789 # if (op == "populate") check-mu-populate-stmt +11790 { +11791 (string-equal? %ecx "populate") # => eax +11792 3d/compare-eax-and 0/imm32/false +11793 74/jump-if-= break/disp8 +11794 (check-mu-populate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11795 e9/jump $check-mu-primitive:end/disp32 +11796 } +11797 # otherwise check-numberlike-stmt +11798 (check-mu-numberlike-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11799 $check-mu-primitive:end: +11800 # . restore registers +11801 59/pop-to-ecx +11802 58/pop-to-eax +11803 # . epilogue +11804 89/<- %esp 5/r32/ebp +11805 5d/pop-to-ebp +11806 c3/return +11807 +11808 # by default, Mu primitives should only operate on 'number-like' types +11809 check-mu-numberlike-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11810 # . prologue +11811 55/push-ebp +11812 89/<- %ebp 4/r32/esp +11813 # . save registers +11814 50/push-eax +11815 51/push-ecx +11816 56/push-esi +11817 # esi = stmt +11818 8b/-> *(ebp+8) 6/r32/esi +11819 # var gas/ecx: int = 2 +11820 b9/copy-to-ecx 2/imm32 +11821 # - check at most 1 output +11822 # var output/eax: (addr stmt-var) = stmt->outputs +11823 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +11824 { +11825 3d/compare-eax-and 0/imm32 +11826 74/jump-if-= break/disp8 +11827 $check-mu-numberlike-primitive:output: +11828 (check-mu-numberlike-output %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11829 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +11830 3d/compare-eax-and 0/imm32 +11831 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-outputs/disp32 +11832 # check output is in a register +11833 # --gas +11834 49/decrement-ecx +11835 } +11836 # - check first inout +11837 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +11838 { +11839 3d/compare-eax-and 0/imm32 +11840 0f 84/jump-if-= $check-mu-numberlike-primitive:end/disp32 +11841 $check-mu-numberlike-primitive:first-inout: +11842 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11843 # --gas +11844 49/decrement-ecx +11845 } +11846 # - check second inout +11847 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +11848 { +11849 3d/compare-eax-and 0/imm32 +11850 74/jump-if-= $check-mu-numberlike-primitive:end/disp8 +11851 $check-mu-numberlike-primitive:second-inout: +11852 # is a second inout allowed? +11853 81 7/subop/compare %ecx 0/imm32 +11854 0f 84/jump-if-= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 +11855 $check-mu-numberlike-primitive:second-inout-permitted: +11856 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11857 } +11858 $check-mu-numberlike-primitive:third-inout: +11859 # if there's a third arg, raise an error +11860 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next +11861 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 +11862 $check-mu-numberlike-primitive:end: +11863 # . restore registers +11864 5e/pop-to-esi +11865 59/pop-to-ecx +11866 58/pop-to-eax +11867 # . epilogue +11868 89/<- %esp 5/r32/ebp +11869 5d/pop-to-ebp +11870 c3/return +11871 +11872 $check-mu-numberlike-primitive:error-too-many-inouts: +11873 (write-buffered *(ebp+0x10) "fn ") +11874 8b/-> *(ebp+0xc) 0/r32/eax +11875 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11876 (write-buffered *(ebp+0x10) %eax) +11877 (write-buffered *(ebp+0x10) ": stmt ") +11878 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +11879 (write-buffered *(ebp+0x10) %eax) +11880 (write-buffered *(ebp+0x10) ": too many inouts; most primitives support at most two arguments, across inouts and outputs\n") +11881 (flush *(ebp+0x10)) +11882 (stop *(ebp+0x14) 1) +11883 # never gets here +11884 +11885 $check-mu-numberlike-primitive:error-too-many-outputs: +11886 (write-buffered *(ebp+0x10) "fn ") +11887 8b/-> *(ebp+0xc) 0/r32/eax +11888 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11889 (write-buffered *(ebp+0x10) %eax) +11890 (write-buffered *(ebp+0x10) ": stmt ") +11891 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +11892 (write-buffered *(ebp+0x10) %eax) +11893 (write-buffered *(ebp+0x10) ": too many outputs; most primitives support at most one output\n") +11894 (flush *(ebp+0x10)) +11895 (stop *(ebp+0x14) 1) +11896 # never gets here +11897 +11898 check-mu-numberlike-arg: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11899 # . prologue +11900 55/push-ebp +11901 89/<- %ebp 4/r32/esp +11902 # . save registers +11903 50/push-eax +11904 56/push-esi +11905 # var t/esi: (addr type-tree) = lookup(v->value->type) +11906 8b/-> *(ebp+8) 0/r32/eax +11907 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +11908 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11909 89/<- %esi 0/r32/eax +11910 $check-mu-numberlike-arg:check-literal: +11911 # if t is an int, return +11912 (is-simple-mu-type? %esi 0) # literal => eax +11913 3d/compare-eax-and 0/imm32/false +11914 75/jump-if-!= $check-mu-numberlike-arg:end/disp8 +11915 $check-mu-numberlike-arg:check-addr: +11916 # if t is an addr and v is dereferenced, return +11917 { +11918 (is-mu-addr-type? %esi) # => eax +11919 3d/compare-eax-and 0/imm32/false +11920 74/jump-if-= break/disp8 +11921 8b/-> *(ebp+8) 0/r32/eax +11922 8b/-> *(eax+0x10) 0/r32/eax +11923 3d/compare-eax-and 0/imm32/false +11924 75/jump-if-!= $check-mu-numberlike-arg:end/disp8 +11925 } +11926 $check-mu-numberlike-arg:output-checks: +11927 (check-mu-numberlike-output *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) +11928 $check-mu-numberlike-arg:end: +11929 # . restore registers +11930 5e/pop-to-esi +11931 58/pop-to-eax +11932 # . epilogue +11933 89/<- %esp 5/r32/ebp +11934 5d/pop-to-ebp +11935 c3/return +11936 +11937 check-mu-numberlike-output: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11938 # . prologue +11939 55/push-ebp +11940 89/<- %ebp 4/r32/esp +11941 # . save registers +11942 50/push-eax +11943 56/push-esi +11944 # var t/esi: (addr type-tree) = lookup(v->value->type) +11945 8b/-> *(ebp+8) 0/r32/eax +11946 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +11947 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11948 89/<- %esi 0/r32/eax +11949 $check-mu-numberlike-output:check-int: +11950 # if t is an int, return +11951 (is-simple-mu-type? %esi 1) # int => eax +11952 3d/compare-eax-and 0/imm32/false +11953 75/jump-if-!= $check-mu-numberlike-output:end/disp8 +11954 $check-mu-numberlike-output:check-boolean: +11955 # if t is a boolean, return +11956 (is-simple-mu-type? %esi 5) # boolean => eax +11957 3d/compare-eax-and 0/imm32/false +11958 75/jump-if-!= $check-mu-numberlike-output:end/disp8 +11959 $check-mu-numberlike-output:check-byte: +11960 # if t is a byte, return +11961 (is-simple-mu-type? %esi 8) # byte => eax +11962 3d/compare-eax-and 0/imm32/false +11963 75/jump-if-!= $check-mu-numberlike-output:end/disp8 +11964 e9/jump $check-mu-numberlike-output:fail/disp32 +11965 $check-mu-numberlike-output:end: +11966 # . restore registers +11967 5e/pop-to-esi +11968 58/pop-to-eax +11969 # . epilogue +11970 89/<- %esp 5/r32/ebp +11971 5d/pop-to-ebp +11972 c3/return +11973 +11974 $check-mu-numberlike-output:fail: +11975 # otherwise raise an error +11976 (write-buffered *(ebp+0x14) "fn ") +11977 8b/-> *(ebp+0x10) 0/r32/eax +11978 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11979 (write-buffered *(ebp+0x14) %eax) +11980 (write-buffered *(ebp+0x14) ": stmt ") +11981 8b/-> *(ebp+0xc) 0/r32/eax +11982 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +11983 (write-buffered *(ebp+0x14) %eax) +11984 (write-buffered *(ebp+0x14) ": only non-addr scalar args permitted\n") +11985 (flush *(ebp+0x14)) +11986 (stop *(ebp+0x18) 1) +11987 # never gets here +11988 +11989 check-mu-copy-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11990 # . prologue +11991 55/push-ebp +11992 89/<- %ebp 4/r32/esp +11993 # . save registers +11994 $check-mu-copy-stmt:end: +11995 # . restore registers +11996 # . epilogue +11997 89/<- %esp 5/r32/ebp +11998 5d/pop-to-ebp +11999 c3/return +12000 +12001 check-mu-copy-to-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12002 # . prologue +12003 55/push-ebp +12004 89/<- %ebp 4/r32/esp +12005 # . save registers +12006 $check-mu-copy-to-stmt:end: +12007 # . restore registers +12008 # . epilogue +12009 89/<- %esp 5/r32/ebp +12010 5d/pop-to-ebp +12011 c3/return +12012 +12013 check-mu-compare-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12014 # . prologue +12015 55/push-ebp +12016 89/<- %ebp 4/r32/esp +12017 # . save registers +12018 $check-mu-compare-stmt:end: +12019 # . restore registers +12020 # . epilogue +12021 89/<- %esp 5/r32/ebp +12022 5d/pop-to-ebp +12023 c3/return +12024 +12025 check-mu-address-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12026 # . prologue +12027 55/push-ebp +12028 89/<- %ebp 4/r32/esp +12029 # . save registers +12030 $check-mu-address-stmt:end: +12031 # . restore registers +12032 # . epilogue +12033 89/<- %esp 5/r32/ebp +12034 5d/pop-to-ebp +12035 c3/return +12036 +12037 check-mu-get-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12038 # . prologue +12039 55/push-ebp +12040 89/<- %ebp 4/r32/esp +12041 # . save registers +12042 50/push-eax +12043 51/push-ecx +12044 52/push-edx +12045 53/push-ebx +12046 56/push-esi +12047 57/push-edi +12048 # esi = stmt +12049 8b/-> *(ebp+8) 6/r32/esi +12050 # - check for 0 inouts +12051 # var base/ecx: (addr var) = stmt->inouts->value +12052 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +12053 3d/compare-eax-and 0/imm32/false +12054 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 +12055 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +12056 89/<- %ecx 0/r32/eax +12057 $check-mu-get-stmt:check-base: +12058 # - check base type +12059 # if it's an 'addr', check that it's in a register +12060 # var base-type/ebx: (addr type-tree) = lookup(base->type) +12061 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +12062 89/<- %ebx 0/r32/eax +12063 { +12064 81 7/subop/compare *ebx 0/imm32/false # Type-tree-is-atom +12065 0f 85/jump-if-!= break/disp32 +12066 $check-mu-get-stmt:base-is-compound: +12067 # if (type->left != addr) break +12068 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +12069 (is-simple-mu-type? %eax 2) # => eax +12070 3d/compare-eax-and 0/imm32/false +12071 74/jump-if-= break/disp8 +12072 $check-mu-get-stmt:base-is-addr: +12073 # now check for register +12074 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +12075 0f 84/jump-if-= $check-mu-get-stmt:error-base-type-addr-but-not-register/disp32 +12076 $check-mu-get-stmt:base-is-addr-in-register: +12077 # type->left is now an addr; skip it +12078 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +12079 81 7/subop/compare *(eax+0xc) 0/imm32 # Type-tree-right +12080 0f 85/jump-if-!= $check-mu-get-stmt:error-bad-base/disp32 +12081 $check-mu-get-stmt:base-is-addr-to-atom-in-register: +12082 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +12083 89/<- %ebx 0/r32/eax +12084 } +12085 $check-mu-get-stmt:check-base-typeinfo: +12086 # ensure type is a container +12087 # var base-type-id/ebx: type-id = base-type->value +12088 8b/-> *(ebx+4) 3/r32/ebx # Type-tree-value +12089 (is-container? %ebx) # => eax +12090 3d/compare-eax-and 0/imm32/false +12091 0f 84/jump-if-= $check-mu-get-stmt:error-bad-base/disp32 +12092 # var base-typeinfo/edx: (addr typeinfo) = find-typeinfo(base-type-id) +12093 # . var container/ecx: (handle typeinfo) +12094 68/push 0/imm32 +12095 68/push 0/imm32 +12096 89/<- %ecx 4/r32/esp +12097 # . +12098 (find-typeinfo %ebx %ecx) +12099 (lookup *ecx *(ecx+4)) # => eax +12100 # . reclaim container +12101 81 0/subop/add %esp 8/imm32 +12102 # . +12103 89/<- %edx 0/r32/eax +12104 # var offset/ecx: (addr stmt-var) = stmt->inouts->next +12105 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +12106 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +12107 89/<- %ecx 0/r32/eax +12108 # - check for 1 inout +12109 3d/compare-eax-and 0/imm32/false +12110 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 +12111 # var offset/ecx: (addr var) = lookup(offset->value) +12112 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +12113 89/<- %ecx 0/r32/eax +12114 # - check for valid field +12115 81 7/subop/compare *(ecx+0x14) -1/imm32/uninitialized # Var-offset +12116 0f 84/jump-if-= $check-mu-get-stmt:error-bad-field/disp32 +12117 # - check for too many inouts +12118 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +12119 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +12120 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +12121 3d/compare-eax-and 0/imm32/false +12122 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-inouts/disp32 +12123 # var output/edi: (addr var) = stmt->outputs->value +12124 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +12125 # - check for 0 outputs +12126 3d/compare-eax-and 0/imm32/false +12127 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-outputs/disp32 +12128 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +12129 89/<- %edi 0/r32/eax +12130 $check-mu-get-stmt:check-output-type: +12131 # - check output type +12132 # must be in register +12133 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +12134 3d/compare-eax-and 0/imm32 +12135 0f 84/jump-if-= $check-mu-get-stmt:error-output-not-in-register/disp32 +12136 # must have a non-atomic type +12137 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +12138 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +12139 0f 85/jump-if-!= $check-mu-get-stmt:error-output-type-not-address/disp32 +12140 # type must start with (addr ...) +12141 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +12142 (is-simple-mu-type? %eax 2) # => eax +12143 3d/compare-eax-and 0/imm32/false +12144 0f 84/jump-if-= $check-mu-get-stmt:error-output-type-not-address/disp32 +12145 $check-mu-get-stmt:check-output-type-match: +12146 # payload of addr type must match 'type' definition +12147 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +12148 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +12149 # if (payload->right == null) payload = payload->left +12150 81 7/subop/compare *(eax+0xc) 0/imm32/null # Type-tree-right +12151 { +12152 75/jump-if-!= break/disp8 +12153 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +12154 } +12155 89/<- %edi 0/r32/eax +12156 # . var output-name/ecx: (addr array byte) +12157 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +12158 89/<- %ecx 0/r32/eax +12159 # . var base-typeinfo-entry/eax: (addr handle typeinfo-entry) +12160 (lookup *(edx+4) *(edx+8)) # Typeinfo-fields Typeinfo-fields => eax +12161 (get %eax %ecx 0x10) # => eax +12162 # . +12163 (lookup *eax *(eax+4)) # => eax +12164 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax +12165 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +12166 # . +12167 (type-equal? %edi %eax) # => eax +12168 3d/compare-eax-and 0/imm32/false +12169 0f 84/jump-if-= $check-mu-get-stmt:error-bad-output-type/disp32 +12170 # - check for too many outputs +12171 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +12172 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +12173 3d/compare-eax-and 0/imm32/false +12174 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-outputs/disp32 +12175 $check-mu-get-stmt:end: +12176 # . restore registers +12177 5f/pop-to-edi +12178 5e/pop-to-esi +12179 5b/pop-to-ebx +12180 5a/pop-to-edx +12181 59/pop-to-ecx +12182 58/pop-to-eax +12183 # . epilogue +12184 89/<- %esp 5/r32/ebp +12185 5d/pop-to-ebp +12186 c3/return +12187 +12188 $check-mu-get-stmt:error-too-few-inouts: +12189 (write-buffered *(ebp+0x10) "fn ") +12190 8b/-> *(ebp+0xc) 0/r32/eax +12191 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12192 (write-buffered *(ebp+0x10) %eax) +12193 (write-buffered *(ebp+0x10) ": stmt get: too few inouts (2 required)\n") +12194 (flush *(ebp+0x10)) +12195 (stop *(ebp+0x14) 1) +12196 # never gets here +12197 +12198 $check-mu-get-stmt:error-too-many-inouts: +12199 (write-buffered *(ebp+0x10) "fn ") +12200 8b/-> *(ebp+0xc) 0/r32/eax +12201 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12202 (write-buffered *(ebp+0x10) %eax) +12203 (write-buffered *(ebp+0x10) ": stmt get: too many inouts (2 required)\n") +12204 (flush *(ebp+0x10)) +12205 (stop *(ebp+0x14) 1) +12206 # never gets here +12207 +12208 $check-mu-get-stmt:error-too-few-outputs: +12209 (write-buffered *(ebp+0x10) "fn ") +12210 8b/-> *(ebp+0xc) 0/r32/eax +12211 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12212 (write-buffered *(ebp+0x10) %eax) +12213 (write-buffered *(ebp+0x10) ": stmt get: must have an output\n") +12214 (flush *(ebp+0x10)) +12215 (stop *(ebp+0x14) 1) +12216 # never gets here +12217 +12218 $check-mu-get-stmt:error-too-many-outputs: +12219 (write-buffered *(ebp+0x10) "fn ") +12220 8b/-> *(ebp+0xc) 0/r32/eax +12221 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12222 (write-buffered *(ebp+0x10) %eax) +12223 (write-buffered *(ebp+0x10) ": stmt get: too many outputs (1 required)\n") +12224 (flush *(ebp+0x10)) +12225 (stop *(ebp+0x14) 1) +12226 # never gets here +12227 +12228 $check-mu-get-stmt:error-bad-base: +12229 # error("fn " fn ": stmt get: var '" base->name "' must have a 'type' definition\n") +12230 (write-buffered *(ebp+0x10) "fn ") +12231 8b/-> *(ebp+0xc) 0/r32/eax +12232 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12233 (write-buffered *(ebp+0x10) %eax) +12234 (write-buffered *(ebp+0x10) ": stmt get: var '") +12235 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +12236 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +12237 (lookup *eax *(eax+4)) # Var-name Var-name => eax +12238 (write-buffered *(ebp+0x10) %eax) +12239 (write-buffered *(ebp+0x10) "' must have a 'type' definition\n") +12240 (flush *(ebp+0x10)) +12241 (stop *(ebp+0x14) 1) +12242 # never gets here +12243 +12244 $check-mu-get-stmt:error-base-type-addr-but-not-register: +12245 (write-buffered *(ebp+0x10) "fn ") +12246 8b/-> *(ebp+0xc) 0/r32/eax +12247 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12248 (write-buffered *(ebp+0x10) %eax) +12249 (write-buffered *(ebp+0x10) ": stmt get: var '") +12250 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +12251 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +12252 (lookup *eax *(eax+4)) # Var-name Var-name => eax +12253 (write-buffered *(ebp+0x10) %eax) +12254 (write-buffered *(ebp+0x10) "' is an 'addr' type, and so must live in a register\n") +12255 (flush *(ebp+0x10)) +12256 (stop *(ebp+0x14) 1) +12257 # never gets here +12258 +12259 $check-mu-get-stmt:error-bad-field: +12260 # error("fn " fn ": stmt get: type " type " has no member called '" curr->name "'\n") +12261 (write-buffered *(ebp+0x10) "fn ") +12262 8b/-> *(ebp+0xc) 0/r32/eax +12263 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12264 (write-buffered *(ebp+0x10) %eax) +12265 (write-buffered *(ebp+0x10) ": stmt get: type '") +12266 # . write(Type-id->data[tmp]) +12267 bf/copy-to-edi Type-id/imm32 +12268 (write-buffered *(ebp+0x10) *(edi+ebx<<2+0xc)) +12269 # . +12270 (write-buffered *(ebp+0x10) "' has no member called '") +12271 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +12272 (write-buffered *(ebp+0x10) %eax) +12273 (write-buffered *(ebp+0x10) "'\n") +12274 (flush *(ebp+0x10)) +12275 (stop *(ebp+0x14) 1) +12276 # never gets here +12277 +12278 $check-mu-get-stmt:error-output-not-in-register: +12279 (write-buffered *(ebp+0x10) "fn ") +12280 8b/-> *(ebp+0xc) 0/r32/eax +12281 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12282 (write-buffered *(ebp+0x10) %eax) +12283 (write-buffered *(ebp+0x10) ": stmt get: output '") +12284 (lookup *edi *(edi+4)) # Var-name Var-name => eax +12285 (write-buffered *(ebp+0x10) %eax) +12286 (write-buffered *(ebp+0x10) "' is not in a register\n") +12287 (flush *(ebp+0x10)) +12288 (stop *(ebp+0x14) 1) +12289 # never gets here +12290 +12291 $check-mu-get-stmt:error-output-type-not-address: +12292 (write-buffered *(ebp+0x10) "fn ") +12293 8b/-> *(ebp+0xc) 0/r32/eax +12294 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12295 (write-buffered *(ebp+0x10) %eax) +12296 (write-buffered *(ebp+0x10) ": stmt get: output must be an address\n") +12297 (flush *(ebp+0x10)) +12298 (stop *(ebp+0x14) 1) +12299 # never gets here +12300 +12301 $check-mu-get-stmt:error-bad-output-type: +12302 (write-buffered *(ebp+0x10) "fn ") +12303 8b/-> *(ebp+0xc) 0/r32/eax +12304 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12305 (write-buffered *(ebp+0x10) %eax) +12306 (write-buffered *(ebp+0x10) ": stmt get: wrong output type for member '") +12307 (write-buffered *(ebp+0x10) %ecx) +12308 (write-buffered *(ebp+0x10) "' of type '") +12309 bf/copy-to-edi Type-id/imm32 +12310 (write-buffered *(ebp+0x10) *(edi+ebx<<2+0xc)) +12311 (write-buffered *(ebp+0x10) "'\n") +12312 (flush *(ebp+0x10)) +12313 (stop *(ebp+0x14) 1) +12314 # never gets here +12315 +12316 check-mu-index-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12317 # . prologue +12318 55/push-ebp +12319 89/<- %ebp 4/r32/esp +12320 # . save registers +12321 $check-mu-index-stmt:end: +12322 # . restore registers +12323 # . epilogue +12324 89/<- %esp 5/r32/ebp +12325 5d/pop-to-ebp +12326 c3/return +12327 +12328 check-mu-length-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12329 # . prologue +12330 55/push-ebp +12331 89/<- %ebp 4/r32/esp +12332 # . save registers +12333 $check-mu-length-stmt:end: +12334 # . restore registers +12335 # . epilogue +12336 89/<- %esp 5/r32/ebp +12337 5d/pop-to-ebp +12338 c3/return +12339 +12340 check-mu-compute-offset-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12341 # . prologue +12342 55/push-ebp +12343 89/<- %ebp 4/r32/esp +12344 # . save registers +12345 $check-mu-compute-offset-stmt:end: +12346 # . restore registers +12347 # . epilogue +12348 89/<- %esp 5/r32/ebp +12349 5d/pop-to-ebp +12350 c3/return +12351 +12352 check-mu-lookup-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12353 # . prologue +12354 55/push-ebp +12355 89/<- %ebp 4/r32/esp +12356 # . save registers +12357 $check-mu-lookup-stmt:end: +12358 # . restore registers +12359 # . epilogue +12360 89/<- %esp 5/r32/ebp +12361 5d/pop-to-ebp +12362 c3/return +12363 +12364 check-mu-allocate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12365 # . prologue +12366 55/push-ebp +12367 89/<- %ebp 4/r32/esp +12368 # . save registers +12369 $check-mu-allocate-stmt:end: +12370 # . restore registers +12371 # . epilogue +12372 89/<- %esp 5/r32/ebp +12373 5d/pop-to-ebp +12374 c3/return +12375 +12376 check-mu-populate-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12377 # . prologue +12378 55/push-ebp +12379 89/<- %ebp 4/r32/esp +12380 # . save registers +12381 $check-mu-populate-stmt:end: +12382 # . restore registers +12383 # . epilogue +12384 89/<- %esp 5/r32/ebp +12385 5d/pop-to-ebp +12386 c3/return +12387 +12388 check-mu-call: # stmt: (addr stmt), callee: (addr function), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +12389 # . prologue +12390 55/push-ebp +12391 89/<- %ebp 4/r32/esp +12392 # var type-parameters: (addr table (handle array byte) (addr type-tree) 8) +12393 68/push 0/imm32 +12394 # var type-parameters-storage: (table (handle array byte) (addr type-tree) 8) +12395 81 5/subop/subtract %esp 0x60/imm32 +12396 68/push 0x60/imm32/size +12397 68/push 0/imm32/read +12398 68/push 0/imm32/write +12399 # save a pointer to type-parameters-storage at type-parameters +12400 89/<- *(ebp-4) 4/r32/esp +12401 (clear-stream *(ebp-4)) +12402 # . save registers +12403 50/push-eax +12404 51/push-ecx +12405 52/push-edx +12406 53/push-ebx +12407 56/push-esi +12408 57/push-edi +12409 # esi = stmt +12410 8b/-> *(ebp+8) 6/r32/esi +12411 # edi = callee +12412 8b/-> *(ebp+0xc) 7/r32/edi +12413 # var inouts/ecx: (addr stmt-var) = lookup(stmt->inouts) +12414 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +12415 89/<- %ecx 0/r32/eax +12416 # var expected/edx: (addr list var) = lookup(f->inouts) +12417 (lookup *(edi+8) *(edi+0xc)) # Function-inouts Function-inouts => eax +12418 89/<- %edx 0/r32/eax +12419 { +12420 $check-mu-call:check-for-inouts: +12421 # if (inouts == 0) break +12422 81 7/subop/compare %ecx 0/imm32 +12423 0f 84/jump-if-= break/disp32 +12424 # if (expected == 0) error +12425 81 7/subop/compare %edx 0/imm32 +12426 0f 84/jump-if-= break/disp32 +12427 $check-mu-call:check-inout-type: +12428 # var v/eax: (addr v) = lookup(inouts->value) +12429 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +12430 # var t/ebx: (addr type-tree) = lookup(v->type) +12431 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +12432 89/<- %ebx 0/r32/eax +12433 # if (inouts->is-deref?) t = t->right # TODO: check that t->left is an addr +12434 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +12435 { +12436 74/jump-if-= break/disp8 +12437 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +12438 89/<- %ebx 0/r32/eax +12439 # if t->right is null, t = t->left +12440 81 7/subop/compare *(ebx+0xc) 0/imm32 # Type-tree-right +12441 75/jump-if-!= break/disp8 +12442 (lookup *(ebx+4) *(ebx+8)) # Type-tree-left Type-tree-left => eax +12443 89/<- %ebx 0/r32/eax +12444 } +12445 # var v2/eax: (addr v) = lookup(expected->value) +12446 (lookup *edx *(edx+4)) # List-value List-value => eax +12447 # var t2/eax: (addr type-tree) = lookup(v2->type) +12448 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +12449 # if (t != t2) error +12450 (type-match? %eax %ebx *(ebp-4)) # => eax +12451 3d/compare-eax-and 0/imm32/false +12452 { +12453 0f 85/jump-if-!= break/disp32 +12454 (write-buffered *(ebp+0x14) "fn ") +12455 8b/-> *(ebp+0x10) 0/r32/eax +12456 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12457 (write-buffered *(ebp+0x14) %eax) +12458 (write-buffered *(ebp+0x14) ": call ") +12459 (lookup *edi *(edi+4)) # Function-name Function-name => eax +12460 (write-buffered *(ebp+0x14) %eax) +12461 (write-buffered *(ebp+0x14) ": type for inout '") +12462 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +12463 (lookup *eax *(eax+4)) # Var-name Var-name => eax +12464 (write-buffered *(ebp+0x14) %eax) +12465 (write-buffered *(ebp+0x14) "' is not right\n") +12466 (flush *(ebp+0x14)) +12467 (stop *(ebp+0x18) 1) +12468 } +12469 $check-mu-call:continue-to-next-inout: +12470 # inouts = lookup(inouts->next) +12471 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +12472 89/<- %ecx 0/r32/eax +12473 # expected = lookup(expected->next) +12474 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +12475 89/<- %edx 0/r32/eax +12476 # +12477 e9/jump loop/disp32 +12478 } +12479 $check-mu-call:check-inout-count: +12480 # if (inouts == expected) proceed +12481 39/compare %ecx 2/r32/edx +12482 { +12483 0f 84/jump-if-= break/disp32 +12484 # exactly one of the two is null +12485 # if (inouts == 0) error("too many inouts") +12486 { +12487 81 7/subop/compare %ecx 0/imm32 +12488 0f 84/jump-if-= break/disp32 +12489 (write-buffered *(ebp+0x14) "fn ") +12490 8b/-> *(ebp+0x10) 0/r32/eax +12491 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12492 (write-buffered *(ebp+0x14) %eax) +12493 (write-buffered *(ebp+0x14) ": call ") +12494 (lookup *edi *(edi+4)) # Function-name Function-name => eax +12495 (write-buffered *(ebp+0x14) %eax) +12496 (write-buffered *(ebp+0x14) ": too many inouts\n") +12497 (flush *(ebp+0x14)) +12498 (stop *(ebp+0x18) 1) 12499 } -12500 { -12501 $emit-subx-stmt-list:check-for-reg-var-def: -12502 81 7/subop/compare *ecx 3/imm32/reg-var-def # Stmt-tag -12503 0f 85/jump-if-!= break/disp32 -12504 $emit-subx-stmt-list:reg-var-def: -12505 # TODO: ensure that there's exactly one output -12506 (push-output-and-maybe-emit-spill *(ebp+8) %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -12507 # emit the instruction as usual -12508 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x18) *(ebp+0x1c)) -12509 # -12510 eb/jump $emit-subx-stmt-list:continue/disp8 -12511 } -12512 $emit-subx-stmt-list:continue: -12513 # TODO: raise an error on unrecognized Stmt-tag -12514 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax -12515 89/<- %esi 0/r32/eax -12516 e9/jump loop/disp32 -12517 } -12518 $emit-subx-stmt-list:emit-cleanup: -12519 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) *Curr-block-depth) -12520 $emit-subx-stmt-list:clean-up: -12521 (clean-up-blocks *(ebp+0x10) *Curr-block-depth *(ebp+0x14)) -12522 $emit-subx-stmt-list:end: -12523 # . restore registers -12524 5e/pop-to-esi -12525 5b/pop-to-ebx -12526 59/pop-to-ecx -12527 58/pop-to-eax -12528 # . epilogue -12529 89/<- %esp 5/r32/ebp -12530 5d/pop-to-ebp -12531 c3/return -12532 -12533 # 'later-stmts' includes 'stmt', but will behave the same even without it; reg-var-def stmts are guaranteed not to write to function outputs. -12534 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) -12535 # . prologue -12536 55/push-ebp -12537 89/<- %ebp 4/r32/esp -12538 # . save registers -12539 50/push-eax -12540 51/push-ecx -12541 52/push-edx -12542 # ecx = stmt -12543 8b/-> *(ebp+0xc) 1/r32/ecx -12544 # var sv/eax: (addr stmt-var) = lookup(curr-stmt->outputs) -12545 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax -12546 # TODO: assert !sv->is-deref? -12547 # var v/ecx: (addr var) = lookup(sv->value) -12548 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12549 89/<- %ecx 0/r32/eax -12550 # v->block-depth = *Curr-block-depth -12551 8b/-> *Curr-block-depth 0/r32/eax -12552 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -12553 #? (write-buffered Stderr "var ") -12554 #? (lookup *ecx *(ecx+4)) -12555 #? (write-buffered Stderr %eax) -12556 #? (write-buffered Stderr " at depth ") -12557 #? (write-int32-hex-buffered Stderr *(ecx+0x10)) -12558 #? (write-buffered Stderr Newline) -12559 #? (flush Stderr) -12560 # ensure that v is in a register -12561 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -12562 0f 84/jump-if-= $push-output-and-maybe-emit-spill:abort/disp32 -12563 # var emit-spill?/edx: boolean = not-yet-spilled-this-block? && will-not-write-some-register?(fn) -12564 (not-yet-spilled-this-block? %ecx *(ebp+0x10)) # => eax -12565 89/<- %edx 0/r32/eax -12566 3d/compare-eax-and 0/imm32/false -12567 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 -12568 (will-not-write-some-register? %ecx *(ebp+0x14) *(ebp+0x18)) # => eax -12569 89/<- %edx 0/r32/eax -12570 # check emit-spill? -12571 3d/compare-eax-and 0/imm32/false -12572 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 -12573 # TODO: assert(size-of(output) == 4) -12574 # *Curr-local-stack-offset -= 4 -12575 81 5/subop/subtract *Curr-local-stack-offset 4/imm32 -12576 # emit spill -12577 (emit-indent *(ebp+8) *Curr-block-depth) -12578 (write-buffered *(ebp+8) "ff 6/subop/push %") -12579 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax -12580 (write-buffered *(ebp+8) %eax) -12581 (write-buffered *(ebp+8) Newline) -12582 $push-output-and-maybe-emit-spill:push: -12583 8b/-> *(ebp+0xc) 1/r32/ecx -12584 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax -12585 # push(vars, {sv->value, emit-spill?}) -12586 (push *(ebp+0x10) *eax) # Stmt-var-value -12587 (push *(ebp+0x10) *(eax+4)) # Stmt-var-value -12588 (push *(ebp+0x10) %edx) -12589 $push-output-and-maybe-emit-spill:end: -12590 # . restore registers -12591 5a/pop-to-edx -12592 59/pop-to-ecx -12593 58/pop-to-eax -12594 # . epilogue -12595 89/<- %esp 5/r32/ebp -12596 5d/pop-to-ebp -12597 c3/return -12598 -12599 $push-output-and-maybe-emit-spill:abort: -12600 # error("var '" var->name "' initialized from an instruction must live in a register\n") -12601 (write-buffered *(ebp+0x1c) "var '") -12602 (write-buffered *(ebp+0x1c) *eax) # Var-name -12603 (write-buffered *(ebp+0x1c) "' initialized from an instruction must live in a register\n") -12604 (flush *(ebp+0x1c)) -12605 (stop *(ebp+0x20) 1) -12606 # never gets here -12607 -12608 emit-subx-cleanup-and-unconditional-nonlocal-branch: # out: (addr buffered-file), stmt: (addr stmt1), vars: (addr stack live-var) -12609 # . prologue -12610 55/push-ebp -12611 89/<- %ebp 4/r32/esp -12612 # . save registers -12613 50/push-eax -12614 51/push-ecx -12615 # ecx = stmt -12616 8b/-> *(ebp+0xc) 1/r32/ecx -12617 # var target/eax: (addr array byte) = curr-stmt->inouts->value->name -12618 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12619 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12620 (lookup *eax *(eax+4)) # Var-name Var-name => eax -12621 # clean up until target block -12622 (emit-cleanup-code-until-target *(ebp+8) *(ebp+0x10) %eax) -12623 # emit jump to target block -12624 (emit-indent *(ebp+8) *Curr-block-depth) -12625 (write-buffered *(ebp+8) "e9/jump ") -12626 (write-buffered *(ebp+8) %eax) -12627 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -12628 (string-starts-with? %eax "break") -12629 3d/compare-eax-and 0/imm32/false -12630 { -12631 74/jump-if-= break/disp8 -12632 (write-buffered *(ebp+8) ":break/disp32\n") -12633 } -12634 3d/compare-eax-and 0/imm32/false # just in case the function call modified flags -12635 { -12636 75/jump-if-!= break/disp8 -12637 (write-buffered *(ebp+8) ":loop/disp32\n") -12638 } -12639 $emit-subx-cleanup-and-unconditional-nonlocal-branch:end: -12640 # . restore registers -12641 59/pop-to-ecx -12642 58/pop-to-eax -12643 # . epilogue -12644 89/<- %esp 5/r32/ebp -12645 5d/pop-to-ebp -12646 c3/return -12647 -12648 is-mu-branch?: # stmt: (addr stmt1) -> result/eax: boolean -12649 # . prologue -12650 55/push-ebp -12651 89/<- %ebp 4/r32/esp -12652 # . save registers -12653 51/push-ecx -12654 # ecx = lookup(stmt->operation) -12655 8b/-> *(ebp+8) 1/r32/ecx -12656 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -12657 89/<- %ecx 0/r32/eax -12658 # if (stmt->operation starts with "loop") return true -12659 (string-starts-with? %ecx "loop") # => eax -12660 3d/compare-eax-and 0/imm32/false -12661 75/jump-if-not-equal $is-mu-branch?:end/disp8 -12662 # otherwise return (stmt->operation starts with "break") -12663 (string-starts-with? %ecx "break") # => eax -12664 $is-mu-branch?:end: -12665 # . restore registers -12666 59/pop-to-ecx -12667 # . epilogue -12668 89/<- %esp 5/r32/ebp -12669 5d/pop-to-ebp -12670 c3/return -12671 -12672 emit-reverse-break: # out: (addr buffered-file), stmt: (addr stmt1) -12673 # . prologue -12674 55/push-ebp -12675 89/<- %ebp 4/r32/esp -12676 # . save registers -12677 50/push-eax -12678 # eax = stmt -12679 8b/-> *(ebp+0xc) 0/r32/eax -12680 # -12681 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -12682 (get Reverse-branch %eax 0x10 "reverse-branch: ") # => eax: (addr handle array byte) -12683 (emit-indent *(ebp+8) *Curr-block-depth) -12684 (lookup *eax *(eax+4)) # => eax -12685 (write-buffered *(ebp+8) %eax) -12686 (write-buffered *(ebp+8) " break/disp32\n") -12687 $emit-reverse-break:end: -12688 # . restore registers -12689 58/pop-to-eax -12690 # . epilogue -12691 89/<- %esp 5/r32/ebp -12692 5d/pop-to-ebp -12693 c3/return -12694 -12695 == data -12696 -12697 # Table from Mu branch instructions to the reverse SubX opcodes for them. -12698 Reverse-branch: # (table (handle array byte) (handle array byte)) -12699 # a table is a stream -12700 0x140/imm32/write -12701 0/imm32/read -12702 0x140/imm32/size -12703 # data -12704 0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 -12705 0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 -12706 0x11/imm32/alloc-id _string-break-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 -12707 0x11/imm32/alloc-id _string-loop-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 -12708 0x11/imm32/alloc-id _string-break-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 -12709 0x11/imm32/alloc-id _string-loop-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 -12710 0x11/imm32/alloc-id _string-break-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 -12711 0x11/imm32/alloc-id _string-loop-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 -12712 0x11/imm32/alloc-id _string-break-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -12713 0x11/imm32/alloc-id _string-loop-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -12714 0x11/imm32/alloc-id _string-break-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 -12715 0x11/imm32/alloc-id _string-loop-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 -12716 0x11/imm32/alloc-id _string-break-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 -12717 0x11/imm32/alloc-id _string-loop-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 -12718 0x11/imm32/alloc-id _string-break-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 -12719 0x11/imm32/alloc-id _string-loop-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 -12720 0x11/imm32/alloc-id _string-break-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -12721 0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -12722 0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 -12723 0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 -12724 -12725 == code -12726 -12727 emit-unconditional-jump-to-depth: # out: (addr buffered-file), vars: (addr stack live-var), depth: int, label-suffix: (addr array byte) -12728 # . prologue -12729 55/push-ebp -12730 89/<- %ebp 4/r32/esp -12731 # . save registers -12732 50/push-eax -12733 51/push-ecx -12734 52/push-edx -12735 53/push-ebx -12736 56/push-esi -12737 # ecx = vars -12738 8b/-> *(ebp+0xc) 1/r32/ecx -12739 # var eax: int = vars->top -12740 8b/-> *ecx 0/r32/eax -12741 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] -12742 8d/copy-address *(ecx+eax-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size -12743 # var min/ecx: (addr handle var) = vars->data -12744 8d/copy-address *(ecx+8) 1/r32/ecx -12745 # edx = depth -12746 8b/-> *(ebp+0x10) 2/r32/edx -12747 { -12748 $emit-unconditional-jump-to-depth:loop: -12749 # if (curr < min) break -12750 39/compare %esi 1/r32/ecx -12751 0f 82/jump-if-addr< break/disp32 -12752 # var v/ebx: (addr var) = lookup(*curr) -12753 (lookup *esi *(esi+4)) # => eax -12754 89/<- %ebx 0/r32/eax -12755 # if (v->block-depth < until-block-depth) break -12756 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -12757 0f 8c/jump-if-< break/disp32 -12758 { -12759 $emit-unconditional-jump-to-depth:check: -12760 # if v->block-depth != until-block-depth, continue -12761 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -12762 0f 85/jump-if-!= break/disp32 -12763 $emit-unconditional-jump-to-depth:depth-found: -12764 # if v is not a literal, continue -12765 (size-of %ebx) # => eax -12766 3d/compare-eax-and 0/imm32 -12767 0f 85/jump-if-!= break/disp32 -12768 $emit-unconditional-jump-to-depth:label-found: -12769 # emit unconditional jump, then return -12770 (emit-indent *(ebp+8) *Curr-block-depth) -12771 (write-buffered *(ebp+8) "e9/jump ") -12772 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -12773 (write-buffered *(ebp+8) %eax) -12774 (write-buffered *(ebp+8) ":") -12775 (write-buffered *(ebp+8) *(ebp+0x14)) -12776 (write-buffered *(ebp+8) "/disp32\n") -12777 eb/jump $emit-unconditional-jump-to-depth:end/disp8 -12778 } -12779 # curr -= 12 -12780 81 5/subop/subtract %esi 0xc/imm32 -12781 e9/jump loop/disp32 -12782 } -12783 # TODO: error if no label at 'depth' was found -12784 $emit-unconditional-jump-to-depth:end: -12785 # . restore registers -12786 5e/pop-to-esi -12787 5b/pop-to-ebx -12788 5a/pop-to-edx -12789 59/pop-to-ecx -12790 58/pop-to-eax -12791 # . epilogue -12792 89/<- %esp 5/r32/ebp -12793 5d/pop-to-ebp -12794 c3/return -12795 -12796 # emit clean-up code for 'vars' until some block depth -12797 # doesn't actually modify 'vars' so we need traverse manually inside the stack -12798 emit-cleanup-code-until-depth: # out: (addr buffered-file), vars: (addr stack live-var), until-block-depth: int -12799 # . prologue -12800 55/push-ebp -12801 89/<- %ebp 4/r32/esp -12802 # . save registers -12803 50/push-eax -12804 51/push-ecx -12805 52/push-edx -12806 53/push-ebx -12807 56/push-esi -12808 #? (write-buffered Stderr "--- cleanup\n") -12809 #? (flush Stderr) -12810 # ecx = vars -12811 8b/-> *(ebp+0xc) 1/r32/ecx -12812 # var esi: int = vars->top -12813 8b/-> *ecx 6/r32/esi -12814 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] -12815 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size -12816 # var min/ecx: (addr handle var) = vars->data -12817 81 0/subop/add %ecx 8/imm32 -12818 # edx = until-block-depth -12819 8b/-> *(ebp+0x10) 2/r32/edx -12820 { -12821 $emit-cleanup-code-until-depth:loop: -12822 # if (curr < min) break -12823 39/compare %esi 1/r32/ecx -12824 0f 82/jump-if-addr< break/disp32 -12825 # var v/ebx: (addr var) = lookup(*curr) -12826 (lookup *esi *(esi+4)) # => eax -12827 89/<- %ebx 0/r32/eax -12828 #? (lookup *ebx *(ebx+4)) # Var-name -12829 #? (write-buffered Stderr "var ") -12830 #? (write-buffered Stderr %eax) -12831 #? (write-buffered Stderr Newline) -12832 #? (flush Stderr) -12833 # if (v->block-depth < until-block-depth) break -12834 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -12835 0f 8c/jump-if-< break/disp32 -12836 # if v is in a register -12837 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register -12838 { -12839 0f 84/jump-if-= break/disp32 -12840 { -12841 $emit-cleanup-code-until-depth:check-for-previous-spill: -12842 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled -12843 3d/compare-eax-and 0/imm32/false -12844 74/jump-if-= break/disp8 -12845 $emit-cleanup-code-until-depth:reclaim-var-in-register: -12846 (emit-indent *(ebp+8) *Curr-block-depth) -12847 (write-buffered *(ebp+8) "8f 0/subop/pop %") -12848 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -12849 (write-buffered *(ebp+8) %eax) -12850 (write-buffered *(ebp+8) Newline) -12851 } -12852 eb/jump $emit-cleanup-code-until-depth:continue/disp8 -12853 } -12854 # otherwise v is on the stack -12855 { -12856 75/jump-if-!= break/disp8 -12857 $emit-cleanup-code-until-depth:var-on-stack: -12858 (size-of %ebx) # => eax -12859 # don't emit code for labels -12860 3d/compare-eax-and 0/imm32 -12861 74/jump-if-= break/disp8 -12862 $emit-cleanup-code-until-depth:reclaim-var-on-stack: -12863 (emit-indent *(ebp+8) *Curr-block-depth) -12864 (write-buffered *(ebp+8) "81 0/subop/add %esp ") -12865 (write-int32-hex-buffered *(ebp+8) %eax) -12866 (write-buffered *(ebp+8) "/imm32\n") -12867 } -12868 $emit-cleanup-code-until-depth:continue: -12869 # curr -= 12 -12870 81 5/subop/subtract %esi 0xc/imm32 -12871 e9/jump loop/disp32 -12872 } -12873 $emit-cleanup-code-until-depth:end: -12874 # . restore registers -12875 5e/pop-to-esi -12876 5b/pop-to-ebx -12877 5a/pop-to-edx -12878 59/pop-to-ecx -12879 58/pop-to-eax -12880 # . epilogue -12881 89/<- %esp 5/r32/ebp -12882 5d/pop-to-ebp -12883 c3/return -12884 -12885 # emit clean-up code for 'vars' until a given label is encountered -12886 # doesn't actually modify 'vars' so we need traverse manually inside the stack -12887 emit-cleanup-code-until-target: # out: (addr buffered-file), vars: (addr stack live-var), until-block-label: (addr array byte) -12888 # . prologue -12889 55/push-ebp -12890 89/<- %ebp 4/r32/esp -12891 # . save registers -12892 50/push-eax -12893 51/push-ecx -12894 52/push-edx -12895 53/push-ebx -12896 # ecx = vars -12897 8b/-> *(ebp+0xc) 1/r32/ecx -12898 # var eax: int = vars->top -12899 8b/-> *ecx 0/r32/eax -12900 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] -12901 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size -12902 # var min/ecx: (addr handle var) = vars->data -12903 81 0/subop/add %ecx 8/imm32 -12904 { -12905 $emit-cleanup-code-until-target:loop: -12906 # if (curr < min) break -12907 39/compare %edx 1/r32/ecx -12908 0f 82/jump-if-addr< break/disp32 -12909 # var v/ebx: (handle var) = lookup(*curr) -12910 (lookup *edx *(edx+4)) # => eax -12911 89/<- %ebx 0/r32/eax -12912 # if (v->name == until-block-label) break -12913 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -12914 (string-equal? %eax *(ebp+0x10)) # => eax -12915 3d/compare-eax-and 0/imm32/false -12916 0f 85/jump-if-!= break/disp32 -12917 # if v is in a register -12918 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register -12919 { -12920 0f 84/jump-if-= break/disp32 -12921 { -12922 $emit-cleanup-code-until-target:check-for-previous-spill: -12923 8b/-> *(edx+8) 0/r32/eax # Live-var-register-spilled -12924 3d/compare-eax-and 0/imm32/false -12925 74/jump-if-= break/disp8 -12926 $emit-cleanup-code-until-target:reclaim-var-in-register: -12927 (emit-indent *(ebp+8) *Curr-block-depth) -12928 (write-buffered *(ebp+8) "8f 0/subop/pop %") -12929 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -12930 (write-buffered *(ebp+8) %eax) -12931 (write-buffered *(ebp+8) Newline) -12932 } -12933 eb/jump $emit-cleanup-code-until-target:continue/disp8 -12934 } -12935 # otherwise v is on the stack -12936 { -12937 75/jump-if-!= break/disp8 -12938 $emit-cleanup-code-until-target:reclaim-var-on-stack: -12939 (size-of %ebx) # => eax -12940 # don't emit code for labels -12941 3d/compare-eax-and 0/imm32 -12942 74/jump-if-= break/disp8 -12943 # -12944 (emit-indent *(ebp+8) *Curr-block-depth) -12945 (write-buffered *(ebp+8) "81 0/subop/add %esp ") -12946 (write-int32-hex-buffered *(ebp+8) %eax) -12947 (write-buffered *(ebp+8) "/imm32\n") -12948 } -12949 $emit-cleanup-code-until-target:continue: -12950 # curr -= 12 -12951 81 5/subop/subtract %edx 0xc/imm32 -12952 e9/jump loop/disp32 -12953 } -12954 $emit-cleanup-code-until-target:end: -12955 # . restore registers -12956 5b/pop-to-ebx -12957 5a/pop-to-edx -12958 59/pop-to-ecx -12959 58/pop-to-eax -12960 # . epilogue -12961 89/<- %esp 5/r32/ebp -12962 5d/pop-to-ebp -12963 c3/return -12964 -12965 # Return true if there isn't a variable in 'vars' with the same block-depth -12966 # and register as 'v'. -12967 # 'v' is guaranteed not to be within 'vars'. -12968 not-yet-spilled-this-block?: # v: (addr var), vars: (addr stack live-var) -> result/eax: boolean -12969 # . prologue -12970 55/push-ebp -12971 89/<- %ebp 4/r32/esp -12972 # . save registers -12973 51/push-ecx -12974 52/push-edx -12975 53/push-ebx -12976 56/push-esi -12977 57/push-edi -12978 # ecx = vars -12979 8b/-> *(ebp+0xc) 1/r32/ecx -12980 # var eax: int = vars->top -12981 8b/-> *ecx 0/r32/eax -12982 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] -12983 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size -12984 # var min/ecx: (addr handle var) = vars->data -12985 8d/copy-address *(ecx+8) 1/r32/ecx -12986 # var depth/ebx: int = v->block-depth -12987 8b/-> *(ebp+8) 3/r32/ebx -12988 8b/-> *(ebx+0x10) 3/r32/ebx # Var-block-depth -12989 # var needle/esi: (addr array byte) = v->register -12990 8b/-> *(ebp+8) 6/r32/esi -12991 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -12992 89/<- %esi 0/r32/eax -12993 { -12994 $not-yet-spilled-this-block?:loop: -12995 # if (curr < min) break -12996 39/compare %edx 1/r32/ecx -12997 0f 82/jump-if-addr< break/disp32 -12998 # var cand/edi: (addr var) = lookup(*curr) -12999 (lookup *edx *(edx+4)) # => eax -13000 89/<- %edi 0/r32/eax -13001 # if (cand->block-depth < depth) break -13002 39/compare *(edi+0x10) 3/r32/ebx # Var-block-depth -13003 0f 8c/jump-if-< break/disp32 -13004 # var cand-reg/edi: (array array byte) = cand->reg -13005 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -13006 89/<- %edi 0/r32/eax -13007 # if (cand-reg == null) continue -13008 { -13009 $not-yet-spilled-this-block?:check-reg: -13010 81 7/subop/compare %edi 0/imm32 -13011 0f 84/jump-if-= break/disp32 -13012 # if (cand-reg == needle) return true -13013 (string-equal? %esi %edi) # => eax -13014 3d/compare-eax-and 0/imm32/false -13015 74/jump-if-= break/disp8 -13016 $not-yet-spilled-this-block?:return-false: -13017 b8/copy-to-eax 0/imm32/false -13018 eb/jump $not-yet-spilled-this-block?:end/disp8 -13019 } -13020 $not-yet-spilled-this-block?:continue: -13021 # curr -= 12 -13022 81 5/subop/subtract %edx 0xc/imm32 -13023 e9/jump loop/disp32 -13024 } -13025 $not-yet-spilled-this-block?:return-true: -13026 # return true -13027 b8/copy-to-eax 1/imm32/true -13028 $not-yet-spilled-this-block?:end: -13029 # . restore registers -13030 5f/pop-to-edi -13031 5e/pop-to-esi -13032 5b/pop-to-ebx -13033 5a/pop-to-edx -13034 59/pop-to-ecx -13035 # . epilogue -13036 89/<- %esp 5/r32/ebp -13037 5d/pop-to-ebp -13038 c3/return -13039 -13040 # could the register of 'v' ever be written to by one of the vars in fn-outputs? -13041 will-not-write-some-register?: # v: (addr var), stmts: (addr list stmt), fn: (addr function) -> result/eax: boolean -13042 # . prologue -13043 55/push-ebp -13044 89/<- %ebp 4/r32/esp -13045 # eax = v -13046 8b/-> *(ebp+8) 0/r32/eax -13047 # var reg/eax: (addr array byte) = lookup(v->register) -13048 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -13049 # var target/eax: (addr var) = find-register(fn-outputs, reg) -13050 (find-register *(ebp+0x10) %eax) # => eax -13051 # if (target == 0) return true -13052 { +12500 # if (expected == 0) error("too few inouts") +12501 { +12502 81 7/subop/compare %edx 0/imm32 +12503 0f 84/jump-if-= break/disp32 +12504 (write-buffered *(ebp+0x14) "fn ") +12505 8b/-> *(ebp+0x10) 0/r32/eax +12506 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12507 (write-buffered *(ebp+0x14) %eax) +12508 (write-buffered *(ebp+0x14) ": call ") +12509 (lookup *edi *(edi+4)) # Function-name Function-name => eax +12510 (write-buffered *(ebp+0x14) %eax) +12511 (write-buffered *(ebp+0x14) ": too few inouts\n") +12512 (flush *(ebp+0x14)) +12513 (stop *(ebp+0x18) 1) +12514 } +12515 } +12516 $check-mu-call:check-outputs: +12517 # var outputs/ecx: (addr stmt-var) = lookup(stmt->outputs) +12518 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +12519 89/<- %ecx 0/r32/eax +12520 # var expected/edx: (addr list var) = lookup(f->outputs) +12521 (lookup *(edi+0x10) *(edi+0x14)) # Function-outputs Function-outputs => eax +12522 89/<- %edx 0/r32/eax +12523 { +12524 $check-mu-call:check-for-outputs: +12525 # if (outputs == 0) break +12526 81 7/subop/compare %ecx 0/imm32 +12527 0f 84/jump-if-= break/disp32 +12528 # if (expected == 0) error +12529 81 7/subop/compare %edx 0/imm32 +12530 0f 84/jump-if-= break/disp32 +12531 $check-mu-call:check-output-type: +12532 # var v/eax: (addr v) = lookup(outputs->value) +12533 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +12534 # var t/ebx: (addr type-tree) = lookup(v->type) +12535 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +12536 89/<- %ebx 0/r32/eax +12537 # if (outputs->is-deref?) t = t->right # TODO: check that t->left is an addr +12538 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +12539 { +12540 74/jump-if-= break/disp8 +12541 (lookup *(ebx+0xc) *(ebx+0x10)) # Type-tree-right Type-tree-right => eax +12542 89/<- %ebx 0/r32/eax +12543 } +12544 # var v2/eax: (addr v) = lookup(expected->value) +12545 (lookup *edx *(edx+4)) # List-value List-value => eax +12546 # var t2/eax: (addr type-tree) = lookup(v2->type) +12547 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +12548 # if (t != t2) error +12549 (type-match? %eax %ebx *(ebp-4)) # => eax +12550 3d/compare-eax-and 0/imm32/false +12551 { +12552 0f 85/jump-if-!= break/disp32 +12553 (write-buffered *(ebp+0x14) "fn ") +12554 8b/-> *(ebp+0x10) 0/r32/eax +12555 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12556 (write-buffered *(ebp+0x14) %eax) +12557 (write-buffered *(ebp+0x14) ": call ") +12558 (lookup *edi *(edi+4)) # Function-name Function-name => eax +12559 (write-buffered *(ebp+0x14) %eax) +12560 (write-buffered *(ebp+0x14) ": type for output '") +12561 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +12562 (lookup *eax *(eax+4)) # Var-name Var-name => eax +12563 (write-buffered *(ebp+0x14) %eax) +12564 (write-buffered *(ebp+0x14) "' is not right\n") +12565 (flush *(ebp+0x14)) +12566 (stop *(ebp+0x18) 1) +12567 } +12568 $check-mu-call:check-output-register: +12569 # var v/eax: (addr v) = lookup(outputs->value) +12570 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +12571 # var r/ebx: (addr array byte) = lookup(v->register) +12572 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax +12573 89/<- %ebx 0/r32/eax +12574 # var v2/eax: (addr v) = lookup(expected->value) +12575 (lookup *edx *(edx+4)) # Stmt-var-value Stmt-var-value => eax +12576 # var r2/eax: (addr array byte) = lookup(v2->register) +12577 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax +12578 # if (r != r2) error +12579 (string-equal? %eax %ebx) # => eax +12580 3d/compare-eax-and 0/imm32/false +12581 { +12582 0f 85/jump-if-!= break/disp32 +12583 (write-buffered *(ebp+0x14) "fn ") +12584 8b/-> *(ebp+0x10) 0/r32/eax +12585 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12586 (write-buffered *(ebp+0x14) %eax) +12587 (write-buffered *(ebp+0x14) ": call ") +12588 (lookup *edi *(edi+4)) # Function-name Function-name => eax +12589 (write-buffered *(ebp+0x14) %eax) +12590 (write-buffered *(ebp+0x14) ": register for output '") +12591 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +12592 (lookup *eax *(eax+4)) # Var-name Var-name => eax +12593 (write-buffered *(ebp+0x14) %eax) +12594 (write-buffered *(ebp+0x14) "' is not right\n") +12595 (flush *(ebp+0x14)) +12596 (stop *(ebp+0x18) 1) +12597 } +12598 $check-mu-call:continue-to-next-output: +12599 # outputs = lookup(outputs->next) +12600 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +12601 89/<- %ecx 0/r32/eax +12602 # expected = lookup(expected->next) +12603 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +12604 89/<- %edx 0/r32/eax +12605 # +12606 e9/jump loop/disp32 +12607 } +12608 $check-mu-call:check-output-count: +12609 # if (outputs == expected) proceed +12610 39/compare %ecx 2/r32/edx +12611 { +12612 0f 84/jump-if-= break/disp32 +12613 # exactly one of the two is null +12614 # if (outputs == 0) error("too many outputs") +12615 { +12616 81 7/subop/compare %ecx 0/imm32 +12617 0f 84/jump-if-= break/disp32 +12618 (write-buffered *(ebp+0x14) "fn ") +12619 8b/-> *(ebp+0x10) 0/r32/eax +12620 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12621 (write-buffered *(ebp+0x14) %eax) +12622 (write-buffered *(ebp+0x14) ": call ") +12623 (lookup *edi *(edi+4)) # Function-name Function-name => eax +12624 (write-buffered *(ebp+0x14) %eax) +12625 (write-buffered *(ebp+0x14) ": too many outputs\n") +12626 (flush *(ebp+0x14)) +12627 (stop *(ebp+0x18) 1) +12628 } +12629 # if (expected == 0) error("too few outputs") +12630 { +12631 81 7/subop/compare %edx 0/imm32 +12632 0f 84/jump-if-= break/disp32 +12633 (write-buffered *(ebp+0x14) "fn ") +12634 8b/-> *(ebp+0x10) 0/r32/eax +12635 (lookup *eax *(eax+4)) # Function-name Function-name => eax +12636 (write-buffered *(ebp+0x14) %eax) +12637 (write-buffered *(ebp+0x14) ": call ") +12638 (lookup *edi *(edi+4)) # Function-name Function-name => eax +12639 (write-buffered *(ebp+0x14) %eax) +12640 (write-buffered *(ebp+0x14) ": too few outputs\n") +12641 (flush *(ebp+0x14)) +12642 (stop *(ebp+0x18) 1) +12643 } +12644 } +12645 $check-mu-call:end: +12646 # . restore registers +12647 5f/pop-to-edi +12648 5e/pop-to-esi +12649 5b/pop-to-ebx +12650 5a/pop-to-edx +12651 59/pop-to-ecx +12652 58/pop-to-eax +12653 # . reclaim locals exclusively on the stack +12654 81 0/subop/add %esp 0x70/imm32 +12655 # . epilogue +12656 89/<- %esp 5/r32/ebp +12657 5d/pop-to-ebp +12658 c3/return +12659 +12660 # like type-equal? but takes literals into account +12661 type-match?: # def: (addr type-tree), call: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean +12662 # . prologue +12663 55/push-ebp +12664 89/<- %ebp 4/r32/esp +12665 # if (call == literal) return true # TODO: more precise +12666 (is-simple-mu-type? *(ebp+0xc) 0) # literal => eax +12667 3d/compare-eax-and 0/imm32/false +12668 b8/copy-to-eax 1/imm32/true +12669 75/jump-if-!= $type-match?:end/disp8 +12670 $type-match?:baseline: +12671 # otherwise fall back +12672 (type-component-match? *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax +12673 $type-match?:end: +12674 # . epilogue +12675 89/<- %esp 5/r32/ebp +12676 5d/pop-to-ebp +12677 c3/return +12678 +12679 type-component-match?: # def: (addr type-tree), call: (addr type-tree), type-parameters: (addr table (handle array byte) (addr type-tree)) -> result/eax: boolean +12680 # . prologue +12681 55/push-ebp +12682 89/<- %ebp 4/r32/esp +12683 # . save registers +12684 51/push-ecx +12685 52/push-edx +12686 53/push-ebx +12687 # ecx = def +12688 8b/-> *(ebp+8) 1/r32/ecx +12689 # edx = call +12690 8b/-> *(ebp+0xc) 2/r32/edx +12691 $type-component-match?:compare-addr: +12692 # if (def == call) return true +12693 8b/-> %ecx 0/r32/eax # Var-type +12694 39/compare %edx 0/r32/eax # Var-type +12695 b8/copy-to-eax 1/imm32/true +12696 0f 84/jump-if-= $type-component-match?:end/disp32 +12697 # if def is a type parameter, return true +12698 { +12699 $type-component-match?:check-type-parameter: +12700 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +12701 74/jump-if-= break/disp8 +12702 81 7/subop/compare *(ecx+4) 0xa/imm32/type-parameter # Type-tree-value +12703 75/jump-if-!= break/disp8 +12704 $type-component-match?:type-parameter: +12705 (type-parameter-match? *(ecx+8) *(ecx+0xc) %edx *(ebp+0x10)) # => eax +12706 e9/jump $type-component-match?:end/disp32 +12707 } +12708 $type-component-match?:compare-atom-state: +12709 # if (def->is-atom? != call->is-atom?) return false +12710 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom +12711 39/compare *edx 3/r32/ebx # Type-tree-is-atom +12712 b8/copy-to-eax 0/imm32/false +12713 0f 85/jump-if-!= $type-component-match?:end/disp32 +12714 # if def->is-atom? return (def->value == call->value) +12715 { +12716 $type-component-match?:check-atom: +12717 81 7/subop/compare %ebx 0/imm32/false +12718 74/jump-if-= break/disp8 +12719 $type-component-match?:is-atom: +12720 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value +12721 39/compare *(edx+4) 0/r32/eax # Type-tree-value +12722 0f 94/set-if-= %al +12723 81 4/subop/and %eax 0xff/imm32 +12724 e9/jump $type-component-match?:end/disp32 +12725 } +12726 $type-component-match?:check-left: +12727 # if (!type-component-match?(def->left, call->left)) return false +12728 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +12729 89/<- %ebx 0/r32/eax +12730 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +12731 (type-component-match? %ebx %eax *(ebp+0x10)) # => eax +12732 3d/compare-eax-and 0/imm32/false +12733 74/jump-if-= $type-component-match?:end/disp8 +12734 $type-component-match?:check-right: +12735 # return type-component-match?(def->right, call->right) +12736 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +12737 89/<- %ebx 0/r32/eax +12738 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax +12739 (type-component-match? %ebx %eax *(ebp+0x10)) # => eax +12740 $type-component-match?:end: +12741 # . restore registers +12742 5b/pop-to-ebx +12743 5a/pop-to-edx +12744 59/pop-to-ecx +12745 # . epilogue +12746 89/<- %esp 5/r32/ebp +12747 5d/pop-to-ebp +12748 c3/return +12749 +12750 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 +12751 # . prologue +12752 55/push-ebp +12753 89/<- %ebp 4/r32/esp +12754 # . save registers +12755 51/push-ecx +12756 # +12757 (get-or-insert-handle *(ebp+0x14) *(ebp+8) *(ebp+0xc) 0xc) # => eax +12758 # if parameter wasn't saved, save it +12759 { +12760 81 7/subop/compare *eax 0/imm32 +12761 75/jump-if-!= break/disp8 +12762 8b/-> *(ebp+0x10) 1/r32/ecx +12763 89/<- *eax 1/r32/ecx +12764 } +12765 # +12766 (type-equal? *(ebp+0x10) *eax) # => eax +12767 $type-parameter-match?:end: +12768 # . restore registers +12769 59/pop-to-ecx +12770 # . epilogue +12771 89/<- %esp 5/r32/ebp +12772 5d/pop-to-ebp +12773 c3/return +12774 +12775 size-of: # v: (addr var) -> result/eax: int +12776 # . prologue +12777 55/push-ebp +12778 89/<- %ebp 4/r32/esp +12779 # . save registers +12780 51/push-ecx +12781 # var t/ecx: (addr type-tree) = lookup(v->type) +12782 8b/-> *(ebp+8) 1/r32/ecx +12783 #? (write-buffered Stderr "size-of ") +12784 #? (write-int32-hex-buffered Stderr %ecx) +12785 #? (write-buffered Stderr Newline) +12786 #? (write-buffered Stderr "type allocid: ") +12787 #? (write-int32-hex-buffered Stderr *(ecx+8)) +12788 #? (write-buffered Stderr Newline) +12789 #? (flush Stderr) +12790 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +12791 89/<- %ecx 0/r32/eax +12792 # if is-mu-array?(t) return size-of-array(t) +12793 { +12794 (is-mu-array? %ecx) # => eax +12795 3d/compare-eax-and 0/imm32/false +12796 74/jump-if-= break/disp8 +12797 (size-of-array %ecx) # => eax +12798 eb/jump $size-of:end/disp8 +12799 } +12800 # if (!t->is-atom?) t = lookup(t->left) +12801 { +12802 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +12803 75/jump-if-!= break/disp8 +12804 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +12805 89/<- %ecx 0/r32/eax +12806 } +12807 # TODO: assert t->is-atom? +12808 (size-of-type-id *(ecx+4)) # Type-tree-value => eax +12809 $size-of:end: +12810 # . restore registers +12811 59/pop-to-ecx +12812 # . epilogue +12813 89/<- %esp 5/r32/ebp +12814 5d/pop-to-ebp +12815 c3/return +12816 +12817 size-of-deref: # v: (addr var) -> result/eax: int +12818 # . prologue +12819 55/push-ebp +12820 89/<- %ebp 4/r32/esp +12821 # . save registers +12822 51/push-ecx +12823 # var t/ecx: (addr type-tree) = lookup(v->type) +12824 8b/-> *(ebp+8) 1/r32/ecx +12825 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +12826 89/<- %ecx 0/r32/eax +12827 # TODO: assert(t is an addr) +12828 # t = lookup(t->right) +12829 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +12830 89/<- %ecx 0/r32/eax +12831 # if is-mu-array?(t) return size-of-array(t) +12832 { +12833 (is-mu-array? %ecx) # => eax +12834 3d/compare-eax-and 0/imm32/false +12835 74/jump-if-= break/disp8 +12836 (size-of-array %ecx) # => eax +12837 eb/jump $size-of:end/disp8 +12838 } +12839 # if (!t->is-atom?) t = lookup(t->left) +12840 { +12841 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +12842 75/jump-if-!= break/disp8 +12843 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +12844 89/<- %ecx 0/r32/eax +12845 } +12846 # TODO: assert t->is-atom? +12847 (size-of-type-id *(ecx+4)) # Type-tree-value => eax +12848 $size-of-deref:end: +12849 # . restore registers +12850 59/pop-to-ecx +12851 # . epilogue +12852 89/<- %esp 5/r32/ebp +12853 5d/pop-to-ebp +12854 c3/return +12855 +12856 is-mu-array?: # t: (addr type-tree) -> result/eax: boolean +12857 # . prologue +12858 55/push-ebp +12859 89/<- %ebp 4/r32/esp +12860 # . save registers +12861 51/push-ecx +12862 # ecx = t +12863 8b/-> *(ebp+8) 1/r32/ecx +12864 # if t->is-atom?, return false +12865 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom +12866 75/jump-if-!= $is-mu-array?:return-false/disp8 +12867 # if !t->left->is-atom?, return false +12868 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +12869 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +12870 74/jump-if-= $is-mu-array?:return-false/disp8 +12871 # return t->left->value == array +12872 81 7/subop/compare *(eax+4) 3/imm32/array-type-id # Type-tree-value +12873 0f 94/set-if-= %al +12874 81 4/subop/and %eax 0xff/imm32 +12875 eb/jump $is-mu-array?:end/disp8 +12876 $is-mu-array?:return-false: +12877 b8/copy-to-eax 0/imm32/false +12878 $is-mu-array?:end: +12879 # . restore registers +12880 59/pop-to-ecx +12881 # . epilogue +12882 89/<- %esp 5/r32/ebp +12883 5d/pop-to-ebp +12884 c3/return +12885 +12886 size-of-array: # a: (addr type-tree) -> result/eax: int +12887 # . prologue +12888 55/push-ebp +12889 89/<- %ebp 4/r32/esp +12890 # . save registers +12891 51/push-ecx +12892 52/push-edx +12893 # +12894 8b/-> *(ebp+8) 1/r32/ecx +12895 # TODO: assert that a->left is 'array' +12896 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +12897 89/<- %ecx 0/r32/eax +12898 # var elem-type/edx: type-id = a->right->left->value +12899 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +12900 8b/-> *(eax+4) 2/r32/edx # Type-tree-value +12901 # TODO: assert that a->right->right->left->value == size +12902 # var array-size/ecx: int = a->right->right->left->value-size +12903 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +12904 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +12905 8b/-> *(eax+8) 1/r32/ecx # Type-tree-value-size +12906 # return array-size * size-of(elem-type) +12907 (size-of-type-id-as-array-element %edx) # => eax +12908 f7 4/subop/multiply-into-eax %ecx +12909 05/add-to-eax 4/imm32 # for array size +12910 $size-of-array:end: +12911 # . restore registers +12912 5a/pop-to-edx +12913 59/pop-to-ecx +12914 # . epilogue +12915 89/<- %esp 5/r32/ebp +12916 5d/pop-to-ebp +12917 c3/return +12918 +12919 size-of-type-id: # t: type-id -> result/eax: int +12920 # . prologue +12921 55/push-ebp +12922 89/<- %ebp 4/r32/esp +12923 # . save registers +12924 51/push-ecx +12925 # var out/ecx: (handle typeinfo) +12926 68/push 0/imm32 +12927 68/push 0/imm32 +12928 89/<- %ecx 4/r32/esp +12929 # eax = t +12930 8b/-> *(ebp+8) 0/r32/eax +12931 # if t is a literal, return 0 +12932 3d/compare-eax-and 0/imm32 +12933 0f 84/jump-if-= $size-of-type-id:end/disp32 # eax changes type from type-id to int +12934 # if t is a byte, return 4 (because we don't really support non-multiples of 4) +12935 3d/compare-eax-and 8/imm32/byte +12936 { +12937 75/jump-if-!= break/disp8 +12938 b8/copy-to-eax 4/imm32 +12939 eb/jump $size-of-type-id:end/disp8 +12940 } +12941 # if t is a handle, return 8 +12942 3d/compare-eax-and 4/imm32/handle +12943 { +12944 75/jump-if-!= break/disp8 +12945 b8/copy-to-eax 8/imm32 +12946 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int +12947 } +12948 # if t is a user-defined type, return its size +12949 # TODO: support non-atom type +12950 (find-typeinfo %eax %ecx) +12951 { +12952 81 7/subop/compare *ecx 0/imm32 +12953 74/jump-if-= break/disp8 +12954 $size-of-type-id:user-defined: +12955 (lookup *ecx *(ecx+4)) # => eax +12956 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes +12957 eb/jump $size-of-type-id:end/disp8 +12958 } +12959 # otherwise return the word size +12960 b8/copy-to-eax 4/imm32 +12961 $size-of-type-id:end: +12962 # . reclaim locals +12963 81 0/subop/add %esp 8/imm32 +12964 # . restore registers +12965 59/pop-to-ecx +12966 # . epilogue +12967 89/<- %esp 5/r32/ebp +12968 5d/pop-to-ebp +12969 c3/return +12970 +12971 type-equal?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean +12972 # . prologue +12973 55/push-ebp +12974 89/<- %ebp 4/r32/esp +12975 # . save registers +12976 51/push-ecx +12977 52/push-edx +12978 53/push-ebx +12979 # ecx = a +12980 8b/-> *(ebp+8) 1/r32/ecx +12981 # edx = b +12982 8b/-> *(ebp+0xc) 2/r32/edx +12983 $type-equal?:compare-addr: +12984 # if (a == b) return true +12985 8b/-> %ecx 0/r32/eax # Var-type +12986 39/compare %edx 0/r32/eax # Var-type +12987 b8/copy-to-eax 1/imm32/true +12988 0f 84/jump-if-= $type-equal?:end/disp32 +12989 $type-equal?:compare-atom-state: +12990 # if (a->is-atom? != b->is-atom?) return false +12991 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom +12992 39/compare *edx 3/r32/ebx # Type-tree-is-atom +12993 b8/copy-to-eax 0/imm32/false +12994 0f 85/jump-if-!= $type-equal?:end/disp32 +12995 # if a->is-atom? return (a->value == b->value) +12996 { +12997 $type-equal?:check-atom: +12998 81 7/subop/compare %ebx 0/imm32/false +12999 74/jump-if-= break/disp8 +13000 $type-equal?:is-atom: +13001 8b/-> *(ecx+4) 0/r32/eax # Type-tree-value +13002 39/compare *(edx+4) 0/r32/eax # Type-tree-value +13003 0f 94/set-if-= %al +13004 81 4/subop/and %eax 0xff/imm32 +13005 e9/jump $type-equal?:end/disp32 +13006 } +13007 $type-equal?:check-left: +13008 # if (!type-equal?(a->left, b->left)) return false +13009 (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax +13010 89/<- %ebx 0/r32/eax +13011 (lookup *(edx+4) *(edx+8)) # Type-tree-left Type-tree-left => eax +13012 (type-equal? %eax %ebx) # => eax +13013 3d/compare-eax-and 0/imm32/false +13014 74/jump-if-= $type-equal?:end/disp8 +13015 $type-equal?:check-right: +13016 # return type-equal?(a->right, b->right) +13017 (lookup *(ecx+0xc) *(ecx+0x10)) # Type-tree-right Type-tree-right => eax +13018 89/<- %ebx 0/r32/eax +13019 (lookup *(edx+0xc) *(edx+0x10)) # Type-tree-right Type-tree-right => eax +13020 (type-equal? %eax %ebx) # => eax +13021 $type-equal?:end: +13022 # . restore registers +13023 5b/pop-to-ebx +13024 5a/pop-to-edx +13025 59/pop-to-ecx +13026 # . epilogue +13027 89/<- %esp 5/r32/ebp +13028 5d/pop-to-ebp +13029 c3/return +13030 +13031 ####################################################### +13032 # Code-generation +13033 ####################################################### +13034 +13035 == data +13036 +13037 # Global state added to each var record when performing code-generation. +13038 Curr-local-stack-offset: # (addr int) +13039 0/imm32 +13040 +13041 == code +13042 +13043 emit-subx: # out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) +13044 # . prologue +13045 55/push-ebp +13046 89/<- %ebp 4/r32/esp +13047 # . save registers +13048 50/push-eax +13049 # var curr/eax: (addr function) = *Program->functions +13050 (lookup *_Program-functions *_Program-functions->payload) # => eax +13051 { +13052 # if (curr == null) break 13053 3d/compare-eax-and 0/imm32 -13054 75/jump-if-!= break/disp8 -13055 b8/copy-to-eax 1/imm32/true -13056 eb/jump $will-not-write-some-register?:end/disp8 -13057 } -13058 # return !assigns-in-stmts?(stmts, target) -13059 (assigns-in-stmts? *(ebp+0xc) %eax) # => eax -13060 3d/compare-eax-and 0/imm32/false -13061 # assume: true = 1, so no need to mask with 0x000000ff -13062 0f 94/set-if-= %al -13063 $will-not-write-some-register?:end: -13064 # . epilogue -13065 89/<- %esp 5/r32/ebp -13066 5d/pop-to-ebp -13067 c3/return -13068 -13069 # return fn output with matching register -13070 # always returns false if 'reg' is null -13071 find-register: # fn: (addr function), reg: (addr array byte) -> result/eax: (addr var) -13072 # . prologue -13073 55/push-ebp -13074 89/<- %ebp 4/r32/esp -13075 # . save registers +13054 0f 84/jump-if-= break/disp32 +13055 (emit-subx-function *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) +13056 # curr = lookup(curr->next) +13057 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax +13058 e9/jump loop/disp32 +13059 } +13060 $emit-subx:end: +13061 # . restore registers +13062 58/pop-to-eax +13063 # . epilogue +13064 89/<- %esp 5/r32/ebp +13065 5d/pop-to-ebp +13066 c3/return +13067 +13068 emit-subx-function: # out: (addr buffered-file), f: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +13069 # . prologue +13070 55/push-ebp +13071 89/<- %ebp 4/r32/esp +13072 # some preprocessing +13073 (populate-mu-type-offsets-in-inouts *(ebp+0xc)) +13074 # . save registers +13075 50/push-eax 13076 51/push-ecx -13077 # var curr/ecx: (addr list var) = lookup(fn->outputs) -13078 8b/-> *(ebp+8) 1/r32/ecx -13079 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax -13080 89/<- %ecx 0/r32/eax -13081 { -13082 $find-register:loop: -13083 # if (curr == 0) break -13084 81 7/subop/compare %ecx 0/imm32 -13085 74/jump-if-= break/disp8 -13086 # eax = curr->value->register -13087 (lookup *ecx *(ecx+4)) # List-value List-value => eax -13088 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -13089 # if (eax == reg) return curr->value -13090 $find-register:compare: -13091 (string-equal? *(ebp+0xc) %eax) # => eax -13092 { -13093 3d/compare-eax-and 0/imm32/false -13094 74/jump-if-= break/disp8 -13095 $find-register:found: -13096 (lookup *ecx *(ecx+4)) # List-value List-value => eax -13097 eb/jump $find-register:end/disp8 -13098 } -13099 # curr = lookup(curr->next) -13100 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -13101 89/<- %ecx 0/r32/eax -13102 # -13103 eb/jump loop/disp8 -13104 } -13105 $find-register:end: -13106 # . restore registers -13107 59/pop-to-ecx +13077 52/push-edx +13078 # initialize some global state +13079 c7 0/subop/copy *Curr-block-depth 1/imm32 # Important: keep this in sync with the parse phase +13080 c7 0/subop/copy *Curr-local-stack-offset 0/imm32 +13081 # ecx = f +13082 8b/-> *(ebp+0xc) 1/r32/ecx +13083 # var vars/edx: (stack (addr var) 256) +13084 81 5/subop/subtract %esp 0xc00/imm32 +13085 68/push 0xc00/imm32/size +13086 68/push 0/imm32/top +13087 89/<- %edx 4/r32/esp +13088 # var name/eax: (addr array byte) = lookup(f->name) +13089 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax +13090 # +13091 (write-buffered *(ebp+8) %eax) +13092 (write-buffered *(ebp+8) ":\n") +13093 (emit-subx-prologue *(ebp+8)) +13094 # var body/eax: (addr block) = lookup(f->body) +13095 (lookup *(ecx+0x18) *(ecx+0x1c)) # Function-body Function-body => eax +13096 # +13097 (emit-subx-block *(ebp+8) %eax %edx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +13098 (emit-subx-epilogue *(ebp+8)) +13099 # TODO: validate that *Curr-block-depth and *Curr-local-stack-offset have +13100 # been cleaned up +13101 $emit-subx-function:end: +13102 # . reclaim locals +13103 81 0/subop/add %esp 0xc08/imm32 +13104 # . restore registers +13105 5a/pop-to-edx +13106 59/pop-to-ecx +13107 58/pop-to-eax 13108 # . epilogue 13109 89/<- %esp 5/r32/ebp 13110 5d/pop-to-ebp 13111 c3/return 13112 -13113 assigns-in-stmts?: # stmts: (addr list stmt), v: (addr var) -> result/eax: boolean +13113 populate-mu-type-offsets-in-inouts: # f: (addr function) 13114 # . prologue 13115 55/push-ebp 13116 89/<- %ebp 4/r32/esp 13117 # . save registers -13118 51/push-ecx -13119 # var curr/ecx: (addr list stmt) = stmts -13120 8b/-> *(ebp+8) 1/r32/ecx -13121 { -13122 # if (curr == 0) break -13123 81 7/subop/compare %ecx 0/imm32 -13124 74/jump-if-= break/disp8 -13125 # if assigns-in-stmt?(curr->value, v) return true -13126 (lookup *ecx *(ecx+4)) # List-value List-value => eax -13127 (assigns-in-stmt? %eax *(ebp+0xc)) # => eax -13128 3d/compare-eax-and 0/imm32/false -13129 75/jump-if-!= break/disp8 -13130 # curr = lookup(curr->next) -13131 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -13132 89/<- %ecx 0/r32/eax -13133 # -13134 eb/jump loop/disp8 -13135 } -13136 $assigns-in-stmts?:end: -13137 # . restore registers -13138 59/pop-to-ecx -13139 # . epilogue -13140 89/<- %esp 5/r32/ebp -13141 5d/pop-to-ebp -13142 c3/return -13143 -13144 assigns-in-stmt?: # stmt: (addr stmt), v: (addr var) -> result/eax: boolean -13145 # . prologue -13146 55/push-ebp -13147 89/<- %ebp 4/r32/esp -13148 # . save registers -13149 51/push-ecx -13150 # ecx = stmt -13151 8b/-> *(ebp+8) 1/r32/ecx -13152 # if stmt is a stmt1, return assigns-in-stmt-vars?(stmt->outputs, v) -13153 { -13154 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag -13155 75/jump-if-!= break/disp8 -13156 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -13157 (assigns-in-stmt-vars? %eax *(ebp+0xc)) # => eax -13158 eb/jump $assigns-in-stmt?:end/disp8 -13159 } -13160 # if stmt is a block, return assigns-in-stmts?(stmt->stmts, v) -13161 { -13162 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag -13163 75/jump-if-!= break/disp8 -13164 (lookup *(ecx+4) *(ecx+8)) # Block-stmts Block-stmts => eax -13165 (assigns-in-stmts? %eax *(ebp+0xc)) # => eax -13166 eb/jump $assigns-in-stmt?:end/disp8 -13167 } -13168 # otherwise return false -13169 b8/copy 0/imm32/false -13170 $assigns-in-stmt?:end: -13171 # . restore registers -13172 59/pop-to-ecx -13173 # . epilogue -13174 89/<- %esp 5/r32/ebp -13175 5d/pop-to-ebp -13176 c3/return -13177 -13178 assigns-in-stmt-vars?: # stmt-var: (addr stmt-var), v: (addr var) -> result/eax: boolean -13179 # . prologue -13180 55/push-ebp -13181 89/<- %ebp 4/r32/esp -13182 # . save registers -13183 51/push-ecx -13184 # var curr/ecx: (addr stmt-var) = stmt-var -13185 8b/-> *(ebp+8) 1/r32/ecx -13186 { -13187 # if (curr == 0) break -13188 81 7/subop/compare %ecx 0/imm32 -13189 74/jump-if-= break/disp8 -13190 # eax = lookup(curr->value) -13191 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -13192 # if (eax == v && curr->is-deref? == false) return true -13193 { -13194 39/compare *(ebp+0xc) 0/r32/eax -13195 75/jump-if-!= break/disp8 -13196 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -13197 75/jump-if-!= break/disp8 -13198 b8/copy-to-eax 1/imm32/true -13199 eb/jump $assigns-in-stmt-vars?:end/disp8 -13200 } -13201 # curr = lookup(curr->next) -13202 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -13203 89/<- %ecx 0/r32/eax -13204 # -13205 eb/jump loop/disp8 -13206 } -13207 $assigns-in-stmt-vars?:end: -13208 # . restore registers -13209 59/pop-to-ecx -13210 # . epilogue -13211 89/<- %esp 5/r32/ebp -13212 5d/pop-to-ebp -13213 c3/return -13214 -13215 # is there a var before 'v' with the same block-depth and register on the 'vars' stack? -13216 # v is guaranteed to be within vars -13217 # 'start' is provided as an optimization, a pointer within vars -13218 # *start == v -13219 same-register-spilled-before?: # v: (addr var), vars: (addr stack (handle var)), start: (addr var) -> result/eax: boolean -13220 # . prologue -13221 55/push-ebp -13222 89/<- %ebp 4/r32/esp -13223 # . save registers -13224 51/push-ecx -13225 52/push-edx -13226 53/push-ebx -13227 56/push-esi -13228 57/push-edi -13229 # ecx = v -13230 8b/-> *(ebp+8) 1/r32/ecx -13231 # var reg/edx: (addr array byte) = lookup(v->register) -13232 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax -13233 89/<- %edx 0/r32/eax -13234 # var depth/ebx: int = v->block-depth -13235 8b/-> *(ecx+0x10) 3/r32/ebx # Var-block-depth -13236 # var min/ecx: (addr handle var) = vars->data -13237 8b/-> *(ebp+0xc) 1/r32/ecx -13238 81 0/subop/add %ecx 8/imm32 -13239 # TODO: check that start >= min and start < &vars->data[top] -13240 # TODO: check that *start == v -13241 # var curr/esi: (addr handle var) = start -13242 8b/-> *(ebp+0x10) 6/r32/esi -13243 # curr -= 8 -13244 81 5/subop/subtract %esi 8/imm32 -13245 { -13246 $same-register-spilled-before?:loop: -13247 # if (curr < min) break -13248 39/compare %esi 1/r32/ecx -13249 0f 82/jump-if-addr< break/disp32 -13250 # var x/eax: (addr var) = lookup(*curr) -13251 (lookup *esi *(esi+4)) # => eax -13252 # if (x->block-depth < depth) break -13253 39/compare *(eax+0x10) 3/r32/ebx # Var-block-depth -13254 0f 8c/jump-if-< break/disp32 -13255 # if (x->register == 0) continue -13256 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -13257 74/jump-if-= $same-register-spilled-before?:continue/disp8 -13258 # if (x->register == reg) return true -13259 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -13260 (string-equal? %eax %edx) # => eax -13261 3d/compare-eax-and 0/imm32/false -13262 b8/copy-to-eax 1/imm32/true -13263 75/jump-if-!= $same-register-spilled-before?:end/disp8 -13264 $same-register-spilled-before?:continue: -13265 # curr -= 8 -13266 81 5/subop/subtract %esi 8/imm32 -13267 e9/jump loop/disp32 -13268 } -13269 $same-register-spilled-before?:false: -13270 b8/copy-to-eax 0/imm32/false -13271 $same-register-spilled-before?:end: -13272 # . restore registers -13273 5f/pop-to-edi -13274 5e/pop-to-esi -13275 5b/pop-to-ebx -13276 5a/pop-to-edx -13277 59/pop-to-ecx -13278 # . epilogue -13279 89/<- %esp 5/r32/ebp -13280 5d/pop-to-ebp -13281 c3/return -13282 -13283 # Clean up global state for 'vars' until some block depth (inclusive). -13284 # -13285 # This would be a simple series of pops, if it wasn't for fn outputs, which -13286 # can occur anywhere in the stack. -13287 # So we have to _compact_ the entire array underlying the stack. -13288 # -13289 # We want to allow a fn output register to be written to by locals before the -13290 # output is set. -13291 # So fn outputs can't just be pushed at the start of the function. -13292 # -13293 # We want to allow other locals to shadow a fn output register after the -13294 # output is set. -13295 # So the output can't just always override anything in the stack. Sequence matters. -13296 clean-up-blocks: # vars: (addr stack live-var), until-block-depth: int, fn: (addr function) -13297 # pseudocode: -13298 # to = vars->top (which points outside the stack) -13299 # while true -13300 # if to <= 0 -13301 # break -13302 # var v = vars->data[to-1] -13303 # if v.depth < until and !in-function-outputs?(fn, v) -13304 # break -13305 # --to -13306 # from = to -13307 # while true -13308 # if from >= vars->top -13309 # break -13310 # assert(from >= to) -13311 # v = vars->data[from] -13312 # if in-function-outputs?(fn, v) -13313 # if from > to -13314 # vars->data[to] = vars->data[from] -13315 # ++to -13316 # ++from -13317 # vars->top = to -13318 # -13319 # . prologue -13320 55/push-ebp -13321 89/<- %ebp 4/r32/esp -13322 # . save registers -13323 50/push-eax -13324 52/push-edx -13325 53/push-ebx -13326 56/push-esi -13327 57/push-edi -13328 # ebx = vars -13329 8b/-> *(ebp+8) 3/r32/ebx -13330 # edx = until-block-depth -13331 8b/-> *(ebp+0xc) 2/r32/edx -13332 $clean-up-blocks:phase1: -13333 # var to/edi: int = vars->top -13334 8b/-> *ebx 7/r32/edi -13335 { -13336 $clean-up-blocks:loop1: -13337 # if (to <= 0) break -13338 81 7/subop/compare %edi 0/imm32 -13339 7e/jump-if-<= break/disp8 -13340 # var v/eax: (addr var) = lookup(vars->data[to-1]->var) -13341 8d/copy-address *(ebx+edi-4) 0/r32/eax # vars + 8 + to - 12 -13342 (lookup *eax *(eax+4)) # => eax -13343 # if (v->block-depth >= until-block-depth) continue -13344 39/compare *(eax+0x10) 2/r32/edx # Var-block-depth -13345 { -13346 7d/jump-if->= break/disp8 -13347 # if (!in-function-outputs?(fn, v)) break -13348 (in-function-outputs? *(ebp+0x10) %eax) # => eax -13349 3d/compare-eax-and 0/imm32/false -13350 74/jump-if-= $clean-up-blocks:phase2/disp8 -13351 } -13352 $clean-up-blocks:loop1-continue: -13353 # --to -13354 81 5/subop/subtract %edi 0xc/imm32 -13355 # -13356 eb/jump loop/disp8 -13357 } -13358 $clean-up-blocks:phase2: -13359 # var from/esi: int = to -13360 89/<- %esi 7/r32/edi -13361 { -13362 $clean-up-blocks:loop2: -13363 # if (from >= vars->top) break -13364 3b/compare 6/r32/esi *ebx -13365 7d/jump-if->= break/disp8 -13366 # var v/eax: (addr var) = lookup(vars->data[from]->var) -13367 8d/copy-address *(ebx+esi+8) 0/r32/eax -13368 (lookup *eax *(eax+4)) # => eax -13369 # if !in-function-outputs?(fn, v) continue -13370 (in-function-outputs? *(ebp+0x10) %eax) # => eax -13371 3d/compare-eax-and 0/imm32/false -13372 74/jump-if-= $clean-up-blocks:loop2-continue/disp8 -13373 # invariant: from >= to -13374 # if (from > to) vars->data[to] = vars->data[from] -13375 { -13376 39/compare %esi 7/r32/edi -13377 7e/jump-if-<= break/disp8 -13378 56/push-esi -13379 57/push-edi -13380 # . var from/esi: (addr byte) = &vars->data[from] -13381 8d/copy-address *(ebx+esi+8) 6/r32/esi -13382 # . var to/edi: (addr byte) = &vars->data[to] -13383 8d/copy-address *(ebx+edi+8) 7/r32/edi -13384 # . -13385 8b/-> *esi 0/r32/eax -13386 89/<- *edi 0/r32/eax -13387 8b/-> *(esi+4) 0/r32/eax -13388 89/<- *(edi+4) 0/r32/eax -13389 8b/-> *(esi+8) 0/r32/eax -13390 89/<- *(edi+8) 0/r32/eax -13391 5f/pop-to-edi -13392 5e/pop-to-esi -13393 } -13394 # ++to -13395 81 0/subop/add %edi 0xc/imm32 -13396 $clean-up-blocks:loop2-continue: -13397 # ++from -13398 81 0/subop/add %esi 0xc/imm32 -13399 # -13400 eb/jump loop/disp8 -13401 } -13402 89/<- *ebx 7/r32/edi -13403 $clean-up-blocks:end: -13404 # . restore registers -13405 5f/pop-to-edi -13406 5e/pop-to-esi -13407 5b/pop-to-ebx -13408 5a/pop-to-edx -13409 58/pop-to-eax -13410 # . epilogue -13411 89/<- %esp 5/r32/ebp -13412 5d/pop-to-ebp -13413 c3/return -13414 -13415 in-function-outputs?: # fn: (addr function), target: (addr var) -> result/eax: boolean -13416 # . prologue -13417 55/push-ebp -13418 89/<- %ebp 4/r32/esp -13419 # . save registers -13420 51/push-ecx -13421 # var curr/ecx: (addr list var) = lookup(fn->outputs) -13422 8b/-> *(ebp+8) 1/r32/ecx -13423 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax -13424 89/<- %ecx 0/r32/eax -13425 # while curr != null -13426 { -13427 81 7/subop/compare %ecx 0/imm32 -13428 74/jump-if-= break/disp8 -13429 # var v/eax: (addr var) = lookup(curr->value) -13430 (lookup *ecx *(ecx+4)) # List-value List-value => eax -13431 # if (v == target) return true -13432 39/compare *(ebp+0xc) 0/r32/eax -13433 b8/copy-to-eax 1/imm32/true -13434 74/jump-if-= $in-function-outputs?:end/disp8 -13435 # curr = curr->next -13436 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -13437 89/<- %ecx 0/r32/eax -13438 # -13439 eb/jump loop/disp8 -13440 } -13441 b8/copy-to-eax 0/imm32 -13442 $in-function-outputs?:end: -13443 # . restore registers -13444 59/pop-to-ecx -13445 # . epilogue -13446 89/<- %esp 5/r32/ebp -13447 5d/pop-to-ebp -13448 c3/return -13449 -13450 emit-subx-var-def: # out: (addr buffered-file), stmt: (addr stmt) -13451 # . prologue -13452 55/push-ebp -13453 89/<- %ebp 4/r32/esp -13454 # . save registers -13455 50/push-eax -13456 51/push-ecx -13457 52/push-edx -13458 # eax = stmt -13459 8b/-> *(ebp+0xc) 0/r32/eax -13460 # var v/ecx: (addr var) -13461 (lookup *(eax+4) *(eax+8)) # Vardef-var Vardef-var => eax -13462 89/<- %ecx 0/r32/eax -13463 # v->block-depth = *Curr-block-depth -13464 8b/-> *Curr-block-depth 0/r32/eax -13465 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -13466 # var n/edx: int = size-of(stmt->var) -13467 (size-of %ecx) # => eax -13468 89/<- %edx 0/r32/eax -13469 # *Curr-local-stack-offset -= n -13470 29/subtract-from *Curr-local-stack-offset 2/r32/edx -13471 # v->offset = *Curr-local-stack-offset -13472 8b/-> *Curr-local-stack-offset 0/r32/eax -13473 89/<- *(ecx+0x14) 0/r32/eax # Var-offset -13474 # if v is an array, do something special -13475 { -13476 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -13477 (is-mu-array? %eax) # => eax -13478 3d/compare-eax-and 0/imm32/false -13479 0f 84/jump-if-= break/disp32 -13480 # var array-size-without-size/edx: int = n-4 -13481 81 5/subop/subtract %edx 4/imm32 -13482 (emit-indent *(ebp+8) *Curr-block-depth) -13483 (write-buffered *(ebp+8) "(push-n-zero-bytes ") -13484 (write-int32-hex-buffered *(ebp+8) %edx) -13485 (write-buffered *(ebp+8) ")\n") -13486 (emit-indent *(ebp+8) *Curr-block-depth) -13487 (write-buffered *(ebp+8) "68/push ") -13488 (write-int32-hex-buffered *(ebp+8) %edx) -13489 (write-buffered *(ebp+8) "/imm32\n") -13490 eb/jump $emit-subx-var-def:end/disp8 -13491 } -13492 # while n > 0 -13493 { -13494 81 7/subop/compare %edx 0/imm32 -13495 7e/jump-if-<= break/disp8 -13496 (emit-indent *(ebp+8) *Curr-block-depth) -13497 (write-buffered *(ebp+8) "68/push 0/imm32\n") -13498 # n -= 4 -13499 81 5/subop/subtract %edx 4/imm32 -13500 # -13501 eb/jump loop/disp8 -13502 } -13503 $emit-subx-var-def:end: -13504 # . restore registers -13505 5a/pop-to-edx -13506 59/pop-to-ecx -13507 58/pop-to-eax -13508 # . epilogue -13509 89/<- %esp 5/r32/ebp -13510 5d/pop-to-ebp -13511 c3/return -13512 -13513 emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) -13514 # . prologue -13515 55/push-ebp -13516 89/<- %ebp 4/r32/esp -13517 # . save registers -13518 50/push-eax -13519 51/push-ecx -13520 # - some special-case primitives that don't actually use the 'primitives' data structure -13521 # var op/ecx: (addr array byte) = lookup(stmt->operation) -13522 8b/-> *(ebp+0xc) 1/r32/ecx -13523 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -13524 89/<- %ecx 0/r32/eax -13525 # array size -13526 { -13527 # if (!string-equal?(stmt->operation, "length")) break -13528 (string-equal? %ecx "length") # => eax -13529 3d/compare-eax-and 0/imm32 -13530 0f 84/jump-if-= break/disp32 -13531 (translate-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -13532 e9/jump $emit-subx-stmt:end/disp32 -13533 } -13534 # index into array -13535 { -13536 # if (!string-equal?(stmt->operation, "index")) break -13537 (string-equal? %ecx "index") # => eax -13538 3d/compare-eax-and 0/imm32 -13539 0f 84/jump-if-= break/disp32 -13540 (translate-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -13541 e9/jump $emit-subx-stmt:end/disp32 -13542 } -13543 # compute-offset for index into array -13544 { -13545 # if (!string-equal?(stmt->operation, "compute-offset")) break -13546 (string-equal? %ecx "compute-offset") # => eax -13547 3d/compare-eax-and 0/imm32 -13548 0f 84/jump-if-= break/disp32 -13549 (translate-mu-compute-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -13550 e9/jump $emit-subx-stmt:end/disp32 -13551 } -13552 # get field from record -13553 { -13554 # if (!string-equal?(stmt->operation, "get")) break -13555 (string-equal? %ecx "get") # => eax -13556 3d/compare-eax-and 0/imm32 -13557 0f 84/jump-if-= break/disp32 -13558 (translate-mu-get-stmt *(ebp+8) *(ebp+0xc)) -13559 e9/jump $emit-subx-stmt:end/disp32 -13560 } -13561 # - if stmt matches a primitive, emit it -13562 { -13563 $emit-subx-stmt:check-for-primitive: -13564 # var curr/eax: (addr primitive) -13565 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => eax -13566 3d/compare-eax-and 0/imm32 -13567 74/jump-if-= break/disp8 -13568 $emit-subx-stmt:primitive: -13569 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr -13570 e9/jump $emit-subx-stmt:end/disp32 -13571 } -13572 # - otherwise emit a call -13573 # TODO: type-checking -13574 $emit-subx-stmt:call: -13575 (emit-call *(ebp+8) *(ebp+0xc)) -13576 $emit-subx-stmt:end: -13577 # . restore registers -13578 59/pop-to-ecx -13579 58/pop-to-eax -13580 # . epilogue -13581 89/<- %esp 5/r32/ebp -13582 5d/pop-to-ebp -13583 c3/return -13584 -13585 translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -13586 # . prologue -13587 55/push-ebp -13588 89/<- %ebp 4/r32/esp -13589 # . save registers -13590 50/push-eax -13591 51/push-ecx -13592 52/push-edx -13593 53/push-ebx -13594 56/push-esi -13595 # esi = stmt -13596 8b/-> *(ebp+0xc) 6/r32/esi -13597 # var base/ebx: (addr var) = stmt->inouts[0]->value -13598 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -13599 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -13600 89/<- %ebx 0/r32/eax -13601 # var elemsize/ecx: int = array-element-size(base) -13602 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -13603 89/<- %ecx 0/r32/eax -13604 # var outreg/edx: (addr array byte) = stmt->outputs[0]->value->register -13605 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -13606 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -13607 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -13608 89/<- %edx 0/r32/eax -13609 # if elemsize == 1 -13610 { -13611 81 7/subop/compare %ecx 1/imm32 -13612 75/jump-if-!= break/disp8 -13613 $translate-mu-length-stmt:size-1: -13614 (emit-save-size-to *(ebp+8) %ebx %edx) -13615 e9/jump $translate-mu-length-stmt:end/disp32 -13616 } -13617 # if elemsize is a power of 2 less than 256 -13618 { -13619 (power-of-2? %ecx *(ebp+0x10) *(ebp+0x14)) # => eax -13620 3d/compare-eax-and 0/imm32/false -13621 74/jump-if-= break/disp8 -13622 81 7/subop/compare %ecx 0xff/imm32 -13623 7f/jump-if-> break/disp8 -13624 $translate-mu-length-stmt:size-power-of-2: -13625 (emit-save-size-to *(ebp+8) %ebx %edx) -13626 (emit-divide-by-shift-right *(ebp+8) %edx %ecx) -13627 e9/jump $translate-mu-length-stmt:end/disp32 -13628 } -13629 # otherwise, the complex case -13630 # . emit register spills -13631 { -13632 $translate-mu-length-stmt:complex: -13633 (string-equal? %edx "eax") # => eax -13634 3d/compare-eax-and 0/imm32/false -13635 75/break-if-!= break/disp8 -13636 (emit-indent *(ebp+8) *Curr-block-depth) -13637 (write-buffered *(ebp+8) "50/push-eax\n") -13638 } -13639 { -13640 (string-equal? %edx "ecx") # => eax -13641 3d/compare-eax-and 0/imm32/false -13642 75/break-if-!= break/disp8 -13643 (emit-indent *(ebp+8) *Curr-block-depth) -13644 (write-buffered *(ebp+8) "51/push-ecx\n") -13645 } -13646 { -13647 (string-equal? %edx "edx") # => eax -13648 3d/compare-eax-and 0/imm32/false -13649 75/break-if-!= break/disp8 -13650 (emit-indent *(ebp+8) *Curr-block-depth) -13651 (write-buffered *(ebp+8) "52/push-edx\n") -13652 } -13653 # . -13654 (emit-save-size-to *(ebp+8) %ebx "eax") -13655 (emit-indent *(ebp+8) *Curr-block-depth) -13656 (write-buffered *(ebp+8) "31/xor %edx 2/r32/edx\n") -13657 (emit-indent *(ebp+8) *Curr-block-depth) -13658 (write-buffered *(ebp+8) "b9/copy-to-ecx ") -13659 (write-int32-hex-buffered *(ebp+8) %ecx) -13660 (write-buffered *(ebp+8) "/imm32\n") -13661 (emit-indent *(ebp+8) *Curr-block-depth) -13662 (write-buffered *(ebp+8) "f7 7/subop/idiv-eax-edx-by %ecx\n") -13663 { -13664 (string-equal? %edx "eax") # => eax -13665 3d/compare-eax-and 0/imm32/false -13666 75/break-if-!= break/disp8 -13667 (emit-indent *(ebp+8) *Curr-block-depth) -13668 (write-buffered *(ebp+8) "89/<- %") -13669 (write-buffered *(ebp+8) %edx) -13670 (write-buffered *(ebp+8) " 0/r32/eax\n") -13671 } -13672 # . emit register restores -13673 { -13674 (string-equal? %edx "edx") # => eax -13675 3d/compare-eax-and 0/imm32/false -13676 75/break-if-!= break/disp8 -13677 (emit-indent *(ebp+8) *Curr-block-depth) -13678 (write-buffered *(ebp+8) "5a/pop-to-edx\n") -13679 } -13680 { -13681 (string-equal? %edx "ecx") # => eax -13682 3d/compare-eax-and 0/imm32/false -13683 75/break-if-!= break/disp8 -13684 (emit-indent *(ebp+8) *Curr-block-depth) -13685 (write-buffered *(ebp+8) "59/pop-to-ecx\n") -13686 } -13687 { -13688 (string-equal? %edx "eax") # => eax -13689 3d/compare-eax-and 0/imm32/false -13690 75/break-if-!= break/disp8 -13691 (emit-indent *(ebp+8) *Curr-block-depth) -13692 (write-buffered *(ebp+8) "58/pop-to-eax\n") +13118 50/push-eax +13119 51/push-ecx +13120 52/push-edx +13121 53/push-ebx +13122 57/push-edi +13123 # var next-offset/edx: int = 8 +13124 ba/copy-to-edx 8/imm32 +13125 # var curr/ecx: (addr list var) = lookup(f->inouts) +13126 8b/-> *(ebp+8) 1/r32/ecx +13127 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax +13128 89/<- %ecx 0/r32/eax +13129 { +13130 $populate-mu-type-offsets-in-inouts:loop: +13131 81 7/subop/compare %ecx 0/imm32 +13132 74/jump-if-= break/disp8 +13133 # var v/ebx: (addr var) = lookup(curr->value) +13134 (lookup *ecx *(ecx+4)) # List-value List-value => eax +13135 89/<- %ebx 0/r32/eax +13136 #? (lookup *ebx *(ebx+4)) +13137 #? (write-buffered Stderr "setting offset of fn inout ") +13138 #? (write-buffered Stderr %eax) +13139 #? (write-buffered Stderr "@") +13140 #? (write-int32-hex-buffered Stderr %ebx) +13141 #? (write-buffered Stderr " to ") +13142 #? (write-int32-hex-buffered Stderr %edx) +13143 #? (write-buffered Stderr Newline) +13144 #? (flush Stderr) +13145 # v->offset = next-offset +13146 89/<- *(ebx+0x14) 2/r32/edx # Var-offset +13147 # next-offset += size-of(v) +13148 (size-of %ebx) # => eax +13149 01/add-to %edx 0/r32/eax +13150 # curr = lookup(curr->next) +13151 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +13152 89/<- %ecx 0/r32/eax +13153 # +13154 eb/jump loop/disp8 +13155 } +13156 $populate-mu-type-offsets-in-inouts:end: +13157 # . restore registers +13158 5f/pop-to-edi +13159 5b/pop-to-ebx +13160 5a/pop-to-edx +13161 59/pop-to-ecx +13162 58/pop-to-eax +13163 # . epilogue +13164 89/<- %esp 5/r32/ebp +13165 5d/pop-to-ebp +13166 c3/return +13167 +13168 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) +13169 # . prologue +13170 55/push-ebp +13171 89/<- %ebp 4/r32/esp +13172 # . save registers +13173 50/push-eax +13174 51/push-ecx +13175 53/push-ebx +13176 56/push-esi +13177 # esi = stmts +13178 8b/-> *(ebp+0xc) 6/r32/esi +13179 # +13180 { +13181 $emit-subx-stmt-list:loop: +13182 81 7/subop/compare %esi 0/imm32 +13183 0f 84/jump-if-= break/disp32 +13184 # var curr-stmt/ecx: (addr stmt) = lookup(stmts->value) +13185 (lookup *esi *(esi+4)) # List-value List-value => eax +13186 89/<- %ecx 0/r32/eax +13187 { +13188 $emit-subx-stmt-list:check-for-block: +13189 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag +13190 75/jump-if-!= break/disp8 +13191 $emit-subx-stmt-list:block: +13192 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +13193 } +13194 { +13195 $emit-subx-stmt-list:check-for-stmt: +13196 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag +13197 0f 85/jump-if-!= break/disp32 +13198 $emit-subx-stmt-list:stmt1: +13199 { +13200 (is-mu-branch? %ecx) # => eax +13201 3d/compare-eax-and 0/imm32/false +13202 0f 84/jump-if-= break/disp32 +13203 $emit-subx-stmt-list:branch-stmt: +13204 +-- 27 lines: # unconditional loops ----------------------------------------------------------------------------------------------------------------------------------------------------- +13231 +-- 16 lines: # unconditional breaks ---------------------------------------------------------------------------------------------------------------------------------------------------- +13247 +-- 38 lines: # simple conditional branches without a target ---------------------------------------------------------------------------------------------------------------------------- +13285 +-- 19 lines: # conditional branches with an explicit target ---------------------------------------------------------------------------------------------------------------------------- +13304 } +13305 $emit-subx-stmt-list:1-to-1: +13306 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x18) *(ebp+0x1c)) +13307 e9/jump $emit-subx-stmt-list:continue/disp32 +13308 } +13309 { +13310 $emit-subx-stmt-list:check-for-var-def: +13311 81 7/subop/compare *ecx 2/imm32/var-def # Stmt-tag +13312 75/jump-if-!= break/disp8 +13313 $emit-subx-stmt-list:var-def: +13314 (emit-subx-var-def *(ebp+8) %ecx) +13315 (push *(ebp+0x10) *(ecx+4)) # Vardef-var +13316 (push *(ebp+0x10) *(ecx+8)) # Vardef-var +13317 (push *(ebp+0x10) 0) # Live-var-register-spilled = 0 for vars on the stack +13318 # +13319 eb/jump $emit-subx-stmt-list:continue/disp8 +13320 } +13321 { +13322 $emit-subx-stmt-list:check-for-reg-var-def: +13323 81 7/subop/compare *ecx 3/imm32/reg-var-def # Stmt-tag +13324 0f 85/jump-if-!= break/disp32 +13325 $emit-subx-stmt-list:reg-var-def: +13326 # TODO: ensure that there's exactly one output +13327 (push-output-and-maybe-emit-spill *(ebp+8) %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +13328 # emit the instruction as usual +13329 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x18) *(ebp+0x1c)) +13330 # +13331 eb/jump $emit-subx-stmt-list:continue/disp8 +13332 } +13333 $emit-subx-stmt-list:continue: +13334 # TODO: raise an error on unrecognized Stmt-tag +13335 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax +13336 89/<- %esi 0/r32/eax +13337 e9/jump loop/disp32 +13338 } +13339 $emit-subx-stmt-list:emit-cleanup: +13340 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) *Curr-block-depth) +13341 $emit-subx-stmt-list:clean-up: +13342 (clean-up-blocks *(ebp+0x10) *Curr-block-depth *(ebp+0x14)) +13343 $emit-subx-stmt-list:end: +13344 # . restore registers +13345 5e/pop-to-esi +13346 5b/pop-to-ebx +13347 59/pop-to-ecx +13348 58/pop-to-eax +13349 # . epilogue +13350 89/<- %esp 5/r32/ebp +13351 5d/pop-to-ebp +13352 c3/return +13353 +13354 # 'later-stmts' includes 'stmt', but will behave the same even without it; reg-var-def stmts are guaranteed not to write to function outputs. +13355 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) +13356 # . prologue +13357 55/push-ebp +13358 89/<- %ebp 4/r32/esp +13359 # . save registers +13360 50/push-eax +13361 51/push-ecx +13362 52/push-edx +13363 # ecx = stmt +13364 8b/-> *(ebp+0xc) 1/r32/ecx +13365 # var sv/eax: (addr stmt-var) = lookup(curr-stmt->outputs) +13366 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax +13367 # TODO: assert !sv->is-deref? +13368 # var v/ecx: (addr var) = lookup(sv->value) +13369 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13370 89/<- %ecx 0/r32/eax +13371 # v->block-depth = *Curr-block-depth +13372 8b/-> *Curr-block-depth 0/r32/eax +13373 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +13374 #? (write-buffered Stderr "var ") +13375 #? (lookup *ecx *(ecx+4)) +13376 #? (write-buffered Stderr %eax) +13377 #? (write-buffered Stderr " at depth ") +13378 #? (write-int32-hex-buffered Stderr *(ecx+0x10)) +13379 #? (write-buffered Stderr Newline) +13380 #? (flush Stderr) +13381 # ensure that v is in a register +13382 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +13383 0f 84/jump-if-= $push-output-and-maybe-emit-spill:abort/disp32 +13384 # var emit-spill?/edx: boolean = not-yet-spilled-this-block? && will-not-write-some-register?(fn) +13385 (not-yet-spilled-this-block? %ecx *(ebp+0x10)) # => eax +13386 89/<- %edx 0/r32/eax +13387 3d/compare-eax-and 0/imm32/false +13388 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 +13389 (will-not-write-some-register? %ecx *(ebp+0x14) *(ebp+0x18)) # => eax +13390 89/<- %edx 0/r32/eax +13391 # check emit-spill? +13392 3d/compare-eax-and 0/imm32/false +13393 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 +13394 # TODO: assert(size-of(output) == 4) +13395 # *Curr-local-stack-offset -= 4 +13396 81 5/subop/subtract *Curr-local-stack-offset 4/imm32 +13397 # emit spill +13398 (emit-indent *(ebp+8) *Curr-block-depth) +13399 (write-buffered *(ebp+8) "ff 6/subop/push %") +13400 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +13401 (write-buffered *(ebp+8) %eax) +13402 (write-buffered *(ebp+8) Newline) +13403 $push-output-and-maybe-emit-spill:push: +13404 8b/-> *(ebp+0xc) 1/r32/ecx +13405 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax +13406 # push(vars, {sv->value, emit-spill?}) +13407 (push *(ebp+0x10) *eax) # Stmt-var-value +13408 (push *(ebp+0x10) *(eax+4)) # Stmt-var-value +13409 (push *(ebp+0x10) %edx) +13410 $push-output-and-maybe-emit-spill:end: +13411 # . restore registers +13412 5a/pop-to-edx +13413 59/pop-to-ecx +13414 58/pop-to-eax +13415 # . epilogue +13416 89/<- %esp 5/r32/ebp +13417 5d/pop-to-ebp +13418 c3/return +13419 +13420 $push-output-and-maybe-emit-spill:abort: +13421 # error("var '" var->name "' initialized from an instruction must live in a register\n") +13422 (write-buffered *(ebp+0x1c) "var '") +13423 (write-buffered *(ebp+0x1c) *eax) # Var-name +13424 (write-buffered *(ebp+0x1c) "' initialized from an instruction must live in a register\n") +13425 (flush *(ebp+0x1c)) +13426 (stop *(ebp+0x20) 1) +13427 # never gets here +13428 +13429 emit-subx-cleanup-and-unconditional-nonlocal-branch: # out: (addr buffered-file), stmt: (addr stmt1), vars: (addr stack live-var) +13430 # . prologue +13431 55/push-ebp +13432 89/<- %ebp 4/r32/esp +13433 # . save registers +13434 50/push-eax +13435 51/push-ecx +13436 # ecx = stmt +13437 8b/-> *(ebp+0xc) 1/r32/ecx +13438 # var target/eax: (addr array byte) = curr-stmt->inouts->value->name +13439 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13440 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13441 (lookup *eax *(eax+4)) # Var-name Var-name => eax +13442 # clean up until target block +13443 (emit-cleanup-code-until-target *(ebp+8) *(ebp+0x10) %eax) +13444 # emit jump to target block +13445 (emit-indent *(ebp+8) *Curr-block-depth) +13446 (write-buffered *(ebp+8) "e9/jump ") +13447 (write-buffered *(ebp+8) %eax) +13448 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +13449 (string-starts-with? %eax "break") +13450 3d/compare-eax-and 0/imm32/false +13451 { +13452 74/jump-if-= break/disp8 +13453 (write-buffered *(ebp+8) ":break/disp32\n") +13454 } +13455 3d/compare-eax-and 0/imm32/false # just in case the function call modified flags +13456 { +13457 75/jump-if-!= break/disp8 +13458 (write-buffered *(ebp+8) ":loop/disp32\n") +13459 } +13460 $emit-subx-cleanup-and-unconditional-nonlocal-branch:end: +13461 # . restore registers +13462 59/pop-to-ecx +13463 58/pop-to-eax +13464 # . epilogue +13465 89/<- %esp 5/r32/ebp +13466 5d/pop-to-ebp +13467 c3/return +13468 +13469 is-mu-branch?: # stmt: (addr stmt1) -> result/eax: boolean +13470 # . prologue +13471 55/push-ebp +13472 89/<- %ebp 4/r32/esp +13473 # . save registers +13474 51/push-ecx +13475 # ecx = lookup(stmt->operation) +13476 8b/-> *(ebp+8) 1/r32/ecx +13477 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +13478 89/<- %ecx 0/r32/eax +13479 # if (stmt->operation starts with "loop") return true +13480 (string-starts-with? %ecx "loop") # => eax +13481 3d/compare-eax-and 0/imm32/false +13482 75/jump-if-not-equal $is-mu-branch?:end/disp8 +13483 # otherwise return (stmt->operation starts with "break") +13484 (string-starts-with? %ecx "break") # => eax +13485 $is-mu-branch?:end: +13486 # . restore registers +13487 59/pop-to-ecx +13488 # . epilogue +13489 89/<- %esp 5/r32/ebp +13490 5d/pop-to-ebp +13491 c3/return +13492 +13493 emit-reverse-break: # out: (addr buffered-file), stmt: (addr stmt1) +13494 # . prologue +13495 55/push-ebp +13496 89/<- %ebp 4/r32/esp +13497 # . save registers +13498 50/push-eax +13499 # eax = stmt +13500 8b/-> *(ebp+0xc) 0/r32/eax +13501 # +13502 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +13503 (get Reverse-branch %eax 0x10 "reverse-branch: ") # => eax: (addr handle array byte) +13504 (emit-indent *(ebp+8) *Curr-block-depth) +13505 (lookup *eax *(eax+4)) # => eax +13506 (write-buffered *(ebp+8) %eax) +13507 (write-buffered *(ebp+8) " break/disp32\n") +13508 $emit-reverse-break:end: +13509 # . restore registers +13510 58/pop-to-eax +13511 # . epilogue +13512 89/<- %esp 5/r32/ebp +13513 5d/pop-to-ebp +13514 c3/return +13515 +13516 == data +13517 +13518 # Table from Mu branch instructions to the reverse SubX opcodes for them. +13519 Reverse-branch: # (table (handle array byte) (handle array byte)) +13520 # a table is a stream +13521 0x140/imm32/write +13522 0/imm32/read +13523 0x140/imm32/size +13524 # data +13525 0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 +13526 0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 +13527 0x11/imm32/alloc-id _string-break-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 +13528 0x11/imm32/alloc-id _string-loop-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 +13529 0x11/imm32/alloc-id _string-break-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 +13530 0x11/imm32/alloc-id _string-loop-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 +13531 0x11/imm32/alloc-id _string-break-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 +13532 0x11/imm32/alloc-id _string-loop-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 +13533 0x11/imm32/alloc-id _string-break-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +13534 0x11/imm32/alloc-id _string-loop-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +13535 0x11/imm32/alloc-id _string-break-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 +13536 0x11/imm32/alloc-id _string-loop-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 +13537 0x11/imm32/alloc-id _string-break-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 +13538 0x11/imm32/alloc-id _string-loop-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 +13539 0x11/imm32/alloc-id _string-break-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 +13540 0x11/imm32/alloc-id _string-loop-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 +13541 0x11/imm32/alloc-id _string-break-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +13542 0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +13543 0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 +13544 0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 +13545 +13546 == code +13547 +13548 emit-unconditional-jump-to-depth: # out: (addr buffered-file), vars: (addr stack live-var), depth: int, label-suffix: (addr array byte) +13549 # . prologue +13550 55/push-ebp +13551 89/<- %ebp 4/r32/esp +13552 # . save registers +13553 50/push-eax +13554 51/push-ecx +13555 52/push-edx +13556 53/push-ebx +13557 56/push-esi +13558 # ecx = vars +13559 8b/-> *(ebp+0xc) 1/r32/ecx +13560 # var eax: int = vars->top +13561 8b/-> *ecx 0/r32/eax +13562 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] +13563 8d/copy-address *(ecx+eax-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size +13564 # var min/ecx: (addr handle var) = vars->data +13565 8d/copy-address *(ecx+8) 1/r32/ecx +13566 # edx = depth +13567 8b/-> *(ebp+0x10) 2/r32/edx +13568 { +13569 $emit-unconditional-jump-to-depth:loop: +13570 # if (curr < min) break +13571 39/compare %esi 1/r32/ecx +13572 0f 82/jump-if-addr< break/disp32 +13573 # var v/ebx: (addr var) = lookup(*curr) +13574 (lookup *esi *(esi+4)) # => eax +13575 89/<- %ebx 0/r32/eax +13576 # if (v->block-depth < until-block-depth) break +13577 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +13578 0f 8c/jump-if-< break/disp32 +13579 { +13580 $emit-unconditional-jump-to-depth:check: +13581 # if v->block-depth != until-block-depth, continue +13582 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +13583 0f 85/jump-if-!= break/disp32 +13584 $emit-unconditional-jump-to-depth:depth-found: +13585 # if v is not a literal, continue +13586 (size-of %ebx) # => eax +13587 3d/compare-eax-and 0/imm32 +13588 0f 85/jump-if-!= break/disp32 +13589 $emit-unconditional-jump-to-depth:label-found: +13590 # emit unconditional jump, then return +13591 (emit-indent *(ebp+8) *Curr-block-depth) +13592 (write-buffered *(ebp+8) "e9/jump ") +13593 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +13594 (write-buffered *(ebp+8) %eax) +13595 (write-buffered *(ebp+8) ":") +13596 (write-buffered *(ebp+8) *(ebp+0x14)) +13597 (write-buffered *(ebp+8) "/disp32\n") +13598 eb/jump $emit-unconditional-jump-to-depth:end/disp8 +13599 } +13600 # curr -= 12 +13601 81 5/subop/subtract %esi 0xc/imm32 +13602 e9/jump loop/disp32 +13603 } +13604 # TODO: error if no label at 'depth' was found +13605 $emit-unconditional-jump-to-depth:end: +13606 # . restore registers +13607 5e/pop-to-esi +13608 5b/pop-to-ebx +13609 5a/pop-to-edx +13610 59/pop-to-ecx +13611 58/pop-to-eax +13612 # . epilogue +13613 89/<- %esp 5/r32/ebp +13614 5d/pop-to-ebp +13615 c3/return +13616 +13617 # emit clean-up code for 'vars' until some block depth +13618 # doesn't actually modify 'vars' so we need traverse manually inside the stack +13619 emit-cleanup-code-until-depth: # out: (addr buffered-file), vars: (addr stack live-var), until-block-depth: int +13620 # . prologue +13621 55/push-ebp +13622 89/<- %ebp 4/r32/esp +13623 # . save registers +13624 50/push-eax +13625 51/push-ecx +13626 52/push-edx +13627 53/push-ebx +13628 56/push-esi +13629 #? (write-buffered Stderr "--- cleanup\n") +13630 #? (flush Stderr) +13631 # ecx = vars +13632 8b/-> *(ebp+0xc) 1/r32/ecx +13633 # var esi: int = vars->top +13634 8b/-> *ecx 6/r32/esi +13635 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] +13636 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size +13637 # var min/ecx: (addr handle var) = vars->data +13638 81 0/subop/add %ecx 8/imm32 +13639 # edx = until-block-depth +13640 8b/-> *(ebp+0x10) 2/r32/edx +13641 { +13642 $emit-cleanup-code-until-depth:loop: +13643 # if (curr < min) break +13644 39/compare %esi 1/r32/ecx +13645 0f 82/jump-if-addr< break/disp32 +13646 # var v/ebx: (addr var) = lookup(*curr) +13647 (lookup *esi *(esi+4)) # => eax +13648 89/<- %ebx 0/r32/eax +13649 #? (lookup *ebx *(ebx+4)) # Var-name +13650 #? (write-buffered Stderr "var ") +13651 #? (write-buffered Stderr %eax) +13652 #? (write-buffered Stderr Newline) +13653 #? (flush Stderr) +13654 # if (v->block-depth < until-block-depth) break +13655 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +13656 0f 8c/jump-if-< break/disp32 +13657 # if v is in a register +13658 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register +13659 { +13660 0f 84/jump-if-= break/disp32 +13661 { +13662 $emit-cleanup-code-until-depth:check-for-previous-spill: +13663 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled +13664 3d/compare-eax-and 0/imm32/false +13665 74/jump-if-= break/disp8 +13666 $emit-cleanup-code-until-depth:reclaim-var-in-register: +13667 (emit-indent *(ebp+8) *Curr-block-depth) +13668 (write-buffered *(ebp+8) "8f 0/subop/pop %") +13669 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +13670 (write-buffered *(ebp+8) %eax) +13671 (write-buffered *(ebp+8) Newline) +13672 } +13673 eb/jump $emit-cleanup-code-until-depth:continue/disp8 +13674 } +13675 # otherwise v is on the stack +13676 { +13677 75/jump-if-!= break/disp8 +13678 $emit-cleanup-code-until-depth:var-on-stack: +13679 (size-of %ebx) # => eax +13680 # don't emit code for labels +13681 3d/compare-eax-and 0/imm32 +13682 74/jump-if-= break/disp8 +13683 $emit-cleanup-code-until-depth:reclaim-var-on-stack: +13684 (emit-indent *(ebp+8) *Curr-block-depth) +13685 (write-buffered *(ebp+8) "81 0/subop/add %esp ") +13686 (write-int32-hex-buffered *(ebp+8) %eax) +13687 (write-buffered *(ebp+8) "/imm32\n") +13688 } +13689 $emit-cleanup-code-until-depth:continue: +13690 # curr -= 12 +13691 81 5/subop/subtract %esi 0xc/imm32 +13692 e9/jump loop/disp32 13693 } -13694 $translate-mu-length-stmt:end: +13694 $emit-cleanup-code-until-depth:end: 13695 # . restore registers 13696 5e/pop-to-esi 13697 5b/pop-to-ebx @@ -13122,6749 +13062,8263 @@ if ('onhashchange' in window) { 13703 5d/pop-to-ebp 13704 c3/return 13705 -13706 array-element-size: # arr: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -13707 # . prologue -13708 55/push-ebp -13709 89/<- %ebp 4/r32/esp -13710 # -13711 (array-element-type-id *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax -13712 (size-of-type-id-as-array-element %eax) # => eax -13713 $array-element-size:end: -13714 # . epilogue -13715 89/<- %esp 5/r32/ebp -13716 5d/pop-to-ebp -13717 c3/return -13718 -13719 size-of-type-id-as-array-element: # t: type-id -> result/eax: int -13720 # . prologue -13721 55/push-ebp -13722 89/<- %ebp 4/r32/esp -13723 # eax = t -13724 8b/-> *(ebp+8) 0/r32/eax -13725 # if t is 'byte', size is 1 -13726 3d/compare-eax-and 8/imm32/byte -13727 { -13728 75/jump-if-!= break/disp8 -13729 b8/copy-to-eax 1/imm32 -13730 eb/jump $array-element-size:end/disp8 -13731 } -13732 # otherwise proceed as usual -13733 (size-of-type-id %eax) # => eax -13734 $size-of-type-id-as-array-element:end: -13735 # . epilogue -13736 89/<- %esp 5/r32/ebp -13737 5d/pop-to-ebp -13738 c3/return -13739 -13740 emit-save-size-to: # out: (addr buffered-file), base: (addr var), outreg: (addr array byte) -13741 # . prologue -13742 55/push-ebp -13743 89/<- %ebp 4/r32/esp -13744 # . save registers -13745 50/push-eax -13746 53/push-ebx -13747 # ebx = base -13748 8b/-> *(ebp+0xc) 3/r32/ebx -13749 (emit-indent *(ebp+8) *Curr-block-depth) -13750 (write-buffered *(ebp+8) "8b/-> *") -13751 # if base is an (addr array ...) in a register -13752 { -13753 81 7/subop/compare *(ebx+0x18)) 0/imm32 # Var-register -13754 74/jump-if-= break/disp8 -13755 $emit-save-size-to:emit-base-from-register: -13756 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -13757 (write-buffered *(ebp+8) %eax) -13758 eb/jump $emit-save-size-to:emit-output/disp8 -13759 } -13760 # otherwise if base is an (array ...) on the stack -13761 { -13762 81 7/subop/compare *(ebx+0x14)) 0/imm32 # Var-offset -13763 74/jump-if-= break/disp8 -13764 $emit-save-size-to:emit-base-from-stack: -13765 (write-buffered *(ebp+8) "(ebp+") -13766 (write-int32-hex-buffered *(ebp+8) *(ebx+0x14)) # Var-offset -13767 (write-buffered *(ebp+8) ")") -13768 } -13769 $emit-save-size-to:emit-output: -13770 (write-buffered *(ebp+8) " ") -13771 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax -13772 (write-int32-hex-buffered *(ebp+8) *eax) -13773 (write-buffered *(ebp+8) "/r32\n") -13774 $emit-save-size-to:end: -13775 # . restore registers -13776 5b/pop-to-ebx -13777 58/pop-to-eax -13778 # . epilogue -13779 89/<- %esp 5/r32/ebp -13780 5d/pop-to-ebp -13781 c3/return -13782 -13783 emit-divide-by-shift-right: # out: (addr buffered-file), reg: (addr array byte), size: int -13784 # . prologue -13785 55/push-ebp -13786 89/<- %ebp 4/r32/esp -13787 # . save registers -13788 50/push-eax -13789 # -13790 (emit-indent *(ebp+8) *Curr-block-depth) -13791 (write-buffered *(ebp+8) "c1/shift 5/subop/>> %") -13792 (write-buffered *(ebp+8) *(ebp+0xc)) -13793 (write-buffered *(ebp+8) Space) -13794 (num-shift-rights *(ebp+0x10)) # => eax -13795 (write-int32-hex-buffered *(ebp+8) %eax) -13796 (write-buffered *(ebp+8) "/imm8\n") -13797 $emit-divide-by-shift-right:end: -13798 # . restore registers -13799 58/pop-to-eax -13800 # . epilogue -13801 89/<- %esp 5/r32/ebp -13802 5d/pop-to-ebp -13803 c3/return -13804 -13805 translate-mu-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -13806 # . prologue -13807 55/push-ebp -13808 89/<- %ebp 4/r32/esp -13809 # . save registers -13810 51/push-ecx -13811 # ecx = stmt -13812 8b/-> *(ebp+0xc) 1/r32/ecx -13813 # var base/ecx: (addr var) = stmt->inouts[0] -13814 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -13815 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -13816 89/<- %ecx 0/r32/eax -13817 # if (var->register) do one thing -13818 { -13819 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -13820 74/jump-if-= break/disp8 -13821 # TODO: ensure there's no dereference -13822 (translate-mu-index-stmt-with-array-in-register *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -13823 eb/jump $translate-mu-index-stmt:end/disp8 -13824 } -13825 # if (var->offset) do a different thing -13826 { -13827 81 7/subop/compare *(ecx+0x14) 0/imm32 # Var-offset -13828 74/jump-if-= break/disp8 -13829 # TODO: ensure there's no dereference -13830 (translate-mu-index-stmt-with-array-on-stack *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -13831 eb/jump $translate-mu-index-stmt:end/disp8 -13832 } -13833 $translate-mu-index-stmt:end: -13834 # . restore registers -13835 59/pop-to-ecx -13836 # . epilogue -13837 89/<- %esp 5/r32/ebp -13838 5d/pop-to-ebp -13839 c3/return -13840 -13841 $translate-mu-index-stmt-with-array:error1: -13842 (write-buffered *(ebp+0x10) "couldn't translate an index instruction. second (index) input must either lie in a register or be a literal\n") -13843 (flush *(ebp+0x10)) -13844 (stop *(ebp+0x14) 1) -13845 # never gets here -13846 -13847 $translate-mu-index-stmt-with-array:error2: -13848 (write-buffered *(ebp+0x10) "couldn't translate an index instruction. second (index) input when in a register must be an int or offset\n") -13849 (flush *(ebp+0x10)) -13850 (stop *(ebp+0x14) 1) -13851 # never gets here -13852 -13853 translate-mu-index-stmt-with-array-in-register: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -13854 # . prologue -13855 55/push-ebp -13856 89/<- %ebp 4/r32/esp -13857 # . save registers -13858 50/push-eax -13859 51/push-ecx -13860 52/push-edx -13861 53/push-ebx -13862 # -13863 (emit-indent *(ebp+8) *Curr-block-depth) -13864 (write-buffered *(ebp+8) "8d/copy-address *(") -13865 # TODO: ensure inouts[0] is in a register and not dereferenced -13866 $translate-mu-index-stmt-with-array-in-register:emit-base: -13867 # ecx = stmt -13868 8b/-> *(ebp+0xc) 1/r32/ecx -13869 # var base/ebx: (addr var) = inouts[0] -13870 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -13871 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -13872 89/<- %ebx 0/r32/eax -13873 # print base->register " + " -13874 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -13875 (write-buffered *(ebp+8) %eax) -13876 (write-buffered *(ebp+8) " + ") -13877 # var index/edx: (addr var) = inouts[1] -13878 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -13879 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -13880 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -13881 89/<- %edx 0/r32/eax -13882 # if index->register -13883 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register -13884 { -13885 0f 84/jump-if-= break/disp32 -13886 $translate-mu-index-stmt-with-array-in-register:emit-register-index: -13887 # if index is an int -13888 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -13889 (is-simple-mu-type? %eax 1) # int => eax -13890 3d/compare-eax-and 0/imm32/false -13891 { -13892 0f 84/jump-if-= break/disp32 -13893 $translate-mu-index-stmt-with-array-in-register:emit-int-register-index: -13894 # print index->register "<<" log2(array-element-size(base)) " + 4) " -13895 # . index->register "<<" -13896 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -13897 (write-buffered *(ebp+8) %eax) -13898 (write-buffered *(ebp+8) "<<") -13899 # . log2(array-element-size(base->type)) -13900 # TODO: ensure size is a power of 2 -13901 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -13902 (num-shift-rights %eax) # => eax -13903 (write-int32-hex-buffered *(ebp+8) %eax) -13904 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-register-index-done/disp32 -13905 } -13906 # if index->type is any other atom, abort -13907 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -13908 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -13909 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 -13910 # if index has type (offset ...) -13911 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -13912 (is-simple-mu-type? %eax 7) # => eax -13913 3d/compare-eax-and 0/imm32/false -13914 { -13915 0f 84/jump-if-= break/disp32 -13916 # print index->register -13917 $translate-mu-index-stmt-with-array-in-register:emit-offset-register-index: -13918 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -13919 (write-buffered *(ebp+8) %eax) -13920 } -13921 $translate-mu-index-stmt-with-array-in-register:emit-register-index-done: -13922 (write-buffered *(ebp+8) " + 4) ") -13923 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 -13924 } -13925 # otherwise if index is a literal -13926 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -13927 (is-simple-mu-type? %eax 0) # => eax -13928 3d/compare-eax-and 0/imm32/false -13929 { -13930 0f 84/jump-if-= break/disp32 -13931 $translate-mu-index-stmt-with-array-in-register:emit-literal-index: -13932 # var index-value/edx: int = parse-hex-int(index->name) -13933 (lookup *edx *(edx+4)) # Var-name Var-name => eax -13934 (parse-hex-int %eax) # => eax -13935 89/<- %edx 0/r32/eax -13936 # offset = idx-value * array-element-size(base->type) -13937 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -13938 f7 4/subop/multiply-into-eax %edx # clobbers edx -13939 # offset += 4 for array size -13940 05/add-to-eax 4/imm32 -13941 # TODO: check edx for overflow -13942 # print offset -13943 (write-int32-hex-buffered *(ebp+8) %eax) -13944 (write-buffered *(ebp+8) ") ") -13945 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 -13946 } -13947 # otherwise abort -13948 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 -13949 $translate-mu-index-stmt-with-array-in-register:emit-output: -13950 # outputs[0] "/r32" -13951 8b/-> *(ebp+0xc) 1/r32/ecx -13952 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -13953 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -13954 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -13955 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -13956 (write-int32-hex-buffered *(ebp+8) *eax) -13957 (write-buffered *(ebp+8) "/r32\n") -13958 $translate-mu-index-stmt-with-array-in-register:end: -13959 # . restore registers -13960 5b/pop-to-ebx -13961 5a/pop-to-edx -13962 59/pop-to-ecx -13963 58/pop-to-eax -13964 # . epilogue -13965 89/<- %esp 5/r32/ebp -13966 5d/pop-to-ebp -13967 c3/return -13968 -13969 translate-mu-index-stmt-with-array-on-stack: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -13970 # . prologue -13971 55/push-ebp -13972 89/<- %ebp 4/r32/esp -13973 # . save registers -13974 50/push-eax -13975 51/push-ecx -13976 52/push-edx -13977 53/push-ebx -13978 # -13979 (emit-indent *(ebp+8) *Curr-block-depth) -13980 (write-buffered *(ebp+8) "8d/copy-address *(ebp + ") -13981 # var curr/edx: (addr stmt-var) = lookup(stmt->inouts) -13982 8b/-> *(ebp+0xc) 0/r32/eax -13983 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -13984 89/<- %edx 0/r32/eax -13985 # var base/ecx: (addr var) = lookup(curr->value) -13986 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -13987 89/<- %ecx 0/r32/eax -13988 # var curr2/eax: (addr stmt-var) = lookup(curr->next) -13989 (lookup *(edx+8) *(edx+0xc)) # Stmt-var-next Stmt-var-next => eax -13990 # var index/edx: (handle var) = curr2->value -13991 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -13992 89/<- %edx 0/r32/eax -13993 # if index->register -13994 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register -13995 { -13996 0f 84/jump-if-= break/disp32 -13997 $translate-mu-index-stmt-with-array-on-stack:emit-register-index: -13998 # if index is an int -13999 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -14000 (is-simple-mu-type? %eax 1) # int => eax -14001 3d/compare-eax-and 0/imm32/false -14002 { -14003 0f 84/jump-if-= break/disp32 -14004 $translate-mu-index-stmt-with-array-on-stack:emit-int-register-index: -14005 # print index->register "<<" log2(array-element-size(base)) " + " base->offset+4 -14006 # . inouts[1]->register "<<" -14007 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -14008 (write-buffered *(ebp+8) %eax) -14009 (write-buffered *(ebp+8) "<<") -14010 # . log2(array-element-size(base)) -14011 # TODO: ensure size is a power of 2 -14012 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax -14013 (num-shift-rights %eax) # => eax -14014 (write-int32-hex-buffered *(ebp+8) %eax) -14015 # -14016 (write-buffered *(ebp+8) " + ") -14017 # -14018 8b/-> *(ecx+0x14) 0/r32/eax # Var-offset -14019 05/add-to-eax 4/imm32 # for array length -14020 (write-int32-hex-buffered *(ebp+8) %eax) -14021 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done/disp32 -14022 } -14023 # if index->type is any other atom, abort -14024 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -14025 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -14026 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 -14027 # if index has type (offset ...) -14028 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -14029 (is-simple-mu-type? %eax 7) # => eax -14030 3d/compare-eax-and 0/imm32/false -14031 { -14032 0f 84/jump-if-= break/disp32 -14033 # print index->register -14034 $translate-mu-index-stmt-with-array-on-stack:emit-offset-register-index: -14035 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -14036 (write-buffered *(ebp+8) %eax) -14037 } -14038 $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done: -14039 (write-buffered *(ebp+8) ") ") -14040 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 -14041 } -14042 # otherwise if index is a literal -14043 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -14044 (is-simple-mu-type? %eax 0) # => eax -14045 3d/compare-eax-and 0/imm32/false -14046 { -14047 0f 84/jump-if-= break/disp32 -14048 $translate-mu-index-stmt-with-array-on-stack:emit-literal-index: -14049 # var idx-value/edx: int = parse-hex-int(index->name) -14050 (lookup *edx *(edx+4)) # Var-name Var-name => eax -14051 (parse-hex-int %eax) # Var-name => eax -14052 89/<- %edx 0/r32/eax -14053 # offset = idx-value * array-element-size(base) -14054 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax -14055 f7 4/subop/multiply-into-eax %edx # clobbers edx -14056 # offset += base->offset -14057 03/add *(ecx+0x14) 0/r32/eax # Var-offset -14058 # offset += 4 for array size -14059 05/add-to-eax 4/imm32 -14060 # TODO: check edx for overflow -14061 # print offset -14062 (write-int32-hex-buffered *(ebp+8) %eax) -14063 (write-buffered *(ebp+8) ") ") -14064 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 -14065 } -14066 # otherwise abort -14067 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 -14068 $translate-mu-index-stmt-with-array-on-stack:emit-output: -14069 # outputs[0] "/r32" -14070 8b/-> *(ebp+0xc) 0/r32/eax -14071 (lookup *(eax+0x14) *(eax+0x18)) # Stmt1-outputs Stmt1-outputs => eax -14072 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -14073 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -14074 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -14075 (write-int32-hex-buffered *(ebp+8) *eax) -14076 (write-buffered *(ebp+8) "/r32\n") -14077 $translate-mu-index-stmt-with-array-on-stack:end: -14078 # . restore registers -14079 5b/pop-to-ebx -14080 5a/pop-to-edx -14081 59/pop-to-ecx -14082 58/pop-to-eax -14083 # . epilogue -14084 89/<- %esp 5/r32/ebp -14085 5d/pop-to-ebp -14086 c3/return -14087 -14088 translate-mu-compute-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -14089 # . prologue -14090 55/push-ebp -14091 89/<- %ebp 4/r32/esp -14092 # . save registers -14093 50/push-eax -14094 51/push-ecx -14095 52/push-edx -14096 53/push-ebx -14097 # -14098 (emit-indent *(ebp+8) *Curr-block-depth) -14099 (write-buffered *(ebp+8) "69/multiply") -14100 # ecx = stmt -14101 8b/-> *(ebp+0xc) 1/r32/ecx -14102 # var first-inout/ebx: (addr stmt-var) = stmt->inouts[0] -14103 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -14104 89/<- %ebx 0/r32/eax -14105 $translate-mu-compute-index-stmt:emit-index: -14106 (lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax -14107 (emit-subx-var-as-rm32 *(ebp+8) %eax) -14108 (write-buffered *(ebp+8) Space) -14109 $translate-mu-compute-index-stmt:emit-elem-size: -14110 # var base/ebx: (addr var) -14111 (lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax -14112 89/<- %ebx 0/r32/eax -14113 # print array-element-size(base) -14114 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -14115 (write-int32-hex-buffered *(ebp+8) %eax) -14116 (write-buffered *(ebp+8) "/imm32 ") -14117 $translate-mu-compute-index-stmt:emit-output: -14118 # outputs[0] "/r32" -14119 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -14120 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -14121 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -14122 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -14123 (write-int32-hex-buffered *(ebp+8) *eax) -14124 (write-buffered *(ebp+8) "/r32\n") -14125 $translate-mu-compute-index-stmt:end: -14126 # . restore registers -14127 5b/pop-to-ebx -14128 5a/pop-to-edx -14129 59/pop-to-ecx -14130 58/pop-to-eax -14131 # . epilogue -14132 89/<- %esp 5/r32/ebp -14133 5d/pop-to-ebp -14134 c3/return -14135 -14136 translate-mu-get-stmt: # out: (addr buffered-file), stmt: (addr stmt) -14137 # . prologue -14138 55/push-ebp -14139 89/<- %ebp 4/r32/esp -14140 # . save registers -14141 50/push-eax -14142 51/push-ecx -14143 52/push-edx -14144 # -14145 (emit-indent *(ebp+8) *Curr-block-depth) -14146 (write-buffered *(ebp+8) "8d/copy-address ") -14147 # ecx = stmt -14148 8b/-> *(ebp+0xc) 1/r32/ecx -14149 # var offset/edx: int = get offset of stmt -14150 (mu-get-offset %ecx) # => eax -14151 89/<- %edx 0/r32/eax -14152 # var base/eax: (addr var) = stmt->inouts->value -14153 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -14154 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -14155 # if base is in a register -14156 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -14157 { -14158 0f 84/jump-if-= break/disp32 -14159 $translate-mu-get-stmt:emit-register-input: -14160 # emit "*(" base->register " + " offset ") " -14161 (write-buffered *(ebp+8) "*(") -14162 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -14163 (write-buffered *(ebp+8) %eax) -14164 (write-buffered *(ebp+8) " + ") -14165 (write-int32-hex-buffered *(ebp+8) %edx) -14166 (write-buffered *(ebp+8) ") ") -14167 e9/jump $translate-mu-get-stmt:emit-output/disp32 -14168 } -14169 # otherwise base is on the stack -14170 { -14171 $translate-mu-get-stmt:emit-stack-input: -14172 # emit "*(ebp + " inouts[0]->stack-offset + offset ") " -14173 (write-buffered *(ebp+8) "*(ebp+") -14174 03/add *(eax+0x14) 2/r32/edx # Var-offset -14175 (write-int32-hex-buffered *(ebp+8) %edx) -14176 (write-buffered *(ebp+8) ") ") -14177 eb/jump $translate-mu-get-stmt:emit-output/disp8 +13706 # emit clean-up code for 'vars' until a given label is encountered +13707 # doesn't actually modify 'vars' so we need traverse manually inside the stack +13708 emit-cleanup-code-until-target: # out: (addr buffered-file), vars: (addr stack live-var), until-block-label: (addr array byte) +13709 # . prologue +13710 55/push-ebp +13711 89/<- %ebp 4/r32/esp +13712 # . save registers +13713 50/push-eax +13714 51/push-ecx +13715 52/push-edx +13716 53/push-ebx +13717 # ecx = vars +13718 8b/-> *(ebp+0xc) 1/r32/ecx +13719 # var eax: int = vars->top +13720 8b/-> *ecx 0/r32/eax +13721 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] +13722 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size +13723 # var min/ecx: (addr handle var) = vars->data +13724 81 0/subop/add %ecx 8/imm32 +13725 { +13726 $emit-cleanup-code-until-target:loop: +13727 # if (curr < min) break +13728 39/compare %edx 1/r32/ecx +13729 0f 82/jump-if-addr< break/disp32 +13730 # var v/ebx: (handle var) = lookup(*curr) +13731 (lookup *edx *(edx+4)) # => eax +13732 89/<- %ebx 0/r32/eax +13733 # if (v->name == until-block-label) break +13734 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +13735 (string-equal? %eax *(ebp+0x10)) # => eax +13736 3d/compare-eax-and 0/imm32/false +13737 0f 85/jump-if-!= break/disp32 +13738 # if v is in a register +13739 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register +13740 { +13741 0f 84/jump-if-= break/disp32 +13742 { +13743 $emit-cleanup-code-until-target:check-for-previous-spill: +13744 8b/-> *(edx+8) 0/r32/eax # Live-var-register-spilled +13745 3d/compare-eax-and 0/imm32/false +13746 74/jump-if-= break/disp8 +13747 $emit-cleanup-code-until-target:reclaim-var-in-register: +13748 (emit-indent *(ebp+8) *Curr-block-depth) +13749 (write-buffered *(ebp+8) "8f 0/subop/pop %") +13750 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +13751 (write-buffered *(ebp+8) %eax) +13752 (write-buffered *(ebp+8) Newline) +13753 } +13754 eb/jump $emit-cleanup-code-until-target:continue/disp8 +13755 } +13756 # otherwise v is on the stack +13757 { +13758 75/jump-if-!= break/disp8 +13759 $emit-cleanup-code-until-target:reclaim-var-on-stack: +13760 (size-of %ebx) # => eax +13761 # don't emit code for labels +13762 3d/compare-eax-and 0/imm32 +13763 74/jump-if-= break/disp8 +13764 # +13765 (emit-indent *(ebp+8) *Curr-block-depth) +13766 (write-buffered *(ebp+8) "81 0/subop/add %esp ") +13767 (write-int32-hex-buffered *(ebp+8) %eax) +13768 (write-buffered *(ebp+8) "/imm32\n") +13769 } +13770 $emit-cleanup-code-until-target:continue: +13771 # curr -= 12 +13772 81 5/subop/subtract %edx 0xc/imm32 +13773 e9/jump loop/disp32 +13774 } +13775 $emit-cleanup-code-until-target:end: +13776 # . restore registers +13777 5b/pop-to-ebx +13778 5a/pop-to-edx +13779 59/pop-to-ecx +13780 58/pop-to-eax +13781 # . epilogue +13782 89/<- %esp 5/r32/ebp +13783 5d/pop-to-ebp +13784 c3/return +13785 +13786 # Return true if there isn't a variable in 'vars' with the same block-depth +13787 # and register as 'v'. +13788 # 'v' is guaranteed not to be within 'vars'. +13789 not-yet-spilled-this-block?: # v: (addr var), vars: (addr stack live-var) -> result/eax: boolean +13790 # . prologue +13791 55/push-ebp +13792 89/<- %ebp 4/r32/esp +13793 # . save registers +13794 51/push-ecx +13795 52/push-edx +13796 53/push-ebx +13797 56/push-esi +13798 57/push-edi +13799 # ecx = vars +13800 8b/-> *(ebp+0xc) 1/r32/ecx +13801 # var eax: int = vars->top +13802 8b/-> *ecx 0/r32/eax +13803 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] +13804 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size +13805 # var min/ecx: (addr handle var) = vars->data +13806 8d/copy-address *(ecx+8) 1/r32/ecx +13807 # var depth/ebx: int = v->block-depth +13808 8b/-> *(ebp+8) 3/r32/ebx +13809 8b/-> *(ebx+0x10) 3/r32/ebx # Var-block-depth +13810 # var needle/esi: (addr array byte) = v->register +13811 8b/-> *(ebp+8) 6/r32/esi +13812 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +13813 89/<- %esi 0/r32/eax +13814 { +13815 $not-yet-spilled-this-block?:loop: +13816 # if (curr < min) break +13817 39/compare %edx 1/r32/ecx +13818 0f 82/jump-if-addr< break/disp32 +13819 # var cand/edi: (addr var) = lookup(*curr) +13820 (lookup *edx *(edx+4)) # => eax +13821 89/<- %edi 0/r32/eax +13822 # if (cand->block-depth < depth) break +13823 39/compare *(edi+0x10) 3/r32/ebx # Var-block-depth +13824 0f 8c/jump-if-< break/disp32 +13825 # var cand-reg/edi: (array array byte) = cand->reg +13826 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +13827 89/<- %edi 0/r32/eax +13828 # if (cand-reg == null) continue +13829 { +13830 $not-yet-spilled-this-block?:check-reg: +13831 81 7/subop/compare %edi 0/imm32 +13832 0f 84/jump-if-= break/disp32 +13833 # if (cand-reg == needle) return true +13834 (string-equal? %esi %edi) # => eax +13835 3d/compare-eax-and 0/imm32/false +13836 74/jump-if-= break/disp8 +13837 $not-yet-spilled-this-block?:return-false: +13838 b8/copy-to-eax 0/imm32/false +13839 eb/jump $not-yet-spilled-this-block?:end/disp8 +13840 } +13841 $not-yet-spilled-this-block?:continue: +13842 # curr -= 12 +13843 81 5/subop/subtract %edx 0xc/imm32 +13844 e9/jump loop/disp32 +13845 } +13846 $not-yet-spilled-this-block?:return-true: +13847 # return true +13848 b8/copy-to-eax 1/imm32/true +13849 $not-yet-spilled-this-block?:end: +13850 # . restore registers +13851 5f/pop-to-edi +13852 5e/pop-to-esi +13853 5b/pop-to-ebx +13854 5a/pop-to-edx +13855 59/pop-to-ecx +13856 # . epilogue +13857 89/<- %esp 5/r32/ebp +13858 5d/pop-to-ebp +13859 c3/return +13860 +13861 # could the register of 'v' ever be written to by one of the vars in fn-outputs? +13862 will-not-write-some-register?: # v: (addr var), stmts: (addr list stmt), fn: (addr function) -> result/eax: boolean +13863 # . prologue +13864 55/push-ebp +13865 89/<- %ebp 4/r32/esp +13866 # eax = v +13867 8b/-> *(ebp+8) 0/r32/eax +13868 # var reg/eax: (addr array byte) = lookup(v->register) +13869 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +13870 # var target/eax: (addr var) = find-register(fn-outputs, reg) +13871 (find-register *(ebp+0x10) %eax) # => eax +13872 # if (target == 0) return true +13873 { +13874 3d/compare-eax-and 0/imm32 +13875 75/jump-if-!= break/disp8 +13876 b8/copy-to-eax 1/imm32/true +13877 eb/jump $will-not-write-some-register?:end/disp8 +13878 } +13879 # return !assigns-in-stmts?(stmts, target) +13880 (assigns-in-stmts? *(ebp+0xc) %eax) # => eax +13881 3d/compare-eax-and 0/imm32/false +13882 # assume: true = 1, so no need to mask with 0x000000ff +13883 0f 94/set-if-= %al +13884 $will-not-write-some-register?:end: +13885 # . epilogue +13886 89/<- %esp 5/r32/ebp +13887 5d/pop-to-ebp +13888 c3/return +13889 +13890 # return fn output with matching register +13891 # always returns false if 'reg' is null +13892 find-register: # fn: (addr function), reg: (addr array byte) -> result/eax: (addr var) +13893 # . prologue +13894 55/push-ebp +13895 89/<- %ebp 4/r32/esp +13896 # . save registers +13897 51/push-ecx +13898 # var curr/ecx: (addr list var) = lookup(fn->outputs) +13899 8b/-> *(ebp+8) 1/r32/ecx +13900 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax +13901 89/<- %ecx 0/r32/eax +13902 { +13903 $find-register:loop: +13904 # if (curr == 0) break +13905 81 7/subop/compare %ecx 0/imm32 +13906 74/jump-if-= break/disp8 +13907 # eax = curr->value->register +13908 (lookup *ecx *(ecx+4)) # List-value List-value => eax +13909 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +13910 # if (eax == reg) return curr->value +13911 $find-register:compare: +13912 (string-equal? *(ebp+0xc) %eax) # => eax +13913 { +13914 3d/compare-eax-and 0/imm32/false +13915 74/jump-if-= break/disp8 +13916 $find-register:found: +13917 (lookup *ecx *(ecx+4)) # List-value List-value => eax +13918 eb/jump $find-register:end/disp8 +13919 } +13920 # curr = lookup(curr->next) +13921 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +13922 89/<- %ecx 0/r32/eax +13923 # +13924 eb/jump loop/disp8 +13925 } +13926 $find-register:end: +13927 # . restore registers +13928 59/pop-to-ecx +13929 # . epilogue +13930 89/<- %esp 5/r32/ebp +13931 5d/pop-to-ebp +13932 c3/return +13933 +13934 assigns-in-stmts?: # stmts: (addr list stmt), v: (addr var) -> result/eax: boolean +13935 # . prologue +13936 55/push-ebp +13937 89/<- %ebp 4/r32/esp +13938 # . save registers +13939 51/push-ecx +13940 # var curr/ecx: (addr list stmt) = stmts +13941 8b/-> *(ebp+8) 1/r32/ecx +13942 { +13943 # if (curr == 0) break +13944 81 7/subop/compare %ecx 0/imm32 +13945 74/jump-if-= break/disp8 +13946 # if assigns-in-stmt?(curr->value, v) return true +13947 (lookup *ecx *(ecx+4)) # List-value List-value => eax +13948 (assigns-in-stmt? %eax *(ebp+0xc)) # => eax +13949 3d/compare-eax-and 0/imm32/false +13950 75/jump-if-!= break/disp8 +13951 # curr = lookup(curr->next) +13952 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +13953 89/<- %ecx 0/r32/eax +13954 # +13955 eb/jump loop/disp8 +13956 } +13957 $assigns-in-stmts?:end: +13958 # . restore registers +13959 59/pop-to-ecx +13960 # . epilogue +13961 89/<- %esp 5/r32/ebp +13962 5d/pop-to-ebp +13963 c3/return +13964 +13965 assigns-in-stmt?: # stmt: (addr stmt), v: (addr var) -> result/eax: boolean +13966 # . prologue +13967 55/push-ebp +13968 89/<- %ebp 4/r32/esp +13969 # . save registers +13970 51/push-ecx +13971 # ecx = stmt +13972 8b/-> *(ebp+8) 1/r32/ecx +13973 # if stmt is a stmt1, return assigns-in-stmt-vars?(stmt->outputs, v) +13974 { +13975 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag +13976 75/jump-if-!= break/disp8 +13977 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13978 (assigns-in-stmt-vars? %eax *(ebp+0xc)) # => eax +13979 eb/jump $assigns-in-stmt?:end/disp8 +13980 } +13981 # if stmt is a block, return assigns-in-stmts?(stmt->stmts, v) +13982 { +13983 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag +13984 75/jump-if-!= break/disp8 +13985 (lookup *(ecx+4) *(ecx+8)) # Block-stmts Block-stmts => eax +13986 (assigns-in-stmts? %eax *(ebp+0xc)) # => eax +13987 eb/jump $assigns-in-stmt?:end/disp8 +13988 } +13989 # otherwise return false +13990 b8/copy 0/imm32/false +13991 $assigns-in-stmt?:end: +13992 # . restore registers +13993 59/pop-to-ecx +13994 # . epilogue +13995 89/<- %esp 5/r32/ebp +13996 5d/pop-to-ebp +13997 c3/return +13998 +13999 assigns-in-stmt-vars?: # stmt-var: (addr stmt-var), v: (addr var) -> result/eax: boolean +14000 # . prologue +14001 55/push-ebp +14002 89/<- %ebp 4/r32/esp +14003 # . save registers +14004 51/push-ecx +14005 # var curr/ecx: (addr stmt-var) = stmt-var +14006 8b/-> *(ebp+8) 1/r32/ecx +14007 { +14008 # if (curr == 0) break +14009 81 7/subop/compare %ecx 0/imm32 +14010 74/jump-if-= break/disp8 +14011 # eax = lookup(curr->value) +14012 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +14013 # if (eax == v && curr->is-deref? == false) return true +14014 { +14015 39/compare *(ebp+0xc) 0/r32/eax +14016 75/jump-if-!= break/disp8 +14017 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +14018 75/jump-if-!= break/disp8 +14019 b8/copy-to-eax 1/imm32/true +14020 eb/jump $assigns-in-stmt-vars?:end/disp8 +14021 } +14022 # curr = lookup(curr->next) +14023 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +14024 89/<- %ecx 0/r32/eax +14025 # +14026 eb/jump loop/disp8 +14027 } +14028 $assigns-in-stmt-vars?:end: +14029 # . restore registers +14030 59/pop-to-ecx +14031 # . epilogue +14032 89/<- %esp 5/r32/ebp +14033 5d/pop-to-ebp +14034 c3/return +14035 +14036 # is there a var before 'v' with the same block-depth and register on the 'vars' stack? +14037 # v is guaranteed to be within vars +14038 # 'start' is provided as an optimization, a pointer within vars +14039 # *start == v +14040 same-register-spilled-before?: # v: (addr var), vars: (addr stack (handle var)), start: (addr var) -> result/eax: boolean +14041 # . prologue +14042 55/push-ebp +14043 89/<- %ebp 4/r32/esp +14044 # . save registers +14045 51/push-ecx +14046 52/push-edx +14047 53/push-ebx +14048 56/push-esi +14049 57/push-edi +14050 # ecx = v +14051 8b/-> *(ebp+8) 1/r32/ecx +14052 # var reg/edx: (addr array byte) = lookup(v->register) +14053 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +14054 89/<- %edx 0/r32/eax +14055 # var depth/ebx: int = v->block-depth +14056 8b/-> *(ecx+0x10) 3/r32/ebx # Var-block-depth +14057 # var min/ecx: (addr handle var) = vars->data +14058 8b/-> *(ebp+0xc) 1/r32/ecx +14059 81 0/subop/add %ecx 8/imm32 +14060 # TODO: check that start >= min and start < &vars->data[top] +14061 # TODO: check that *start == v +14062 # var curr/esi: (addr handle var) = start +14063 8b/-> *(ebp+0x10) 6/r32/esi +14064 # curr -= 8 +14065 81 5/subop/subtract %esi 8/imm32 +14066 { +14067 $same-register-spilled-before?:loop: +14068 # if (curr < min) break +14069 39/compare %esi 1/r32/ecx +14070 0f 82/jump-if-addr< break/disp32 +14071 # var x/eax: (addr var) = lookup(*curr) +14072 (lookup *esi *(esi+4)) # => eax +14073 # if (x->block-depth < depth) break +14074 39/compare *(eax+0x10) 3/r32/ebx # Var-block-depth +14075 0f 8c/jump-if-< break/disp32 +14076 # if (x->register == 0) continue +14077 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +14078 74/jump-if-= $same-register-spilled-before?:continue/disp8 +14079 # if (x->register == reg) return true +14080 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +14081 (string-equal? %eax %edx) # => eax +14082 3d/compare-eax-and 0/imm32/false +14083 b8/copy-to-eax 1/imm32/true +14084 75/jump-if-!= $same-register-spilled-before?:end/disp8 +14085 $same-register-spilled-before?:continue: +14086 # curr -= 8 +14087 81 5/subop/subtract %esi 8/imm32 +14088 e9/jump loop/disp32 +14089 } +14090 $same-register-spilled-before?:false: +14091 b8/copy-to-eax 0/imm32/false +14092 $same-register-spilled-before?:end: +14093 # . restore registers +14094 5f/pop-to-edi +14095 5e/pop-to-esi +14096 5b/pop-to-ebx +14097 5a/pop-to-edx +14098 59/pop-to-ecx +14099 # . epilogue +14100 89/<- %esp 5/r32/ebp +14101 5d/pop-to-ebp +14102 c3/return +14103 +14104 # Clean up global state for 'vars' until some block depth (inclusive). +14105 # +14106 # This would be a simple series of pops, if it wasn't for fn outputs, which +14107 # can occur anywhere in the stack. +14108 # So we have to _compact_ the entire array underlying the stack. +14109 # +14110 # We want to allow a fn output register to be written to by locals before the +14111 # output is set. +14112 # So fn outputs can't just be pushed at the start of the function. +14113 # +14114 # We want to allow other locals to shadow a fn output register after the +14115 # output is set. +14116 # So the output can't just always override anything in the stack. Sequence matters. +14117 clean-up-blocks: # vars: (addr stack live-var), until-block-depth: int, fn: (addr function) +14118 # pseudocode: +14119 # to = vars->top (which points outside the stack) +14120 # while true +14121 # if to <= 0 +14122 # break +14123 # var v = vars->data[to-1] +14124 # if v.depth < until and !in-function-outputs?(fn, v) +14125 # break +14126 # --to +14127 # from = to +14128 # while true +14129 # if from >= vars->top +14130 # break +14131 # assert(from >= to) +14132 # v = vars->data[from] +14133 # if in-function-outputs?(fn, v) +14134 # if from > to +14135 # vars->data[to] = vars->data[from] +14136 # ++to +14137 # ++from +14138 # vars->top = to +14139 # +14140 # . prologue +14141 55/push-ebp +14142 89/<- %ebp 4/r32/esp +14143 # . save registers +14144 50/push-eax +14145 52/push-edx +14146 53/push-ebx +14147 56/push-esi +14148 57/push-edi +14149 # ebx = vars +14150 8b/-> *(ebp+8) 3/r32/ebx +14151 # edx = until-block-depth +14152 8b/-> *(ebp+0xc) 2/r32/edx +14153 $clean-up-blocks:phase1: +14154 # var to/edi: int = vars->top +14155 8b/-> *ebx 7/r32/edi +14156 { +14157 $clean-up-blocks:loop1: +14158 # if (to <= 0) break +14159 81 7/subop/compare %edi 0/imm32 +14160 7e/jump-if-<= break/disp8 +14161 # var v/eax: (addr var) = lookup(vars->data[to-1]->var) +14162 8d/copy-address *(ebx+edi-4) 0/r32/eax # vars + 8 + to - 12 +14163 (lookup *eax *(eax+4)) # => eax +14164 # if (v->block-depth >= until-block-depth) continue +14165 39/compare *(eax+0x10) 2/r32/edx # Var-block-depth +14166 { +14167 7d/jump-if->= break/disp8 +14168 # if (!in-function-outputs?(fn, v)) break +14169 (in-function-outputs? *(ebp+0x10) %eax) # => eax +14170 3d/compare-eax-and 0/imm32/false +14171 74/jump-if-= $clean-up-blocks:phase2/disp8 +14172 } +14173 $clean-up-blocks:loop1-continue: +14174 # --to +14175 81 5/subop/subtract %edi 0xc/imm32 +14176 # +14177 eb/jump loop/disp8 14178 } -14179 $translate-mu-get-stmt:emit-output: -14180 # var output/eax: (addr var) = stmt->outputs->value -14181 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -14182 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -14183 # emit offset->register "/r32" -14184 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -14185 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -14186 (write-int32-hex-buffered *(ebp+8) *eax) -14187 (write-buffered *(ebp+8) "/r32\n") -14188 $translate-mu-get-stmt:end: -14189 # . restore registers -14190 5a/pop-to-edx -14191 59/pop-to-ecx -14192 58/pop-to-eax -14193 # . epilogue -14194 89/<- %esp 5/r32/ebp -14195 5d/pop-to-ebp -14196 c3/return -14197 -14198 array-element-type-id: # v: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: type-id -14199 # precondition: n is positive -14200 # . prologue -14201 55/push-ebp -14202 89/<- %ebp 4/r32/esp -14203 # -14204 8b/-> *(ebp+8) 0/r32/eax -14205 # var t/eax: (addr type-tree) -14206 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -14207 # if t == 0 abort -14208 3d/compare-eax-with 0/imm32 -14209 0f 84/jump-if-== $array-element-type-id:error0/disp32 -14210 # if t->is-atom? abort -14211 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -14212 0f 85/jump-if-!= $array-element-type-id:error1/disp32 -14213 # if (t->left == addr) t = t->right -14214 { -14215 50/push-eax -14216 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -14217 (is-simple-mu-type? %eax 2) # addr => eax -14218 3d/compare-eax-with 0/imm32/false -14219 58/pop-to-eax -14220 74/jump-if-= break/disp8 -14221 $array-element-type-id:skip-addr: -14222 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -14223 } -14224 # if t == 0 abort -14225 3d/compare-eax-with 0/imm32 -14226 0f 84/jump-if-= $array-element-type-id:error2/disp32 -14227 # if t->is-atom? abort -14228 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -14229 0f 85/jump-if-!= $array-element-type-id:error2/disp32 -14230 # if t->left != array abort -14231 { -14232 50/push-eax -14233 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -14234 (is-simple-mu-type? %eax 3) # array => eax -14235 3d/compare-eax-with 0/imm32/false -14236 58/pop-to-eax -14237 $array-element-type-id:no-array: -14238 0f 84/jump-if-= $array-element-type-id:error2/disp32 -14239 } -14240 $array-element-type-id:skip-array: -14241 # t = t->right -14242 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax -14243 # if t == 0 abort -14244 3d/compare-eax-with 0/imm32 -14245 0f 84/jump-if-= $array-element-type-id:error2/disp32 -14246 # if t->is-atom? abort -14247 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -14248 0f 85/jump-if-!= $array-element-type-id:error2/disp32 -14249 # return t->left->value -14250 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -14251 8b/-> *(eax+4) 0/r32/eax # Type-tree-value -14252 $array-element-type-id:end: -14253 # . epilogue -14254 89/<- %esp 5/r32/ebp -14255 5d/pop-to-ebp -14256 c3/return -14257 -14258 $array-element-type-id:error0: -14259 (write-buffered *(ebp+0xc) "array-element-type-id: var '") -14260 50/push-eax -14261 8b/-> *(ebp+8) 0/r32/eax -14262 (lookup *eax *(eax+4)) # Var-name Var-name => eax -14263 (write-buffered *(ebp+0xc) %eax) -14264 58/pop-to-eax -14265 (write-buffered *(ebp+0xc) "' has no type\n") -14266 (flush *(ebp+0xc)) -14267 (stop *(ebp+0x10) 1) -14268 # never gets here -14269 -14270 $array-element-type-id:error1: -14271 (write-buffered *(ebp+0xc) "array-element-type-id: var '") -14272 50/push-eax -14273 8b/-> *(ebp+8) 0/r32/eax -14274 (lookup *eax *(eax+4)) # Var-name Var-name => eax -14275 (write-buffered *(ebp+0xc) %eax) -14276 58/pop-to-eax -14277 (write-buffered *(ebp+0xc) "' has atomic type ") -14278 (write-int32-hex-buffered *(ebp+0xc) *(eax+4)) # Type-tree-value -14279 (write-buffered *(ebp+0xc) Newline) -14280 (flush *(ebp+0xc)) -14281 (stop *(ebp+0x10) 1) -14282 # never gets here -14283 -14284 $array-element-type-id:error2: -14285 (write-buffered *(ebp+0xc) "array-element-type-id: var '") -14286 50/push-eax -14287 8b/-> *(ebp+8) 0/r32/eax -14288 (lookup *eax *(eax+4)) # Var-name Var-name => eax -14289 (write-buffered *(ebp+0xc) %eax) -14290 58/pop-to-eax -14291 (write-buffered *(ebp+0xc) "' has non-array type\n") -14292 (flush *(ebp+0xc)) -14293 (stop *(ebp+0x10) 1) -14294 # never gets here -14295 -14296 power-of-2?: # n: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: boolean -14297 # precondition: n is positive -14298 # . prologue -14299 55/push-ebp -14300 89/<- %ebp 4/r32/esp -14301 # eax = n -14302 8b/-> *(ebp+8) 0/r32/eax -14303 # if (n < 0) abort -14304 3d/compare-eax-with 0/imm32 -14305 0f 8c/jump-if-< $power-of-2?:abort/disp32 -14306 # var tmp/eax: int = n-1 -14307 48/decrement-eax -14308 # var tmp2/eax: int = n & tmp -14309 23/and-> *(ebp+8) 0/r32/eax -14310 # return (tmp2 == 0) -14311 3d/compare-eax-and 0/imm32 -14312 0f 94/set-byte-if-= %al -14313 81 4/subop/and %eax 0xff/imm32 -14314 $power-of-2?:end: -14315 # . epilogue -14316 89/<- %esp 5/r32/ebp -14317 5d/pop-to-ebp -14318 c3/return -14319 -14320 $power-of-2?:abort: -14321 (write-buffered *(ebp+0xc) "power-of-2?: negative number\n") -14322 (flush *(ebp+0xc)) -14323 (stop *(ebp+0x10) 1) -14324 # never gets here -14325 -14326 num-shift-rights: # n: int -> result/eax: int -14327 # precondition: n is a positive power of 2 -14328 # . prologue -14329 55/push-ebp -14330 89/<- %ebp 4/r32/esp -14331 # . save registers -14332 51/push-ecx -14333 # var curr/ecx: int = n -14334 8b/-> *(ebp+8) 1/r32/ecx -14335 # result = 0 -14336 b8/copy-to-eax 0/imm32 -14337 { -14338 # if (curr <= 1) break -14339 81 7/subop/compare %ecx 1/imm32 -14340 7e/jump-if-<= break/disp8 -14341 40/increment-eax -14342 c1/shift 5/subop/arithmetic-right %ecx 1/imm8 -14343 eb/jump loop/disp8 -14344 } -14345 $num-shift-rights:end: -14346 # . restore registers -14347 59/pop-to-ecx -14348 # . epilogue -14349 89/<- %esp 5/r32/ebp -14350 5d/pop-to-ebp -14351 c3/return -14352 -14353 mu-get-offset: # stmt: (addr stmt) -> result/eax: int -14354 # . prologue -14355 55/push-ebp -14356 89/<- %ebp 4/r32/esp -14357 # var second-inout/eax: (addr stmt-var) = stmt->inouts->next -14358 8b/-> *(ebp+8) 0/r32/eax -14359 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -14360 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -14361 # var output-var/eax: (addr var) = second-inout->value -14362 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -14363 #? (write-buffered Stderr "mu-get-offset: ") -14364 #? (write-int32-hex-buffered Stderr %eax) -14365 #? (write-buffered Stderr " name: ") -14366 #? 50/push-eax -14367 #? (lookup *eax *(eax+4)) # Var-name -14368 #? (write-buffered Stderr %eax) -14369 #? 58/pop-to-eax -14370 #? (write-buffered Stderr Newline) -14371 #? (flush Stderr) -14372 # return output-var->stack-offset -14373 8b/-> *(eax+0x14) 0/r32/eax # Var-offset -14374 #? (write-buffered Stderr "=> ") -14375 #? (write-int32-hex-buffered Stderr %eax) -14376 #? (write-buffered Stderr Newline) -14377 #? (flush Stderr) -14378 $emit-get-offset:end: -14379 # . epilogue -14380 89/<- %esp 5/r32/ebp -14381 5d/pop-to-ebp -14382 c3/return -14383 -14384 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) -14385 # . prologue -14386 55/push-ebp -14387 89/<- %ebp 4/r32/esp -14388 # . save registers -14389 50/push-eax -14390 51/push-ecx -14391 56/push-esi -14392 # esi = block -14393 8b/-> *(ebp+0xc) 6/r32/esi -14394 # block->var->block-depth = *Curr-block-depth -14395 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax -14396 8b/-> *Curr-block-depth 1/r32/ecx -14397 89/<- *(eax+0x10) 1/r32/ecx # Var-block-depth -14398 # var stmts/eax: (addr list stmt) = lookup(block->statements) -14399 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax -14400 # +14179 $clean-up-blocks:phase2: +14180 # var from/esi: int = to +14181 89/<- %esi 7/r32/edi +14182 { +14183 $clean-up-blocks:loop2: +14184 # if (from >= vars->top) break +14185 3b/compare 6/r32/esi *ebx +14186 7d/jump-if->= break/disp8 +14187 # var v/eax: (addr var) = lookup(vars->data[from]->var) +14188 8d/copy-address *(ebx+esi+8) 0/r32/eax +14189 (lookup *eax *(eax+4)) # => eax +14190 # if !in-function-outputs?(fn, v) continue +14191 (in-function-outputs? *(ebp+0x10) %eax) # => eax +14192 3d/compare-eax-and 0/imm32/false +14193 74/jump-if-= $clean-up-blocks:loop2-continue/disp8 +14194 # invariant: from >= to +14195 # if (from > to) vars->data[to] = vars->data[from] +14196 { +14197 39/compare %esi 7/r32/edi +14198 7e/jump-if-<= break/disp8 +14199 56/push-esi +14200 57/push-edi +14201 # . var from/esi: (addr byte) = &vars->data[from] +14202 8d/copy-address *(ebx+esi+8) 6/r32/esi +14203 # . var to/edi: (addr byte) = &vars->data[to] +14204 8d/copy-address *(ebx+edi+8) 7/r32/edi +14205 # . +14206 8b/-> *esi 0/r32/eax +14207 89/<- *edi 0/r32/eax +14208 8b/-> *(esi+4) 0/r32/eax +14209 89/<- *(edi+4) 0/r32/eax +14210 8b/-> *(esi+8) 0/r32/eax +14211 89/<- *(edi+8) 0/r32/eax +14212 5f/pop-to-edi +14213 5e/pop-to-esi +14214 } +14215 # ++to +14216 81 0/subop/add %edi 0xc/imm32 +14217 $clean-up-blocks:loop2-continue: +14218 # ++from +14219 81 0/subop/add %esi 0xc/imm32 +14220 # +14221 eb/jump loop/disp8 +14222 } +14223 89/<- *ebx 7/r32/edi +14224 $clean-up-blocks:end: +14225 # . restore registers +14226 5f/pop-to-edi +14227 5e/pop-to-esi +14228 5b/pop-to-ebx +14229 5a/pop-to-edx +14230 58/pop-to-eax +14231 # . epilogue +14232 89/<- %esp 5/r32/ebp +14233 5d/pop-to-ebp +14234 c3/return +14235 +14236 in-function-outputs?: # fn: (addr function), target: (addr var) -> result/eax: boolean +14237 # . prologue +14238 55/push-ebp +14239 89/<- %ebp 4/r32/esp +14240 # . save registers +14241 51/push-ecx +14242 # var curr/ecx: (addr list var) = lookup(fn->outputs) +14243 8b/-> *(ebp+8) 1/r32/ecx +14244 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax +14245 89/<- %ecx 0/r32/eax +14246 # while curr != null +14247 { +14248 81 7/subop/compare %ecx 0/imm32 +14249 74/jump-if-= break/disp8 +14250 # var v/eax: (addr var) = lookup(curr->value) +14251 (lookup *ecx *(ecx+4)) # List-value List-value => eax +14252 # if (v == target) return true +14253 39/compare *(ebp+0xc) 0/r32/eax +14254 b8/copy-to-eax 1/imm32/true +14255 74/jump-if-= $in-function-outputs?:end/disp8 +14256 # curr = curr->next +14257 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +14258 89/<- %ecx 0/r32/eax +14259 # +14260 eb/jump loop/disp8 +14261 } +14262 b8/copy-to-eax 0/imm32 +14263 $in-function-outputs?:end: +14264 # . restore registers +14265 59/pop-to-ecx +14266 # . epilogue +14267 89/<- %esp 5/r32/ebp +14268 5d/pop-to-ebp +14269 c3/return +14270 +14271 emit-subx-var-def: # out: (addr buffered-file), stmt: (addr stmt) +14272 # . prologue +14273 55/push-ebp +14274 89/<- %ebp 4/r32/esp +14275 # . save registers +14276 50/push-eax +14277 51/push-ecx +14278 52/push-edx +14279 # eax = stmt +14280 8b/-> *(ebp+0xc) 0/r32/eax +14281 # var v/ecx: (addr var) +14282 (lookup *(eax+4) *(eax+8)) # Vardef-var Vardef-var => eax +14283 89/<- %ecx 0/r32/eax +14284 # v->block-depth = *Curr-block-depth +14285 8b/-> *Curr-block-depth 0/r32/eax +14286 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +14287 # var n/edx: int = size-of(stmt->var) +14288 (size-of %ecx) # => eax +14289 89/<- %edx 0/r32/eax +14290 # *Curr-local-stack-offset -= n +14291 29/subtract-from *Curr-local-stack-offset 2/r32/edx +14292 # v->offset = *Curr-local-stack-offset +14293 8b/-> *Curr-local-stack-offset 0/r32/eax +14294 89/<- *(ecx+0x14) 0/r32/eax # Var-offset +14295 # if v is an array, do something special +14296 { +14297 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +14298 (is-mu-array? %eax) # => eax +14299 3d/compare-eax-and 0/imm32/false +14300 0f 84/jump-if-= break/disp32 +14301 # var array-size-without-size/edx: int = n-4 +14302 81 5/subop/subtract %edx 4/imm32 +14303 (emit-indent *(ebp+8) *Curr-block-depth) +14304 (write-buffered *(ebp+8) "(push-n-zero-bytes ") +14305 (write-int32-hex-buffered *(ebp+8) %edx) +14306 (write-buffered *(ebp+8) ")\n") +14307 (emit-indent *(ebp+8) *Curr-block-depth) +14308 (write-buffered *(ebp+8) "68/push ") +14309 (write-int32-hex-buffered *(ebp+8) %edx) +14310 (write-buffered *(ebp+8) "/imm32\n") +14311 eb/jump $emit-subx-var-def:end/disp8 +14312 } +14313 # while n > 0 +14314 { +14315 81 7/subop/compare %edx 0/imm32 +14316 7e/jump-if-<= break/disp8 +14317 (emit-indent *(ebp+8) *Curr-block-depth) +14318 (write-buffered *(ebp+8) "68/push 0/imm32\n") +14319 # n -= 4 +14320 81 5/subop/subtract %edx 4/imm32 +14321 # +14322 eb/jump loop/disp8 +14323 } +14324 $emit-subx-var-def:end: +14325 # . restore registers +14326 5a/pop-to-edx +14327 59/pop-to-ecx +14328 58/pop-to-eax +14329 # . epilogue +14330 89/<- %esp 5/r32/ebp +14331 5d/pop-to-ebp +14332 c3/return +14333 +14334 emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) +14335 # . prologue +14336 55/push-ebp +14337 89/<- %ebp 4/r32/esp +14338 # . save registers +14339 50/push-eax +14340 51/push-ecx +14341 # - some special-case primitives that don't actually use the 'primitives' data structure +14342 # var op/ecx: (addr array byte) = lookup(stmt->operation) +14343 8b/-> *(ebp+0xc) 1/r32/ecx +14344 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +14345 89/<- %ecx 0/r32/eax +14346 # array size +14347 { +14348 # if (!string-equal?(stmt->operation, "length")) break +14349 (string-equal? %ecx "length") # => eax +14350 3d/compare-eax-and 0/imm32 +14351 0f 84/jump-if-= break/disp32 +14352 (translate-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +14353 e9/jump $emit-subx-stmt:end/disp32 +14354 } +14355 # index into array +14356 { +14357 # if (!string-equal?(stmt->operation, "index")) break +14358 (string-equal? %ecx "index") # => eax +14359 3d/compare-eax-and 0/imm32 +14360 0f 84/jump-if-= break/disp32 +14361 (translate-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +14362 e9/jump $emit-subx-stmt:end/disp32 +14363 } +14364 # compute-offset for index into array +14365 { +14366 # if (!string-equal?(stmt->operation, "compute-offset")) break +14367 (string-equal? %ecx "compute-offset") # => eax +14368 3d/compare-eax-and 0/imm32 +14369 0f 84/jump-if-= break/disp32 +14370 (translate-mu-compute-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +14371 e9/jump $emit-subx-stmt:end/disp32 +14372 } +14373 # get field from record +14374 { +14375 # if (!string-equal?(stmt->operation, "get")) break +14376 (string-equal? %ecx "get") # => eax +14377 3d/compare-eax-and 0/imm32 +14378 0f 84/jump-if-= break/disp32 +14379 (translate-mu-get-stmt *(ebp+8) *(ebp+0xc)) +14380 e9/jump $emit-subx-stmt:end/disp32 +14381 } +14382 # allocate scalar +14383 { +14384 # if (!string-equal?(stmt->operation, "allocate")) break +14385 (string-equal? %ecx "allocate") # => eax +14386 3d/compare-eax-and 0/imm32 +14387 0f 84/jump-if-= break/disp32 +14388 (translate-mu-allocate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +14389 e9/jump $emit-subx-stmt:end/disp32 +14390 } +14391 # allocate array +14392 { +14393 # if (!string-equal?(stmt->operation, "populate")) break +14394 (string-equal? %ecx "populate") # => eax +14395 3d/compare-eax-and 0/imm32 +14396 0f 84/jump-if-= break/disp32 +14397 (translate-mu-populate-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +14398 e9/jump $emit-subx-stmt:end/disp32 +14399 } +14400 # - if stmt matches a primitive, emit it 14401 { -14402 $emit-subx-block:check-empty: -14403 3d/compare-eax-and 0/imm32 -14404 0f 84/jump-if-= break/disp32 -14405 (emit-indent *(ebp+8) *Curr-block-depth) -14406 (write-buffered *(ebp+8) "{\n") -14407 # var v/ecx: (addr var) = lookup(block->var) -14408 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax -14409 89/<- %ecx 0/r32/eax -14410 # -14411 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -14412 (write-buffered *(ebp+8) %eax) -14413 (write-buffered *(ebp+8) ":loop:\n") -14414 ff 0/subop/increment *Curr-block-depth -14415 (push *(ebp+0x10) *(esi+0xc)) # Block-var -14416 (push *(ebp+0x10) *(esi+0x10)) # Block-var -14417 (push *(ebp+0x10) 0) # false -14418 # emit block->statements -14419 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax -14420 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -14421 (pop *(ebp+0x10)) # => eax -14422 (pop *(ebp+0x10)) # => eax -14423 (pop *(ebp+0x10)) # => eax -14424 ff 1/subop/decrement *Curr-block-depth -14425 (emit-indent *(ebp+8) *Curr-block-depth) -14426 (write-buffered *(ebp+8) "}\n") -14427 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -14428 (write-buffered *(ebp+8) %eax) -14429 (write-buffered *(ebp+8) ":break:\n") -14430 } -14431 $emit-subx-block:end: -14432 # . restore registers -14433 5e/pop-to-esi -14434 59/pop-to-ecx -14435 58/pop-to-eax -14436 # . epilogue -14437 89/<- %esp 5/r32/ebp -14438 5d/pop-to-ebp -14439 c3/return -14440 -14441 # Primitives supported -14442 # See mu_instructions for a summary of this linked-list data structure. -14443 # -14444 # For each operation, put variants with hard-coded registers before flexible ones. -14445 # -14446 # Unfortunately, our restrictions on addresses require that various fields in -14447 # primitives be handles, which complicates these definitions. -14448 # - we need to insert dummy fields all over the place for fake alloc-ids -14449 # - we can't use our syntax sugar of quoted literals for string fields -14450 # -14451 # Fake alloc-ids are needed because our type definitions up top require -14452 # handles but it's clearer to statically allocate these long-lived objects. -14453 # Fake alloc-ids are perfectly safe, but they can't be reclaimed. -14454 # -14455 # Every 'object' below starts with a fake alloc-id. It may also contain other -14456 # fake alloc-ids for various handle fields. -14457 # -14458 # I think of objects starting with a fake alloc-id as having type 'payload'. -14459 # It's not really intended to be created dynamically; for that use `allocate` -14460 # as usual. -14461 # -14462 # Idea for a notation to simplify such definitions: -14463 # _Primitive-increment-eax: # (payload primitive) -14464 # 0x11/alloc-id:fake:payload -14465 # 0x11 @(0x11 "increment") # name -14466 # 0 0 # inouts -14467 # 0x11 @(0x11/payload -14468 # 0x11 @(0x11/payload # List-value -14469 # 0 0 # Var-name -14470 # 0x11 @(0x11 # Var-type -14471 # 1/is-atom -14472 # 1/value 0/unused # Type-tree-left -14473 # 0 0 # Type-tree-right -14474 # ) -14475 # 1 # block-depth -14476 # 0 # stack-offset -14477 # 0x11 @(0x11 "eax") # Var-register -14478 # ) -14479 # 0 0) # List-next -14480 # ... -14481 # _Primitive-increment-ecx/imm32/next -14482 # ... -14483 # Awfully complex and non-obvious. But also clearly signals there's something -14484 # to learn here, so may be worth trying. -14485 # -14486 # '@' is just an initial thought. Punctuation used so far in Mu: () * % # / " -14487 # -14488 # For now we'll continue to just use comments and manually ensure they stay up -14489 # to date. -14490 == data -14491 Primitives: # (addr primitive) -14492 # - increment/decrement -14493 _Primitive-increment-eax: # (addr primitive) -14494 # var/eax <- increment => 40/increment-eax -14495 0x11/imm32/alloc-id:fake -14496 _string-increment/imm32/name -14497 0/imm32/no-inouts -14498 0/imm32/no-inouts -14499 0x11/imm32/alloc-id:fake -14500 Single-int-var-in-eax/imm32/outputs -14501 0x11/imm32/alloc-id:fake -14502 _string_40_increment_eax/imm32/subx-name -14503 0/imm32/no-rm32 -14504 0/imm32/no-r32 -14505 0/imm32/no-imm32 -14506 0/imm32/no-disp32 -14507 0/imm32/output-is-write-only -14508 0x11/imm32/alloc-id:fake -14509 _Primitive-increment-ecx/imm32/next -14510 _Primitive-increment-ecx: # (payload primitive) -14511 0x11/imm32/alloc-id:fake:payload -14512 # var/ecx <- increment => 41/increment-ecx -14513 0x11/imm32/alloc-id:fake -14514 _string-increment/imm32/name -14515 0/imm32/no-inouts -14516 0/imm32/no-inouts -14517 0x11/imm32/alloc-id:fake -14518 Single-int-var-in-ecx/imm32/outputs -14519 0x11/imm32/alloc-id:fake -14520 _string_41_increment_ecx/imm32/subx-name -14521 0/imm32/no-rm32 -14522 0/imm32/no-r32 -14523 0/imm32/no-imm32 -14524 0/imm32/no-disp32 -14525 0/imm32/output-is-write-only -14526 0x11/imm32/alloc-id:fake -14527 _Primitive-increment-edx/imm32/next -14528 _Primitive-increment-edx: # (payload primitive) -14529 0x11/imm32/alloc-id:fake:payload -14530 # var/edx <- increment => 42/increment-edx -14531 0x11/imm32/alloc-id:fake -14532 _string-increment/imm32/name -14533 0/imm32/no-inouts -14534 0/imm32/no-inouts -14535 0x11/imm32/alloc-id:fake -14536 Single-int-var-in-edx/imm32/outputs -14537 0x11/imm32/alloc-id:fake -14538 _string_42_increment_edx/imm32/subx-name -14539 0/imm32/no-rm32 -14540 0/imm32/no-r32 -14541 0/imm32/no-imm32 -14542 0/imm32/no-disp32 -14543 0/imm32/output-is-write-only -14544 0x11/imm32/alloc-id:fake -14545 _Primitive-increment-ebx/imm32/next -14546 _Primitive-increment-ebx: # (payload primitive) -14547 0x11/imm32/alloc-id:fake:payload -14548 # var/ebx <- increment => 43/increment-ebx -14549 0x11/imm32/alloc-id:fake -14550 _string-increment/imm32/name -14551 0/imm32/no-inouts -14552 0/imm32/no-inouts -14553 0x11/imm32/alloc-id:fake -14554 Single-int-var-in-ebx/imm32/outputs -14555 0x11/imm32/alloc-id:fake -14556 _string_43_increment_ebx/imm32/subx-name -14557 0/imm32/no-rm32 -14558 0/imm32/no-r32 -14559 0/imm32/no-imm32 -14560 0/imm32/no-disp32 -14561 0/imm32/output-is-write-only -14562 0x11/imm32/alloc-id:fake -14563 _Primitive-increment-esi/imm32/next -14564 _Primitive-increment-esi: # (payload primitive) -14565 0x11/imm32/alloc-id:fake:payload -14566 # var/esi <- increment => 46/increment-esi -14567 0x11/imm32/alloc-id:fake -14568 _string-increment/imm32/name -14569 0/imm32/no-inouts -14570 0/imm32/no-inouts -14571 0x11/imm32/alloc-id:fake -14572 Single-int-var-in-esi/imm32/outputs -14573 0x11/imm32/alloc-id:fake -14574 _string_46_increment_esi/imm32/subx-name -14575 0/imm32/no-rm32 -14576 0/imm32/no-r32 -14577 0/imm32/no-imm32 -14578 0/imm32/no-disp32 -14579 0/imm32/output-is-write-only -14580 0x11/imm32/alloc-id:fake -14581 _Primitive-increment-edi/imm32/next -14582 _Primitive-increment-edi: # (payload primitive) -14583 0x11/imm32/alloc-id:fake:payload -14584 # var/edi <- increment => 47/increment-edi -14585 0x11/imm32/alloc-id:fake -14586 _string-increment/imm32/name -14587 0/imm32/no-inouts -14588 0/imm32/no-inouts -14589 0x11/imm32/alloc-id:fake -14590 Single-int-var-in-edi/imm32/outputs -14591 0x11/imm32/alloc-id:fake -14592 _string_47_increment_edi/imm32/subx-name -14593 0/imm32/no-rm32 -14594 0/imm32/no-r32 -14595 0/imm32/no-imm32 -14596 0/imm32/no-disp32 -14597 0/imm32/output-is-write-only -14598 0x11/imm32/alloc-id:fake -14599 _Primitive-decrement-eax/imm32/next -14600 _Primitive-decrement-eax: # (payload primitive) -14601 0x11/imm32/alloc-id:fake:payload -14602 # var/eax <- decrement => 48/decrement-eax -14603 0x11/imm32/alloc-id:fake -14604 _string-decrement/imm32/name -14605 0/imm32/no-inouts -14606 0/imm32/no-inouts -14607 0x11/imm32/alloc-id:fake -14608 Single-int-var-in-eax/imm32/outputs -14609 0x11/imm32/alloc-id:fake -14610 _string_48_decrement_eax/imm32/subx-name -14611 0/imm32/no-rm32 -14612 0/imm32/no-r32 -14613 0/imm32/no-imm32 -14614 0/imm32/no-disp32 -14615 0/imm32/output-is-write-only -14616 0x11/imm32/alloc-id:fake -14617 _Primitive-decrement-ecx/imm32/next -14618 _Primitive-decrement-ecx: # (payload primitive) -14619 0x11/imm32/alloc-id:fake:payload -14620 # var/ecx <- decrement => 49/decrement-ecx -14621 0x11/imm32/alloc-id:fake -14622 _string-decrement/imm32/name -14623 0/imm32/no-inouts -14624 0/imm32/no-inouts -14625 0x11/imm32/alloc-id:fake -14626 Single-int-var-in-ecx/imm32/outputs -14627 0x11/imm32/alloc-id:fake -14628 _string_49_decrement_ecx/imm32/subx-name -14629 0/imm32/no-rm32 -14630 0/imm32/no-r32 -14631 0/imm32/no-imm32 -14632 0/imm32/no-disp32 -14633 0/imm32/output-is-write-only -14634 0x11/imm32/alloc-id:fake -14635 _Primitive-decrement-edx/imm32/next -14636 _Primitive-decrement-edx: # (payload primitive) -14637 0x11/imm32/alloc-id:fake:payload -14638 # var/edx <- decrement => 4a/decrement-edx -14639 0x11/imm32/alloc-id:fake -14640 _string-decrement/imm32/name -14641 0/imm32/no-inouts -14642 0/imm32/no-inouts -14643 0x11/imm32/alloc-id:fake -14644 Single-int-var-in-edx/imm32/outputs -14645 0x11/imm32/alloc-id:fake -14646 _string_4a_decrement_edx/imm32/subx-name -14647 0/imm32/no-rm32 -14648 0/imm32/no-r32 -14649 0/imm32/no-imm32 -14650 0/imm32/no-disp32 -14651 0/imm32/output-is-write-only -14652 0x11/imm32/alloc-id:fake -14653 _Primitive-decrement-ebx/imm32/next -14654 _Primitive-decrement-ebx: # (payload primitive) -14655 0x11/imm32/alloc-id:fake:payload -14656 # var/ebx <- decrement => 4b/decrement-ebx -14657 0x11/imm32/alloc-id:fake -14658 _string-decrement/imm32/name -14659 0/imm32/no-inouts -14660 0/imm32/no-inouts -14661 0x11/imm32/alloc-id:fake -14662 Single-int-var-in-ebx/imm32/outputs -14663 0x11/imm32/alloc-id:fake -14664 _string_4b_decrement_ebx/imm32/subx-name -14665 0/imm32/no-rm32 -14666 0/imm32/no-r32 -14667 0/imm32/no-imm32 -14668 0/imm32/no-disp32 -14669 0/imm32/output-is-write-only -14670 0x11/imm32/alloc-id:fake -14671 _Primitive-decrement-esi/imm32/next -14672 _Primitive-decrement-esi: # (payload primitive) -14673 0x11/imm32/alloc-id:fake:payload -14674 # var/esi <- decrement => 4e/decrement-esi -14675 0x11/imm32/alloc-id:fake -14676 _string-decrement/imm32/name -14677 0/imm32/no-inouts -14678 0/imm32/no-inouts -14679 0x11/imm32/alloc-id:fake -14680 Single-int-var-in-esi/imm32/outputs -14681 0x11/imm32/alloc-id:fake -14682 _string_4e_decrement_esi/imm32/subx-name -14683 0/imm32/no-rm32 -14684 0/imm32/no-r32 -14685 0/imm32/no-imm32 -14686 0/imm32/no-disp32 -14687 0/imm32/output-is-write-only -14688 0x11/imm32/alloc-id:fake -14689 _Primitive-decrement-edi/imm32/next -14690 _Primitive-decrement-edi: # (payload primitive) -14691 0x11/imm32/alloc-id:fake:payload -14692 # var/edi <- decrement => 4f/decrement-edi -14693 0x11/imm32/alloc-id:fake -14694 _string-decrement/imm32/name -14695 0/imm32/no-inouts -14696 0/imm32/no-inouts -14697 0x11/imm32/alloc-id:fake -14698 Single-int-var-in-edi/imm32/outputs -14699 0x11/imm32/alloc-id:fake -14700 _string_4f_decrement_edi/imm32/subx-name -14701 0/imm32/no-rm32 -14702 0/imm32/no-r32 -14703 0/imm32/no-imm32 -14704 0/imm32/no-disp32 -14705 0/imm32/output-is-write-only -14706 0x11/imm32/alloc-id:fake -14707 _Primitive-increment-mem/imm32/next -14708 _Primitive-increment-mem: # (payload primitive) -14709 0x11/imm32/alloc-id:fake:payload -14710 # increment var => ff 0/subop/increment *(ebp+__) -14711 0x11/imm32/alloc-id:fake -14712 _string-increment/imm32/name -14713 0x11/imm32/alloc-id:fake -14714 Single-int-var-in-mem/imm32/inouts -14715 0/imm32/no-outputs -14716 0/imm32/no-outputs -14717 0x11/imm32/alloc-id:fake -14718 _string_ff_subop_increment/imm32/subx-name -14719 1/imm32/rm32-is-first-inout -14720 0/imm32/no-r32 -14721 0/imm32/no-imm32 -14722 0/imm32/no-disp32 -14723 0/imm32/output-is-write-only -14724 0x11/imm32/alloc-id:fake -14725 _Primitive-increment-reg/imm32/next -14726 _Primitive-increment-reg: # (payload primitive) -14727 0x11/imm32/alloc-id:fake:payload -14728 # var/reg <- increment => ff 0/subop/increment %__ -14729 0x11/imm32/alloc-id:fake -14730 _string-increment/imm32/name -14731 0/imm32/no-inouts -14732 0/imm32/no-inouts -14733 0x11/imm32/alloc-id:fake -14734 Single-int-var-in-some-register/imm32/outputs -14735 0x11/imm32/alloc-id:fake -14736 _string_ff_subop_increment/imm32/subx-name -14737 3/imm32/rm32-is-first-output -14738 0/imm32/no-r32 -14739 0/imm32/no-imm32 -14740 0/imm32/no-disp32 -14741 0/imm32/output-is-write-only -14742 0x11/imm32/alloc-id:fake -14743 _Primitive-decrement-mem/imm32/next -14744 _Primitive-decrement-mem: # (payload primitive) -14745 0x11/imm32/alloc-id:fake:payload -14746 # decrement var => ff 1/subop/decrement *(ebp+__) -14747 0x11/imm32/alloc-id:fake -14748 _string-decrement/imm32/name -14749 0x11/imm32/alloc-id:fake -14750 Single-int-var-in-mem/imm32/inouts -14751 0/imm32/no-outputs -14752 0/imm32/no-outputs -14753 0x11/imm32/alloc-id:fake -14754 _string_ff_subop_decrement/imm32/subx-name -14755 1/imm32/rm32-is-first-inout -14756 0/imm32/no-r32 -14757 0/imm32/no-imm32 -14758 0/imm32/no-disp32 -14759 0/imm32/output-is-write-only -14760 0x11/imm32/alloc-id:fake -14761 _Primitive-decrement-reg/imm32/next -14762 _Primitive-decrement-reg: # (payload primitive) -14763 0x11/imm32/alloc-id:fake:payload -14764 # var/reg <- decrement => ff 1/subop/decrement %__ -14765 0x11/imm32/alloc-id:fake -14766 _string-decrement/imm32/name -14767 0/imm32/no-inouts -14768 0/imm32/no-inouts -14769 0x11/imm32/alloc-id:fake -14770 Single-int-var-in-some-register/imm32/outputs -14771 0x11/imm32/alloc-id:fake -14772 _string_ff_subop_decrement/imm32/subx-name -14773 3/imm32/rm32-is-first-output -14774 0/imm32/no-r32 -14775 0/imm32/no-imm32 -14776 0/imm32/no-disp32 -14777 0/imm32/output-is-write-only -14778 0x11/imm32/alloc-id:fake -14779 _Primitive-add-to-eax/imm32/next -14780 # - add -14781 _Primitive-add-to-eax: # (payload primitive) -14782 0x11/imm32/alloc-id:fake:payload -14783 # var/eax <- add lit => 05/add-to-eax lit/imm32 -14784 0x11/imm32/alloc-id:fake -14785 _string-add/imm32/name -14786 0x11/imm32/alloc-id:fake -14787 Single-lit-var/imm32/inouts -14788 0x11/imm32/alloc-id:fake -14789 Single-int-var-in-eax/imm32/outputs -14790 0x11/imm32/alloc-id:fake -14791 _string_05_add_to_eax/imm32/subx-name -14792 0/imm32/no-rm32 -14793 0/imm32/no-r32 -14794 1/imm32/imm32-is-first-inout -14795 0/imm32/no-disp32 -14796 0/imm32/output-is-write-only -14797 0x11/imm32/alloc-id:fake -14798 _Primitive-add-reg-to-reg/imm32/next -14799 _Primitive-add-reg-to-reg: # (payload primitive) -14800 0x11/imm32/alloc-id:fake:payload -14801 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 -14802 0x11/imm32/alloc-id:fake -14803 _string-add/imm32/name -14804 0x11/imm32/alloc-id:fake -14805 Single-int-var-in-some-register/imm32/inouts -14806 0x11/imm32/alloc-id:fake -14807 Single-int-var-in-some-register/imm32/outputs -14808 0x11/imm32/alloc-id:fake -14809 _string_01_add_to/imm32/subx-name -14810 3/imm32/rm32-is-first-output -14811 1/imm32/r32-is-first-inout -14812 0/imm32/no-imm32 -14813 0/imm32/no-disp32 -14814 0/imm32/output-is-write-only -14815 0x11/imm32/alloc-id:fake -14816 _Primitive-add-reg-to-mem/imm32/next -14817 _Primitive-add-reg-to-mem: # (payload primitive) -14818 0x11/imm32/alloc-id:fake:payload -14819 # add-to var1 var2/reg => 01/add-to var1 var2/r32 -14820 0x11/imm32/alloc-id:fake -14821 _string-add-to/imm32/name -14822 0x11/imm32/alloc-id:fake -14823 Two-args-int-stack-int-reg/imm32/inouts -14824 0/imm32/no-outputs -14825 0/imm32/no-outputs -14826 0x11/imm32/alloc-id:fake -14827 _string_01_add_to/imm32/subx-name -14828 1/imm32/rm32-is-first-inout -14829 2/imm32/r32-is-second-inout -14830 0/imm32/no-imm32 -14831 0/imm32/no-disp32 -14832 0/imm32/output-is-write-only -14833 0x11/imm32/alloc-id:fake -14834 _Primitive-add-mem-to-reg/imm32/next -14835 _Primitive-add-mem-to-reg: # (payload primitive) -14836 0x11/imm32/alloc-id:fake:payload -14837 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 -14838 0x11/imm32/alloc-id:fake -14839 _string-add/imm32/name -14840 0x11/imm32/alloc-id:fake -14841 Single-int-var-in-mem/imm32/inouts -14842 0x11/imm32/alloc-id:fake -14843 Single-int-var-in-some-register/imm32/outputs -14844 0x11/imm32/alloc-id:fake -14845 _string_03_add/imm32/subx-name -14846 1/imm32/rm32-is-first-inout -14847 3/imm32/r32-is-first-output -14848 0/imm32/no-imm32 -14849 0/imm32/no-disp32 -14850 0/imm32/output-is-write-only -14851 0x11/imm32/alloc-id:fake -14852 _Primitive-add-lit-to-reg/imm32/next -14853 _Primitive-add-lit-to-reg: # (payload primitive) -14854 0x11/imm32/alloc-id:fake:payload -14855 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 -14856 0x11/imm32/alloc-id:fake -14857 _string-add/imm32/name -14858 0x11/imm32/alloc-id:fake -14859 Single-lit-var/imm32/inouts -14860 0x11/imm32/alloc-id:fake -14861 Single-int-var-in-some-register/imm32/outputs -14862 0x11/imm32/alloc-id:fake -14863 _string_81_subop_add/imm32/subx-name -14864 3/imm32/rm32-is-first-output -14865 0/imm32/no-r32 -14866 1/imm32/imm32-is-first-inout -14867 0/imm32/no-disp32 -14868 0/imm32/output-is-write-only -14869 0x11/imm32/alloc-id:fake -14870 _Primitive-add-lit-to-mem/imm32/next -14871 _Primitive-add-lit-to-mem: # (payload primitive) -14872 0x11/imm32/alloc-id:fake:payload -14873 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 -14874 0x11/imm32/alloc-id:fake -14875 _string-add-to/imm32/name -14876 0x11/imm32/alloc-id:fake -14877 Int-var-and-literal/imm32/inouts -14878 0/imm32/no-outputs -14879 0/imm32/no-outputs -14880 0x11/imm32/alloc-id:fake -14881 _string_81_subop_add/imm32/subx-name -14882 1/imm32/rm32-is-first-inout -14883 0/imm32/no-r32 -14884 2/imm32/imm32-is-second-inout -14885 0/imm32/no-disp32 -14886 0/imm32/output-is-write-only -14887 0x11/imm32/alloc-id:fake -14888 _Primitive-subtract-from-eax/imm32/next -14889 # - subtract -14890 _Primitive-subtract-from-eax: # (payload primitive) -14891 0x11/imm32/alloc-id:fake:payload -14892 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 -14893 0x11/imm32/alloc-id:fake -14894 _string-subtract/imm32/name -14895 0x11/imm32/alloc-id:fake -14896 Single-lit-var/imm32/inouts -14897 0x11/imm32/alloc-id:fake -14898 Single-int-var-in-eax/imm32/outputs -14899 0x11/imm32/alloc-id:fake -14900 _string_2d_subtract_from_eax/imm32/subx-name -14901 0/imm32/no-rm32 -14902 0/imm32/no-r32 -14903 1/imm32/imm32-is-first-inout -14904 0/imm32/no-disp32 -14905 0/imm32/output-is-write-only -14906 0x11/imm32/alloc-id:fake -14907 _Primitive-subtract-reg-from-reg/imm32/next -14908 _Primitive-subtract-reg-from-reg: # (payload primitive) -14909 0x11/imm32/alloc-id:fake:payload -14910 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 -14911 0x11/imm32/alloc-id:fake -14912 _string-subtract/imm32/name -14913 0x11/imm32/alloc-id:fake -14914 Single-int-var-in-some-register/imm32/inouts -14915 0x11/imm32/alloc-id:fake -14916 Single-int-var-in-some-register/imm32/outputs -14917 0x11/imm32/alloc-id:fake -14918 _string_29_subtract_from/imm32/subx-name -14919 3/imm32/rm32-is-first-output -14920 1/imm32/r32-is-first-inout -14921 0/imm32/no-imm32 -14922 0/imm32/no-disp32 -14923 0/imm32/output-is-write-only -14924 0x11/imm32/alloc-id:fake -14925 _Primitive-subtract-reg-from-mem/imm32/next -14926 _Primitive-subtract-reg-from-mem: # (payload primitive) -14927 0x11/imm32/alloc-id:fake:payload -14928 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 -14929 0x11/imm32/alloc-id:fake -14930 _string-subtract-from/imm32/name -14931 0x11/imm32/alloc-id:fake -14932 Two-args-int-stack-int-reg/imm32/inouts -14933 0/imm32/no-outputs -14934 0/imm32/no-outputs -14935 0x11/imm32/alloc-id:fake -14936 _string_29_subtract_from/imm32/subx-name -14937 1/imm32/rm32-is-first-inout -14938 2/imm32/r32-is-second-inout -14939 0/imm32/no-imm32 -14940 0/imm32/no-disp32 -14941 0/imm32/output-is-write-only -14942 0x11/imm32/alloc-id:fake -14943 _Primitive-subtract-mem-from-reg/imm32/next -14944 _Primitive-subtract-mem-from-reg: # (payload primitive) -14945 0x11/imm32/alloc-id:fake:payload -14946 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 -14947 0x11/imm32/alloc-id:fake -14948 _string-subtract/imm32/name -14949 0x11/imm32/alloc-id:fake -14950 Single-int-var-in-mem/imm32/inouts -14951 0x11/imm32/alloc-id:fake -14952 Single-int-var-in-some-register/imm32/outputs -14953 0x11/imm32/alloc-id:fake -14954 _string_2b_subtract/imm32/subx-name -14955 1/imm32/rm32-is-first-inout -14956 3/imm32/r32-is-first-output -14957 0/imm32/no-imm32 -14958 0/imm32/no-disp32 -14959 0/imm32/output-is-write-only -14960 0x11/imm32/alloc-id:fake -14961 _Primitive-subtract-lit-from-reg/imm32/next -14962 _Primitive-subtract-lit-from-reg: # (payload primitive) -14963 0x11/imm32/alloc-id:fake:payload -14964 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 -14965 0x11/imm32/alloc-id:fake -14966 _string-subtract/imm32/name -14967 0x11/imm32/alloc-id:fake -14968 Single-lit-var/imm32/inouts -14969 0x11/imm32/alloc-id:fake -14970 Single-int-var-in-some-register/imm32/outputs -14971 0x11/imm32/alloc-id:fake -14972 _string_81_subop_subtract/imm32/subx-name -14973 3/imm32/rm32-is-first-output -14974 0/imm32/no-r32 -14975 1/imm32/imm32-is-first-inout -14976 0/imm32/no-disp32 -14977 0/imm32/output-is-write-only -14978 0x11/imm32/alloc-id:fake -14979 _Primitive-subtract-lit-from-mem/imm32/next -14980 _Primitive-subtract-lit-from-mem: # (payload primitive) -14981 0x11/imm32/alloc-id:fake:payload -14982 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 -14983 0x11/imm32/alloc-id:fake -14984 _string-subtract-from/imm32/name -14985 0x11/imm32/alloc-id:fake -14986 Int-var-and-literal/imm32/inouts -14987 0/imm32/no-outputs -14988 0/imm32/no-outputs -14989 0x11/imm32/alloc-id:fake -14990 _string_81_subop_subtract/imm32/subx-name -14991 1/imm32/rm32-is-first-inout -14992 0/imm32/no-r32 -14993 2/imm32/imm32-is-first-inout -14994 0/imm32/no-disp32 -14995 0/imm32/output-is-write-only -14996 0x11/imm32/alloc-id:fake -14997 _Primitive-and-with-eax/imm32/next -14998 # - and -14999 _Primitive-and-with-eax: # (payload primitive) -15000 0x11/imm32/alloc-id:fake:payload -15001 # var/eax <- and lit => 25/and-with-eax lit/imm32 -15002 0x11/imm32/alloc-id:fake -15003 _string-and/imm32/name -15004 0x11/imm32/alloc-id:fake -15005 Single-lit-var/imm32/inouts -15006 0x11/imm32/alloc-id:fake -15007 Single-int-var-in-eax/imm32/outputs -15008 0x11/imm32/alloc-id:fake -15009 _string_25_and_with_eax/imm32/subx-name -15010 0/imm32/no-rm32 -15011 0/imm32/no-r32 -15012 1/imm32/imm32-is-first-inout -15013 0/imm32/no-disp32 -15014 0/imm32/output-is-write-only -15015 0x11/imm32/alloc-id:fake -15016 _Primitive-and-reg-with-reg/imm32/next -15017 _Primitive-and-reg-with-reg: # (payload primitive) -15018 0x11/imm32/alloc-id:fake:payload -15019 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 -15020 0x11/imm32/alloc-id:fake -15021 _string-and/imm32/name -15022 0x11/imm32/alloc-id:fake -15023 Single-int-var-in-some-register/imm32/inouts -15024 0x11/imm32/alloc-id:fake -15025 Single-int-var-in-some-register/imm32/outputs -15026 0x11/imm32/alloc-id:fake -15027 _string_21_and_with/imm32/subx-name -15028 3/imm32/rm32-is-first-output -15029 1/imm32/r32-is-first-inout -15030 0/imm32/no-imm32 -15031 0/imm32/no-disp32 -15032 0/imm32/output-is-write-only -15033 0x11/imm32/alloc-id:fake -15034 _Primitive-and-reg-with-mem/imm32/next -15035 _Primitive-and-reg-with-mem: # (payload primitive) -15036 0x11/imm32/alloc-id:fake:payload -15037 # and-with var1 var2/reg => 21/and-with var1 var2/r32 -15038 0x11/imm32/alloc-id:fake -15039 _string-and-with/imm32/name -15040 0x11/imm32/alloc-id:fake -15041 Two-args-int-stack-int-reg/imm32/inouts -15042 0/imm32/no-outputs -15043 0/imm32/no-outputs -15044 0x11/imm32/alloc-id:fake -15045 _string_21_and_with/imm32/subx-name -15046 1/imm32/rm32-is-first-inout -15047 2/imm32/r32-is-second-inout -15048 0/imm32/no-imm32 -15049 0/imm32/no-disp32 -15050 0/imm32/output-is-write-only -15051 0x11/imm32/alloc-id:fake -15052 _Primitive-and-mem-with-reg/imm32/next -15053 _Primitive-and-mem-with-reg: # (payload primitive) -15054 0x11/imm32/alloc-id:fake:payload -15055 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 -15056 0x11/imm32/alloc-id:fake -15057 _string-and/imm32/name -15058 0x11/imm32/alloc-id:fake -15059 Single-int-var-in-mem/imm32/inouts -15060 0x11/imm32/alloc-id:fake -15061 Single-int-var-in-some-register/imm32/outputs -15062 0x11/imm32/alloc-id:fake -15063 _string_23_and/imm32/subx-name -15064 1/imm32/rm32-is-first-inout -15065 3/imm32/r32-is-first-output -15066 0/imm32/no-imm32 -15067 0/imm32/no-disp32 -15068 0/imm32/output-is-write-only -15069 0x11/imm32/alloc-id:fake -15070 _Primitive-and-lit-with-reg/imm32/next -15071 _Primitive-and-lit-with-reg: # (payload primitive) -15072 0x11/imm32/alloc-id:fake:payload -15073 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 -15074 0x11/imm32/alloc-id:fake -15075 _string-and/imm32/name -15076 0x11/imm32/alloc-id:fake -15077 Single-lit-var/imm32/inouts -15078 0x11/imm32/alloc-id:fake -15079 Single-int-var-in-some-register/imm32/outputs -15080 0x11/imm32/alloc-id:fake -15081 _string_81_subop_and/imm32/subx-name -15082 3/imm32/rm32-is-first-output -15083 0/imm32/no-r32 -15084 1/imm32/imm32-is-first-inout -15085 0/imm32/no-disp32 -15086 0/imm32/output-is-write-only -15087 0x11/imm32/alloc-id:fake -15088 _Primitive-and-lit-with-mem/imm32/next -15089 _Primitive-and-lit-with-mem: # (payload primitive) -15090 0x11/imm32/alloc-id:fake:payload -15091 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 -15092 0x11/imm32/alloc-id:fake -15093 _string-and-with/imm32/name -15094 0x11/imm32/alloc-id:fake -15095 Int-var-and-literal/imm32/inouts -15096 0/imm32/no-outputs -15097 0/imm32/no-outputs -15098 0x11/imm32/alloc-id:fake -15099 _string_81_subop_and/imm32/subx-name -15100 1/imm32/rm32-is-first-inout -15101 0/imm32/no-r32 -15102 2/imm32/imm32-is-first-inout -15103 0/imm32/no-disp32 -15104 0/imm32/output-is-write-only -15105 0x11/imm32/alloc-id:fake -15106 _Primitive-or-with-eax/imm32/next -15107 # - or -15108 _Primitive-or-with-eax: # (payload primitive) -15109 0x11/imm32/alloc-id:fake:payload -15110 # var/eax <- or lit => 0d/or-with-eax lit/imm32 -15111 0x11/imm32/alloc-id:fake -15112 _string-or/imm32/name -15113 0x11/imm32/alloc-id:fake -15114 Single-lit-var/imm32/inouts -15115 0x11/imm32/alloc-id:fake -15116 Single-int-var-in-eax/imm32/outputs -15117 0x11/imm32/alloc-id:fake -15118 _string_0d_or_with_eax/imm32/subx-name -15119 0/imm32/no-rm32 -15120 0/imm32/no-r32 -15121 1/imm32/imm32-is-first-inout -15122 0/imm32/no-disp32 -15123 0/imm32/output-is-write-only -15124 0x11/imm32/alloc-id:fake -15125 _Primitive-or-reg-with-reg/imm32/next -15126 _Primitive-or-reg-with-reg: # (payload primitive) -15127 0x11/imm32/alloc-id:fake:payload -15128 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 -15129 0x11/imm32/alloc-id:fake -15130 _string-or/imm32/name -15131 0x11/imm32/alloc-id:fake -15132 Single-int-var-in-some-register/imm32/inouts -15133 0x11/imm32/alloc-id:fake -15134 Single-int-var-in-some-register/imm32/outputs -15135 0x11/imm32/alloc-id:fake -15136 _string_09_or_with/imm32/subx-name -15137 3/imm32/rm32-is-first-output -15138 1/imm32/r32-is-first-inout -15139 0/imm32/no-imm32 -15140 0/imm32/no-disp32 -15141 0/imm32/output-is-write-only -15142 0x11/imm32/alloc-id:fake -15143 _Primitive-or-reg-with-mem/imm32/next -15144 _Primitive-or-reg-with-mem: # (payload primitive) -15145 0x11/imm32/alloc-id:fake:payload -15146 # or-with var1 var2/reg => 09/or-with var1 var2/r32 -15147 0x11/imm32/alloc-id:fake -15148 _string-or-with/imm32/name -15149 0x11/imm32/alloc-id:fake -15150 Two-args-int-stack-int-reg/imm32/inouts -15151 0/imm32/no-outputs -15152 0/imm32/no-outputs -15153 0x11/imm32/alloc-id:fake -15154 _string_09_or_with/imm32/subx-name -15155 1/imm32/rm32-is-first-inout -15156 2/imm32/r32-is-second-inout -15157 0/imm32/no-imm32 -15158 0/imm32/no-disp32 -15159 0/imm32/output-is-write-only -15160 0x11/imm32/alloc-id:fake -15161 _Primitive-or-mem-with-reg/imm32/next -15162 _Primitive-or-mem-with-reg: # (payload primitive) -15163 0x11/imm32/alloc-id:fake:payload -15164 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 -15165 0x11/imm32/alloc-id:fake -15166 _string-or/imm32/name -15167 0x11/imm32/alloc-id:fake -15168 Single-int-var-in-mem/imm32/inouts -15169 0x11/imm32/alloc-id:fake -15170 Single-int-var-in-some-register/imm32/outputs -15171 0x11/imm32/alloc-id:fake -15172 _string_0b_or/imm32/subx-name -15173 1/imm32/rm32-is-first-inout -15174 3/imm32/r32-is-first-output -15175 0/imm32/no-imm32 -15176 0/imm32/no-disp32 -15177 0/imm32/output-is-write-only -15178 0x11/imm32/alloc-id:fake -15179 _Primitive-or-lit-with-reg/imm32/next -15180 _Primitive-or-lit-with-reg: # (payload primitive) -15181 0x11/imm32/alloc-id:fake:payload -15182 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 -15183 0x11/imm32/alloc-id:fake -15184 _string-or/imm32/name -15185 0x11/imm32/alloc-id:fake -15186 Single-lit-var/imm32/inouts -15187 0x11/imm32/alloc-id:fake -15188 Single-int-var-in-some-register/imm32/outputs -15189 0x11/imm32/alloc-id:fake -15190 _string_81_subop_or/imm32/subx-name -15191 3/imm32/rm32-is-first-output -15192 0/imm32/no-r32 -15193 1/imm32/imm32-is-first-inout -15194 0/imm32/no-disp32 -15195 0/imm32/output-is-write-only -15196 0x11/imm32/alloc-id:fake -15197 _Primitive-or-lit-with-mem/imm32/next -15198 _Primitive-or-lit-with-mem: # (payload primitive) -15199 0x11/imm32/alloc-id:fake:payload -15200 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 -15201 0x11/imm32/alloc-id:fake -15202 _string-or-with/imm32/name -15203 0x11/imm32/alloc-id:fake -15204 Int-var-and-literal/imm32/inouts -15205 0/imm32/no-outputs -15206 0/imm32/no-outputs -15207 0x11/imm32/alloc-id:fake -15208 _string_81_subop_or/imm32/subx-name -15209 1/imm32/rm32-is-first-inout -15210 0/imm32/no-r32 -15211 2/imm32/imm32-is-second-inout -15212 0/imm32/no-disp32 -15213 0/imm32/output-is-write-only -15214 0x11/imm32/alloc-id:fake -15215 _Primitive-xor-with-eax/imm32/next -15216 # - xor -15217 _Primitive-xor-with-eax: # (payload primitive) -15218 0x11/imm32/alloc-id:fake:payload -15219 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 -15220 0x11/imm32/alloc-id:fake -15221 _string-xor/imm32/name -15222 0x11/imm32/alloc-id:fake -15223 Single-lit-var/imm32/inouts -15224 0x11/imm32/alloc-id:fake -15225 Single-int-var-in-eax/imm32/outputs -15226 0x11/imm32/alloc-id:fake -15227 _string_35_xor_with_eax/imm32/subx-name -15228 0/imm32/no-rm32 -15229 0/imm32/no-r32 -15230 1/imm32/imm32-is-first-inout -15231 0/imm32/no-disp32 -15232 0/imm32/output-is-write-only -15233 0x11/imm32/alloc-id:fake -15234 _Primitive-xor-reg-with-reg/imm32/next -15235 _Primitive-xor-reg-with-reg: # (payload primitive) -15236 0x11/imm32/alloc-id:fake:payload -15237 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 -15238 0x11/imm32/alloc-id:fake -15239 _string-xor/imm32/name -15240 0x11/imm32/alloc-id:fake -15241 Single-int-var-in-some-register/imm32/inouts -15242 0x11/imm32/alloc-id:fake -15243 Single-int-var-in-some-register/imm32/outputs -15244 0x11/imm32/alloc-id:fake -15245 _string_31_xor_with/imm32/subx-name -15246 3/imm32/rm32-is-first-output -15247 1/imm32/r32-is-first-inout -15248 0/imm32/no-imm32 -15249 0/imm32/no-disp32 -15250 0/imm32/output-is-write-only -15251 0x11/imm32/alloc-id:fake -15252 _Primitive-xor-reg-with-mem/imm32/next -15253 _Primitive-xor-reg-with-mem: # (payload primitive) -15254 0x11/imm32/alloc-id:fake:payload -15255 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 -15256 0x11/imm32/alloc-id:fake -15257 _string-xor-with/imm32/name -15258 0x11/imm32/alloc-id:fake -15259 Two-args-int-stack-int-reg/imm32/inouts -15260 0/imm32/no-outputs -15261 0/imm32/no-outputs -15262 0x11/imm32/alloc-id:fake -15263 _string_31_xor_with/imm32/subx-name -15264 1/imm32/rm32-is-first-inout -15265 2/imm32/r32-is-second-inout -15266 0/imm32/no-imm32 -15267 0/imm32/no-disp32 -15268 0/imm32/output-is-write-only -15269 0x11/imm32/alloc-id:fake -15270 _Primitive-xor-mem-with-reg/imm32/next -15271 _Primitive-xor-mem-with-reg: # (payload primitive) -15272 0x11/imm32/alloc-id:fake:payload -15273 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 -15274 0x11/imm32/alloc-id:fake -15275 _string-xor/imm32/name -15276 0x11/imm32/alloc-id:fake -15277 Single-int-var-in-mem/imm32/inouts -15278 0x11/imm32/alloc-id:fake -15279 Single-int-var-in-some-register/imm32/outputs -15280 0x11/imm32/alloc-id:fake -15281 _string_33_xor/imm32/subx-name -15282 1/imm32/rm32-is-first-inout -15283 3/imm32/r32-is-first-output -15284 0/imm32/no-imm32 -15285 0/imm32/no-disp32 -15286 0/imm32/output-is-write-only -15287 0x11/imm32/alloc-id:fake -15288 _Primitive-xor-lit-with-reg/imm32/next -15289 _Primitive-xor-lit-with-reg: # (payload primitive) -15290 0x11/imm32/alloc-id:fake:payload -15291 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 -15292 0x11/imm32/alloc-id:fake -15293 _string-xor/imm32/name -15294 0x11/imm32/alloc-id:fake -15295 Single-lit-var/imm32/inouts -15296 0x11/imm32/alloc-id:fake -15297 Single-int-var-in-some-register/imm32/outputs -15298 0x11/imm32/alloc-id:fake -15299 _string_81_subop_xor/imm32/subx-name -15300 3/imm32/rm32-is-first-output -15301 0/imm32/no-r32 -15302 1/imm32/imm32-is-first-inout -15303 0/imm32/no-disp32 -15304 0/imm32/output-is-write-only -15305 0x11/imm32/alloc-id:fake -15306 _Primitive-xor-lit-with-mem/imm32/next -15307 _Primitive-xor-lit-with-mem: # (payload primitive) -15308 0x11/imm32/alloc-id:fake:payload -15309 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 -15310 0x11/imm32/alloc-id:fake -15311 _string-xor-with/imm32/name -15312 0x11/imm32/alloc-id:fake -15313 Int-var-and-literal/imm32/inouts -15314 0/imm32/no-outputs -15315 0/imm32/no-outputs -15316 0x11/imm32/alloc-id:fake -15317 _string_81_subop_xor/imm32/subx-name -15318 1/imm32/rm32-is-first-inout -15319 0/imm32/no-r32 -15320 2/imm32/imm32-is-first-inout -15321 0/imm32/no-disp32 -15322 0/imm32/output-is-write-only -15323 0x11/imm32/alloc-id:fake -15324 _Primitive-copy-to-eax/imm32/next -15325 # - copy -15326 _Primitive-copy-to-eax: # (payload primitive) -15327 0x11/imm32/alloc-id:fake:payload -15328 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 -15329 0x11/imm32/alloc-id:fake -15330 _string-copy/imm32/name -15331 0x11/imm32/alloc-id:fake -15332 Single-lit-var/imm32/inouts -15333 0x11/imm32/alloc-id:fake -15334 Single-int-var-in-eax/imm32/outputs -15335 0x11/imm32/alloc-id:fake -15336 _string_b8_copy_to_eax/imm32/subx-name -15337 0/imm32/no-rm32 -15338 0/imm32/no-r32 -15339 1/imm32/imm32-is-first-inout -15340 0/imm32/no-disp32 -15341 1/imm32/output-is-write-only -15342 0x11/imm32/alloc-id:fake -15343 _Primitive-copy-to-ecx/imm32/next -15344 _Primitive-copy-to-ecx: # (payload primitive) -15345 0x11/imm32/alloc-id:fake:payload -15346 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 -15347 0x11/imm32/alloc-id:fake -15348 _string-copy/imm32/name -15349 0x11/imm32/alloc-id:fake -15350 Single-lit-var/imm32/inouts -15351 0x11/imm32/alloc-id:fake -15352 Single-int-var-in-ecx/imm32/outputs -15353 0x11/imm32/alloc-id:fake -15354 _string_b9_copy_to_ecx/imm32/subx-name -15355 0/imm32/no-rm32 -15356 0/imm32/no-r32 -15357 1/imm32/imm32-is-first-inout -15358 0/imm32/no-disp32 -15359 1/imm32/output-is-write-only -15360 0x11/imm32/alloc-id:fake -15361 _Primitive-copy-to-edx/imm32/next -15362 _Primitive-copy-to-edx: # (payload primitive) -15363 0x11/imm32/alloc-id:fake:payload -15364 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 -15365 0x11/imm32/alloc-id:fake -15366 _string-copy/imm32/name -15367 0x11/imm32/alloc-id:fake -15368 Single-lit-var/imm32/inouts -15369 0x11/imm32/alloc-id:fake -15370 Single-int-var-in-edx/imm32/outputs -15371 0x11/imm32/alloc-id:fake -15372 _string_ba_copy_to_edx/imm32/subx-name -15373 0/imm32/no-rm32 -15374 0/imm32/no-r32 -15375 1/imm32/imm32-is-first-inout -15376 0/imm32/no-disp32 -15377 1/imm32/output-is-write-only -15378 0x11/imm32/alloc-id:fake -15379 _Primitive-copy-to-ebx/imm32/next -15380 _Primitive-copy-to-ebx: # (payload primitive) -15381 0x11/imm32/alloc-id:fake:payload -15382 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 -15383 0x11/imm32/alloc-id:fake -15384 _string-copy/imm32/name -15385 0x11/imm32/alloc-id:fake -15386 Single-lit-var/imm32/inouts -15387 0x11/imm32/alloc-id:fake -15388 Single-int-var-in-ebx/imm32/outputs -15389 0x11/imm32/alloc-id:fake -15390 _string_bb_copy_to_ebx/imm32/subx-name -15391 0/imm32/no-rm32 -15392 0/imm32/no-r32 -15393 1/imm32/imm32-is-first-inout -15394 0/imm32/no-disp32 -15395 1/imm32/output-is-write-only -15396 0x11/imm32/alloc-id:fake -15397 _Primitive-copy-to-esi/imm32/next -15398 _Primitive-copy-to-esi: # (payload primitive) -15399 0x11/imm32/alloc-id:fake:payload -15400 # var/esi <- copy lit => be/copy-to-esi lit/imm32 -15401 0x11/imm32/alloc-id:fake -15402 _string-copy/imm32/name -15403 0x11/imm32/alloc-id:fake -15404 Single-lit-var/imm32/inouts -15405 0x11/imm32/alloc-id:fake -15406 Single-int-var-in-esi/imm32/outputs -15407 0x11/imm32/alloc-id:fake -15408 _string_be_copy_to_esi/imm32/subx-name -15409 0/imm32/no-rm32 -15410 0/imm32/no-r32 -15411 1/imm32/imm32-is-first-inout -15412 0/imm32/no-disp32 -15413 1/imm32/output-is-write-only -15414 0x11/imm32/alloc-id:fake -15415 _Primitive-copy-to-edi/imm32/next -15416 _Primitive-copy-to-edi: # (payload primitive) -15417 0x11/imm32/alloc-id:fake:payload -15418 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 -15419 0x11/imm32/alloc-id:fake -15420 _string-copy/imm32/name -15421 0x11/imm32/alloc-id:fake -15422 Single-lit-var/imm32/inouts -15423 0x11/imm32/alloc-id:fake -15424 Single-int-var-in-edi/imm32/outputs -15425 0x11/imm32/alloc-id:fake -15426 _string_bf_copy_to_edi/imm32/subx-name -15427 0/imm32/no-rm32 -15428 0/imm32/no-r32 -15429 1/imm32/imm32-is-first-inout -15430 0/imm32/no-disp32 -15431 1/imm32/output-is-write-only -15432 0x11/imm32/alloc-id:fake -15433 _Primitive-copy-reg-to-reg/imm32/next -15434 _Primitive-copy-reg-to-reg: # (payload primitive) -15435 0x11/imm32/alloc-id:fake:payload -15436 # var1/reg <- copy var2/reg => 89/<- var1/rm32 var2/r32 -15437 0x11/imm32/alloc-id:fake -15438 _string-copy/imm32/name -15439 0x11/imm32/alloc-id:fake -15440 Single-int-var-in-some-register/imm32/inouts -15441 0x11/imm32/alloc-id:fake -15442 Single-int-var-in-some-register/imm32/outputs -15443 0x11/imm32/alloc-id:fake -15444 _string_89_<-/imm32/subx-name -15445 3/imm32/rm32-is-first-output -15446 1/imm32/r32-is-first-inout -15447 0/imm32/no-imm32 -15448 0/imm32/no-disp32 -15449 1/imm32/output-is-write-only -15450 0x11/imm32/alloc-id:fake -15451 _Primitive-copy-reg-to-mem/imm32/next -15452 _Primitive-copy-reg-to-mem: # (payload primitive) -15453 0x11/imm32/alloc-id:fake:payload -15454 # copy-to var1 var2/reg => 89/<- var1 var2/r32 -15455 0x11/imm32/alloc-id:fake -15456 _string-copy-to/imm32/name -15457 0x11/imm32/alloc-id:fake -15458 Two-args-int-stack-int-reg/imm32/inouts -15459 0/imm32/no-outputs -15460 0/imm32/no-outputs -15461 0x11/imm32/alloc-id:fake -15462 _string_89_<-/imm32/subx-name -15463 1/imm32/rm32-is-first-inout -15464 2/imm32/r32-is-second-inout -15465 0/imm32/no-imm32 -15466 0/imm32/no-disp32 -15467 1/imm32/output-is-write-only -15468 0x11/imm32/alloc-id:fake -15469 _Primitive-copy-mem-to-reg/imm32/next -15470 _Primitive-copy-mem-to-reg: # (payload primitive) -15471 0x11/imm32/alloc-id:fake:payload -15472 # var1/reg <- copy var2 => 8b/-> var2/rm32 var1/r32 -15473 0x11/imm32/alloc-id:fake -15474 _string-copy/imm32/name -15475 0x11/imm32/alloc-id:fake -15476 Single-int-var-in-mem/imm32/inouts -15477 0x11/imm32/alloc-id:fake -15478 Single-int-var-in-some-register/imm32/outputs +14402 $emit-subx-stmt:check-for-primitive: +14403 # var curr/eax: (addr primitive) +14404 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => eax +14405 3d/compare-eax-and 0/imm32 +14406 74/jump-if-= break/disp8 +14407 $emit-subx-stmt:primitive: +14408 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr +14409 e9/jump $emit-subx-stmt:end/disp32 +14410 } +14411 # - otherwise emit a call +14412 # TODO: type-checking +14413 $emit-subx-stmt:call: +14414 (emit-call *(ebp+8) *(ebp+0xc)) +14415 $emit-subx-stmt:end: +14416 # . restore registers +14417 59/pop-to-ecx +14418 58/pop-to-eax +14419 # . epilogue +14420 89/<- %esp 5/r32/ebp +14421 5d/pop-to-ebp +14422 c3/return +14423 +14424 translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +14425 # . prologue +14426 55/push-ebp +14427 89/<- %ebp 4/r32/esp +14428 # . save registers +14429 50/push-eax +14430 51/push-ecx +14431 52/push-edx +14432 53/push-ebx +14433 56/push-esi +14434 # esi = stmt +14435 8b/-> *(ebp+0xc) 6/r32/esi +14436 # var base/ebx: (addr var) = stmt->inouts[0]->value +14437 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +14438 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +14439 89/<- %ebx 0/r32/eax +14440 # var elemsize/ecx: int = array-element-size(base) +14441 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +14442 89/<- %ecx 0/r32/eax +14443 # var outreg/edx: (addr array byte) = stmt->outputs[0]->value->register +14444 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +14445 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +14446 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +14447 89/<- %edx 0/r32/eax +14448 # if elemsize == 1 +14449 { +14450 81 7/subop/compare %ecx 1/imm32 +14451 75/jump-if-!= break/disp8 +14452 $translate-mu-length-stmt:size-1: +14453 (emit-save-size-to *(ebp+8) %ebx %edx) +14454 e9/jump $translate-mu-length-stmt:end/disp32 +14455 } +14456 # if elemsize is a power of 2 less than 256 +14457 { +14458 (power-of-2? %ecx *(ebp+0x10) *(ebp+0x14)) # => eax +14459 3d/compare-eax-and 0/imm32/false +14460 74/jump-if-= break/disp8 +14461 81 7/subop/compare %ecx 0xff/imm32 +14462 7f/jump-if-> break/disp8 +14463 $translate-mu-length-stmt:size-power-of-2: +14464 (emit-save-size-to *(ebp+8) %ebx %edx) +14465 (emit-divide-by-shift-right *(ebp+8) %edx %ecx) +14466 e9/jump $translate-mu-length-stmt:end/disp32 +14467 } +14468 # otherwise, the complex case +14469 # . emit register spills +14470 { +14471 $translate-mu-length-stmt:complex: +14472 (string-equal? %edx "eax") # => eax +14473 3d/compare-eax-and 0/imm32/false +14474 75/break-if-!= break/disp8 +14475 (emit-indent *(ebp+8) *Curr-block-depth) +14476 (write-buffered *(ebp+8) "50/push-eax\n") +14477 } +14478 { +14479 (string-equal? %edx "ecx") # => eax +14480 3d/compare-eax-and 0/imm32/false +14481 75/break-if-!= break/disp8 +14482 (emit-indent *(ebp+8) *Curr-block-depth) +14483 (write-buffered *(ebp+8) "51/push-ecx\n") +14484 } +14485 { +14486 (string-equal? %edx "edx") # => eax +14487 3d/compare-eax-and 0/imm32/false +14488 75/break-if-!= break/disp8 +14489 (emit-indent *(ebp+8) *Curr-block-depth) +14490 (write-buffered *(ebp+8) "52/push-edx\n") +14491 } +14492 # . +14493 (emit-save-size-to *(ebp+8) %ebx "eax") +14494 (emit-indent *(ebp+8) *Curr-block-depth) +14495 (write-buffered *(ebp+8) "31/xor %edx 2/r32/edx\n") +14496 (emit-indent *(ebp+8) *Curr-block-depth) +14497 (write-buffered *(ebp+8) "b9/copy-to-ecx ") +14498 (write-int32-hex-buffered *(ebp+8) %ecx) +14499 (write-buffered *(ebp+8) "/imm32\n") +14500 (emit-indent *(ebp+8) *Curr-block-depth) +14501 (write-buffered *(ebp+8) "f7 7/subop/idiv-eax-edx-by %ecx\n") +14502 { +14503 (string-equal? %edx "eax") # => eax +14504 3d/compare-eax-and 0/imm32/false +14505 75/break-if-!= break/disp8 +14506 (emit-indent *(ebp+8) *Curr-block-depth) +14507 (write-buffered *(ebp+8) "89/<- %") +14508 (write-buffered *(ebp+8) %edx) +14509 (write-buffered *(ebp+8) " 0/r32/eax\n") +14510 } +14511 # . emit register restores +14512 { +14513 (string-equal? %edx "edx") # => eax +14514 3d/compare-eax-and 0/imm32/false +14515 75/break-if-!= break/disp8 +14516 (emit-indent *(ebp+8) *Curr-block-depth) +14517 (write-buffered *(ebp+8) "5a/pop-to-edx\n") +14518 } +14519 { +14520 (string-equal? %edx "ecx") # => eax +14521 3d/compare-eax-and 0/imm32/false +14522 75/break-if-!= break/disp8 +14523 (emit-indent *(ebp+8) *Curr-block-depth) +14524 (write-buffered *(ebp+8) "59/pop-to-ecx\n") +14525 } +14526 { +14527 (string-equal? %edx "eax") # => eax +14528 3d/compare-eax-and 0/imm32/false +14529 75/break-if-!= break/disp8 +14530 (emit-indent *(ebp+8) *Curr-block-depth) +14531 (write-buffered *(ebp+8) "58/pop-to-eax\n") +14532 } +14533 $translate-mu-length-stmt:end: +14534 # . restore registers +14535 5e/pop-to-esi +14536 5b/pop-to-ebx +14537 5a/pop-to-edx +14538 59/pop-to-ecx +14539 58/pop-to-eax +14540 # . epilogue +14541 89/<- %esp 5/r32/ebp +14542 5d/pop-to-ebp +14543 c3/return +14544 +14545 array-element-size: # arr: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +14546 # . prologue +14547 55/push-ebp +14548 89/<- %ebp 4/r32/esp +14549 # +14550 (array-element-type-id *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax +14551 (size-of-type-id-as-array-element %eax) # => eax +14552 $array-element-size:end: +14553 # . epilogue +14554 89/<- %esp 5/r32/ebp +14555 5d/pop-to-ebp +14556 c3/return +14557 +14558 array-element-type-id: # v: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: type-id +14559 # precondition: n is positive +14560 # . prologue +14561 55/push-ebp +14562 89/<- %ebp 4/r32/esp +14563 # +14564 8b/-> *(ebp+8) 0/r32/eax +14565 # var t/eax: (addr type-tree) +14566 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +14567 # if t == 0 abort +14568 3d/compare-eax-with 0/imm32 +14569 0f 84/jump-if-== $array-element-type-id:error0/disp32 +14570 # if t->is-atom? abort +14571 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +14572 0f 85/jump-if-!= $array-element-type-id:error1/disp32 +14573 # if (t->left == addr) t = t->right +14574 { +14575 50/push-eax +14576 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +14577 (is-simple-mu-type? %eax 2) # addr => eax +14578 3d/compare-eax-with 0/imm32/false +14579 58/pop-to-eax +14580 74/jump-if-= break/disp8 +14581 $array-element-type-id:skip-addr: +14582 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +14583 } +14584 # if t == 0 abort +14585 3d/compare-eax-with 0/imm32 +14586 0f 84/jump-if-= $array-element-type-id:error2/disp32 +14587 # if t->is-atom? abort +14588 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +14589 0f 85/jump-if-!= $array-element-type-id:error2/disp32 +14590 # if t->left != array abort +14591 { +14592 50/push-eax +14593 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +14594 (is-simple-mu-type? %eax 3) # array => eax +14595 3d/compare-eax-with 0/imm32/false +14596 58/pop-to-eax +14597 $array-element-type-id:no-array: +14598 0f 84/jump-if-= $array-element-type-id:error2/disp32 +14599 } +14600 $array-element-type-id:skip-array: +14601 # t = t->right +14602 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +14603 # if t == 0 abort +14604 3d/compare-eax-with 0/imm32 +14605 0f 84/jump-if-= $array-element-type-id:error2/disp32 +14606 # if t->is-atom? abort +14607 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +14608 0f 85/jump-if-!= $array-element-type-id:error2/disp32 +14609 # return t->left->value +14610 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +14611 8b/-> *(eax+4) 0/r32/eax # Type-tree-value +14612 $array-element-type-id:end: +14613 # . epilogue +14614 89/<- %esp 5/r32/ebp +14615 5d/pop-to-ebp +14616 c3/return +14617 +14618 $array-element-type-id:error0: +14619 (write-buffered *(ebp+0xc) "array-element-type-id: var '") +14620 50/push-eax +14621 8b/-> *(ebp+8) 0/r32/eax +14622 (lookup *eax *(eax+4)) # Var-name Var-name => eax +14623 (write-buffered *(ebp+0xc) %eax) +14624 58/pop-to-eax +14625 (write-buffered *(ebp+0xc) "' has no type\n") +14626 (flush *(ebp+0xc)) +14627 (stop *(ebp+0x10) 1) +14628 # never gets here +14629 +14630 $array-element-type-id:error1: +14631 (write-buffered *(ebp+0xc) "array-element-type-id: var '") +14632 50/push-eax +14633 8b/-> *(ebp+8) 0/r32/eax +14634 (lookup *eax *(eax+4)) # Var-name Var-name => eax +14635 (write-buffered *(ebp+0xc) %eax) +14636 58/pop-to-eax +14637 (write-buffered *(ebp+0xc) "' has atomic type ") +14638 (write-int32-hex-buffered *(ebp+0xc) *(eax+4)) # Type-tree-value +14639 (write-buffered *(ebp+0xc) Newline) +14640 (flush *(ebp+0xc)) +14641 (stop *(ebp+0x10) 1) +14642 # never gets here +14643 +14644 $array-element-type-id:error2: +14645 (write-buffered *(ebp+0xc) "array-element-type-id: var '") +14646 50/push-eax +14647 8b/-> *(ebp+8) 0/r32/eax +14648 (lookup *eax *(eax+4)) # Var-name Var-name => eax +14649 (write-buffered *(ebp+0xc) %eax) +14650 58/pop-to-eax +14651 (write-buffered *(ebp+0xc) "' has non-array type\n") +14652 (flush *(ebp+0xc)) +14653 (stop *(ebp+0x10) 1) +14654 # never gets here +14655 +14656 size-of-type-id-as-array-element: # t: type-id -> result/eax: int +14657 # . prologue +14658 55/push-ebp +14659 89/<- %ebp 4/r32/esp +14660 # eax = t +14661 8b/-> *(ebp+8) 0/r32/eax +14662 # if t is 'byte', size is 1 +14663 3d/compare-eax-and 8/imm32/byte +14664 { +14665 75/jump-if-!= break/disp8 +14666 b8/copy-to-eax 1/imm32 +14667 eb/jump $size-of-type-id-as-array-element:end/disp8 +14668 } +14669 # otherwise proceed as usual +14670 (size-of-type-id %eax) # => eax +14671 $size-of-type-id-as-array-element:end: +14672 # . epilogue +14673 89/<- %esp 5/r32/ebp +14674 5d/pop-to-ebp +14675 c3/return +14676 +14677 emit-save-size-to: # out: (addr buffered-file), base: (addr var), outreg: (addr array byte) +14678 # . prologue +14679 55/push-ebp +14680 89/<- %ebp 4/r32/esp +14681 # . save registers +14682 50/push-eax +14683 53/push-ebx +14684 # ebx = base +14685 8b/-> *(ebp+0xc) 3/r32/ebx +14686 (emit-indent *(ebp+8) *Curr-block-depth) +14687 (write-buffered *(ebp+8) "8b/-> *") +14688 # if base is an (addr array ...) in a register +14689 { +14690 81 7/subop/compare *(ebx+0x18)) 0/imm32 # Var-register +14691 74/jump-if-= break/disp8 +14692 $emit-save-size-to:emit-base-from-register: +14693 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +14694 (write-buffered *(ebp+8) %eax) +14695 eb/jump $emit-save-size-to:emit-output/disp8 +14696 } +14697 # otherwise if base is an (array ...) on the stack +14698 { +14699 81 7/subop/compare *(ebx+0x14)) 0/imm32 # Var-offset +14700 74/jump-if-= break/disp8 +14701 $emit-save-size-to:emit-base-from-stack: +14702 (write-buffered *(ebp+8) "(ebp+") +14703 (write-int32-hex-buffered *(ebp+8) *(ebx+0x14)) # Var-offset +14704 (write-buffered *(ebp+8) ")") +14705 } +14706 $emit-save-size-to:emit-output: +14707 (write-buffered *(ebp+8) " ") +14708 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax +14709 (write-int32-hex-buffered *(ebp+8) *eax) +14710 (write-buffered *(ebp+8) "/r32\n") +14711 $emit-save-size-to:end: +14712 # . restore registers +14713 5b/pop-to-ebx +14714 58/pop-to-eax +14715 # . epilogue +14716 89/<- %esp 5/r32/ebp +14717 5d/pop-to-ebp +14718 c3/return +14719 +14720 emit-divide-by-shift-right: # out: (addr buffered-file), reg: (addr array byte), size: int +14721 # . prologue +14722 55/push-ebp +14723 89/<- %ebp 4/r32/esp +14724 # . save registers +14725 50/push-eax +14726 # +14727 (emit-indent *(ebp+8) *Curr-block-depth) +14728 (write-buffered *(ebp+8) "c1/shift 5/subop/>> %") +14729 (write-buffered *(ebp+8) *(ebp+0xc)) +14730 (write-buffered *(ebp+8) Space) +14731 (num-shift-rights *(ebp+0x10)) # => eax +14732 (write-int32-hex-buffered *(ebp+8) %eax) +14733 (write-buffered *(ebp+8) "/imm8\n") +14734 $emit-divide-by-shift-right:end: +14735 # . restore registers +14736 58/pop-to-eax +14737 # . epilogue +14738 89/<- %esp 5/r32/ebp +14739 5d/pop-to-ebp +14740 c3/return +14741 +14742 translate-mu-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +14743 # . prologue +14744 55/push-ebp +14745 89/<- %ebp 4/r32/esp +14746 # . save registers +14747 51/push-ecx +14748 # ecx = stmt +14749 8b/-> *(ebp+0xc) 1/r32/ecx +14750 # var base/ecx: (addr var) = stmt->inouts[0] +14751 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +14752 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +14753 89/<- %ecx 0/r32/eax +14754 # if (var->register) do one thing +14755 { +14756 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +14757 74/jump-if-= break/disp8 +14758 # TODO: ensure there's no dereference +14759 (translate-mu-index-stmt-with-array-in-register *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +14760 eb/jump $translate-mu-index-stmt:end/disp8 +14761 } +14762 # if (var->offset) do a different thing +14763 { +14764 81 7/subop/compare *(ecx+0x14) 0/imm32 # Var-offset +14765 74/jump-if-= break/disp8 +14766 # TODO: ensure there's no dereference +14767 (translate-mu-index-stmt-with-array-on-stack *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +14768 eb/jump $translate-mu-index-stmt:end/disp8 +14769 } +14770 $translate-mu-index-stmt:end: +14771 # . restore registers +14772 59/pop-to-ecx +14773 # . epilogue +14774 89/<- %esp 5/r32/ebp +14775 5d/pop-to-ebp +14776 c3/return +14777 +14778 $translate-mu-index-stmt-with-array:error1: +14779 (write-buffered *(ebp+0x10) "couldn't translate an index instruction. second (index) input must either lie in a register or be a literal\n") +14780 (flush *(ebp+0x10)) +14781 (stop *(ebp+0x14) 1) +14782 # never gets here +14783 +14784 $translate-mu-index-stmt-with-array:error2: +14785 (write-buffered *(ebp+0x10) "couldn't translate an index instruction. second (index) input when in a register must be an int or offset\n") +14786 (flush *(ebp+0x10)) +14787 (stop *(ebp+0x14) 1) +14788 # never gets here +14789 +14790 translate-mu-index-stmt-with-array-in-register: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +14791 # . prologue +14792 55/push-ebp +14793 89/<- %ebp 4/r32/esp +14794 # . save registers +14795 50/push-eax +14796 51/push-ecx +14797 52/push-edx +14798 53/push-ebx +14799 # +14800 (emit-indent *(ebp+8) *Curr-block-depth) +14801 (write-buffered *(ebp+8) "8d/copy-address *(") +14802 # TODO: ensure inouts[0] is in a register and not dereferenced +14803 $translate-mu-index-stmt-with-array-in-register:emit-base: +14804 # ecx = stmt +14805 8b/-> *(ebp+0xc) 1/r32/ecx +14806 # var base/ebx: (addr var) = inouts[0] +14807 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +14808 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +14809 89/<- %ebx 0/r32/eax +14810 # print base->register " + " +14811 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +14812 (write-buffered *(ebp+8) %eax) +14813 (write-buffered *(ebp+8) " + ") +14814 # var index/edx: (addr var) = inouts[1] +14815 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +14816 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +14817 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +14818 89/<- %edx 0/r32/eax +14819 # if index->register +14820 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register +14821 { +14822 0f 84/jump-if-= break/disp32 +14823 $translate-mu-index-stmt-with-array-in-register:emit-register-index: +14824 # if index is an int +14825 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +14826 (is-simple-mu-type? %eax 1) # int => eax +14827 3d/compare-eax-and 0/imm32/false +14828 { +14829 0f 84/jump-if-= break/disp32 +14830 $translate-mu-index-stmt-with-array-in-register:emit-int-register-index: +14831 # print index->register "<<" log2(array-element-size(base)) " + 4) " +14832 # . index->register "<<" +14833 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +14834 (write-buffered *(ebp+8) %eax) +14835 (write-buffered *(ebp+8) "<<") +14836 # . log2(array-element-size(base->type)) +14837 # TODO: ensure size is a power of 2 +14838 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +14839 (num-shift-rights %eax) # => eax +14840 (write-int32-hex-buffered *(ebp+8) %eax) +14841 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-register-index-done/disp32 +14842 } +14843 # if index->type is any other atom, abort +14844 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +14845 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +14846 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 +14847 # if index has type (offset ...) +14848 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +14849 (is-simple-mu-type? %eax 7) # => eax +14850 3d/compare-eax-and 0/imm32/false +14851 { +14852 0f 84/jump-if-= break/disp32 +14853 # print index->register +14854 $translate-mu-index-stmt-with-array-in-register:emit-offset-register-index: +14855 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +14856 (write-buffered *(ebp+8) %eax) +14857 } +14858 $translate-mu-index-stmt-with-array-in-register:emit-register-index-done: +14859 (write-buffered *(ebp+8) " + 4) ") +14860 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 +14861 } +14862 # otherwise if index is a literal +14863 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +14864 (is-simple-mu-type? %eax 0) # => eax +14865 3d/compare-eax-and 0/imm32/false +14866 { +14867 0f 84/jump-if-= break/disp32 +14868 $translate-mu-index-stmt-with-array-in-register:emit-literal-index: +14869 # var index-value/edx: int = parse-hex-int(index->name) +14870 (lookup *edx *(edx+4)) # Var-name Var-name => eax +14871 (parse-hex-int %eax) # => eax +14872 89/<- %edx 0/r32/eax +14873 # offset = idx-value * array-element-size(base->type) +14874 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +14875 f7 4/subop/multiply-into-eax %edx # clobbers edx +14876 # offset += 4 for array size +14877 05/add-to-eax 4/imm32 +14878 # TODO: check edx for overflow +14879 # print offset +14880 (write-int32-hex-buffered *(ebp+8) %eax) +14881 (write-buffered *(ebp+8) ") ") +14882 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 +14883 } +14884 # otherwise abort +14885 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 +14886 $translate-mu-index-stmt-with-array-in-register:emit-output: +14887 # outputs[0] "/r32" +14888 8b/-> *(ebp+0xc) 1/r32/ecx +14889 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +14890 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +14891 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +14892 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +14893 (write-int32-hex-buffered *(ebp+8) *eax) +14894 (write-buffered *(ebp+8) "/r32\n") +14895 $translate-mu-index-stmt-with-array-in-register:end: +14896 # . restore registers +14897 5b/pop-to-ebx +14898 5a/pop-to-edx +14899 59/pop-to-ecx +14900 58/pop-to-eax +14901 # . epilogue +14902 89/<- %esp 5/r32/ebp +14903 5d/pop-to-ebp +14904 c3/return +14905 +14906 translate-mu-index-stmt-with-array-on-stack: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +14907 # . prologue +14908 55/push-ebp +14909 89/<- %ebp 4/r32/esp +14910 # . save registers +14911 50/push-eax +14912 51/push-ecx +14913 52/push-edx +14914 53/push-ebx +14915 # +14916 (emit-indent *(ebp+8) *Curr-block-depth) +14917 (write-buffered *(ebp+8) "8d/copy-address *(ebp + ") +14918 # var curr/edx: (addr stmt-var) = lookup(stmt->inouts) +14919 8b/-> *(ebp+0xc) 0/r32/eax +14920 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +14921 89/<- %edx 0/r32/eax +14922 # var base/ecx: (addr var) = lookup(curr->value) +14923 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +14924 89/<- %ecx 0/r32/eax +14925 # var curr2/eax: (addr stmt-var) = lookup(curr->next) +14926 (lookup *(edx+8) *(edx+0xc)) # Stmt-var-next Stmt-var-next => eax +14927 # var index/edx: (handle var) = curr2->value +14928 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +14929 89/<- %edx 0/r32/eax +14930 # if index->register +14931 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register +14932 { +14933 0f 84/jump-if-= break/disp32 +14934 $translate-mu-index-stmt-with-array-on-stack:emit-register-index: +14935 # if index is an int +14936 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +14937 (is-simple-mu-type? %eax 1) # int => eax +14938 3d/compare-eax-and 0/imm32/false +14939 { +14940 0f 84/jump-if-= break/disp32 +14941 $translate-mu-index-stmt-with-array-on-stack:emit-int-register-index: +14942 # print index->register "<<" log2(array-element-size(base)) " + " base->offset+4 +14943 # . inouts[1]->register "<<" +14944 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +14945 (write-buffered *(ebp+8) %eax) +14946 (write-buffered *(ebp+8) "<<") +14947 # . log2(array-element-size(base)) +14948 # TODO: ensure size is a power of 2 +14949 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax +14950 (num-shift-rights %eax) # => eax +14951 (write-int32-hex-buffered *(ebp+8) %eax) +14952 # +14953 (write-buffered *(ebp+8) " + ") +14954 # +14955 8b/-> *(ecx+0x14) 0/r32/eax # Var-offset +14956 05/add-to-eax 4/imm32 # for array length +14957 (write-int32-hex-buffered *(ebp+8) %eax) +14958 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done/disp32 +14959 } +14960 # if index->type is any other atom, abort +14961 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +14962 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +14963 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 +14964 # if index has type (offset ...) +14965 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +14966 (is-simple-mu-type? %eax 7) # => eax +14967 3d/compare-eax-and 0/imm32/false +14968 { +14969 0f 84/jump-if-= break/disp32 +14970 # print index->register +14971 $translate-mu-index-stmt-with-array-on-stack:emit-offset-register-index: +14972 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +14973 (write-buffered *(ebp+8) %eax) +14974 } +14975 $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done: +14976 (write-buffered *(ebp+8) ") ") +14977 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 +14978 } +14979 # otherwise if index is a literal +14980 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +14981 (is-simple-mu-type? %eax 0) # => eax +14982 3d/compare-eax-and 0/imm32/false +14983 { +14984 0f 84/jump-if-= break/disp32 +14985 $translate-mu-index-stmt-with-array-on-stack:emit-literal-index: +14986 # var idx-value/edx: int = parse-hex-int(index->name) +14987 (lookup *edx *(edx+4)) # Var-name Var-name => eax +14988 (parse-hex-int %eax) # Var-name => eax +14989 89/<- %edx 0/r32/eax +14990 # offset = idx-value * array-element-size(base) +14991 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax +14992 f7 4/subop/multiply-into-eax %edx # clobbers edx +14993 # offset += base->offset +14994 03/add *(ecx+0x14) 0/r32/eax # Var-offset +14995 # offset += 4 for array size +14996 05/add-to-eax 4/imm32 +14997 # TODO: check edx for overflow +14998 # print offset +14999 (write-int32-hex-buffered *(ebp+8) %eax) +15000 (write-buffered *(ebp+8) ") ") +15001 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 +15002 } +15003 # otherwise abort +15004 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 +15005 $translate-mu-index-stmt-with-array-on-stack:emit-output: +15006 # outputs[0] "/r32" +15007 8b/-> *(ebp+0xc) 0/r32/eax +15008 (lookup *(eax+0x14) *(eax+0x18)) # Stmt1-outputs Stmt1-outputs => eax +15009 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +15010 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +15011 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +15012 (write-int32-hex-buffered *(ebp+8) *eax) +15013 (write-buffered *(ebp+8) "/r32\n") +15014 $translate-mu-index-stmt-with-array-on-stack:end: +15015 # . restore registers +15016 5b/pop-to-ebx +15017 5a/pop-to-edx +15018 59/pop-to-ecx +15019 58/pop-to-eax +15020 # . epilogue +15021 89/<- %esp 5/r32/ebp +15022 5d/pop-to-ebp +15023 c3/return +15024 +15025 translate-mu-compute-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +15026 # . prologue +15027 55/push-ebp +15028 89/<- %ebp 4/r32/esp +15029 # . save registers +15030 50/push-eax +15031 51/push-ecx +15032 52/push-edx +15033 53/push-ebx +15034 # +15035 (emit-indent *(ebp+8) *Curr-block-depth) +15036 (write-buffered *(ebp+8) "69/multiply") +15037 # ecx = stmt +15038 8b/-> *(ebp+0xc) 1/r32/ecx +15039 # var first-inout/ebx: (addr stmt-var) = stmt->inouts[0] +15040 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +15041 89/<- %ebx 0/r32/eax +15042 $translate-mu-compute-index-stmt:emit-index: +15043 (lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax +15044 (emit-subx-var-as-rm32 *(ebp+8) %eax) +15045 (write-buffered *(ebp+8) Space) +15046 $translate-mu-compute-index-stmt:emit-elem-size: +15047 # var base/ebx: (addr var) +15048 (lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax +15049 89/<- %ebx 0/r32/eax +15050 # print array-element-size(base) +15051 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +15052 (write-int32-hex-buffered *(ebp+8) %eax) +15053 (write-buffered *(ebp+8) "/imm32 ") +15054 $translate-mu-compute-index-stmt:emit-output: +15055 # outputs[0] "/r32" +15056 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +15057 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +15058 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +15059 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +15060 (write-int32-hex-buffered *(ebp+8) *eax) +15061 (write-buffered *(ebp+8) "/r32\n") +15062 $translate-mu-compute-index-stmt:end: +15063 # . restore registers +15064 5b/pop-to-ebx +15065 5a/pop-to-edx +15066 59/pop-to-ecx +15067 58/pop-to-eax +15068 # . epilogue +15069 89/<- %esp 5/r32/ebp +15070 5d/pop-to-ebp +15071 c3/return +15072 +15073 translate-mu-get-stmt: # out: (addr buffered-file), stmt: (addr stmt) +15074 # . prologue +15075 55/push-ebp +15076 89/<- %ebp 4/r32/esp +15077 # . save registers +15078 50/push-eax +15079 51/push-ecx +15080 52/push-edx +15081 # +15082 (emit-indent *(ebp+8) *Curr-block-depth) +15083 (write-buffered *(ebp+8) "8d/copy-address ") +15084 # ecx = stmt +15085 8b/-> *(ebp+0xc) 1/r32/ecx +15086 # var offset/edx: int = get offset of stmt +15087 (mu-get-offset %ecx) # => eax +15088 89/<- %edx 0/r32/eax +15089 # var base/eax: (addr var) = stmt->inouts->value +15090 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +15091 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +15092 # if base is in a register +15093 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +15094 { +15095 0f 84/jump-if-= break/disp32 +15096 $translate-mu-get-stmt:emit-register-input: +15097 # emit "*(" base->register " + " offset ") " +15098 (write-buffered *(ebp+8) "*(") +15099 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +15100 (write-buffered *(ebp+8) %eax) +15101 (write-buffered *(ebp+8) " + ") +15102 (write-int32-hex-buffered *(ebp+8) %edx) +15103 (write-buffered *(ebp+8) ") ") +15104 e9/jump $translate-mu-get-stmt:emit-output/disp32 +15105 } +15106 # otherwise base is on the stack +15107 { +15108 $translate-mu-get-stmt:emit-stack-input: +15109 # emit "*(ebp + " inouts[0]->stack-offset + offset ") " +15110 (write-buffered *(ebp+8) "*(ebp+") +15111 03/add *(eax+0x14) 2/r32/edx # Var-offset +15112 (write-int32-hex-buffered *(ebp+8) %edx) +15113 (write-buffered *(ebp+8) ") ") +15114 eb/jump $translate-mu-get-stmt:emit-output/disp8 +15115 } +15116 $translate-mu-get-stmt:emit-output: +15117 # var output/eax: (addr var) = stmt->outputs->value +15118 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +15119 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +15120 # emit offset->register "/r32" +15121 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +15122 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +15123 (write-int32-hex-buffered *(ebp+8) *eax) +15124 (write-buffered *(ebp+8) "/r32\n") +15125 $translate-mu-get-stmt:end: +15126 # . restore registers +15127 5a/pop-to-edx +15128 59/pop-to-ecx +15129 58/pop-to-eax +15130 # . epilogue +15131 89/<- %esp 5/r32/ebp +15132 5d/pop-to-ebp +15133 c3/return +15134 +15135 translate-mu-allocate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +15136 # . prologue +15137 55/push-ebp +15138 89/<- %ebp 4/r32/esp +15139 # . save registers +15140 50/push-eax +15141 56/push-esi +15142 57/push-edi +15143 # esi = stmt +15144 8b/-> *(ebp+0xc) 6/r32/esi +15145 # var target/edi: (addr stmt-var) = stmt->inouts[0] +15146 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +15147 89/<- %edi 0/r32/eax +15148 # +15149 (emit-indent *(ebp+8) *Curr-block-depth) +15150 (write-buffered *(ebp+8) "(allocate Heap ") +15151 (addr-handle-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax +15152 (write-int32-hex-buffered *(ebp+8) %eax) +15153 (emit-subx-call-operand *(ebp+8) %edi) +15154 (write-buffered *(ebp+8) ")\n") +15155 $translate-mu-allocate-stmt:end: +15156 # . restore registers +15157 5f/pop-to-edi +15158 5e/pop-to-esi +15159 58/pop-to-eax +15160 # . epilogue +15161 89/<- %esp 5/r32/ebp +15162 5d/pop-to-ebp +15163 c3/return +15164 +15165 addr-handle-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +15166 # . prologue +15167 55/push-ebp +15168 89/<- %ebp 4/r32/esp +15169 # var t/eax: (addr type-tree) = s->value->type +15170 8b/-> *(ebp+8) 0/r32/eax +15171 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +15172 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +15173 # TODO: check eax != 0 +15174 # TODO: check !t->is-atom? +15175 # TODO: check t->left == addr +15176 # t = t->right +15177 $addr-handle-payload-size:skip-addr: +15178 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +15179 # TODO: check eax != 0 +15180 # TODO: check !t->is-atom? +15181 # TODO: check t->left == handle +15182 # t = t->right +15183 $addr-handle-payload-size:skip-handle: +15184 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +15185 # TODO: check eax != 0 +15186 # if !t->is-atom? t = t->left +15187 81 7/subop/compare *eax 0/imm32/false +15188 { +15189 75/jump-if-!= break/disp8 +15190 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +15191 } +15192 # TODO: check t->is-atom? +15193 # return size(t->value) +15194 (size-of-type-id *(eax+4)) # Type-tree-value => eax +15195 $addr-handle-payload-size:end: +15196 # . epilogue +15197 89/<- %esp 5/r32/ebp +15198 5d/pop-to-ebp +15199 c3/return +15200 +15201 translate-mu-populate-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +15202 # . prologue +15203 55/push-ebp +15204 89/<- %ebp 4/r32/esp +15205 # . save registers +15206 50/push-eax +15207 51/push-ecx +15208 56/push-esi +15209 57/push-edi +15210 # esi = stmt +15211 8b/-> *(ebp+0xc) 6/r32/esi +15212 # var target/edi: (addr stmt-var) = stmt->inouts[0] +15213 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +15214 89/<- %edi 0/r32/eax +15215 # var len/ecx: (addr stmt-var) = stmt->inouts[1] +15216 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax +15217 89/<- %ecx 0/r32/eax +15218 # +15219 (emit-indent *(ebp+8) *Curr-block-depth) +15220 (write-buffered *(ebp+8) "(allocate-array2 Heap ") +15221 (addr-handle-array-payload-size %edi *(ebp+0x10) *(ebp+0x14)) # => eax +15222 (write-int32-hex-buffered *(ebp+8) %eax) +15223 (emit-subx-call-operand *(ebp+8) %ecx) +15224 (emit-subx-call-operand *(ebp+8) %edi) +15225 (write-buffered *(ebp+8) ")\n") +15226 $translate-mu-populate-stmt:end: +15227 # . restore registers +15228 5f/pop-to-edi +15229 5e/pop-to-esi +15230 59/pop-to-ecx +15231 58/pop-to-eax +15232 # . epilogue +15233 89/<- %esp 5/r32/ebp +15234 5d/pop-to-ebp +15235 c3/return +15236 +15237 addr-handle-array-payload-size: # s: (addr stmt-var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +15238 # . prologue +15239 55/push-ebp +15240 89/<- %ebp 4/r32/esp +15241 # var t/eax: (addr type-tree) = s->value->type +15242 8b/-> *(ebp+8) 0/r32/eax +15243 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +15244 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +15245 # TODO: check eax != 0 +15246 # TODO: check !t->is-atom? +15247 # TODO: check t->left == addr +15248 # t = t->right +15249 $addr-handle-array-payload-size:skip-addr: +15250 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +15251 # TODO: check eax != 0 +15252 # TODO: check !t->is-atom? +15253 # TODO: check t->left == handle +15254 # t = t->right +15255 $addr-handle-array-payload-size:skip-handle: +15256 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +15257 # TODO: check eax != 0 +15258 # TODO: check !t->is-atom? +15259 # TODO: check t->left == array +15260 # t = t->right +15261 $addr-handle-array-payload-size:skip-array: +15262 (lookup *(eax+0xc) *(eax+0x10)) # Type-tree-right Type-tree-right => eax +15263 # TODO: check eax != 0 +15264 # if !t->is-atom? t = t->left +15265 81 7/subop/compare *eax 0/imm32/false +15266 { +15267 75/jump-if-!= break/disp8 +15268 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +15269 } +15270 $addr-handle-array-payload-size:compute-size: +15271 # TODO: check t->is-atom? +15272 # return size(t->value) +15273 (size-of-type-id-as-array-element *(eax+4)) # Type-tree-value => eax +15274 $addr-handle-array-payload-size:end: +15275 # . epilogue +15276 89/<- %esp 5/r32/ebp +15277 5d/pop-to-ebp +15278 c3/return +15279 +15280 power-of-2?: # n: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: boolean +15281 # precondition: n is positive +15282 # . prologue +15283 55/push-ebp +15284 89/<- %ebp 4/r32/esp +15285 # eax = n +15286 8b/-> *(ebp+8) 0/r32/eax +15287 # if (n < 0) abort +15288 3d/compare-eax-with 0/imm32 +15289 0f 8c/jump-if-< $power-of-2?:abort/disp32 +15290 # var tmp/eax: int = n-1 +15291 48/decrement-eax +15292 # var tmp2/eax: int = n & tmp +15293 23/and-> *(ebp+8) 0/r32/eax +15294 # return (tmp2 == 0) +15295 3d/compare-eax-and 0/imm32 +15296 0f 94/set-byte-if-= %al +15297 81 4/subop/and %eax 0xff/imm32 +15298 $power-of-2?:end: +15299 # . epilogue +15300 89/<- %esp 5/r32/ebp +15301 5d/pop-to-ebp +15302 c3/return +15303 +15304 $power-of-2?:abort: +15305 (write-buffered *(ebp+0xc) "power-of-2?: negative number\n") +15306 (flush *(ebp+0xc)) +15307 (stop *(ebp+0x10) 1) +15308 # never gets here +15309 +15310 num-shift-rights: # n: int -> result/eax: int +15311 # precondition: n is a positive power of 2 +15312 # . prologue +15313 55/push-ebp +15314 89/<- %ebp 4/r32/esp +15315 # . save registers +15316 51/push-ecx +15317 # var curr/ecx: int = n +15318 8b/-> *(ebp+8) 1/r32/ecx +15319 # result = 0 +15320 b8/copy-to-eax 0/imm32 +15321 { +15322 # if (curr <= 1) break +15323 81 7/subop/compare %ecx 1/imm32 +15324 7e/jump-if-<= break/disp8 +15325 40/increment-eax +15326 c1/shift 5/subop/arithmetic-right %ecx 1/imm8 +15327 eb/jump loop/disp8 +15328 } +15329 $num-shift-rights:end: +15330 # . restore registers +15331 59/pop-to-ecx +15332 # . epilogue +15333 89/<- %esp 5/r32/ebp +15334 5d/pop-to-ebp +15335 c3/return +15336 +15337 mu-get-offset: # stmt: (addr stmt) -> result/eax: int +15338 # . prologue +15339 55/push-ebp +15340 89/<- %ebp 4/r32/esp +15341 # var second-inout/eax: (addr stmt-var) = stmt->inouts->next +15342 8b/-> *(ebp+8) 0/r32/eax +15343 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +15344 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +15345 # var output-var/eax: (addr var) = second-inout->value +15346 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +15347 #? (write-buffered Stderr "mu-get-offset: ") +15348 #? (write-int32-hex-buffered Stderr %eax) +15349 #? (write-buffered Stderr " name: ") +15350 #? 50/push-eax +15351 #? (lookup *eax *(eax+4)) # Var-name +15352 #? (write-buffered Stderr %eax) +15353 #? 58/pop-to-eax +15354 #? (write-buffered Stderr Newline) +15355 #? (flush Stderr) +15356 # return output-var->stack-offset +15357 8b/-> *(eax+0x14) 0/r32/eax # Var-offset +15358 #? (write-buffered Stderr "=> ") +15359 #? (write-int32-hex-buffered Stderr %eax) +15360 #? (write-buffered Stderr Newline) +15361 #? (flush Stderr) +15362 $emit-get-offset:end: +15363 # . epilogue +15364 89/<- %esp 5/r32/ebp +15365 5d/pop-to-ebp +15366 c3/return +15367 +15368 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) +15369 # . prologue +15370 55/push-ebp +15371 89/<- %ebp 4/r32/esp +15372 # . save registers +15373 50/push-eax +15374 51/push-ecx +15375 56/push-esi +15376 # esi = block +15377 8b/-> *(ebp+0xc) 6/r32/esi +15378 # block->var->block-depth = *Curr-block-depth +15379 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax +15380 8b/-> *Curr-block-depth 1/r32/ecx +15381 89/<- *(eax+0x10) 1/r32/ecx # Var-block-depth +15382 # var stmts/eax: (addr list stmt) = lookup(block->statements) +15383 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax +15384 # +15385 { +15386 $emit-subx-block:check-empty: +15387 3d/compare-eax-and 0/imm32 +15388 0f 84/jump-if-= break/disp32 +15389 (emit-indent *(ebp+8) *Curr-block-depth) +15390 (write-buffered *(ebp+8) "{\n") +15391 # var v/ecx: (addr var) = lookup(block->var) +15392 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax +15393 89/<- %ecx 0/r32/eax +15394 # +15395 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +15396 (write-buffered *(ebp+8) %eax) +15397 (write-buffered *(ebp+8) ":loop:\n") +15398 ff 0/subop/increment *Curr-block-depth +15399 (push *(ebp+0x10) *(esi+0xc)) # Block-var +15400 (push *(ebp+0x10) *(esi+0x10)) # Block-var +15401 (push *(ebp+0x10) 0) # false +15402 # emit block->statements +15403 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax +15404 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +15405 (pop *(ebp+0x10)) # => eax +15406 (pop *(ebp+0x10)) # => eax +15407 (pop *(ebp+0x10)) # => eax +15408 ff 1/subop/decrement *Curr-block-depth +15409 (emit-indent *(ebp+8) *Curr-block-depth) +15410 (write-buffered *(ebp+8) "}\n") +15411 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +15412 (write-buffered *(ebp+8) %eax) +15413 (write-buffered *(ebp+8) ":break:\n") +15414 } +15415 $emit-subx-block:end: +15416 # . restore registers +15417 5e/pop-to-esi +15418 59/pop-to-ecx +15419 58/pop-to-eax +15420 # . epilogue +15421 89/<- %esp 5/r32/ebp +15422 5d/pop-to-ebp +15423 c3/return +15424 +15425 # Primitives supported +15426 # See mu_instructions for a summary of this linked-list data structure. +15427 # +15428 # For each operation, put variants with hard-coded registers before flexible ones. +15429 # +15430 # Unfortunately, our restrictions on addresses require that various fields in +15431 # primitives be handles, which complicates these definitions. +15432 # - we need to insert dummy fields all over the place for fake alloc-ids +15433 # - we can't use our syntax sugar of quoted literals for string fields +15434 # +15435 # Fake alloc-ids are needed because our type definitions up top require +15436 # handles but it's clearer to statically allocate these long-lived objects. +15437 # Fake alloc-ids are perfectly safe, but they can't be reclaimed. +15438 # +15439 # Every 'object' below starts with a fake alloc-id. It may also contain other +15440 # fake alloc-ids for various handle fields. +15441 # +15442 # I think of objects starting with a fake alloc-id as having type 'payload'. +15443 # It's not really intended to be created dynamically; for that use `allocate` +15444 # as usual. +15445 # +15446 # Idea for a notation to simplify such definitions: +15447 # _Primitive-increment-eax: # (payload primitive) +15448 # 0x11/alloc-id:fake:payload +15449 # 0x11 @(0x11 "increment") # name +15450 # 0 0 # inouts +15451 # 0x11 @(0x11/payload +15452 # 0x11 @(0x11/payload # List-value +15453 # 0 0 # Var-name +15454 # 0x11 @(0x11 # Var-type +15455 # 1/is-atom +15456 # 1/value 0/unused # Type-tree-left +15457 # 0 0 # Type-tree-right +15458 # ) +15459 # 1 # block-depth +15460 # 0 # stack-offset +15461 # 0x11 @(0x11 "eax") # Var-register +15462 # ) +15463 # 0 0) # List-next +15464 # ... +15465 # _Primitive-increment-ecx/imm32/next +15466 # ... +15467 # Awfully complex and non-obvious. But also clearly signals there's something +15468 # to learn here, so may be worth trying. +15469 # +15470 # '@' is just an initial thought. Punctuation used so far in Mu: () * % # / " +15471 # +15472 # For now we'll continue to just use comments and manually ensure they stay up +15473 # to date. +15474 == data +15475 Primitives: # (addr primitive) +15476 # - increment/decrement +15477 _Primitive-increment-eax: # (addr primitive) +15478 # var/eax <- increment => 40/increment-eax 15479 0x11/imm32/alloc-id:fake -15480 _string_8b_->/imm32/subx-name -15481 1/imm32/rm32-is-first-inout -15482 3/imm32/r32-is-first-output -15483 0/imm32/no-imm32 -15484 0/imm32/no-disp32 -15485 1/imm32/output-is-write-only -15486 0x11/imm32/alloc-id:fake -15487 _Primitive-copy-lit-to-reg/imm32/next -15488 _Primitive-copy-lit-to-reg: # (payload primitive) -15489 0x11/imm32/alloc-id:fake:payload -15490 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 -15491 0x11/imm32/alloc-id:fake -15492 _string-copy/imm32/name +15480 _string-increment/imm32/name +15481 0/imm32/no-inouts +15482 0/imm32/no-inouts +15483 0x11/imm32/alloc-id:fake +15484 Single-int-var-in-eax/imm32/outputs +15485 0x11/imm32/alloc-id:fake +15486 _string_40_increment_eax/imm32/subx-name +15487 0/imm32/no-rm32 +15488 0/imm32/no-r32 +15489 0/imm32/no-imm32 +15490 0/imm32/no-imm8 +15491 0/imm32/no-disp32 +15492 0/imm32/output-is-write-only 15493 0x11/imm32/alloc-id:fake -15494 Single-lit-var/imm32/inouts -15495 0x11/imm32/alloc-id:fake -15496 Single-int-var-in-some-register/imm32/outputs -15497 0x11/imm32/alloc-id:fake -15498 _string_c7_subop_copy/imm32/subx-name -15499 3/imm32/rm32-is-first-output -15500 0/imm32/no-r32 -15501 1/imm32/imm32-is-first-inout -15502 0/imm32/no-disp32 -15503 1/imm32/output-is-write-only +15494 _Primitive-increment-ecx/imm32/next +15495 _Primitive-increment-ecx: # (payload primitive) +15496 0x11/imm32/alloc-id:fake:payload +15497 # var/ecx <- increment => 41/increment-ecx +15498 0x11/imm32/alloc-id:fake +15499 _string-increment/imm32/name +15500 0/imm32/no-inouts +15501 0/imm32/no-inouts +15502 0x11/imm32/alloc-id:fake +15503 Single-int-var-in-ecx/imm32/outputs 15504 0x11/imm32/alloc-id:fake -15505 _Primitive-copy-lit-to-mem/imm32/next -15506 _Primitive-copy-lit-to-mem: # (payload primitive) -15507 0x11/imm32/alloc-id:fake:payload -15508 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 -15509 0x11/imm32/alloc-id:fake -15510 _string-copy-to/imm32/name -15511 0x11/imm32/alloc-id:fake -15512 Int-var-and-literal/imm32/inouts -15513 0/imm32/no-outputs -15514 0/imm32/no-outputs -15515 0x11/imm32/alloc-id:fake -15516 _string_c7_subop_copy/imm32/subx-name -15517 1/imm32/rm32-is-first-inout -15518 0/imm32/no-r32 -15519 2/imm32/imm32-is-first-inout -15520 0/imm32/no-disp32 -15521 1/imm32/output-is-write-only -15522 0x11/imm32/alloc-id:fake -15523 _Primitive-copy-byte-from-reg/imm32/next -15524 # - copy byte -15525 _Primitive-copy-byte-from-reg: -15526 0x11/imm32/alloc-id:fake:payload -15527 # var/reg <- copy-byte var2/reg2 => 8a/byte-> %var2 var/r32 -15528 0x11/imm32/alloc-id:fake -15529 _string-copy-byte/imm32/name -15530 0x11/imm32/alloc-id:fake -15531 Single-byte-var-in-some-register/imm32/inouts -15532 0x11/imm32/alloc-id:fake -15533 Single-byte-var-in-some-register/imm32/outputs -15534 0x11/imm32/alloc-id:fake -15535 _string_8a_copy_byte/imm32/subx-name -15536 1/imm32/rm32-is-first-inout -15537 3/imm32/r32-is-first-output -15538 0/imm32/no-imm32 -15539 0/imm32/no-disp32 -15540 1/imm32/output-is-write-only -15541 0x11/imm32/alloc-id:fake -15542 _Primitive-copy-byte-from-mem/imm32/next -15543 _Primitive-copy-byte-from-mem: -15544 0x11/imm32/alloc-id:fake:payload -15545 # var/reg <- copy-byte *var2/reg2 => 8a/byte-> *var2 var/r32 -15546 0x11/imm32/alloc-id:fake -15547 _string-copy-byte/imm32/name -15548 0x11/imm32/alloc-id:fake -15549 Single-byte-var-in-mem/imm32/inouts +15505 _string_41_increment_ecx/imm32/subx-name +15506 0/imm32/no-rm32 +15507 0/imm32/no-r32 +15508 0/imm32/no-imm32 +15509 0/imm32/no-imm8 +15510 0/imm32/no-disp32 +15511 0/imm32/output-is-write-only +15512 0x11/imm32/alloc-id:fake +15513 _Primitive-increment-edx/imm32/next +15514 _Primitive-increment-edx: # (payload primitive) +15515 0x11/imm32/alloc-id:fake:payload +15516 # var/edx <- increment => 42/increment-edx +15517 0x11/imm32/alloc-id:fake +15518 _string-increment/imm32/name +15519 0/imm32/no-inouts +15520 0/imm32/no-inouts +15521 0x11/imm32/alloc-id:fake +15522 Single-int-var-in-edx/imm32/outputs +15523 0x11/imm32/alloc-id:fake +15524 _string_42_increment_edx/imm32/subx-name +15525 0/imm32/no-rm32 +15526 0/imm32/no-r32 +15527 0/imm32/no-imm32 +15528 0/imm32/no-imm8 +15529 0/imm32/no-disp32 +15530 0/imm32/output-is-write-only +15531 0x11/imm32/alloc-id:fake +15532 _Primitive-increment-ebx/imm32/next +15533 _Primitive-increment-ebx: # (payload primitive) +15534 0x11/imm32/alloc-id:fake:payload +15535 # var/ebx <- increment => 43/increment-ebx +15536 0x11/imm32/alloc-id:fake +15537 _string-increment/imm32/name +15538 0/imm32/no-inouts +15539 0/imm32/no-inouts +15540 0x11/imm32/alloc-id:fake +15541 Single-int-var-in-ebx/imm32/outputs +15542 0x11/imm32/alloc-id:fake +15543 _string_43_increment_ebx/imm32/subx-name +15544 0/imm32/no-rm32 +15545 0/imm32/no-r32 +15546 0/imm32/no-imm32 +15547 0/imm32/no-imm8 +15548 0/imm32/no-disp32 +15549 0/imm32/output-is-write-only 15550 0x11/imm32/alloc-id:fake -15551 Single-byte-var-in-some-register/imm32/outputs -15552 0x11/imm32/alloc-id:fake -15553 _string_8a_copy_byte/imm32/subx-name -15554 1/imm32/rm32-is-first-inout -15555 3/imm32/r32-is-first-output -15556 0/imm32/no-imm32 -15557 0/imm32/no-disp32 -15558 1/imm32/output-is-write-only +15551 _Primitive-increment-esi/imm32/next +15552 _Primitive-increment-esi: # (payload primitive) +15553 0x11/imm32/alloc-id:fake:payload +15554 # var/esi <- increment => 46/increment-esi +15555 0x11/imm32/alloc-id:fake +15556 _string-increment/imm32/name +15557 0/imm32/no-inouts +15558 0/imm32/no-inouts 15559 0x11/imm32/alloc-id:fake -15560 _Primitive-copy-byte-to-mem/imm32/next -15561 _Primitive-copy-byte-to-mem: -15562 0x11/imm32/alloc-id:fake:payload -15563 # copy-byte-to *var1/reg1, var2/reg2 => 88/byte<- *reg1 reg2/r32 -15564 0x11/imm32/alloc-id:fake -15565 _string-copy-byte-to/imm32/name -15566 0x11/imm32/alloc-id:fake -15567 Two-args-byte-stack-byte-reg/imm32/inouts -15568 0/imm32/no-outputs -15569 0/imm32/no-outputs -15570 0x11/imm32/alloc-id:fake -15571 _string_88_copy_byte/imm32/subx-name -15572 1/imm32/rm32-is-first-inout -15573 2/imm32/r32-is-second-inout -15574 0/imm32/no-imm32 -15575 0/imm32/no-disp32 -15576 0/imm32/output-is-write-only -15577 0x11/imm32/alloc-id:fake -15578 _Primitive-address/imm32/next -15579 # - address -15580 _Primitive-address: # (payload primitive) -15581 0x11/imm32/alloc-id:fake:payload -15582 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32 -15583 0x11/imm32/alloc-id:fake -15584 _string-address/imm32/name -15585 0x11/imm32/alloc-id:fake -15586 Single-int-var-in-mem/imm32/inouts -15587 0x11/imm32/alloc-id:fake -15588 Single-addr-var-in-some-register/imm32/outputs -15589 0x11/imm32/alloc-id:fake -15590 _string_8d_copy_address/imm32/subx-name -15591 1/imm32/rm32-is-first-inout -15592 3/imm32/r32-is-first-output -15593 0/imm32/no-imm32 -15594 0/imm32/no-disp32 -15595 1/imm32/output-is-write-only -15596 0x11/imm32/alloc-id:fake -15597 _Primitive-compare-reg-with-reg/imm32/next -15598 # - compare -15599 _Primitive-compare-reg-with-reg: # (payload primitive) -15600 0x11/imm32/alloc-id:fake:payload -15601 # compare var1/reg1 var2/reg2 => 39/compare var1/rm32 var2/r32 -15602 0x11/imm32/alloc-id:fake -15603 _string-compare/imm32/name -15604 0x11/imm32/alloc-id:fake -15605 Two-int-args-in-regs/imm32/inouts -15606 0/imm32/no-outputs -15607 0/imm32/no-outputs -15608 0x11/imm32/alloc-id:fake -15609 _string_39_compare->/imm32/subx-name -15610 1/imm32/rm32-is-first-inout -15611 2/imm32/r32-is-second-inout -15612 0/imm32/no-imm32 -15613 0/imm32/no-disp32 -15614 0/imm32/output-is-write-only -15615 0x11/imm32/alloc-id:fake -15616 _Primitive-compare-mem-with-reg/imm32/next -15617 _Primitive-compare-mem-with-reg: # (payload primitive) -15618 0x11/imm32/alloc-id:fake:payload -15619 # compare var1 var2/reg => 39/compare var1/rm32 var2/r32 -15620 0x11/imm32/alloc-id:fake -15621 _string-compare/imm32/name -15622 0x11/imm32/alloc-id:fake -15623 Two-args-int-stack-int-reg/imm32/inouts -15624 0/imm32/no-outputs -15625 0/imm32/no-outputs +15560 Single-int-var-in-esi/imm32/outputs +15561 0x11/imm32/alloc-id:fake +15562 _string_46_increment_esi/imm32/subx-name +15563 0/imm32/no-rm32 +15564 0/imm32/no-r32 +15565 0/imm32/no-imm32 +15566 0/imm32/no-imm8 +15567 0/imm32/no-disp32 +15568 0/imm32/output-is-write-only +15569 0x11/imm32/alloc-id:fake +15570 _Primitive-increment-edi/imm32/next +15571 _Primitive-increment-edi: # (payload primitive) +15572 0x11/imm32/alloc-id:fake:payload +15573 # var/edi <- increment => 47/increment-edi +15574 0x11/imm32/alloc-id:fake +15575 _string-increment/imm32/name +15576 0/imm32/no-inouts +15577 0/imm32/no-inouts +15578 0x11/imm32/alloc-id:fake +15579 Single-int-var-in-edi/imm32/outputs +15580 0x11/imm32/alloc-id:fake +15581 _string_47_increment_edi/imm32/subx-name +15582 0/imm32/no-rm32 +15583 0/imm32/no-r32 +15584 0/imm32/no-imm32 +15585 0/imm32/no-imm8 +15586 0/imm32/no-disp32 +15587 0/imm32/output-is-write-only +15588 0x11/imm32/alloc-id:fake +15589 _Primitive-decrement-eax/imm32/next +15590 _Primitive-decrement-eax: # (payload primitive) +15591 0x11/imm32/alloc-id:fake:payload +15592 # var/eax <- decrement => 48/decrement-eax +15593 0x11/imm32/alloc-id:fake +15594 _string-decrement/imm32/name +15595 0/imm32/no-inouts +15596 0/imm32/no-inouts +15597 0x11/imm32/alloc-id:fake +15598 Single-int-var-in-eax/imm32/outputs +15599 0x11/imm32/alloc-id:fake +15600 _string_48_decrement_eax/imm32/subx-name +15601 0/imm32/no-rm32 +15602 0/imm32/no-r32 +15603 0/imm32/no-imm32 +15604 0/imm32/no-imm8 +15605 0/imm32/no-disp32 +15606 0/imm32/output-is-write-only +15607 0x11/imm32/alloc-id:fake +15608 _Primitive-decrement-ecx/imm32/next +15609 _Primitive-decrement-ecx: # (payload primitive) +15610 0x11/imm32/alloc-id:fake:payload +15611 # var/ecx <- decrement => 49/decrement-ecx +15612 0x11/imm32/alloc-id:fake +15613 _string-decrement/imm32/name +15614 0/imm32/no-inouts +15615 0/imm32/no-inouts +15616 0x11/imm32/alloc-id:fake +15617 Single-int-var-in-ecx/imm32/outputs +15618 0x11/imm32/alloc-id:fake +15619 _string_49_decrement_ecx/imm32/subx-name +15620 0/imm32/no-rm32 +15621 0/imm32/no-r32 +15622 0/imm32/no-imm32 +15623 0/imm32/no-imm8 +15624 0/imm32/no-disp32 +15625 0/imm32/output-is-write-only 15626 0x11/imm32/alloc-id:fake -15627 _string_39_compare->/imm32/subx-name -15628 1/imm32/rm32-is-first-inout -15629 2/imm32/r32-is-second-inout -15630 0/imm32/no-imm32 -15631 0/imm32/no-disp32 -15632 0/imm32/output-is-write-only -15633 0x11/imm32/alloc-id:fake -15634 _Primitive-compare-reg-with-mem/imm32/next -15635 _Primitive-compare-reg-with-mem: # (payload primitive) -15636 0x11/imm32/alloc-id:fake:payload -15637 # compare var1/reg var2 => 3b/compare<- var2/rm32 var1/r32 -15638 0x11/imm32/alloc-id:fake -15639 _string-compare/imm32/name -15640 0x11/imm32/alloc-id:fake -15641 Two-args-int-reg-int-stack/imm32/inouts -15642 0/imm32/no-outputs -15643 0/imm32/no-outputs -15644 0x11/imm32/alloc-id:fake -15645 _string_3b_compare<-/imm32/subx-name -15646 2/imm32/rm32-is-second-inout -15647 1/imm32/r32-is-first-inout -15648 0/imm32/no-imm32 -15649 0/imm32/no-disp32 -15650 0/imm32/output-is-write-only -15651 0x11/imm32/alloc-id:fake -15652 _Primitive-compare-eax-with-literal/imm32/next -15653 _Primitive-compare-eax-with-literal: # (payload primitive) -15654 0x11/imm32/alloc-id:fake:payload -15655 # compare var1/eax n => 3d/compare-eax-with n/imm32 +15627 _Primitive-decrement-edx/imm32/next +15628 _Primitive-decrement-edx: # (payload primitive) +15629 0x11/imm32/alloc-id:fake:payload +15630 # var/edx <- decrement => 4a/decrement-edx +15631 0x11/imm32/alloc-id:fake +15632 _string-decrement/imm32/name +15633 0/imm32/no-inouts +15634 0/imm32/no-inouts +15635 0x11/imm32/alloc-id:fake +15636 Single-int-var-in-edx/imm32/outputs +15637 0x11/imm32/alloc-id:fake +15638 _string_4a_decrement_edx/imm32/subx-name +15639 0/imm32/no-rm32 +15640 0/imm32/no-r32 +15641 0/imm32/no-imm32 +15642 0/imm32/no-imm8 +15643 0/imm32/no-disp32 +15644 0/imm32/output-is-write-only +15645 0x11/imm32/alloc-id:fake +15646 _Primitive-decrement-ebx/imm32/next +15647 _Primitive-decrement-ebx: # (payload primitive) +15648 0x11/imm32/alloc-id:fake:payload +15649 # var/ebx <- decrement => 4b/decrement-ebx +15650 0x11/imm32/alloc-id:fake +15651 _string-decrement/imm32/name +15652 0/imm32/no-inouts +15653 0/imm32/no-inouts +15654 0x11/imm32/alloc-id:fake +15655 Single-int-var-in-ebx/imm32/outputs 15656 0x11/imm32/alloc-id:fake -15657 _string-compare/imm32/name -15658 0x11/imm32/alloc-id:fake -15659 Two-args-int-eax-int-literal/imm32/inouts -15660 0/imm32/no-outputs -15661 0/imm32/no-outputs -15662 0x11/imm32/alloc-id:fake -15663 _string_3d_compare_eax_with/imm32/subx-name -15664 0/imm32/no-rm32 -15665 0/imm32/no-r32 -15666 2/imm32/imm32-is-second-inout -15667 0/imm32/no-disp32 -15668 0/imm32/output-is-write-only +15657 _string_4b_decrement_ebx/imm32/subx-name +15658 0/imm32/no-rm32 +15659 0/imm32/no-r32 +15660 0/imm32/no-imm32 +15661 0/imm32/no-imm8 +15662 0/imm32/no-disp32 +15663 0/imm32/output-is-write-only +15664 0x11/imm32/alloc-id:fake +15665 _Primitive-decrement-esi/imm32/next +15666 _Primitive-decrement-esi: # (payload primitive) +15667 0x11/imm32/alloc-id:fake:payload +15668 # var/esi <- decrement => 4e/decrement-esi 15669 0x11/imm32/alloc-id:fake -15670 _Primitive-compare-reg-with-literal/imm32/next -15671 _Primitive-compare-reg-with-literal: # (payload primitive) -15672 0x11/imm32/alloc-id:fake:payload -15673 # compare var1/reg n => 81 7/subop/compare %reg n/imm32 -15674 0x11/imm32/alloc-id:fake -15675 _string-compare/imm32/name -15676 0x11/imm32/alloc-id:fake -15677 Int-var-in-register-and-literal/imm32/inouts -15678 0/imm32/no-outputs -15679 0/imm32/no-outputs -15680 0x11/imm32/alloc-id:fake -15681 _string_81_subop_compare/imm32/subx-name -15682 1/imm32/rm32-is-first-inout -15683 0/imm32/no-r32 -15684 2/imm32/imm32-is-second-inout -15685 0/imm32/no-disp32 -15686 0/imm32/output-is-write-only -15687 0x11/imm32/alloc-id:fake -15688 _Primitive-compare-mem-with-literal/imm32/next -15689 _Primitive-compare-mem-with-literal: # (payload primitive) -15690 0x11/imm32/alloc-id:fake:payload -15691 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32 +15670 _string-decrement/imm32/name +15671 0/imm32/no-inouts +15672 0/imm32/no-inouts +15673 0x11/imm32/alloc-id:fake +15674 Single-int-var-in-esi/imm32/outputs +15675 0x11/imm32/alloc-id:fake +15676 _string_4e_decrement_esi/imm32/subx-name +15677 0/imm32/no-rm32 +15678 0/imm32/no-r32 +15679 0/imm32/no-imm32 +15680 0/imm32/no-imm8 +15681 0/imm32/no-disp32 +15682 0/imm32/output-is-write-only +15683 0x11/imm32/alloc-id:fake +15684 _Primitive-decrement-edi/imm32/next +15685 _Primitive-decrement-edi: # (payload primitive) +15686 0x11/imm32/alloc-id:fake:payload +15687 # var/edi <- decrement => 4f/decrement-edi +15688 0x11/imm32/alloc-id:fake +15689 _string-decrement/imm32/name +15690 0/imm32/no-inouts +15691 0/imm32/no-inouts 15692 0x11/imm32/alloc-id:fake -15693 _string-compare/imm32/name +15693 Single-int-var-in-edi/imm32/outputs 15694 0x11/imm32/alloc-id:fake -15695 Int-var-and-literal/imm32/inouts -15696 0/imm32/no-outputs -15697 0/imm32/no-outputs -15698 0x11/imm32/alloc-id:fake -15699 _string_81_subop_compare/imm32/subx-name -15700 1/imm32/rm32-is-first-inout -15701 0/imm32/no-r32 -15702 2/imm32/imm32-is-second-inout -15703 0/imm32/no-disp32 -15704 0/imm32/output-is-write-only -15705 0x11/imm32/alloc-id:fake -15706 _Primitive-multiply-reg-by-reg/imm32/next -15707 # - multiply -15708 _Primitive-multiply-reg-by-reg: # (payload primitive) -15709 0x11/imm32/alloc-id:fake:payload -15710 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 -15711 0x11/imm32/alloc-id:fake -15712 _string-multiply/imm32/name +15695 _string_4f_decrement_edi/imm32/subx-name +15696 0/imm32/no-rm32 +15697 0/imm32/no-r32 +15698 0/imm32/no-imm32 +15699 0/imm32/no-imm8 +15700 0/imm32/no-disp32 +15701 0/imm32/output-is-write-only +15702 0x11/imm32/alloc-id:fake +15703 _Primitive-increment-mem/imm32/next +15704 _Primitive-increment-mem: # (payload primitive) +15705 0x11/imm32/alloc-id:fake:payload +15706 # increment var => ff 0/subop/increment *(ebp+__) +15707 0x11/imm32/alloc-id:fake +15708 _string-increment/imm32/name +15709 0x11/imm32/alloc-id:fake +15710 Single-int-var-in-mem/imm32/inouts +15711 0/imm32/no-outputs +15712 0/imm32/no-outputs 15713 0x11/imm32/alloc-id:fake -15714 Single-int-var-in-some-register/imm32/inouts -15715 0x11/imm32/alloc-id:fake -15716 Single-int-var-in-some-register/imm32/outputs -15717 0x11/imm32/alloc-id:fake -15718 _string_0f_af_multiply/imm32/subx-name -15719 1/imm32/rm32-is-first-inout -15720 3/imm32/r32-is-first-output -15721 0/imm32/no-imm32 -15722 0/imm32/no-disp32 -15723 0/imm32/output-is-write-only -15724 0x11/imm32/alloc-id:fake -15725 _Primitive-multiply-reg-by-mem/imm32/next -15726 _Primitive-multiply-reg-by-mem: # (payload primitive) -15727 0x11/imm32/alloc-id:fake:payload -15728 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 -15729 0x11/imm32/alloc-id:fake -15730 _string-multiply/imm32/name -15731 0x11/imm32/alloc-id:fake -15732 Single-int-var-in-mem/imm32/inouts -15733 0x11/imm32/alloc-id:fake -15734 Single-int-var-in-some-register/imm32/outputs -15735 0x11/imm32/alloc-id:fake -15736 _string_0f_af_multiply/imm32/subx-name -15737 1/imm32/rm32-is-first-inout -15738 3/imm32/r32-is-first-output -15739 0/imm32/no-imm32 -15740 0/imm32/no-disp32 -15741 0/imm32/output-is-write-only -15742 0x11/imm32/alloc-id:fake -15743 _Primitive-break-if-addr</imm32/next -15744 # - branches -15745 _Primitive-break-if-addr<: # (payload primitive) -15746 0x11/imm32/alloc-id:fake:payload +15714 _string_ff_subop_increment/imm32/subx-name +15715 1/imm32/rm32-is-first-inout +15716 0/imm32/no-r32 +15717 0/imm32/no-imm32 +15718 0/imm32/no-imm8 +15719 0/imm32/no-disp32 +15720 0/imm32/output-is-write-only +15721 0x11/imm32/alloc-id:fake +15722 _Primitive-increment-reg/imm32/next +15723 _Primitive-increment-reg: # (payload primitive) +15724 0x11/imm32/alloc-id:fake:payload +15725 # var/reg <- increment => ff 0/subop/increment %__ +15726 0x11/imm32/alloc-id:fake +15727 _string-increment/imm32/name +15728 0/imm32/no-inouts +15729 0/imm32/no-inouts +15730 0x11/imm32/alloc-id:fake +15731 Single-int-var-in-some-register/imm32/outputs +15732 0x11/imm32/alloc-id:fake +15733 _string_ff_subop_increment/imm32/subx-name +15734 3/imm32/rm32-is-first-output +15735 0/imm32/no-r32 +15736 0/imm32/no-imm32 +15737 0/imm32/no-imm8 +15738 0/imm32/no-disp32 +15739 0/imm32/output-is-write-only +15740 0x11/imm32/alloc-id:fake +15741 _Primitive-decrement-mem/imm32/next +15742 _Primitive-decrement-mem: # (payload primitive) +15743 0x11/imm32/alloc-id:fake:payload +15744 # decrement var => ff 1/subop/decrement *(ebp+__) +15745 0x11/imm32/alloc-id:fake +15746 _string-decrement/imm32/name 15747 0x11/imm32/alloc-id:fake -15748 _string-break-if-addr</imm32/name -15749 0/imm32/no-inouts -15750 0/imm32/no-inouts -15751 0/imm32/no-outputs -15752 0/imm32/no-outputs -15753 0x11/imm32/alloc-id:fake -15754 _string_0f_82_jump_break/imm32/subx-name -15755 0/imm32/no-rm32 -15756 0/imm32/no-r32 -15757 0/imm32/no-imm32 -15758 0/imm32/no-disp32 -15759 0/imm32/no-output -15760 0x11/imm32/alloc-id:fake -15761 _Primitive-break-if-addr>=/imm32/next -15762 _Primitive-break-if-addr>=: # (payload primitive) -15763 0x11/imm32/alloc-id:fake:payload +15748 Single-int-var-in-mem/imm32/inouts +15749 0/imm32/no-outputs +15750 0/imm32/no-outputs +15751 0x11/imm32/alloc-id:fake +15752 _string_ff_subop_decrement/imm32/subx-name +15753 1/imm32/rm32-is-first-inout +15754 0/imm32/no-r32 +15755 0/imm32/no-imm32 +15756 0/imm32/no-imm8 +15757 0/imm32/no-disp32 +15758 0/imm32/output-is-write-only +15759 0x11/imm32/alloc-id:fake +15760 _Primitive-decrement-reg/imm32/next +15761 _Primitive-decrement-reg: # (payload primitive) +15762 0x11/imm32/alloc-id:fake:payload +15763 # var/reg <- decrement => ff 1/subop/decrement %__ 15764 0x11/imm32/alloc-id:fake -15765 _string-break-if-addr>=/imm32/name +15765 _string-decrement/imm32/name 15766 0/imm32/no-inouts 15767 0/imm32/no-inouts -15768 0/imm32/no-outputs -15769 0/imm32/no-outputs +15768 0x11/imm32/alloc-id:fake +15769 Single-int-var-in-some-register/imm32/outputs 15770 0x11/imm32/alloc-id:fake -15771 _string_0f_83_jump_break/imm32/subx-name -15772 0/imm32/no-rm32 +15771 _string_ff_subop_decrement/imm32/subx-name +15772 3/imm32/rm32-is-first-output 15773 0/imm32/no-r32 15774 0/imm32/no-imm32 -15775 0/imm32/no-disp32 -15776 0/imm32/no-output -15777 0x11/imm32/alloc-id:fake -15778 _Primitive-break-if-=/imm32/next -15779 _Primitive-break-if-=: # (payload primitive) -15780 0x11/imm32/alloc-id:fake:payload -15781 0x11/imm32/alloc-id:fake -15782 _string-break-if-=/imm32/name -15783 0/imm32/no-inouts -15784 0/imm32/no-inouts -15785 0/imm32/no-outputs -15786 0/imm32/no-outputs -15787 0x11/imm32/alloc-id:fake -15788 _string_0f_84_jump_break/imm32/subx-name -15789 0/imm32/no-rm32 -15790 0/imm32/no-r32 -15791 0/imm32/no-imm32 -15792 0/imm32/no-disp32 -15793 0/imm32/no-output -15794 0x11/imm32/alloc-id:fake -15795 _Primitive-break-if-!=/imm32/next -15796 _Primitive-break-if-!=: # (payload primitive) -15797 0x11/imm32/alloc-id:fake:payload +15775 0/imm32/no-imm8 +15776 0/imm32/no-disp32 +15777 0/imm32/output-is-write-only +15778 0x11/imm32/alloc-id:fake +15779 _Primitive-add-to-eax/imm32/next +15780 # - add +15781 _Primitive-add-to-eax: # (payload primitive) +15782 0x11/imm32/alloc-id:fake:payload +15783 # var/eax <- add lit => 05/add-to-eax lit/imm32 +15784 0x11/imm32/alloc-id:fake +15785 _string-add/imm32/name +15786 0x11/imm32/alloc-id:fake +15787 Single-lit-var/imm32/inouts +15788 0x11/imm32/alloc-id:fake +15789 Single-int-var-in-eax/imm32/outputs +15790 0x11/imm32/alloc-id:fake +15791 _string_05_add_to_eax/imm32/subx-name +15792 0/imm32/no-rm32 +15793 0/imm32/no-r32 +15794 1/imm32/imm32-is-first-inout +15795 0/imm32/no-imm8 +15796 0/imm32/no-disp32 +15797 0/imm32/output-is-write-only 15798 0x11/imm32/alloc-id:fake -15799 _string-break-if-!=/imm32/name -15800 0/imm32/no-inouts -15801 0/imm32/no-inouts -15802 0/imm32/no-outputs -15803 0/imm32/no-outputs -15804 0x11/imm32/alloc-id:fake -15805 _string_0f_85_jump_break/imm32/subx-name -15806 0/imm32/no-rm32 -15807 0/imm32/no-r32 -15808 0/imm32/no-imm32 -15809 0/imm32/no-disp32 -15810 0/imm32/no-output -15811 0x11/imm32/alloc-id:fake -15812 _Primitive-break-if-addr<=/imm32/next -15813 _Primitive-break-if-addr<=: # (payload primitive) -15814 0x11/imm32/alloc-id:fake:payload -15815 0x11/imm32/alloc-id:fake -15816 _string-break-if-addr<=/imm32/name -15817 0/imm32/no-inouts -15818 0/imm32/no-inouts -15819 0/imm32/no-outputs -15820 0/imm32/no-outputs -15821 0x11/imm32/alloc-id:fake -15822 _string_0f_86_jump_break/imm32/subx-name -15823 0/imm32/no-rm32 -15824 0/imm32/no-r32 -15825 0/imm32/no-imm32 -15826 0/imm32/no-disp32 -15827 0/imm32/no-output +15799 _Primitive-add-reg-to-reg/imm32/next +15800 _Primitive-add-reg-to-reg: # (payload primitive) +15801 0x11/imm32/alloc-id:fake:payload +15802 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 +15803 0x11/imm32/alloc-id:fake +15804 _string-add/imm32/name +15805 0x11/imm32/alloc-id:fake +15806 Single-int-var-in-some-register/imm32/inouts +15807 0x11/imm32/alloc-id:fake +15808 Single-int-var-in-some-register/imm32/outputs +15809 0x11/imm32/alloc-id:fake +15810 _string_01_add_to/imm32/subx-name +15811 3/imm32/rm32-is-first-output +15812 1/imm32/r32-is-first-inout +15813 0/imm32/no-imm32 +15814 0/imm32/no-imm8 +15815 0/imm32/no-disp32 +15816 0/imm32/output-is-write-only +15817 0x11/imm32/alloc-id:fake +15818 _Primitive-add-reg-to-mem/imm32/next +15819 _Primitive-add-reg-to-mem: # (payload primitive) +15820 0x11/imm32/alloc-id:fake:payload +15821 # add-to var1 var2/reg => 01/add-to var1 var2/r32 +15822 0x11/imm32/alloc-id:fake +15823 _string-add-to/imm32/name +15824 0x11/imm32/alloc-id:fake +15825 Two-args-int-stack-int-reg/imm32/inouts +15826 0/imm32/no-outputs +15827 0/imm32/no-outputs 15828 0x11/imm32/alloc-id:fake -15829 _Primitive-break-if-addr>/imm32/next -15830 _Primitive-break-if-addr>: # (payload primitive) -15831 0x11/imm32/alloc-id:fake:payload -15832 0x11/imm32/alloc-id:fake -15833 _string-break-if-addr>/imm32/name -15834 0/imm32/no-inouts -15835 0/imm32/no-inouts -15836 0/imm32/no-outputs -15837 0/imm32/no-outputs -15838 0x11/imm32/alloc-id:fake -15839 _string_0f_87_jump_break/imm32/subx-name -15840 0/imm32/no-rm32 -15841 0/imm32/no-r32 -15842 0/imm32/no-imm32 -15843 0/imm32/no-disp32 -15844 0/imm32/no-output +15829 _string_01_add_to/imm32/subx-name +15830 1/imm32/rm32-is-first-inout +15831 2/imm32/r32-is-second-inout +15832 0/imm32/no-imm32 +15833 0/imm32/no-imm8 +15834 0/imm32/no-disp32 +15835 0/imm32/output-is-write-only +15836 0x11/imm32/alloc-id:fake +15837 _Primitive-add-mem-to-reg/imm32/next +15838 _Primitive-add-mem-to-reg: # (payload primitive) +15839 0x11/imm32/alloc-id:fake:payload +15840 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 +15841 0x11/imm32/alloc-id:fake +15842 _string-add/imm32/name +15843 0x11/imm32/alloc-id:fake +15844 Single-int-var-in-mem/imm32/inouts 15845 0x11/imm32/alloc-id:fake -15846 _Primitive-break-if-</imm32/next -15847 _Primitive-break-if-<: # (payload primitive) -15848 0x11/imm32/alloc-id:fake:payload -15849 0x11/imm32/alloc-id:fake -15850 _string-break-if-</imm32/name -15851 0/imm32/no-inouts -15852 0/imm32/no-inouts -15853 0/imm32/no-outputs -15854 0/imm32/no-outputs +15846 Single-int-var-in-some-register/imm32/outputs +15847 0x11/imm32/alloc-id:fake +15848 _string_03_add/imm32/subx-name +15849 1/imm32/rm32-is-first-inout +15850 3/imm32/r32-is-first-output +15851 0/imm32/no-imm32 +15852 0/imm32/no-imm8 +15853 0/imm32/no-disp32 +15854 0/imm32/output-is-write-only 15855 0x11/imm32/alloc-id:fake -15856 _string_0f_8c_jump_break/imm32/subx-name -15857 0/imm32/no-rm32 -15858 0/imm32/no-r32 -15859 0/imm32/no-imm32 -15860 0/imm32/no-disp32 -15861 0/imm32/no-output +15856 _Primitive-add-lit-to-reg/imm32/next +15857 _Primitive-add-lit-to-reg: # (payload primitive) +15858 0x11/imm32/alloc-id:fake:payload +15859 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 +15860 0x11/imm32/alloc-id:fake +15861 _string-add/imm32/name 15862 0x11/imm32/alloc-id:fake -15863 _Primitive-break-if->=/imm32/next -15864 _Primitive-break-if->=: # (payload primitive) -15865 0x11/imm32/alloc-id:fake:payload +15863 Single-lit-var/imm32/inouts +15864 0x11/imm32/alloc-id:fake +15865 Single-int-var-in-some-register/imm32/outputs 15866 0x11/imm32/alloc-id:fake -15867 _string-break-if->=/imm32/name -15868 0/imm32/no-inouts -15869 0/imm32/no-inouts -15870 0/imm32/no-outputs -15871 0/imm32/no-outputs -15872 0x11/imm32/alloc-id:fake -15873 _string_0f_8d_jump_break/imm32/subx-name -15874 0/imm32/no-rm32 -15875 0/imm32/no-r32 -15876 0/imm32/no-imm32 -15877 0/imm32/no-disp32 -15878 0/imm32/no-output +15867 _string_81_subop_add/imm32/subx-name +15868 3/imm32/rm32-is-first-output +15869 0/imm32/no-r32 +15870 1/imm32/imm32-is-first-inout +15871 0/imm32/no-imm8 +15872 0/imm32/no-disp32 +15873 0/imm32/output-is-write-only +15874 0x11/imm32/alloc-id:fake +15875 _Primitive-add-lit-to-mem/imm32/next +15876 _Primitive-add-lit-to-mem: # (payload primitive) +15877 0x11/imm32/alloc-id:fake:payload +15878 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 15879 0x11/imm32/alloc-id:fake -15880 _Primitive-break-if-<=/imm32/next -15881 _Primitive-break-if-<=: # (payload primitive) -15882 0x11/imm32/alloc-id:fake:payload -15883 0x11/imm32/alloc-id:fake -15884 _string-break-if-<=/imm32/name -15885 0/imm32/no-inouts -15886 0/imm32/no-inouts -15887 0/imm32/no-outputs -15888 0/imm32/no-outputs -15889 0x11/imm32/alloc-id:fake -15890 _string_0f_8e_jump_break/imm32/subx-name -15891 0/imm32/no-rm32 -15892 0/imm32/no-r32 -15893 0/imm32/no-imm32 -15894 0/imm32/no-disp32 -15895 0/imm32/no-output -15896 0x11/imm32/alloc-id:fake -15897 _Primitive-break-if->/imm32/next -15898 _Primitive-break-if->: # (payload primitive) -15899 0x11/imm32/alloc-id:fake:payload -15900 0x11/imm32/alloc-id:fake -15901 _string-break-if->/imm32/name -15902 0/imm32/no-inouts -15903 0/imm32/no-inouts -15904 0/imm32/no-outputs -15905 0/imm32/no-outputs -15906 0x11/imm32/alloc-id:fake -15907 _string_0f_8f_jump_break/imm32/subx-name -15908 0/imm32/no-rm32 -15909 0/imm32/no-r32 -15910 0/imm32/no-imm32 +15880 _string-add-to/imm32/name +15881 0x11/imm32/alloc-id:fake +15882 Int-var-and-literal/imm32/inouts +15883 0/imm32/no-outputs +15884 0/imm32/no-outputs +15885 0x11/imm32/alloc-id:fake +15886 _string_81_subop_add/imm32/subx-name +15887 1/imm32/rm32-is-first-inout +15888 0/imm32/no-r32 +15889 2/imm32/imm32-is-second-inout +15890 0/imm32/no-imm8 +15891 0/imm32/no-disp32 +15892 0/imm32/output-is-write-only +15893 0x11/imm32/alloc-id:fake +15894 _Primitive-subtract-from-eax/imm32/next +15895 # - subtract +15896 _Primitive-subtract-from-eax: # (payload primitive) +15897 0x11/imm32/alloc-id:fake:payload +15898 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 +15899 0x11/imm32/alloc-id:fake +15900 _string-subtract/imm32/name +15901 0x11/imm32/alloc-id:fake +15902 Single-lit-var/imm32/inouts +15903 0x11/imm32/alloc-id:fake +15904 Single-int-var-in-eax/imm32/outputs +15905 0x11/imm32/alloc-id:fake +15906 _string_2d_subtract_from_eax/imm32/subx-name +15907 0/imm32/no-rm32 +15908 0/imm32/no-r32 +15909 1/imm32/imm32-is-first-inout +15910 0/imm32/no-imm8 15911 0/imm32/no-disp32 -15912 0/imm32/no-output +15912 0/imm32/output-is-write-only 15913 0x11/imm32/alloc-id:fake -15914 _Primitive-break/imm32/next -15915 _Primitive-break: # (payload primitive) +15914 _Primitive-subtract-reg-from-reg/imm32/next +15915 _Primitive-subtract-reg-from-reg: # (payload primitive) 15916 0x11/imm32/alloc-id:fake:payload -15917 0x11/imm32/alloc-id:fake -15918 _string-break/imm32/name -15919 0/imm32/no-inouts -15920 0/imm32/no-inouts -15921 0/imm32/no-outputs -15922 0/imm32/no-outputs -15923 0x11/imm32/alloc-id:fake -15924 _string_e9_jump_break/imm32/subx-name -15925 0/imm32/no-rm32 -15926 0/imm32/no-r32 -15927 0/imm32/no-imm32 -15928 0/imm32/no-disp32 -15929 0/imm32/no-output -15930 0x11/imm32/alloc-id:fake -15931 _Primitive-loop-if-addr</imm32/next -15932 _Primitive-loop-if-addr<: # (payload primitive) -15933 0x11/imm32/alloc-id:fake:payload -15934 0x11/imm32/alloc-id:fake -15935 _string-loop-if-addr</imm32/name -15936 0/imm32/no-inouts -15937 0/imm32/no-inouts -15938 0/imm32/no-outputs -15939 0/imm32/no-outputs -15940 0x11/imm32/alloc-id:fake -15941 _string_0f_82_jump_loop/imm32/subx-name -15942 0/imm32/no-rm32 -15943 0/imm32/no-r32 -15944 0/imm32/no-imm32 -15945 0/imm32/no-disp32 -15946 0/imm32/no-output -15947 0x11/imm32/alloc-id:fake -15948 _Primitive-loop-if-addr>=/imm32/next -15949 _Primitive-loop-if-addr>=: # (payload primitive) -15950 0x11/imm32/alloc-id:fake:payload +15917 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 +15918 0x11/imm32/alloc-id:fake +15919 _string-subtract/imm32/name +15920 0x11/imm32/alloc-id:fake +15921 Single-int-var-in-some-register/imm32/inouts +15922 0x11/imm32/alloc-id:fake +15923 Single-int-var-in-some-register/imm32/outputs +15924 0x11/imm32/alloc-id:fake +15925 _string_29_subtract_from/imm32/subx-name +15926 3/imm32/rm32-is-first-output +15927 1/imm32/r32-is-first-inout +15928 0/imm32/no-imm32 +15929 0/imm32/no-imm8 +15930 0/imm32/no-disp32 +15931 0/imm32/output-is-write-only +15932 0x11/imm32/alloc-id:fake +15933 _Primitive-subtract-reg-from-mem/imm32/next +15934 _Primitive-subtract-reg-from-mem: # (payload primitive) +15935 0x11/imm32/alloc-id:fake:payload +15936 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 +15937 0x11/imm32/alloc-id:fake +15938 _string-subtract-from/imm32/name +15939 0x11/imm32/alloc-id:fake +15940 Two-args-int-stack-int-reg/imm32/inouts +15941 0/imm32/no-outputs +15942 0/imm32/no-outputs +15943 0x11/imm32/alloc-id:fake +15944 _string_29_subtract_from/imm32/subx-name +15945 1/imm32/rm32-is-first-inout +15946 2/imm32/r32-is-second-inout +15947 0/imm32/no-imm32 +15948 0/imm32/no-imm8 +15949 0/imm32/no-disp32 +15950 0/imm32/output-is-write-only 15951 0x11/imm32/alloc-id:fake -15952 _string-loop-if-addr>=/imm32/name -15953 0/imm32/no-inouts -15954 0/imm32/no-inouts -15955 0/imm32/no-outputs -15956 0/imm32/no-outputs -15957 0x11/imm32/alloc-id:fake -15958 _string_0f_83_jump_loop/imm32/subx-name -15959 0/imm32/no-rm32 -15960 0/imm32/no-r32 -15961 0/imm32/no-imm32 -15962 0/imm32/no-disp32 -15963 0/imm32/no-output -15964 0x11/imm32/alloc-id:fake -15965 _Primitive-loop-if-=/imm32/next -15966 _Primitive-loop-if-=: # (payload primitive) -15967 0x11/imm32/alloc-id:fake:payload -15968 0x11/imm32/alloc-id:fake -15969 _string-loop-if-=/imm32/name -15970 0/imm32/no-inouts -15971 0/imm32/no-inouts -15972 0/imm32/no-outputs -15973 0/imm32/no-outputs -15974 0x11/imm32/alloc-id:fake -15975 _string_0f_84_jump_loop/imm32/subx-name -15976 0/imm32/no-rm32 -15977 0/imm32/no-r32 -15978 0/imm32/no-imm32 -15979 0/imm32/no-disp32 -15980 0/imm32/no-output +15952 _Primitive-subtract-mem-from-reg/imm32/next +15953 _Primitive-subtract-mem-from-reg: # (payload primitive) +15954 0x11/imm32/alloc-id:fake:payload +15955 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 +15956 0x11/imm32/alloc-id:fake +15957 _string-subtract/imm32/name +15958 0x11/imm32/alloc-id:fake +15959 Single-int-var-in-mem/imm32/inouts +15960 0x11/imm32/alloc-id:fake +15961 Single-int-var-in-some-register/imm32/outputs +15962 0x11/imm32/alloc-id:fake +15963 _string_2b_subtract/imm32/subx-name +15964 1/imm32/rm32-is-first-inout +15965 3/imm32/r32-is-first-output +15966 0/imm32/no-imm32 +15967 0/imm32/no-imm8 +15968 0/imm32/no-disp32 +15969 0/imm32/output-is-write-only +15970 0x11/imm32/alloc-id:fake +15971 _Primitive-subtract-lit-from-reg/imm32/next +15972 _Primitive-subtract-lit-from-reg: # (payload primitive) +15973 0x11/imm32/alloc-id:fake:payload +15974 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 +15975 0x11/imm32/alloc-id:fake +15976 _string-subtract/imm32/name +15977 0x11/imm32/alloc-id:fake +15978 Single-lit-var/imm32/inouts +15979 0x11/imm32/alloc-id:fake +15980 Single-int-var-in-some-register/imm32/outputs 15981 0x11/imm32/alloc-id:fake -15982 _Primitive-loop-if-!=/imm32/next -15983 _Primitive-loop-if-!=: # (payload primitive) -15984 0x11/imm32/alloc-id:fake:payload -15985 0x11/imm32/alloc-id:fake -15986 _string-loop-if-!=/imm32/name -15987 0/imm32/no-inouts -15988 0/imm32/no-inouts -15989 0/imm32/no-outputs -15990 0/imm32/no-outputs -15991 0x11/imm32/alloc-id:fake -15992 _string_0f_85_jump_loop/imm32/subx-name -15993 0/imm32/no-rm32 -15994 0/imm32/no-r32 -15995 0/imm32/no-imm32 -15996 0/imm32/no-disp32 -15997 0/imm32/no-output -15998 0x11/imm32/alloc-id:fake -15999 _Primitive-loop-if-addr<=/imm32/next -16000 _Primitive-loop-if-addr<=: # (payload primitive) -16001 0x11/imm32/alloc-id:fake:payload -16002 0x11/imm32/alloc-id:fake -16003 _string-loop-if-addr<=/imm32/name -16004 0/imm32/no-inouts -16005 0/imm32/no-inouts -16006 0/imm32/no-outputs -16007 0/imm32/no-outputs +15982 _string_81_subop_subtract/imm32/subx-name +15983 3/imm32/rm32-is-first-output +15984 0/imm32/no-r32 +15985 1/imm32/imm32-is-first-inout +15986 0/imm32/no-imm8 +15987 0/imm32/no-disp32 +15988 0/imm32/output-is-write-only +15989 0x11/imm32/alloc-id:fake +15990 _Primitive-subtract-lit-from-mem/imm32/next +15991 _Primitive-subtract-lit-from-mem: # (payload primitive) +15992 0x11/imm32/alloc-id:fake:payload +15993 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 +15994 0x11/imm32/alloc-id:fake +15995 _string-subtract-from/imm32/name +15996 0x11/imm32/alloc-id:fake +15997 Int-var-and-literal/imm32/inouts +15998 0/imm32/no-outputs +15999 0/imm32/no-outputs +16000 0x11/imm32/alloc-id:fake +16001 _string_81_subop_subtract/imm32/subx-name +16002 1/imm32/rm32-is-first-inout +16003 0/imm32/no-r32 +16004 2/imm32/imm32-is-second-inout +16005 0/imm32/no-imm8 +16006 0/imm32/no-disp32 +16007 0/imm32/output-is-write-only 16008 0x11/imm32/alloc-id:fake -16009 _string_0f_86_jump_loop/imm32/subx-name -16010 0/imm32/no-rm32 -16011 0/imm32/no-r32 -16012 0/imm32/no-imm32 -16013 0/imm32/no-disp32 -16014 0/imm32/no-output -16015 0x11/imm32/alloc-id:fake -16016 _Primitive-loop-if-addr>/imm32/next -16017 _Primitive-loop-if-addr>: # (payload primitive) -16018 0x11/imm32/alloc-id:fake:payload -16019 0x11/imm32/alloc-id:fake -16020 _string-loop-if-addr>/imm32/name -16021 0/imm32/no-inouts -16022 0/imm32/no-inouts -16023 0/imm32/no-outputs -16024 0/imm32/no-outputs -16025 0x11/imm32/alloc-id:fake -16026 _string_0f_87_jump_loop/imm32/subx-name -16027 0/imm32/no-rm32 -16028 0/imm32/no-r32 -16029 0/imm32/no-imm32 -16030 0/imm32/no-disp32 -16031 0/imm32/no-output -16032 0x11/imm32/alloc-id:fake -16033 _Primitive-loop-if-</imm32/next -16034 _Primitive-loop-if-<: # (payload primitive) -16035 0x11/imm32/alloc-id:fake:payload -16036 0x11/imm32/alloc-id:fake -16037 _string-loop-if-</imm32/name -16038 0/imm32/no-inouts -16039 0/imm32/no-inouts -16040 0/imm32/no-outputs -16041 0/imm32/no-outputs -16042 0x11/imm32/alloc-id:fake -16043 _string_0f_8c_jump_loop/imm32/subx-name -16044 0/imm32/no-rm32 -16045 0/imm32/no-r32 -16046 0/imm32/no-imm32 -16047 0/imm32/no-disp32 -16048 0/imm32/no-output -16049 0x11/imm32/alloc-id:fake -16050 _Primitive-loop-if->=/imm32/next -16051 _Primitive-loop-if->=: # (payload primitive) -16052 0x11/imm32/alloc-id:fake:payload -16053 0x11/imm32/alloc-id:fake -16054 _string-loop-if->=/imm32/name -16055 0/imm32/no-inouts -16056 0/imm32/no-inouts +16009 _Primitive-and-with-eax/imm32/next +16010 # - and +16011 _Primitive-and-with-eax: # (payload primitive) +16012 0x11/imm32/alloc-id:fake:payload +16013 # var/eax <- and lit => 25/and-with-eax lit/imm32 +16014 0x11/imm32/alloc-id:fake +16015 _string-and/imm32/name +16016 0x11/imm32/alloc-id:fake +16017 Single-lit-var/imm32/inouts +16018 0x11/imm32/alloc-id:fake +16019 Single-int-var-in-eax/imm32/outputs +16020 0x11/imm32/alloc-id:fake +16021 _string_25_and_with_eax/imm32/subx-name +16022 0/imm32/no-rm32 +16023 0/imm32/no-r32 +16024 1/imm32/imm32-is-first-inout +16025 0/imm32/no-imm8 +16026 0/imm32/no-disp32 +16027 0/imm32/output-is-write-only +16028 0x11/imm32/alloc-id:fake +16029 _Primitive-and-reg-with-reg/imm32/next +16030 _Primitive-and-reg-with-reg: # (payload primitive) +16031 0x11/imm32/alloc-id:fake:payload +16032 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 +16033 0x11/imm32/alloc-id:fake +16034 _string-and/imm32/name +16035 0x11/imm32/alloc-id:fake +16036 Single-int-var-in-some-register/imm32/inouts +16037 0x11/imm32/alloc-id:fake +16038 Single-int-var-in-some-register/imm32/outputs +16039 0x11/imm32/alloc-id:fake +16040 _string_21_and_with/imm32/subx-name +16041 3/imm32/rm32-is-first-output +16042 1/imm32/r32-is-first-inout +16043 0/imm32/no-imm32 +16044 0/imm32/no-imm8 +16045 0/imm32/no-disp32 +16046 0/imm32/output-is-write-only +16047 0x11/imm32/alloc-id:fake +16048 _Primitive-and-reg-with-mem/imm32/next +16049 _Primitive-and-reg-with-mem: # (payload primitive) +16050 0x11/imm32/alloc-id:fake:payload +16051 # and-with var1 var2/reg => 21/and-with var1 var2/r32 +16052 0x11/imm32/alloc-id:fake +16053 _string-and-with/imm32/name +16054 0x11/imm32/alloc-id:fake +16055 Two-args-int-stack-int-reg/imm32/inouts +16056 0/imm32/no-outputs 16057 0/imm32/no-outputs -16058 0/imm32/no-outputs -16059 0x11/imm32/alloc-id:fake -16060 _string_0f_8d_jump_loop/imm32/subx-name -16061 0/imm32/no-rm32 -16062 0/imm32/no-r32 -16063 0/imm32/no-imm32 +16058 0x11/imm32/alloc-id:fake +16059 _string_21_and_with/imm32/subx-name +16060 1/imm32/rm32-is-first-inout +16061 2/imm32/r32-is-second-inout +16062 0/imm32/no-imm32 +16063 0/imm32/no-imm8 16064 0/imm32/no-disp32 -16065 0/imm32/no-output +16065 0/imm32/output-is-write-only 16066 0x11/imm32/alloc-id:fake -16067 _Primitive-loop-if-<=/imm32/next -16068 _Primitive-loop-if-<=: # (payload primitive) +16067 _Primitive-and-mem-with-reg/imm32/next +16068 _Primitive-and-mem-with-reg: # (payload primitive) 16069 0x11/imm32/alloc-id:fake:payload -16070 0x11/imm32/alloc-id:fake -16071 _string-loop-if-<=/imm32/name -16072 0/imm32/no-inouts -16073 0/imm32/no-inouts -16074 0/imm32/no-outputs -16075 0/imm32/no-outputs -16076 0x11/imm32/alloc-id:fake -16077 _string_0f_8e_jump_loop/imm32/subx-name -16078 0/imm32/no-rm32 -16079 0/imm32/no-r32 -16080 0/imm32/no-imm32 -16081 0/imm32/no-disp32 -16082 0/imm32/no-output -16083 0x11/imm32/alloc-id:fake -16084 _Primitive-loop-if->/imm32/next -16085 _Primitive-loop-if->: # (payload primitive) -16086 0x11/imm32/alloc-id:fake:payload -16087 0x11/imm32/alloc-id:fake -16088 _string-loop-if->/imm32/name -16089 0/imm32/no-inouts -16090 0/imm32/no-inouts -16091 0/imm32/no-outputs -16092 0/imm32/no-outputs -16093 0x11/imm32/alloc-id:fake -16094 _string_0f_8f_jump_loop/imm32/subx-name -16095 0/imm32/no-rm32 -16096 0/imm32/no-r32 -16097 0/imm32/no-imm32 -16098 0/imm32/no-disp32 -16099 0/imm32/no-output -16100 0x11/imm32/alloc-id:fake -16101 _Primitive-loop/imm32/next # we probably don't need an unconditional break -16102 _Primitive-loop: # (payload primitive) -16103 0x11/imm32/alloc-id:fake:payload +16070 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 +16071 0x11/imm32/alloc-id:fake +16072 _string-and/imm32/name +16073 0x11/imm32/alloc-id:fake +16074 Single-int-var-in-mem/imm32/inouts +16075 0x11/imm32/alloc-id:fake +16076 Single-int-var-in-some-register/imm32/outputs +16077 0x11/imm32/alloc-id:fake +16078 _string_23_and/imm32/subx-name +16079 1/imm32/rm32-is-first-inout +16080 3/imm32/r32-is-first-output +16081 0/imm32/no-imm32 +16082 0/imm32/no-imm8 +16083 0/imm32/no-disp32 +16084 0/imm32/output-is-write-only +16085 0x11/imm32/alloc-id:fake +16086 _Primitive-and-lit-with-reg/imm32/next +16087 _Primitive-and-lit-with-reg: # (payload primitive) +16088 0x11/imm32/alloc-id:fake:payload +16089 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 +16090 0x11/imm32/alloc-id:fake +16091 _string-and/imm32/name +16092 0x11/imm32/alloc-id:fake +16093 Single-lit-var/imm32/inouts +16094 0x11/imm32/alloc-id:fake +16095 Single-int-var-in-some-register/imm32/outputs +16096 0x11/imm32/alloc-id:fake +16097 _string_81_subop_and/imm32/subx-name +16098 3/imm32/rm32-is-first-output +16099 0/imm32/no-r32 +16100 1/imm32/imm32-is-first-inout +16101 0/imm32/no-imm8 +16102 0/imm32/no-disp32 +16103 0/imm32/output-is-write-only 16104 0x11/imm32/alloc-id:fake -16105 _string-loop/imm32/name -16106 0/imm32/no-inouts -16107 0/imm32/no-inouts -16108 0/imm32/no-outputs -16109 0/imm32/no-outputs -16110 0x11/imm32/alloc-id:fake -16111 _string_e9_jump_loop/imm32/subx-name -16112 0/imm32/no-rm32 -16113 0/imm32/no-r32 -16114 0/imm32/no-imm32 -16115 0/imm32/no-disp32 -16116 0/imm32/no-output -16117 0x11/imm32/alloc-id:fake -16118 _Primitive-break-if-addr<-named/imm32/next -16119 # - branches to named blocks -16120 _Primitive-break-if-addr<-named: # (payload primitive) -16121 0x11/imm32/alloc-id:fake:payload -16122 0x11/imm32/alloc-id:fake -16123 _string-break-if-addr</imm32/name -16124 0x11/imm32/alloc-id:fake -16125 Single-lit-var/imm32/inouts -16126 0/imm32/no-outputs -16127 0/imm32/no-outputs -16128 0x11/imm32/alloc-id:fake -16129 _string_0f_82_jump_label/imm32/subx-name -16130 0/imm32/no-rm32 -16131 0/imm32/no-r32 -16132 0/imm32/no-imm32 -16133 1/imm32/disp32-is-first-inout -16134 0/imm32/no-output +16105 _Primitive-and-lit-with-mem/imm32/next +16106 _Primitive-and-lit-with-mem: # (payload primitive) +16107 0x11/imm32/alloc-id:fake:payload +16108 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 +16109 0x11/imm32/alloc-id:fake +16110 _string-and-with/imm32/name +16111 0x11/imm32/alloc-id:fake +16112 Int-var-and-literal/imm32/inouts +16113 0/imm32/no-outputs +16114 0/imm32/no-outputs +16115 0x11/imm32/alloc-id:fake +16116 _string_81_subop_and/imm32/subx-name +16117 1/imm32/rm32-is-first-inout +16118 0/imm32/no-r32 +16119 2/imm32/imm32-is-second-inout +16120 0/imm32/no-imm8 +16121 0/imm32/no-disp32 +16122 0/imm32/output-is-write-only +16123 0x11/imm32/alloc-id:fake +16124 _Primitive-or-with-eax/imm32/next +16125 # - or +16126 _Primitive-or-with-eax: # (payload primitive) +16127 0x11/imm32/alloc-id:fake:payload +16128 # var/eax <- or lit => 0d/or-with-eax lit/imm32 +16129 0x11/imm32/alloc-id:fake +16130 _string-or/imm32/name +16131 0x11/imm32/alloc-id:fake +16132 Single-lit-var/imm32/inouts +16133 0x11/imm32/alloc-id:fake +16134 Single-int-var-in-eax/imm32/outputs 16135 0x11/imm32/alloc-id:fake -16136 _Primitive-break-if-addr>=-named/imm32/next -16137 _Primitive-break-if-addr>=-named: # (payload primitive) -16138 0x11/imm32/alloc-id:fake:payload -16139 0x11/imm32/alloc-id:fake -16140 _string-break-if-addr>=/imm32/name -16141 0x11/imm32/alloc-id:fake -16142 Single-lit-var/imm32/inouts -16143 0/imm32/no-outputs -16144 0/imm32/no-outputs -16145 0x11/imm32/alloc-id:fake -16146 _string_0f_83_jump_label/imm32/subx-name -16147 0/imm32/no-rm32 -16148 0/imm32/no-r32 -16149 0/imm32/no-imm32 -16150 1/imm32/disp32-is-first-inout -16151 0/imm32/no-output +16136 _string_0d_or_with_eax/imm32/subx-name +16137 0/imm32/no-rm32 +16138 0/imm32/no-r32 +16139 1/imm32/imm32-is-first-inout +16140 0/imm32/no-imm8 +16141 0/imm32/no-disp32 +16142 0/imm32/output-is-write-only +16143 0x11/imm32/alloc-id:fake +16144 _Primitive-or-reg-with-reg/imm32/next +16145 _Primitive-or-reg-with-reg: # (payload primitive) +16146 0x11/imm32/alloc-id:fake:payload +16147 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 +16148 0x11/imm32/alloc-id:fake +16149 _string-or/imm32/name +16150 0x11/imm32/alloc-id:fake +16151 Single-int-var-in-some-register/imm32/inouts 16152 0x11/imm32/alloc-id:fake -16153 _Primitive-break-if-=-named/imm32/next -16154 _Primitive-break-if-=-named: # (payload primitive) -16155 0x11/imm32/alloc-id:fake:payload -16156 0x11/imm32/alloc-id:fake -16157 _string-break-if-=/imm32/name -16158 0x11/imm32/alloc-id:fake -16159 Single-lit-var/imm32/inouts -16160 0/imm32/no-outputs -16161 0/imm32/no-outputs +16153 Single-int-var-in-some-register/imm32/outputs +16154 0x11/imm32/alloc-id:fake +16155 _string_09_or_with/imm32/subx-name +16156 3/imm32/rm32-is-first-output +16157 1/imm32/r32-is-first-inout +16158 0/imm32/no-imm32 +16159 0/imm32/no-imm8 +16160 0/imm32/no-disp32 +16161 0/imm32/output-is-write-only 16162 0x11/imm32/alloc-id:fake -16163 _string_0f_84_jump_label/imm32/subx-name -16164 0/imm32/no-rm32 -16165 0/imm32/no-r32 -16166 0/imm32/no-imm32 -16167 1/imm32/disp32-is-first-inout -16168 0/imm32/no-output +16163 _Primitive-or-reg-with-mem/imm32/next +16164 _Primitive-or-reg-with-mem: # (payload primitive) +16165 0x11/imm32/alloc-id:fake:payload +16166 # or-with var1 var2/reg => 09/or-with var1 var2/r32 +16167 0x11/imm32/alloc-id:fake +16168 _string-or-with/imm32/name 16169 0x11/imm32/alloc-id:fake -16170 _Primitive-break-if-!=-named/imm32/next -16171 _Primitive-break-if-!=-named: # (payload primitive) -16172 0x11/imm32/alloc-id:fake:payload +16170 Two-args-int-stack-int-reg/imm32/inouts +16171 0/imm32/no-outputs +16172 0/imm32/no-outputs 16173 0x11/imm32/alloc-id:fake -16174 _string-break-if-!=/imm32/name -16175 0x11/imm32/alloc-id:fake -16176 Single-lit-var/imm32/inouts -16177 0/imm32/no-outputs -16178 0/imm32/no-outputs -16179 0x11/imm32/alloc-id:fake -16180 _string_0f_85_jump_label/imm32/subx-name -16181 0/imm32/no-rm32 -16182 0/imm32/no-r32 -16183 0/imm32/no-imm32 -16184 1/imm32/disp32-is-first-inout -16185 0/imm32/no-output +16174 _string_09_or_with/imm32/subx-name +16175 1/imm32/rm32-is-first-inout +16176 2/imm32/r32-is-second-inout +16177 0/imm32/no-imm32 +16178 0/imm32/no-imm8 +16179 0/imm32/no-disp32 +16180 0/imm32/output-is-write-only +16181 0x11/imm32/alloc-id:fake +16182 _Primitive-or-mem-with-reg/imm32/next +16183 _Primitive-or-mem-with-reg: # (payload primitive) +16184 0x11/imm32/alloc-id:fake:payload +16185 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 16186 0x11/imm32/alloc-id:fake -16187 _Primitive-break-if-addr<=-named/imm32/next -16188 _Primitive-break-if-addr<=-named: # (payload primitive) -16189 0x11/imm32/alloc-id:fake:payload +16187 _string-or/imm32/name +16188 0x11/imm32/alloc-id:fake +16189 Single-int-var-in-mem/imm32/inouts 16190 0x11/imm32/alloc-id:fake -16191 _string-break-if-addr<=/imm32/name +16191 Single-int-var-in-some-register/imm32/outputs 16192 0x11/imm32/alloc-id:fake -16193 Single-lit-var/imm32/inouts -16194 0/imm32/no-outputs -16195 0/imm32/no-outputs -16196 0x11/imm32/alloc-id:fake -16197 _string_0f_86_jump_label/imm32/subx-name -16198 0/imm32/no-rm32 -16199 0/imm32/no-r32 -16200 0/imm32/no-imm32 -16201 1/imm32/disp32-is-first-inout -16202 0/imm32/no-output -16203 0x11/imm32/alloc-id:fake -16204 _Primitive-break-if-addr>-named/imm32/next -16205 _Primitive-break-if-addr>-named: # (payload primitive) -16206 0x11/imm32/alloc-id:fake:payload +16193 _string_0b_or/imm32/subx-name +16194 1/imm32/rm32-is-first-inout +16195 3/imm32/r32-is-first-output +16196 0/imm32/no-imm32 +16197 0/imm32/no-imm8 +16198 0/imm32/no-disp32 +16199 0/imm32/output-is-write-only +16200 0x11/imm32/alloc-id:fake +16201 _Primitive-or-lit-with-reg/imm32/next +16202 _Primitive-or-lit-with-reg: # (payload primitive) +16203 0x11/imm32/alloc-id:fake:payload +16204 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 +16205 0x11/imm32/alloc-id:fake +16206 _string-or/imm32/name 16207 0x11/imm32/alloc-id:fake -16208 _string-break-if-addr>/imm32/name +16208 Single-lit-var/imm32/inouts 16209 0x11/imm32/alloc-id:fake -16210 Single-lit-var/imm32/inouts -16211 0/imm32/no-outputs -16212 0/imm32/no-outputs -16213 0x11/imm32/alloc-id:fake -16214 _string_0f_87_jump_label/imm32/subx-name -16215 0/imm32/no-rm32 -16216 0/imm32/no-r32 -16217 0/imm32/no-imm32 -16218 1/imm32/disp32-is-first-inout -16219 0/imm32/no-output -16220 0x11/imm32/alloc-id:fake -16221 _Primitive-break-if-<-named/imm32/next -16222 _Primitive-break-if-<-named: # (payload primitive) -16223 0x11/imm32/alloc-id:fake:payload +16210 Single-int-var-in-some-register/imm32/outputs +16211 0x11/imm32/alloc-id:fake +16212 _string_81_subop_or/imm32/subx-name +16213 3/imm32/rm32-is-first-output +16214 0/imm32/no-r32 +16215 1/imm32/imm32-is-first-inout +16216 0/imm32/no-imm8 +16217 0/imm32/no-disp32 +16218 0/imm32/output-is-write-only +16219 0x11/imm32/alloc-id:fake +16220 _Primitive-or-lit-with-mem/imm32/next +16221 _Primitive-or-lit-with-mem: # (payload primitive) +16222 0x11/imm32/alloc-id:fake:payload +16223 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 16224 0x11/imm32/alloc-id:fake -16225 _string-break-if-</imm32/name +16225 _string-or-with/imm32/name 16226 0x11/imm32/alloc-id:fake -16227 Single-lit-var/imm32/inouts +16227 Int-var-and-literal/imm32/inouts 16228 0/imm32/no-outputs 16229 0/imm32/no-outputs 16230 0x11/imm32/alloc-id:fake -16231 _string_0f_8c_jump_label/imm32/subx-name -16232 0/imm32/no-rm32 +16231 _string_81_subop_or/imm32/subx-name +16232 1/imm32/rm32-is-first-inout 16233 0/imm32/no-r32 -16234 0/imm32/no-imm32 -16235 1/imm32/disp32-is-first-inout -16236 0/imm32/no-output -16237 0x11/imm32/alloc-id:fake -16238 _Primitive-break-if->=-named/imm32/next -16239 _Primitive-break-if->=-named: # (payload primitive) -16240 0x11/imm32/alloc-id:fake:payload -16241 0x11/imm32/alloc-id:fake -16242 _string-break-if->=/imm32/name -16243 0x11/imm32/alloc-id:fake -16244 Single-lit-var/imm32/inouts -16245 0/imm32/no-outputs -16246 0/imm32/no-outputs -16247 0x11/imm32/alloc-id:fake -16248 _string_0f_8d_jump_label/imm32/subx-name -16249 0/imm32/no-rm32 -16250 0/imm32/no-r32 -16251 0/imm32/no-imm32 -16252 1/imm32/disp32-is-first-inout -16253 0/imm32/no-output -16254 0x11/imm32/alloc-id:fake -16255 _Primitive-break-if-<=-named/imm32/next -16256 _Primitive-break-if-<=-named: # (payload primitive) -16257 0x11/imm32/alloc-id:fake:payload +16234 2/imm32/imm32-is-second-inout +16235 0/imm32/no-imm8 +16236 0/imm32/no-disp32 +16237 0/imm32/output-is-write-only +16238 0x11/imm32/alloc-id:fake +16239 _Primitive-xor-with-eax/imm32/next +16240 # - xor +16241 _Primitive-xor-with-eax: # (payload primitive) +16242 0x11/imm32/alloc-id:fake:payload +16243 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 +16244 0x11/imm32/alloc-id:fake +16245 _string-xor/imm32/name +16246 0x11/imm32/alloc-id:fake +16247 Single-lit-var/imm32/inouts +16248 0x11/imm32/alloc-id:fake +16249 Single-int-var-in-eax/imm32/outputs +16250 0x11/imm32/alloc-id:fake +16251 _string_35_xor_with_eax/imm32/subx-name +16252 0/imm32/no-rm32 +16253 0/imm32/no-r32 +16254 1/imm32/imm32-is-first-inout +16255 0/imm32/no-imm8 +16256 0/imm32/no-disp32 +16257 0/imm32/output-is-write-only 16258 0x11/imm32/alloc-id:fake -16259 _string-break-if-<=/imm32/name -16260 0x11/imm32/alloc-id:fake -16261 Single-lit-var/imm32/inouts -16262 0/imm32/no-outputs -16263 0/imm32/no-outputs -16264 0x11/imm32/alloc-id:fake -16265 _string_0f_8e_jump_label/imm32/subx-name -16266 0/imm32/no-rm32 -16267 0/imm32/no-r32 -16268 0/imm32/no-imm32 -16269 1/imm32/disp32-is-first-inout -16270 0/imm32/no-output -16271 0x11/imm32/alloc-id:fake -16272 _Primitive-break-if->-named/imm32/next -16273 _Primitive-break-if->-named: # (payload primitive) -16274 0x11/imm32/alloc-id:fake:payload -16275 0x11/imm32/alloc-id:fake -16276 _string-break-if->/imm32/name +16259 _Primitive-xor-reg-with-reg/imm32/next +16260 _Primitive-xor-reg-with-reg: # (payload primitive) +16261 0x11/imm32/alloc-id:fake:payload +16262 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 +16263 0x11/imm32/alloc-id:fake +16264 _string-xor/imm32/name +16265 0x11/imm32/alloc-id:fake +16266 Single-int-var-in-some-register/imm32/inouts +16267 0x11/imm32/alloc-id:fake +16268 Single-int-var-in-some-register/imm32/outputs +16269 0x11/imm32/alloc-id:fake +16270 _string_31_xor_with/imm32/subx-name +16271 3/imm32/rm32-is-first-output +16272 1/imm32/r32-is-first-inout +16273 0/imm32/no-imm32 +16274 0/imm32/no-imm8 +16275 0/imm32/no-disp32 +16276 0/imm32/output-is-write-only 16277 0x11/imm32/alloc-id:fake -16278 Single-lit-var/imm32/inouts -16279 0/imm32/no-outputs -16280 0/imm32/no-outputs -16281 0x11/imm32/alloc-id:fake -16282 _string_0f_8f_jump_label/imm32/subx-name -16283 0/imm32/no-rm32 -16284 0/imm32/no-r32 -16285 0/imm32/no-imm32 -16286 1/imm32/disp32-is-first-inout -16287 0/imm32/no-output +16278 _Primitive-xor-reg-with-mem/imm32/next +16279 _Primitive-xor-reg-with-mem: # (payload primitive) +16280 0x11/imm32/alloc-id:fake:payload +16281 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 +16282 0x11/imm32/alloc-id:fake +16283 _string-xor-with/imm32/name +16284 0x11/imm32/alloc-id:fake +16285 Two-args-int-stack-int-reg/imm32/inouts +16286 0/imm32/no-outputs +16287 0/imm32/no-outputs 16288 0x11/imm32/alloc-id:fake -16289 _Primitive-break-named/imm32/next -16290 _Primitive-break-named: # (payload primitive) -16291 0x11/imm32/alloc-id:fake:payload -16292 0x11/imm32/alloc-id:fake -16293 _string-break/imm32/name -16294 0x11/imm32/alloc-id:fake -16295 Single-lit-var/imm32/inouts -16296 0/imm32/no-outputs -16297 0/imm32/no-outputs -16298 0x11/imm32/alloc-id:fake -16299 _string_e9_jump_label/imm32/subx-name -16300 0/imm32/no-rm32 -16301 0/imm32/no-r32 -16302 0/imm32/no-imm32 -16303 1/imm32/disp32-is-first-inout -16304 0/imm32/no-output +16289 _string_31_xor_with/imm32/subx-name +16290 1/imm32/rm32-is-first-inout +16291 2/imm32/r32-is-second-inout +16292 0/imm32/no-imm32 +16293 0/imm32/no-imm8 +16294 0/imm32/no-disp32 +16295 0/imm32/output-is-write-only +16296 0x11/imm32/alloc-id:fake +16297 _Primitive-xor-mem-with-reg/imm32/next +16298 _Primitive-xor-mem-with-reg: # (payload primitive) +16299 0x11/imm32/alloc-id:fake:payload +16300 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 +16301 0x11/imm32/alloc-id:fake +16302 _string-xor/imm32/name +16303 0x11/imm32/alloc-id:fake +16304 Single-int-var-in-mem/imm32/inouts 16305 0x11/imm32/alloc-id:fake -16306 _Primitive-loop-if-addr<-named/imm32/next -16307 _Primitive-loop-if-addr<-named: # (payload primitive) -16308 0x11/imm32/alloc-id:fake:payload -16309 0x11/imm32/alloc-id:fake -16310 _string-loop-if-addr</imm32/name -16311 0x11/imm32/alloc-id:fake -16312 Single-lit-var/imm32/inouts -16313 0/imm32/no-outputs -16314 0/imm32/no-outputs +16306 Single-int-var-in-some-register/imm32/outputs +16307 0x11/imm32/alloc-id:fake +16308 _string_33_xor/imm32/subx-name +16309 1/imm32/rm32-is-first-inout +16310 3/imm32/r32-is-first-output +16311 0/imm32/no-imm32 +16312 0/imm32/no-imm8 +16313 0/imm32/no-disp32 +16314 0/imm32/output-is-write-only 16315 0x11/imm32/alloc-id:fake -16316 _string_0f_82_jump_label/imm32/subx-name -16317 0/imm32/no-rm32 -16318 0/imm32/no-r32 -16319 0/imm32/no-imm32 -16320 1/imm32/disp32-is-first-inout -16321 0/imm32/no-output +16316 _Primitive-xor-lit-with-reg/imm32/next +16317 _Primitive-xor-lit-with-reg: # (payload primitive) +16318 0x11/imm32/alloc-id:fake:payload +16319 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 +16320 0x11/imm32/alloc-id:fake +16321 _string-xor/imm32/name 16322 0x11/imm32/alloc-id:fake -16323 _Primitive-loop-if-addr>=-named/imm32/next -16324 _Primitive-loop-if-addr>=-named: # (payload primitive) -16325 0x11/imm32/alloc-id:fake:payload +16323 Single-lit-var/imm32/inouts +16324 0x11/imm32/alloc-id:fake +16325 Single-int-var-in-some-register/imm32/outputs 16326 0x11/imm32/alloc-id:fake -16327 _string-loop-if-addr>=/imm32/name -16328 0x11/imm32/alloc-id:fake -16329 Single-lit-var/imm32/inouts -16330 0/imm32/no-outputs -16331 0/imm32/no-outputs -16332 0x11/imm32/alloc-id:fake -16333 _string_0f_83_jump_label/imm32/subx-name -16334 0/imm32/no-rm32 -16335 0/imm32/no-r32 -16336 0/imm32/no-imm32 -16337 1/imm32/disp32-is-first-inout -16338 0/imm32/no-output +16327 _string_81_subop_xor/imm32/subx-name +16328 3/imm32/rm32-is-first-output +16329 0/imm32/no-r32 +16330 1/imm32/imm32-is-first-inout +16331 0/imm32/no-imm8 +16332 0/imm32/no-disp32 +16333 0/imm32/output-is-write-only +16334 0x11/imm32/alloc-id:fake +16335 _Primitive-xor-lit-with-mem/imm32/next +16336 _Primitive-xor-lit-with-mem: # (payload primitive) +16337 0x11/imm32/alloc-id:fake:payload +16338 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 16339 0x11/imm32/alloc-id:fake -16340 _Primitive-loop-if-=-named/imm32/next -16341 _Primitive-loop-if-=-named: # (payload primitive) -16342 0x11/imm32/alloc-id:fake:payload -16343 0x11/imm32/alloc-id:fake -16344 _string-loop-if-=/imm32/name +16340 _string-xor-with/imm32/name +16341 0x11/imm32/alloc-id:fake +16342 Int-var-and-literal/imm32/inouts +16343 0/imm32/no-outputs +16344 0/imm32/no-outputs 16345 0x11/imm32/alloc-id:fake -16346 Single-lit-var/imm32/inouts -16347 0/imm32/no-outputs -16348 0/imm32/no-outputs -16349 0x11/imm32/alloc-id:fake -16350 _string_0f_84_jump_label/imm32/subx-name -16351 0/imm32/no-rm32 -16352 0/imm32/no-r32 -16353 0/imm32/no-imm32 -16354 1/imm32/disp32-is-first-inout -16355 0/imm32/no-output -16356 0x11/imm32/alloc-id:fake -16357 _Primitive-loop-if-!=-named/imm32/next -16358 _Primitive-loop-if-!=-named: # (payload primitive) -16359 0x11/imm32/alloc-id:fake:payload +16346 _string_81_subop_xor/imm32/subx-name +16347 1/imm32/rm32-is-first-inout +16348 0/imm32/no-r32 +16349 2/imm32/imm32-is-second-inout +16350 0/imm32/no-imm8 +16351 0/imm32/no-disp32 +16352 0/imm32/output-is-write-only +16353 0x11/imm32/alloc-id:fake +16354 _Primitive-shift-reg-left-by-lit/imm32/next +16355 _Primitive-shift-reg-left-by-lit: # (payload primitive) +16356 0x11/imm32/alloc-id:fake:payload +16357 # var1/reg <- shift-left lit => c1/shift 4/subop/left var1/rm32 lit/imm32 +16358 0x11/imm32/alloc-id:fake +16359 _string-shift-left/imm32/name 16360 0x11/imm32/alloc-id:fake -16361 _string-loop-if-!=/imm32/name +16361 Single-lit-var/imm32/inouts 16362 0x11/imm32/alloc-id:fake -16363 Single-lit-var/imm32/inouts -16364 0/imm32/no-outputs -16365 0/imm32/no-outputs -16366 0x11/imm32/alloc-id:fake -16367 _string_0f_85_jump_label/imm32/subx-name -16368 0/imm32/no-rm32 -16369 0/imm32/no-r32 -16370 0/imm32/no-imm32 -16371 1/imm32/disp32-is-first-inout -16372 0/imm32/no-output -16373 0x11/imm32/alloc-id:fake -16374 _Primitive-loop-if-addr<=-named/imm32/next -16375 _Primitive-loop-if-addr<=-named: # (payload primitive) -16376 0x11/imm32/alloc-id:fake:payload +16363 Single-int-var-in-some-register/imm32/outputs +16364 0x11/imm32/alloc-id:fake +16365 _string_c1_subop_shift_left/imm32/subx-name +16366 3/imm32/rm32-is-first-output +16367 0/imm32/no-r32 +16368 0/imm32/no-imm32 +16369 1/imm32/imm8-is-first-inout +16370 0/imm32/no-disp32 +16371 0/imm32/output-is-write-only +16372 0x11/imm32/alloc-id:fake +16373 _Primitive-shift-reg-right-by-lit/imm32/next +16374 _Primitive-shift-reg-right-by-lit: # (payload primitive) +16375 0x11/imm32/alloc-id:fake:payload +16376 # var1/reg <- shift-right lit => c1/shift 5/subop/right var1/rm32 lit/imm32 16377 0x11/imm32/alloc-id:fake -16378 _string-loop-if-addr<=/imm32/name +16378 _string-shift-right/imm32/name 16379 0x11/imm32/alloc-id:fake -16380 Single-lit-var/imm32/inouts -16381 0/imm32/no-outputs -16382 0/imm32/no-outputs +16380 Single-lit-var/imm32/inouts +16381 0x11/imm32/alloc-id:fake +16382 Single-int-var-in-some-register/imm32/outputs 16383 0x11/imm32/alloc-id:fake -16384 _string_0f_86_jump_label/imm32/subx-name -16385 0/imm32/no-rm32 +16384 _string_c1_subop_shift_right_padding_zeroes/imm32/subx-name +16385 3/imm32/rm32-is-first-output 16386 0/imm32/no-r32 16387 0/imm32/no-imm32 -16388 1/imm32/disp32-is-first-inout -16389 0/imm32/no-output -16390 0x11/imm32/alloc-id:fake -16391 _Primitive-loop-if-addr>-named/imm32/next -16392 _Primitive-loop-if-addr>-named: # (payload primitive) -16393 0x11/imm32/alloc-id:fake:payload -16394 0x11/imm32/alloc-id:fake -16395 _string-loop-if-addr>/imm32/name +16388 1/imm32/imm8-is-first-inout +16389 0/imm32/no-disp32 +16390 0/imm32/output-is-write-only +16391 0x11/imm32/alloc-id:fake +16392 _Primitive-shift-reg-right-signed-by-lit/imm32/next +16393 _Primitive-shift-reg-right-signed-by-lit: # (payload primitive) +16394 0x11/imm32/alloc-id:fake:payload +16395 # var1/reg <- shift-right-signed lit => c1/shift 7/subop/right-preserving-sign var1/rm32 lit/imm32 16396 0x11/imm32/alloc-id:fake -16397 Single-lit-var/imm32/inouts -16398 0/imm32/no-outputs -16399 0/imm32/no-outputs +16397 _string-shift-right-signed/imm32/name +16398 0x11/imm32/alloc-id:fake +16399 Single-lit-var/imm32/inouts 16400 0x11/imm32/alloc-id:fake -16401 _string_0f_87_jump_label/imm32/subx-name -16402 0/imm32/no-rm32 -16403 0/imm32/no-r32 -16404 0/imm32/no-imm32 -16405 1/imm32/disp32-is-first-inout -16406 0/imm32/no-output -16407 0x11/imm32/alloc-id:fake -16408 _Primitive-loop-if-<-named/imm32/next -16409 _Primitive-loop-if-<-named: # (payload primitive) -16410 0x11/imm32/alloc-id:fake:payload -16411 0x11/imm32/alloc-id:fake -16412 _string-loop-if-</imm32/name -16413 0x11/imm32/alloc-id:fake -16414 Single-lit-var/imm32/inouts -16415 0/imm32/no-outputs -16416 0/imm32/no-outputs +16401 Single-int-var-in-some-register/imm32/outputs +16402 0x11/imm32/alloc-id:fake +16403 _string_c1_subop_shift_right_preserving_sign/imm32/subx-name +16404 3/imm32/rm32-is-first-output +16405 0/imm32/no-r32 +16406 0/imm32/no-imm32 +16407 1/imm32/imm8-is-first-inout +16408 0/imm32/no-disp32 +16409 0/imm32/output-is-write-only +16410 0x11/imm32/alloc-id:fake +16411 _Primitive-shift-mem-left-by-lit/imm32/next +16412 _Primitive-shift-mem-left-by-lit: # (payload primitive) +16413 0x11/imm32/alloc-id:fake:payload +16414 # shift-left var1, lit => c1/shift 4/subop/left var1/rm32 lit/imm32 +16415 0x11/imm32/alloc-id:fake +16416 _string-shift-left/imm32/name 16417 0x11/imm32/alloc-id:fake -16418 _string_0f_8c_jump_label/imm32/subx-name -16419 0/imm32/no-rm32 -16420 0/imm32/no-r32 -16421 0/imm32/no-imm32 -16422 1/imm32/disp32-is-first-inout -16423 0/imm32/no-output -16424 0x11/imm32/alloc-id:fake -16425 _Primitive-loop-if->=-named/imm32/next -16426 _Primitive-loop-if->=-named: # (payload primitive) -16427 0x11/imm32/alloc-id:fake:payload -16428 0x11/imm32/alloc-id:fake -16429 _string-loop-if->=/imm32/name -16430 0x11/imm32/alloc-id:fake -16431 Single-lit-var/imm32/inouts -16432 0/imm32/no-outputs -16433 0/imm32/no-outputs +16418 Int-var-and-literal/imm32/inouts +16419 0/imm32/no-outputs +16420 0/imm32/no-outputs +16421 0x11/imm32/alloc-id:fake +16422 _string_c1_subop_shift_left/imm32/subx-name +16423 1/imm32/rm32-is-first-inout +16424 0/imm32/no-r32 +16425 0/imm32/no-imm32 +16426 2/imm32/imm8-is-second-inout +16427 0/imm32/no-disp32 +16428 0/imm32/output-is-write-only +16429 0x11/imm32/alloc-id:fake +16430 _Primitive-shift-mem-right-by-lit/imm32/next +16431 _Primitive-shift-mem-right-by-lit: # (payload primitive) +16432 0x11/imm32/alloc-id:fake:payload +16433 # shift-right var1, lit => c1/shift 5/subop/right var1/rm32 lit/imm32 16434 0x11/imm32/alloc-id:fake -16435 _string_0f_8d_jump_label/imm32/subx-name -16436 0/imm32/no-rm32 -16437 0/imm32/no-r32 -16438 0/imm32/no-imm32 -16439 1/imm32/disp32-is-first-inout -16440 0/imm32/no-output -16441 0x11/imm32/alloc-id:fake -16442 _Primitive-loop-if-<=-named/imm32/next -16443 _Primitive-loop-if-<=-named: # (payload primitive) -16444 0x11/imm32/alloc-id:fake:payload -16445 0x11/imm32/alloc-id:fake -16446 _string-loop-if-<=/imm32/name -16447 0x11/imm32/alloc-id:fake -16448 Single-lit-var/imm32/inouts -16449 0/imm32/no-outputs -16450 0/imm32/no-outputs -16451 0x11/imm32/alloc-id:fake -16452 _string_0f_8e_jump_label/imm32/subx-name -16453 0/imm32/no-rm32 -16454 0/imm32/no-r32 -16455 0/imm32/no-imm32 -16456 1/imm32/disp32-is-first-inout -16457 0/imm32/no-output -16458 0x11/imm32/alloc-id:fake -16459 _Primitive-loop-if->-named/imm32/next -16460 _Primitive-loop-if->-named: # (payload primitive) -16461 0x11/imm32/alloc-id:fake:payload -16462 0x11/imm32/alloc-id:fake -16463 _string-loop-if->/imm32/name -16464 0x11/imm32/alloc-id:fake -16465 Single-lit-var/imm32/inouts -16466 0/imm32/no-outputs -16467 0/imm32/no-outputs -16468 0x11/imm32/alloc-id:fake -16469 _string_0f_8f_jump_label/imm32/subx-name -16470 0/imm32/no-rm32 -16471 0/imm32/no-r32 -16472 0/imm32/no-imm32 -16473 1/imm32/disp32-is-first-inout -16474 0/imm32/no-output +16435 _string-shift-right/imm32/name +16436 0x11/imm32/alloc-id:fake +16437 Int-var-and-literal/imm32/inouts +16438 0/imm32/no-outputs +16439 0/imm32/no-outputs +16440 0x11/imm32/alloc-id:fake +16441 _string_c1_subop_shift_right_padding_zeroes/imm32/subx-name +16442 1/imm32/rm32-is-first-inout +16443 0/imm32/no-r32 +16444 0/imm32/no-imm32 +16445 2/imm32/imm8-is-second-inout +16446 0/imm32/no-disp32 +16447 0/imm32/output-is-write-only +16448 0x11/imm32/alloc-id:fake +16449 _Primitive-shift-mem-right-signed-by-lit/imm32/next +16450 _Primitive-shift-mem-right-signed-by-lit: # (payload primitive) +16451 0x11/imm32/alloc-id:fake:payload +16452 # shift-right-signed var1, lit => c1/shift 7/subop/right-preserving-sign var1/rm32 lit/imm32 +16453 0x11/imm32/alloc-id:fake +16454 _string-shift-right-signed/imm32/name +16455 0x11/imm32/alloc-id:fake +16456 Int-var-and-literal/imm32/inouts +16457 0/imm32/no-outputs +16458 0/imm32/no-outputs +16459 0x11/imm32/alloc-id:fake +16460 _string_c1_subop_shift_right_preserving_sign/imm32/subx-name +16461 1/imm32/rm32-is-first-inout +16462 0/imm32/no-r32 +16463 0/imm32/no-imm32 +16464 2/imm32/imm8-is-second-inout +16465 0/imm32/no-disp32 +16466 0/imm32/output-is-write-only +16467 0x11/imm32/alloc-id:fake +16468 _Primitive-copy-to-eax/imm32/next +16469 # - copy +16470 _Primitive-copy-to-eax: # (payload primitive) +16471 0x11/imm32/alloc-id:fake:payload +16472 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 +16473 0x11/imm32/alloc-id:fake +16474 _string-copy/imm32/name 16475 0x11/imm32/alloc-id:fake -16476 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break -16477 _Primitive-loop-named: # (payload primitive) -16478 0x11/imm32/alloc-id:fake:payload +16476 Single-lit-var/imm32/inouts +16477 0x11/imm32/alloc-id:fake +16478 Single-int-var-in-eax/imm32/outputs 16479 0x11/imm32/alloc-id:fake -16480 _string-loop/imm32/name -16481 0x11/imm32/alloc-id:fake -16482 Single-lit-var/imm32/inouts -16483 0/imm32/no-outputs -16484 0/imm32/no-outputs -16485 0x11/imm32/alloc-id:fake -16486 _string_e9_jump_label/imm32/subx-name -16487 0/imm32/no-rm32 -16488 0/imm32/no-r32 -16489 0/imm32/no-imm32 -16490 1/imm32/disp32-is-first-inout -16491 0/imm32/no-output -16492 0/imm32/next -16493 0/imm32/next -16494 -16495 # string literals for Mu instructions -16496 _string-add: # (payload array byte) -16497 0x11/imm32/alloc-id:fake:payload -16498 # "add" -16499 0x3/imm32/size -16500 0x61/a 0x64/d 0x64/d -16501 _string-address: # (payload array byte) -16502 0x11/imm32/alloc-id:fake:payload -16503 # "address" -16504 0x7/imm32/size -16505 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s -16506 _string-add-to: # (payload array byte) -16507 0x11/imm32/alloc-id:fake:payload -16508 # "add-to" -16509 0x6/imm32/size -16510 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o -16511 _string-and: # (payload array byte) -16512 0x11/imm32/alloc-id:fake:payload -16513 # "and" -16514 0x3/imm32/size -16515 0x61/a 0x6e/n 0x64/d -16516 _string-and-with: # (payload array byte) -16517 0x11/imm32/alloc-id:fake:payload -16518 # "and-with" -16519 0x8/imm32/size -16520 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -16521 _string-break: # (payload array byte) -16522 0x11/imm32/alloc-id:fake:payload -16523 # "break" -16524 0x5/imm32/size -16525 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k -16526 _string-break-if-<: # (payload array byte) -16527 0x11/imm32/alloc-id:fake:payload -16528 # "break-if-<" -16529 0xa/imm32/size -16530 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -16531 _string-break-if-<=: # (payload array byte) -16532 0x11/imm32/alloc-id:fake:payload -16533 # "break-if-<=" -16534 0xb/imm32/size -16535 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -16536 _string-break-if-=: # (payload array byte) -16537 0x11/imm32/alloc-id:fake:payload -16538 # "break-if-=" -16539 0xa/imm32/size -16540 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -16541 _string-break-if->: # (payload array byte) -16542 0x11/imm32/alloc-id:fake:payload -16543 # "break-if->" -16544 0xa/imm32/size -16545 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -16546 _string-break-if->=: # (payload array byte) +16480 _string_b8_copy_to_eax/imm32/subx-name +16481 0/imm32/no-rm32 +16482 0/imm32/no-r32 +16483 1/imm32/imm32-is-first-inout +16484 0/imm32/no-imm8 +16485 0/imm32/no-disp32 +16486 1/imm32/output-is-write-only +16487 0x11/imm32/alloc-id:fake +16488 _Primitive-copy-to-ecx/imm32/next +16489 _Primitive-copy-to-ecx: # (payload primitive) +16490 0x11/imm32/alloc-id:fake:payload +16491 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 +16492 0x11/imm32/alloc-id:fake +16493 _string-copy/imm32/name +16494 0x11/imm32/alloc-id:fake +16495 Single-lit-var/imm32/inouts +16496 0x11/imm32/alloc-id:fake +16497 Single-int-var-in-ecx/imm32/outputs +16498 0x11/imm32/alloc-id:fake +16499 _string_b9_copy_to_ecx/imm32/subx-name +16500 0/imm32/no-rm32 +16501 0/imm32/no-r32 +16502 1/imm32/imm32-is-first-inout +16503 0/imm32/no-imm8 +16504 0/imm32/no-disp32 +16505 1/imm32/output-is-write-only +16506 0x11/imm32/alloc-id:fake +16507 _Primitive-copy-to-edx/imm32/next +16508 _Primitive-copy-to-edx: # (payload primitive) +16509 0x11/imm32/alloc-id:fake:payload +16510 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 +16511 0x11/imm32/alloc-id:fake +16512 _string-copy/imm32/name +16513 0x11/imm32/alloc-id:fake +16514 Single-lit-var/imm32/inouts +16515 0x11/imm32/alloc-id:fake +16516 Single-int-var-in-edx/imm32/outputs +16517 0x11/imm32/alloc-id:fake +16518 _string_ba_copy_to_edx/imm32/subx-name +16519 0/imm32/no-rm32 +16520 0/imm32/no-r32 +16521 1/imm32/imm32-is-first-inout +16522 0/imm32/no-imm8 +16523 0/imm32/no-disp32 +16524 1/imm32/output-is-write-only +16525 0x11/imm32/alloc-id:fake +16526 _Primitive-copy-to-ebx/imm32/next +16527 _Primitive-copy-to-ebx: # (payload primitive) +16528 0x11/imm32/alloc-id:fake:payload +16529 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 +16530 0x11/imm32/alloc-id:fake +16531 _string-copy/imm32/name +16532 0x11/imm32/alloc-id:fake +16533 Single-lit-var/imm32/inouts +16534 0x11/imm32/alloc-id:fake +16535 Single-int-var-in-ebx/imm32/outputs +16536 0x11/imm32/alloc-id:fake +16537 _string_bb_copy_to_ebx/imm32/subx-name +16538 0/imm32/no-rm32 +16539 0/imm32/no-r32 +16540 1/imm32/imm32-is-first-inout +16541 0/imm32/no-imm8 +16542 0/imm32/no-disp32 +16543 1/imm32/output-is-write-only +16544 0x11/imm32/alloc-id:fake +16545 _Primitive-copy-to-esi/imm32/next +16546 _Primitive-copy-to-esi: # (payload primitive) 16547 0x11/imm32/alloc-id:fake:payload -16548 # "break-if->=" -16549 0xb/imm32/size -16550 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -16551 _string-break-if-!=: # (payload array byte) -16552 0x11/imm32/alloc-id:fake:payload -16553 # "break-if-!=" -16554 0xb/imm32/size -16555 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -16556 _string-break-if-addr<: # (payload array byte) -16557 0x11/imm32/alloc-id:fake:payload -16558 # "break-if-addr<" -16559 0xe/imm32/size -16560 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/< -16561 _string-break-if-addr<=: # (payload array byte) -16562 0x11/imm32/alloc-id:fake:payload -16563 # "break-if-addr<=" -16564 0xf/imm32/size -16565 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/= -16566 _string-break-if-addr>: # (payload array byte) -16567 0x11/imm32/alloc-id:fake:payload -16568 # "break-if-addr>" -16569 0xe/imm32/size -16570 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/> -16571 _string-break-if-addr>=: # (payload array byte) -16572 0x11/imm32/alloc-id:fake:payload -16573 # "break-if-addr>=" -16574 0xf/imm32/size -16575 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/= -16576 _string-compare: # (payload array byte) -16577 0x11/imm32/alloc-id:fake:payload -16578 # "compare" -16579 0x7/imm32/size -16580 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e -16581 _string-copy: # (payload array byte) -16582 0x11/imm32/alloc-id:fake:payload -16583 # "copy" -16584 0x4/imm32/size -16585 0x63/c 0x6f/o 0x70/p 0x79/y -16586 _string-copy-to: # (payload array byte) -16587 0x11/imm32/alloc-id:fake:payload -16588 # "copy-to" -16589 0x7/imm32/size -16590 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o -16591 _string-copy-byte: -16592 0x11/imm32/alloc-id:fake:payload -16593 # "copy-byte" -16594 0x9/imm32/size -16595 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e -16596 _string-copy-byte-to: -16597 0x11/imm32/alloc-id:fake:payload -16598 # "copy-byte-to" -16599 0xc/imm32/size -16600 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x74/t 0x6f/o -16601 _string-decrement: # (payload array byte) -16602 0x11/imm32/alloc-id:fake:payload -16603 # "decrement" -16604 0x9/imm32/size -16605 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -16606 _string-increment: # (payload array byte) -16607 0x11/imm32/alloc-id:fake:payload -16608 # "increment" -16609 0x9/imm32/size -16610 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -16611 _string-loop: # (payload array byte) -16612 0x11/imm32/alloc-id:fake:payload -16613 # "loop" -16614 0x4/imm32/size -16615 0x6c/l 0x6f/o 0x6f/o 0x70/p -16616 _string-loop-if-<: # (payload array byte) -16617 0x11/imm32/alloc-id:fake:payload -16618 # "loop-if-<" -16619 0x9/imm32/size -16620 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -16621 _string-loop-if-<=: # (payload array byte) -16622 0x11/imm32/alloc-id:fake:payload -16623 # "loop-if-<=" -16624 0xa/imm32/size -16625 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -16626 _string-loop-if-=: # (payload array byte) -16627 0x11/imm32/alloc-id:fake:payload -16628 # "loop-if-=" -16629 0x9/imm32/size -16630 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -16631 _string-loop-if->: # (payload array byte) -16632 0x11/imm32/alloc-id:fake:payload -16633 # "loop-if->" -16634 0x9/imm32/size -16635 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -16636 _string-loop-if->=: # (payload array byte) -16637 0x11/imm32/alloc-id:fake:payload -16638 # "loop-if->=" -16639 0xa/imm32/size -16640 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -16641 _string-loop-if-!=: # (payload array byte) +16548 # var/esi <- copy lit => be/copy-to-esi lit/imm32 +16549 0x11/imm32/alloc-id:fake +16550 _string-copy/imm32/name +16551 0x11/imm32/alloc-id:fake +16552 Single-lit-var/imm32/inouts +16553 0x11/imm32/alloc-id:fake +16554 Single-int-var-in-esi/imm32/outputs +16555 0x11/imm32/alloc-id:fake +16556 _string_be_copy_to_esi/imm32/subx-name +16557 0/imm32/no-rm32 +16558 0/imm32/no-r32 +16559 1/imm32/imm32-is-first-inout +16560 0/imm32/no-imm8 +16561 0/imm32/no-disp32 +16562 1/imm32/output-is-write-only +16563 0x11/imm32/alloc-id:fake +16564 _Primitive-copy-to-edi/imm32/next +16565 _Primitive-copy-to-edi: # (payload primitive) +16566 0x11/imm32/alloc-id:fake:payload +16567 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 +16568 0x11/imm32/alloc-id:fake +16569 _string-copy/imm32/name +16570 0x11/imm32/alloc-id:fake +16571 Single-lit-var/imm32/inouts +16572 0x11/imm32/alloc-id:fake +16573 Single-int-var-in-edi/imm32/outputs +16574 0x11/imm32/alloc-id:fake +16575 _string_bf_copy_to_edi/imm32/subx-name +16576 0/imm32/no-rm32 +16577 0/imm32/no-r32 +16578 1/imm32/imm32-is-first-inout +16579 0/imm32/no-imm8 +16580 0/imm32/no-disp32 +16581 1/imm32/output-is-write-only +16582 0x11/imm32/alloc-id:fake +16583 _Primitive-copy-reg-to-reg/imm32/next +16584 _Primitive-copy-reg-to-reg: # (payload primitive) +16585 0x11/imm32/alloc-id:fake:payload +16586 # var1/reg <- copy var2/reg => 89/<- var1/rm32 var2/r32 +16587 0x11/imm32/alloc-id:fake +16588 _string-copy/imm32/name +16589 0x11/imm32/alloc-id:fake +16590 Single-int-var-in-some-register/imm32/inouts +16591 0x11/imm32/alloc-id:fake +16592 Single-int-var-in-some-register/imm32/outputs +16593 0x11/imm32/alloc-id:fake +16594 _string_89_<-/imm32/subx-name +16595 3/imm32/rm32-is-first-output +16596 1/imm32/r32-is-first-inout +16597 0/imm32/no-imm32 +16598 0/imm32/no-imm8 +16599 0/imm32/no-disp32 +16600 1/imm32/output-is-write-only +16601 0x11/imm32/alloc-id:fake +16602 _Primitive-copy-reg-to-mem/imm32/next +16603 _Primitive-copy-reg-to-mem: # (payload primitive) +16604 0x11/imm32/alloc-id:fake:payload +16605 # copy-to var1 var2/reg => 89/<- var1 var2/r32 +16606 0x11/imm32/alloc-id:fake +16607 _string-copy-to/imm32/name +16608 0x11/imm32/alloc-id:fake +16609 Two-args-int-stack-int-reg/imm32/inouts +16610 0/imm32/no-outputs +16611 0/imm32/no-outputs +16612 0x11/imm32/alloc-id:fake +16613 _string_89_<-/imm32/subx-name +16614 1/imm32/rm32-is-first-inout +16615 2/imm32/r32-is-second-inout +16616 0/imm32/no-imm32 +16617 0/imm32/no-imm8 +16618 0/imm32/no-disp32 +16619 1/imm32/output-is-write-only +16620 0x11/imm32/alloc-id:fake +16621 _Primitive-copy-mem-to-reg/imm32/next +16622 _Primitive-copy-mem-to-reg: # (payload primitive) +16623 0x11/imm32/alloc-id:fake:payload +16624 # var1/reg <- copy var2 => 8b/-> var2/rm32 var1/r32 +16625 0x11/imm32/alloc-id:fake +16626 _string-copy/imm32/name +16627 0x11/imm32/alloc-id:fake +16628 Single-int-var-in-mem/imm32/inouts +16629 0x11/imm32/alloc-id:fake +16630 Single-int-var-in-some-register/imm32/outputs +16631 0x11/imm32/alloc-id:fake +16632 _string_8b_->/imm32/subx-name +16633 1/imm32/rm32-is-first-inout +16634 3/imm32/r32-is-first-output +16635 0/imm32/no-imm32 +16636 0/imm32/no-imm8 +16637 0/imm32/no-disp32 +16638 1/imm32/output-is-write-only +16639 0x11/imm32/alloc-id:fake +16640 _Primitive-copy-lit-to-reg/imm32/next +16641 _Primitive-copy-lit-to-reg: # (payload primitive) 16642 0x11/imm32/alloc-id:fake:payload -16643 # "loop-if-!=" -16644 0xa/imm32/size -16645 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -16646 _string-loop-if-addr<: # (payload array byte) -16647 0x11/imm32/alloc-id:fake:payload -16648 # "loop-if-addr<" -16649 0xd/imm32/size -16650 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/< -16651 _string-loop-if-addr<=: # (payload array byte) -16652 0x11/imm32/alloc-id:fake:payload -16653 # "loop-if-addr<=" -16654 0xe/imm32/size -16655 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/= -16656 _string-loop-if-addr>: # (payload array byte) -16657 0x11/imm32/alloc-id:fake:payload -16658 # "loop-if-addr>" -16659 0xd/imm32/size -16660 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/> -16661 _string-loop-if-addr>=: # (payload array byte) -16662 0x11/imm32/alloc-id:fake:payload -16663 # "loop-if-addr>=" -16664 0xe/imm32/size -16665 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/= -16666 _string-multiply: # (payload array byte) -16667 0x11/imm32/alloc-id:fake:payload -16668 # "multiply" -16669 0x8/imm32/size -16670 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y -16671 _string-or: # (payload array byte) -16672 0x11/imm32/alloc-id:fake:payload -16673 # "or" -16674 0x2/imm32/size -16675 0x6f/o 0x72/r -16676 _string-or-with: # (payload array byte) -16677 0x11/imm32/alloc-id:fake:payload -16678 # "or-with" -16679 0x7/imm32/size -16680 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -16681 _string-subtract: # (payload array byte) -16682 0x11/imm32/alloc-id:fake:payload -16683 # "subtract" -16684 0x8/imm32/size -16685 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -16686 _string-subtract-from: # (payload array byte) -16687 0x11/imm32/alloc-id:fake:payload -16688 # "subtract-from" -16689 0xd/imm32/size -16690 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 -16691 _string-xor: # (payload array byte) -16692 0x11/imm32/alloc-id:fake:payload -16693 # "xor" -16694 0x3/imm32/size -16695 0x78/x 0x6f/o 0x72/r -16696 _string-xor-with: # (payload array byte) -16697 0x11/imm32/alloc-id:fake:payload -16698 # "xor-with" -16699 0x8/imm32/size -16700 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -16701 -16702 # string literals for SubX instructions -16703 _string_01_add_to: # (payload array byte) -16704 0x11/imm32/alloc-id:fake:payload -16705 # "01/add-to" -16706 0x9/imm32/size -16707 0x30/0 0x31/1 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o -16708 _string_03_add: # (payload array byte) -16709 0x11/imm32/alloc-id:fake:payload -16710 # "03/add" -16711 0x6/imm32/size -16712 0x30/0 0x33/3 0x2f/slash 0x61/a 0x64/d 0x64/d -16713 _string_05_add_to_eax: # (payload array byte) -16714 0x11/imm32/alloc-id:fake:payload -16715 # "05/add-to-eax" -16716 0xd/imm32/size -16717 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 -16718 _string_09_or_with: # (payload array byte) +16643 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 +16644 0x11/imm32/alloc-id:fake +16645 _string-copy/imm32/name +16646 0x11/imm32/alloc-id:fake +16647 Single-lit-var/imm32/inouts +16648 0x11/imm32/alloc-id:fake +16649 Single-int-var-in-some-register/imm32/outputs +16650 0x11/imm32/alloc-id:fake +16651 _string_c7_subop_copy/imm32/subx-name +16652 3/imm32/rm32-is-first-output +16653 0/imm32/no-r32 +16654 1/imm32/imm32-is-first-inout +16655 0/imm32/no-imm8 +16656 0/imm32/no-disp32 +16657 1/imm32/output-is-write-only +16658 0x11/imm32/alloc-id:fake +16659 _Primitive-copy-lit-to-mem/imm32/next +16660 _Primitive-copy-lit-to-mem: # (payload primitive) +16661 0x11/imm32/alloc-id:fake:payload +16662 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 +16663 0x11/imm32/alloc-id:fake +16664 _string-copy-to/imm32/name +16665 0x11/imm32/alloc-id:fake +16666 Int-var-and-literal/imm32/inouts +16667 0/imm32/no-outputs +16668 0/imm32/no-outputs +16669 0x11/imm32/alloc-id:fake +16670 _string_c7_subop_copy/imm32/subx-name +16671 1/imm32/rm32-is-first-inout +16672 0/imm32/no-r32 +16673 2/imm32/imm32-is-second-inout +16674 0/imm32/no-imm8 +16675 0/imm32/no-disp32 +16676 1/imm32/output-is-write-only +16677 0x11/imm32/alloc-id:fake +16678 _Primitive-copy-byte-from-reg/imm32/next +16679 # - copy byte +16680 _Primitive-copy-byte-from-reg: +16681 0x11/imm32/alloc-id:fake:payload +16682 # var/reg <- copy-byte var2/reg2 => 8a/byte-> %var2 var/r32 +16683 0x11/imm32/alloc-id:fake +16684 _string-copy-byte/imm32/name +16685 0x11/imm32/alloc-id:fake +16686 Single-byte-var-in-some-register/imm32/inouts +16687 0x11/imm32/alloc-id:fake +16688 Single-byte-var-in-some-register/imm32/outputs +16689 0x11/imm32/alloc-id:fake +16690 _string_8a_copy_byte/imm32/subx-name +16691 1/imm32/rm32-is-first-inout +16692 3/imm32/r32-is-first-output +16693 0/imm32/no-imm32 +16694 0/imm32/no-imm8 +16695 0/imm32/no-disp32 +16696 1/imm32/output-is-write-only +16697 0x11/imm32/alloc-id:fake +16698 _Primitive-copy-byte-from-mem/imm32/next +16699 _Primitive-copy-byte-from-mem: +16700 0x11/imm32/alloc-id:fake:payload +16701 # var/reg <- copy-byte *var2/reg2 => 8a/byte-> *var2 var/r32 +16702 0x11/imm32/alloc-id:fake +16703 _string-copy-byte/imm32/name +16704 0x11/imm32/alloc-id:fake +16705 Single-byte-var-in-mem/imm32/inouts +16706 0x11/imm32/alloc-id:fake +16707 Single-byte-var-in-some-register/imm32/outputs +16708 0x11/imm32/alloc-id:fake +16709 _string_8a_copy_byte/imm32/subx-name +16710 1/imm32/rm32-is-first-inout +16711 3/imm32/r32-is-first-output +16712 0/imm32/no-imm32 +16713 0/imm32/no-imm8 +16714 0/imm32/no-disp32 +16715 1/imm32/output-is-write-only +16716 0x11/imm32/alloc-id:fake +16717 _Primitive-copy-byte-to-mem/imm32/next +16718 _Primitive-copy-byte-to-mem: 16719 0x11/imm32/alloc-id:fake:payload -16720 # "09/or-with" -16721 0xa/imm32/size -16722 0x30/0 0x39/9 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -16723 _string_0b_or: # (payload array byte) -16724 0x11/imm32/alloc-id:fake:payload -16725 # "0b/or" -16726 0x5/imm32/size -16727 0x30/0 0x62/b 0x2f/slash 0x6f/o 0x72/r -16728 _string_0d_or_with_eax: # (payload array byte) -16729 0x11/imm32/alloc-id:fake:payload -16730 # "0d/or-with-eax" -16731 0xe/imm32/size -16732 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 -16733 _string_0f_82_jump_label: # (payload array byte) -16734 0x11/imm32/alloc-id:fake:payload -16735 # "0f 82/jump-if-addr<" -16736 0x13/imm32/size -16737 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/< -16738 _string_0f_82_jump_break: # (payload array byte) +16720 # copy-byte-to *var1/reg1, var2/reg2 => 88/byte<- *reg1 reg2/r32 +16721 0x11/imm32/alloc-id:fake +16722 _string-copy-byte-to/imm32/name +16723 0x11/imm32/alloc-id:fake +16724 Two-args-byte-stack-byte-reg/imm32/inouts +16725 0/imm32/no-outputs +16726 0/imm32/no-outputs +16727 0x11/imm32/alloc-id:fake +16728 _string_88_copy_byte/imm32/subx-name +16729 1/imm32/rm32-is-first-inout +16730 2/imm32/r32-is-second-inout +16731 0/imm32/no-imm32 +16732 0/imm32/no-imm8 +16733 0/imm32/no-disp32 +16734 0/imm32/output-is-write-only +16735 0x11/imm32/alloc-id:fake +16736 _Primitive-address/imm32/next +16737 # - address +16738 _Primitive-address: # (payload primitive) 16739 0x11/imm32/alloc-id:fake:payload -16740 # "0f 82/jump-if-addr< break/disp32" -16741 0x20/imm32/size -16742 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 -16743 _string_0f_82_jump_loop: # (payload array byte) -16744 0x11/imm32/alloc-id:fake:payload -16745 # "0f 82/jump-if-addr< loop/disp32" -16746 0x1f/imm32/size -16747 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 -16748 _string_0f_83_jump_label: # (payload array byte) -16749 0x11/imm32/alloc-id:fake:payload -16750 # "0f 83/jump-if-addr>=" -16751 0x14/imm32/size -16752 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/= -16753 _string_0f_83_jump_break: # (payload array byte) -16754 0x11/imm32/alloc-id:fake:payload -16755 # "0f 83/jump-if-addr>= break/disp32" -16756 0x21/imm32/size -16757 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 -16758 _string_0f_83_jump_loop: # (payload array byte) +16740 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32 +16741 0x11/imm32/alloc-id:fake +16742 _string-address/imm32/name +16743 0x11/imm32/alloc-id:fake +16744 Single-int-var-in-mem/imm32/inouts +16745 0x11/imm32/alloc-id:fake +16746 Single-addr-var-in-some-register/imm32/outputs +16747 0x11/imm32/alloc-id:fake +16748 _string_8d_copy_address/imm32/subx-name +16749 1/imm32/rm32-is-first-inout +16750 3/imm32/r32-is-first-output +16751 0/imm32/no-imm32 +16752 0/imm32/no-imm8 +16753 0/imm32/no-disp32 +16754 1/imm32/output-is-write-only +16755 0x11/imm32/alloc-id:fake +16756 _Primitive-compare-reg-with-reg/imm32/next +16757 # - compare +16758 _Primitive-compare-reg-with-reg: # (payload primitive) 16759 0x11/imm32/alloc-id:fake:payload -16760 # "0f 83/jump-if-addr>= loop/disp32" -16761 0x20/imm32/size -16762 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 -16763 _string_0f_84_jump_label: # (payload array byte) -16764 0x11/imm32/alloc-id:fake:payload -16765 # "0f 84/jump-if-=" -16766 0xf/imm32/size -16767 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/= -16768 _string_0f_84_jump_break: # (payload array byte) -16769 0x11/imm32/alloc-id:fake:payload -16770 # "0f 84/jump-if-= break/disp32" -16771 0x1c/imm32/size -16772 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 -16773 _string_0f_84_jump_loop: # (payload array byte) -16774 0x11/imm32/alloc-id:fake:payload -16775 # "0f 84/jump-if-= loop/disp32" -16776 0x1b/imm32/size -16777 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 -16778 _string_0f_85_jump_label: # (payload array byte) -16779 0x11/imm32/alloc-id:fake:payload -16780 # "0f 85/jump-if-!=" -16781 0x10/imm32/size -16782 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/= -16783 _string_0f_85_jump_break: # (payload array byte) -16784 0x11/imm32/alloc-id:fake:payload -16785 # "0f 85/jump-if-!= break/disp32" -16786 0x1d/imm32/size -16787 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 -16788 _string_0f_85_jump_loop: # (payload array byte) -16789 0x11/imm32/alloc-id:fake:payload -16790 # "0f 85/jump-if-!= loop/disp32" -16791 0x1c/imm32/size -16792 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 -16793 _string_0f_86_jump_label: # (payload array byte) -16794 0x11/imm32/alloc-id:fake:payload -16795 # "0f 86/jump-if-addr<=" -16796 0x14/imm32/size -16797 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/= -16798 _string_0f_86_jump_break: # (payload array byte) -16799 0x11/imm32/alloc-id:fake:payload -16800 # "0f 86/jump-if-addr<= break/disp32" -16801 0x21/imm32/size -16802 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 -16803 _string_0f_86_jump_loop: # (payload array byte) -16804 0x11/imm32/alloc-id:fake:payload -16805 # "0f 86/jump-if-addr<= loop/disp32" -16806 0x20/imm32/size -16807 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 -16808 _string_0f_87_jump_label: # (payload array byte) -16809 0x11/imm32/alloc-id:fake:payload -16810 # "0f 87/jump-if-addr>" -16811 0x13/imm32/size -16812 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/> -16813 _string_0f_87_jump_break: # (payload array byte) -16814 0x11/imm32/alloc-id:fake:payload -16815 # "0f 87/jump-if-addr> break/disp32" -16816 0x20/imm32/size -16817 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 -16818 _string_0f_87_jump_loop: # (payload array byte) -16819 0x11/imm32/alloc-id:fake:payload -16820 # "0f 87/jump-if-addr> loop/disp32" -16821 0x1f/imm32/size -16822 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 -16823 _string_0f_8c_jump_label: # (payload array byte) -16824 0x11/imm32/alloc-id:fake:payload -16825 # "0f 8c/jump-if-<" -16826 0xf/imm32/size -16827 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/< -16828 _string_0f_8c_jump_break: # (payload array byte) -16829 0x11/imm32/alloc-id:fake:payload -16830 # "0f 8c/jump-if-< break/disp32" -16831 0x1c/imm32/size -16832 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 -16833 _string_0f_8c_jump_loop: # (payload array byte) -16834 0x11/imm32/alloc-id:fake:payload -16835 # "0f 8c/jump-if-< loop/disp32" -16836 0x1b/imm32/size -16837 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 -16838 _string_0f_8d_jump_label: # (payload array byte) -16839 0x11/imm32/alloc-id:fake:payload -16840 # "0f 8d/jump-if->=" -16841 0x10/imm32/size -16842 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/= -16843 _string_0f_8d_jump_break: # (payload array byte) -16844 0x11/imm32/alloc-id:fake:payload -16845 # "0f 8d/jump-if->= break/disp32" -16846 0x1d/imm32/size -16847 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 -16848 _string_0f_8d_jump_loop: # (payload array byte) -16849 0x11/imm32/alloc-id:fake:payload -16850 # "0f 8d/jump-if->= loop/disp32" -16851 0x1c/imm32/size -16852 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 -16853 _string_0f_8e_jump_label: # (payload array byte) +16760 # compare var1/reg1 var2/reg2 => 39/compare var1/rm32 var2/r32 +16761 0x11/imm32/alloc-id:fake +16762 _string-compare/imm32/name +16763 0x11/imm32/alloc-id:fake +16764 Two-int-args-in-regs/imm32/inouts +16765 0/imm32/no-outputs +16766 0/imm32/no-outputs +16767 0x11/imm32/alloc-id:fake +16768 _string_39_compare->/imm32/subx-name +16769 1/imm32/rm32-is-first-inout +16770 2/imm32/r32-is-second-inout +16771 0/imm32/no-imm32 +16772 0/imm32/no-imm8 +16773 0/imm32/no-disp32 +16774 0/imm32/output-is-write-only +16775 0x11/imm32/alloc-id:fake +16776 _Primitive-compare-mem-with-reg/imm32/next +16777 _Primitive-compare-mem-with-reg: # (payload primitive) +16778 0x11/imm32/alloc-id:fake:payload +16779 # compare var1 var2/reg => 39/compare var1/rm32 var2/r32 +16780 0x11/imm32/alloc-id:fake +16781 _string-compare/imm32/name +16782 0x11/imm32/alloc-id:fake +16783 Two-args-int-stack-int-reg/imm32/inouts +16784 0/imm32/no-outputs +16785 0/imm32/no-outputs +16786 0x11/imm32/alloc-id:fake +16787 _string_39_compare->/imm32/subx-name +16788 1/imm32/rm32-is-first-inout +16789 2/imm32/r32-is-second-inout +16790 0/imm32/no-imm32 +16791 0/imm32/no-imm8 +16792 0/imm32/no-disp32 +16793 0/imm32/output-is-write-only +16794 0x11/imm32/alloc-id:fake +16795 _Primitive-compare-reg-with-mem/imm32/next +16796 _Primitive-compare-reg-with-mem: # (payload primitive) +16797 0x11/imm32/alloc-id:fake:payload +16798 # compare var1/reg var2 => 3b/compare<- var2/rm32 var1/r32 +16799 0x11/imm32/alloc-id:fake +16800 _string-compare/imm32/name +16801 0x11/imm32/alloc-id:fake +16802 Two-args-int-reg-int-stack/imm32/inouts +16803 0/imm32/no-outputs +16804 0/imm32/no-outputs +16805 0x11/imm32/alloc-id:fake +16806 _string_3b_compare<-/imm32/subx-name +16807 2/imm32/rm32-is-second-inout +16808 1/imm32/r32-is-first-inout +16809 0/imm32/no-imm32 +16810 0/imm32/no-imm8 +16811 0/imm32/no-disp32 +16812 0/imm32/output-is-write-only +16813 0x11/imm32/alloc-id:fake +16814 _Primitive-compare-eax-with-literal/imm32/next +16815 _Primitive-compare-eax-with-literal: # (payload primitive) +16816 0x11/imm32/alloc-id:fake:payload +16817 # compare var1/eax n => 3d/compare-eax-with n/imm32 +16818 0x11/imm32/alloc-id:fake +16819 _string-compare/imm32/name +16820 0x11/imm32/alloc-id:fake +16821 Two-args-int-eax-int-literal/imm32/inouts +16822 0/imm32/no-outputs +16823 0/imm32/no-outputs +16824 0x11/imm32/alloc-id:fake +16825 _string_3d_compare_eax_with/imm32/subx-name +16826 0/imm32/no-rm32 +16827 0/imm32/no-r32 +16828 2/imm32/imm32-is-second-inout +16829 0/imm32/no-imm8 +16830 0/imm32/no-disp32 +16831 0/imm32/output-is-write-only +16832 0x11/imm32/alloc-id:fake +16833 _Primitive-compare-reg-with-literal/imm32/next +16834 _Primitive-compare-reg-with-literal: # (payload primitive) +16835 0x11/imm32/alloc-id:fake:payload +16836 # compare var1/reg n => 81 7/subop/compare %reg n/imm32 +16837 0x11/imm32/alloc-id:fake +16838 _string-compare/imm32/name +16839 0x11/imm32/alloc-id:fake +16840 Int-var-in-register-and-literal/imm32/inouts +16841 0/imm32/no-outputs +16842 0/imm32/no-outputs +16843 0x11/imm32/alloc-id:fake +16844 _string_81_subop_compare/imm32/subx-name +16845 1/imm32/rm32-is-first-inout +16846 0/imm32/no-r32 +16847 2/imm32/imm32-is-second-inout +16848 0/imm32/no-imm8 +16849 0/imm32/no-disp32 +16850 0/imm32/output-is-write-only +16851 0x11/imm32/alloc-id:fake +16852 _Primitive-compare-mem-with-literal/imm32/next +16853 _Primitive-compare-mem-with-literal: # (payload primitive) 16854 0x11/imm32/alloc-id:fake:payload -16855 # "0f 8e/jump-if-<=" -16856 0x10/imm32/size -16857 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/= -16858 _string_0f_8e_jump_break: # (payload array byte) -16859 0x11/imm32/alloc-id:fake:payload -16860 # "0f 8e/jump-if-<= break/disp32" -16861 0x1d/imm32/size -16862 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 -16863 _string_0f_8e_jump_loop: # (payload array byte) -16864 0x11/imm32/alloc-id:fake:payload -16865 # "0f 8e/jump-if-<= loop/disp32" -16866 0x1c/imm32/size -16867 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 -16868 _string_0f_8f_jump_label: # (payload array byte) -16869 0x11/imm32/alloc-id:fake:payload -16870 # "0f 8f/jump-if->" -16871 0xf/imm32/size -16872 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/> -16873 _string_0f_8f_jump_break: # (payload array byte) +16855 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32 +16856 0x11/imm32/alloc-id:fake +16857 _string-compare/imm32/name +16858 0x11/imm32/alloc-id:fake +16859 Int-var-and-literal/imm32/inouts +16860 0/imm32/no-outputs +16861 0/imm32/no-outputs +16862 0x11/imm32/alloc-id:fake +16863 _string_81_subop_compare/imm32/subx-name +16864 1/imm32/rm32-is-first-inout +16865 0/imm32/no-r32 +16866 2/imm32/imm32-is-second-inout +16867 0/imm32/no-imm8 +16868 0/imm32/no-disp32 +16869 0/imm32/output-is-write-only +16870 0x11/imm32/alloc-id:fake +16871 _Primitive-multiply-reg-by-reg/imm32/next +16872 # - multiply +16873 _Primitive-multiply-reg-by-reg: # (payload primitive) 16874 0x11/imm32/alloc-id:fake:payload -16875 # "0f 8f/jump-if-> break/disp32" -16876 0x1c/imm32/size -16877 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 -16878 _string_0f_8f_jump_loop: # (payload array byte) -16879 0x11/imm32/alloc-id:fake:payload -16880 # "0f 8f/jump-if-> loop/disp32" -16881 0x1b/imm32/size -16882 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 -16883 _string_0f_af_multiply: # (payload array byte) -16884 0x11/imm32/alloc-id:fake:payload -16885 # "0f af/multiply" -16886 0xe/imm32/size -16887 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 -16888 _string_21_and_with: # (payload array byte) -16889 0x11/imm32/alloc-id:fake:payload -16890 # "21/and-with" -16891 0xb/imm32/size -16892 0x32/2 0x31/1 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -16893 _string_23_and: # (payload array byte) -16894 0x11/imm32/alloc-id:fake:payload -16895 # "23/and" -16896 0x6/imm32/size -16897 0x32/2 0x33/3 0x2f/slash 0x61/a 0x6e/n 0x64/d -16898 _string_25_and_with_eax: # (payload array byte) -16899 0x11/imm32/alloc-id:fake:payload -16900 # "25/and-with-eax" -16901 0xf/imm32/size -16902 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 -16903 _string_29_subtract_from: # (payload array byte) -16904 0x11/imm32/alloc-id:fake:payload -16905 # "29/subtract-from" -16906 0x10/imm32/size -16907 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 -16908 _string_2b_subtract: # (payload array byte) -16909 0x11/imm32/alloc-id:fake:payload -16910 # "2b/subtract" -16911 0xb/imm32/size -16912 0x32/2 0x62/b 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -16913 _string_2d_subtract_from_eax: # (payload array byte) -16914 0x11/imm32/alloc-id:fake:payload -16915 # "2d/subtract-from-eax" -16916 0x14/imm32/size -16917 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 -16918 _string_31_xor_with: # (payload array byte) -16919 0x11/imm32/alloc-id:fake:payload -16920 # "31/xor-with" -16921 0xb/imm32/size -16922 0x33/3 0x31/1 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -16923 _string_33_xor: # (payload array byte) -16924 0x11/imm32/alloc-id:fake:payload -16925 # "33/xor" -16926 0x6/imm32/size -16927 0x33/3 0x33/3 0x2f/slash 0x78/x 0x6f/o 0x72/r -16928 _string_35_xor_with_eax: # (payload array byte) -16929 0x11/imm32/alloc-id:fake:payload -16930 # "35/xor-with-eax" -16931 0xf/imm32/size -16932 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 -16933 _string_39_compare->: # (payload array byte) -16934 0x11/imm32/alloc-id:fake:payload -16935 # "39/compare->" -16936 0xc/imm32/size -16937 0x33/3 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x3e/> -16938 _string_3b_compare<-: # (payload array byte) -16939 0x11/imm32/alloc-id:fake:payload -16940 # "3b/compare<-" -16941 0xc/imm32/size -16942 0x33/3 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x3c/< 0x2d/dash -16943 _string_3d_compare_eax_with: # (payload array byte) -16944 0x11/imm32/alloc-id:fake:payload -16945 # "3d/compare-eax-with" -16946 0x13/imm32/size -16947 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 -16948 _string_40_increment_eax: # (payload array byte) +16875 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 +16876 0x11/imm32/alloc-id:fake +16877 _string-multiply/imm32/name +16878 0x11/imm32/alloc-id:fake +16879 Single-int-var-in-some-register/imm32/inouts +16880 0x11/imm32/alloc-id:fake +16881 Single-int-var-in-some-register/imm32/outputs +16882 0x11/imm32/alloc-id:fake +16883 _string_0f_af_multiply/imm32/subx-name +16884 1/imm32/rm32-is-first-inout +16885 3/imm32/r32-is-first-output +16886 0/imm32/no-imm32 +16887 0/imm32/no-imm8 +16888 0/imm32/no-disp32 +16889 0/imm32/output-is-write-only +16890 0x11/imm32/alloc-id:fake +16891 _Primitive-multiply-reg-by-mem/imm32/next +16892 _Primitive-multiply-reg-by-mem: # (payload primitive) +16893 0x11/imm32/alloc-id:fake:payload +16894 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 +16895 0x11/imm32/alloc-id:fake +16896 _string-multiply/imm32/name +16897 0x11/imm32/alloc-id:fake +16898 Single-int-var-in-mem/imm32/inouts +16899 0x11/imm32/alloc-id:fake +16900 Single-int-var-in-some-register/imm32/outputs +16901 0x11/imm32/alloc-id:fake +16902 _string_0f_af_multiply/imm32/subx-name +16903 1/imm32/rm32-is-first-inout +16904 3/imm32/r32-is-first-output +16905 0/imm32/no-imm32 +16906 0/imm32/no-imm8 +16907 0/imm32/no-disp32 +16908 0/imm32/output-is-write-only +16909 0x11/imm32/alloc-id:fake +16910 _Primitive-break-if-addr</imm32/next +16911 # - branches +16912 _Primitive-break-if-addr<: # (payload primitive) +16913 0x11/imm32/alloc-id:fake:payload +16914 0x11/imm32/alloc-id:fake +16915 _string-break-if-addr</imm32/name +16916 0/imm32/no-inouts +16917 0/imm32/no-inouts +16918 0/imm32/no-outputs +16919 0/imm32/no-outputs +16920 0x11/imm32/alloc-id:fake +16921 _string_0f_82_jump_break/imm32/subx-name +16922 0/imm32/no-rm32 +16923 0/imm32/no-r32 +16924 0/imm32/no-imm32 +16925 0/imm32/no-imm8 +16926 0/imm32/no-disp32 +16927 0/imm32/no-output +16928 0x11/imm32/alloc-id:fake +16929 _Primitive-break-if-addr>=/imm32/next +16930 _Primitive-break-if-addr>=: # (payload primitive) +16931 0x11/imm32/alloc-id:fake:payload +16932 0x11/imm32/alloc-id:fake +16933 _string-break-if-addr>=/imm32/name +16934 0/imm32/no-inouts +16935 0/imm32/no-inouts +16936 0/imm32/no-outputs +16937 0/imm32/no-outputs +16938 0x11/imm32/alloc-id:fake +16939 _string_0f_83_jump_break/imm32/subx-name +16940 0/imm32/no-rm32 +16941 0/imm32/no-r32 +16942 0/imm32/no-imm32 +16943 0/imm32/no-imm8 +16944 0/imm32/no-disp32 +16945 0/imm32/no-output +16946 0x11/imm32/alloc-id:fake +16947 _Primitive-break-if-=/imm32/next +16948 _Primitive-break-if-=: # (payload primitive) 16949 0x11/imm32/alloc-id:fake:payload -16950 # "40/increment-eax" -16951 0x10/imm32/size -16952 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 -16953 _string_41_increment_ecx: # (payload array byte) -16954 0x11/imm32/alloc-id:fake:payload -16955 # "41/increment-ecx" -16956 0x10/imm32/size -16957 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 -16958 _string_42_increment_edx: # (payload array byte) -16959 0x11/imm32/alloc-id:fake:payload -16960 # "42/increment-edx" -16961 0x10/imm32/size -16962 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 -16963 _string_43_increment_ebx: # (payload array byte) -16964 0x11/imm32/alloc-id:fake:payload -16965 # "43/increment-ebx" -16966 0x10/imm32/size -16967 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 -16968 _string_46_increment_esi: # (payload array byte) -16969 0x11/imm32/alloc-id:fake:payload -16970 # "46/increment-esi" -16971 0x10/imm32/size -16972 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 -16973 _string_47_increment_edi: # (payload array byte) -16974 0x11/imm32/alloc-id:fake:payload -16975 # "47/increment-edi" -16976 0x10/imm32/size -16977 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 -16978 _string_48_decrement_eax: # (payload array byte) -16979 0x11/imm32/alloc-id:fake:payload -16980 # "48/decrement-eax" -16981 0x10/imm32/size -16982 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 -16983 _string_49_decrement_ecx: # (payload array byte) -16984 0x11/imm32/alloc-id:fake:payload -16985 # "49/decrement-ecx" -16986 0x10/imm32/size -16987 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 -16988 _string_4a_decrement_edx: # (payload array byte) -16989 0x11/imm32/alloc-id:fake:payload -16990 # "4a/decrement-edx" -16991 0x10/imm32/size -16992 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 -16993 _string_4b_decrement_ebx: # (payload array byte) -16994 0x11/imm32/alloc-id:fake:payload -16995 # "4b/decrement-ebx" -16996 0x10/imm32/size -16997 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 -16998 _string_4e_decrement_esi: # (payload array byte) -16999 0x11/imm32/alloc-id:fake:payload -17000 # "4e/decrement-esi" -17001 0x10/imm32/size -17002 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 -17003 _string_4f_decrement_edi: # (payload array byte) -17004 0x11/imm32/alloc-id:fake:payload -17005 # "4f/decrement-edi" -17006 0x10/imm32/size -17007 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 -17008 _string_81_subop_add: # (payload array byte) -17009 0x11/imm32/alloc-id:fake:payload -17010 # "81 0/subop/add" -17011 0xe/imm32/size -17012 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 -17013 _string_81_subop_or: # (payload array byte) -17014 0x11/imm32/alloc-id:fake:payload -17015 # "81 1/subop/or" -17016 0xd/imm32/size -17017 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 -17018 _string_81_subop_and: # (payload array byte) -17019 0x11/imm32/alloc-id:fake:payload -17020 # "81 4/subop/and" -17021 0xe/imm32/size -17022 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 -17023 _string_81_subop_subtract: # (payload array byte) -17024 0x11/imm32/alloc-id:fake:payload -17025 # "81 5/subop/subtract" -17026 0x13/imm32/size -17027 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 -17028 _string_81_subop_xor: # (payload array byte) -17029 0x11/imm32/alloc-id:fake:payload -17030 # "81 6/subop/xor" -17031 0xe/imm32/size -17032 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 -17033 _string_81_subop_compare: # (payload array byte) -17034 0x11/imm32/alloc-id:fake:payload -17035 # "81 7/subop/compare" -17036 0x12/imm32/size -17037 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 -17038 _string_89_<-: # (payload array byte) +16950 0x11/imm32/alloc-id:fake +16951 _string-break-if-=/imm32/name +16952 0/imm32/no-inouts +16953 0/imm32/no-inouts +16954 0/imm32/no-outputs +16955 0/imm32/no-outputs +16956 0x11/imm32/alloc-id:fake +16957 _string_0f_84_jump_break/imm32/subx-name +16958 0/imm32/no-rm32 +16959 0/imm32/no-r32 +16960 0/imm32/no-imm32 +16961 0/imm32/no-imm8 +16962 0/imm32/no-disp32 +16963 0/imm32/no-output +16964 0x11/imm32/alloc-id:fake +16965 _Primitive-break-if-!=/imm32/next +16966 _Primitive-break-if-!=: # (payload primitive) +16967 0x11/imm32/alloc-id:fake:payload +16968 0x11/imm32/alloc-id:fake +16969 _string-break-if-!=/imm32/name +16970 0/imm32/no-inouts +16971 0/imm32/no-inouts +16972 0/imm32/no-outputs +16973 0/imm32/no-outputs +16974 0x11/imm32/alloc-id:fake +16975 _string_0f_85_jump_break/imm32/subx-name +16976 0/imm32/no-rm32 +16977 0/imm32/no-r32 +16978 0/imm32/no-imm32 +16979 0/imm32/no-imm8 +16980 0/imm32/no-disp32 +16981 0/imm32/no-output +16982 0x11/imm32/alloc-id:fake +16983 _Primitive-break-if-addr<=/imm32/next +16984 _Primitive-break-if-addr<=: # (payload primitive) +16985 0x11/imm32/alloc-id:fake:payload +16986 0x11/imm32/alloc-id:fake +16987 _string-break-if-addr<=/imm32/name +16988 0/imm32/no-inouts +16989 0/imm32/no-inouts +16990 0/imm32/no-outputs +16991 0/imm32/no-outputs +16992 0x11/imm32/alloc-id:fake +16993 _string_0f_86_jump_break/imm32/subx-name +16994 0/imm32/no-rm32 +16995 0/imm32/no-r32 +16996 0/imm32/no-imm32 +16997 0/imm32/no-imm8 +16998 0/imm32/no-disp32 +16999 0/imm32/no-output +17000 0x11/imm32/alloc-id:fake +17001 _Primitive-break-if-addr>/imm32/next +17002 _Primitive-break-if-addr>: # (payload primitive) +17003 0x11/imm32/alloc-id:fake:payload +17004 0x11/imm32/alloc-id:fake +17005 _string-break-if-addr>/imm32/name +17006 0/imm32/no-inouts +17007 0/imm32/no-inouts +17008 0/imm32/no-outputs +17009 0/imm32/no-outputs +17010 0x11/imm32/alloc-id:fake +17011 _string_0f_87_jump_break/imm32/subx-name +17012 0/imm32/no-rm32 +17013 0/imm32/no-r32 +17014 0/imm32/no-imm32 +17015 0/imm32/no-imm8 +17016 0/imm32/no-disp32 +17017 0/imm32/no-output +17018 0x11/imm32/alloc-id:fake +17019 _Primitive-break-if-</imm32/next +17020 _Primitive-break-if-<: # (payload primitive) +17021 0x11/imm32/alloc-id:fake:payload +17022 0x11/imm32/alloc-id:fake +17023 _string-break-if-</imm32/name +17024 0/imm32/no-inouts +17025 0/imm32/no-inouts +17026 0/imm32/no-outputs +17027 0/imm32/no-outputs +17028 0x11/imm32/alloc-id:fake +17029 _string_0f_8c_jump_break/imm32/subx-name +17030 0/imm32/no-rm32 +17031 0/imm32/no-r32 +17032 0/imm32/no-imm32 +17033 0/imm32/no-imm8 +17034 0/imm32/no-disp32 +17035 0/imm32/no-output +17036 0x11/imm32/alloc-id:fake +17037 _Primitive-break-if->=/imm32/next +17038 _Primitive-break-if->=: # (payload primitive) 17039 0x11/imm32/alloc-id:fake:payload -17040 # "89/<-" -17041 0x5/imm32/size -17042 0x38/8 0x39/9 0x2f/slash 0x3c/< 0x2d/dash -17043 _string_8b_->: # (payload array byte) -17044 0x11/imm32/alloc-id:fake:payload -17045 # "8b/->" -17046 0x5/imm32/size -17047 0x38/8 0x62/b 0x2f/slash 0x2d/dash 0x3e/> -17048 _string_8a_copy_byte: -17049 0x11/imm32/alloc-id:fake:payload -17050 # "8a/byte->" -17051 0x9/imm32/size -17052 0x38/8 0x61/a 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x3e/> -17053 _string_88_copy_byte: -17054 0x11/imm32/alloc-id:fake:payload -17055 # "88/byte<-" -17056 0x9/imm32/size -17057 0x38/8 0x38/8 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/- -17058 _string_8d_copy_address: # (payload array byte) -17059 0x11/imm32/alloc-id:fake:payload -17060 # "8d/copy-address" -17061 0xf/imm32/size -17062 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 -17063 _string_b8_copy_to_eax: # (payload array byte) -17064 0x11/imm32/alloc-id:fake:payload -17065 # "b8/copy-to-eax" -17066 0xe/imm32/size -17067 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 -17068 _string_b9_copy_to_ecx: # (payload array byte) -17069 0x11/imm32/alloc-id:fake:payload -17070 # "b9/copy-to-ecx" -17071 0xe/imm32/size -17072 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 -17073 _string_ba_copy_to_edx: # (payload array byte) -17074 0x11/imm32/alloc-id:fake:payload -17075 # "ba/copy-to-edx" -17076 0xe/imm32/size -17077 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 -17078 _string_bb_copy_to_ebx: # (payload array byte) -17079 0x11/imm32/alloc-id:fake:payload -17080 # "bb/copy-to-ebx" -17081 0xe/imm32/size -17082 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 -17083 _string_be_copy_to_esi: # (payload array byte) -17084 0x11/imm32/alloc-id:fake:payload -17085 # "be/copy-to-esi" -17086 0xe/imm32/size -17087 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 -17088 _string_bf_copy_to_edi: # (payload array byte) -17089 0x11/imm32/alloc-id:fake:payload -17090 # "bf/copy-to-edi" -17091 0xe/imm32/size -17092 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 -17093 _string_c7_subop_copy: # (payload array byte) -17094 0x11/imm32/alloc-id:fake:payload -17095 # "c7 0/subop/copy" -17096 0xf/imm32/size -17097 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 -17098 _string_e9_jump_label: # (payload array byte) -17099 0x11/imm32/alloc-id:fake:payload -17100 # "e9/jump" -17101 0x7/imm32/size -17102 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p -17103 _string_e9_jump_break: # (payload array byte) -17104 0x11/imm32/alloc-id:fake:payload -17105 # "e9/jump break/disp32" -17106 0x14/imm32/size -17107 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 -17108 _string_e9_jump_loop: # (payload array byte) -17109 0x11/imm32/alloc-id:fake:payload -17110 # "e9/jump loop/disp32" -17111 0x13/imm32/size -17112 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 -17113 _string_ff_subop_increment: # (payload array byte) -17114 0x11/imm32/alloc-id:fake:payload -17115 # "ff 0/subop/increment" -17116 0x14/imm32/size -17117 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 -17118 _string_ff_subop_decrement: # (payload array byte) -17119 0x11/imm32/alloc-id:fake:payload -17120 # "ff 1/subop/decrement" -17121 0x14/imm32/size -17122 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 -17123 -17124 Single-int-var-in-mem: # (payload list var) -17125 0x11/imm32/alloc-id:fake:payload +17040 0x11/imm32/alloc-id:fake +17041 _string-break-if->=/imm32/name +17042 0/imm32/no-inouts +17043 0/imm32/no-inouts +17044 0/imm32/no-outputs +17045 0/imm32/no-outputs +17046 0x11/imm32/alloc-id:fake +17047 _string_0f_8d_jump_break/imm32/subx-name +17048 0/imm32/no-rm32 +17049 0/imm32/no-r32 +17050 0/imm32/no-imm32 +17051 0/imm32/no-imm8 +17052 0/imm32/no-disp32 +17053 0/imm32/no-output +17054 0x11/imm32/alloc-id:fake +17055 _Primitive-break-if-<=/imm32/next +17056 _Primitive-break-if-<=: # (payload primitive) +17057 0x11/imm32/alloc-id:fake:payload +17058 0x11/imm32/alloc-id:fake +17059 _string-break-if-<=/imm32/name +17060 0/imm32/no-inouts +17061 0/imm32/no-inouts +17062 0/imm32/no-outputs +17063 0/imm32/no-outputs +17064 0x11/imm32/alloc-id:fake +17065 _string_0f_8e_jump_break/imm32/subx-name +17066 0/imm32/no-rm32 +17067 0/imm32/no-r32 +17068 0/imm32/no-imm32 +17069 0/imm32/no-imm8 +17070 0/imm32/no-disp32 +17071 0/imm32/no-output +17072 0x11/imm32/alloc-id:fake +17073 _Primitive-break-if->/imm32/next +17074 _Primitive-break-if->: # (payload primitive) +17075 0x11/imm32/alloc-id:fake:payload +17076 0x11/imm32/alloc-id:fake +17077 _string-break-if->/imm32/name +17078 0/imm32/no-inouts +17079 0/imm32/no-inouts +17080 0/imm32/no-outputs +17081 0/imm32/no-outputs +17082 0x11/imm32/alloc-id:fake +17083 _string_0f_8f_jump_break/imm32/subx-name +17084 0/imm32/no-rm32 +17085 0/imm32/no-r32 +17086 0/imm32/no-imm32 +17087 0/imm32/no-imm8 +17088 0/imm32/no-disp32 +17089 0/imm32/no-output +17090 0x11/imm32/alloc-id:fake +17091 _Primitive-break/imm32/next +17092 _Primitive-break: # (payload primitive) +17093 0x11/imm32/alloc-id:fake:payload +17094 0x11/imm32/alloc-id:fake +17095 _string-break/imm32/name +17096 0/imm32/no-inouts +17097 0/imm32/no-inouts +17098 0/imm32/no-outputs +17099 0/imm32/no-outputs +17100 0x11/imm32/alloc-id:fake +17101 _string_e9_jump_break/imm32/subx-name +17102 0/imm32/no-rm32 +17103 0/imm32/no-r32 +17104 0/imm32/no-imm32 +17105 0/imm32/no-imm8 +17106 0/imm32/no-disp32 +17107 0/imm32/no-output +17108 0x11/imm32/alloc-id:fake +17109 _Primitive-loop-if-addr</imm32/next +17110 _Primitive-loop-if-addr<: # (payload primitive) +17111 0x11/imm32/alloc-id:fake:payload +17112 0x11/imm32/alloc-id:fake +17113 _string-loop-if-addr</imm32/name +17114 0/imm32/no-inouts +17115 0/imm32/no-inouts +17116 0/imm32/no-outputs +17117 0/imm32/no-outputs +17118 0x11/imm32/alloc-id:fake +17119 _string_0f_82_jump_loop/imm32/subx-name +17120 0/imm32/no-rm32 +17121 0/imm32/no-r32 +17122 0/imm32/no-imm32 +17123 0/imm32/no-imm8 +17124 0/imm32/no-disp32 +17125 0/imm32/no-output 17126 0x11/imm32/alloc-id:fake -17127 Int-var-in-mem/imm32 -17128 0/imm32/next -17129 0/imm32/next -17130 -17131 Int-var-in-mem: # (payload var) -17132 0x11/imm32/alloc-id:fake:payload -17133 0/imm32/name -17134 0/imm32/name -17135 0x11/imm32/alloc-id:fake -17136 Type-int/imm32 -17137 1/imm32/some-block-depth -17138 1/imm32/some-stack-offset -17139 0/imm32/no-register -17140 0/imm32/no-register -17141 -17142 # Not really legal, but closest we can currently represent a dereference of an (addr byte) -17143 Single-byte-var-in-mem: # (payload list var) -17144 0x11/imm32/alloc-id:fake:payload -17145 0x11/imm32/alloc-id:fake -17146 Byte-var-in-mem/imm32 -17147 0/imm32/next -17148 0/imm32/next -17149 -17150 # Not really legal, but closest we can currently represent a dereference of an (addr byte) -17151 Byte-var-in-mem: # (payload var) -17152 0x11/imm32/alloc-id:fake:payload -17153 0/imm32/name -17154 0/imm32/name -17155 0x11/imm32/alloc-id:fake -17156 Type-byte/imm32 -17157 1/imm32/some-block-depth -17158 1/imm32/some-stack-offset -17159 0/imm32/no-register -17160 0/imm32/no-register -17161 -17162 Two-args-int-stack-int-reg: # (payload list var) -17163 0x11/imm32/alloc-id:fake:payload -17164 0x11/imm32/alloc-id:fake -17165 Int-var-in-mem/imm32 +17127 _Primitive-loop-if-addr>=/imm32/next +17128 _Primitive-loop-if-addr>=: # (payload primitive) +17129 0x11/imm32/alloc-id:fake:payload +17130 0x11/imm32/alloc-id:fake +17131 _string-loop-if-addr>=/imm32/name +17132 0/imm32/no-inouts +17133 0/imm32/no-inouts +17134 0/imm32/no-outputs +17135 0/imm32/no-outputs +17136 0x11/imm32/alloc-id:fake +17137 _string_0f_83_jump_loop/imm32/subx-name +17138 0/imm32/no-rm32 +17139 0/imm32/no-r32 +17140 0/imm32/no-imm32 +17141 0/imm32/no-imm8 +17142 0/imm32/no-disp32 +17143 0/imm32/no-output +17144 0x11/imm32/alloc-id:fake +17145 _Primitive-loop-if-=/imm32/next +17146 _Primitive-loop-if-=: # (payload primitive) +17147 0x11/imm32/alloc-id:fake:payload +17148 0x11/imm32/alloc-id:fake +17149 _string-loop-if-=/imm32/name +17150 0/imm32/no-inouts +17151 0/imm32/no-inouts +17152 0/imm32/no-outputs +17153 0/imm32/no-outputs +17154 0x11/imm32/alloc-id:fake +17155 _string_0f_84_jump_loop/imm32/subx-name +17156 0/imm32/no-rm32 +17157 0/imm32/no-r32 +17158 0/imm32/no-imm32 +17159 0/imm32/no-imm8 +17160 0/imm32/no-disp32 +17161 0/imm32/no-output +17162 0x11/imm32/alloc-id:fake +17163 _Primitive-loop-if-!=/imm32/next +17164 _Primitive-loop-if-!=: # (payload primitive) +17165 0x11/imm32/alloc-id:fake:payload 17166 0x11/imm32/alloc-id:fake -17167 Single-int-var-in-some-register/imm32/next -17168 -17169 Two-int-args-in-regs: # (payload list var) -17170 0x11/imm32/alloc-id:fake:payload -17171 0x11/imm32/alloc-id:fake -17172 Int-var-in-some-register/imm32 -17173 0x11/imm32/alloc-id:fake -17174 Single-int-var-in-some-register/imm32/next -17175 -17176 # Not really legal, but closest we can currently represent a dereference of an (addr byte) -17177 Two-args-byte-stack-byte-reg: # (payload list var) -17178 0x11/imm32/alloc-id:fake:payload -17179 0x11/imm32/alloc-id:fake -17180 Byte-var-in-mem/imm32 -17181 0x11/imm32/alloc-id:fake -17182 Single-byte-var-in-some-register/imm32/next -17183 -17184 Two-args-int-reg-int-stack: # (payload list var) -17185 0x11/imm32/alloc-id:fake:payload -17186 0x11/imm32/alloc-id:fake -17187 Int-var-in-some-register/imm32 -17188 0x11/imm32/alloc-id:fake -17189 Single-int-var-in-mem/imm32/next -17190 -17191 Two-args-int-eax-int-literal: # (payload list var) -17192 0x11/imm32/alloc-id:fake:payload -17193 0x11/imm32/alloc-id:fake -17194 Int-var-in-eax/imm32 -17195 0x11/imm32/alloc-id:fake -17196 Single-lit-var/imm32/next -17197 -17198 Int-var-and-literal: # (payload list var) -17199 0x11/imm32/alloc-id:fake:payload -17200 0x11/imm32/alloc-id:fake -17201 Int-var-in-mem/imm32 +17167 _string-loop-if-!=/imm32/name +17168 0/imm32/no-inouts +17169 0/imm32/no-inouts +17170 0/imm32/no-outputs +17171 0/imm32/no-outputs +17172 0x11/imm32/alloc-id:fake +17173 _string_0f_85_jump_loop/imm32/subx-name +17174 0/imm32/no-rm32 +17175 0/imm32/no-r32 +17176 0/imm32/no-imm32 +17177 0/imm32/no-imm8 +17178 0/imm32/no-disp32 +17179 0/imm32/no-output +17180 0x11/imm32/alloc-id:fake +17181 _Primitive-loop-if-addr<=/imm32/next +17182 _Primitive-loop-if-addr<=: # (payload primitive) +17183 0x11/imm32/alloc-id:fake:payload +17184 0x11/imm32/alloc-id:fake +17185 _string-loop-if-addr<=/imm32/name +17186 0/imm32/no-inouts +17187 0/imm32/no-inouts +17188 0/imm32/no-outputs +17189 0/imm32/no-outputs +17190 0x11/imm32/alloc-id:fake +17191 _string_0f_86_jump_loop/imm32/subx-name +17192 0/imm32/no-rm32 +17193 0/imm32/no-r32 +17194 0/imm32/no-imm32 +17195 0/imm32/no-imm8 +17196 0/imm32/no-disp32 +17197 0/imm32/no-output +17198 0x11/imm32/alloc-id:fake +17199 _Primitive-loop-if-addr>/imm32/next +17200 _Primitive-loop-if-addr>: # (payload primitive) +17201 0x11/imm32/alloc-id:fake:payload 17202 0x11/imm32/alloc-id:fake -17203 Single-lit-var/imm32/next -17204 -17205 Int-var-in-register-and-literal: # (payload list var) -17206 0x11/imm32/alloc-id:fake:payload -17207 0x11/imm32/alloc-id:fake -17208 Int-var-in-some-register/imm32 -17209 0x11/imm32/alloc-id:fake -17210 Single-lit-var/imm32/next -17211 -17212 Single-int-var-in-some-register: # (payload list var) -17213 0x11/imm32/alloc-id:fake:payload -17214 0x11/imm32/alloc-id:fake -17215 Int-var-in-some-register/imm32 -17216 0/imm32/next -17217 0/imm32/next -17218 -17219 Single-addr-var-in-some-register: # (payload list var) -17220 0x11/imm32/alloc-id:fake:payload -17221 0x11/imm32/alloc-id:fake -17222 Addr-var-in-some-register/imm32 -17223 0/imm32/next -17224 0/imm32/next -17225 -17226 Single-byte-var-in-some-register: # (payload list var) -17227 0x11/imm32/alloc-id:fake:payload -17228 0x11/imm32/alloc-id:fake -17229 Byte-var-in-some-register/imm32 -17230 0/imm32/next -17231 0/imm32/next -17232 -17233 Int-var-in-some-register: # (payload var) -17234 0x11/imm32/alloc-id:fake:payload -17235 0/imm32/name -17236 0/imm32/name -17237 0x11/imm32/alloc-id:fake -17238 Type-int/imm32 -17239 1/imm32/some-block-depth -17240 0/imm32/no-stack-offset -17241 0x11/imm32/alloc-id:fake -17242 Any-register/imm32 -17243 -17244 Any-register: # (payload array byte) -17245 0x11/imm32/alloc-id:fake:payload -17246 1/imm32/size -17247 # data -17248 2a/asterisk -17249 -17250 Addr-var-in-some-register: # (payload var) -17251 0x11/imm32/alloc-id:fake:payload -17252 0/imm32/name -17253 0/imm32/name -17254 0x11/imm32/alloc-id:fake -17255 Type-addr/imm32 -17256 1/imm32/some-block-depth -17257 0/imm32/no-stack-offset -17258 0x11/imm32/alloc-id:fake -17259 Any-register/imm32 -17260 -17261 Byte-var-in-some-register: # (payload var) -17262 0x11/imm32/alloc-id:fake:payload -17263 0/imm32/name -17264 0/imm32/name -17265 0x11/imm32/alloc-id:fake -17266 Type-byte/imm32 -17267 1/imm32/some-block-depth -17268 0/imm32/no-stack-offset -17269 0x11/imm32/alloc-id:fake -17270 Any-register/imm32 -17271 -17272 Single-int-var-in-eax: # (payload list var) +17203 _string-loop-if-addr>/imm32/name +17204 0/imm32/no-inouts +17205 0/imm32/no-inouts +17206 0/imm32/no-outputs +17207 0/imm32/no-outputs +17208 0x11/imm32/alloc-id:fake +17209 _string_0f_87_jump_loop/imm32/subx-name +17210 0/imm32/no-rm32 +17211 0/imm32/no-r32 +17212 0/imm32/no-imm32 +17213 0/imm32/no-imm8 +17214 0/imm32/no-disp32 +17215 0/imm32/no-output +17216 0x11/imm32/alloc-id:fake +17217 _Primitive-loop-if-</imm32/next +17218 _Primitive-loop-if-<: # (payload primitive) +17219 0x11/imm32/alloc-id:fake:payload +17220 0x11/imm32/alloc-id:fake +17221 _string-loop-if-</imm32/name +17222 0/imm32/no-inouts +17223 0/imm32/no-inouts +17224 0/imm32/no-outputs +17225 0/imm32/no-outputs +17226 0x11/imm32/alloc-id:fake +17227 _string_0f_8c_jump_loop/imm32/subx-name +17228 0/imm32/no-rm32 +17229 0/imm32/no-r32 +17230 0/imm32/no-imm32 +17231 0/imm32/no-imm8 +17232 0/imm32/no-disp32 +17233 0/imm32/no-output +17234 0x11/imm32/alloc-id:fake +17235 _Primitive-loop-if->=/imm32/next +17236 _Primitive-loop-if->=: # (payload primitive) +17237 0x11/imm32/alloc-id:fake:payload +17238 0x11/imm32/alloc-id:fake +17239 _string-loop-if->=/imm32/name +17240 0/imm32/no-inouts +17241 0/imm32/no-inouts +17242 0/imm32/no-outputs +17243 0/imm32/no-outputs +17244 0x11/imm32/alloc-id:fake +17245 _string_0f_8d_jump_loop/imm32/subx-name +17246 0/imm32/no-rm32 +17247 0/imm32/no-r32 +17248 0/imm32/no-imm32 +17249 0/imm32/no-imm8 +17250 0/imm32/no-disp32 +17251 0/imm32/no-output +17252 0x11/imm32/alloc-id:fake +17253 _Primitive-loop-if-<=/imm32/next +17254 _Primitive-loop-if-<=: # (payload primitive) +17255 0x11/imm32/alloc-id:fake:payload +17256 0x11/imm32/alloc-id:fake +17257 _string-loop-if-<=/imm32/name +17258 0/imm32/no-inouts +17259 0/imm32/no-inouts +17260 0/imm32/no-outputs +17261 0/imm32/no-outputs +17262 0x11/imm32/alloc-id:fake +17263 _string_0f_8e_jump_loop/imm32/subx-name +17264 0/imm32/no-rm32 +17265 0/imm32/no-r32 +17266 0/imm32/no-imm32 +17267 0/imm32/no-imm8 +17268 0/imm32/no-disp32 +17269 0/imm32/no-output +17270 0x11/imm32/alloc-id:fake +17271 _Primitive-loop-if->/imm32/next +17272 _Primitive-loop-if->: # (payload primitive) 17273 0x11/imm32/alloc-id:fake:payload 17274 0x11/imm32/alloc-id:fake -17275 Int-var-in-eax/imm32 -17276 0/imm32/next -17277 0/imm32/next -17278 -17279 Int-var-in-eax: -17280 0x11/imm32/alloc-id:fake:payload -17281 0/imm32/name -17282 0/imm32/name -17283 0x11/imm32/alloc-id:fake -17284 Type-int/imm32 -17285 1/imm32/some-block-depth -17286 0/imm32/no-stack-offset -17287 0x11/imm32/alloc-id:fake -17288 $Register-eax/imm32 -17289 -17290 Single-int-var-in-ecx: # (payload list var) +17275 _string-loop-if->/imm32/name +17276 0/imm32/no-inouts +17277 0/imm32/no-inouts +17278 0/imm32/no-outputs +17279 0/imm32/no-outputs +17280 0x11/imm32/alloc-id:fake +17281 _string_0f_8f_jump_loop/imm32/subx-name +17282 0/imm32/no-rm32 +17283 0/imm32/no-r32 +17284 0/imm32/no-imm32 +17285 0/imm32/no-imm8 +17286 0/imm32/no-disp32 +17287 0/imm32/no-output +17288 0x11/imm32/alloc-id:fake +17289 _Primitive-loop/imm32/next # we probably don't need an unconditional break +17290 _Primitive-loop: # (payload primitive) 17291 0x11/imm32/alloc-id:fake:payload 17292 0x11/imm32/alloc-id:fake -17293 Int-var-in-ecx/imm32 -17294 0/imm32/next -17295 0/imm32/next -17296 -17297 Int-var-in-ecx: -17298 0x11/imm32/alloc-id:fake:payload -17299 0/imm32/name -17300 0/imm32/name -17301 0x11/imm32/alloc-id:fake -17302 Type-int/imm32 -17303 1/imm32/some-block-depth -17304 0/imm32/no-stack-offset -17305 0x11/imm32/alloc-id:fake -17306 $Register-ecx/imm32/register -17307 -17308 Single-int-var-in-edx: # (payload list var) -17309 0x11/imm32/alloc-id:fake:payload -17310 0x11/imm32/alloc-id:fake -17311 Int-var-in-edx/imm32 -17312 0/imm32/next -17313 0/imm32/next -17314 -17315 Int-var-in-edx: # (payload list var) -17316 0x11/imm32/alloc-id:fake:payload -17317 0/imm32/name -17318 0/imm32/name -17319 0x11/imm32/alloc-id:fake -17320 Type-int/imm32 -17321 1/imm32/some-block-depth -17322 0/imm32/no-stack-offset -17323 0x11/imm32/alloc-id:fake -17324 $Register-edx/imm32/register -17325 -17326 Single-int-var-in-ebx: # (payload list var) -17327 0x11/imm32/alloc-id:fake:payload -17328 0x11/imm32/alloc-id:fake -17329 Int-var-in-ebx/imm32 -17330 0/imm32/next -17331 0/imm32/next -17332 -17333 Int-var-in-ebx: # (payload list var) -17334 0x11/imm32/alloc-id:fake:payload -17335 0/imm32/name -17336 0/imm32/name -17337 0x11/imm32/alloc-id:fake -17338 Type-int/imm32 -17339 1/imm32/some-block-depth -17340 0/imm32/no-stack-offset -17341 0x11/imm32/alloc-id:fake -17342 $Register-ebx/imm32/register -17343 -17344 Single-int-var-in-esi: # (payload list var) -17345 0x11/imm32/alloc-id:fake:payload -17346 0x11/imm32/alloc-id:fake -17347 Int-var-in-esi/imm32 -17348 0/imm32/next -17349 0/imm32/next -17350 -17351 Int-var-in-esi: # (payload list var) -17352 0x11/imm32/alloc-id:fake:payload -17353 0/imm32/name -17354 0/imm32/name -17355 0x11/imm32/alloc-id:fake -17356 Type-int/imm32 -17357 1/imm32/some-block-depth -17358 0/imm32/no-stack-offset -17359 0x11/imm32/alloc-id:fake -17360 $Register-esi/imm32/register -17361 -17362 Single-int-var-in-edi: # (payload list var) -17363 0x11/imm32/alloc-id:fake:payload -17364 0x11/imm32/alloc-id:fake -17365 Int-var-in-edi/imm32 -17366 0/imm32/next -17367 0/imm32/next -17368 -17369 Int-var-in-edi: # (payload list var) -17370 0x11/imm32/alloc-id:fake:payload -17371 0/imm32/name -17372 0/imm32/name -17373 0x11/imm32/alloc-id:fake -17374 Type-int/imm32 -17375 1/imm32/some-block-depth -17376 0/imm32/no-stack-offset -17377 0x11/imm32/alloc-id:fake -17378 $Register-edi/imm32/register -17379 -17380 Single-lit-var: # (payload list var) -17381 0x11/imm32/alloc-id:fake:payload -17382 0x11/imm32/alloc-id:fake -17383 Lit-var/imm32 -17384 0/imm32/next -17385 0/imm32/next -17386 -17387 Lit-var: # (payload var) -17388 0x11/imm32/alloc-id:fake:payload -17389 0/imm32/name -17390 0/imm32/name -17391 0x11/imm32/alloc-id:fake -17392 Type-literal/imm32 -17393 1/imm32/some-block-depth -17394 0/imm32/no-stack-offset -17395 0/imm32/no-register -17396 0/imm32/no-register -17397 -17398 Type-int: # (payload type-tree) -17399 0x11/imm32/alloc-id:fake:payload -17400 1/imm32/left-is-atom -17401 1/imm32/value:int -17402 0/imm32/left:unused -17403 0/imm32/right:null -17404 0/imm32/right:null -17405 -17406 Type-literal: # (payload type-tree) -17407 0x11/imm32/alloc-id:fake:payload -17408 1/imm32/is-atom -17409 0/imm32/value:literal -17410 0/imm32/left:unused -17411 0/imm32/right:null -17412 0/imm32/right:null -17413 -17414 Type-addr: # (payload type-tree) -17415 0x11/imm32/alloc-id:fake:payload -17416 1/imm32/is-atom -17417 2/imm32/value:addr -17418 0/imm32/left:unused -17419 0/imm32/right:null -17420 0/imm32/right:null -17421 -17422 Type-byte: # (payload type-tree) -17423 0x11/imm32/alloc-id:fake:payload -17424 1/imm32/is-atom -17425 8/imm32/value:byte -17426 0/imm32/left:unused -17427 0/imm32/right:null -17428 0/imm32/right:null -17429 -17430 == code -17431 emit-subx-primitive: # out: (addr buffered-file), stmt: (addr stmt), primitive: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) -17432 # . prologue -17433 55/push-ebp -17434 89/<- %ebp 4/r32/esp -17435 # . save registers -17436 50/push-eax -17437 51/push-ecx -17438 # ecx = primitive -17439 8b/-> *(ebp+0x10) 1/r32/ecx -17440 # emit primitive name -17441 (emit-indent *(ebp+8) *Curr-block-depth) -17442 (lookup *(ecx+0x18) *(ecx+0x1c)) # Primitive-subx-name Primitive-subx-name => eax -17443 (write-buffered *(ebp+8) %eax) -17444 # emit rm32 if necessary -17445 (emit-subx-rm32 *(ebp+8) *(ecx+0x20) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-rm32 -17446 # emit r32 if necessary -17447 (emit-subx-r32 *(ebp+8) *(ecx+0x24) *(ebp+0xc)) # Primitive-subx-r32 -17448 # emit imm32 if necessary -17449 (emit-subx-imm32 *(ebp+8) *(ecx+0x28) *(ebp+0xc)) # Primitive-subx-imm32 -17450 # emit disp32 if necessary -17451 (emit-subx-disp32 *(ebp+8) *(ecx+0x2c) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-disp32 -17452 (write-buffered *(ebp+8) Newline) -17453 $emit-subx-primitive:end: -17454 # . restore registers -17455 59/pop-to-ecx -17456 58/pop-to-eax -17457 # . epilogue -17458 89/<- %esp 5/r32/ebp -17459 5d/pop-to-ebp -17460 c3/return -17461 -17462 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -17463 # . prologue -17464 55/push-ebp -17465 89/<- %ebp 4/r32/esp -17466 # . save registers -17467 50/push-eax -17468 # if (l == 0) return -17469 81 7/subop/compare *(ebp+0xc) 0/imm32 -17470 74/jump-if-= $emit-subx-rm32:end/disp8 -17471 # var v/eax: (addr stmt-var) -17472 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax -17473 (emit-subx-var-as-rm32 *(ebp+8) %eax) -17474 $emit-subx-rm32:end: -17475 # . restore registers -17476 58/pop-to-eax -17477 # . epilogue -17478 89/<- %esp 5/r32/ebp -17479 5d/pop-to-ebp -17480 c3/return -17481 -17482 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) -17483 # . prologue -17484 55/push-ebp -17485 89/<- %ebp 4/r32/esp -17486 # . save registers -17487 51/push-ecx -17488 # eax = l -17489 8b/-> *(ebp+0xc) 0/r32/eax -17490 # ecx = stmt -17491 8b/-> *(ebp+8) 1/r32/ecx -17492 # if (l == 1) return stmt->inouts -17493 { -17494 3d/compare-eax-and 1/imm32 -17495 75/jump-if-!= break/disp8 -17496 $get-stmt-operand-from-arg-location:1: -17497 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -17498 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -17499 } -17500 # if (l == 2) return stmt->inouts->next -17501 { -17502 3d/compare-eax-and 2/imm32 -17503 75/jump-if-!= break/disp8 -17504 $get-stmt-operand-from-arg-location:2: -17505 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -17506 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -17507 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -17508 } -17509 # if (l == 3) return stmt->outputs -17510 { -17511 3d/compare-eax-and 3/imm32 -17512 75/jump-if-!= break/disp8 -17513 $get-stmt-operand-from-arg-location:3: -17514 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -17515 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -17516 } -17517 # abort -17518 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 -17519 $get-stmt-operand-from-arg-location:end: -17520 # . restore registers -17521 59/pop-to-ecx -17522 # . epilogue -17523 89/<- %esp 5/r32/ebp -17524 5d/pop-to-ebp -17525 c3/return -17526 -17527 $get-stmt-operand-from-arg-location:abort: -17528 # error("invalid arg-location " eax) -17529 (write-buffered *(ebp+0x10) "invalid arg-location ") -17530 (write-int32-hex-buffered *(ebp+0x10) %eax) -17531 (write-buffered *(ebp+0x10) Newline) -17532 (flush *(ebp+0x10)) -17533 (stop *(ebp+0x14) 1) -17534 # never gets here -17535 -17536 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -17537 # . prologue -17538 55/push-ebp -17539 89/<- %ebp 4/r32/esp -17540 # . save registers -17541 50/push-eax -17542 51/push-ecx -17543 # if (l == 0) return -17544 81 7/subop/compare *(ebp+0xc) 0/imm32 -17545 0f 84/jump-if-= $emit-subx-r32:end/disp32 -17546 # var v/eax: (addr stmt-var) -17547 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -17548 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -17549 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -17550 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index) -17551 (write-buffered *(ebp+8) Space) -17552 (write-int32-hex-buffered *(ebp+8) *eax) -17553 (write-buffered *(ebp+8) "/r32") -17554 $emit-subx-r32:end: -17555 # . restore registers -17556 59/pop-to-ecx -17557 58/pop-to-eax -17558 # . epilogue -17559 89/<- %esp 5/r32/ebp -17560 5d/pop-to-ebp -17561 c3/return -17562 -17563 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -17564 # . prologue -17565 55/push-ebp -17566 89/<- %ebp 4/r32/esp -17567 # . save registers -17568 50/push-eax -17569 51/push-ecx -17570 # if (l == 0) return -17571 81 7/subop/compare *(ebp+0xc) 0/imm32 -17572 0f 84/jump-if-= $emit-subx-imm32:end/disp32 -17573 # var v/eax: (handle var) -17574 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -17575 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -17576 (lookup *eax *(eax+4)) # Var-name Var-name => eax -17577 (write-buffered *(ebp+8) Space) -17578 (write-buffered *(ebp+8) %eax) -17579 (write-buffered *(ebp+8) "/imm32") -17580 $emit-subx-imm32:end: -17581 # . restore registers -17582 59/pop-to-ecx -17583 58/pop-to-eax -17584 # . epilogue -17585 89/<- %esp 5/r32/ebp -17586 5d/pop-to-ebp -17587 c3/return -17588 -17589 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -17590 # . prologue -17591 55/push-ebp -17592 89/<- %ebp 4/r32/esp -17593 # . save registers -17594 50/push-eax -17595 51/push-ecx -17596 # if (location == 0) return -17597 81 7/subop/compare *(ebp+0xc) 0/imm32 -17598 0f 84/jump-if-= $emit-subx-disp32:end/disp32 -17599 # var v/eax: (addr stmt-var) -17600 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax -17601 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -17602 (lookup *eax *(eax+4)) # Var-name Var-name => eax -17603 (write-buffered *(ebp+8) Space) -17604 (write-buffered *(ebp+8) %eax) -17605 # hack: if instruction operation starts with "break", emit ":break" -17606 # var name/ecx: (addr array byte) = lookup(stmt->operation) -17607 8b/-> *(ebp+0x10) 0/r32/eax -17608 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -17609 89/<- %ecx 0/r32/eax -17610 { -17611 (string-starts-with? %ecx "break") # => eax -17612 3d/compare-eax-and 0/imm32/false -17613 74/jump-if-= break/disp8 -17614 (write-buffered *(ebp+8) ":break") -17615 } -17616 # hack: if instruction operation starts with "loop", emit ":loop" -17617 { -17618 (string-starts-with? %ecx "loop") # => eax -17619 3d/compare-eax-and 0/imm32/false -17620 74/jump-if-= break/disp8 -17621 (write-buffered *(ebp+8) ":loop") -17622 } -17623 (write-buffered *(ebp+8) "/disp32") -17624 $emit-subx-disp32:end: -17625 # . restore registers -17626 59/pop-to-ecx -17627 58/pop-to-eax -17628 # . epilogue -17629 89/<- %esp 5/r32/ebp -17630 5d/pop-to-ebp -17631 c3/return -17632 -17633 emit-call: # out: (addr buffered-file), stmt: (addr stmt) -17634 # . prologue -17635 55/push-ebp -17636 89/<- %ebp 4/r32/esp -17637 # . save registers -17638 50/push-eax -17639 51/push-ecx -17640 # -17641 (emit-indent *(ebp+8) *Curr-block-depth) -17642 (write-buffered *(ebp+8) "(") -17643 # ecx = stmt -17644 8b/-> *(ebp+0xc) 1/r32/ecx -17645 # - emit function name -17646 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -17647 (write-buffered *(ebp+8) %eax) -17648 # - emit arguments -17649 # var curr/eax: (addr stmt-var) = lookup(stmt->inouts) -17650 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -17651 { -17652 # if (curr == null) break -17653 3d/compare-eax-and 0/imm32 -17654 74/jump-if-= break/disp8 -17655 # -17656 (emit-subx-call-operand *(ebp+8) %eax) -17657 # curr = lookup(curr->next) -17658 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -17659 eb/jump loop/disp8 -17660 } -17661 # -17662 (write-buffered *(ebp+8) ")\n") -17663 $emit-call:end: -17664 # . restore registers -17665 59/pop-to-ecx -17666 58/pop-to-eax -17667 # . epilogue -17668 89/<- %esp 5/r32/ebp -17669 5d/pop-to-ebp -17670 c3/return -17671 -17672 emit-subx-call-operand: # out: (addr buffered-file), s: (addr stmt-var) -17673 # shares code with emit-subx-var-as-rm32 -17674 # . prologue -17675 55/push-ebp -17676 89/<- %ebp 4/r32/esp -17677 # . save registers -17678 50/push-eax -17679 51/push-ecx -17680 56/push-esi -17681 # ecx = s -17682 8b/-> *(ebp+0xc) 1/r32/ecx -17683 # var operand/esi: (addr var) = lookup(s->value) -17684 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -17685 89/<- %esi 0/r32/eax -17686 # if (operand->register && !s->is-deref?) emit "%__" -17687 { -17688 $emit-subx-call-operand:check-for-register-direct: -17689 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -17690 74/jump-if-= break/disp8 -17691 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -17692 75/jump-if-!= break/disp8 -17693 $emit-subx-call-operand:register-direct: -17694 (write-buffered *(ebp+8) " %") -17695 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -17696 (write-buffered *(ebp+8) %eax) -17697 e9/jump $emit-subx-call-operand:end/disp32 -17698 } -17699 # else if (operand->register && s->is-deref?) emit "*__" -17700 { -17701 $emit-subx-call-operand:check-for-register-indirect: -17702 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -17703 74/jump-if-= break/disp8 -17704 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -17705 74/jump-if-= break/disp8 -17706 $emit-subx-call-operand:register-indirect: -17707 (emit-subx-call-operand-register-indirect *(ebp+8) %esi) -17708 e9/jump $emit-subx-call-operand:end/disp32 -17709 } -17710 # else if (operand->stack-offset) emit "*(ebp+__)" -17711 { -17712 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset -17713 74/jump-if-= break/disp8 -17714 $emit-subx-call-operand:stack: -17715 (emit-subx-call-operand-stack *(ebp+8) %esi) -17716 e9/jump $emit-subx-call-operand:end/disp32 -17717 } -17718 # else if (operand->type == literal) emit "__" -17719 { -17720 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -17721 81 7/subop/compare *(eax+4) 0/imm32 # Type-tree-left -17722 75/jump-if-!= break/disp8 -17723 $emit-subx-call-operand:literal: -17724 (write-buffered *(ebp+8) Space) -17725 (lookup *esi *(esi+4)) # Var-name Var-name => eax -17726 (write-buffered *(ebp+8) %eax) -17727 } -17728 $emit-subx-call-operand:end: -17729 # . restore registers -17730 5e/pop-to-esi -17731 59/pop-to-ecx -17732 58/pop-to-eax -17733 # . epilogue -17734 89/<- %esp 5/r32/ebp -17735 5d/pop-to-ebp -17736 c3/return -17737 -17738 emit-subx-call-operand-register-indirect: # out: (addr buffered-file), v: (addr var) -17739 # . prologue -17740 55/push-ebp -17741 89/<- %ebp 4/r32/esp -17742 # . save registers -17743 50/push-eax -17744 51/push-ecx -17745 56/push-esi -17746 # esi = v -17747 8b/-> *(ebp+0xc) 6/r32/esi -17748 # var size/ecx: int = size-of-deref(v) -17749 (size-of-deref %esi) # => eax -17750 89/<- %ecx 0/r32/eax -17751 # var reg-name/esi: (addr array byte) = lookup(v->register) -17752 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -17753 89/<- %esi 0/r32/eax -17754 # TODO: assert size is a multiple of 4 -17755 # var i/eax: int = 0 -17756 b8/copy-to-eax 0/imm32 -17757 { -17758 $emit-subx-call-operand-register-indirect:loop: -17759 # if (i >= size) break -17760 39/compare %eax 1/r32/ecx -17761 7d/jump-if->= break/disp8 -17762 # emit " *(" v->register "+" i ")" -17763 (write-buffered *(ebp+8) " *(") -17764 (write-buffered *(ebp+8) %esi) -17765 (write-buffered *(ebp+8) "+") -17766 (write-int32-hex-buffered *(ebp+8) %eax) -17767 (write-buffered *(ebp+8) ")") -17768 # i += 4 -17769 05/add-to-eax 4/imm32 -17770 # -17771 eb/jump loop/disp8 -17772 } -17773 $emit-subx-call-operand-register-indirect:end: -17774 # . restore registers -17775 5e/pop-to-esi -17776 59/pop-to-ecx -17777 58/pop-to-eax -17778 # . epilogue -17779 89/<- %esp 5/r32/ebp -17780 5d/pop-to-ebp -17781 c3/return -17782 -17783 emit-subx-call-operand-stack: # out: (addr buffered-file), v: (addr var) -17784 # . prologue -17785 55/push-ebp -17786 89/<- %ebp 4/r32/esp -17787 # . save registers -17788 50/push-eax -17789 51/push-ecx -17790 56/push-esi -17791 # esi = v -17792 8b/-> *(ebp+0xc) 6/r32/esi -17793 # var curr/ecx: int = v->offset -17794 8b/-> *(esi+0x14) 1/r32/ecx # Var-offset -17795 # var max/eax: int = v->offset + size-of(v) -17796 (size-of %esi) # => eax -17797 # TODO: assert size is a multiple of 4 -17798 01/add-to %eax 1/r32/ecx -17799 { -17800 $emit-subx-call-operand-stack:loop: -17801 # if (curr >= max) break -17802 39/compare %ecx 0/r32/eax -17803 7d/jump-if->= break/disp8 -17804 # emit " *(ebp+" curr ")" -17805 (write-buffered *(ebp+8) " *(ebp+") -17806 (write-int32-hex-buffered *(ebp+8) %ecx) -17807 (write-buffered *(ebp+8) ")") -17808 # i += 4 -17809 81 0/subop/add %ecx 4/imm32 -17810 # -17811 eb/jump loop/disp8 -17812 } -17813 $emit-subx-call-operand-stack:end: -17814 # . restore registers -17815 5e/pop-to-esi -17816 59/pop-to-ecx -17817 58/pop-to-eax -17818 # . epilogue -17819 89/<- %esp 5/r32/ebp -17820 5d/pop-to-ebp -17821 c3/return -17822 -17823 emit-subx-var-as-rm32: # out: (addr buffered-file), s: (addr stmt-var) -17824 # . prologue -17825 55/push-ebp -17826 89/<- %ebp 4/r32/esp -17827 # . save registers -17828 50/push-eax -17829 51/push-ecx -17830 56/push-esi -17831 # ecx = s -17832 8b/-> *(ebp+0xc) 1/r32/ecx -17833 # var operand/esi: (addr var) = lookup(s->value) -17834 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -17835 89/<- %esi 0/r32/eax -17836 # if (operand->register && s->is-deref?) emit "*__" -17837 { -17838 $emit-subx-var-as-rm32:check-for-register-indirect: -17839 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -17840 74/jump-if-= break/disp8 -17841 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -17842 74/jump-if-= break/disp8 -17843 $emit-subx-var-as-rm32:register-indirect: -17844 (write-buffered *(ebp+8) " *") -17845 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -17846 (write-buffered *(ebp+8) %eax) -17847 e9/jump $emit-subx-var-as-rm32:end/disp32 -17848 } -17849 # if (operand->register && !s->is-deref?) emit "%__" -17850 { -17851 $emit-subx-var-as-rm32:check-for-register-direct: -17852 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -17853 74/jump-if-= break/disp8 -17854 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -17855 75/jump-if-!= break/disp8 -17856 $emit-subx-var-as-rm32:register-direct: -17857 (write-buffered *(ebp+8) " %") -17858 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -17859 (write-buffered *(ebp+8) %eax) -17860 e9/jump $emit-subx-var-as-rm32:end/disp32 -17861 } -17862 # else if (operand->stack-offset) emit "*(ebp+__)" -17863 { -17864 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset -17865 74/jump-if-= break/disp8 -17866 $emit-subx-var-as-rm32:stack: -17867 (write-buffered *(ebp+8) Space) -17868 (write-buffered *(ebp+8) "*(ebp+") -17869 (write-int32-hex-buffered *(ebp+8) *(esi+0x14)) # Var-offset -17870 (write-buffered *(ebp+8) ")") -17871 } -17872 $emit-subx-var-as-rm32:end: -17873 # . restore registers -17874 5e/pop-to-esi -17875 59/pop-to-ecx -17876 58/pop-to-eax -17877 # . epilogue -17878 89/<- %esp 5/r32/ebp -17879 5d/pop-to-ebp -17880 c3/return -17881 -17882 find-matching-primitive: # primitives: (addr primitive), stmt: (addr stmt) -> result/eax: (addr primitive) -17883 # . prologue -17884 55/push-ebp -17885 89/<- %ebp 4/r32/esp -17886 # . save registers -17887 51/push-ecx -17888 # var curr/ecx: (addr primitive) = primitives -17889 8b/-> *(ebp+8) 1/r32/ecx -17890 { -17891 $find-matching-primitive:loop: -17892 # if (curr == null) break -17893 81 7/subop/compare %ecx 0/imm32 -17894 74/jump-if-= break/disp8 -17895 # if match(curr, stmt) return curr -17896 { -17897 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax -17898 3d/compare-eax-and 0/imm32/false -17899 74/jump-if-= break/disp8 -17900 89/<- %eax 1/r32/ecx -17901 eb/jump $find-matching-primitive:end/disp8 -17902 } -17903 $find-matching-primitive:next-primitive: -17904 # curr = curr->next -17905 (lookup *(ecx+0x34) *(ecx+0x38)) # Primitive-next Primitive-next => eax -17906 89/<- %ecx 0/r32/eax -17907 # -17908 e9/jump loop/disp32 -17909 } -17910 # return null -17911 b8/copy-to-eax 0/imm32 -17912 $find-matching-primitive:end: -17913 # . restore registers -17914 59/pop-to-ecx -17915 # . epilogue -17916 89/<- %esp 5/r32/ebp -17917 5d/pop-to-ebp -17918 c3/return -17919 -17920 mu-stmt-matches-primitive?: # stmt: (addr stmt), primitive: (addr primitive) -> result/eax: boolean -17921 # A mu stmt matches a primitive if the name matches, all the inout vars -17922 # match, and all the output vars match. -17923 # Vars match if types match and registers match. -17924 # In addition, a stmt output matches a primitive's output if types match -17925 # and the primitive has a wildcard register. -17926 # . prologue -17927 55/push-ebp -17928 89/<- %ebp 4/r32/esp -17929 # . save registers -17930 51/push-ecx -17931 52/push-edx -17932 53/push-ebx -17933 56/push-esi -17934 57/push-edi -17935 # ecx = stmt -17936 8b/-> *(ebp+8) 1/r32/ecx -17937 # edx = primitive -17938 8b/-> *(ebp+0xc) 2/r32/edx -17939 { -17940 $mu-stmt-matches-primitive?:check-name: -17941 # if (primitive->name != stmt->operation) return false -17942 # . var esi: (addr array byte) = lookup(stmt->operation) -17943 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -17944 89/<- %esi 0/r32/eax -17945 # . var edi: (addr array byte) = lookup(primitive->name) -17946 (lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax -17947 89/<- %edi 0/r32/eax -17948 (string-equal? %esi %edi) # => eax -17949 3d/compare-eax-and 0/imm32/false -17950 75/jump-if-!= break/disp8 -17951 b8/copy-to-eax 0/imm32 -17952 e9/jump $mu-stmt-matches-primitive?:end/disp32 -17953 } -17954 # var curr/esi: (addr stmt-var) = lookup(stmt->inouts) -17955 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -17956 89/<- %esi 0/r32/eax -17957 # var curr2/edi: (addr list var) = lookup(primitive->inouts) -17958 (lookup *(edx+8) *(edx+0xc)) # Primitive-inouts Primitive-inouts => eax -17959 89/<- %edi 0/r32/eax -17960 { -17961 $mu-stmt-matches-primitive?:inouts-loop: -17962 # if (curr == 0 && curr2 == 0) move on to check outputs -17963 { -17964 $mu-stmt-matches-primitive?:check-both-inouts-null: -17965 81 7/subop/compare %esi 0/imm32 -17966 75/jump-if-!= break/disp8 -17967 $mu-stmt-matches-primitive?:stmt-inout-null: -17968 81 7/subop/compare %edi 0/imm32 -17969 0f 84/jump-if-= $mu-stmt-matches-primitive?:check-outputs/disp32 -17970 $mu-stmt-matches-primitive?:stmt-inout-null-and-prim-inout-not-null: -17971 # return false -17972 b8/copy-to-eax 0/imm32/false -17973 e9/jump $mu-stmt-matches-primitive?:end/disp32 -17974 } -17975 # if (curr2 == 0) return false -17976 { -17977 $mu-stmt-matches-primitive?:check-prim-inout-null: -17978 81 7/subop/compare %edi 0/imm32 -17979 75/jump-if-!= break/disp8 -17980 $mu-stmt-matches-primitive?:prim-inout-null: -17981 b8/copy-to-eax 0/imm32/false -17982 e9/jump $mu-stmt-matches-primitive?:end/disp32 -17983 } -17984 # if (curr != curr2) return false -17985 { -17986 $mu-stmt-matches-primitive?:check-inouts-match: -17987 (lookup *edi *(edi+4)) # List-value List-value => eax -17988 (operand-matches-primitive? %esi %eax) # => eax -17989 3d/compare-eax-and 0/imm32/false -17990 75/jump-if-!= break/disp8 -17991 $mu-stmt-matches-primitive?:inouts-match: -17992 b8/copy-to-eax 0/imm32/false -17993 e9/jump $mu-stmt-matches-primitive?:end/disp32 -17994 } -17995 $mu-stmt-matches-primitive?:next-inout: -17996 # curr = lookup(curr->next) -17997 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -17998 89/<- %esi 0/r32/eax -17999 # curr2 = lookup(curr2->next) -18000 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax -18001 89/<- %edi 0/r32/eax -18002 # -18003 e9/jump loop/disp32 -18004 } -18005 $mu-stmt-matches-primitive?:check-outputs: -18006 # var curr/esi: (addr stmt-var) = lookup(stmt->outputs) -18007 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -18008 89/<- %esi 0/r32/eax -18009 # var curr2/edi: (addr list var) = lookup(primitive->outputs) -18010 (lookup *(edx+0x10) *(edx+0x14)) # Primitive-outputs Primitive-outputs => eax -18011 89/<- %edi 0/r32/eax -18012 { -18013 $mu-stmt-matches-primitive?:outputs-loop: -18014 # if (curr == 0) return (curr2 == 0) -18015 { -18016 $mu-stmt-matches-primitive?:check-both-outputs-null: -18017 81 7/subop/compare %esi 0/imm32 -18018 75/jump-if-!= break/disp8 -18019 { -18020 $mu-stmt-matches-primitive?:stmt-output-null: -18021 81 7/subop/compare %edi 0/imm32 -18022 75/jump-if-!= break/disp8 -18023 $mu-stmt-matches-primitive?:both-outputs-null: -18024 # return true -18025 b8/copy-to-eax 1/imm32 -18026 e9/jump $mu-stmt-matches-primitive?:end/disp32 -18027 } -18028 $mu-stmt-matches-primitive?:stmt-output-null-and-prim-output-not-null: -18029 # return false -18030 b8/copy-to-eax 0/imm32 -18031 e9/jump $mu-stmt-matches-primitive?:end/disp32 -18032 } -18033 # if (curr2 == 0) return false -18034 { -18035 $mu-stmt-matches-primitive?:check-prim-output-null: -18036 81 7/subop/compare %edi 0/imm32 -18037 75/jump-if-!= break/disp8 -18038 $mu-stmt-matches-primitive?:prim-output-is-null: -18039 b8/copy-to-eax 0/imm32 -18040 e9/jump $mu-stmt-matches-primitive?:end/disp32 -18041 } -18042 # if (curr != curr2) return false -18043 { -18044 $mu-stmt-matches-primitive?:check-outputs-match: -18045 (lookup *edi *(edi+4)) # List-value List-value => eax -18046 (operand-matches-primitive? %esi %eax) # => eax -18047 3d/compare-eax-and 0/imm32/false -18048 75/jump-if-!= break/disp8 -18049 $mu-stmt-matches-primitive?:outputs-match: -18050 b8/copy-to-eax 0/imm32 -18051 e9/jump $mu-stmt-matches-primitive?:end/disp32 -18052 } -18053 $mu-stmt-matches-primitive?:next-output: -18054 # curr = lookup(curr->next) -18055 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -18056 89/<- %esi 0/r32/eax -18057 # curr2 = lookup(curr2->next) -18058 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax -18059 89/<- %edi 0/r32/eax -18060 # -18061 e9/jump loop/disp32 -18062 } -18063 $mu-stmt-matches-primitive?:return-true: -18064 b8/copy-to-eax 1/imm32 -18065 $mu-stmt-matches-primitive?:end: -18066 # . restore registers -18067 5f/pop-to-edi -18068 5e/pop-to-esi -18069 5b/pop-to-ebx -18070 5a/pop-to-edx -18071 59/pop-to-ecx -18072 # . epilogue -18073 89/<- %esp 5/r32/ebp -18074 5d/pop-to-ebp -18075 c3/return -18076 -18077 operand-matches-primitive?: # s: (addr stmt-var), prim-var: (addr var) -> result/eax: boolean -18078 # . prologue -18079 55/push-ebp -18080 89/<- %ebp 4/r32/esp -18081 # . save registers -18082 51/push-ecx -18083 52/push-edx -18084 53/push-ebx -18085 56/push-esi -18086 57/push-edi -18087 # ecx = s -18088 8b/-> *(ebp+8) 1/r32/ecx -18089 # var var/esi: (addr var) = lookup(s->value) -18090 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -18091 89/<- %esi 0/r32/eax -18092 # edi = prim-var -18093 8b/-> *(ebp+0xc) 7/r32/edi -18094 $operand-matches-primitive?:check-type: -18095 # if !category-match?(var->type, prim-var->type) return false -18096 # . var vtype/ebx: (addr type-tree) = lookup(var->type) -18097 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -18098 89/<- %ebx 0/r32/eax -18099 # . var ptype/eax: (addr type-tree) = lookup(prim-var->type) -18100 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -18101 (subx-type-category-match? %ebx %eax) # => eax -18102 3d/compare-eax-and 0/imm32/false -18103 0f 84/jump-if-= $operand-matches-primitive?:return-false/disp32 -18104 { -18105 $operand-matches-primitive?:check-register: -18106 # if prim-var is in memory and var is in register but dereference, match -18107 { -18108 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register -18109 0f 85/jump-if-!= break/disp32 -18110 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -18111 74/jump-if-= break/disp8 -18112 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -18113 74/jump-if-= break/disp8 -18114 $operand-matches-primitive?:var-deref-match: -18115 e9/jump $operand-matches-primitive?:return-true/disp32 -18116 } -18117 # if prim-var is in register and var is in register but dereference, no match -18118 { -18119 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register -18120 0f 84/jump-if-= break/disp32 -18121 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -18122 0f 84/jump-if-= break/disp32 -18123 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -18124 74/jump-if-= break/disp8 -18125 $operand-matches-primitive?:var-deref-no-match: -18126 e9/jump $operand-matches-primitive?:return-false/disp32 -18127 } -18128 # return false if var->register doesn't match prim-var->register -18129 { -18130 # if register addresses are equal, it's a match -18131 # var vreg/ebx: (addr array byte) = lookup(var->register) -18132 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -18133 89/<- %ebx 0/r32/eax -18134 # var preg/ecx: (addr array byte) = lookup(prim-var->register) -18135 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -18136 89/<- %ecx 0/r32/eax -18137 # if (vreg == preg) break -18138 39/compare %ecx 3/r32/ebx -18139 74/jump-if-= break/disp8 -18140 $operand-matches-primitive?:var-register-no-match: -18141 # if either address is 0, return false -18142 81 7/subop/compare %ebx 0/imm32 -18143 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -18144 81 7/subop/compare %ecx 0/imm32 -18145 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -18146 # if prim-var->register is wildcard, it's a match -18147 (string-equal? %ecx "*") # Any-register => eax -18148 3d/compare-eax-and 0/imm32/false -18149 75/jump-if-!= break/disp8 -18150 $operand-matches-primitive?:wildcard-no-match: -18151 # if string contents aren't equal, return false -18152 (string-equal? %ecx %ebx) # => eax -18153 3d/compare-eax-and 0/imm32/false -18154 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -18155 } -18156 } -18157 $operand-matches-primitive?:return-true: -18158 b8/copy-to-eax 1/imm32/true -18159 eb/jump $operand-matches-primitive?:end/disp8 -18160 $operand-matches-primitive?:return-false: -18161 b8/copy-to-eax 0/imm32/false -18162 $operand-matches-primitive?:end: -18163 # . restore registers -18164 5f/pop-to-edi -18165 5e/pop-to-esi -18166 5b/pop-to-ebx -18167 5a/pop-to-edx -18168 59/pop-to-ecx -18169 # . epilogue -18170 89/<- %esp 5/r32/ebp -18171 5d/pop-to-ebp -18172 c3/return -18173 -18174 find-matching-function: # functions: (addr function), stmt: (addr stmt) -> result/eax: (addr function) -18175 # . prologue -18176 55/push-ebp -18177 89/<- %ebp 4/r32/esp -18178 # . save registers -18179 51/push-ecx -18180 # var curr/ecx: (handle function) = functions -18181 8b/-> *(ebp+8) 1/r32/ecx -18182 { -18183 # if (curr == null) break -18184 81 7/subop/compare %ecx 0/imm32 -18185 74/jump-if-= break/disp8 -18186 #? (write-buffered Stderr "iter\n") -18187 #? (flush Stderr) -18188 # if match(stmt, curr) return curr -18189 { -18190 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax -18191 3d/compare-eax-and 0/imm32/false -18192 74/jump-if-= break/disp8 -18193 89/<- %eax 1/r32/ecx -18194 eb/jump $find-matching-function:end/disp8 -18195 } -18196 # curr = curr->next -18197 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax -18198 89/<- %ecx 0/r32/eax -18199 # -18200 eb/jump loop/disp8 -18201 } -18202 # return null -18203 b8/copy-to-eax 0/imm32 -18204 $find-matching-function:end: -18205 # . restore registers -18206 59/pop-to-ecx -18207 # . epilogue -18208 89/<- %esp 5/r32/ebp -18209 5d/pop-to-ebp -18210 c3/return -18211 -18212 # Just compare names; user-defined functions don't support overloading yet. -18213 mu-stmt-matches-function?: # stmt: (addr stmt1), function: (addr function) -> result/eax: boolean -18214 # . prologue -18215 55/push-ebp -18216 89/<- %ebp 4/r32/esp -18217 # . save registers -18218 51/push-ecx -18219 # return function->name == stmt->operation -18220 # ecx = lookup(stmt->operation) -18221 8b/-> *(ebp+8) 0/r32/eax -18222 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -18223 89/<- %ecx 0/r32/eax -18224 # eax = lookup(function->name) -18225 8b/-> *(ebp+0xc) 0/r32/eax -18226 (lookup *eax *(eax+4)) # Function-name Function-name => eax -18227 (string-equal? %eax %ecx) # => eax -18228 $mu-stmt-matches-function?:end: -18229 # . restore registers -18230 59/pop-to-ecx -18231 # . epilogue -18232 89/<- %esp 5/r32/ebp -18233 5d/pop-to-ebp -18234 c3/return -18235 -18236 # Type-checking happens elsewhere. This method is for selecting between -18237 # primitives. -18238 subx-type-category-match?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean -18239 # . prologue -18240 55/push-ebp -18241 89/<- %ebp 4/r32/esp -18242 # . save registers -18243 51/push-ecx -18244 # var alit/ecx: boolean = is-literal-type?(a) -18245 (is-simple-mu-type? *(ebp+8) 0) # => eax -18246 89/<- %ecx 0/r32/eax -18247 # var blit/eax: boolean = is-literal-type?(b) -18248 (is-simple-mu-type? *(ebp+0xc) 0) # => eax -18249 # return alit == blit -18250 39/compare %eax 1/r32/ecx -18251 0f 94/set-byte-if-= %al -18252 81 4/subop/and %eax 0xff/imm32 -18253 $subx-type-category-match?:end: -18254 # . restore registers -18255 59/pop-to-ecx -18256 # . epilogue -18257 89/<- %esp 5/r32/ebp -18258 5d/pop-to-ebp -18259 c3/return -18260 -18261 is-simple-mu-type?: # a: (addr type-tree), n: type-id -> result/eax: boolean -18262 # . prologue -18263 55/push-ebp -18264 89/<- %ebp 4/r32/esp -18265 # . save registers -18266 51/push-ecx -18267 # ecx = n -18268 8b/-> *(ebp+0xc) 1/r32/ecx -18269 # return (a->value == n) -18270 8b/-> *(ebp+8) 0/r32/eax -18271 39/compare *(eax+4) 1/r32/ecx # Type-tree-value -18272 0f 94/set-byte-if-= %al -18273 81 4/subop/and %eax 0xff/imm32 -18274 $is-simple-mu-type?:end: -18275 # . restore registers -18276 59/pop-to-ecx -18277 # . epilogue -18278 89/<- %esp 5/r32/ebp -18279 5d/pop-to-ebp -18280 c3/return -18281 -18282 is-mu-addr-type?: # a: (addr type-tree) -> result/eax: boolean -18283 # . prologue -18284 55/push-ebp -18285 89/<- %ebp 4/r32/esp -18286 # eax = a -18287 8b/-> *(ebp+8) 0/r32/eax -18288 # if (!a->is-atom?) a = a->left -18289 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom -18290 { -18291 75/jump-if-!= break/disp8 -18292 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax -18293 } -18294 # return (a->value == addr) -18295 81 7/subop/compare *(eax+4) 2/imm32/addr # Type-tree-value -18296 0f 94/set-byte-if-= %al -18297 81 4/subop/and %eax 0xff/imm32 -18298 $is-mu-addr-type?:end: -18299 # . epilogue -18300 89/<- %esp 5/r32/ebp -18301 5d/pop-to-ebp -18302 c3/return -18303 -18304 test-emit-subx-stmt-primitive: -18305 # Primitive operation on a variable on the stack. -18306 # increment foo -18307 # => -18308 # ff 0/subop/increment *(ebp-8) -18309 # -18310 # There's a variable on the var stack as follows: -18311 # name: 'foo' -18312 # type: int -18313 # stack-offset: -8 -18314 # -18315 # There's a primitive with this info: -18316 # name: 'increment' -18317 # inouts: int/mem -18318 # value: 'ff 0/subop/increment' -18319 # -18320 # . prologue -18321 55/push-ebp -18322 89/<- %ebp 4/r32/esp -18323 # setup -18324 (clear-stream _test-output-stream) -18325 (clear-stream $_test-output-buffered-file->buffer) -18326 # simulate allocated payloads starting with an initial fake alloc-id (0x11) -18327 $test-emit-subx-stmt-primitive:initialize-type: -18328 # var type/ecx: (payload type-tree) = int -18329 68/push 0/imm32/right:null -18330 68/push 0/imm32/right:null -18331 68/push 0/imm32/left:unused -18332 68/push 1/imm32/value:int -18333 68/push 1/imm32/is-atom?:true -18334 68/push 0x11/imm32/alloc-id:fake:payload -18335 89/<- %ecx 4/r32/esp -18336 $test-emit-subx-stmt-primitive:initialize-var: -18337 # var var-foo/ecx: (payload var) = var(type) -18338 68/push 0/imm32/no-register -18339 68/push 0/imm32/no-register -18340 68/push -8/imm32/stack-offset -18341 68/push 1/imm32/block-depth -18342 51/push-ecx/type -18343 68/push 0x11/imm32/alloc-id:fake -18344 68/push 0/imm32/name -18345 68/push 0/imm32/name -18346 68/push 0x11/imm32/alloc-id:fake:payload -18347 89/<- %ecx 4/r32/esp -18348 $test-emit-subx-stmt-primitive:initialize-var-name: -18349 # var-foo->name = "foo" -18350 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -18351 (copy-array Heap "foo" %eax) -18352 $test-emit-subx-stmt-primitive:initialize-stmt-var: -18353 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -18354 68/push 0/imm32/is-deref:false -18355 68/push 0/imm32/next -18356 68/push 0/imm32/next -18357 51/push-ecx/var-foo -18358 68/push 0x11/imm32/alloc-id:fake -18359 68/push 0x11/imm32/alloc-id:fake:payload -18360 89/<- %ebx 4/r32/esp -18361 $test-emit-subx-stmt-primitive:initialize-stmt: -18362 # var stmt/esi: (addr statement) -18363 68/push 0/imm32/no-outputs -18364 68/push 0/imm32/no-outputs -18365 53/push-ebx/inouts -18366 68/push 0x11/imm32/alloc-id:fake -18367 68/push 0/imm32/operation -18368 68/push 0/imm32/operation -18369 68/push 1/imm32/tag -18370 89/<- %esi 4/r32/esp -18371 $test-emit-subx-stmt-primitive:initialize-stmt-operation: -18372 # stmt->operation = "increment" -18373 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -18374 (copy-array Heap "increment" %eax) -18375 $test-emit-subx-stmt-primitive:initialize-primitive: -18376 # var primitives/ebx: (addr primitive) -18377 68/push 0/imm32/next -18378 68/push 0/imm32/next -18379 68/push 0/imm32/output-is-write-only -18380 68/push 0/imm32/no-disp32 -18381 68/push 0/imm32/no-imm32 -18382 68/push 0/imm32/no-r32 -18383 68/push 1/imm32/rm32-is-first-inout -18384 68/push 0/imm32/subx-name -18385 68/push 0/imm32/subx-name -18386 68/push 0/imm32/no-outputs -18387 68/push 0/imm32/no-outputs -18388 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration -18389 68/push 0x11/imm32/alloc-id:fake -18390 68/push 0/imm32/name -18391 68/push 0/imm32/name -18392 89/<- %ebx 4/r32/esp -18393 $test-emit-subx-stmt-primitive:initialize-primitive-name: -18394 # primitives->name = "increment" -18395 (copy-array Heap "increment" %ebx) # Primitive-name -18396 $test-emit-subx-stmt-primitive:initialize-primitive-subx-name: -18397 # primitives->subx-name = "ff 0/subop/increment" -18398 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -18399 (copy-array Heap "ff 0/subop/increment" %eax) -18400 # convert -18401 c7 0/subop/copy *Curr-block-depth 0/imm32 -18402 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) -18403 (flush _test-output-buffered-file) -18404 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -18410 # check output -18411 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-stmt-primitive") -18412 # . epilogue -18413 89/<- %esp 5/r32/ebp -18414 5d/pop-to-ebp -18415 c3/return +17293 _string-loop/imm32/name +17294 0/imm32/no-inouts +17295 0/imm32/no-inouts +17296 0/imm32/no-outputs +17297 0/imm32/no-outputs +17298 0x11/imm32/alloc-id:fake +17299 _string_e9_jump_loop/imm32/subx-name +17300 0/imm32/no-rm32 +17301 0/imm32/no-r32 +17302 0/imm32/no-imm32 +17303 0/imm32/no-imm8 +17304 0/imm32/no-disp32 +17305 0/imm32/no-output +17306 0x11/imm32/alloc-id:fake +17307 _Primitive-break-if-addr<-named/imm32/next +17308 # - branches to named blocks +17309 _Primitive-break-if-addr<-named: # (payload primitive) +17310 0x11/imm32/alloc-id:fake:payload +17311 0x11/imm32/alloc-id:fake +17312 _string-break-if-addr</imm32/name +17313 0x11/imm32/alloc-id:fake +17314 Single-lit-var/imm32/inouts +17315 0/imm32/no-outputs +17316 0/imm32/no-outputs +17317 0x11/imm32/alloc-id:fake +17318 _string_0f_82_jump_label/imm32/subx-name +17319 0/imm32/no-rm32 +17320 0/imm32/no-r32 +17321 0/imm32/no-imm32 +17322 0/imm32/no-imm8 +17323 1/imm32/disp32-is-first-inout +17324 0/imm32/no-output +17325 0x11/imm32/alloc-id:fake +17326 _Primitive-break-if-addr>=-named/imm32/next +17327 _Primitive-break-if-addr>=-named: # (payload primitive) +17328 0x11/imm32/alloc-id:fake:payload +17329 0x11/imm32/alloc-id:fake +17330 _string-break-if-addr>=/imm32/name +17331 0x11/imm32/alloc-id:fake +17332 Single-lit-var/imm32/inouts +17333 0/imm32/no-outputs +17334 0/imm32/no-outputs +17335 0x11/imm32/alloc-id:fake +17336 _string_0f_83_jump_label/imm32/subx-name +17337 0/imm32/no-rm32 +17338 0/imm32/no-r32 +17339 0/imm32/no-imm32 +17340 0/imm32/no-imm8 +17341 1/imm32/disp32-is-first-inout +17342 0/imm32/no-output +17343 0x11/imm32/alloc-id:fake +17344 _Primitive-break-if-=-named/imm32/next +17345 _Primitive-break-if-=-named: # (payload primitive) +17346 0x11/imm32/alloc-id:fake:payload +17347 0x11/imm32/alloc-id:fake +17348 _string-break-if-=/imm32/name +17349 0x11/imm32/alloc-id:fake +17350 Single-lit-var/imm32/inouts +17351 0/imm32/no-outputs +17352 0/imm32/no-outputs +17353 0x11/imm32/alloc-id:fake +17354 _string_0f_84_jump_label/imm32/subx-name +17355 0/imm32/no-rm32 +17356 0/imm32/no-r32 +17357 0/imm32/no-imm32 +17358 0/imm32/no-imm8 +17359 1/imm32/disp32-is-first-inout +17360 0/imm32/no-output +17361 0x11/imm32/alloc-id:fake +17362 _Primitive-break-if-!=-named/imm32/next +17363 _Primitive-break-if-!=-named: # (payload primitive) +17364 0x11/imm32/alloc-id:fake:payload +17365 0x11/imm32/alloc-id:fake +17366 _string-break-if-!=/imm32/name +17367 0x11/imm32/alloc-id:fake +17368 Single-lit-var/imm32/inouts +17369 0/imm32/no-outputs +17370 0/imm32/no-outputs +17371 0x11/imm32/alloc-id:fake +17372 _string_0f_85_jump_label/imm32/subx-name +17373 0/imm32/no-rm32 +17374 0/imm32/no-r32 +17375 0/imm32/no-imm32 +17376 0/imm32/no-imm8 +17377 1/imm32/disp32-is-first-inout +17378 0/imm32/no-output +17379 0x11/imm32/alloc-id:fake +17380 _Primitive-break-if-addr<=-named/imm32/next +17381 _Primitive-break-if-addr<=-named: # (payload primitive) +17382 0x11/imm32/alloc-id:fake:payload +17383 0x11/imm32/alloc-id:fake +17384 _string-break-if-addr<=/imm32/name +17385 0x11/imm32/alloc-id:fake +17386 Single-lit-var/imm32/inouts +17387 0/imm32/no-outputs +17388 0/imm32/no-outputs +17389 0x11/imm32/alloc-id:fake +17390 _string_0f_86_jump_label/imm32/subx-name +17391 0/imm32/no-rm32 +17392 0/imm32/no-r32 +17393 0/imm32/no-imm32 +17394 0/imm32/no-imm8 +17395 1/imm32/disp32-is-first-inout +17396 0/imm32/no-output +17397 0x11/imm32/alloc-id:fake +17398 _Primitive-break-if-addr>-named/imm32/next +17399 _Primitive-break-if-addr>-named: # (payload primitive) +17400 0x11/imm32/alloc-id:fake:payload +17401 0x11/imm32/alloc-id:fake +17402 _string-break-if-addr>/imm32/name +17403 0x11/imm32/alloc-id:fake +17404 Single-lit-var/imm32/inouts +17405 0/imm32/no-outputs +17406 0/imm32/no-outputs +17407 0x11/imm32/alloc-id:fake +17408 _string_0f_87_jump_label/imm32/subx-name +17409 0/imm32/no-rm32 +17410 0/imm32/no-r32 +17411 0/imm32/no-imm32 +17412 0/imm32/no-imm8 +17413 1/imm32/disp32-is-first-inout +17414 0/imm32/no-output +17415 0x11/imm32/alloc-id:fake +17416 _Primitive-break-if-<-named/imm32/next +17417 _Primitive-break-if-<-named: # (payload primitive) +17418 0x11/imm32/alloc-id:fake:payload +17419 0x11/imm32/alloc-id:fake +17420 _string-break-if-</imm32/name +17421 0x11/imm32/alloc-id:fake +17422 Single-lit-var/imm32/inouts +17423 0/imm32/no-outputs +17424 0/imm32/no-outputs +17425 0x11/imm32/alloc-id:fake +17426 _string_0f_8c_jump_label/imm32/subx-name +17427 0/imm32/no-rm32 +17428 0/imm32/no-r32 +17429 0/imm32/no-imm32 +17430 0/imm32/no-imm8 +17431 1/imm32/disp32-is-first-inout +17432 0/imm32/no-output +17433 0x11/imm32/alloc-id:fake +17434 _Primitive-break-if->=-named/imm32/next +17435 _Primitive-break-if->=-named: # (payload primitive) +17436 0x11/imm32/alloc-id:fake:payload +17437 0x11/imm32/alloc-id:fake +17438 _string-break-if->=/imm32/name +17439 0x11/imm32/alloc-id:fake +17440 Single-lit-var/imm32/inouts +17441 0/imm32/no-outputs +17442 0/imm32/no-outputs +17443 0x11/imm32/alloc-id:fake +17444 _string_0f_8d_jump_label/imm32/subx-name +17445 0/imm32/no-rm32 +17446 0/imm32/no-r32 +17447 0/imm32/no-imm32 +17448 0/imm32/no-imm8 +17449 1/imm32/disp32-is-first-inout +17450 0/imm32/no-output +17451 0x11/imm32/alloc-id:fake +17452 _Primitive-break-if-<=-named/imm32/next +17453 _Primitive-break-if-<=-named: # (payload primitive) +17454 0x11/imm32/alloc-id:fake:payload +17455 0x11/imm32/alloc-id:fake +17456 _string-break-if-<=/imm32/name +17457 0x11/imm32/alloc-id:fake +17458 Single-lit-var/imm32/inouts +17459 0/imm32/no-outputs +17460 0/imm32/no-outputs +17461 0x11/imm32/alloc-id:fake +17462 _string_0f_8e_jump_label/imm32/subx-name +17463 0/imm32/no-rm32 +17464 0/imm32/no-r32 +17465 0/imm32/no-imm32 +17466 0/imm32/no-imm8 +17467 1/imm32/disp32-is-first-inout +17468 0/imm32/no-output +17469 0x11/imm32/alloc-id:fake +17470 _Primitive-break-if->-named/imm32/next +17471 _Primitive-break-if->-named: # (payload primitive) +17472 0x11/imm32/alloc-id:fake:payload +17473 0x11/imm32/alloc-id:fake +17474 _string-break-if->/imm32/name +17475 0x11/imm32/alloc-id:fake +17476 Single-lit-var/imm32/inouts +17477 0/imm32/no-outputs +17478 0/imm32/no-outputs +17479 0x11/imm32/alloc-id:fake +17480 _string_0f_8f_jump_label/imm32/subx-name +17481 0/imm32/no-rm32 +17482 0/imm32/no-r32 +17483 0/imm32/no-imm32 +17484 0/imm32/no-imm8 +17485 1/imm32/disp32-is-first-inout +17486 0/imm32/no-output +17487 0x11/imm32/alloc-id:fake +17488 _Primitive-break-named/imm32/next +17489 _Primitive-break-named: # (payload primitive) +17490 0x11/imm32/alloc-id:fake:payload +17491 0x11/imm32/alloc-id:fake +17492 _string-break/imm32/name +17493 0x11/imm32/alloc-id:fake +17494 Single-lit-var/imm32/inouts +17495 0/imm32/no-outputs +17496 0/imm32/no-outputs +17497 0x11/imm32/alloc-id:fake +17498 _string_e9_jump_label/imm32/subx-name +17499 0/imm32/no-rm32 +17500 0/imm32/no-r32 +17501 0/imm32/no-imm32 +17502 0/imm32/no-imm8 +17503 1/imm32/disp32-is-first-inout +17504 0/imm32/no-output +17505 0x11/imm32/alloc-id:fake +17506 _Primitive-loop-if-addr<-named/imm32/next +17507 _Primitive-loop-if-addr<-named: # (payload primitive) +17508 0x11/imm32/alloc-id:fake:payload +17509 0x11/imm32/alloc-id:fake +17510 _string-loop-if-addr</imm32/name +17511 0x11/imm32/alloc-id:fake +17512 Single-lit-var/imm32/inouts +17513 0/imm32/no-outputs +17514 0/imm32/no-outputs +17515 0x11/imm32/alloc-id:fake +17516 _string_0f_82_jump_label/imm32/subx-name +17517 0/imm32/no-rm32 +17518 0/imm32/no-r32 +17519 0/imm32/no-imm32 +17520 0/imm32/no-imm8 +17521 1/imm32/disp32-is-first-inout +17522 0/imm32/no-output +17523 0x11/imm32/alloc-id:fake +17524 _Primitive-loop-if-addr>=-named/imm32/next +17525 _Primitive-loop-if-addr>=-named: # (payload primitive) +17526 0x11/imm32/alloc-id:fake:payload +17527 0x11/imm32/alloc-id:fake +17528 _string-loop-if-addr>=/imm32/name +17529 0x11/imm32/alloc-id:fake +17530 Single-lit-var/imm32/inouts +17531 0/imm32/no-outputs +17532 0/imm32/no-outputs +17533 0x11/imm32/alloc-id:fake +17534 _string_0f_83_jump_label/imm32/subx-name +17535 0/imm32/no-rm32 +17536 0/imm32/no-r32 +17537 0/imm32/no-imm32 +17538 0/imm32/no-imm8 +17539 1/imm32/disp32-is-first-inout +17540 0/imm32/no-output +17541 0x11/imm32/alloc-id:fake +17542 _Primitive-loop-if-=-named/imm32/next +17543 _Primitive-loop-if-=-named: # (payload primitive) +17544 0x11/imm32/alloc-id:fake:payload +17545 0x11/imm32/alloc-id:fake +17546 _string-loop-if-=/imm32/name +17547 0x11/imm32/alloc-id:fake +17548 Single-lit-var/imm32/inouts +17549 0/imm32/no-outputs +17550 0/imm32/no-outputs +17551 0x11/imm32/alloc-id:fake +17552 _string_0f_84_jump_label/imm32/subx-name +17553 0/imm32/no-rm32 +17554 0/imm32/no-r32 +17555 0/imm32/no-imm32 +17556 0/imm32/no-imm8 +17557 1/imm32/disp32-is-first-inout +17558 0/imm32/no-output +17559 0x11/imm32/alloc-id:fake +17560 _Primitive-loop-if-!=-named/imm32/next +17561 _Primitive-loop-if-!=-named: # (payload primitive) +17562 0x11/imm32/alloc-id:fake:payload +17563 0x11/imm32/alloc-id:fake +17564 _string-loop-if-!=/imm32/name +17565 0x11/imm32/alloc-id:fake +17566 Single-lit-var/imm32/inouts +17567 0/imm32/no-outputs +17568 0/imm32/no-outputs +17569 0x11/imm32/alloc-id:fake +17570 _string_0f_85_jump_label/imm32/subx-name +17571 0/imm32/no-rm32 +17572 0/imm32/no-r32 +17573 0/imm32/no-imm32 +17574 0/imm32/no-imm8 +17575 1/imm32/disp32-is-first-inout +17576 0/imm32/no-output +17577 0x11/imm32/alloc-id:fake +17578 _Primitive-loop-if-addr<=-named/imm32/next +17579 _Primitive-loop-if-addr<=-named: # (payload primitive) +17580 0x11/imm32/alloc-id:fake:payload +17581 0x11/imm32/alloc-id:fake +17582 _string-loop-if-addr<=/imm32/name +17583 0x11/imm32/alloc-id:fake +17584 Single-lit-var/imm32/inouts +17585 0/imm32/no-outputs +17586 0/imm32/no-outputs +17587 0x11/imm32/alloc-id:fake +17588 _string_0f_86_jump_label/imm32/subx-name +17589 0/imm32/no-rm32 +17590 0/imm32/no-r32 +17591 0/imm32/no-imm32 +17592 0/imm32/no-imm8 +17593 1/imm32/disp32-is-first-inout +17594 0/imm32/no-output +17595 0x11/imm32/alloc-id:fake +17596 _Primitive-loop-if-addr>-named/imm32/next +17597 _Primitive-loop-if-addr>-named: # (payload primitive) +17598 0x11/imm32/alloc-id:fake:payload +17599 0x11/imm32/alloc-id:fake +17600 _string-loop-if-addr>/imm32/name +17601 0x11/imm32/alloc-id:fake +17602 Single-lit-var/imm32/inouts +17603 0/imm32/no-outputs +17604 0/imm32/no-outputs +17605 0x11/imm32/alloc-id:fake +17606 _string_0f_87_jump_label/imm32/subx-name +17607 0/imm32/no-rm32 +17608 0/imm32/no-r32 +17609 0/imm32/no-imm32 +17610 0/imm32/no-imm8 +17611 1/imm32/disp32-is-first-inout +17612 0/imm32/no-output +17613 0x11/imm32/alloc-id:fake +17614 _Primitive-loop-if-<-named/imm32/next +17615 _Primitive-loop-if-<-named: # (payload primitive) +17616 0x11/imm32/alloc-id:fake:payload +17617 0x11/imm32/alloc-id:fake +17618 _string-loop-if-</imm32/name +17619 0x11/imm32/alloc-id:fake +17620 Single-lit-var/imm32/inouts +17621 0/imm32/no-outputs +17622 0/imm32/no-outputs +17623 0x11/imm32/alloc-id:fake +17624 _string_0f_8c_jump_label/imm32/subx-name +17625 0/imm32/no-rm32 +17626 0/imm32/no-r32 +17627 0/imm32/no-imm32 +17628 0/imm32/no-imm8 +17629 1/imm32/disp32-is-first-inout +17630 0/imm32/no-output +17631 0x11/imm32/alloc-id:fake +17632 _Primitive-loop-if->=-named/imm32/next +17633 _Primitive-loop-if->=-named: # (payload primitive) +17634 0x11/imm32/alloc-id:fake:payload +17635 0x11/imm32/alloc-id:fake +17636 _string-loop-if->=/imm32/name +17637 0x11/imm32/alloc-id:fake +17638 Single-lit-var/imm32/inouts +17639 0/imm32/no-outputs +17640 0/imm32/no-outputs +17641 0x11/imm32/alloc-id:fake +17642 _string_0f_8d_jump_label/imm32/subx-name +17643 0/imm32/no-rm32 +17644 0/imm32/no-r32 +17645 0/imm32/no-imm32 +17646 0/imm32/no-imm8 +17647 1/imm32/disp32-is-first-inout +17648 0/imm32/no-output +17649 0x11/imm32/alloc-id:fake +17650 _Primitive-loop-if-<=-named/imm32/next +17651 _Primitive-loop-if-<=-named: # (payload primitive) +17652 0x11/imm32/alloc-id:fake:payload +17653 0x11/imm32/alloc-id:fake +17654 _string-loop-if-<=/imm32/name +17655 0x11/imm32/alloc-id:fake +17656 Single-lit-var/imm32/inouts +17657 0/imm32/no-outputs +17658 0/imm32/no-outputs +17659 0x11/imm32/alloc-id:fake +17660 _string_0f_8e_jump_label/imm32/subx-name +17661 0/imm32/no-rm32 +17662 0/imm32/no-r32 +17663 0/imm32/no-imm32 +17664 0/imm32/no-imm8 +17665 1/imm32/disp32-is-first-inout +17666 0/imm32/no-output +17667 0x11/imm32/alloc-id:fake +17668 _Primitive-loop-if->-named/imm32/next +17669 _Primitive-loop-if->-named: # (payload primitive) +17670 0x11/imm32/alloc-id:fake:payload +17671 0x11/imm32/alloc-id:fake +17672 _string-loop-if->/imm32/name +17673 0x11/imm32/alloc-id:fake +17674 Single-lit-var/imm32/inouts +17675 0/imm32/no-outputs +17676 0/imm32/no-outputs +17677 0x11/imm32/alloc-id:fake +17678 _string_0f_8f_jump_label/imm32/subx-name +17679 0/imm32/no-rm32 +17680 0/imm32/no-r32 +17681 0/imm32/no-imm32 +17682 0/imm32/no-imm8 +17683 1/imm32/disp32-is-first-inout +17684 0/imm32/no-output +17685 0x11/imm32/alloc-id:fake +17686 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break +17687 _Primitive-loop-named: # (payload primitive) +17688 0x11/imm32/alloc-id:fake:payload +17689 0x11/imm32/alloc-id:fake +17690 _string-loop/imm32/name +17691 0x11/imm32/alloc-id:fake +17692 Single-lit-var/imm32/inouts +17693 0/imm32/no-outputs +17694 0/imm32/no-outputs +17695 0x11/imm32/alloc-id:fake +17696 _string_e9_jump_label/imm32/subx-name +17697 0/imm32/no-rm32 +17698 0/imm32/no-r32 +17699 0/imm32/no-imm32 +17700 0/imm32/no-imm8 +17701 1/imm32/disp32-is-first-inout +17702 0/imm32/no-output +17703 0/imm32/next +17704 0/imm32/next +17705 +17706 # string literals for Mu instructions +17707 _string-add: # (payload array byte) +17708 0x11/imm32/alloc-id:fake:payload +17709 # "add" +17710 0x3/imm32/size +17711 0x61/a 0x64/d 0x64/d +17712 _string-address: # (payload array byte) +17713 0x11/imm32/alloc-id:fake:payload +17714 # "address" +17715 0x7/imm32/size +17716 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s +17717 _string-add-to: # (payload array byte) +17718 0x11/imm32/alloc-id:fake:payload +17719 # "add-to" +17720 0x6/imm32/size +17721 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o +17722 _string-and: # (payload array byte) +17723 0x11/imm32/alloc-id:fake:payload +17724 # "and" +17725 0x3/imm32/size +17726 0x61/a 0x6e/n 0x64/d +17727 _string-and-with: # (payload array byte) +17728 0x11/imm32/alloc-id:fake:payload +17729 # "and-with" +17730 0x8/imm32/size +17731 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +17732 _string-break: # (payload array byte) +17733 0x11/imm32/alloc-id:fake:payload +17734 # "break" +17735 0x5/imm32/size +17736 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k +17737 _string-break-if-<: # (payload array byte) +17738 0x11/imm32/alloc-id:fake:payload +17739 # "break-if-<" +17740 0xa/imm32/size +17741 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +17742 _string-break-if-<=: # (payload array byte) +17743 0x11/imm32/alloc-id:fake:payload +17744 # "break-if-<=" +17745 0xb/imm32/size +17746 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +17747 _string-break-if-=: # (payload array byte) +17748 0x11/imm32/alloc-id:fake:payload +17749 # "break-if-=" +17750 0xa/imm32/size +17751 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +17752 _string-break-if->: # (payload array byte) +17753 0x11/imm32/alloc-id:fake:payload +17754 # "break-if->" +17755 0xa/imm32/size +17756 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +17757 _string-break-if->=: # (payload array byte) +17758 0x11/imm32/alloc-id:fake:payload +17759 # "break-if->=" +17760 0xb/imm32/size +17761 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +17762 _string-break-if-!=: # (payload array byte) +17763 0x11/imm32/alloc-id:fake:payload +17764 # "break-if-!=" +17765 0xb/imm32/size +17766 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +17767 _string-break-if-addr<: # (payload array byte) +17768 0x11/imm32/alloc-id:fake:payload +17769 # "break-if-addr<" +17770 0xe/imm32/size +17771 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/< +17772 _string-break-if-addr<=: # (payload array byte) +17773 0x11/imm32/alloc-id:fake:payload +17774 # "break-if-addr<=" +17775 0xf/imm32/size +17776 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/= +17777 _string-break-if-addr>: # (payload array byte) +17778 0x11/imm32/alloc-id:fake:payload +17779 # "break-if-addr>" +17780 0xe/imm32/size +17781 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/> +17782 _string-break-if-addr>=: # (payload array byte) +17783 0x11/imm32/alloc-id:fake:payload +17784 # "break-if-addr>=" +17785 0xf/imm32/size +17786 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/= +17787 _string-compare: # (payload array byte) +17788 0x11/imm32/alloc-id:fake:payload +17789 # "compare" +17790 0x7/imm32/size +17791 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e +17792 _string-copy: # (payload array byte) +17793 0x11/imm32/alloc-id:fake:payload +17794 # "copy" +17795 0x4/imm32/size +17796 0x63/c 0x6f/o 0x70/p 0x79/y +17797 _string-copy-to: # (payload array byte) +17798 0x11/imm32/alloc-id:fake:payload +17799 # "copy-to" +17800 0x7/imm32/size +17801 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o +17802 _string-copy-byte: +17803 0x11/imm32/alloc-id:fake:payload +17804 # "copy-byte" +17805 0x9/imm32/size +17806 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e +17807 _string-copy-byte-to: +17808 0x11/imm32/alloc-id:fake:payload +17809 # "copy-byte-to" +17810 0xc/imm32/size +17811 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x74/t 0x6f/o +17812 _string-decrement: # (payload array byte) +17813 0x11/imm32/alloc-id:fake:payload +17814 # "decrement" +17815 0x9/imm32/size +17816 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +17817 _string-increment: # (payload array byte) +17818 0x11/imm32/alloc-id:fake:payload +17819 # "increment" +17820 0x9/imm32/size +17821 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +17822 _string-loop: # (payload array byte) +17823 0x11/imm32/alloc-id:fake:payload +17824 # "loop" +17825 0x4/imm32/size +17826 0x6c/l 0x6f/o 0x6f/o 0x70/p +17827 _string-loop-if-<: # (payload array byte) +17828 0x11/imm32/alloc-id:fake:payload +17829 # "loop-if-<" +17830 0x9/imm32/size +17831 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +17832 _string-loop-if-<=: # (payload array byte) +17833 0x11/imm32/alloc-id:fake:payload +17834 # "loop-if-<=" +17835 0xa/imm32/size +17836 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +17837 _string-loop-if-=: # (payload array byte) +17838 0x11/imm32/alloc-id:fake:payload +17839 # "loop-if-=" +17840 0x9/imm32/size +17841 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +17842 _string-loop-if->: # (payload array byte) +17843 0x11/imm32/alloc-id:fake:payload +17844 # "loop-if->" +17845 0x9/imm32/size +17846 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +17847 _string-loop-if->=: # (payload array byte) +17848 0x11/imm32/alloc-id:fake:payload +17849 # "loop-if->=" +17850 0xa/imm32/size +17851 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +17852 _string-loop-if-!=: # (payload array byte) +17853 0x11/imm32/alloc-id:fake:payload +17854 # "loop-if-!=" +17855 0xa/imm32/size +17856 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +17857 _string-loop-if-addr<: # (payload array byte) +17858 0x11/imm32/alloc-id:fake:payload +17859 # "loop-if-addr<" +17860 0xd/imm32/size +17861 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/< +17862 _string-loop-if-addr<=: # (payload array byte) +17863 0x11/imm32/alloc-id:fake:payload +17864 # "loop-if-addr<=" +17865 0xe/imm32/size +17866 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/= +17867 _string-loop-if-addr>: # (payload array byte) +17868 0x11/imm32/alloc-id:fake:payload +17869 # "loop-if-addr>" +17870 0xd/imm32/size +17871 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/> +17872 _string-loop-if-addr>=: # (payload array byte) +17873 0x11/imm32/alloc-id:fake:payload +17874 # "loop-if-addr>=" +17875 0xe/imm32/size +17876 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/= +17877 _string-multiply: # (payload array byte) +17878 0x11/imm32/alloc-id:fake:payload +17879 # "multiply" +17880 0x8/imm32/size +17881 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y +17882 _string-or: # (payload array byte) +17883 0x11/imm32/alloc-id:fake:payload +17884 # "or" +17885 0x2/imm32/size +17886 0x6f/o 0x72/r +17887 _string-or-with: # (payload array byte) +17888 0x11/imm32/alloc-id:fake:payload +17889 # "or-with" +17890 0x7/imm32/size +17891 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +17892 _string-subtract: # (payload array byte) +17893 0x11/imm32/alloc-id:fake:payload +17894 # "subtract" +17895 0x8/imm32/size +17896 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +17897 _string-subtract-from: # (payload array byte) +17898 0x11/imm32/alloc-id:fake:payload +17899 # "subtract-from" +17900 0xd/imm32/size +17901 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 +17902 _string-xor: # (payload array byte) +17903 0x11/imm32/alloc-id:fake:payload +17904 # "xor" +17905 0x3/imm32/size +17906 0x78/x 0x6f/o 0x72/r +17907 _string-xor-with: # (payload array byte) +17908 0x11/imm32/alloc-id:fake:payload +17909 # "xor-with" +17910 0x8/imm32/size +17911 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +17912 _string-shift-left: # (payload array byte) +17913 0x11/imm32/alloc-id:fake:payload +17914 # "shift-left" +17915 0xa/imm32/size +17916 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x6c/l 0x65/e 0x66/f 0x74/t +17917 _string-shift-right: # (payload array byte) +17918 0x11/imm32/alloc-id:fake:payload +17919 # "shift-right" +17920 0xb/imm32/size +17921 0x73/s 0x68/h 0x69/i 0x66/f 0x74/t 0x2d/dash 0x72/r 0x69/i 0x67/g 0x68/h 0x74/t +17922 _string-shift-right-signed: # (payload array byte) +17923 0x11/imm32/alloc-id:fake:payload +17924 # "shift-right-signed" +17925 0x12/imm32/size +17926 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 +17927 +17928 # string literals for SubX instructions +17929 _string_01_add_to: # (payload array byte) +17930 0x11/imm32/alloc-id:fake:payload +17931 # "01/add-to" +17932 0x9/imm32/size +17933 0x30/0 0x31/1 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o +17934 _string_03_add: # (payload array byte) +17935 0x11/imm32/alloc-id:fake:payload +17936 # "03/add" +17937 0x6/imm32/size +17938 0x30/0 0x33/3 0x2f/slash 0x61/a 0x64/d 0x64/d +17939 _string_05_add_to_eax: # (payload array byte) +17940 0x11/imm32/alloc-id:fake:payload +17941 # "05/add-to-eax" +17942 0xd/imm32/size +17943 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 +17944 _string_09_or_with: # (payload array byte) +17945 0x11/imm32/alloc-id:fake:payload +17946 # "09/or-with" +17947 0xa/imm32/size +17948 0x30/0 0x39/9 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +17949 _string_0b_or: # (payload array byte) +17950 0x11/imm32/alloc-id:fake:payload +17951 # "0b/or" +17952 0x5/imm32/size +17953 0x30/0 0x62/b 0x2f/slash 0x6f/o 0x72/r +17954 _string_0d_or_with_eax: # (payload array byte) +17955 0x11/imm32/alloc-id:fake:payload +17956 # "0d/or-with-eax" +17957 0xe/imm32/size +17958 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 +17959 _string_0f_82_jump_label: # (payload array byte) +17960 0x11/imm32/alloc-id:fake:payload +17961 # "0f 82/jump-if-addr<" +17962 0x13/imm32/size +17963 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/< +17964 _string_0f_82_jump_break: # (payload array byte) +17965 0x11/imm32/alloc-id:fake:payload +17966 # "0f 82/jump-if-addr< break/disp32" +17967 0x20/imm32/size +17968 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 +17969 _string_0f_82_jump_loop: # (payload array byte) +17970 0x11/imm32/alloc-id:fake:payload +17971 # "0f 82/jump-if-addr< loop/disp32" +17972 0x1f/imm32/size +17973 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 +17974 _string_0f_83_jump_label: # (payload array byte) +17975 0x11/imm32/alloc-id:fake:payload +17976 # "0f 83/jump-if-addr>=" +17977 0x14/imm32/size +17978 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/= +17979 _string_0f_83_jump_break: # (payload array byte) +17980 0x11/imm32/alloc-id:fake:payload +17981 # "0f 83/jump-if-addr>= break/disp32" +17982 0x21/imm32/size +17983 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 +17984 _string_0f_83_jump_loop: # (payload array byte) +17985 0x11/imm32/alloc-id:fake:payload +17986 # "0f 83/jump-if-addr>= loop/disp32" +17987 0x20/imm32/size +17988 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 +17989 _string_0f_84_jump_label: # (payload array byte) +17990 0x11/imm32/alloc-id:fake:payload +17991 # "0f 84/jump-if-=" +17992 0xf/imm32/size +17993 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/= +17994 _string_0f_84_jump_break: # (payload array byte) +17995 0x11/imm32/alloc-id:fake:payload +17996 # "0f 84/jump-if-= break/disp32" +17997 0x1c/imm32/size +17998 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 +17999 _string_0f_84_jump_loop: # (payload array byte) +18000 0x11/imm32/alloc-id:fake:payload +18001 # "0f 84/jump-if-= loop/disp32" +18002 0x1b/imm32/size +18003 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 +18004 _string_0f_85_jump_label: # (payload array byte) +18005 0x11/imm32/alloc-id:fake:payload +18006 # "0f 85/jump-if-!=" +18007 0x10/imm32/size +18008 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/= +18009 _string_0f_85_jump_break: # (payload array byte) +18010 0x11/imm32/alloc-id:fake:payload +18011 # "0f 85/jump-if-!= break/disp32" +18012 0x1d/imm32/size +18013 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 +18014 _string_0f_85_jump_loop: # (payload array byte) +18015 0x11/imm32/alloc-id:fake:payload +18016 # "0f 85/jump-if-!= loop/disp32" +18017 0x1c/imm32/size +18018 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 +18019 _string_0f_86_jump_label: # (payload array byte) +18020 0x11/imm32/alloc-id:fake:payload +18021 # "0f 86/jump-if-addr<=" +18022 0x14/imm32/size +18023 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/= +18024 _string_0f_86_jump_break: # (payload array byte) +18025 0x11/imm32/alloc-id:fake:payload +18026 # "0f 86/jump-if-addr<= break/disp32" +18027 0x21/imm32/size +18028 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 +18029 _string_0f_86_jump_loop: # (payload array byte) +18030 0x11/imm32/alloc-id:fake:payload +18031 # "0f 86/jump-if-addr<= loop/disp32" +18032 0x20/imm32/size +18033 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 +18034 _string_0f_87_jump_label: # (payload array byte) +18035 0x11/imm32/alloc-id:fake:payload +18036 # "0f 87/jump-if-addr>" +18037 0x13/imm32/size +18038 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/> +18039 _string_0f_87_jump_break: # (payload array byte) +18040 0x11/imm32/alloc-id:fake:payload +18041 # "0f 87/jump-if-addr> break/disp32" +18042 0x20/imm32/size +18043 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 +18044 _string_0f_87_jump_loop: # (payload array byte) +18045 0x11/imm32/alloc-id:fake:payload +18046 # "0f 87/jump-if-addr> loop/disp32" +18047 0x1f/imm32/size +18048 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 +18049 _string_0f_8c_jump_label: # (payload array byte) +18050 0x11/imm32/alloc-id:fake:payload +18051 # "0f 8c/jump-if-<" +18052 0xf/imm32/size +18053 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/< +18054 _string_0f_8c_jump_break: # (payload array byte) +18055 0x11/imm32/alloc-id:fake:payload +18056 # "0f 8c/jump-if-< break/disp32" +18057 0x1c/imm32/size +18058 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 +18059 _string_0f_8c_jump_loop: # (payload array byte) +18060 0x11/imm32/alloc-id:fake:payload +18061 # "0f 8c/jump-if-< loop/disp32" +18062 0x1b/imm32/size +18063 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 +18064 _string_0f_8d_jump_label: # (payload array byte) +18065 0x11/imm32/alloc-id:fake:payload +18066 # "0f 8d/jump-if->=" +18067 0x10/imm32/size +18068 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/= +18069 _string_0f_8d_jump_break: # (payload array byte) +18070 0x11/imm32/alloc-id:fake:payload +18071 # "0f 8d/jump-if->= break/disp32" +18072 0x1d/imm32/size +18073 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 +18074 _string_0f_8d_jump_loop: # (payload array byte) +18075 0x11/imm32/alloc-id:fake:payload +18076 # "0f 8d/jump-if->= loop/disp32" +18077 0x1c/imm32/size +18078 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 +18079 _string_0f_8e_jump_label: # (payload array byte) +18080 0x11/imm32/alloc-id:fake:payload +18081 # "0f 8e/jump-if-<=" +18082 0x10/imm32/size +18083 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/= +18084 _string_0f_8e_jump_break: # (payload array byte) +18085 0x11/imm32/alloc-id:fake:payload +18086 # "0f 8e/jump-if-<= break/disp32" +18087 0x1d/imm32/size +18088 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 +18089 _string_0f_8e_jump_loop: # (payload array byte) +18090 0x11/imm32/alloc-id:fake:payload +18091 # "0f 8e/jump-if-<= loop/disp32" +18092 0x1c/imm32/size +18093 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 +18094 _string_0f_8f_jump_label: # (payload array byte) +18095 0x11/imm32/alloc-id:fake:payload +18096 # "0f 8f/jump-if->" +18097 0xf/imm32/size +18098 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/> +18099 _string_0f_8f_jump_break: # (payload array byte) +18100 0x11/imm32/alloc-id:fake:payload +18101 # "0f 8f/jump-if-> break/disp32" +18102 0x1c/imm32/size +18103 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 +18104 _string_0f_8f_jump_loop: # (payload array byte) +18105 0x11/imm32/alloc-id:fake:payload +18106 # "0f 8f/jump-if-> loop/disp32" +18107 0x1b/imm32/size +18108 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 +18109 _string_0f_af_multiply: # (payload array byte) +18110 0x11/imm32/alloc-id:fake:payload +18111 # "0f af/multiply" +18112 0xe/imm32/size +18113 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 +18114 _string_21_and_with: # (payload array byte) +18115 0x11/imm32/alloc-id:fake:payload +18116 # "21/and-with" +18117 0xb/imm32/size +18118 0x32/2 0x31/1 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +18119 _string_23_and: # (payload array byte) +18120 0x11/imm32/alloc-id:fake:payload +18121 # "23/and" +18122 0x6/imm32/size +18123 0x32/2 0x33/3 0x2f/slash 0x61/a 0x6e/n 0x64/d +18124 _string_25_and_with_eax: # (payload array byte) +18125 0x11/imm32/alloc-id:fake:payload +18126 # "25/and-with-eax" +18127 0xf/imm32/size +18128 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 +18129 _string_29_subtract_from: # (payload array byte) +18130 0x11/imm32/alloc-id:fake:payload +18131 # "29/subtract-from" +18132 0x10/imm32/size +18133 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 +18134 _string_2b_subtract: # (payload array byte) +18135 0x11/imm32/alloc-id:fake:payload +18136 # "2b/subtract" +18137 0xb/imm32/size +18138 0x32/2 0x62/b 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +18139 _string_2d_subtract_from_eax: # (payload array byte) +18140 0x11/imm32/alloc-id:fake:payload +18141 # "2d/subtract-from-eax" +18142 0x14/imm32/size +18143 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 +18144 _string_31_xor_with: # (payload array byte) +18145 0x11/imm32/alloc-id:fake:payload +18146 # "31/xor-with" +18147 0xb/imm32/size +18148 0x33/3 0x31/1 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +18149 _string_33_xor: # (payload array byte) +18150 0x11/imm32/alloc-id:fake:payload +18151 # "33/xor" +18152 0x6/imm32/size +18153 0x33/3 0x33/3 0x2f/slash 0x78/x 0x6f/o 0x72/r +18154 _string_35_xor_with_eax: # (payload array byte) +18155 0x11/imm32/alloc-id:fake:payload +18156 # "35/xor-with-eax" +18157 0xf/imm32/size +18158 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 +18159 _string_39_compare->: # (payload array byte) +18160 0x11/imm32/alloc-id:fake:payload +18161 # "39/compare->" +18162 0xc/imm32/size +18163 0x33/3 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x3e/> +18164 _string_3b_compare<-: # (payload array byte) +18165 0x11/imm32/alloc-id:fake:payload +18166 # "3b/compare<-" +18167 0xc/imm32/size +18168 0x33/3 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x3c/< 0x2d/dash +18169 _string_3d_compare_eax_with: # (payload array byte) +18170 0x11/imm32/alloc-id:fake:payload +18171 # "3d/compare-eax-with" +18172 0x13/imm32/size +18173 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 +18174 _string_40_increment_eax: # (payload array byte) +18175 0x11/imm32/alloc-id:fake:payload +18176 # "40/increment-eax" +18177 0x10/imm32/size +18178 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 +18179 _string_41_increment_ecx: # (payload array byte) +18180 0x11/imm32/alloc-id:fake:payload +18181 # "41/increment-ecx" +18182 0x10/imm32/size +18183 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 +18184 _string_42_increment_edx: # (payload array byte) +18185 0x11/imm32/alloc-id:fake:payload +18186 # "42/increment-edx" +18187 0x10/imm32/size +18188 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 +18189 _string_43_increment_ebx: # (payload array byte) +18190 0x11/imm32/alloc-id:fake:payload +18191 # "43/increment-ebx" +18192 0x10/imm32/size +18193 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 +18194 _string_46_increment_esi: # (payload array byte) +18195 0x11/imm32/alloc-id:fake:payload +18196 # "46/increment-esi" +18197 0x10/imm32/size +18198 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 +18199 _string_47_increment_edi: # (payload array byte) +18200 0x11/imm32/alloc-id:fake:payload +18201 # "47/increment-edi" +18202 0x10/imm32/size +18203 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 +18204 _string_48_decrement_eax: # (payload array byte) +18205 0x11/imm32/alloc-id:fake:payload +18206 # "48/decrement-eax" +18207 0x10/imm32/size +18208 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 +18209 _string_49_decrement_ecx: # (payload array byte) +18210 0x11/imm32/alloc-id:fake:payload +18211 # "49/decrement-ecx" +18212 0x10/imm32/size +18213 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 +18214 _string_4a_decrement_edx: # (payload array byte) +18215 0x11/imm32/alloc-id:fake:payload +18216 # "4a/decrement-edx" +18217 0x10/imm32/size +18218 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 +18219 _string_4b_decrement_ebx: # (payload array byte) +18220 0x11/imm32/alloc-id:fake:payload +18221 # "4b/decrement-ebx" +18222 0x10/imm32/size +18223 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 +18224 _string_4e_decrement_esi: # (payload array byte) +18225 0x11/imm32/alloc-id:fake:payload +18226 # "4e/decrement-esi" +18227 0x10/imm32/size +18228 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 +18229 _string_4f_decrement_edi: # (payload array byte) +18230 0x11/imm32/alloc-id:fake:payload +18231 # "4f/decrement-edi" +18232 0x10/imm32/size +18233 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 +18234 _string_81_subop_add: # (payload array byte) +18235 0x11/imm32/alloc-id:fake:payload +18236 # "81 0/subop/add" +18237 0xe/imm32/size +18238 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 +18239 _string_81_subop_or: # (payload array byte) +18240 0x11/imm32/alloc-id:fake:payload +18241 # "81 1/subop/or" +18242 0xd/imm32/size +18243 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 +18244 _string_81_subop_and: # (payload array byte) +18245 0x11/imm32/alloc-id:fake:payload +18246 # "81 4/subop/and" +18247 0xe/imm32/size +18248 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 +18249 _string_81_subop_subtract: # (payload array byte) +18250 0x11/imm32/alloc-id:fake:payload +18251 # "81 5/subop/subtract" +18252 0x13/imm32/size +18253 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 +18254 _string_81_subop_xor: # (payload array byte) +18255 0x11/imm32/alloc-id:fake:payload +18256 # "81 6/subop/xor" +18257 0xe/imm32/size +18258 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 +18259 _string_81_subop_compare: # (payload array byte) +18260 0x11/imm32/alloc-id:fake:payload +18261 # "81 7/subop/compare" +18262 0x12/imm32/size +18263 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 +18264 _string_89_<-: # (payload array byte) +18265 0x11/imm32/alloc-id:fake:payload +18266 # "89/<-" +18267 0x5/imm32/size +18268 0x38/8 0x39/9 0x2f/slash 0x3c/< 0x2d/dash +18269 _string_8b_->: # (payload array byte) +18270 0x11/imm32/alloc-id:fake:payload +18271 # "8b/->" +18272 0x5/imm32/size +18273 0x38/8 0x62/b 0x2f/slash 0x2d/dash 0x3e/> +18274 _string_8a_copy_byte: +18275 0x11/imm32/alloc-id:fake:payload +18276 # "8a/byte->" +18277 0x9/imm32/size +18278 0x38/8 0x61/a 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x3e/> +18279 _string_88_copy_byte: +18280 0x11/imm32/alloc-id:fake:payload +18281 # "88/byte<-" +18282 0x9/imm32/size +18283 0x38/8 0x38/8 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/- +18284 _string_8d_copy_address: # (payload array byte) +18285 0x11/imm32/alloc-id:fake:payload +18286 # "8d/copy-address" +18287 0xf/imm32/size +18288 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 +18289 _string_b8_copy_to_eax: # (payload array byte) +18290 0x11/imm32/alloc-id:fake:payload +18291 # "b8/copy-to-eax" +18292 0xe/imm32/size +18293 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 +18294 _string_b9_copy_to_ecx: # (payload array byte) +18295 0x11/imm32/alloc-id:fake:payload +18296 # "b9/copy-to-ecx" +18297 0xe/imm32/size +18298 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 +18299 _string_ba_copy_to_edx: # (payload array byte) +18300 0x11/imm32/alloc-id:fake:payload +18301 # "ba/copy-to-edx" +18302 0xe/imm32/size +18303 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 +18304 _string_bb_copy_to_ebx: # (payload array byte) +18305 0x11/imm32/alloc-id:fake:payload +18306 # "bb/copy-to-ebx" +18307 0xe/imm32/size +18308 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 +18309 _string_be_copy_to_esi: # (payload array byte) +18310 0x11/imm32/alloc-id:fake:payload +18311 # "be/copy-to-esi" +18312 0xe/imm32/size +18313 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 +18314 _string_bf_copy_to_edi: # (payload array byte) +18315 0x11/imm32/alloc-id:fake:payload +18316 # "bf/copy-to-edi" +18317 0xe/imm32/size +18318 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 +18319 _string_c7_subop_copy: # (payload array byte) +18320 0x11/imm32/alloc-id:fake:payload +18321 # "c7 0/subop/copy" +18322 0xf/imm32/size +18323 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 +18324 _string_e9_jump_label: # (payload array byte) +18325 0x11/imm32/alloc-id:fake:payload +18326 # "e9/jump" +18327 0x7/imm32/size +18328 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p +18329 _string_e9_jump_break: # (payload array byte) +18330 0x11/imm32/alloc-id:fake:payload +18331 # "e9/jump break/disp32" +18332 0x14/imm32/size +18333 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 +18334 _string_e9_jump_loop: # (payload array byte) +18335 0x11/imm32/alloc-id:fake:payload +18336 # "e9/jump loop/disp32" +18337 0x13/imm32/size +18338 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 +18339 _string_ff_subop_increment: # (payload array byte) +18340 0x11/imm32/alloc-id:fake:payload +18341 # "ff 0/subop/increment" +18342 0x14/imm32/size +18343 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 +18344 _string_ff_subop_decrement: # (payload array byte) +18345 0x11/imm32/alloc-id:fake:payload +18346 # "ff 1/subop/decrement" +18347 0x14/imm32/size +18348 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 +18349 _string_c1_subop_shift_left: # (payload array byte) +18350 0x11/imm32/alloc-id:fake:payload +18351 # "c1/shift 4/subop/left" +18352 0x15/imm32/size +18353 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 +18354 _string_c1_subop_shift_right_padding_zeroes: # (payload array byte) +18355 0x11/imm32/alloc-id:fake:payload +18356 # "c1/shift 5/subop/right-padding-zeroes" +18357 0x25/imm32/size +18358 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 +18359 _string_c1_subop_shift_right_preserving_sign: # (payload array byte) +18360 0x11/imm32/alloc-id:fake:payload +18361 # "c1/shift 7/subop/right-preserving-sign" +18362 0x26/imm32/size +18363 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 +18364 +18365 Single-int-var-in-mem: # (payload list var) +18366 0x11/imm32/alloc-id:fake:payload +18367 0x11/imm32/alloc-id:fake +18368 Int-var-in-mem/imm32 +18369 0/imm32/next +18370 0/imm32/next +18371 +18372 Int-var-in-mem: # (payload var) +18373 0x11/imm32/alloc-id:fake:payload +18374 0/imm32/name +18375 0/imm32/name +18376 0x11/imm32/alloc-id:fake +18377 Type-int/imm32 +18378 1/imm32/some-block-depth +18379 1/imm32/some-stack-offset +18380 0/imm32/no-register +18381 0/imm32/no-register +18382 +18383 # Not really legal, but closest we can currently represent a dereference of an (addr byte) +18384 Single-byte-var-in-mem: # (payload list var) +18385 0x11/imm32/alloc-id:fake:payload +18386 0x11/imm32/alloc-id:fake +18387 Byte-var-in-mem/imm32 +18388 0/imm32/next +18389 0/imm32/next +18390 +18391 # Not really legal, but closest we can currently represent a dereference of an (addr byte) +18392 Byte-var-in-mem: # (payload var) +18393 0x11/imm32/alloc-id:fake:payload +18394 0/imm32/name +18395 0/imm32/name +18396 0x11/imm32/alloc-id:fake +18397 Type-byte/imm32 +18398 1/imm32/some-block-depth +18399 1/imm32/some-stack-offset +18400 0/imm32/no-register +18401 0/imm32/no-register +18402 +18403 Two-args-int-stack-int-reg: # (payload list var) +18404 0x11/imm32/alloc-id:fake:payload +18405 0x11/imm32/alloc-id:fake +18406 Int-var-in-mem/imm32 +18407 0x11/imm32/alloc-id:fake +18408 Single-int-var-in-some-register/imm32/next +18409 +18410 Two-int-args-in-regs: # (payload list var) +18411 0x11/imm32/alloc-id:fake:payload +18412 0x11/imm32/alloc-id:fake +18413 Int-var-in-some-register/imm32 +18414 0x11/imm32/alloc-id:fake +18415 Single-int-var-in-some-register/imm32/next 18416 -18417 test-emit-subx-stmt-primitive-register: -18418 # Primitive operation on a variable in a register. -18419 # foo <- increment -18420 # => -18421 # ff 0/subop/increment %eax # sub-optimal, but should suffice -18422 # -18423 # There's a variable on the var stack as follows: -18424 # name: 'foo' -18425 # type: int -18426 # register: 'eax' -18427 # -18428 # There's a primitive with this info: -18429 # name: 'increment' -18430 # out: int/reg -18431 # value: 'ff 0/subop/increment' -18432 # -18433 # . prologue -18434 55/push-ebp -18435 89/<- %ebp 4/r32/esp -18436 # setup -18437 (clear-stream _test-output-stream) -18438 (clear-stream $_test-output-buffered-file->buffer) -18439 $test-emit-subx-stmt-primitive-register:initialize-type: -18440 # var type/ecx: (payload type-tree) = int -18441 68/push 0/imm32/right:null -18442 68/push 0/imm32/right:null -18443 68/push 0/imm32/left:unused -18444 68/push 1/imm32/value:int -18445 68/push 1/imm32/is-atom?:true -18446 68/push 0x11/imm32/alloc-id:fake:payload -18447 89/<- %ecx 4/r32/esp -18448 $test-emit-subx-stmt-primitive-register:initialize-var: -18449 # var var-foo/ecx: (payload var) -18450 68/push 0/imm32/register -18451 68/push 0/imm32/register -18452 68/push 0/imm32/no-stack-offset -18453 68/push 1/imm32/block-depth -18454 51/push-ecx -18455 68/push 0x11/imm32/alloc-id:fake -18456 68/push 0/imm32/name -18457 68/push 0/imm32/name -18458 68/push 0x11/imm32/alloc-id:fake:payload -18459 89/<- %ecx 4/r32/esp -18460 $test-emit-subx-stmt-primitive-register:initialize-var-name: -18461 # var-foo->name = "foo" -18462 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -18463 (copy-array Heap "foo" %eax) -18464 $test-emit-subx-stmt-primitive-register:initialize-var-register: -18465 # var-foo->register = "eax" -18466 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -18467 (copy-array Heap "eax" %eax) -18468 $test-emit-subx-stmt-primitive-register:initialize-stmt-var: -18469 # var operand/ebx: (payload stmt-var) -18470 68/push 0/imm32/is-deref:false -18471 68/push 0/imm32/next -18472 68/push 0/imm32/next -18473 51/push-ecx/var-foo -18474 68/push 0x11/imm32/alloc-id:fake -18475 68/push 0x11/imm32/alloc-id:fake:payload -18476 89/<- %ebx 4/r32/esp -18477 $test-emit-subx-stmt-primitive-register:initialize-stmt: -18478 # var stmt/esi: (addr statement) -18479 53/push-ebx/outputs -18480 68/push 0x11/imm32/alloc-id:fake -18481 68/push 0/imm32/no-inouts -18482 68/push 0/imm32/no-inouts -18483 68/push 0/imm32/operation -18484 68/push 0/imm32/operation -18485 68/push 1/imm32 -18486 89/<- %esi 4/r32/esp -18487 $test-emit-subx-stmt-primitive-register:initialize-stmt-operation: -18488 # stmt->operation = "increment" -18489 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -18490 (copy-array Heap "increment" %eax) -18491 $test-emit-subx-stmt-primitive-register:initialize-formal-var: -18492 # var formal-var/ebx: (payload var) -18493 68/push 0/imm32/register -18494 68/push 0/imm32/register -18495 68/push 0/imm32/no-stack-offset -18496 68/push 1/imm32/block-depth -18497 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -18498 68/push 0x11/imm32/alloc-id:fake -18499 68/push 0/imm32/name -18500 68/push 0/imm32/name -18501 68/push 0x11/imm32/alloc-id:fake:payload -18502 89/<- %ebx 4/r32/esp -18503 $test-emit-subx-stmt-primitive-register:initialize-formal-var-name: -18504 # formal-var->name = "dummy" -18505 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -18506 (copy-array Heap "dummy" %eax) -18507 $test-emit-subx-stmt-primitive-register:initialize-formal-register: -18508 # formal-var->register = "*" -18509 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -18510 (copy-array Heap "*" %eax) # Any-register -18511 $test-emit-subx-stmt-primitive-register:initialize-var-list: -18512 # var formal-outputs/ebx: (payload list var) -18513 68/push 0/imm32/next -18514 68/push 0/imm32/next -18515 53/push-ebx/formal-var -18516 68/push 0x11/imm32/alloc-id:fake -18517 68/push 0x11/imm32/alloc-id:fake:payload -18518 89/<- %ebx 4/r32/esp -18519 $test-emit-subx-stmt-primitive-register:initialize-primitive: -18520 # var primitives/ebx: (addr primitive) -18521 68/push 0/imm32/next -18522 68/push 0/imm32/next -18523 68/push 0/imm32/output-is-write-only -18524 68/push 0/imm32/no-disp32 -18525 68/push 0/imm32/no-imm32 -18526 68/push 0/imm32/no-r32 -18527 68/push 3/imm32/rm32-is-first-output -18528 68/push 0/imm32/subx-name -18529 68/push 0/imm32/subx-name -18530 53/push-ebx/outputs -18531 68/push 0x11/imm32/alloc-id:fake -18532 68/push 0/imm32/no-inouts -18533 68/push 0/imm32/no-inouts -18534 68/push 0/imm32/name -18535 68/push 0/imm32/name -18536 89/<- %ebx 4/r32/esp -18537 $test-emit-subx-stmt-primitive-register:initialize-primitive-name: -18538 # primitives->name = "increment" -18539 (copy-array Heap "increment" %ebx) # Primitive-name -18540 $test-emit-subx-stmt-primitive-register:initialize-primitive-subx-name: -18541 # primitives->subx-name = "ff 0/subop/increment" -18542 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -18543 (copy-array Heap "ff 0/subop/increment" %eax) -18544 # convert -18545 c7 0/subop/copy *Curr-block-depth 0/imm32 -18546 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) -18547 (flush _test-output-buffered-file) -18548 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -18554 # check output -18555 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-primitive-register") -18556 # . epilogue -18557 89/<- %esp 5/r32/ebp -18558 5d/pop-to-ebp -18559 c3/return -18560 -18561 test-emit-subx-stmt-select-primitive: -18562 # Select the right primitive between overloads. -18563 # foo <- increment -18564 # => -18565 # ff 0/subop/increment %eax # sub-optimal, but should suffice -18566 # -18567 # There's a variable on the var stack as follows: -18568 # name: 'foo' -18569 # type: int -18570 # register: 'eax' -18571 # -18572 # There's two primitives, as follows: -18573 # - name: 'increment' -18574 # out: int/reg -18575 # value: 'ff 0/subop/increment' -18576 # - name: 'increment' -18577 # inout: int/mem -18578 # value: 'ff 0/subop/increment' -18579 # -18580 # . prologue -18581 55/push-ebp -18582 89/<- %ebp 4/r32/esp -18583 # setup -18584 (clear-stream _test-output-stream) -18585 (clear-stream $_test-output-buffered-file->buffer) -18586 $test-emit-subx-stmt-select-primitive:initialize-type: -18587 # var type/ecx: (payload type-tree) = int -18588 68/push 0/imm32/right:null -18589 68/push 0/imm32/right:null -18590 68/push 0/imm32/left:unused -18591 68/push 1/imm32/value:int -18592 68/push 1/imm32/is-atom?:true -18593 68/push 0x11/imm32/alloc-id:fake:payload -18594 89/<- %ecx 4/r32/esp -18595 $test-emit-subx-stmt-select-primitive:initialize-var: -18596 # var var-foo/ecx: (payload var) -18597 68/push 0/imm32/register -18598 68/push 0/imm32/register -18599 68/push 0/imm32/no-stack-offset -18600 68/push 1/imm32/block-depth -18601 51/push-ecx -18602 68/push 0x11/imm32/alloc-id:fake -18603 68/push 0/imm32/name -18604 68/push 0/imm32/name -18605 68/push 0x11/imm32/alloc-id:fake:payload -18606 89/<- %ecx 4/r32/esp -18607 $test-emit-subx-stmt-select-primitive:initialize-var-name: -18608 # var-foo->name = "foo" -18609 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -18610 (copy-array Heap "foo" %eax) -18611 $test-emit-subx-stmt-select-primitive:initialize-var-register: -18612 # var-foo->register = "eax" -18613 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -18614 (copy-array Heap "eax" %eax) -18615 $test-emit-subx-stmt-select-primitive:initialize-stmt-var: -18616 # var operand/ebx: (payload stmt-var) -18617 68/push 0/imm32/is-deref:false -18618 68/push 0/imm32/next -18619 68/push 0/imm32/next -18620 51/push-ecx/var-foo -18621 68/push 0x11/imm32/alloc-id:fake -18622 68/push 0x11/imm32/alloc-id:fake:payload -18623 89/<- %ebx 4/r32/esp -18624 $test-emit-subx-stmt-select-primitive:initialize-stmt: -18625 # var stmt/esi: (addr statement) -18626 53/push-ebx/outputs -18627 68/push 0x11/imm32/alloc-id:fake -18628 68/push 0/imm32/no-inouts -18629 68/push 0/imm32/no-inouts -18630 68/push 0/imm32/operation -18631 68/push 0/imm32/operation -18632 68/push 1/imm32 -18633 89/<- %esi 4/r32/esp -18634 $test-emit-subx-stmt-select-primitive:initialize-stmt-operation: -18635 # stmt->operation = "increment" -18636 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -18637 (copy-array Heap "increment" %eax) -18638 $test-emit-subx-stmt-select-primitive:initialize-formal-var: -18639 # var formal-var/ebx: (payload var) -18640 68/push 0/imm32/register -18641 68/push 0/imm32/register -18642 68/push 0/imm32/no-stack-offset -18643 68/push 1/imm32/block-depth -18644 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -18645 68/push 0x11/imm32/alloc-id:fake -18646 68/push 0/imm32/name -18647 68/push 0/imm32/name -18648 68/push 0x11/imm32/alloc-id:fake:payload -18649 89/<- %ebx 4/r32/esp -18650 $test-emit-subx-stmt-select-primitive:initialize-formal-var-name: -18651 # formal-var->name = "dummy" -18652 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -18653 (copy-array Heap "dummy" %eax) -18654 $test-emit-subx-stmt-select-primitive:initialize-formal-register: -18655 # formal-var->register = "*" -18656 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -18657 (copy-array Heap "*" %eax) # Any-register -18658 $test-emit-subx-stmt-select-primitive:initialize-var-list: -18659 # var formal-outputs/ebx: (payload list var) -18660 68/push 0/imm32/next -18661 68/push 0/imm32/next -18662 53/push-ebx/formal-var -18663 68/push 0x11/imm32/alloc-id:fake -18664 68/push 0x11/imm32/alloc-id:fake:payload -18665 89/<- %ebx 4/r32/esp -18666 $test-emit-subx-stmt-select-primitive:initialize-primitive2: -18667 # var primitive2/edi: (payload primitive) -18668 68/push 0/imm32/next -18669 68/push 0/imm32/next -18670 68/push 0/imm32/output-is-write-only -18671 68/push 0/imm32/no-disp32 -18672 68/push 0/imm32/no-imm32 -18673 68/push 0/imm32/no-r32 -18674 68/push 3/imm32/rm32-is-first-output -18675 68/push 0/imm32/subx-name -18676 68/push 0/imm32/subx-name -18677 53/push-ebx/outputs -18678 68/push 0x11/imm32/alloc-id:fake -18679 68/push 0/imm32/no-inouts -18680 68/push 0/imm32/no-inouts -18681 68/push 0/imm32/name -18682 68/push 0/imm32/name -18683 68/push 0x11/imm32/alloc-id:fake:payload -18684 89/<- %edi 4/r32/esp -18685 $test-emit-subx-stmt-select-primitive:initialize-primitive2-name: -18686 # primitives->name = "increment" -18687 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 -18688 (copy-array Heap "increment" %eax) -18689 $test-emit-subx-stmt-select-primitive:initialize-primitive2-subx-name: -18690 # primitives->subx-name = "ff 0/subop/increment" -18691 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 -18692 (copy-array Heap "ff 0/subop/increment" %eax) -18693 $test-emit-subx-stmt-select-primitive:initialize-primitive: -18694 # var primitives/ebx: (addr primitive) -18695 57/push-edi -18696 68/push 0x11/imm32/alloc-id:fake -18697 68/push 0/imm32/output-is-write-only -18698 68/push 0/imm32/no-disp32 -18699 68/push 0/imm32/no-imm32 -18700 68/push 0/imm32/no-r32 -18701 68/push 1/imm32/rm32-is-first-inout -18702 68/push 0/imm32/subx-name -18703 68/push 0/imm32/subx-name -18704 68/push 0/imm32/no-outputs -18705 68/push 0/imm32/no-outputs -18706 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration -18707 68/push 0x11/imm32/alloc-id:fake -18708 68/push 0/imm32/name -18709 68/push 0/imm32/name -18710 89/<- %ebx 4/r32/esp -18711 $test-emit-subx-stmt-select-primitive:initialize-primitive-name: -18712 # primitives->name = "increment" -18713 (copy-array Heap "increment" %ebx) # Primitive-name -18714 $test-emit-subx-stmt-select-primitive:initialize-primitive-subx-name: -18715 # primitives->subx-name = "ff 0/subop/increment" -18716 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -18717 (copy-array Heap "ff 0/subop/increment" %eax) -18718 # convert -18719 c7 0/subop/copy *Curr-block-depth 0/imm32 -18720 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) -18721 (flush _test-output-buffered-file) -18722 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -18728 # check output -18729 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive") -18730 # . epilogue -18731 89/<- %esp 5/r32/ebp -18732 5d/pop-to-ebp -18733 c3/return -18734 -18735 test-emit-subx-stmt-select-primitive-2: -18736 # Select the right primitive between overloads. -18737 # increment foo -18738 # => -18739 # ff 0/subop/increment %eax # sub-optimal, but should suffice -18740 # -18741 # There's a variable on the var stack as follows: -18742 # name: 'foo' -18743 # type: int -18744 # register: 'eax' -18745 # -18746 # There's two primitives, as follows: -18747 # - name: 'increment' -18748 # out: int/reg -18749 # value: 'ff 0/subop/increment' -18750 # - name: 'increment' -18751 # inout: int/mem -18752 # value: 'ff 0/subop/increment' -18753 # -18754 # . prologue -18755 55/push-ebp -18756 89/<- %ebp 4/r32/esp -18757 # setup -18758 (clear-stream _test-output-stream) -18759 (clear-stream $_test-output-buffered-file->buffer) -18760 $test-emit-subx-stmt-select-primitive-2:initialize-type: -18761 # var type/ecx: (payload type-tree) = int -18762 68/push 0/imm32/right:null -18763 68/push 0/imm32/right:null -18764 68/push 0/imm32/left:unused -18765 68/push 1/imm32/value:int -18766 68/push 1/imm32/is-atom?:true -18767 68/push 0x11/imm32/alloc-id:fake:payload -18768 89/<- %ecx 4/r32/esp -18769 $test-emit-subx-stmt-select-primitive-2:initialize-var: -18770 # var var-foo/ecx: (payload var) -18771 68/push 0/imm32/register -18772 68/push 0/imm32/register -18773 68/push 0/imm32/no-stack-offset -18774 68/push 1/imm32/block-depth -18775 51/push-ecx -18776 68/push 0x11/imm32/alloc-id:fake -18777 68/push 0/imm32/name -18778 68/push 0/imm32/name -18779 68/push 0x11/imm32/alloc-id:fake:payload -18780 89/<- %ecx 4/r32/esp -18781 $test-emit-subx-stmt-select-primitive-2:initialize-var-name: -18782 # var-foo->name = "foo" -18783 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -18784 (copy-array Heap "foo" %eax) -18785 $test-emit-subx-stmt-select-primitive-2:initialize-var-register: -18786 # var-foo->register = "eax" -18787 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -18788 (copy-array Heap "eax" %eax) -18789 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-var: -18790 # var operand/ebx: (payload stmt-var) -18791 68/push 0/imm32/is-deref:false -18792 68/push 0/imm32/next -18793 68/push 0/imm32/next -18794 51/push-ecx/var-foo -18795 68/push 0x11/imm32/alloc-id:fake -18796 68/push 0x11/imm32/alloc-id:fake:payload -18797 89/<- %ebx 4/r32/esp -18798 $test-emit-subx-stmt-select-primitive-2:initialize-stmt: -18799 # var stmt/esi: (addr statement) -18800 68/push 0/imm32/no-outputs -18801 68/push 0/imm32/no-outputs -18802 53/push-ebx/inouts -18803 68/push 0x11/imm32/alloc-id:fake -18804 68/push 0/imm32/operation -18805 68/push 0/imm32/operation -18806 68/push 1/imm32 -18807 89/<- %esi 4/r32/esp -18808 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-operation: -18809 # stmt->operation = "increment" -18810 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -18811 (copy-array Heap "increment" %eax) -18812 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var: -18813 # var formal-var/ebx: (payload var) -18814 68/push 0/imm32/register -18815 68/push 0/imm32/register -18816 68/push 0/imm32/no-stack-offset -18817 68/push 1/imm32/block-depth -18818 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -18819 68/push 0x11/imm32/alloc-id:fake -18820 68/push 0/imm32/name -18821 68/push 0/imm32/name -18822 68/push 0x11/imm32/alloc-id:fake:payload -18823 89/<- %ebx 4/r32/esp -18824 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var-name: -18825 # formal-var->name = "dummy" -18826 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -18827 (copy-array Heap "dummy" %eax) -18828 $test-emit-subx-stmt-select-primitive-2:initialize-formal-register: -18829 # formal-var->register = "*" -18830 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -18831 (copy-array Heap "*" %eax) # Any-register -18832 $test-emit-subx-stmt-select-primitive-2:initialize-var-list: -18833 # var formal-outputs/ebx: (payload list stmt-var) -18834 68/push 0/imm32/next -18835 68/push 0/imm32/next -18836 53/push-ebx/formal-var -18837 68/push 0x11/imm32/alloc-id:fake -18838 68/push 0x11/imm32/alloc-id:fake:payload -18839 89/<- %ebx 4/r32/esp -18840 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2: -18841 # var primitive2/edi: (payload primitive) -18842 68/push 0/imm32/next -18843 68/push 0/imm32/next -18844 68/push 0/imm32/output-is-write-only -18845 68/push 0/imm32/no-disp32 -18846 68/push 0/imm32/no-imm32 -18847 68/push 0/imm32/no-r32 -18848 68/push 3/imm32/rm32-is-first-output -18849 68/push 0/imm32/subx-name -18850 68/push 0/imm32/subx-name -18851 53/push-ebx/outputs -18852 68/push 0x11/imm32/alloc-id:fake -18853 68/push 0/imm32/no-inouts -18854 68/push 0/imm32/no-inouts -18855 68/push 0/imm32/name -18856 68/push 0/imm32/name -18857 68/push 0x11/imm32/alloc-id:fake:payload -18858 89/<- %edi 4/r32/esp -18859 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-name: -18860 # primitives->name = "increment" -18861 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 -18862 (copy-array Heap "increment" %eax) -18863 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-subx-name: -18864 # primitives->subx-name = "ff 0/subop/increment" -18865 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 -18866 (copy-array Heap "ff 0/subop/increment" %eax) -18867 $test-emit-subx-stmt-select-primitive-2:initialize-primitive: -18868 # var primitives/ebx: (addr primitive) -18869 57/push-edi -18870 68/push 0x11/imm32/alloc-id:fake -18871 68/push 0/imm32/output-is-write-only -18872 68/push 0/imm32/no-disp32 -18873 68/push 0/imm32/no-imm32 -18874 68/push 0/imm32/no-r32 -18875 68/push 1/imm32/rm32-is-first-inout -18876 68/push 0/imm32/subx-name -18877 68/push 0/imm32/subx-name -18878 68/push 0/imm32/no-outputs -18879 68/push 0/imm32/no-outputs -18880 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration -18881 68/push 0x11/imm32/alloc-id:fake -18882 68/push 0/imm32/name -18883 68/push 0/imm32/name -18884 89/<- %ebx 4/r32/esp -18885 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-name: -18886 # primitives->name = "increment" -18887 (copy-array Heap "increment" %ebx) # Primitive-name -18888 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-subx-name: -18889 # primitives->subx-name = "ff 0/subop/increment" -18890 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -18891 (copy-array Heap "ff 0/subop/increment" %eax) -18892 # convert -18893 c7 0/subop/copy *Curr-block-depth 0/imm32 -18894 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) -18895 (flush _test-output-buffered-file) -18896 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -18902 # check output -18903 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive-2") -18904 # . epilogue -18905 89/<- %esp 5/r32/ebp -18906 5d/pop-to-ebp -18907 c3/return -18908 -18909 test-increment-register: -18910 # Select the right register between overloads. -18911 # foo <- increment -18912 # => -18913 # 50/increment-eax -18914 # -18915 # There's a variable on the var stack as follows: -18916 # name: 'foo' -18917 # type: int -18918 # register: 'eax' -18919 # -18920 # Primitives are the global definitions. -18921 # -18922 # . prologue -18923 55/push-ebp -18924 89/<- %ebp 4/r32/esp -18925 # setup -18926 (clear-stream _test-output-stream) -18927 (clear-stream $_test-output-buffered-file->buffer) -18928 $test-increment-register:initialize-type: -18929 # var type/ecx: (payload type-tree) = int -18930 68/push 0/imm32/right:null -18931 68/push 0/imm32/right:null -18932 68/push 0/imm32/left:unused -18933 68/push 1/imm32/value:int -18934 68/push 1/imm32/is-atom?:true -18935 68/push 0x11/imm32/alloc-id:fake:payload -18936 89/<- %ecx 4/r32/esp -18937 $test-increment-register:initialize-var: -18938 # var var-foo/ecx: (payload var) -18939 68/push 0/imm32/register -18940 68/push 0/imm32/register -18941 68/push 0/imm32/no-stack-offset -18942 68/push 1/imm32/block-depth -18943 51/push-ecx -18944 68/push 0x11/imm32/alloc-id:fake -18945 68/push 0/imm32/name -18946 68/push 0/imm32/name -18947 68/push 0x11/imm32/alloc-id:fake:payload -18948 89/<- %ecx 4/r32/esp -18949 $test-increment-register:initialize-var-name: -18950 # var-foo->name = "foo" -18951 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -18952 (copy-array Heap "foo" %eax) -18953 $test-increment-register:initialize-var-register: -18954 # var-foo->register = "eax" -18955 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -18956 (copy-array Heap "eax" %eax) -18957 $test-increment-register:initialize-stmt-var: -18958 # var operand/ebx: (payload stmt-var) -18959 68/push 0/imm32/is-deref:false -18960 68/push 0/imm32/next -18961 68/push 0/imm32/next -18962 51/push-ecx/var-foo -18963 68/push 0x11/imm32/alloc-id:fake -18964 68/push 0x11/imm32/alloc-id:fake:payload -18965 89/<- %ebx 4/r32/esp -18966 $test-increment-register:initialize-stmt: -18967 # var stmt/esi: (addr statement) -18968 53/push-ebx/outputs -18969 68/push 0x11/imm32/alloc-id:fake -18970 68/push 0/imm32/no-inouts -18971 68/push 0/imm32/no-inouts -18972 68/push 0/imm32/operation -18973 68/push 0/imm32/operation -18974 68/push 1/imm32 -18975 89/<- %esi 4/r32/esp -18976 $test-increment-register:initialize-stmt-operation: -18977 # stmt->operation = "increment" -18978 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -18979 (copy-array Heap "increment" %eax) -18980 # convert -18981 c7 0/subop/copy *Curr-block-depth 0/imm32 -18982 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -18983 (flush _test-output-buffered-file) -18984 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -18990 # check output -18991 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") -18992 # . epilogue -18993 89/<- %esp 5/r32/ebp -18994 5d/pop-to-ebp -18995 c3/return -18996 -18997 test-add-reg-to-reg: -18998 # var1/reg <- add var2/reg -18999 # => -19000 # 01/add-to %var1 var2 -19001 # -19002 # . prologue -19003 55/push-ebp -19004 89/<- %ebp 4/r32/esp -19005 # setup -19006 (clear-stream _test-output-stream) -19007 (clear-stream $_test-output-buffered-file->buffer) -19008 $test-add-reg-to-reg:initialize-type: -19009 # var type/ecx: (payload type-tree) = int -19010 68/push 0/imm32/right:null -19011 68/push 0/imm32/right:null -19012 68/push 0/imm32/left:unused -19013 68/push 1/imm32/value:int -19014 68/push 1/imm32/is-atom?:true -19015 68/push 0x11/imm32/alloc-id:fake:payload -19016 89/<- %ecx 4/r32/esp -19017 $test-add-reg-to-reg:initialize-var1: -19018 # var var1/ecx: (payload var) -19019 68/push 0/imm32/register -19020 68/push 0/imm32/register -19021 68/push 0/imm32/no-stack-offset -19022 68/push 1/imm32/block-depth -19023 51/push-ecx -19024 68/push 0x11/imm32/alloc-id:fake -19025 68/push 0/imm32/name -19026 68/push 0/imm32/name -19027 68/push 0x11/imm32/alloc-id:fake:payload -19028 89/<- %ecx 4/r32/esp -19029 $test-add-reg-to-reg:initialize-var1-name: -19030 # var1->name = "var1" -19031 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -19032 (copy-array Heap "var1" %eax) -19033 $test-add-reg-to-reg:initialize-var1-register: -19034 # var1->register = "eax" -19035 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -19036 (copy-array Heap "eax" %eax) -19037 $test-add-reg-to-reg:initialize-var2: -19038 # var var2/edx: (payload var) -19039 68/push 0/imm32/register -19040 68/push 0/imm32/register -19041 68/push 0/imm32/no-stack-offset -19042 68/push 1/imm32/block-depth -19043 ff 6/subop/push *(ecx+0x10) -19044 68/push 0x11/imm32/alloc-id:fake -19045 68/push 0/imm32/name -19046 68/push 0/imm32/name -19047 68/push 0x11/imm32/alloc-id:fake:payload -19048 89/<- %edx 4/r32/esp -19049 $test-add-reg-to-reg:initialize-var2-name: -19050 # var2->name = "var2" -19051 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -19052 (copy-array Heap "var2" %eax) -19053 $test-add-reg-to-reg:initialize-var2-register: -19054 # var2->register = "ecx" -19055 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -19056 (copy-array Heap "ecx" %eax) -19057 $test-add-reg-to-reg:initialize-inouts: -19058 # var inouts/esi: (payload stmt-var) = [var2] -19059 68/push 0/imm32/is-deref:false -19060 68/push 0/imm32/next -19061 68/push 0/imm32/next -19062 52/push-edx/var2 -19063 68/push 0x11/imm32/alloc-id:fake -19064 68/push 0x11/imm32/alloc-id:fake:payload -19065 89/<- %esi 4/r32/esp -19066 $test-add-reg-to-reg:initialize-outputs: -19067 # var outputs/edi: (payload stmt-var) = [var1] -19068 68/push 0/imm32/is-deref:false -19069 68/push 0/imm32/next -19070 68/push 0/imm32/next -19071 51/push-ecx/var1 -19072 68/push 0x11/imm32/alloc-id:fake -19073 68/push 0x11/imm32/alloc-id:fake:payload -19074 89/<- %edi 4/r32/esp -19075 $test-add-reg-to-reg:initialize-stmt: -19076 # var stmt/esi: (addr statement) -19077 68/push 0/imm32/next -19078 68/push 0/imm32/next -19079 57/push-edi/outputs -19080 68/push 0x11/imm32/alloc-id:fake -19081 56/push-esi/inouts -19082 68/push 0x11/imm32/alloc-id:fake -19083 68/push 0/imm32/operation -19084 68/push 0/imm32/operation -19085 68/push 1/imm32/tag:stmt1 -19086 89/<- %esi 4/r32/esp -19087 $test-add-reg-to-reg:initialize-stmt-operation: -19088 # stmt->operation = "add" -19089 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -19090 (copy-array Heap "add" %eax) -19091 # convert -19092 c7 0/subop/copy *Curr-block-depth 0/imm32 -19093 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -19094 (flush _test-output-buffered-file) -19095 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -19101 # check output -19102 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") -19103 # . epilogue -19104 89/<- %esp 5/r32/ebp -19105 5d/pop-to-ebp -19106 c3/return -19107 -19108 test-add-reg-to-mem: -19109 # add-to var1 var2/reg -19110 # => -19111 # 01/add-to *(ebp+__) var2 -19112 # -19113 # . prologue -19114 55/push-ebp -19115 89/<- %ebp 4/r32/esp -19116 # setup -19117 (clear-stream _test-output-stream) -19118 (clear-stream $_test-output-buffered-file->buffer) -19119 $test-add-reg-to-mem:initialize-type: -19120 # var type/ecx: (payload type-tree) = int -19121 68/push 0/imm32/right:null -19122 68/push 0/imm32/right:null -19123 68/push 0/imm32/left:unused -19124 68/push 1/imm32/value:int -19125 68/push 1/imm32/is-atom?:true -19126 68/push 0x11/imm32/alloc-id:fake:payload -19127 89/<- %ecx 4/r32/esp -19128 $test-add-reg-to-mem:initialize-var1: -19129 # var var1/ecx: (payload var) -19130 68/push 0/imm32/register -19131 68/push 0/imm32/register -19132 68/push 8/imm32/stack-offset -19133 68/push 1/imm32/block-depth -19134 51/push-ecx -19135 68/push 0x11/imm32/alloc-id:fake -19136 68/push 0/imm32/name -19137 68/push 0/imm32/name -19138 68/push 0x11/imm32/alloc-id:fake:payload -19139 89/<- %ecx 4/r32/esp -19140 $test-add-reg-to-mem:initialize-var1-name: -19141 # var1->name = "var1" -19142 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -19143 (copy-array Heap "var1" %eax) -19144 $test-add-reg-to-mem:initialize-var2: -19145 # var var2/edx: (payload var) -19146 68/push 0/imm32/register -19147 68/push 0/imm32/register -19148 68/push 0/imm32/no-stack-offset -19149 68/push 1/imm32/block-depth -19150 ff 6/subop/push *(ecx+0x10) -19151 68/push 0x11/imm32/alloc-id:fake -19152 68/push 0/imm32/name -19153 68/push 0/imm32/name -19154 68/push 0x11/imm32/alloc-id:fake:payload -19155 89/<- %edx 4/r32/esp -19156 $test-add-reg-to-mem:initialize-var2-name: -19157 # var2->name = "var2" -19158 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -19159 (copy-array Heap "var2" %eax) -19160 $test-add-reg-to-mem:initialize-var2-register: -19161 # var2->register = "ecx" -19162 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -19163 (copy-array Heap "ecx" %eax) -19164 $test-add-reg-to-mem:initialize-inouts: -19165 # var inouts/esi: (payload stmt-var) = [var2] -19166 68/push 0/imm32/is-deref:false -19167 68/push 0/imm32/next -19168 68/push 0/imm32/next -19169 52/push-edx/var2 -19170 68/push 0x11/imm32/alloc-id:fake -19171 68/push 0x11/imm32/alloc-id:fake:payload -19172 89/<- %esi 4/r32/esp -19173 # inouts = [var1, var2] -19174 68/push 0/imm32/is-deref:false -19175 56/push-esi/next -19176 68/push 0x11/imm32/alloc-id:fake -19177 51/push-ecx/var1 -19178 68/push 0x11/imm32/alloc-id:fake -19179 68/push 0x11/imm32/alloc-id:fake:payload -19180 89/<- %esi 4/r32/esp -19181 $test-add-reg-to-mem:initialize-stmt: -19182 # var stmt/esi: (addr statement) -19183 68/push 0/imm32/next -19184 68/push 0/imm32/next -19185 68/push 0/imm32/outputs -19186 68/push 0/imm32/outputs -19187 56/push-esi/inouts -19188 68/push 0x11/imm32/alloc-id:fake -19189 68/push 0/imm32/operation -19190 68/push 0/imm32/operation -19191 68/push 1/imm32/tag:stmt1 -19192 89/<- %esi 4/r32/esp -19193 $test-add-reg-to-mem:initialize-stmt-operation: -19194 # stmt->operation = "add-to" -19195 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -19196 (copy-array Heap "add-to" %eax) -19197 # convert -19198 c7 0/subop/copy *Curr-block-depth 0/imm32 -19199 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -19200 (flush _test-output-buffered-file) -19201 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -19207 # check output -19208 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") -19209 # . epilogue -19210 89/<- %esp 5/r32/ebp -19211 5d/pop-to-ebp -19212 c3/return -19213 -19214 test-add-mem-to-reg: -19215 # var1/reg <- add var2 -19216 # => -19217 # 03/add *(ebp+__) var1 -19218 # -19219 # . prologue -19220 55/push-ebp -19221 89/<- %ebp 4/r32/esp -19222 # setup -19223 (clear-stream _test-output-stream) -19224 (clear-stream $_test-output-buffered-file->buffer) -19225 $test-add-mem-to-reg:initialize-type: -19226 # var type/ecx: (payload type-tree) = int -19227 68/push 0/imm32/right:null -19228 68/push 0/imm32/right:null -19229 68/push 0/imm32/left:unused -19230 68/push 1/imm32/value:int -19231 68/push 1/imm32/is-atom?:true -19232 68/push 0x11/imm32/alloc-id:fake:payload -19233 89/<- %ecx 4/r32/esp -19234 $test-add-mem-to-reg:initialize-var: -19235 # var var1/ecx: (payload var) -19236 68/push 0/imm32/register -19237 68/push 0/imm32/register -19238 68/push 0/imm32/no-stack-offset -19239 68/push 1/imm32/block-depth -19240 51/push-ecx -19241 68/push 0x11/imm32/alloc-id:fake -19242 68/push 0/imm32/name -19243 68/push 0/imm32/name -19244 68/push 0x11/imm32/alloc-id:fake:payload -19245 89/<- %ecx 4/r32/esp -19246 $test-add-mem-to-reg:initialize-var-name: -19247 # var1->name = "foo" -19248 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -19249 (copy-array Heap "var1" %eax) -19250 $test-add-mem-to-reg:initialize-var-register: -19251 # var1->register = "eax" -19252 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -19253 (copy-array Heap "eax" %eax) -19254 $test-add-mem-to-reg:initialize-var2: -19255 # var var2/edx: (payload var) -19256 68/push 0/imm32/register -19257 68/push 0/imm32/register -19258 68/push 8/imm32/stack-offset -19259 68/push 1/imm32/block-depth -19260 ff 6/subop/push *(ecx+0x10) -19261 68/push 0x11/imm32/alloc-id:fake -19262 68/push 0/imm32/name -19263 68/push 0/imm32/name -19264 68/push 0x11/imm32/alloc-id:fake:payload -19265 89/<- %edx 4/r32/esp -19266 $test-add-mem-to-reg:initialize-var2-name: -19267 # var2->name = "var2" -19268 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -19269 (copy-array Heap "var2" %eax) -19270 $test-add-mem-to-reg:initialize-inouts: -19271 # var inouts/esi: (payload stmt-var) = [var2] -19272 68/push 0/imm32/is-deref:false -19273 68/push 0/imm32/next -19274 68/push 0/imm32/next -19275 52/push-edx/var2 -19276 68/push 0x11/imm32/alloc-id:fake -19277 68/push 0x11/imm32/alloc-id:fake:payload -19278 89/<- %esi 4/r32/esp -19279 $test-add-mem-to-reg:initialize-outputs: -19280 # var outputs/edi: (payload stmt-var) = [var1] -19281 68/push 0/imm32/is-deref:false -19282 68/push 0/imm32/next -19283 68/push 0/imm32/next -19284 51/push-ecx/var1 -19285 68/push 0x11/imm32/alloc-id:fake -19286 68/push 0x11/imm32/alloc-id:fake:payload -19287 89/<- %edi 4/r32/esp -19288 $test-add-mem-to-reg:initialize-stmt: -19289 # var stmt/esi: (addr statement) -19290 68/push 0/imm32/next -19291 68/push 0/imm32/next -19292 57/push-edi/outputs -19293 68/push 0x11/imm32/alloc-id:fake -19294 56/push-esi/inouts -19295 68/push 0x11/imm32/alloc-id:fake -19296 68/push 0/imm32/operation -19297 68/push 0/imm32/operation -19298 68/push 1/imm32/tag:stmt1 -19299 89/<- %esi 4/r32/esp -19300 $test-add-mem-to-reg:initialize-stmt-operation: -19301 # stmt->operation = "add" -19302 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -19303 (copy-array Heap "add" %eax) -19304 # convert -19305 c7 0/subop/copy *Curr-block-depth 0/imm32 -19306 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -19307 (flush _test-output-buffered-file) -19308 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -19314 # check output -19315 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") -19316 # . epilogue -19317 89/<- %esp 5/r32/ebp -19318 5d/pop-to-ebp -19319 c3/return -19320 -19321 test-add-literal-to-eax: -19322 # var1/eax <- add 0x34 -19323 # => -19324 # 05/add-to-eax 0x34/imm32 -19325 # -19326 # . prologue -19327 55/push-ebp -19328 89/<- %ebp 4/r32/esp -19329 # setup -19330 (clear-stream _test-output-stream) -19331 (clear-stream $_test-output-buffered-file->buffer) -19332 $test-add-literal-to-eax:initialize-var-type: -19333 # var type/ecx: (payload type-tree) = int -19334 68/push 0/imm32/right:null -19335 68/push 0/imm32/right:null -19336 68/push 0/imm32/left:unused -19337 68/push 1/imm32/value:int -19338 68/push 1/imm32/is-atom?:true -19339 68/push 0x11/imm32/alloc-id:fake:payload -19340 89/<- %ecx 4/r32/esp -19341 $test-add-literal-to-eax:initialize-var: -19342 # var v/ecx: (payload var) -19343 68/push 0/imm32/register -19344 68/push 0/imm32/register -19345 68/push 0/imm32/no-stack-offset -19346 68/push 1/imm32/block-depth -19347 51/push-ecx -19348 68/push 0x11/imm32/alloc-id:fake -19349 68/push 0/imm32/name -19350 68/push 0/imm32/name -19351 68/push 0x11/imm32/alloc-id:fake:payload -19352 89/<- %ecx 4/r32/esp -19353 $test-add-literal-to-eax:initialize-var-name: -19354 # v->name = "v" -19355 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -19356 (copy-array Heap "v" %eax) -19357 $test-add-literal-to-eax:initialize-var-register: -19358 # v->register = "eax" -19359 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -19360 (copy-array Heap "eax" %eax) -19361 $test-add-literal-to-eax:initialize-literal-type: -19362 # var type/edx: (payload type-tree) = literal -19363 68/push 0/imm32/right:null -19364 68/push 0/imm32/right:null -19365 68/push 0/imm32/left:unused -19366 68/push 0/imm32/value:literal -19367 68/push 1/imm32/is-atom?:true -19368 68/push 0x11/imm32/alloc-id:fake:payload -19369 89/<- %edx 4/r32/esp -19370 $test-add-literal-to-eax:initialize-literal: -19371 # var l/edx: (payload var) -19372 68/push 0/imm32/register -19373 68/push 0/imm32/register -19374 68/push 0/imm32/no-stack-offset -19375 68/push 1/imm32/block-depth -19376 52/push-edx -19377 68/push 0x11/imm32/alloc-id:fake -19378 68/push 0/imm32/name -19379 68/push 0/imm32/name -19380 68/push 0x11/imm32/alloc-id:fake:payload -19381 89/<- %edx 4/r32/esp -19382 $test-add-literal-to-eax:initialize-literal-value: -19383 # l->name = "0x34" -19384 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -19385 (copy-array Heap "0x34" %eax) -19386 $test-add-literal-to-eax:initialize-inouts: -19387 # var inouts/esi: (payload stmt-var) = [l] -19388 68/push 0/imm32/is-deref:false -19389 68/push 0/imm32/next -19390 68/push 0/imm32/next -19391 52/push-edx/l -19392 68/push 0x11/imm32/alloc-id:fake -19393 68/push 0x11/imm32/alloc-id:fake:payload -19394 89/<- %esi 4/r32/esp -19395 $test-add-literal-to-eax:initialize-outputs: -19396 # var outputs/edi: (payload stmt-var) = [v] -19397 68/push 0/imm32/is-deref:false -19398 68/push 0/imm32/next -19399 68/push 0/imm32/next -19400 51/push-ecx/v -19401 68/push 0x11/imm32/alloc-id:fake -19402 68/push 0x11/imm32/alloc-id:fake:payload -19403 89/<- %edi 4/r32/esp -19404 $test-add-literal-to-eax:initialize-stmt: -19405 # var stmt/esi: (addr statement) -19406 68/push 0/imm32/next -19407 68/push 0/imm32/next -19408 57/push-edi/outputs -19409 68/push 0x11/imm32/alloc-id:fake -19410 56/push-esi/inouts -19411 68/push 0x11/imm32/alloc-id:fake -19412 68/push 0/imm32/operation -19413 68/push 0/imm32/operation -19414 68/push 1/imm32/tag:stmt1 -19415 89/<- %esi 4/r32/esp -19416 $test-add-literal-to-eax:initialize-stmt-operation: -19417 # stmt->operation = "add" -19418 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -19419 (copy-array Heap "add" %eax) -19420 # convert -19421 c7 0/subop/copy *Curr-block-depth 0/imm32 -19422 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -19423 (flush _test-output-buffered-file) -19424 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -19430 # check output -19431 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") -19432 # . epilogue -19433 89/<- %esp 5/r32/ebp -19434 5d/pop-to-ebp -19435 c3/return -19436 -19437 test-add-literal-to-reg: -19438 # var1/ecx <- add 0x34 -19439 # => -19440 # 81 0/subop/add %ecx 0x34/imm32 -19441 # -19442 # . prologue -19443 55/push-ebp -19444 89/<- %ebp 4/r32/esp -19445 # setup -19446 (clear-stream _test-output-stream) -19447 (clear-stream $_test-output-buffered-file->buffer) -19448 $test-add-literal-to-reg:initialize-var-type: -19449 # var type/ecx: (payload type-tree) = int -19450 68/push 0/imm32/right:null -19451 68/push 0/imm32/right:null -19452 68/push 0/imm32/left:unused -19453 68/push 1/imm32/value:int -19454 68/push 1/imm32/is-atom?:true -19455 68/push 0x11/imm32/alloc-id:fake:payload -19456 89/<- %ecx 4/r32/esp -19457 $test-add-literal-to-reg:initialize-var: -19458 # var v/ecx: (payload var) -19459 68/push 0/imm32/register -19460 68/push 0/imm32/register -19461 68/push 0/imm32/no-stack-offset -19462 68/push 1/imm32/block-depth -19463 51/push-ecx -19464 68/push 0x11/imm32/alloc-id:fake -19465 68/push 0/imm32/name -19466 68/push 0/imm32/name -19467 68/push 0x11/imm32/alloc-id:fake:payload -19468 89/<- %ecx 4/r32/esp -19469 $test-add-literal-to-reg:initialize-var-name: -19470 # v->name = "v" -19471 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -19472 (copy-array Heap "v" %eax) -19473 $test-add-literal-to-reg:initialize-var-register: -19474 # v->register = "ecx" -19475 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -19476 (copy-array Heap "ecx" %eax) -19477 $test-add-literal-to-reg:initialize-literal-type: -19478 # var type/edx: (payload type-tree) = literal -19479 68/push 0/imm32/right:null -19480 68/push 0/imm32/right:null -19481 68/push 0/imm32/left:unused -19482 68/push 0/imm32/value:literal -19483 68/push 1/imm32/is-atom?:true -19484 68/push 0x11/imm32/alloc-id:fake:payload -19485 89/<- %edx 4/r32/esp -19486 $test-add-literal-to-reg:initialize-literal: -19487 # var l/edx: (payload var) -19488 68/push 0/imm32/register -19489 68/push 0/imm32/register -19490 68/push 0/imm32/no-stack-offset -19491 68/push 1/imm32/block-depth -19492 52/push-edx -19493 68/push 0x11/imm32/alloc-id:fake -19494 68/push 0/imm32/name -19495 68/push 0/imm32/name -19496 68/push 0x11/imm32/alloc-id:fake:payload -19497 89/<- %edx 4/r32/esp -19498 $test-add-literal-to-reg:initialize-literal-value: -19499 # l->name = "0x34" -19500 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -19501 (copy-array Heap "0x34" %eax) -19502 $test-add-literal-to-reg:initialize-inouts: -19503 # var inouts/esi: (payload stmt-var) = [l] -19504 68/push 0/imm32/is-deref:false -19505 68/push 0/imm32/next -19506 68/push 0/imm32/next -19507 52/push-edx/l -19508 68/push 0x11/imm32/alloc-id:fake -19509 68/push 0x11/imm32/alloc-id:fake:payload -19510 89/<- %esi 4/r32/esp -19511 $test-add-literal-to-reg:initialize-outputs: -19512 # var outputs/edi: (payload stmt-var) = [v] -19513 68/push 0/imm32/is-deref:false -19514 68/push 0/imm32/next -19515 68/push 0/imm32/next -19516 51/push-ecx/v -19517 68/push 0x11/imm32/alloc-id:fake -19518 68/push 0x11/imm32/alloc-id:fake:payload -19519 89/<- %edi 4/r32/esp -19520 $test-add-literal-to-reg:initialize-stmt: -19521 # var stmt/esi: (addr statement) -19522 68/push 0/imm32/next -19523 68/push 0/imm32/next -19524 57/push-edi/outputs -19525 68/push 0x11/imm32/alloc-id:fake -19526 56/push-esi/inouts -19527 68/push 0x11/imm32/alloc-id:fake -19528 68/push 0/imm32/operation -19529 68/push 0/imm32/operation -19530 68/push 1/imm32/tag:stmt1 -19531 89/<- %esi 4/r32/esp -19532 $test-add-literal-to-reg:initialize-stmt-operation: -19533 # stmt->operation = "add" -19534 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -19535 (copy-array Heap "add" %eax) -19536 # convert -19537 c7 0/subop/copy *Curr-block-depth 0/imm32 -19538 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -19539 (flush _test-output-buffered-file) -19540 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -19546 # check output -19547 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") -19548 # . epilogue -19549 89/<- %esp 5/r32/ebp -19550 5d/pop-to-ebp -19551 c3/return -19552 -19553 test-add-literal-to-mem: -19554 # add-to var1, 0x34 -19555 # => -19556 # 81 0/subop/add %eax 0x34/imm32 -19557 # -19558 # . prologue -19559 55/push-ebp -19560 89/<- %ebp 4/r32/esp -19561 # setup -19562 (clear-stream _test-output-stream) -19563 (clear-stream $_test-output-buffered-file->buffer) -19564 $test-add-literal-to-mem:initialize-type: -19565 # var type/ecx: (payload type-tree) = int -19566 68/push 0/imm32/right:null -19567 68/push 0/imm32/right:null -19568 68/push 0/imm32/left:unused -19569 68/push 1/imm32/value:int -19570 68/push 1/imm32/is-atom?:true -19571 68/push 0x11/imm32/alloc-id:fake:payload -19572 89/<- %ecx 4/r32/esp -19573 $test-add-literal-to-mem:initialize-var1: -19574 # var var1/ecx: (payload var) -19575 68/push 0/imm32/register -19576 68/push 0/imm32/register -19577 68/push 8/imm32/stack-offset -19578 68/push 1/imm32/block-depth -19579 51/push-ecx -19580 68/push 0x11/imm32/alloc-id:fake -19581 68/push 0/imm32/name -19582 68/push 0/imm32/name -19583 68/push 0x11/imm32/alloc-id:fake:payload -19584 89/<- %ecx 4/r32/esp -19585 $test-add-literal-to-mem:initialize-var1-name: -19586 # var1->name = "var1" -19587 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -19588 (copy-array Heap "var1" %eax) -19589 $test-add-literal-to-mem:initialize-literal-type: -19590 # var type/edx: (payload type-tree) = literal -19591 68/push 0/imm32/right:null -19592 68/push 0/imm32/right:null -19593 68/push 0/imm32/left:unused -19594 68/push 0/imm32/value:literal -19595 68/push 1/imm32/is-atom?:true -19596 68/push 0x11/imm32/alloc-id:fake:payload -19597 89/<- %edx 4/r32/esp -19598 $test-add-literal-to-mem:initialize-literal: -19599 # var l/edx: (payload var) -19600 68/push 0/imm32/register -19601 68/push 0/imm32/register -19602 68/push 0/imm32/no-stack-offset -19603 68/push 1/imm32/block-depth -19604 52/push-edx -19605 68/push 0x11/imm32/alloc-id:fake -19606 68/push 0/imm32/name -19607 68/push 0/imm32/name -19608 68/push 0x11/imm32/alloc-id:fake:payload -19609 89/<- %edx 4/r32/esp -19610 $test-add-literal-to-mem:initialize-literal-value: -19611 # l->name = "0x34" -19612 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -19613 (copy-array Heap "0x34" %eax) -19614 $test-add-literal-to-mem:initialize-inouts: -19615 # var inouts/esi: (payload stmt-var) = [l] -19616 68/push 0/imm32/is-deref:false -19617 68/push 0/imm32/next -19618 68/push 0/imm32/next -19619 52/push-edx/l -19620 68/push 0x11/imm32/alloc-id:fake -19621 68/push 0x11/imm32/alloc-id:fake:payload -19622 89/<- %esi 4/r32/esp -19623 # var inouts = (handle stmt-var) = [var1, var2] -19624 68/push 0/imm32/is-deref:false -19625 56/push-esi/next -19626 68/push 0x11/imm32/alloc-id:fake -19627 51/push-ecx/var1 -19628 68/push 0x11/imm32/alloc-id:fake -19629 68/push 0x11/imm32/alloc-id:fake:payload -19630 89/<- %esi 4/r32/esp -19631 $test-add-literal-to-mem:initialize-stmt: -19632 # var stmt/esi: (addr statement) -19633 68/push 0/imm32/next -19634 68/push 0/imm32/next -19635 68/push 0/imm32/outputs -19636 68/push 0/imm32/outputs -19637 56/push-esi/inouts -19638 68/push 0x11/imm32/alloc-id:fake -19639 68/push 0/imm32/operation -19640 68/push 0/imm32/operation -19641 68/push 1/imm32/tag:stmt1 -19642 89/<- %esi 4/r32/esp -19643 $test-add-literal-to-mem:initialize-stmt-operation: -19644 # stmt->operation = "add-to" -19645 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -19646 (copy-array Heap "add-to" %eax) -19647 # convert -19648 c7 0/subop/copy *Curr-block-depth 0/imm32 -19649 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -19650 (flush _test-output-buffered-file) -19651 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -19657 # check output -19658 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") -19659 # . epilogue -19660 89/<- %esp 5/r32/ebp -19661 5d/pop-to-ebp -19662 c3/return -19663 -19664 test-compare-reg-with-reg: -19665 # compare var1/ecx, var2/eax -19666 # => -19667 # 39/compare %ecx 0/r32/eax -19668 # -19669 # . prologue -19670 55/push-ebp -19671 89/<- %ebp 4/r32/esp -19672 # setup -19673 (clear-stream _test-output-stream) -19674 (clear-stream $_test-output-buffered-file->buffer) -19675 $test-compare-reg-with-reg:initialize-type: -19676 # var type/ecx: (payload type-tree) = int -19677 68/push 0/imm32/right:null -19678 68/push 0/imm32/right:null -19679 68/push 0/imm32/left:unused -19680 68/push 1/imm32/value:int -19681 68/push 1/imm32/is-atom?:true -19682 68/push 0x11/imm32/alloc-id:fake:payload -19683 89/<- %ecx 4/r32/esp -19684 $test-compare-reg-with-reg:initialize-var1: -19685 # var var1/ecx: (payload var) -19686 68/push 0/imm32/register -19687 68/push 0/imm32/register -19688 68/push 0/imm32/no-stack-offset -19689 68/push 1/imm32/block-depth -19690 51/push-ecx -19691 68/push 0x11/imm32/alloc-id:fake -19692 68/push 0/imm32/name -19693 68/push 0/imm32/name -19694 68/push 0x11/imm32/alloc-id:fake:payload -19695 89/<- %ecx 4/r32/esp -19696 $test-compare-reg-with-reg:initialize-var1-name: -19697 # var1->name = "var1" -19698 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -19699 (copy-array Heap "var1" %eax) -19700 $test-compare-reg-with-reg:initialize-var1-register: -19701 # var1->register = "ecx" -19702 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -19703 (copy-array Heap "ecx" %eax) -19704 $test-compare-reg-with-reg:initialize-var2: -19705 # var var2/edx: (payload var) -19706 68/push 0/imm32/register -19707 68/push 0/imm32/register -19708 68/push 0/imm32/no-stack-offset -19709 68/push 1/imm32/block-depth -19710 ff 6/subop/push *(ecx+0x10) -19711 68/push 0x11/imm32/alloc-id:fake -19712 68/push 0/imm32/name -19713 68/push 0/imm32/name -19714 68/push 0x11/imm32/alloc-id:fake:payload -19715 89/<- %edx 4/r32/esp -19716 $test-compare-reg-with-reg:initialize-var2-name: -19717 # var2->name = "var2" -19718 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -19719 (copy-array Heap "var2" %eax) -19720 $test-compare-reg-with-reg:initialize-var2-register: -19721 # var2->register = "eax" -19722 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -19723 (copy-array Heap "eax" %eax) -19724 $test-compare-reg-with-reg:initialize-inouts: -19725 # var inouts/esi: (payload stmt-var) = [var2] -19726 68/push 0/imm32/is-deref:false -19727 68/push 0/imm32/next -19728 68/push 0/imm32/next -19729 52/push-edx/var2 -19730 68/push 0x11/imm32/alloc-id:fake -19731 68/push 0x11/imm32/alloc-id:fake:payload -19732 89/<- %esi 4/r32/esp -19733 # inouts = [var1, var2] -19734 68/push 0/imm32/is-deref:false -19735 56/push-esi/next -19736 68/push 0x11/imm32/alloc-id:fake -19737 51/push-ecx/var1 -19738 68/push 0x11/imm32/alloc-id:fake -19739 68/push 0x11/imm32/alloc-id:fake:payload -19740 89/<- %esi 4/r32/esp -19741 $test-compare-reg-with-reg:initialize-stmt: -19742 # var stmt/esi: (addr statement) -19743 68/push 0/imm32/next -19744 68/push 0/imm32/next -19745 68/push 0/imm32/outputs -19746 68/push 0/imm32/outputs -19747 56/push-esi/inouts -19748 68/push 0x11/imm32/alloc-id:fake -19749 68/push 0/imm32/operation -19750 68/push 0/imm32/operation -19751 68/push 1/imm32/tag:stmt1 -19752 89/<- %esi 4/r32/esp -19753 $test-compare-reg-with-reg:initialize-stmt-operation: -19754 # stmt->operation = "compare" -19755 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -19756 (copy-array Heap "compare" %eax) -19757 # convert -19758 c7 0/subop/copy *Curr-block-depth 0/imm32 -19759 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -19760 (flush _test-output-buffered-file) -19761 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -19767 # check output -19768 (check-next-stream-line-equal _test-output-stream "39/compare-> %ecx 0x00000000/r32" "F - test-compare-reg-with-reg") -19769 # . epilogue -19770 89/<- %esp 5/r32/ebp -19771 5d/pop-to-ebp -19772 c3/return -19773 -19774 test-compare-mem-with-reg: -19775 # compare var1, var2/eax -19776 # => -19777 # 39/compare *(ebp+___) 0/r32/eax -19778 # -19779 # . prologue -19780 55/push-ebp -19781 89/<- %ebp 4/r32/esp -19782 # setup -19783 (clear-stream _test-output-stream) -19784 (clear-stream $_test-output-buffered-file->buffer) -19785 $test-compare-mem-with-reg:initialize-type: -19786 # var type/ecx: (payload type-tree) = int -19787 68/push 0/imm32/right:null -19788 68/push 0/imm32/right:null -19789 68/push 0/imm32/left:unused -19790 68/push 1/imm32/value:int -19791 68/push 1/imm32/is-atom?:true -19792 68/push 0x11/imm32/alloc-id:fake:payload -19793 89/<- %ecx 4/r32/esp -19794 $test-compare-mem-with-reg:initialize-var1: -19795 # var var1/ecx: (payload var) -19796 68/push 0/imm32/register -19797 68/push 0/imm32/register -19798 68/push 8/imm32/stack-offset -19799 68/push 1/imm32/block-depth -19800 51/push-ecx -19801 68/push 0x11/imm32/alloc-id:fake -19802 68/push 0/imm32/name -19803 68/push 0/imm32/name -19804 68/push 0x11/imm32/alloc-id:fake:payload -19805 89/<- %ecx 4/r32/esp -19806 $test-compare-mem-with-reg:initialize-var1-name: -19807 # var1->name = "var1" -19808 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -19809 (copy-array Heap "var1" %eax) -19810 $test-compare-mem-with-reg:initialize-var2: -19811 # var var2/edx: (payload var) -19812 68/push 0/imm32/register -19813 68/push 0/imm32/register -19814 68/push 0/imm32/no-stack-offset -19815 68/push 1/imm32/block-depth -19816 ff 6/subop/push *(ecx+0x10) -19817 68/push 0x11/imm32/alloc-id:fake -19818 68/push 0/imm32/name -19819 68/push 0/imm32/name -19820 68/push 0x11/imm32/alloc-id:fake:payload -19821 89/<- %edx 4/r32/esp -19822 $test-compare-mem-with-reg:initialize-var2-name: -19823 # var2->name = "var2" -19824 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -19825 (copy-array Heap "var2" %eax) -19826 $test-compare-mem-with-reg:initialize-var2-register: -19827 # var2->register = "eax" -19828 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -19829 (copy-array Heap "eax" %eax) -19830 $test-compare-mem-with-reg:initialize-inouts: -19831 # var inouts/esi: (payload stmt-var) = [var2] -19832 68/push 0/imm32/is-deref:false -19833 68/push 0/imm32/next -19834 68/push 0/imm32/next -19835 52/push-edx/var2 -19836 68/push 0x11/imm32/alloc-id:fake -19837 68/push 0x11/imm32/alloc-id:fake:payload -19838 89/<- %esi 4/r32/esp -19839 # inouts = [var1, var2] -19840 68/push 0/imm32/is-deref:false -19841 56/push-esi/next -19842 68/push 0x11/imm32/alloc-id:fake -19843 51/push-ecx/var1 -19844 68/push 0x11/imm32/alloc-id:fake -19845 68/push 0x11/imm32/alloc-id:fake:payload -19846 89/<- %esi 4/r32/esp -19847 $test-compare-mem-with-reg:initialize-stmt: -19848 # var stmt/esi: (addr statement) -19849 68/push 0/imm32/next -19850 68/push 0/imm32/next -19851 68/push 0/imm32/outputs -19852 68/push 0/imm32/outputs -19853 56/push-esi/inouts -19854 68/push 0x11/imm32/alloc-id:fake -19855 68/push 0/imm32/operation -19856 68/push 0/imm32/operation -19857 68/push 1/imm32/tag:stmt1 -19858 89/<- %esi 4/r32/esp -19859 $test-compare-mem-with-reg:initialize-stmt-operation: -19860 # stmt->operation = "compare" -19861 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -19862 (copy-array Heap "compare" %eax) -19863 # convert -19864 c7 0/subop/copy *Curr-block-depth 0/imm32 -19865 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -19866 (flush _test-output-buffered-file) -19867 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -19873 # check output -19874 (check-next-stream-line-equal _test-output-stream "39/compare-> *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg") -19875 # . epilogue -19876 89/<- %esp 5/r32/ebp -19877 5d/pop-to-ebp -19878 c3/return -19879 -19880 test-compare-reg-with-mem: -19881 # compare var1/eax, var2 -19882 # => -19883 # 3b/compare<- *(ebp+___) 0/r32/eax -19884 # -19885 # . prologue -19886 55/push-ebp -19887 89/<- %ebp 4/r32/esp -19888 # setup -19889 (clear-stream _test-output-stream) -19890 (clear-stream $_test-output-buffered-file->buffer) -19891 $test-compare-reg-with-mem:initialize-type: -19892 # var type/ecx: (payload type-tree) = int -19893 68/push 0/imm32/right:null -19894 68/push 0/imm32/right:null -19895 68/push 0/imm32/left:unused -19896 68/push 1/imm32/value:int -19897 68/push 1/imm32/is-atom?:true +18417 # Not really legal, but closest we can currently represent a dereference of an (addr byte) +18418 Two-args-byte-stack-byte-reg: # (payload list var) +18419 0x11/imm32/alloc-id:fake:payload +18420 0x11/imm32/alloc-id:fake +18421 Byte-var-in-mem/imm32 +18422 0x11/imm32/alloc-id:fake +18423 Single-byte-var-in-some-register/imm32/next +18424 +18425 Two-args-int-reg-int-stack: # (payload list var) +18426 0x11/imm32/alloc-id:fake:payload +18427 0x11/imm32/alloc-id:fake +18428 Int-var-in-some-register/imm32 +18429 0x11/imm32/alloc-id:fake +18430 Single-int-var-in-mem/imm32/next +18431 +18432 Two-args-int-eax-int-literal: # (payload list var) +18433 0x11/imm32/alloc-id:fake:payload +18434 0x11/imm32/alloc-id:fake +18435 Int-var-in-eax/imm32 +18436 0x11/imm32/alloc-id:fake +18437 Single-lit-var/imm32/next +18438 +18439 Int-var-and-literal: # (payload list var) +18440 0x11/imm32/alloc-id:fake:payload +18441 0x11/imm32/alloc-id:fake +18442 Int-var-in-mem/imm32 +18443 0x11/imm32/alloc-id:fake +18444 Single-lit-var/imm32/next +18445 +18446 Int-var-in-register-and-literal: # (payload list var) +18447 0x11/imm32/alloc-id:fake:payload +18448 0x11/imm32/alloc-id:fake +18449 Int-var-in-some-register/imm32 +18450 0x11/imm32/alloc-id:fake +18451 Single-lit-var/imm32/next +18452 +18453 Single-int-var-in-some-register: # (payload list var) +18454 0x11/imm32/alloc-id:fake:payload +18455 0x11/imm32/alloc-id:fake +18456 Int-var-in-some-register/imm32 +18457 0/imm32/next +18458 0/imm32/next +18459 +18460 Single-addr-var-in-some-register: # (payload list var) +18461 0x11/imm32/alloc-id:fake:payload +18462 0x11/imm32/alloc-id:fake +18463 Addr-var-in-some-register/imm32 +18464 0/imm32/next +18465 0/imm32/next +18466 +18467 Single-byte-var-in-some-register: # (payload list var) +18468 0x11/imm32/alloc-id:fake:payload +18469 0x11/imm32/alloc-id:fake +18470 Byte-var-in-some-register/imm32 +18471 0/imm32/next +18472 0/imm32/next +18473 +18474 Int-var-in-some-register: # (payload var) +18475 0x11/imm32/alloc-id:fake:payload +18476 0/imm32/name +18477 0/imm32/name +18478 0x11/imm32/alloc-id:fake +18479 Type-int/imm32 +18480 1/imm32/some-block-depth +18481 0/imm32/no-stack-offset +18482 0x11/imm32/alloc-id:fake +18483 Any-register/imm32 +18484 +18485 Any-register: # (payload array byte) +18486 0x11/imm32/alloc-id:fake:payload +18487 1/imm32/size +18488 # data +18489 2a/asterisk +18490 +18491 Addr-var-in-some-register: # (payload var) +18492 0x11/imm32/alloc-id:fake:payload +18493 0/imm32/name +18494 0/imm32/name +18495 0x11/imm32/alloc-id:fake +18496 Type-addr/imm32 +18497 1/imm32/some-block-depth +18498 0/imm32/no-stack-offset +18499 0x11/imm32/alloc-id:fake +18500 Any-register/imm32 +18501 +18502 Byte-var-in-some-register: # (payload var) +18503 0x11/imm32/alloc-id:fake:payload +18504 0/imm32/name +18505 0/imm32/name +18506 0x11/imm32/alloc-id:fake +18507 Type-byte/imm32 +18508 1/imm32/some-block-depth +18509 0/imm32/no-stack-offset +18510 0x11/imm32/alloc-id:fake +18511 Any-register/imm32 +18512 +18513 Single-int-var-in-eax: # (payload list var) +18514 0x11/imm32/alloc-id:fake:payload +18515 0x11/imm32/alloc-id:fake +18516 Int-var-in-eax/imm32 +18517 0/imm32/next +18518 0/imm32/next +18519 +18520 Int-var-in-eax: +18521 0x11/imm32/alloc-id:fake:payload +18522 0/imm32/name +18523 0/imm32/name +18524 0x11/imm32/alloc-id:fake +18525 Type-int/imm32 +18526 1/imm32/some-block-depth +18527 0/imm32/no-stack-offset +18528 0x11/imm32/alloc-id:fake +18529 $Register-eax/imm32 +18530 +18531 Single-int-var-in-ecx: # (payload list var) +18532 0x11/imm32/alloc-id:fake:payload +18533 0x11/imm32/alloc-id:fake +18534 Int-var-in-ecx/imm32 +18535 0/imm32/next +18536 0/imm32/next +18537 +18538 Int-var-in-ecx: +18539 0x11/imm32/alloc-id:fake:payload +18540 0/imm32/name +18541 0/imm32/name +18542 0x11/imm32/alloc-id:fake +18543 Type-int/imm32 +18544 1/imm32/some-block-depth +18545 0/imm32/no-stack-offset +18546 0x11/imm32/alloc-id:fake +18547 $Register-ecx/imm32/register +18548 +18549 Single-int-var-in-edx: # (payload list var) +18550 0x11/imm32/alloc-id:fake:payload +18551 0x11/imm32/alloc-id:fake +18552 Int-var-in-edx/imm32 +18553 0/imm32/next +18554 0/imm32/next +18555 +18556 Int-var-in-edx: # (payload list var) +18557 0x11/imm32/alloc-id:fake:payload +18558 0/imm32/name +18559 0/imm32/name +18560 0x11/imm32/alloc-id:fake +18561 Type-int/imm32 +18562 1/imm32/some-block-depth +18563 0/imm32/no-stack-offset +18564 0x11/imm32/alloc-id:fake +18565 $Register-edx/imm32/register +18566 +18567 Single-int-var-in-ebx: # (payload list var) +18568 0x11/imm32/alloc-id:fake:payload +18569 0x11/imm32/alloc-id:fake +18570 Int-var-in-ebx/imm32 +18571 0/imm32/next +18572 0/imm32/next +18573 +18574 Int-var-in-ebx: # (payload list var) +18575 0x11/imm32/alloc-id:fake:payload +18576 0/imm32/name +18577 0/imm32/name +18578 0x11/imm32/alloc-id:fake +18579 Type-int/imm32 +18580 1/imm32/some-block-depth +18581 0/imm32/no-stack-offset +18582 0x11/imm32/alloc-id:fake +18583 $Register-ebx/imm32/register +18584 +18585 Single-int-var-in-esi: # (payload list var) +18586 0x11/imm32/alloc-id:fake:payload +18587 0x11/imm32/alloc-id:fake +18588 Int-var-in-esi/imm32 +18589 0/imm32/next +18590 0/imm32/next +18591 +18592 Int-var-in-esi: # (payload list var) +18593 0x11/imm32/alloc-id:fake:payload +18594 0/imm32/name +18595 0/imm32/name +18596 0x11/imm32/alloc-id:fake +18597 Type-int/imm32 +18598 1/imm32/some-block-depth +18599 0/imm32/no-stack-offset +18600 0x11/imm32/alloc-id:fake +18601 $Register-esi/imm32/register +18602 +18603 Single-int-var-in-edi: # (payload list var) +18604 0x11/imm32/alloc-id:fake:payload +18605 0x11/imm32/alloc-id:fake +18606 Int-var-in-edi/imm32 +18607 0/imm32/next +18608 0/imm32/next +18609 +18610 Int-var-in-edi: # (payload list var) +18611 0x11/imm32/alloc-id:fake:payload +18612 0/imm32/name +18613 0/imm32/name +18614 0x11/imm32/alloc-id:fake +18615 Type-int/imm32 +18616 1/imm32/some-block-depth +18617 0/imm32/no-stack-offset +18618 0x11/imm32/alloc-id:fake +18619 $Register-edi/imm32/register +18620 +18621 Single-lit-var: # (payload list var) +18622 0x11/imm32/alloc-id:fake:payload +18623 0x11/imm32/alloc-id:fake +18624 Lit-var/imm32 +18625 0/imm32/next +18626 0/imm32/next +18627 +18628 Lit-var: # (payload var) +18629 0x11/imm32/alloc-id:fake:payload +18630 0/imm32/name +18631 0/imm32/name +18632 0x11/imm32/alloc-id:fake +18633 Type-literal/imm32 +18634 1/imm32/some-block-depth +18635 0/imm32/no-stack-offset +18636 0/imm32/no-register +18637 0/imm32/no-register +18638 +18639 Type-int: # (payload type-tree) +18640 0x11/imm32/alloc-id:fake:payload +18641 1/imm32/is-atom +18642 1/imm32/value:int +18643 0/imm32/left:unused +18644 0/imm32/right:null +18645 0/imm32/right:null +18646 +18647 Type-literal: # (payload type-tree) +18648 0x11/imm32/alloc-id:fake:payload +18649 1/imm32/is-atom +18650 0/imm32/value:literal +18651 0/imm32/left:unused +18652 0/imm32/right:null +18653 0/imm32/right:null +18654 +18655 Type-addr: # (payload type-tree) +18656 0x11/imm32/alloc-id:fake:payload +18657 1/imm32/is-atom +18658 2/imm32/value:addr +18659 0/imm32/left:unused +18660 0/imm32/right:null +18661 0/imm32/right:null +18662 +18663 Type-byte: # (payload type-tree) +18664 0x11/imm32/alloc-id:fake:payload +18665 1/imm32/is-atom +18666 8/imm32/value:byte +18667 0/imm32/left:unused +18668 0/imm32/right:null +18669 0/imm32/right:null +18670 +18671 == code +18672 emit-subx-primitive: # out: (addr buffered-file), stmt: (addr stmt), primitive: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) +18673 # . prologue +18674 55/push-ebp +18675 89/<- %ebp 4/r32/esp +18676 # . save registers +18677 50/push-eax +18678 51/push-ecx +18679 # ecx = primitive +18680 8b/-> *(ebp+0x10) 1/r32/ecx +18681 # emit primitive name +18682 (emit-indent *(ebp+8) *Curr-block-depth) +18683 (lookup *(ecx+0x18) *(ecx+0x1c)) # Primitive-subx-name Primitive-subx-name => eax +18684 (write-buffered *(ebp+8) %eax) +18685 # emit rm32 if necessary +18686 (emit-subx-rm32 *(ebp+8) *(ecx+0x20) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-rm32 +18687 # emit r32 if necessary +18688 (emit-subx-r32 *(ebp+8) *(ecx+0x24) *(ebp+0xc)) # Primitive-subx-r32 +18689 # emit imm32 if necessary +18690 (emit-subx-imm32 *(ebp+8) *(ecx+0x28) *(ebp+0xc)) # Primitive-subx-imm32 +18691 # emit imm8 if necessary +18692 (emit-subx-imm8 *(ebp+8) *(ecx+0x2c) *(ebp+0xc)) # Primitive-subx-imm8 +18693 # emit disp32 if necessary +18694 (emit-subx-disp32 *(ebp+8) *(ecx+0x30) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-disp32 +18695 (write-buffered *(ebp+8) Newline) +18696 $emit-subx-primitive:end: +18697 # . restore registers +18698 59/pop-to-ecx +18699 58/pop-to-eax +18700 # . epilogue +18701 89/<- %esp 5/r32/ebp +18702 5d/pop-to-ebp +18703 c3/return +18704 +18705 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +18706 # . prologue +18707 55/push-ebp +18708 89/<- %ebp 4/r32/esp +18709 # . save registers +18710 50/push-eax +18711 # if (l == 0) return +18712 81 7/subop/compare *(ebp+0xc) 0/imm32 +18713 74/jump-if-= $emit-subx-rm32:end/disp8 +18714 # var v/eax: (addr stmt-var) +18715 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax +18716 (emit-subx-var-as-rm32 *(ebp+8) %eax) +18717 $emit-subx-rm32:end: +18718 # . restore registers +18719 58/pop-to-eax +18720 # . epilogue +18721 89/<- %esp 5/r32/ebp +18722 5d/pop-to-ebp +18723 c3/return +18724 +18725 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) +18726 # . prologue +18727 55/push-ebp +18728 89/<- %ebp 4/r32/esp +18729 # . save registers +18730 51/push-ecx +18731 # eax = l +18732 8b/-> *(ebp+0xc) 0/r32/eax +18733 # ecx = stmt +18734 8b/-> *(ebp+8) 1/r32/ecx +18735 # if (l == 1) return stmt->inouts +18736 { +18737 3d/compare-eax-and 1/imm32 +18738 75/jump-if-!= break/disp8 +18739 $get-stmt-operand-from-arg-location:1: +18740 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +18741 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +18742 } +18743 # if (l == 2) return stmt->inouts->next +18744 { +18745 3d/compare-eax-and 2/imm32 +18746 75/jump-if-!= break/disp8 +18747 $get-stmt-operand-from-arg-location:2: +18748 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +18749 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +18750 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +18751 } +18752 # if (l == 3) return stmt->outputs +18753 { +18754 3d/compare-eax-and 3/imm32 +18755 75/jump-if-!= break/disp8 +18756 $get-stmt-operand-from-arg-location:3: +18757 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +18758 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +18759 } +18760 # abort +18761 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 +18762 $get-stmt-operand-from-arg-location:end: +18763 # . restore registers +18764 59/pop-to-ecx +18765 # . epilogue +18766 89/<- %esp 5/r32/ebp +18767 5d/pop-to-ebp +18768 c3/return +18769 +18770 $get-stmt-operand-from-arg-location:abort: +18771 # error("invalid arg-location " eax) +18772 (write-buffered *(ebp+0x10) "invalid arg-location ") +18773 (write-int32-hex-buffered *(ebp+0x10) %eax) +18774 (write-buffered *(ebp+0x10) Newline) +18775 (flush *(ebp+0x10)) +18776 (stop *(ebp+0x14) 1) +18777 # never gets here +18778 +18779 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +18780 # . prologue +18781 55/push-ebp +18782 89/<- %ebp 4/r32/esp +18783 # . save registers +18784 50/push-eax +18785 51/push-ecx +18786 # if (l == 0) return +18787 81 7/subop/compare *(ebp+0xc) 0/imm32 +18788 0f 84/jump-if-= $emit-subx-r32:end/disp32 +18789 # var v/eax: (addr stmt-var) +18790 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +18791 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +18792 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +18793 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index) +18794 (write-buffered *(ebp+8) Space) +18795 (write-int32-hex-buffered *(ebp+8) *eax) +18796 (write-buffered *(ebp+8) "/r32") +18797 $emit-subx-r32:end: +18798 # . restore registers +18799 59/pop-to-ecx +18800 58/pop-to-eax +18801 # . epilogue +18802 89/<- %esp 5/r32/ebp +18803 5d/pop-to-ebp +18804 c3/return +18805 +18806 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +18807 # . prologue +18808 55/push-ebp +18809 89/<- %ebp 4/r32/esp +18810 # . save registers +18811 50/push-eax +18812 51/push-ecx +18813 # if (l == 0) return +18814 81 7/subop/compare *(ebp+0xc) 0/imm32 +18815 0f 84/jump-if-= $emit-subx-imm32:end/disp32 +18816 # var v/eax: (handle var) +18817 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +18818 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +18819 (lookup *eax *(eax+4)) # Var-name Var-name => eax +18820 (write-buffered *(ebp+8) Space) +18821 (write-buffered *(ebp+8) %eax) +18822 (write-buffered *(ebp+8) "/imm32") +18823 $emit-subx-imm32:end: +18824 # . restore registers +18825 59/pop-to-ecx +18826 58/pop-to-eax +18827 # . epilogue +18828 89/<- %esp 5/r32/ebp +18829 5d/pop-to-ebp +18830 c3/return +18831 +18832 emit-subx-imm8: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +18833 # . prologue +18834 55/push-ebp +18835 89/<- %ebp 4/r32/esp +18836 # . save registers +18837 50/push-eax +18838 51/push-ecx +18839 # if (l == 0) return +18840 81 7/subop/compare *(ebp+0xc) 0/imm32 +18841 0f 84/jump-if-= $emit-subx-imm32:end/disp32 +18842 # var v/eax: (handle var) +18843 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +18844 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +18845 (lookup *eax *(eax+4)) # Var-name Var-name => eax +18846 (write-buffered *(ebp+8) Space) +18847 (write-buffered *(ebp+8) %eax) +18848 (write-buffered *(ebp+8) "/imm8") +18849 $emit-subx-imm8:end: +18850 # . restore registers +18851 59/pop-to-ecx +18852 58/pop-to-eax +18853 # . epilogue +18854 89/<- %esp 5/r32/ebp +18855 5d/pop-to-ebp +18856 c3/return +18857 +18858 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +18859 # . prologue +18860 55/push-ebp +18861 89/<- %ebp 4/r32/esp +18862 # . save registers +18863 50/push-eax +18864 51/push-ecx +18865 # if (location == 0) return +18866 81 7/subop/compare *(ebp+0xc) 0/imm32 +18867 0f 84/jump-if-= $emit-subx-disp32:end/disp32 +18868 # var v/eax: (addr stmt-var) +18869 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax +18870 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +18871 (lookup *eax *(eax+4)) # Var-name Var-name => eax +18872 (write-buffered *(ebp+8) Space) +18873 (write-buffered *(ebp+8) %eax) +18874 # hack: if instruction operation starts with "break", emit ":break" +18875 # var name/ecx: (addr array byte) = lookup(stmt->operation) +18876 8b/-> *(ebp+0x10) 0/r32/eax +18877 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +18878 89/<- %ecx 0/r32/eax +18879 { +18880 (string-starts-with? %ecx "break") # => eax +18881 3d/compare-eax-and 0/imm32/false +18882 74/jump-if-= break/disp8 +18883 (write-buffered *(ebp+8) ":break") +18884 } +18885 # hack: if instruction operation starts with "loop", emit ":loop" +18886 { +18887 (string-starts-with? %ecx "loop") # => eax +18888 3d/compare-eax-and 0/imm32/false +18889 74/jump-if-= break/disp8 +18890 (write-buffered *(ebp+8) ":loop") +18891 } +18892 (write-buffered *(ebp+8) "/disp32") +18893 $emit-subx-disp32:end: +18894 # . restore registers +18895 59/pop-to-ecx +18896 58/pop-to-eax +18897 # . epilogue +18898 89/<- %esp 5/r32/ebp +18899 5d/pop-to-ebp +18900 c3/return +18901 +18902 emit-call: # out: (addr buffered-file), stmt: (addr stmt) +18903 # . prologue +18904 55/push-ebp +18905 89/<- %ebp 4/r32/esp +18906 # . save registers +18907 50/push-eax +18908 51/push-ecx +18909 # +18910 (emit-indent *(ebp+8) *Curr-block-depth) +18911 (write-buffered *(ebp+8) "(") +18912 # ecx = stmt +18913 8b/-> *(ebp+0xc) 1/r32/ecx +18914 # - emit function name +18915 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +18916 (write-buffered *(ebp+8) %eax) +18917 # - emit arguments +18918 # var curr/eax: (addr stmt-var) = lookup(stmt->inouts) +18919 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +18920 { +18921 # if (curr == null) break +18922 3d/compare-eax-and 0/imm32 +18923 74/jump-if-= break/disp8 +18924 # +18925 (emit-subx-call-operand *(ebp+8) %eax) +18926 # curr = lookup(curr->next) +18927 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +18928 eb/jump loop/disp8 +18929 } +18930 # +18931 (write-buffered *(ebp+8) ")\n") +18932 $emit-call:end: +18933 # . restore registers +18934 59/pop-to-ecx +18935 58/pop-to-eax +18936 # . epilogue +18937 89/<- %esp 5/r32/ebp +18938 5d/pop-to-ebp +18939 c3/return +18940 +18941 emit-subx-call-operand: # out: (addr buffered-file), s: (addr stmt-var) +18942 # shares code with emit-subx-var-as-rm32 +18943 # . prologue +18944 55/push-ebp +18945 89/<- %ebp 4/r32/esp +18946 # . save registers +18947 50/push-eax +18948 51/push-ecx +18949 56/push-esi +18950 # ecx = s +18951 8b/-> *(ebp+0xc) 1/r32/ecx +18952 # var operand/esi: (addr var) = lookup(s->value) +18953 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +18954 89/<- %esi 0/r32/eax +18955 # if (operand->register && !s->is-deref?) emit "%__" +18956 { +18957 $emit-subx-call-operand:check-for-register-direct: +18958 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +18959 74/jump-if-= break/disp8 +18960 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +18961 75/jump-if-!= break/disp8 +18962 $emit-subx-call-operand:register-direct: +18963 (write-buffered *(ebp+8) " %") +18964 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +18965 (write-buffered *(ebp+8) %eax) +18966 e9/jump $emit-subx-call-operand:end/disp32 +18967 } +18968 # else if (operand->register && s->is-deref?) emit "*__" +18969 { +18970 $emit-subx-call-operand:check-for-register-indirect: +18971 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +18972 74/jump-if-= break/disp8 +18973 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +18974 74/jump-if-= break/disp8 +18975 $emit-subx-call-operand:register-indirect: +18976 (emit-subx-call-operand-register-indirect *(ebp+8) %esi) +18977 e9/jump $emit-subx-call-operand:end/disp32 +18978 } +18979 # else if (operand->stack-offset) emit "*(ebp+__)" +18980 { +18981 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset +18982 74/jump-if-= break/disp8 +18983 $emit-subx-call-operand:stack: +18984 (emit-subx-call-operand-stack *(ebp+8) %esi) +18985 e9/jump $emit-subx-call-operand:end/disp32 +18986 } +18987 # else if (operand->type == literal) emit "__" +18988 { +18989 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +18990 81 7/subop/compare *(eax+4) 0/imm32 # Type-tree-left +18991 75/jump-if-!= break/disp8 +18992 $emit-subx-call-operand:literal: +18993 (write-buffered *(ebp+8) Space) +18994 (lookup *esi *(esi+4)) # Var-name Var-name => eax +18995 (write-buffered *(ebp+8) %eax) +18996 } +18997 $emit-subx-call-operand:end: +18998 # . restore registers +18999 5e/pop-to-esi +19000 59/pop-to-ecx +19001 58/pop-to-eax +19002 # . epilogue +19003 89/<- %esp 5/r32/ebp +19004 5d/pop-to-ebp +19005 c3/return +19006 +19007 emit-subx-call-operand-register-indirect: # out: (addr buffered-file), v: (addr var) +19008 # . prologue +19009 55/push-ebp +19010 89/<- %ebp 4/r32/esp +19011 # . save registers +19012 50/push-eax +19013 51/push-ecx +19014 56/push-esi +19015 # esi = v +19016 8b/-> *(ebp+0xc) 6/r32/esi +19017 # var size/ecx: int = size-of-deref(v) +19018 (size-of-deref %esi) # => eax +19019 89/<- %ecx 0/r32/eax +19020 # var reg-name/esi: (addr array byte) = lookup(v->register) +19021 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +19022 89/<- %esi 0/r32/eax +19023 # TODO: assert size is a multiple of 4 +19024 # var i/eax: int = 0 +19025 b8/copy-to-eax 0/imm32 +19026 { +19027 $emit-subx-call-operand-register-indirect:loop: +19028 # if (i >= size) break +19029 39/compare %eax 1/r32/ecx +19030 7d/jump-if->= break/disp8 +19031 # emit " *(" v->register "+" i ")" +19032 (write-buffered *(ebp+8) " *(") +19033 (write-buffered *(ebp+8) %esi) +19034 (write-buffered *(ebp+8) "+") +19035 (write-int32-hex-buffered *(ebp+8) %eax) +19036 (write-buffered *(ebp+8) ")") +19037 # i += 4 +19038 05/add-to-eax 4/imm32 +19039 # +19040 eb/jump loop/disp8 +19041 } +19042 $emit-subx-call-operand-register-indirect:end: +19043 # . restore registers +19044 5e/pop-to-esi +19045 59/pop-to-ecx +19046 58/pop-to-eax +19047 # . epilogue +19048 89/<- %esp 5/r32/ebp +19049 5d/pop-to-ebp +19050 c3/return +19051 +19052 emit-subx-call-operand-stack: # out: (addr buffered-file), v: (addr var) +19053 # . prologue +19054 55/push-ebp +19055 89/<- %ebp 4/r32/esp +19056 # . save registers +19057 50/push-eax +19058 51/push-ecx +19059 56/push-esi +19060 # esi = v +19061 8b/-> *(ebp+0xc) 6/r32/esi +19062 # var curr/ecx: int = v->offset +19063 8b/-> *(esi+0x14) 1/r32/ecx # Var-offset +19064 # var max/eax: int = v->offset + size-of(v) +19065 (size-of %esi) # => eax +19066 # TODO: assert size is a multiple of 4 +19067 01/add-to %eax 1/r32/ecx +19068 { +19069 $emit-subx-call-operand-stack:loop: +19070 # if (curr >= max) break +19071 39/compare %ecx 0/r32/eax +19072 7d/jump-if->= break/disp8 +19073 # emit " *(ebp+" curr ")" +19074 (write-buffered *(ebp+8) " *(ebp+") +19075 (write-int32-hex-buffered *(ebp+8) %ecx) +19076 (write-buffered *(ebp+8) ")") +19077 # i += 4 +19078 81 0/subop/add %ecx 4/imm32 +19079 # +19080 eb/jump loop/disp8 +19081 } +19082 $emit-subx-call-operand-stack:end: +19083 # . restore registers +19084 5e/pop-to-esi +19085 59/pop-to-ecx +19086 58/pop-to-eax +19087 # . epilogue +19088 89/<- %esp 5/r32/ebp +19089 5d/pop-to-ebp +19090 c3/return +19091 +19092 emit-subx-var-as-rm32: # out: (addr buffered-file), s: (addr stmt-var) +19093 # . prologue +19094 55/push-ebp +19095 89/<- %ebp 4/r32/esp +19096 # . save registers +19097 50/push-eax +19098 51/push-ecx +19099 56/push-esi +19100 # ecx = s +19101 8b/-> *(ebp+0xc) 1/r32/ecx +19102 # var operand/esi: (addr var) = lookup(s->value) +19103 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +19104 89/<- %esi 0/r32/eax +19105 # if (operand->register && s->is-deref?) emit "*__" +19106 { +19107 $emit-subx-var-as-rm32:check-for-register-indirect: +19108 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +19109 74/jump-if-= break/disp8 +19110 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +19111 74/jump-if-= break/disp8 +19112 $emit-subx-var-as-rm32:register-indirect: +19113 (write-buffered *(ebp+8) " *") +19114 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +19115 (write-buffered *(ebp+8) %eax) +19116 e9/jump $emit-subx-var-as-rm32:end/disp32 +19117 } +19118 # if (operand->register && !s->is-deref?) emit "%__" +19119 { +19120 $emit-subx-var-as-rm32:check-for-register-direct: +19121 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +19122 74/jump-if-= break/disp8 +19123 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +19124 75/jump-if-!= break/disp8 +19125 $emit-subx-var-as-rm32:register-direct: +19126 (write-buffered *(ebp+8) " %") +19127 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +19128 (write-buffered *(ebp+8) %eax) +19129 e9/jump $emit-subx-var-as-rm32:end/disp32 +19130 } +19131 # else if (operand->stack-offset) emit "*(ebp+__)" +19132 { +19133 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset +19134 74/jump-if-= break/disp8 +19135 $emit-subx-var-as-rm32:stack: +19136 (write-buffered *(ebp+8) Space) +19137 (write-buffered *(ebp+8) "*(ebp+") +19138 (write-int32-hex-buffered *(ebp+8) *(esi+0x14)) # Var-offset +19139 (write-buffered *(ebp+8) ")") +19140 } +19141 $emit-subx-var-as-rm32:end: +19142 # . restore registers +19143 5e/pop-to-esi +19144 59/pop-to-ecx +19145 58/pop-to-eax +19146 # . epilogue +19147 89/<- %esp 5/r32/ebp +19148 5d/pop-to-ebp +19149 c3/return +19150 +19151 find-matching-primitive: # primitives: (addr primitive), stmt: (addr stmt) -> result/eax: (addr primitive) +19152 # . prologue +19153 55/push-ebp +19154 89/<- %ebp 4/r32/esp +19155 # . save registers +19156 51/push-ecx +19157 # var curr/ecx: (addr primitive) = primitives +19158 8b/-> *(ebp+8) 1/r32/ecx +19159 { +19160 $find-matching-primitive:loop: +19161 # if (curr == null) break +19162 81 7/subop/compare %ecx 0/imm32 +19163 74/jump-if-= break/disp8 +19164 # if match(curr, stmt) return curr +19165 { +19166 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax +19167 3d/compare-eax-and 0/imm32/false +19168 74/jump-if-= break/disp8 +19169 89/<- %eax 1/r32/ecx +19170 eb/jump $find-matching-primitive:end/disp8 +19171 } +19172 $find-matching-primitive:next-primitive: +19173 # curr = curr->next +19174 (lookup *(ecx+0x38) *(ecx+0x3c)) # Primitive-next Primitive-next => eax +19175 89/<- %ecx 0/r32/eax +19176 # +19177 e9/jump loop/disp32 +19178 } +19179 # return null +19180 b8/copy-to-eax 0/imm32 +19181 $find-matching-primitive:end: +19182 # . restore registers +19183 59/pop-to-ecx +19184 # . epilogue +19185 89/<- %esp 5/r32/ebp +19186 5d/pop-to-ebp +19187 c3/return +19188 +19189 mu-stmt-matches-primitive?: # stmt: (addr stmt), primitive: (addr primitive) -> result/eax: boolean +19190 # A mu stmt matches a primitive if the name matches, all the inout vars +19191 # match, and all the output vars match. +19192 # Vars match if types match and registers match. +19193 # In addition, a stmt output matches a primitive's output if types match +19194 # and the primitive has a wildcard register. +19195 # . prologue +19196 55/push-ebp +19197 89/<- %ebp 4/r32/esp +19198 # . save registers +19199 51/push-ecx +19200 52/push-edx +19201 53/push-ebx +19202 56/push-esi +19203 57/push-edi +19204 # ecx = stmt +19205 8b/-> *(ebp+8) 1/r32/ecx +19206 # edx = primitive +19207 8b/-> *(ebp+0xc) 2/r32/edx +19208 { +19209 $mu-stmt-matches-primitive?:check-name: +19210 # if (primitive->name != stmt->operation) return false +19211 # . var esi: (addr array byte) = lookup(stmt->operation) +19212 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +19213 89/<- %esi 0/r32/eax +19214 # . var edi: (addr array byte) = lookup(primitive->name) +19215 (lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax +19216 89/<- %edi 0/r32/eax +19217 (string-equal? %esi %edi) # => eax +19218 3d/compare-eax-and 0/imm32/false +19219 75/jump-if-!= break/disp8 +19220 b8/copy-to-eax 0/imm32 +19221 e9/jump $mu-stmt-matches-primitive?:end/disp32 +19222 } +19223 # var curr/esi: (addr stmt-var) = lookup(stmt->inouts) +19224 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +19225 89/<- %esi 0/r32/eax +19226 # var curr2/edi: (addr list var) = lookup(primitive->inouts) +19227 (lookup *(edx+8) *(edx+0xc)) # Primitive-inouts Primitive-inouts => eax +19228 89/<- %edi 0/r32/eax +19229 { +19230 $mu-stmt-matches-primitive?:inouts-loop: +19231 # if (curr == 0 && curr2 == 0) move on to check outputs +19232 { +19233 $mu-stmt-matches-primitive?:check-both-inouts-null: +19234 81 7/subop/compare %esi 0/imm32 +19235 75/jump-if-!= break/disp8 +19236 $mu-stmt-matches-primitive?:stmt-inout-null: +19237 81 7/subop/compare %edi 0/imm32 +19238 0f 84/jump-if-= $mu-stmt-matches-primitive?:check-outputs/disp32 +19239 $mu-stmt-matches-primitive?:stmt-inout-null-and-prim-inout-not-null: +19240 # return false +19241 b8/copy-to-eax 0/imm32/false +19242 e9/jump $mu-stmt-matches-primitive?:end/disp32 +19243 } +19244 # if (curr2 == 0) return false +19245 { +19246 $mu-stmt-matches-primitive?:check-prim-inout-null: +19247 81 7/subop/compare %edi 0/imm32 +19248 75/jump-if-!= break/disp8 +19249 $mu-stmt-matches-primitive?:prim-inout-null: +19250 b8/copy-to-eax 0/imm32/false +19251 e9/jump $mu-stmt-matches-primitive?:end/disp32 +19252 } +19253 # if (curr != curr2) return false +19254 { +19255 $mu-stmt-matches-primitive?:check-inouts-match: +19256 (lookup *edi *(edi+4)) # List-value List-value => eax +19257 (operand-matches-primitive? %esi %eax) # => eax +19258 3d/compare-eax-and 0/imm32/false +19259 75/jump-if-!= break/disp8 +19260 $mu-stmt-matches-primitive?:inouts-match: +19261 b8/copy-to-eax 0/imm32/false +19262 e9/jump $mu-stmt-matches-primitive?:end/disp32 +19263 } +19264 $mu-stmt-matches-primitive?:next-inout: +19265 # curr = lookup(curr->next) +19266 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +19267 89/<- %esi 0/r32/eax +19268 # curr2 = lookup(curr2->next) +19269 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax +19270 89/<- %edi 0/r32/eax +19271 # +19272 e9/jump loop/disp32 +19273 } +19274 $mu-stmt-matches-primitive?:check-outputs: +19275 # var curr/esi: (addr stmt-var) = lookup(stmt->outputs) +19276 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +19277 89/<- %esi 0/r32/eax +19278 # var curr2/edi: (addr list var) = lookup(primitive->outputs) +19279 (lookup *(edx+0x10) *(edx+0x14)) # Primitive-outputs Primitive-outputs => eax +19280 89/<- %edi 0/r32/eax +19281 { +19282 $mu-stmt-matches-primitive?:outputs-loop: +19283 # if (curr == 0) return (curr2 == 0) +19284 { +19285 $mu-stmt-matches-primitive?:check-both-outputs-null: +19286 81 7/subop/compare %esi 0/imm32 +19287 75/jump-if-!= break/disp8 +19288 { +19289 $mu-stmt-matches-primitive?:stmt-output-null: +19290 81 7/subop/compare %edi 0/imm32 +19291 75/jump-if-!= break/disp8 +19292 $mu-stmt-matches-primitive?:both-outputs-null: +19293 # return true +19294 b8/copy-to-eax 1/imm32 +19295 e9/jump $mu-stmt-matches-primitive?:end/disp32 +19296 } +19297 $mu-stmt-matches-primitive?:stmt-output-null-and-prim-output-not-null: +19298 # return false +19299 b8/copy-to-eax 0/imm32 +19300 e9/jump $mu-stmt-matches-primitive?:end/disp32 +19301 } +19302 # if (curr2 == 0) return false +19303 { +19304 $mu-stmt-matches-primitive?:check-prim-output-null: +19305 81 7/subop/compare %edi 0/imm32 +19306 75/jump-if-!= break/disp8 +19307 $mu-stmt-matches-primitive?:prim-output-is-null: +19308 b8/copy-to-eax 0/imm32 +19309 e9/jump $mu-stmt-matches-primitive?:end/disp32 +19310 } +19311 # if (curr != curr2) return false +19312 { +19313 $mu-stmt-matches-primitive?:check-outputs-match: +19314 (lookup *edi *(edi+4)) # List-value List-value => eax +19315 (operand-matches-primitive? %esi %eax) # => eax +19316 3d/compare-eax-and 0/imm32/false +19317 75/jump-if-!= break/disp8 +19318 $mu-stmt-matches-primitive?:outputs-match: +19319 b8/copy-to-eax 0/imm32 +19320 e9/jump $mu-stmt-matches-primitive?:end/disp32 +19321 } +19322 $mu-stmt-matches-primitive?:next-output: +19323 # curr = lookup(curr->next) +19324 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +19325 89/<- %esi 0/r32/eax +19326 # curr2 = lookup(curr2->next) +19327 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax +19328 89/<- %edi 0/r32/eax +19329 # +19330 e9/jump loop/disp32 +19331 } +19332 $mu-stmt-matches-primitive?:return-true: +19333 b8/copy-to-eax 1/imm32 +19334 $mu-stmt-matches-primitive?:end: +19335 # . restore registers +19336 5f/pop-to-edi +19337 5e/pop-to-esi +19338 5b/pop-to-ebx +19339 5a/pop-to-edx +19340 59/pop-to-ecx +19341 # . epilogue +19342 89/<- %esp 5/r32/ebp +19343 5d/pop-to-ebp +19344 c3/return +19345 +19346 operand-matches-primitive?: # s: (addr stmt-var), prim-var: (addr var) -> result/eax: boolean +19347 # . prologue +19348 55/push-ebp +19349 89/<- %ebp 4/r32/esp +19350 # . save registers +19351 51/push-ecx +19352 52/push-edx +19353 53/push-ebx +19354 56/push-esi +19355 57/push-edi +19356 # ecx = s +19357 8b/-> *(ebp+8) 1/r32/ecx +19358 # var var/esi: (addr var) = lookup(s->value) +19359 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +19360 89/<- %esi 0/r32/eax +19361 # edi = prim-var +19362 8b/-> *(ebp+0xc) 7/r32/edi +19363 $operand-matches-primitive?:check-type: +19364 # if !category-match?(var->type, prim-var->type) return false +19365 # . var vtype/ebx: (addr type-tree) = lookup(var->type) +19366 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +19367 89/<- %ebx 0/r32/eax +19368 # . var ptype/eax: (addr type-tree) = lookup(prim-var->type) +19369 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +19370 (subx-type-category-match? %ebx %eax) # => eax +19371 3d/compare-eax-and 0/imm32/false +19372 0f 84/jump-if-= $operand-matches-primitive?:return-false/disp32 +19373 { +19374 $operand-matches-primitive?:check-register: +19375 # if prim-var is in memory and var is in register but dereference, match +19376 { +19377 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register +19378 0f 85/jump-if-!= break/disp32 +19379 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +19380 74/jump-if-= break/disp8 +19381 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +19382 74/jump-if-= break/disp8 +19383 $operand-matches-primitive?:var-deref-match: +19384 e9/jump $operand-matches-primitive?:return-true/disp32 +19385 } +19386 # if prim-var is in register and var is in register but dereference, no match +19387 { +19388 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register +19389 0f 84/jump-if-= break/disp32 +19390 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +19391 0f 84/jump-if-= break/disp32 +19392 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +19393 74/jump-if-= break/disp8 +19394 $operand-matches-primitive?:var-deref-no-match: +19395 e9/jump $operand-matches-primitive?:return-false/disp32 +19396 } +19397 # return false if var->register doesn't match prim-var->register +19398 { +19399 # if register addresses are equal, it's a match +19400 # var vreg/ebx: (addr array byte) = lookup(var->register) +19401 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +19402 89/<- %ebx 0/r32/eax +19403 # var preg/ecx: (addr array byte) = lookup(prim-var->register) +19404 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +19405 89/<- %ecx 0/r32/eax +19406 # if (vreg == preg) break +19407 39/compare %ecx 3/r32/ebx +19408 74/jump-if-= break/disp8 +19409 $operand-matches-primitive?:var-register-no-match: +19410 # if either address is 0, return false +19411 81 7/subop/compare %ebx 0/imm32 +19412 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +19413 81 7/subop/compare %ecx 0/imm32 +19414 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +19415 # if prim-var->register is wildcard, it's a match +19416 (string-equal? %ecx "*") # Any-register => eax +19417 3d/compare-eax-and 0/imm32/false +19418 75/jump-if-!= break/disp8 +19419 $operand-matches-primitive?:wildcard-no-match: +19420 # if string contents aren't equal, return false +19421 (string-equal? %ecx %ebx) # => eax +19422 3d/compare-eax-and 0/imm32/false +19423 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +19424 } +19425 } +19426 $operand-matches-primitive?:return-true: +19427 b8/copy-to-eax 1/imm32/true +19428 eb/jump $operand-matches-primitive?:end/disp8 +19429 $operand-matches-primitive?:return-false: +19430 b8/copy-to-eax 0/imm32/false +19431 $operand-matches-primitive?:end: +19432 # . restore registers +19433 5f/pop-to-edi +19434 5e/pop-to-esi +19435 5b/pop-to-ebx +19436 5a/pop-to-edx +19437 59/pop-to-ecx +19438 # . epilogue +19439 89/<- %esp 5/r32/ebp +19440 5d/pop-to-ebp +19441 c3/return +19442 +19443 find-matching-function: # functions: (addr function), stmt: (addr stmt) -> result/eax: (addr function) +19444 # . prologue +19445 55/push-ebp +19446 89/<- %ebp 4/r32/esp +19447 # . save registers +19448 51/push-ecx +19449 # var curr/ecx: (handle function) = functions +19450 8b/-> *(ebp+8) 1/r32/ecx +19451 { +19452 # if (curr == null) break +19453 81 7/subop/compare %ecx 0/imm32 +19454 74/jump-if-= break/disp8 +19455 #? (write-buffered Stderr "iter\n") +19456 #? (flush Stderr) +19457 # if match(stmt, curr) return curr +19458 { +19459 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax +19460 3d/compare-eax-and 0/imm32/false +19461 74/jump-if-= break/disp8 +19462 89/<- %eax 1/r32/ecx +19463 eb/jump $find-matching-function:end/disp8 +19464 } +19465 # curr = curr->next +19466 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax +19467 89/<- %ecx 0/r32/eax +19468 # +19469 eb/jump loop/disp8 +19470 } +19471 # return null +19472 b8/copy-to-eax 0/imm32 +19473 $find-matching-function:end: +19474 # . restore registers +19475 59/pop-to-ecx +19476 # . epilogue +19477 89/<- %esp 5/r32/ebp +19478 5d/pop-to-ebp +19479 c3/return +19480 +19481 # Just compare names; user-defined functions don't support overloading yet. +19482 mu-stmt-matches-function?: # stmt: (addr stmt1), function: (addr function) -> result/eax: boolean +19483 # . prologue +19484 55/push-ebp +19485 89/<- %ebp 4/r32/esp +19486 # . save registers +19487 51/push-ecx +19488 # return function->name == stmt->operation +19489 # ecx = lookup(stmt->operation) +19490 8b/-> *(ebp+8) 0/r32/eax +19491 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +19492 89/<- %ecx 0/r32/eax +19493 # eax = lookup(function->name) +19494 8b/-> *(ebp+0xc) 0/r32/eax +19495 (lookup *eax *(eax+4)) # Function-name Function-name => eax +19496 (string-equal? %eax %ecx) # => eax +19497 $mu-stmt-matches-function?:end: +19498 # . restore registers +19499 59/pop-to-ecx +19500 # . epilogue +19501 89/<- %esp 5/r32/ebp +19502 5d/pop-to-ebp +19503 c3/return +19504 +19505 # Type-checking happens elsewhere. This method is for selecting between +19506 # primitives. +19507 subx-type-category-match?: # a: (addr type-tree), b: (addr type-tree) -> result/eax: boolean +19508 # . prologue +19509 55/push-ebp +19510 89/<- %ebp 4/r32/esp +19511 # . save registers +19512 51/push-ecx +19513 # var alit/ecx: boolean = is-literal-type?(a) +19514 (is-simple-mu-type? *(ebp+8) 0) # => eax +19515 89/<- %ecx 0/r32/eax +19516 # var blit/eax: boolean = is-literal-type?(b) +19517 (is-simple-mu-type? *(ebp+0xc) 0) # => eax +19518 # return alit == blit +19519 39/compare %eax 1/r32/ecx +19520 0f 94/set-byte-if-= %al +19521 81 4/subop/and %eax 0xff/imm32 +19522 $subx-type-category-match?:end: +19523 # . restore registers +19524 59/pop-to-ecx +19525 # . epilogue +19526 89/<- %esp 5/r32/ebp +19527 5d/pop-to-ebp +19528 c3/return +19529 +19530 is-simple-mu-type?: # a: (addr type-tree), n: type-id -> result/eax: boolean +19531 # . prologue +19532 55/push-ebp +19533 89/<- %ebp 4/r32/esp +19534 # . save registers +19535 51/push-ecx +19536 # ecx = n +19537 8b/-> *(ebp+0xc) 1/r32/ecx +19538 # return (a->value == n) +19539 8b/-> *(ebp+8) 0/r32/eax +19540 39/compare *(eax+4) 1/r32/ecx # Type-tree-value +19541 0f 94/set-byte-if-= %al +19542 81 4/subop/and %eax 0xff/imm32 +19543 $is-simple-mu-type?:end: +19544 # . restore registers +19545 59/pop-to-ecx +19546 # . epilogue +19547 89/<- %esp 5/r32/ebp +19548 5d/pop-to-ebp +19549 c3/return +19550 +19551 is-mu-addr-type?: # a: (addr type-tree) -> result/eax: boolean +19552 # . prologue +19553 55/push-ebp +19554 89/<- %ebp 4/r32/esp +19555 # eax = a +19556 8b/-> *(ebp+8) 0/r32/eax +19557 # if (!a->is-atom?) a = a->left +19558 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +19559 { +19560 75/jump-if-!= break/disp8 +19561 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +19562 } +19563 # return (a->value == addr) +19564 81 7/subop/compare *(eax+4) 2/imm32/addr # Type-tree-value +19565 0f 94/set-byte-if-= %al +19566 81 4/subop/and %eax 0xff/imm32 +19567 $is-mu-addr-type?:end: +19568 # . epilogue +19569 89/<- %esp 5/r32/ebp +19570 5d/pop-to-ebp +19571 c3/return +19572 +19573 is-mu-array-type?: # a: (addr type-tree) -> result/eax: boolean +19574 # . prologue +19575 55/push-ebp +19576 89/<- %ebp 4/r32/esp +19577 # eax = a +19578 8b/-> *(ebp+8) 0/r32/eax +19579 # if (!a->is-atom?) a = a->left +19580 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom +19581 { +19582 75/jump-if-!= break/disp8 +19583 (lookup *(eax+4) *(eax+8)) # Type-tree-left Type-tree-left => eax +19584 } +19585 # return (a->value == array) +19586 81 7/subop/compare *(eax+4) 3/imm32/array # Type-tree-value +19587 0f 94/set-byte-if-= %al +19588 81 4/subop/and %eax 0xff/imm32 +19589 $is-mu-array-type?:end: +19590 # . epilogue +19591 89/<- %esp 5/r32/ebp +19592 5d/pop-to-ebp +19593 c3/return +19594 +19595 test-emit-subx-stmt-primitive: +19596 # Primitive operation on a variable on the stack. +19597 # increment foo +19598 # => +19599 # ff 0/subop/increment *(ebp-8) +19600 # +19601 # There's a variable on the var stack as follows: +19602 # name: 'foo' +19603 # type: int +19604 # stack-offset: -8 +19605 # +19606 # There's a primitive with this info: +19607 # name: 'increment' +19608 # inouts: int/mem +19609 # value: 'ff 0/subop/increment' +19610 # +19611 # . prologue +19612 55/push-ebp +19613 89/<- %ebp 4/r32/esp +19614 # setup +19615 (clear-stream _test-output-stream) +19616 (clear-stream $_test-output-buffered-file->buffer) +19617 # simulate allocated payloads starting with an initial fake alloc-id (0x11) +19618 $test-emit-subx-stmt-primitive:initialize-type: +19619 # var type/ecx: (payload type-tree) = int +19620 68/push 0/imm32/right:null +19621 68/push 0/imm32/right:null +19622 68/push 0/imm32/left:unused +19623 68/push 1/imm32/value:int +19624 68/push 1/imm32/is-atom?:true +19625 68/push 0x11/imm32/alloc-id:fake:payload +19626 89/<- %ecx 4/r32/esp +19627 $test-emit-subx-stmt-primitive:initialize-var: +19628 # var var-foo/ecx: (payload var) = var(type) +19629 68/push 0/imm32/no-register +19630 68/push 0/imm32/no-register +19631 68/push -8/imm32/stack-offset +19632 68/push 1/imm32/block-depth +19633 51/push-ecx/type +19634 68/push 0x11/imm32/alloc-id:fake +19635 68/push 0/imm32/name +19636 68/push 0/imm32/name +19637 68/push 0x11/imm32/alloc-id:fake:payload +19638 89/<- %ecx 4/r32/esp +19639 $test-emit-subx-stmt-primitive:initialize-var-name: +19640 # var-foo->name = "foo" +19641 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +19642 (copy-array Heap "foo" %eax) +19643 $test-emit-subx-stmt-primitive:initialize-stmt-var: +19644 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +19645 68/push 0/imm32/is-deref:false +19646 68/push 0/imm32/next +19647 68/push 0/imm32/next +19648 51/push-ecx/var-foo +19649 68/push 0x11/imm32/alloc-id:fake +19650 68/push 0x11/imm32/alloc-id:fake:payload +19651 89/<- %ebx 4/r32/esp +19652 $test-emit-subx-stmt-primitive:initialize-stmt: +19653 # var stmt/esi: (addr statement) +19654 68/push 0/imm32/no-outputs +19655 68/push 0/imm32/no-outputs +19656 53/push-ebx/inouts +19657 68/push 0x11/imm32/alloc-id:fake +19658 68/push 0/imm32/operation +19659 68/push 0/imm32/operation +19660 68/push 1/imm32/tag +19661 89/<- %esi 4/r32/esp +19662 $test-emit-subx-stmt-primitive:initialize-stmt-operation: +19663 # stmt->operation = "increment" +19664 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +19665 (copy-array Heap "increment" %eax) +19666 $test-emit-subx-stmt-primitive:initialize-primitive: +19667 # var primitives/ebx: (addr primitive) +19668 68/push 0/imm32/next +19669 68/push 0/imm32/next +19670 68/push 0/imm32/output-is-write-only +19671 68/push 0/imm32/no-disp32 +19672 68/push 0/imm32/no-imm8 +19673 68/push 0/imm32/no-imm32 +19674 68/push 0/imm32/no-r32 +19675 68/push 1/imm32/rm32-is-first-inout +19676 68/push 0/imm32/subx-name +19677 68/push 0/imm32/subx-name +19678 68/push 0/imm32/no-outputs +19679 68/push 0/imm32/no-outputs +19680 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +19681 68/push 0x11/imm32/alloc-id:fake +19682 68/push 0/imm32/name +19683 68/push 0/imm32/name +19684 89/<- %ebx 4/r32/esp +19685 $test-emit-subx-stmt-primitive:initialize-primitive-name: +19686 # primitives->name = "increment" +19687 (copy-array Heap "increment" %ebx) # Primitive-name +19688 $test-emit-subx-stmt-primitive:initialize-primitive-subx-name: +19689 # primitives->subx-name = "ff 0/subop/increment" +19690 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +19691 (copy-array Heap "ff 0/subop/increment" %eax) +19692 # convert +19693 c7 0/subop/copy *Curr-block-depth 0/imm32 +19694 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) +19695 (flush _test-output-buffered-file) +19696 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +19702 # check output +19703 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-stmt-primitive") +19704 # . epilogue +19705 89/<- %esp 5/r32/ebp +19706 5d/pop-to-ebp +19707 c3/return +19708 +19709 test-emit-subx-stmt-primitive-register: +19710 # Primitive operation on a variable in a register. +19711 # foo <- increment +19712 # => +19713 # ff 0/subop/increment %eax # sub-optimal, but should suffice +19714 # +19715 # There's a variable on the var stack as follows: +19716 # name: 'foo' +19717 # type: int +19718 # register: 'eax' +19719 # +19720 # There's a primitive with this info: +19721 # name: 'increment' +19722 # out: int/reg +19723 # value: 'ff 0/subop/increment' +19724 # +19725 # . prologue +19726 55/push-ebp +19727 89/<- %ebp 4/r32/esp +19728 # setup +19729 (clear-stream _test-output-stream) +19730 (clear-stream $_test-output-buffered-file->buffer) +19731 $test-emit-subx-stmt-primitive-register:initialize-type: +19732 # var type/ecx: (payload type-tree) = int +19733 68/push 0/imm32/right:null +19734 68/push 0/imm32/right:null +19735 68/push 0/imm32/left:unused +19736 68/push 1/imm32/value:int +19737 68/push 1/imm32/is-atom?:true +19738 68/push 0x11/imm32/alloc-id:fake:payload +19739 89/<- %ecx 4/r32/esp +19740 $test-emit-subx-stmt-primitive-register:initialize-var: +19741 # var var-foo/ecx: (payload var) +19742 68/push 0/imm32/register +19743 68/push 0/imm32/register +19744 68/push 0/imm32/no-stack-offset +19745 68/push 1/imm32/block-depth +19746 51/push-ecx +19747 68/push 0x11/imm32/alloc-id:fake +19748 68/push 0/imm32/name +19749 68/push 0/imm32/name +19750 68/push 0x11/imm32/alloc-id:fake:payload +19751 89/<- %ecx 4/r32/esp +19752 $test-emit-subx-stmt-primitive-register:initialize-var-name: +19753 # var-foo->name = "foo" +19754 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +19755 (copy-array Heap "foo" %eax) +19756 $test-emit-subx-stmt-primitive-register:initialize-var-register: +19757 # var-foo->register = "eax" +19758 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +19759 (copy-array Heap "eax" %eax) +19760 $test-emit-subx-stmt-primitive-register:initialize-stmt-var: +19761 # var operand/ebx: (payload stmt-var) +19762 68/push 0/imm32/is-deref:false +19763 68/push 0/imm32/next +19764 68/push 0/imm32/next +19765 51/push-ecx/var-foo +19766 68/push 0x11/imm32/alloc-id:fake +19767 68/push 0x11/imm32/alloc-id:fake:payload +19768 89/<- %ebx 4/r32/esp +19769 $test-emit-subx-stmt-primitive-register:initialize-stmt: +19770 # var stmt/esi: (addr statement) +19771 53/push-ebx/outputs +19772 68/push 0x11/imm32/alloc-id:fake +19773 68/push 0/imm32/no-inouts +19774 68/push 0/imm32/no-inouts +19775 68/push 0/imm32/operation +19776 68/push 0/imm32/operation +19777 68/push 1/imm32 +19778 89/<- %esi 4/r32/esp +19779 $test-emit-subx-stmt-primitive-register:initialize-stmt-operation: +19780 # stmt->operation = "increment" +19781 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +19782 (copy-array Heap "increment" %eax) +19783 $test-emit-subx-stmt-primitive-register:initialize-formal-var: +19784 # var formal-var/ebx: (payload var) +19785 68/push 0/imm32/register +19786 68/push 0/imm32/register +19787 68/push 0/imm32/no-stack-offset +19788 68/push 1/imm32/block-depth +19789 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +19790 68/push 0x11/imm32/alloc-id:fake +19791 68/push 0/imm32/name +19792 68/push 0/imm32/name +19793 68/push 0x11/imm32/alloc-id:fake:payload +19794 89/<- %ebx 4/r32/esp +19795 $test-emit-subx-stmt-primitive-register:initialize-formal-var-name: +19796 # formal-var->name = "dummy" +19797 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +19798 (copy-array Heap "dummy" %eax) +19799 $test-emit-subx-stmt-primitive-register:initialize-formal-register: +19800 # formal-var->register = "*" +19801 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +19802 (copy-array Heap "*" %eax) # Any-register +19803 $test-emit-subx-stmt-primitive-register:initialize-var-list: +19804 # var formal-outputs/ebx: (payload list var) +19805 68/push 0/imm32/next +19806 68/push 0/imm32/next +19807 53/push-ebx/formal-var +19808 68/push 0x11/imm32/alloc-id:fake +19809 68/push 0x11/imm32/alloc-id:fake:payload +19810 89/<- %ebx 4/r32/esp +19811 $test-emit-subx-stmt-primitive-register:initialize-primitive: +19812 # var primitives/ebx: (addr primitive) +19813 68/push 0/imm32/next +19814 68/push 0/imm32/next +19815 68/push 0/imm32/output-is-write-only +19816 68/push 0/imm32/no-disp32 +19817 68/push 0/imm32/no-imm8 +19818 68/push 0/imm32/no-imm32 +19819 68/push 0/imm32/no-r32 +19820 68/push 3/imm32/rm32-is-first-output +19821 68/push 0/imm32/subx-name +19822 68/push 0/imm32/subx-name +19823 53/push-ebx/outputs +19824 68/push 0x11/imm32/alloc-id:fake +19825 68/push 0/imm32/no-inouts +19826 68/push 0/imm32/no-inouts +19827 68/push 0/imm32/name +19828 68/push 0/imm32/name +19829 89/<- %ebx 4/r32/esp +19830 $test-emit-subx-stmt-primitive-register:initialize-primitive-name: +19831 # primitives->name = "increment" +19832 (copy-array Heap "increment" %ebx) # Primitive-name +19833 $test-emit-subx-stmt-primitive-register:initialize-primitive-subx-name: +19834 # primitives->subx-name = "ff 0/subop/increment" +19835 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +19836 (copy-array Heap "ff 0/subop/increment" %eax) +19837 # convert +19838 c7 0/subop/copy *Curr-block-depth 0/imm32 +19839 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) +19840 (flush _test-output-buffered-file) +19841 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +19847 # check output +19848 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-primitive-register") +19849 # . epilogue +19850 89/<- %esp 5/r32/ebp +19851 5d/pop-to-ebp +19852 c3/return +19853 +19854 test-emit-subx-stmt-select-primitive: +19855 # Select the right primitive between overloads. +19856 # foo <- increment +19857 # => +19858 # ff 0/subop/increment %eax # sub-optimal, but should suffice +19859 # +19860 # There's a variable on the var stack as follows: +19861 # name: 'foo' +19862 # type: int +19863 # register: 'eax' +19864 # +19865 # There's two primitives, as follows: +19866 # - name: 'increment' +19867 # out: int/reg +19868 # value: 'ff 0/subop/increment' +19869 # - name: 'increment' +19870 # inout: int/mem +19871 # value: 'ff 0/subop/increment' +19872 # +19873 # . prologue +19874 55/push-ebp +19875 89/<- %ebp 4/r32/esp +19876 # setup +19877 (clear-stream _test-output-stream) +19878 (clear-stream $_test-output-buffered-file->buffer) +19879 $test-emit-subx-stmt-select-primitive:initialize-type: +19880 # var type/ecx: (payload type-tree) = int +19881 68/push 0/imm32/right:null +19882 68/push 0/imm32/right:null +19883 68/push 0/imm32/left:unused +19884 68/push 1/imm32/value:int +19885 68/push 1/imm32/is-atom?:true +19886 68/push 0x11/imm32/alloc-id:fake:payload +19887 89/<- %ecx 4/r32/esp +19888 $test-emit-subx-stmt-select-primitive:initialize-var: +19889 # var var-foo/ecx: (payload var) +19890 68/push 0/imm32/register +19891 68/push 0/imm32/register +19892 68/push 0/imm32/no-stack-offset +19893 68/push 1/imm32/block-depth +19894 51/push-ecx +19895 68/push 0x11/imm32/alloc-id:fake +19896 68/push 0/imm32/name +19897 68/push 0/imm32/name 19898 68/push 0x11/imm32/alloc-id:fake:payload 19899 89/<- %ecx 4/r32/esp -19900 $test-compare-reg-with-mem:initialize-var1: -19901 # var var1/ecx: (payload var) -19902 68/push 0/imm32/register -19903 68/push 0/imm32/register -19904 68/push 0/imm32/no-stack-offset -19905 68/push 1/imm32/block-depth -19906 51/push-ecx -19907 68/push 0x11/imm32/alloc-id:fake -19908 68/push 0/imm32/name -19909 68/push 0/imm32/name -19910 68/push 0x11/imm32/alloc-id:fake:payload -19911 89/<- %ecx 4/r32/esp -19912 $test-compare-reg-with-mem:initialize-var1-name: -19913 # var1->name = "var1" -19914 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -19915 (copy-array Heap "var1" %eax) -19916 $test-compare-reg-with-mem:initialize-var1-register: -19917 # var1->register = "eax" -19918 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -19919 (copy-array Heap "eax" %eax) -19920 $test-compare-reg-with-mem:initialize-var2: -19921 # var var2/edx: (payload var) -19922 68/push 0/imm32/register -19923 68/push 0/imm32/register -19924 68/push 8/imm32/stack-offset -19925 68/push 1/imm32/block-depth -19926 ff 6/subop/push *(ecx+0x10) -19927 68/push 0x11/imm32/alloc-id:fake -19928 68/push 0/imm32/name -19929 68/push 0/imm32/name -19930 68/push 0x11/imm32/alloc-id:fake:payload -19931 89/<- %edx 4/r32/esp -19932 $test-compare-reg-with-mem:initialize-var2-name: -19933 # var2->name = "var2" -19934 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -19935 (copy-array Heap "var2" %eax) -19936 $test-compare-reg-with-mem:initialize-inouts: -19937 # var inouts/esi: (payload stmt-var) = [var2] -19938 68/push 0/imm32/is-deref:false -19939 68/push 0/imm32/next -19940 68/push 0/imm32/next -19941 52/push-edx/var2 -19942 68/push 0x11/imm32/alloc-id:fake -19943 68/push 0x11/imm32/alloc-id:fake:payload -19944 89/<- %esi 4/r32/esp -19945 # inouts = [var1, var2] -19946 68/push 0/imm32/is-deref:false -19947 56/push-esi/next -19948 68/push 0x11/imm32/alloc-id:fake -19949 51/push-ecx/var1 -19950 68/push 0x11/imm32/alloc-id:fake -19951 68/push 0x11/imm32/alloc-id:fake:payload -19952 89/<- %esi 4/r32/esp -19953 $test-compare-reg-with-mem:initialize-stmt: -19954 # var stmt/esi: (addr statement) -19955 68/push 0/imm32/next -19956 68/push 0/imm32/next -19957 68/push 0/imm32/outputs -19958 68/push 0/imm32/outputs -19959 56/push-esi/inouts -19960 68/push 0x11/imm32/alloc-id:fake -19961 68/push 0/imm32/operation -19962 68/push 0/imm32/operation -19963 68/push 1/imm32/tag:stmt1 -19964 89/<- %esi 4/r32/esp -19965 $test-compare-reg-with-mem:initialize-stmt-operation: -19966 # stmt->operation = "compare" -19967 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -19968 (copy-array Heap "compare" %eax) -19969 # convert -19970 c7 0/subop/copy *Curr-block-depth 0/imm32 -19971 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -19972 (flush _test-output-buffered-file) -19973 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -19979 # check output -19980 (check-next-stream-line-equal _test-output-stream "3b/compare<- *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem") -19981 # . epilogue -19982 89/<- %esp 5/r32/ebp -19983 5d/pop-to-ebp -19984 c3/return -19985 -19986 test-compare-mem-with-literal: -19987 # compare var1, 0x34 -19988 # => -19989 # 81 7/subop/compare *(ebp+___) 0x34/imm32 -19990 # -19991 # . prologue -19992 55/push-ebp -19993 89/<- %ebp 4/r32/esp -19994 # setup -19995 (clear-stream _test-output-stream) -19996 (clear-stream $_test-output-buffered-file->buffer) -19997 $test-compare-mem-with-literal:initialize-type: -19998 # var type/ecx: (payload type-tree) = int -19999 68/push 0/imm32/right:null -20000 68/push 0/imm32/right:null -20001 68/push 0/imm32/left:unused -20002 68/push 1/imm32/value:int -20003 68/push 1/imm32/is-atom?:true -20004 68/push 0x11/imm32/alloc-id:fake:payload -20005 89/<- %ecx 4/r32/esp -20006 $test-compare-mem-with-literal:initialize-var1: -20007 # var var1/ecx: (payload var) -20008 68/push 0/imm32/register -20009 68/push 0/imm32/register -20010 68/push 8/imm32/stack-offset -20011 68/push 1/imm32/block-depth -20012 51/push-ecx -20013 68/push 0x11/imm32/alloc-id:fake -20014 68/push 0/imm32/name -20015 68/push 0/imm32/name -20016 68/push 0x11/imm32/alloc-id:fake:payload -20017 89/<- %ecx 4/r32/esp -20018 $test-compare-mem-with-literal:initialize-var1-name: -20019 # var1->name = "var1" -20020 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -20021 (copy-array Heap "var1" %eax) -20022 $test-compare-mem-with-literal:initialize-literal-type: -20023 # var type/edx: (payload type-tree) = literal -20024 68/push 0/imm32/right:null -20025 68/push 0/imm32/right:null -20026 68/push 0/imm32/left:unused -20027 68/push 0/imm32/value:literal -20028 68/push 1/imm32/is-atom?:true -20029 68/push 0x11/imm32/alloc-id:fake:payload -20030 89/<- %edx 4/r32/esp -20031 $test-compare-mem-with-literal:initialize-literal: -20032 # var l/edx: (payload var) -20033 68/push 0/imm32/register -20034 68/push 0/imm32/register -20035 68/push 0/imm32/no-stack-offset -20036 68/push 1/imm32/block-depth -20037 52/push-edx -20038 68/push 0x11/imm32/alloc-id:fake -20039 68/push 0/imm32/name -20040 68/push 0/imm32/name -20041 68/push 0x11/imm32/alloc-id:fake:payload -20042 89/<- %edx 4/r32/esp -20043 $test-compare-mem-with-literal:initialize-literal-value: -20044 # l->name = "0x34" -20045 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -20046 (copy-array Heap "0x34" %eax) -20047 $test-compare-mem-with-literal:initialize-inouts: -20048 # var inouts/esi: (payload stmt-var) = [l] -20049 68/push 0/imm32/is-deref:false -20050 68/push 0/imm32/next -20051 68/push 0/imm32/next -20052 52/push-edx/l -20053 68/push 0x11/imm32/alloc-id:fake -20054 68/push 0x11/imm32/alloc-id:fake:payload -20055 89/<- %esi 4/r32/esp -20056 # var inouts = (handle stmt-var) = [var1, var2] -20057 68/push 0/imm32/is-deref:false -20058 56/push-esi/next -20059 68/push 0x11/imm32/alloc-id:fake -20060 51/push-ecx/var1 -20061 68/push 0x11/imm32/alloc-id:fake +19900 $test-emit-subx-stmt-select-primitive:initialize-var-name: +19901 # var-foo->name = "foo" +19902 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +19903 (copy-array Heap "foo" %eax) +19904 $test-emit-subx-stmt-select-primitive:initialize-var-register: +19905 # var-foo->register = "eax" +19906 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +19907 (copy-array Heap "eax" %eax) +19908 $test-emit-subx-stmt-select-primitive:initialize-stmt-var: +19909 # var operand/ebx: (payload stmt-var) +19910 68/push 0/imm32/is-deref:false +19911 68/push 0/imm32/next +19912 68/push 0/imm32/next +19913 51/push-ecx/var-foo +19914 68/push 0x11/imm32/alloc-id:fake +19915 68/push 0x11/imm32/alloc-id:fake:payload +19916 89/<- %ebx 4/r32/esp +19917 $test-emit-subx-stmt-select-primitive:initialize-stmt: +19918 # var stmt/esi: (addr statement) +19919 53/push-ebx/outputs +19920 68/push 0x11/imm32/alloc-id:fake +19921 68/push 0/imm32/no-inouts +19922 68/push 0/imm32/no-inouts +19923 68/push 0/imm32/operation +19924 68/push 0/imm32/operation +19925 68/push 1/imm32 +19926 89/<- %esi 4/r32/esp +19927 $test-emit-subx-stmt-select-primitive:initialize-stmt-operation: +19928 # stmt->operation = "increment" +19929 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +19930 (copy-array Heap "increment" %eax) +19931 $test-emit-subx-stmt-select-primitive:initialize-formal-var: +19932 # var formal-var/ebx: (payload var) +19933 68/push 0/imm32/register +19934 68/push 0/imm32/register +19935 68/push 0/imm32/no-stack-offset +19936 68/push 1/imm32/block-depth +19937 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +19938 68/push 0x11/imm32/alloc-id:fake +19939 68/push 0/imm32/name +19940 68/push 0/imm32/name +19941 68/push 0x11/imm32/alloc-id:fake:payload +19942 89/<- %ebx 4/r32/esp +19943 $test-emit-subx-stmt-select-primitive:initialize-formal-var-name: +19944 # formal-var->name = "dummy" +19945 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +19946 (copy-array Heap "dummy" %eax) +19947 $test-emit-subx-stmt-select-primitive:initialize-formal-register: +19948 # formal-var->register = "*" +19949 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +19950 (copy-array Heap "*" %eax) # Any-register +19951 $test-emit-subx-stmt-select-primitive:initialize-var-list: +19952 # var formal-outputs/ebx: (payload list var) +19953 68/push 0/imm32/next +19954 68/push 0/imm32/next +19955 53/push-ebx/formal-var +19956 68/push 0x11/imm32/alloc-id:fake +19957 68/push 0x11/imm32/alloc-id:fake:payload +19958 89/<- %ebx 4/r32/esp +19959 $test-emit-subx-stmt-select-primitive:initialize-primitive2: +19960 # var primitive2/edi: (payload primitive) +19961 68/push 0/imm32/next +19962 68/push 0/imm32/next +19963 68/push 0/imm32/output-is-write-only +19964 68/push 0/imm32/no-disp32 +19965 68/push 0/imm32/no-imm8 +19966 68/push 0/imm32/no-imm32 +19967 68/push 0/imm32/no-r32 +19968 68/push 3/imm32/rm32-is-first-output +19969 68/push 0/imm32/subx-name +19970 68/push 0/imm32/subx-name +19971 53/push-ebx/outputs +19972 68/push 0x11/imm32/alloc-id:fake +19973 68/push 0/imm32/no-inouts +19974 68/push 0/imm32/no-inouts +19975 68/push 0/imm32/name +19976 68/push 0/imm32/name +19977 68/push 0x11/imm32/alloc-id:fake:payload +19978 89/<- %edi 4/r32/esp +19979 $test-emit-subx-stmt-select-primitive:initialize-primitive2-name: +19980 # primitives->name = "increment" +19981 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 +19982 (copy-array Heap "increment" %eax) +19983 $test-emit-subx-stmt-select-primitive:initialize-primitive2-subx-name: +19984 # primitives->subx-name = "ff 0/subop/increment" +19985 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 +19986 (copy-array Heap "ff 0/subop/increment" %eax) +19987 $test-emit-subx-stmt-select-primitive:initialize-primitive: +19988 # var primitives/ebx: (addr primitive) +19989 57/push-edi +19990 68/push 0x11/imm32/alloc-id:fake +19991 68/push 0/imm32/output-is-write-only +19992 68/push 0/imm32/no-disp32 +19993 68/push 0/imm32/no-imm8 +19994 68/push 0/imm32/no-imm32 +19995 68/push 0/imm32/no-r32 +19996 68/push 1/imm32/rm32-is-first-inout +19997 68/push 0/imm32/subx-name +19998 68/push 0/imm32/subx-name +19999 68/push 0/imm32/no-outputs +20000 68/push 0/imm32/no-outputs +20001 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +20002 68/push 0x11/imm32/alloc-id:fake +20003 68/push 0/imm32/name +20004 68/push 0/imm32/name +20005 89/<- %ebx 4/r32/esp +20006 $test-emit-subx-stmt-select-primitive:initialize-primitive-name: +20007 # primitives->name = "increment" +20008 (copy-array Heap "increment" %ebx) # Primitive-name +20009 $test-emit-subx-stmt-select-primitive:initialize-primitive-subx-name: +20010 # primitives->subx-name = "ff 0/subop/increment" +20011 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +20012 (copy-array Heap "ff 0/subop/increment" %eax) +20013 # convert +20014 c7 0/subop/copy *Curr-block-depth 0/imm32 +20015 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) +20016 (flush _test-output-buffered-file) +20017 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +20023 # check output +20024 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive") +20025 # . epilogue +20026 89/<- %esp 5/r32/ebp +20027 5d/pop-to-ebp +20028 c3/return +20029 +20030 test-emit-subx-stmt-select-primitive-2: +20031 # Select the right primitive between overloads. +20032 # increment foo +20033 # => +20034 # ff 0/subop/increment %eax # sub-optimal, but should suffice +20035 # +20036 # There's a variable on the var stack as follows: +20037 # name: 'foo' +20038 # type: int +20039 # register: 'eax' +20040 # +20041 # There's two primitives, as follows: +20042 # - name: 'increment' +20043 # out: int/reg +20044 # value: 'ff 0/subop/increment' +20045 # - name: 'increment' +20046 # inout: int/mem +20047 # value: 'ff 0/subop/increment' +20048 # +20049 # . prologue +20050 55/push-ebp +20051 89/<- %ebp 4/r32/esp +20052 # setup +20053 (clear-stream _test-output-stream) +20054 (clear-stream $_test-output-buffered-file->buffer) +20055 $test-emit-subx-stmt-select-primitive-2:initialize-type: +20056 # var type/ecx: (payload type-tree) = int +20057 68/push 0/imm32/right:null +20058 68/push 0/imm32/right:null +20059 68/push 0/imm32/left:unused +20060 68/push 1/imm32/value:int +20061 68/push 1/imm32/is-atom?:true 20062 68/push 0x11/imm32/alloc-id:fake:payload -20063 89/<- %esi 4/r32/esp -20064 $test-compare-mem-with-literal:initialize-stmt: -20065 # var stmt/esi: (addr statement) -20066 68/push 0/imm32/next -20067 68/push 0/imm32/next -20068 68/push 0/imm32/outputs -20069 68/push 0/imm32/outputs -20070 56/push-esi/inouts +20063 89/<- %ecx 4/r32/esp +20064 $test-emit-subx-stmt-select-primitive-2:initialize-var: +20065 # var var-foo/ecx: (payload var) +20066 68/push 0/imm32/register +20067 68/push 0/imm32/register +20068 68/push 0/imm32/no-stack-offset +20069 68/push 1/imm32/block-depth +20070 51/push-ecx 20071 68/push 0x11/imm32/alloc-id:fake -20072 68/push 0/imm32/operation -20073 68/push 0/imm32/operation -20074 68/push 1/imm32/tag:stmt1 -20075 89/<- %esi 4/r32/esp -20076 $test-compare-mem-with-literal:initialize-stmt-operation: -20077 # stmt->operation = "compare" -20078 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -20079 (copy-array Heap "compare" %eax) -20080 # convert -20081 c7 0/subop/copy *Curr-block-depth 0/imm32 -20082 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -20083 (flush _test-output-buffered-file) -20084 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -20090 # check output -20091 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal") -20092 # . epilogue -20093 89/<- %esp 5/r32/ebp -20094 5d/pop-to-ebp -20095 c3/return -20096 -20097 test-compare-eax-with-literal: -20098 # compare var1/eax 0x34 -20099 # => -20100 # 3d/compare-eax-with 0x34/imm32 -20101 # -20102 # . prologue -20103 55/push-ebp -20104 89/<- %ebp 4/r32/esp -20105 # setup -20106 (clear-stream _test-output-stream) -20107 (clear-stream $_test-output-buffered-file->buffer) -20108 $test-compare-eax-with-literal:initialize-type: -20109 # var type/ecx: (payload type-tree) = int -20110 68/push 0/imm32/right:null -20111 68/push 0/imm32/right:null -20112 68/push 0/imm32/left:unused -20113 68/push 1/imm32/value:int -20114 68/push 1/imm32/is-atom?:true -20115 68/push 0x11/imm32/alloc-id:fake:payload -20116 89/<- %ecx 4/r32/esp -20117 $test-compare-eax-with-literal:initialize-var1: -20118 # var var1/ecx: (payload var) -20119 68/push 0/imm32/register -20120 68/push 0/imm32/register -20121 68/push 0/imm32/no-stack-offset -20122 68/push 1/imm32/block-depth -20123 51/push-ecx -20124 68/push 0x11/imm32/alloc-id:fake -20125 68/push 0/imm32/name -20126 68/push 0/imm32/name -20127 68/push 0x11/imm32/alloc-id:fake:payload -20128 89/<- %ecx 4/r32/esp -20129 $test-compare-eax-with-literal:initialize-var1-name: -20130 # var1->name = "var1" -20131 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -20132 (copy-array Heap "var1" %eax) -20133 $test-compare-eax-with-literal:initialize-var1-register: -20134 # v->register = "eax" -20135 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -20136 (copy-array Heap "eax" %eax) -20137 $test-compare-eax-with-literal:initialize-literal-type: -20138 # var type/edx: (payload type-tree) = literal -20139 68/push 0/imm32/right:null -20140 68/push 0/imm32/right:null -20141 68/push 0/imm32/left:unused -20142 68/push 0/imm32/value:literal -20143 68/push 1/imm32/is-atom?:true -20144 68/push 0x11/imm32/alloc-id:fake:payload -20145 89/<- %edx 4/r32/esp -20146 $test-compare-eax-with-literal:initialize-literal: -20147 # var l/edx: (payload var) -20148 68/push 0/imm32/register -20149 68/push 0/imm32/register -20150 68/push 0/imm32/no-stack-offset -20151 68/push 1/imm32/block-depth -20152 52/push-edx -20153 68/push 0x11/imm32/alloc-id:fake -20154 68/push 0/imm32/name -20155 68/push 0/imm32/name -20156 68/push 0x11/imm32/alloc-id:fake:payload -20157 89/<- %edx 4/r32/esp -20158 $test-compare-eax-with-literal:initialize-literal-value: -20159 # l->name = "0x34" -20160 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -20161 (copy-array Heap "0x34" %eax) -20162 $test-compare-eax-with-literal:initialize-inouts: -20163 # var inouts/esi: (payload stmt-var) = [l] -20164 68/push 0/imm32/is-deref:false -20165 68/push 0/imm32/next -20166 68/push 0/imm32/next -20167 52/push-edx/l -20168 68/push 0x11/imm32/alloc-id:fake -20169 68/push 0x11/imm32/alloc-id:fake:payload -20170 89/<- %esi 4/r32/esp -20171 # var inouts = (handle stmt-var) = [var1, var2] -20172 68/push 0/imm32/is-deref:false -20173 56/push-esi/next -20174 68/push 0x11/imm32/alloc-id:fake -20175 51/push-ecx/var1 -20176 68/push 0x11/imm32/alloc-id:fake -20177 68/push 0x11/imm32/alloc-id:fake:payload -20178 89/<- %esi 4/r32/esp -20179 $test-compare-eax-with-literal:initialize-stmt: -20180 # var stmt/esi: (addr statement) -20181 68/push 0/imm32/next -20182 68/push 0/imm32/next -20183 68/push 0/imm32/outputs -20184 68/push 0/imm32/outputs -20185 56/push-esi/inouts -20186 68/push 0x11/imm32/alloc-id:fake -20187 68/push 0/imm32/operation -20188 68/push 0/imm32/operation -20189 68/push 1/imm32/tag:stmt1 -20190 89/<- %esi 4/r32/esp -20191 $test-compare-eax-with-literal:initialize-stmt-operation: -20192 # stmt->operation = "compare" -20193 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -20194 (copy-array Heap "compare" %eax) -20195 # convert -20196 c7 0/subop/copy *Curr-block-depth 0/imm32 -20197 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -20198 (flush _test-output-buffered-file) -20199 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -20205 # check output -20206 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal") -20207 # . epilogue -20208 89/<- %esp 5/r32/ebp -20209 5d/pop-to-ebp -20210 c3/return -20211 -20212 test-compare-reg-with-literal: -20213 # compare var1/ecx 0x34 -20214 # => -20215 # 81 7/subop/compare %ecx 0x34/imm32 +20072 68/push 0/imm32/name +20073 68/push 0/imm32/name +20074 68/push 0x11/imm32/alloc-id:fake:payload +20075 89/<- %ecx 4/r32/esp +20076 $test-emit-subx-stmt-select-primitive-2:initialize-var-name: +20077 # var-foo->name = "foo" +20078 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +20079 (copy-array Heap "foo" %eax) +20080 $test-emit-subx-stmt-select-primitive-2:initialize-var-register: +20081 # var-foo->register = "eax" +20082 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +20083 (copy-array Heap "eax" %eax) +20084 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-var: +20085 # var operand/ebx: (payload stmt-var) +20086 68/push 0/imm32/is-deref:false +20087 68/push 0/imm32/next +20088 68/push 0/imm32/next +20089 51/push-ecx/var-foo +20090 68/push 0x11/imm32/alloc-id:fake +20091 68/push 0x11/imm32/alloc-id:fake:payload +20092 89/<- %ebx 4/r32/esp +20093 $test-emit-subx-stmt-select-primitive-2:initialize-stmt: +20094 # var stmt/esi: (addr statement) +20095 68/push 0/imm32/no-outputs +20096 68/push 0/imm32/no-outputs +20097 53/push-ebx/inouts +20098 68/push 0x11/imm32/alloc-id:fake +20099 68/push 0/imm32/operation +20100 68/push 0/imm32/operation +20101 68/push 1/imm32 +20102 89/<- %esi 4/r32/esp +20103 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-operation: +20104 # stmt->operation = "increment" +20105 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +20106 (copy-array Heap "increment" %eax) +20107 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var: +20108 # var formal-var/ebx: (payload var) +20109 68/push 0/imm32/register +20110 68/push 0/imm32/register +20111 68/push 0/imm32/no-stack-offset +20112 68/push 1/imm32/block-depth +20113 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +20114 68/push 0x11/imm32/alloc-id:fake +20115 68/push 0/imm32/name +20116 68/push 0/imm32/name +20117 68/push 0x11/imm32/alloc-id:fake:payload +20118 89/<- %ebx 4/r32/esp +20119 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var-name: +20120 # formal-var->name = "dummy" +20121 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +20122 (copy-array Heap "dummy" %eax) +20123 $test-emit-subx-stmt-select-primitive-2:initialize-formal-register: +20124 # formal-var->register = "*" +20125 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +20126 (copy-array Heap "*" %eax) # Any-register +20127 $test-emit-subx-stmt-select-primitive-2:initialize-var-list: +20128 # var formal-outputs/ebx: (payload list stmt-var) +20129 68/push 0/imm32/next +20130 68/push 0/imm32/next +20131 53/push-ebx/formal-var +20132 68/push 0x11/imm32/alloc-id:fake +20133 68/push 0x11/imm32/alloc-id:fake:payload +20134 89/<- %ebx 4/r32/esp +20135 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2: +20136 # var primitive2/edi: (payload primitive) +20137 68/push 0/imm32/next +20138 68/push 0/imm32/next +20139 68/push 0/imm32/output-is-write-only +20140 68/push 0/imm32/no-disp32 +20141 68/push 0/imm32/no-imm8 +20142 68/push 0/imm32/no-imm32 +20143 68/push 0/imm32/no-r32 +20144 68/push 3/imm32/rm32-is-first-output +20145 68/push 0/imm32/subx-name +20146 68/push 0/imm32/subx-name +20147 53/push-ebx/outputs +20148 68/push 0x11/imm32/alloc-id:fake +20149 68/push 0/imm32/no-inouts +20150 68/push 0/imm32/no-inouts +20151 68/push 0/imm32/name +20152 68/push 0/imm32/name +20153 68/push 0x11/imm32/alloc-id:fake:payload +20154 89/<- %edi 4/r32/esp +20155 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-name: +20156 # primitives->name = "increment" +20157 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 +20158 (copy-array Heap "increment" %eax) +20159 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-subx-name: +20160 # primitives->subx-name = "ff 0/subop/increment" +20161 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 +20162 (copy-array Heap "ff 0/subop/increment" %eax) +20163 $test-emit-subx-stmt-select-primitive-2:initialize-primitive: +20164 # var primitives/ebx: (addr primitive) +20165 57/push-edi +20166 68/push 0x11/imm32/alloc-id:fake +20167 68/push 0/imm32/output-is-write-only +20168 68/push 0/imm32/no-disp32 +20169 68/push 0/imm32/no-imm8 +20170 68/push 0/imm32/no-imm32 +20171 68/push 0/imm32/no-r32 +20172 68/push 1/imm32/rm32-is-first-inout +20173 68/push 0/imm32/subx-name +20174 68/push 0/imm32/subx-name +20175 68/push 0/imm32/no-outputs +20176 68/push 0/imm32/no-outputs +20177 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +20178 68/push 0x11/imm32/alloc-id:fake +20179 68/push 0/imm32/name +20180 68/push 0/imm32/name +20181 89/<- %ebx 4/r32/esp +20182 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-name: +20183 # primitives->name = "increment" +20184 (copy-array Heap "increment" %ebx) # Primitive-name +20185 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-subx-name: +20186 # primitives->subx-name = "ff 0/subop/increment" +20187 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +20188 (copy-array Heap "ff 0/subop/increment" %eax) +20189 # convert +20190 c7 0/subop/copy *Curr-block-depth 0/imm32 +20191 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) +20192 (flush _test-output-buffered-file) +20193 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +20199 # check output +20200 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive-2") +20201 # . epilogue +20202 89/<- %esp 5/r32/ebp +20203 5d/pop-to-ebp +20204 c3/return +20205 +20206 test-increment-register: +20207 # Select the right register between overloads. +20208 # foo <- increment +20209 # => +20210 # 50/increment-eax +20211 # +20212 # There's a variable on the var stack as follows: +20213 # name: 'foo' +20214 # type: int +20215 # register: 'eax' 20216 # -20217 # . prologue -20218 55/push-ebp -20219 89/<- %ebp 4/r32/esp -20220 # setup -20221 (clear-stream _test-output-stream) -20222 (clear-stream $_test-output-buffered-file->buffer) -20223 $test-compare-reg-with-literal:initialize-type: -20224 # var type/ecx: (payload type-tree) = int -20225 68/push 0/imm32/right:null -20226 68/push 0/imm32/right:null -20227 68/push 0/imm32/left:unused -20228 68/push 1/imm32/value:int -20229 68/push 1/imm32/is-atom?:true -20230 68/push 0x11/imm32/alloc-id:fake:payload -20231 89/<- %ecx 4/r32/esp -20232 $test-compare-reg-with-literal:initialize-var1: -20233 # var var1/ecx: (payload var) -20234 68/push 0/imm32/register -20235 68/push 0/imm32/register -20236 68/push 0/imm32/no-stack-offset -20237 68/push 1/imm32/block-depth -20238 51/push-ecx -20239 68/push 0x11/imm32/alloc-id:fake -20240 68/push 0/imm32/name -20241 68/push 0/imm32/name -20242 68/push 0x11/imm32/alloc-id:fake:payload -20243 89/<- %ecx 4/r32/esp -20244 $test-compare-reg-with-literal:initialize-var1-name: -20245 # var1->name = "var1" -20246 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -20247 (copy-array Heap "var1" %eax) -20248 $test-compare-reg-with-literal:initialize-var1-register: -20249 # v->register = "ecx" -20250 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -20251 (copy-array Heap "ecx" %eax) -20252 $test-compare-reg-with-literal:initialize-literal-type: -20253 # var type/edx: (payload type-tree) = literal -20254 68/push 0/imm32/right:null -20255 68/push 0/imm32/right:null -20256 68/push 0/imm32/left:unused -20257 68/push 0/imm32/value:literal -20258 68/push 1/imm32/is-atom?:true -20259 68/push 0x11/imm32/alloc-id:fake:payload -20260 89/<- %edx 4/r32/esp -20261 $test-compare-reg-with-literal:initialize-literal: -20262 # var l/edx: (payload var) -20263 68/push 0/imm32/register -20264 68/push 0/imm32/register -20265 68/push 0/imm32/no-stack-offset -20266 68/push 1/imm32/block-depth -20267 52/push-edx -20268 68/push 0x11/imm32/alloc-id:fake -20269 68/push 0/imm32/name -20270 68/push 0/imm32/name -20271 68/push 0x11/imm32/alloc-id:fake:payload -20272 89/<- %edx 4/r32/esp -20273 $test-compare-reg-with-literal:initialize-literal-value: -20274 # l->name = "0x34" -20275 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -20276 (copy-array Heap "0x34" %eax) -20277 $test-compare-reg-with-literal:initialize-inouts: -20278 # var inouts/esi: (payload stmt-var) = [l] -20279 68/push 0/imm32/is-deref:false -20280 68/push 0/imm32/next -20281 68/push 0/imm32/next -20282 52/push-edx/l -20283 68/push 0x11/imm32/alloc-id:fake -20284 68/push 0x11/imm32/alloc-id:fake:payload -20285 89/<- %esi 4/r32/esp -20286 # var inouts = (handle stmt-var) = [var1, var2] -20287 68/push 0/imm32/is-deref:false -20288 56/push-esi/next -20289 68/push 0x11/imm32/alloc-id:fake -20290 51/push-ecx/var1 -20291 68/push 0x11/imm32/alloc-id:fake -20292 68/push 0x11/imm32/alloc-id:fake:payload -20293 89/<- %esi 4/r32/esp -20294 $test-compare-reg-with-literal:initialize-stmt: -20295 # var stmt/esi: (addr statement) -20296 68/push 0/imm32/next -20297 68/push 0/imm32/next -20298 68/push 0/imm32/outputs -20299 68/push 0/imm32/outputs -20300 56/push-esi/inouts -20301 68/push 0x11/imm32/alloc-id:fake -20302 68/push 0/imm32/operation -20303 68/push 0/imm32/operation -20304 68/push 1/imm32/tag:stmt1 -20305 89/<- %esi 4/r32/esp -20306 $test-compare-reg-with-literal:initialize-stmt-operation: -20307 # stmt->operation = "compare" -20308 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -20309 (copy-array Heap "compare" %eax) -20310 # convert -20311 c7 0/subop/copy *Curr-block-depth 0/imm32 -20312 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -20313 (flush _test-output-buffered-file) -20314 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -20320 # check output -20321 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal") -20322 # . epilogue -20323 89/<- %esp 5/r32/ebp -20324 5d/pop-to-ebp -20325 c3/return -20326 -20327 test-emit-subx-stmt-function-call: -20328 # Call a function on a variable on the stack. -20329 # f foo -20330 # => -20331 # (f *(ebp-8)) -20332 # (Changing the function name supports overloading in general, but here it -20333 # just serves to help disambiguate things.) -20334 # -20335 # There's a variable on the var stack as follows: -20336 # name: 'foo' -20337 # type: int -20338 # stack-offset: -8 -20339 # -20340 # There's nothing in primitives. -20341 # -20342 # We don't perform any checking here on the type of 'f'. -20343 # -20344 # . prologue -20345 55/push-ebp -20346 89/<- %ebp 4/r32/esp -20347 # setup -20348 (clear-stream _test-output-stream) -20349 (clear-stream $_test-output-buffered-file->buffer) -20350 $test-emit-subx-function-call:initialize-type: -20351 # var type/ecx: (payload type-tree) = int -20352 68/push 0/imm32/right:null -20353 68/push 0/imm32/right:null -20354 68/push 0/imm32/left:unused -20355 68/push 1/imm32/value:int -20356 68/push 1/imm32/is-atom?:true -20357 68/push 0x11/imm32/alloc-id:fake:payload -20358 89/<- %ecx 4/r32/esp -20359 $test-emit-subx-function-call:initialize-var: -20360 # var var-foo/ecx: (payload var) = var(type) -20361 68/push 0/imm32/no-register -20362 68/push 0/imm32/no-register -20363 68/push -8/imm32/stack-offset -20364 68/push 1/imm32/block-depth -20365 51/push-ecx/type -20366 68/push 0x11/imm32/alloc-id:fake -20367 68/push 0/imm32/name -20368 68/push 0/imm32/name -20369 68/push 0x11/imm32/alloc-id:fake:payload -20370 89/<- %ecx 4/r32/esp -20371 $test-emit-subx-function-call:initialize-var-name: -20372 # var-foo->name = "foo" -20373 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -20374 (copy-array Heap "foo" %eax) -20375 $test-emit-subx-function-call:initialize-stmt-var: -20376 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -20377 68/push 0/imm32/is-deref:false -20378 68/push 0/imm32/next -20379 68/push 0/imm32/next -20380 51/push-ecx/var-foo -20381 68/push 0x11/imm32/alloc-id:fake -20382 68/push 0x11/imm32/alloc-id:fake:payload -20383 89/<- %ebx 4/r32/esp -20384 $test-emit-subx-function-call:initialize-stmt: -20385 # var stmt/esi: (addr statement) -20386 68/push 0/imm32/no-outputs -20387 68/push 0/imm32/no-outputs -20388 53/push-ebx/inouts -20389 68/push 0x11/imm32/alloc-id:fake -20390 68/push 0/imm32/operation -20391 68/push 0/imm32/operation -20392 68/push 1/imm32/tag -20393 89/<- %esi 4/r32/esp -20394 $test-emit-subx-function-call:initialize-stmt-operation: -20395 # stmt->operation = "f" -20396 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -20397 (copy-array Heap "f" %eax) -20398 # convert -20399 c7 0/subop/copy *Curr-block-depth 0/imm32 -20400 (emit-subx-stmt _test-output-buffered-file %esi 0 Stderr 0) -20401 (flush _test-output-buffered-file) -20402 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -20408 # check output -20409 (check-next-stream-line-equal _test-output-stream "(f *(ebp+0xfffffff8))" "F - test-emit-subx-stmt-function-call") -20410 # . epilogue -20411 89/<- %esp 5/r32/ebp -20412 5d/pop-to-ebp -20413 c3/return -20414 -20415 test-emit-subx-stmt-function-call-with-literal-arg: -20416 # Call a function on a literal. -20417 # f 0x34 -20418 # => -20419 # (f2 0x34) -20420 # -20421 # . prologue -20422 55/push-ebp -20423 89/<- %ebp 4/r32/esp -20424 # setup -20425 (clear-stream _test-output-stream) -20426 (clear-stream $_test-output-buffered-file->buffer) -20427 $test-emit-subx-function-call-with-literal-arg:initialize-type: -20428 # var type/ecx: (payload type-tree) = int -20429 68/push 0/imm32/right:null -20430 68/push 0/imm32/right:null -20431 68/push 0/imm32/left:unused -20432 68/push 0/imm32/value:literal -20433 68/push 1/imm32/is-atom?:true -20434 68/push 0x11/imm32/alloc-id:fake:payload -20435 89/<- %ecx 4/r32/esp -20436 $test-emit-subx-function-call-with-literal-arg:initialize-var: -20437 # var var-foo/ecx: (payload var) = var(lit) -20438 68/push 0/imm32/no-register -20439 68/push 0/imm32/no-register -20440 68/push 0/imm32/no-stack-offset -20441 68/push 1/imm32/block-depth -20442 51/push-ecx/type -20443 68/push 0x11/imm32/alloc-id:fake -20444 68/push 0/imm32/name -20445 68/push 0/imm32/name -20446 68/push 0x11/imm32/alloc-id:fake:payload -20447 89/<- %ecx 4/r32/esp -20448 $test-emit-subx-function-call-with-literal-arg:initialize-var-name: -20449 # var-foo->name = "0x34" -20450 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -20451 (copy-array Heap "0x34" %eax) -20452 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-var: -20453 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -20454 68/push 0/imm32/is-deref:false -20455 68/push 0/imm32/next -20456 68/push 0/imm32/next -20457 51/push-ecx/var-foo -20458 68/push 0x11/imm32/alloc-id:fake -20459 68/push 0x11/imm32/alloc-id:fake:payload -20460 89/<- %ebx 4/r32/esp -20461 $test-emit-subx-function-call-with-literal-arg:initialize-stmt: -20462 # var stmt/esi: (addr statement) -20463 68/push 0/imm32/no-outputs -20464 68/push 0/imm32/no-outputs -20465 53/push-ebx/inouts -20466 68/push 0x11/imm32/alloc-id:fake -20467 68/push 0/imm32/operation -20468 68/push 0/imm32/operation -20469 68/push 1/imm32/tag -20470 89/<- %esi 4/r32/esp -20471 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-operation: -20472 # stmt->operation = "f" -20473 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -20474 (copy-array Heap "f" %eax) -20475 # convert -20476 c7 0/subop/copy *Curr-block-depth 0/imm32 -20477 (emit-subx-stmt _test-output-buffered-file %esi 0 %ebx Stderr 0) -20478 (flush _test-output-buffered-file) -20479 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -20485 # check output -20486 (check-next-stream-line-equal _test-output-stream "(f 0x34)" "F - test-emit-subx-stmt-function-call-with-literal-arg") -20487 # . epilogue -20488 89/<- %esp 5/r32/ebp -20489 5d/pop-to-ebp -20490 c3/return -20491 -20492 emit-indent: # out: (addr buffered-file), n: int -20493 # . prologue -20494 55/push-ebp -20495 89/<- %ebp 4/r32/esp -20496 # . save registers -20497 50/push-eax -20498 # var i/eax: int = n -20499 8b/-> *(ebp+0xc) 0/r32/eax -20500 { -20501 # if (i <= 0) break -20502 3d/compare-eax-with 0/imm32 -20503 7e/jump-if-<= break/disp8 -20504 (write-buffered *(ebp+8) " ") -20505 48/decrement-eax -20506 eb/jump loop/disp8 -20507 } -20508 $emit-indent:end: -20509 # . restore registers -20510 58/pop-to-eax -20511 # . epilogue -20512 89/<- %esp 5/r32/ebp -20513 5d/pop-to-ebp -20514 c3/return -20515 -20516 emit-subx-prologue: # out: (addr buffered-file) -20517 # . prologue -20518 55/push-ebp -20519 89/<- %ebp 4/r32/esp -20520 # -20521 (write-buffered *(ebp+8) " # . prologue\n") -20522 (write-buffered *(ebp+8) " 55/push-ebp\n") -20523 (write-buffered *(ebp+8) " 89/<- %ebp 4/r32/esp\n") -20524 $emit-subx-prologue:end: -20525 # . epilogue -20526 89/<- %esp 5/r32/ebp -20527 5d/pop-to-ebp -20528 c3/return -20529 -20530 emit-subx-epilogue: # out: (addr buffered-file) -20531 # . prologue -20532 55/push-ebp -20533 89/<- %ebp 4/r32/esp -20534 # -20535 (write-buffered *(ebp+8) " # . epilogue\n") -20536 (write-buffered *(ebp+8) " 89/<- %esp 5/r32/ebp\n") -20537 (write-buffered *(ebp+8) " 5d/pop-to-ebp\n") -20538 (write-buffered *(ebp+8) " c3/return\n") -20539 $emit-subx-epilogue:end: -20540 # . epilogue -20541 89/<- %esp 5/r32/ebp -20542 5d/pop-to-ebp -20543 c3/return +20217 # Primitives are the global definitions. +20218 # +20219 # . prologue +20220 55/push-ebp +20221 89/<- %ebp 4/r32/esp +20222 # setup +20223 (clear-stream _test-output-stream) +20224 (clear-stream $_test-output-buffered-file->buffer) +20225 $test-increment-register:initialize-type: +20226 # var type/ecx: (payload type-tree) = int +20227 68/push 0/imm32/right:null +20228 68/push 0/imm32/right:null +20229 68/push 0/imm32/left:unused +20230 68/push 1/imm32/value:int +20231 68/push 1/imm32/is-atom?:true +20232 68/push 0x11/imm32/alloc-id:fake:payload +20233 89/<- %ecx 4/r32/esp +20234 $test-increment-register:initialize-var: +20235 # var var-foo/ecx: (payload var) +20236 68/push 0/imm32/register +20237 68/push 0/imm32/register +20238 68/push 0/imm32/no-stack-offset +20239 68/push 1/imm32/block-depth +20240 51/push-ecx +20241 68/push 0x11/imm32/alloc-id:fake +20242 68/push 0/imm32/name +20243 68/push 0/imm32/name +20244 68/push 0x11/imm32/alloc-id:fake:payload +20245 89/<- %ecx 4/r32/esp +20246 $test-increment-register:initialize-var-name: +20247 # var-foo->name = "foo" +20248 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +20249 (copy-array Heap "foo" %eax) +20250 $test-increment-register:initialize-var-register: +20251 # var-foo->register = "eax" +20252 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +20253 (copy-array Heap "eax" %eax) +20254 $test-increment-register:initialize-stmt-var: +20255 # var operand/ebx: (payload stmt-var) +20256 68/push 0/imm32/is-deref:false +20257 68/push 0/imm32/next +20258 68/push 0/imm32/next +20259 51/push-ecx/var-foo +20260 68/push 0x11/imm32/alloc-id:fake +20261 68/push 0x11/imm32/alloc-id:fake:payload +20262 89/<- %ebx 4/r32/esp +20263 $test-increment-register:initialize-stmt: +20264 # var stmt/esi: (addr statement) +20265 53/push-ebx/outputs +20266 68/push 0x11/imm32/alloc-id:fake +20267 68/push 0/imm32/no-inouts +20268 68/push 0/imm32/no-inouts +20269 68/push 0/imm32/operation +20270 68/push 0/imm32/operation +20271 68/push 1/imm32 +20272 89/<- %esi 4/r32/esp +20273 $test-increment-register:initialize-stmt-operation: +20274 # stmt->operation = "increment" +20275 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +20276 (copy-array Heap "increment" %eax) +20277 # convert +20278 c7 0/subop/copy *Curr-block-depth 0/imm32 +20279 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +20280 (flush _test-output-buffered-file) +20281 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +20287 # check output +20288 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") +20289 # . epilogue +20290 89/<- %esp 5/r32/ebp +20291 5d/pop-to-ebp +20292 c3/return +20293 +20294 test-add-reg-to-reg: +20295 # var1/reg <- add var2/reg +20296 # => +20297 # 01/add-to %var1 var2 +20298 # +20299 # . prologue +20300 55/push-ebp +20301 89/<- %ebp 4/r32/esp +20302 # setup +20303 (clear-stream _test-output-stream) +20304 (clear-stream $_test-output-buffered-file->buffer) +20305 $test-add-reg-to-reg:initialize-type: +20306 # var type/ecx: (payload type-tree) = int +20307 68/push 0/imm32/right:null +20308 68/push 0/imm32/right:null +20309 68/push 0/imm32/left:unused +20310 68/push 1/imm32/value:int +20311 68/push 1/imm32/is-atom?:true +20312 68/push 0x11/imm32/alloc-id:fake:payload +20313 89/<- %ecx 4/r32/esp +20314 $test-add-reg-to-reg:initialize-var1: +20315 # var var1/ecx: (payload var) +20316 68/push 0/imm32/register +20317 68/push 0/imm32/register +20318 68/push 0/imm32/no-stack-offset +20319 68/push 1/imm32/block-depth +20320 51/push-ecx +20321 68/push 0x11/imm32/alloc-id:fake +20322 68/push 0/imm32/name +20323 68/push 0/imm32/name +20324 68/push 0x11/imm32/alloc-id:fake:payload +20325 89/<- %ecx 4/r32/esp +20326 $test-add-reg-to-reg:initialize-var1-name: +20327 # var1->name = "var1" +20328 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +20329 (copy-array Heap "var1" %eax) +20330 $test-add-reg-to-reg:initialize-var1-register: +20331 # var1->register = "eax" +20332 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +20333 (copy-array Heap "eax" %eax) +20334 $test-add-reg-to-reg:initialize-var2: +20335 # var var2/edx: (payload var) +20336 68/push 0/imm32/register +20337 68/push 0/imm32/register +20338 68/push 0/imm32/no-stack-offset +20339 68/push 1/imm32/block-depth +20340 ff 6/subop/push *(ecx+0x10) +20341 68/push 0x11/imm32/alloc-id:fake +20342 68/push 0/imm32/name +20343 68/push 0/imm32/name +20344 68/push 0x11/imm32/alloc-id:fake:payload +20345 89/<- %edx 4/r32/esp +20346 $test-add-reg-to-reg:initialize-var2-name: +20347 # var2->name = "var2" +20348 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +20349 (copy-array Heap "var2" %eax) +20350 $test-add-reg-to-reg:initialize-var2-register: +20351 # var2->register = "ecx" +20352 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +20353 (copy-array Heap "ecx" %eax) +20354 $test-add-reg-to-reg:initialize-inouts: +20355 # var inouts/esi: (payload stmt-var) = [var2] +20356 68/push 0/imm32/is-deref:false +20357 68/push 0/imm32/next +20358 68/push 0/imm32/next +20359 52/push-edx/var2 +20360 68/push 0x11/imm32/alloc-id:fake +20361 68/push 0x11/imm32/alloc-id:fake:payload +20362 89/<- %esi 4/r32/esp +20363 $test-add-reg-to-reg:initialize-outputs: +20364 # var outputs/edi: (payload stmt-var) = [var1] +20365 68/push 0/imm32/is-deref:false +20366 68/push 0/imm32/next +20367 68/push 0/imm32/next +20368 51/push-ecx/var1 +20369 68/push 0x11/imm32/alloc-id:fake +20370 68/push 0x11/imm32/alloc-id:fake:payload +20371 89/<- %edi 4/r32/esp +20372 $test-add-reg-to-reg:initialize-stmt: +20373 # var stmt/esi: (addr statement) +20374 68/push 0/imm32/next +20375 68/push 0/imm32/next +20376 57/push-edi/outputs +20377 68/push 0x11/imm32/alloc-id:fake +20378 56/push-esi/inouts +20379 68/push 0x11/imm32/alloc-id:fake +20380 68/push 0/imm32/operation +20381 68/push 0/imm32/operation +20382 68/push 1/imm32/tag:stmt1 +20383 89/<- %esi 4/r32/esp +20384 $test-add-reg-to-reg:initialize-stmt-operation: +20385 # stmt->operation = "add" +20386 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +20387 (copy-array Heap "add" %eax) +20388 # convert +20389 c7 0/subop/copy *Curr-block-depth 0/imm32 +20390 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +20391 (flush _test-output-buffered-file) +20392 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +20398 # check output +20399 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") +20400 # . epilogue +20401 89/<- %esp 5/r32/ebp +20402 5d/pop-to-ebp +20403 c3/return +20404 +20405 test-add-reg-to-mem: +20406 # add-to var1 var2/reg +20407 # => +20408 # 01/add-to *(ebp+__) var2 +20409 # +20410 # . prologue +20411 55/push-ebp +20412 89/<- %ebp 4/r32/esp +20413 # setup +20414 (clear-stream _test-output-stream) +20415 (clear-stream $_test-output-buffered-file->buffer) +20416 $test-add-reg-to-mem:initialize-type: +20417 # var type/ecx: (payload type-tree) = int +20418 68/push 0/imm32/right:null +20419 68/push 0/imm32/right:null +20420 68/push 0/imm32/left:unused +20421 68/push 1/imm32/value:int +20422 68/push 1/imm32/is-atom?:true +20423 68/push 0x11/imm32/alloc-id:fake:payload +20424 89/<- %ecx 4/r32/esp +20425 $test-add-reg-to-mem:initialize-var1: +20426 # var var1/ecx: (payload var) +20427 68/push 0/imm32/register +20428 68/push 0/imm32/register +20429 68/push 8/imm32/stack-offset +20430 68/push 1/imm32/block-depth +20431 51/push-ecx +20432 68/push 0x11/imm32/alloc-id:fake +20433 68/push 0/imm32/name +20434 68/push 0/imm32/name +20435 68/push 0x11/imm32/alloc-id:fake:payload +20436 89/<- %ecx 4/r32/esp +20437 $test-add-reg-to-mem:initialize-var1-name: +20438 # var1->name = "var1" +20439 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +20440 (copy-array Heap "var1" %eax) +20441 $test-add-reg-to-mem:initialize-var2: +20442 # var var2/edx: (payload var) +20443 68/push 0/imm32/register +20444 68/push 0/imm32/register +20445 68/push 0/imm32/no-stack-offset +20446 68/push 1/imm32/block-depth +20447 ff 6/subop/push *(ecx+0x10) +20448 68/push 0x11/imm32/alloc-id:fake +20449 68/push 0/imm32/name +20450 68/push 0/imm32/name +20451 68/push 0x11/imm32/alloc-id:fake:payload +20452 89/<- %edx 4/r32/esp +20453 $test-add-reg-to-mem:initialize-var2-name: +20454 # var2->name = "var2" +20455 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +20456 (copy-array Heap "var2" %eax) +20457 $test-add-reg-to-mem:initialize-var2-register: +20458 # var2->register = "ecx" +20459 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +20460 (copy-array Heap "ecx" %eax) +20461 $test-add-reg-to-mem:initialize-inouts: +20462 # var inouts/esi: (payload stmt-var) = [var2] +20463 68/push 0/imm32/is-deref:false +20464 68/push 0/imm32/next +20465 68/push 0/imm32/next +20466 52/push-edx/var2 +20467 68/push 0x11/imm32/alloc-id:fake +20468 68/push 0x11/imm32/alloc-id:fake:payload +20469 89/<- %esi 4/r32/esp +20470 # inouts = [var1, var2] +20471 68/push 0/imm32/is-deref:false +20472 56/push-esi/next +20473 68/push 0x11/imm32/alloc-id:fake +20474 51/push-ecx/var1 +20475 68/push 0x11/imm32/alloc-id:fake +20476 68/push 0x11/imm32/alloc-id:fake:payload +20477 89/<- %esi 4/r32/esp +20478 $test-add-reg-to-mem:initialize-stmt: +20479 # var stmt/esi: (addr statement) +20480 68/push 0/imm32/next +20481 68/push 0/imm32/next +20482 68/push 0/imm32/outputs +20483 68/push 0/imm32/outputs +20484 56/push-esi/inouts +20485 68/push 0x11/imm32/alloc-id:fake +20486 68/push 0/imm32/operation +20487 68/push 0/imm32/operation +20488 68/push 1/imm32/tag:stmt1 +20489 89/<- %esi 4/r32/esp +20490 $test-add-reg-to-mem:initialize-stmt-operation: +20491 # stmt->operation = "add-to" +20492 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +20493 (copy-array Heap "add-to" %eax) +20494 # convert +20495 c7 0/subop/copy *Curr-block-depth 0/imm32 +20496 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +20497 (flush _test-output-buffered-file) +20498 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +20504 # check output +20505 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") +20506 # . epilogue +20507 89/<- %esp 5/r32/ebp +20508 5d/pop-to-ebp +20509 c3/return +20510 +20511 test-add-mem-to-reg: +20512 # var1/reg <- add var2 +20513 # => +20514 # 03/add *(ebp+__) var1 +20515 # +20516 # . prologue +20517 55/push-ebp +20518 89/<- %ebp 4/r32/esp +20519 # setup +20520 (clear-stream _test-output-stream) +20521 (clear-stream $_test-output-buffered-file->buffer) +20522 $test-add-mem-to-reg:initialize-type: +20523 # var type/ecx: (payload type-tree) = int +20524 68/push 0/imm32/right:null +20525 68/push 0/imm32/right:null +20526 68/push 0/imm32/left:unused +20527 68/push 1/imm32/value:int +20528 68/push 1/imm32/is-atom?:true +20529 68/push 0x11/imm32/alloc-id:fake:payload +20530 89/<- %ecx 4/r32/esp +20531 $test-add-mem-to-reg:initialize-var: +20532 # var var1/ecx: (payload var) +20533 68/push 0/imm32/register +20534 68/push 0/imm32/register +20535 68/push 0/imm32/no-stack-offset +20536 68/push 1/imm32/block-depth +20537 51/push-ecx +20538 68/push 0x11/imm32/alloc-id:fake +20539 68/push 0/imm32/name +20540 68/push 0/imm32/name +20541 68/push 0x11/imm32/alloc-id:fake:payload +20542 89/<- %ecx 4/r32/esp +20543 $test-add-mem-to-reg:initialize-var-name: +20544 # var1->name = "foo" +20545 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +20546 (copy-array Heap "var1" %eax) +20547 $test-add-mem-to-reg:initialize-var-register: +20548 # var1->register = "eax" +20549 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +20550 (copy-array Heap "eax" %eax) +20551 $test-add-mem-to-reg:initialize-var2: +20552 # var var2/edx: (payload var) +20553 68/push 0/imm32/register +20554 68/push 0/imm32/register +20555 68/push 8/imm32/stack-offset +20556 68/push 1/imm32/block-depth +20557 ff 6/subop/push *(ecx+0x10) +20558 68/push 0x11/imm32/alloc-id:fake +20559 68/push 0/imm32/name +20560 68/push 0/imm32/name +20561 68/push 0x11/imm32/alloc-id:fake:payload +20562 89/<- %edx 4/r32/esp +20563 $test-add-mem-to-reg:initialize-var2-name: +20564 # var2->name = "var2" +20565 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +20566 (copy-array Heap "var2" %eax) +20567 $test-add-mem-to-reg:initialize-inouts: +20568 # var inouts/esi: (payload stmt-var) = [var2] +20569 68/push 0/imm32/is-deref:false +20570 68/push 0/imm32/next +20571 68/push 0/imm32/next +20572 52/push-edx/var2 +20573 68/push 0x11/imm32/alloc-id:fake +20574 68/push 0x11/imm32/alloc-id:fake:payload +20575 89/<- %esi 4/r32/esp +20576 $test-add-mem-to-reg:initialize-outputs: +20577 # var outputs/edi: (payload stmt-var) = [var1] +20578 68/push 0/imm32/is-deref:false +20579 68/push 0/imm32/next +20580 68/push 0/imm32/next +20581 51/push-ecx/var1 +20582 68/push 0x11/imm32/alloc-id:fake +20583 68/push 0x11/imm32/alloc-id:fake:payload +20584 89/<- %edi 4/r32/esp +20585 $test-add-mem-to-reg:initialize-stmt: +20586 # var stmt/esi: (addr statement) +20587 68/push 0/imm32/next +20588 68/push 0/imm32/next +20589 57/push-edi/outputs +20590 68/push 0x11/imm32/alloc-id:fake +20591 56/push-esi/inouts +20592 68/push 0x11/imm32/alloc-id:fake +20593 68/push 0/imm32/operation +20594 68/push 0/imm32/operation +20595 68/push 1/imm32/tag:stmt1 +20596 89/<- %esi 4/r32/esp +20597 $test-add-mem-to-reg:initialize-stmt-operation: +20598 # stmt->operation = "add" +20599 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +20600 (copy-array Heap "add" %eax) +20601 # convert +20602 c7 0/subop/copy *Curr-block-depth 0/imm32 +20603 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +20604 (flush _test-output-buffered-file) +20605 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +20611 # check output +20612 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") +20613 # . epilogue +20614 89/<- %esp 5/r32/ebp +20615 5d/pop-to-ebp +20616 c3/return +20617 +20618 test-add-literal-to-eax: +20619 # var1/eax <- add 0x34 +20620 # => +20621 # 05/add-to-eax 0x34/imm32 +20622 # +20623 # . prologue +20624 55/push-ebp +20625 89/<- %ebp 4/r32/esp +20626 # setup +20627 (clear-stream _test-output-stream) +20628 (clear-stream $_test-output-buffered-file->buffer) +20629 $test-add-literal-to-eax:initialize-var-type: +20630 # var type/ecx: (payload type-tree) = int +20631 68/push 0/imm32/right:null +20632 68/push 0/imm32/right:null +20633 68/push 0/imm32/left:unused +20634 68/push 1/imm32/value:int +20635 68/push 1/imm32/is-atom?:true +20636 68/push 0x11/imm32/alloc-id:fake:payload +20637 89/<- %ecx 4/r32/esp +20638 $test-add-literal-to-eax:initialize-var: +20639 # var v/ecx: (payload var) +20640 68/push 0/imm32/register +20641 68/push 0/imm32/register +20642 68/push 0/imm32/no-stack-offset +20643 68/push 1/imm32/block-depth +20644 51/push-ecx +20645 68/push 0x11/imm32/alloc-id:fake +20646 68/push 0/imm32/name +20647 68/push 0/imm32/name +20648 68/push 0x11/imm32/alloc-id:fake:payload +20649 89/<- %ecx 4/r32/esp +20650 $test-add-literal-to-eax:initialize-var-name: +20651 # v->name = "v" +20652 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +20653 (copy-array Heap "v" %eax) +20654 $test-add-literal-to-eax:initialize-var-register: +20655 # v->register = "eax" +20656 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +20657 (copy-array Heap "eax" %eax) +20658 $test-add-literal-to-eax:initialize-literal-type: +20659 # var type/edx: (payload type-tree) = literal +20660 68/push 0/imm32/right:null +20661 68/push 0/imm32/right:null +20662 68/push 0/imm32/left:unused +20663 68/push 0/imm32/value:literal +20664 68/push 1/imm32/is-atom?:true +20665 68/push 0x11/imm32/alloc-id:fake:payload +20666 89/<- %edx 4/r32/esp +20667 $test-add-literal-to-eax:initialize-literal: +20668 # var l/edx: (payload var) +20669 68/push 0/imm32/register +20670 68/push 0/imm32/register +20671 68/push 0/imm32/no-stack-offset +20672 68/push 1/imm32/block-depth +20673 52/push-edx +20674 68/push 0x11/imm32/alloc-id:fake +20675 68/push 0/imm32/name +20676 68/push 0/imm32/name +20677 68/push 0x11/imm32/alloc-id:fake:payload +20678 89/<- %edx 4/r32/esp +20679 $test-add-literal-to-eax:initialize-literal-value: +20680 # l->name = "0x34" +20681 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +20682 (copy-array Heap "0x34" %eax) +20683 $test-add-literal-to-eax:initialize-inouts: +20684 # var inouts/esi: (payload stmt-var) = [l] +20685 68/push 0/imm32/is-deref:false +20686 68/push 0/imm32/next +20687 68/push 0/imm32/next +20688 52/push-edx/l +20689 68/push 0x11/imm32/alloc-id:fake +20690 68/push 0x11/imm32/alloc-id:fake:payload +20691 89/<- %esi 4/r32/esp +20692 $test-add-literal-to-eax:initialize-outputs: +20693 # var outputs/edi: (payload stmt-var) = [v] +20694 68/push 0/imm32/is-deref:false +20695 68/push 0/imm32/next +20696 68/push 0/imm32/next +20697 51/push-ecx/v +20698 68/push 0x11/imm32/alloc-id:fake +20699 68/push 0x11/imm32/alloc-id:fake:payload +20700 89/<- %edi 4/r32/esp +20701 $test-add-literal-to-eax:initialize-stmt: +20702 # var stmt/esi: (addr statement) +20703 68/push 0/imm32/next +20704 68/push 0/imm32/next +20705 57/push-edi/outputs +20706 68/push 0x11/imm32/alloc-id:fake +20707 56/push-esi/inouts +20708 68/push 0x11/imm32/alloc-id:fake +20709 68/push 0/imm32/operation +20710 68/push 0/imm32/operation +20711 68/push 1/imm32/tag:stmt1 +20712 89/<- %esi 4/r32/esp +20713 $test-add-literal-to-eax:initialize-stmt-operation: +20714 # stmt->operation = "add" +20715 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +20716 (copy-array Heap "add" %eax) +20717 # convert +20718 c7 0/subop/copy *Curr-block-depth 0/imm32 +20719 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +20720 (flush _test-output-buffered-file) +20721 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +20727 # check output +20728 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") +20729 # . epilogue +20730 89/<- %esp 5/r32/ebp +20731 5d/pop-to-ebp +20732 c3/return +20733 +20734 test-add-literal-to-reg: +20735 # var1/ecx <- add 0x34 +20736 # => +20737 # 81 0/subop/add %ecx 0x34/imm32 +20738 # +20739 # . prologue +20740 55/push-ebp +20741 89/<- %ebp 4/r32/esp +20742 # setup +20743 (clear-stream _test-output-stream) +20744 (clear-stream $_test-output-buffered-file->buffer) +20745 $test-add-literal-to-reg:initialize-var-type: +20746 # var type/ecx: (payload type-tree) = int +20747 68/push 0/imm32/right:null +20748 68/push 0/imm32/right:null +20749 68/push 0/imm32/left:unused +20750 68/push 1/imm32/value:int +20751 68/push 1/imm32/is-atom?:true +20752 68/push 0x11/imm32/alloc-id:fake:payload +20753 89/<- %ecx 4/r32/esp +20754 $test-add-literal-to-reg:initialize-var: +20755 # var v/ecx: (payload var) +20756 68/push 0/imm32/register +20757 68/push 0/imm32/register +20758 68/push 0/imm32/no-stack-offset +20759 68/push 1/imm32/block-depth +20760 51/push-ecx +20761 68/push 0x11/imm32/alloc-id:fake +20762 68/push 0/imm32/name +20763 68/push 0/imm32/name +20764 68/push 0x11/imm32/alloc-id:fake:payload +20765 89/<- %ecx 4/r32/esp +20766 $test-add-literal-to-reg:initialize-var-name: +20767 # v->name = "v" +20768 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +20769 (copy-array Heap "v" %eax) +20770 $test-add-literal-to-reg:initialize-var-register: +20771 # v->register = "ecx" +20772 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +20773 (copy-array Heap "ecx" %eax) +20774 $test-add-literal-to-reg:initialize-literal-type: +20775 # var type/edx: (payload type-tree) = literal +20776 68/push 0/imm32/right:null +20777 68/push 0/imm32/right:null +20778 68/push 0/imm32/left:unused +20779 68/push 0/imm32/value:literal +20780 68/push 1/imm32/is-atom?:true +20781 68/push 0x11/imm32/alloc-id:fake:payload +20782 89/<- %edx 4/r32/esp +20783 $test-add-literal-to-reg:initialize-literal: +20784 # var l/edx: (payload var) +20785 68/push 0/imm32/register +20786 68/push 0/imm32/register +20787 68/push 0/imm32/no-stack-offset +20788 68/push 1/imm32/block-depth +20789 52/push-edx +20790 68/push 0x11/imm32/alloc-id:fake +20791 68/push 0/imm32/name +20792 68/push 0/imm32/name +20793 68/push 0x11/imm32/alloc-id:fake:payload +20794 89/<- %edx 4/r32/esp +20795 $test-add-literal-to-reg:initialize-literal-value: +20796 # l->name = "0x34" +20797 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +20798 (copy-array Heap "0x34" %eax) +20799 $test-add-literal-to-reg:initialize-inouts: +20800 # var inouts/esi: (payload stmt-var) = [l] +20801 68/push 0/imm32/is-deref:false +20802 68/push 0/imm32/next +20803 68/push 0/imm32/next +20804 52/push-edx/l +20805 68/push 0x11/imm32/alloc-id:fake +20806 68/push 0x11/imm32/alloc-id:fake:payload +20807 89/<- %esi 4/r32/esp +20808 $test-add-literal-to-reg:initialize-outputs: +20809 # var outputs/edi: (payload stmt-var) = [v] +20810 68/push 0/imm32/is-deref:false +20811 68/push 0/imm32/next +20812 68/push 0/imm32/next +20813 51/push-ecx/v +20814 68/push 0x11/imm32/alloc-id:fake +20815 68/push 0x11/imm32/alloc-id:fake:payload +20816 89/<- %edi 4/r32/esp +20817 $test-add-literal-to-reg:initialize-stmt: +20818 # var stmt/esi: (addr statement) +20819 68/push 0/imm32/next +20820 68/push 0/imm32/next +20821 57/push-edi/outputs +20822 68/push 0x11/imm32/alloc-id:fake +20823 56/push-esi/inouts +20824 68/push 0x11/imm32/alloc-id:fake +20825 68/push 0/imm32/operation +20826 68/push 0/imm32/operation +20827 68/push 1/imm32/tag:stmt1 +20828 89/<- %esi 4/r32/esp +20829 $test-add-literal-to-reg:initialize-stmt-operation: +20830 # stmt->operation = "add" +20831 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +20832 (copy-array Heap "add" %eax) +20833 # convert +20834 c7 0/subop/copy *Curr-block-depth 0/imm32 +20835 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +20836 (flush _test-output-buffered-file) +20837 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +20843 # check output +20844 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") +20845 # . epilogue +20846 89/<- %esp 5/r32/ebp +20847 5d/pop-to-ebp +20848 c3/return +20849 +20850 test-add-literal-to-mem: +20851 # add-to var1, 0x34 +20852 # => +20853 # 81 0/subop/add %eax 0x34/imm32 +20854 # +20855 # . prologue +20856 55/push-ebp +20857 89/<- %ebp 4/r32/esp +20858 # setup +20859 (clear-stream _test-output-stream) +20860 (clear-stream $_test-output-buffered-file->buffer) +20861 $test-add-literal-to-mem:initialize-type: +20862 # var type/ecx: (payload type-tree) = int +20863 68/push 0/imm32/right:null +20864 68/push 0/imm32/right:null +20865 68/push 0/imm32/left:unused +20866 68/push 1/imm32/value:int +20867 68/push 1/imm32/is-atom?:true +20868 68/push 0x11/imm32/alloc-id:fake:payload +20869 89/<- %ecx 4/r32/esp +20870 $test-add-literal-to-mem:initialize-var1: +20871 # var var1/ecx: (payload var) +20872 68/push 0/imm32/register +20873 68/push 0/imm32/register +20874 68/push 8/imm32/stack-offset +20875 68/push 1/imm32/block-depth +20876 51/push-ecx +20877 68/push 0x11/imm32/alloc-id:fake +20878 68/push 0/imm32/name +20879 68/push 0/imm32/name +20880 68/push 0x11/imm32/alloc-id:fake:payload +20881 89/<- %ecx 4/r32/esp +20882 $test-add-literal-to-mem:initialize-var1-name: +20883 # var1->name = "var1" +20884 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +20885 (copy-array Heap "var1" %eax) +20886 $test-add-literal-to-mem:initialize-literal-type: +20887 # var type/edx: (payload type-tree) = literal +20888 68/push 0/imm32/right:null +20889 68/push 0/imm32/right:null +20890 68/push 0/imm32/left:unused +20891 68/push 0/imm32/value:literal +20892 68/push 1/imm32/is-atom?:true +20893 68/push 0x11/imm32/alloc-id:fake:payload +20894 89/<- %edx 4/r32/esp +20895 $test-add-literal-to-mem:initialize-literal: +20896 # var l/edx: (payload var) +20897 68/push 0/imm32/register +20898 68/push 0/imm32/register +20899 68/push 0/imm32/no-stack-offset +20900 68/push 1/imm32/block-depth +20901 52/push-edx +20902 68/push 0x11/imm32/alloc-id:fake +20903 68/push 0/imm32/name +20904 68/push 0/imm32/name +20905 68/push 0x11/imm32/alloc-id:fake:payload +20906 89/<- %edx 4/r32/esp +20907 $test-add-literal-to-mem:initialize-literal-value: +20908 # l->name = "0x34" +20909 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +20910 (copy-array Heap "0x34" %eax) +20911 $test-add-literal-to-mem:initialize-inouts: +20912 # var inouts/esi: (payload stmt-var) = [l] +20913 68/push 0/imm32/is-deref:false +20914 68/push 0/imm32/next +20915 68/push 0/imm32/next +20916 52/push-edx/l +20917 68/push 0x11/imm32/alloc-id:fake +20918 68/push 0x11/imm32/alloc-id:fake:payload +20919 89/<- %esi 4/r32/esp +20920 # var inouts = (handle stmt-var) = [var1, var2] +20921 68/push 0/imm32/is-deref:false +20922 56/push-esi/next +20923 68/push 0x11/imm32/alloc-id:fake +20924 51/push-ecx/var1 +20925 68/push 0x11/imm32/alloc-id:fake +20926 68/push 0x11/imm32/alloc-id:fake:payload +20927 89/<- %esi 4/r32/esp +20928 $test-add-literal-to-mem:initialize-stmt: +20929 # var stmt/esi: (addr statement) +20930 68/push 0/imm32/next +20931 68/push 0/imm32/next +20932 68/push 0/imm32/outputs +20933 68/push 0/imm32/outputs +20934 56/push-esi/inouts +20935 68/push 0x11/imm32/alloc-id:fake +20936 68/push 0/imm32/operation +20937 68/push 0/imm32/operation +20938 68/push 1/imm32/tag:stmt1 +20939 89/<- %esi 4/r32/esp +20940 $test-add-literal-to-mem:initialize-stmt-operation: +20941 # stmt->operation = "add-to" +20942 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +20943 (copy-array Heap "add-to" %eax) +20944 # convert +20945 c7 0/subop/copy *Curr-block-depth 0/imm32 +20946 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +20947 (flush _test-output-buffered-file) +20948 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +20954 # check output +20955 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") +20956 # . epilogue +20957 89/<- %esp 5/r32/ebp +20958 5d/pop-to-ebp +20959 c3/return +20960 +20961 test-shift-reg-by-literal: +20962 # var1/ecx <- shift-left 2 +20963 # => +20964 # c1/shift 4/subop/left %ecx 2/imm8 +20965 # +20966 # . prologue +20967 55/push-ebp +20968 89/<- %ebp 4/r32/esp +20969 # setup +20970 (clear-stream _test-output-stream) +20971 (clear-stream $_test-output-buffered-file->buffer) +20972 $test-shift-reg-by-literal:initialize-var-type: +20973 # var type/ecx: (payload type-tree) = int +20974 68/push 0/imm32/right:null +20975 68/push 0/imm32/right:null +20976 68/push 0/imm32/left:unused +20977 68/push 1/imm32/value:int +20978 68/push 1/imm32/is-atom?:true +20979 68/push 0x11/imm32/alloc-id:fake:payload +20980 89/<- %ecx 4/r32/esp +20981 $test-shift-reg-by-literal:initialize-var: +20982 # var v/ecx: (payload var) +20983 68/push 0/imm32/register +20984 68/push 0/imm32/register +20985 68/push 0/imm32/no-stack-offset +20986 68/push 1/imm32/block-depth +20987 51/push-ecx +20988 68/push 0x11/imm32/alloc-id:fake +20989 68/push 0/imm32/name +20990 68/push 0/imm32/name +20991 68/push 0x11/imm32/alloc-id:fake:payload +20992 89/<- %ecx 4/r32/esp +20993 $test-shift-reg-by-literal:initialize-var-name: +20994 # v->name = "v" +20995 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +20996 (copy-array Heap "v" %eax) +20997 $test-shift-reg-by-literal:initialize-var-register: +20998 # v->register = "ecx" +20999 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +21000 (copy-array Heap "ecx" %eax) +21001 $test-shift-reg-by-literal:initialize-literal-type: +21002 # var type/edx: (payload type-tree) = literal +21003 68/push 0/imm32/right:null +21004 68/push 0/imm32/right:null +21005 68/push 0/imm32/left:unused +21006 68/push 0/imm32/value:literal +21007 68/push 1/imm32/is-atom?:true +21008 68/push 0x11/imm32/alloc-id:fake:payload +21009 89/<- %edx 4/r32/esp +21010 $test-shift-reg-by-literal:initialize-literal: +21011 # var l/edx: (payload var) +21012 68/push 0/imm32/register +21013 68/push 0/imm32/register +21014 68/push 0/imm32/no-stack-offset +21015 68/push 1/imm32/block-depth +21016 52/push-edx +21017 68/push 0x11/imm32/alloc-id:fake +21018 68/push 0/imm32/name +21019 68/push 0/imm32/name +21020 68/push 0x11/imm32/alloc-id:fake:payload +21021 89/<- %edx 4/r32/esp +21022 $test-shift-reg-by-literal:initialize-literal-value: +21023 # l->name = "2" +21024 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +21025 (copy-array Heap "2" %eax) +21026 $test-shift-reg-by-literal:initialize-inouts: +21027 # var inouts/esi: (payload stmt-var) = [l] +21028 68/push 0/imm32/is-deref:false +21029 68/push 0/imm32/next +21030 68/push 0/imm32/next +21031 52/push-edx/l +21032 68/push 0x11/imm32/alloc-id:fake +21033 68/push 0x11/imm32/alloc-id:fake:payload +21034 89/<- %esi 4/r32/esp +21035 $test-shift-reg-by-literal:initialize-outputs: +21036 # var outputs/edi: (payload stmt-var) = [v] +21037 68/push 0/imm32/is-deref:false +21038 68/push 0/imm32/next +21039 68/push 0/imm32/next +21040 51/push-ecx/v +21041 68/push 0x11/imm32/alloc-id:fake +21042 68/push 0x11/imm32/alloc-id:fake:payload +21043 89/<- %edi 4/r32/esp +21044 $test-shift-reg-by-literal:initialize-stmt: +21045 # var stmt/esi: (addr statement) +21046 68/push 0/imm32/next +21047 68/push 0/imm32/next +21048 57/push-edi/outputs +21049 68/push 0x11/imm32/alloc-id:fake +21050 56/push-esi/inouts +21051 68/push 0x11/imm32/alloc-id:fake +21052 68/push 0/imm32/operation +21053 68/push 0/imm32/operation +21054 68/push 1/imm32/tag:stmt1 +21055 89/<- %esi 4/r32/esp +21056 $test-shift-reg-by-literal:initialize-stmt-operation: +21057 # stmt->operation = "shift-left" +21058 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21059 (copy-array Heap "shift-left" %eax) +21060 # convert +21061 c7 0/subop/copy *Curr-block-depth 0/imm32 +21062 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +21063 (flush _test-output-buffered-file) +21064 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +21070 # check output +21071 (check-next-stream-line-equal _test-output-stream "c1/shift 4/subop/left %ecx 2/imm8" "F - test-shift-reg-by-literal") +21072 # . epilogue +21073 89/<- %esp 5/r32/ebp +21074 5d/pop-to-ebp +21075 c3/return +21076 +21077 test-shift-mem-by-literal: +21078 # shift-left var 3 +21079 # => +21080 # c1/shift 4/subop/left *(ebp+8) 3/imm8 +21081 # +21082 # . prologue +21083 55/push-ebp +21084 89/<- %ebp 4/r32/esp +21085 # setup +21086 (clear-stream _test-output-stream) +21087 (clear-stream $_test-output-buffered-file->buffer) +21088 $test-shift-mem-by-literal:initialize-type: +21089 # var type/ecx: (payload type-tree) = int +21090 68/push 0/imm32/right:null +21091 68/push 0/imm32/right:null +21092 68/push 0/imm32/left:unused +21093 68/push 1/imm32/value:int +21094 68/push 1/imm32/is-atom?:true +21095 68/push 0x11/imm32/alloc-id:fake:payload +21096 89/<- %ecx 4/r32/esp +21097 $test-shift-mem-by-literal:initialize-var1: +21098 # var var1/ecx: (payload var) +21099 68/push 0/imm32/register +21100 68/push 0/imm32/register +21101 68/push 8/imm32/stack-offset +21102 68/push 1/imm32/block-depth +21103 51/push-ecx +21104 68/push 0x11/imm32/alloc-id:fake +21105 68/push 0/imm32/name +21106 68/push 0/imm32/name +21107 68/push 0x11/imm32/alloc-id:fake:payload +21108 89/<- %ecx 4/r32/esp +21109 $test-shift-mem-by-literal:initialize-var1-name: +21110 # var1->name = "var1" +21111 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21112 (copy-array Heap "var1" %eax) +21113 $test-shift-mem-by-literal:initialize-literal-type: +21114 # var type/edx: (payload type-tree) = literal +21115 68/push 0/imm32/right:null +21116 68/push 0/imm32/right:null +21117 68/push 0/imm32/left:unused +21118 68/push 0/imm32/value:literal +21119 68/push 1/imm32/is-atom?:true +21120 68/push 0x11/imm32/alloc-id:fake:payload +21121 89/<- %edx 4/r32/esp +21122 $test-shift-mem-by-literal:initialize-literal: +21123 # var l/edx: (payload var) +21124 68/push 0/imm32/register +21125 68/push 0/imm32/register +21126 68/push 0/imm32/no-stack-offset +21127 68/push 1/imm32/block-depth +21128 52/push-edx +21129 68/push 0x11/imm32/alloc-id:fake +21130 68/push 0/imm32/name +21131 68/push 0/imm32/name +21132 68/push 0x11/imm32/alloc-id:fake:payload +21133 89/<- %edx 4/r32/esp +21134 $test-shift-mem-by-literal:initialize-literal-value: +21135 # l->name = "3" +21136 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +21137 (copy-array Heap "3" %eax) +21138 $test-shift-mem-by-literal:initialize-inouts: +21139 # var inouts/esi: (payload stmt-var) = [l] +21140 68/push 0/imm32/is-deref:false +21141 68/push 0/imm32/next +21142 68/push 0/imm32/next +21143 52/push-edx/l +21144 68/push 0x11/imm32/alloc-id:fake +21145 68/push 0x11/imm32/alloc-id:fake:payload +21146 89/<- %esi 4/r32/esp +21147 # var inouts = (handle stmt-var) = [var1, var2] +21148 68/push 0/imm32/is-deref:false +21149 56/push-esi/next +21150 68/push 0x11/imm32/alloc-id:fake +21151 51/push-ecx/var1 +21152 68/push 0x11/imm32/alloc-id:fake +21153 68/push 0x11/imm32/alloc-id:fake:payload +21154 89/<- %esi 4/r32/esp +21155 $test-shift-mem-by-literal:initialize-stmt: +21156 # var stmt/esi: (addr statement) +21157 68/push 0/imm32/next +21158 68/push 0/imm32/next +21159 68/push 0/imm32/outputs +21160 68/push 0/imm32/outputs +21161 56/push-esi/inouts +21162 68/push 0x11/imm32/alloc-id:fake +21163 68/push 0/imm32/operation +21164 68/push 0/imm32/operation +21165 68/push 1/imm32/tag:stmt1 +21166 89/<- %esi 4/r32/esp +21167 $test-shift-mem-by-literal:initialize-stmt-operation: +21168 # stmt->operation = "shift-left" +21169 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21170 (copy-array Heap "shift-left" %eax) +21171 # convert +21172 c7 0/subop/copy *Curr-block-depth 0/imm32 +21173 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +21174 (flush _test-output-buffered-file) +21175 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +21181 # check output +21182 (check-next-stream-line-equal _test-output-stream "c1/shift 4/subop/left *(ebp+0x00000008) 3/imm8" "F - test-shift-mem-by-literal") +21183 # . epilogue +21184 89/<- %esp 5/r32/ebp +21185 5d/pop-to-ebp +21186 c3/return +21187 +21188 test-compare-reg-with-reg: +21189 # compare var1/ecx, var2/eax +21190 # => +21191 # 39/compare %ecx 0/r32/eax +21192 # +21193 # . prologue +21194 55/push-ebp +21195 89/<- %ebp 4/r32/esp +21196 # setup +21197 (clear-stream _test-output-stream) +21198 (clear-stream $_test-output-buffered-file->buffer) +21199 $test-compare-reg-with-reg:initialize-type: +21200 # var type/ecx: (payload type-tree) = int +21201 68/push 0/imm32/right:null +21202 68/push 0/imm32/right:null +21203 68/push 0/imm32/left:unused +21204 68/push 1/imm32/value:int +21205 68/push 1/imm32/is-atom?:true +21206 68/push 0x11/imm32/alloc-id:fake:payload +21207 89/<- %ecx 4/r32/esp +21208 $test-compare-reg-with-reg:initialize-var1: +21209 # var var1/ecx: (payload var) +21210 68/push 0/imm32/register +21211 68/push 0/imm32/register +21212 68/push 0/imm32/no-stack-offset +21213 68/push 1/imm32/block-depth +21214 51/push-ecx +21215 68/push 0x11/imm32/alloc-id:fake +21216 68/push 0/imm32/name +21217 68/push 0/imm32/name +21218 68/push 0x11/imm32/alloc-id:fake:payload +21219 89/<- %ecx 4/r32/esp +21220 $test-compare-reg-with-reg:initialize-var1-name: +21221 # var1->name = "var1" +21222 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21223 (copy-array Heap "var1" %eax) +21224 $test-compare-reg-with-reg:initialize-var1-register: +21225 # var1->register = "ecx" +21226 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +21227 (copy-array Heap "ecx" %eax) +21228 $test-compare-reg-with-reg:initialize-var2: +21229 # var var2/edx: (payload var) +21230 68/push 0/imm32/register +21231 68/push 0/imm32/register +21232 68/push 0/imm32/no-stack-offset +21233 68/push 1/imm32/block-depth +21234 ff 6/subop/push *(ecx+0x10) +21235 68/push 0x11/imm32/alloc-id:fake +21236 68/push 0/imm32/name +21237 68/push 0/imm32/name +21238 68/push 0x11/imm32/alloc-id:fake:payload +21239 89/<- %edx 4/r32/esp +21240 $test-compare-reg-with-reg:initialize-var2-name: +21241 # var2->name = "var2" +21242 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +21243 (copy-array Heap "var2" %eax) +21244 $test-compare-reg-with-reg:initialize-var2-register: +21245 # var2->register = "eax" +21246 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +21247 (copy-array Heap "eax" %eax) +21248 $test-compare-reg-with-reg:initialize-inouts: +21249 # var inouts/esi: (payload stmt-var) = [var2] +21250 68/push 0/imm32/is-deref:false +21251 68/push 0/imm32/next +21252 68/push 0/imm32/next +21253 52/push-edx/var2 +21254 68/push 0x11/imm32/alloc-id:fake +21255 68/push 0x11/imm32/alloc-id:fake:payload +21256 89/<- %esi 4/r32/esp +21257 # inouts = [var1, var2] +21258 68/push 0/imm32/is-deref:false +21259 56/push-esi/next +21260 68/push 0x11/imm32/alloc-id:fake +21261 51/push-ecx/var1 +21262 68/push 0x11/imm32/alloc-id:fake +21263 68/push 0x11/imm32/alloc-id:fake:payload +21264 89/<- %esi 4/r32/esp +21265 $test-compare-reg-with-reg:initialize-stmt: +21266 # var stmt/esi: (addr statement) +21267 68/push 0/imm32/next +21268 68/push 0/imm32/next +21269 68/push 0/imm32/outputs +21270 68/push 0/imm32/outputs +21271 56/push-esi/inouts +21272 68/push 0x11/imm32/alloc-id:fake +21273 68/push 0/imm32/operation +21274 68/push 0/imm32/operation +21275 68/push 1/imm32/tag:stmt1 +21276 89/<- %esi 4/r32/esp +21277 $test-compare-reg-with-reg:initialize-stmt-operation: +21278 # stmt->operation = "compare" +21279 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21280 (copy-array Heap "compare" %eax) +21281 # convert +21282 c7 0/subop/copy *Curr-block-depth 0/imm32 +21283 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +21284 (flush _test-output-buffered-file) +21285 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +21291 # check output +21292 (check-next-stream-line-equal _test-output-stream "39/compare-> %ecx 0x00000000/r32" "F - test-compare-reg-with-reg") +21293 # . epilogue +21294 89/<- %esp 5/r32/ebp +21295 5d/pop-to-ebp +21296 c3/return +21297 +21298 test-compare-mem-with-reg: +21299 # compare var1, var2/eax +21300 # => +21301 # 39/compare *(ebp+___) 0/r32/eax +21302 # +21303 # . prologue +21304 55/push-ebp +21305 89/<- %ebp 4/r32/esp +21306 # setup +21307 (clear-stream _test-output-stream) +21308 (clear-stream $_test-output-buffered-file->buffer) +21309 $test-compare-mem-with-reg:initialize-type: +21310 # var type/ecx: (payload type-tree) = int +21311 68/push 0/imm32/right:null +21312 68/push 0/imm32/right:null +21313 68/push 0/imm32/left:unused +21314 68/push 1/imm32/value:int +21315 68/push 1/imm32/is-atom?:true +21316 68/push 0x11/imm32/alloc-id:fake:payload +21317 89/<- %ecx 4/r32/esp +21318 $test-compare-mem-with-reg:initialize-var1: +21319 # var var1/ecx: (payload var) +21320 68/push 0/imm32/register +21321 68/push 0/imm32/register +21322 68/push 8/imm32/stack-offset +21323 68/push 1/imm32/block-depth +21324 51/push-ecx +21325 68/push 0x11/imm32/alloc-id:fake +21326 68/push 0/imm32/name +21327 68/push 0/imm32/name +21328 68/push 0x11/imm32/alloc-id:fake:payload +21329 89/<- %ecx 4/r32/esp +21330 $test-compare-mem-with-reg:initialize-var1-name: +21331 # var1->name = "var1" +21332 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21333 (copy-array Heap "var1" %eax) +21334 $test-compare-mem-with-reg:initialize-var2: +21335 # var var2/edx: (payload var) +21336 68/push 0/imm32/register +21337 68/push 0/imm32/register +21338 68/push 0/imm32/no-stack-offset +21339 68/push 1/imm32/block-depth +21340 ff 6/subop/push *(ecx+0x10) +21341 68/push 0x11/imm32/alloc-id:fake +21342 68/push 0/imm32/name +21343 68/push 0/imm32/name +21344 68/push 0x11/imm32/alloc-id:fake:payload +21345 89/<- %edx 4/r32/esp +21346 $test-compare-mem-with-reg:initialize-var2-name: +21347 # var2->name = "var2" +21348 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +21349 (copy-array Heap "var2" %eax) +21350 $test-compare-mem-with-reg:initialize-var2-register: +21351 # var2->register = "eax" +21352 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +21353 (copy-array Heap "eax" %eax) +21354 $test-compare-mem-with-reg:initialize-inouts: +21355 # var inouts/esi: (payload stmt-var) = [var2] +21356 68/push 0/imm32/is-deref:false +21357 68/push 0/imm32/next +21358 68/push 0/imm32/next +21359 52/push-edx/var2 +21360 68/push 0x11/imm32/alloc-id:fake +21361 68/push 0x11/imm32/alloc-id:fake:payload +21362 89/<- %esi 4/r32/esp +21363 # inouts = [var1, var2] +21364 68/push 0/imm32/is-deref:false +21365 56/push-esi/next +21366 68/push 0x11/imm32/alloc-id:fake +21367 51/push-ecx/var1 +21368 68/push 0x11/imm32/alloc-id:fake +21369 68/push 0x11/imm32/alloc-id:fake:payload +21370 89/<- %esi 4/r32/esp +21371 $test-compare-mem-with-reg:initialize-stmt: +21372 # var stmt/esi: (addr statement) +21373 68/push 0/imm32/next +21374 68/push 0/imm32/next +21375 68/push 0/imm32/outputs +21376 68/push 0/imm32/outputs +21377 56/push-esi/inouts +21378 68/push 0x11/imm32/alloc-id:fake +21379 68/push 0/imm32/operation +21380 68/push 0/imm32/operation +21381 68/push 1/imm32/tag:stmt1 +21382 89/<- %esi 4/r32/esp +21383 $test-compare-mem-with-reg:initialize-stmt-operation: +21384 # stmt->operation = "compare" +21385 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21386 (copy-array Heap "compare" %eax) +21387 # convert +21388 c7 0/subop/copy *Curr-block-depth 0/imm32 +21389 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +21390 (flush _test-output-buffered-file) +21391 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +21397 # check output +21398 (check-next-stream-line-equal _test-output-stream "39/compare-> *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg") +21399 # . epilogue +21400 89/<- %esp 5/r32/ebp +21401 5d/pop-to-ebp +21402 c3/return +21403 +21404 test-compare-reg-with-mem: +21405 # compare var1/eax, var2 +21406 # => +21407 # 3b/compare<- *(ebp+___) 0/r32/eax +21408 # +21409 # . prologue +21410 55/push-ebp +21411 89/<- %ebp 4/r32/esp +21412 # setup +21413 (clear-stream _test-output-stream) +21414 (clear-stream $_test-output-buffered-file->buffer) +21415 $test-compare-reg-with-mem:initialize-type: +21416 # var type/ecx: (payload type-tree) = int +21417 68/push 0/imm32/right:null +21418 68/push 0/imm32/right:null +21419 68/push 0/imm32/left:unused +21420 68/push 1/imm32/value:int +21421 68/push 1/imm32/is-atom?:true +21422 68/push 0x11/imm32/alloc-id:fake:payload +21423 89/<- %ecx 4/r32/esp +21424 $test-compare-reg-with-mem:initialize-var1: +21425 # var var1/ecx: (payload var) +21426 68/push 0/imm32/register +21427 68/push 0/imm32/register +21428 68/push 0/imm32/no-stack-offset +21429 68/push 1/imm32/block-depth +21430 51/push-ecx +21431 68/push 0x11/imm32/alloc-id:fake +21432 68/push 0/imm32/name +21433 68/push 0/imm32/name +21434 68/push 0x11/imm32/alloc-id:fake:payload +21435 89/<- %ecx 4/r32/esp +21436 $test-compare-reg-with-mem:initialize-var1-name: +21437 # var1->name = "var1" +21438 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21439 (copy-array Heap "var1" %eax) +21440 $test-compare-reg-with-mem:initialize-var1-register: +21441 # var1->register = "eax" +21442 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +21443 (copy-array Heap "eax" %eax) +21444 $test-compare-reg-with-mem:initialize-var2: +21445 # var var2/edx: (payload var) +21446 68/push 0/imm32/register +21447 68/push 0/imm32/register +21448 68/push 8/imm32/stack-offset +21449 68/push 1/imm32/block-depth +21450 ff 6/subop/push *(ecx+0x10) +21451 68/push 0x11/imm32/alloc-id:fake +21452 68/push 0/imm32/name +21453 68/push 0/imm32/name +21454 68/push 0x11/imm32/alloc-id:fake:payload +21455 89/<- %edx 4/r32/esp +21456 $test-compare-reg-with-mem:initialize-var2-name: +21457 # var2->name = "var2" +21458 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +21459 (copy-array Heap "var2" %eax) +21460 $test-compare-reg-with-mem:initialize-inouts: +21461 # var inouts/esi: (payload stmt-var) = [var2] +21462 68/push 0/imm32/is-deref:false +21463 68/push 0/imm32/next +21464 68/push 0/imm32/next +21465 52/push-edx/var2 +21466 68/push 0x11/imm32/alloc-id:fake +21467 68/push 0x11/imm32/alloc-id:fake:payload +21468 89/<- %esi 4/r32/esp +21469 # inouts = [var1, var2] +21470 68/push 0/imm32/is-deref:false +21471 56/push-esi/next +21472 68/push 0x11/imm32/alloc-id:fake +21473 51/push-ecx/var1 +21474 68/push 0x11/imm32/alloc-id:fake +21475 68/push 0x11/imm32/alloc-id:fake:payload +21476 89/<- %esi 4/r32/esp +21477 $test-compare-reg-with-mem:initialize-stmt: +21478 # var stmt/esi: (addr statement) +21479 68/push 0/imm32/next +21480 68/push 0/imm32/next +21481 68/push 0/imm32/outputs +21482 68/push 0/imm32/outputs +21483 56/push-esi/inouts +21484 68/push 0x11/imm32/alloc-id:fake +21485 68/push 0/imm32/operation +21486 68/push 0/imm32/operation +21487 68/push 1/imm32/tag:stmt1 +21488 89/<- %esi 4/r32/esp +21489 $test-compare-reg-with-mem:initialize-stmt-operation: +21490 # stmt->operation = "compare" +21491 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21492 (copy-array Heap "compare" %eax) +21493 # convert +21494 c7 0/subop/copy *Curr-block-depth 0/imm32 +21495 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +21496 (flush _test-output-buffered-file) +21497 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +21503 # check output +21504 (check-next-stream-line-equal _test-output-stream "3b/compare<- *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem") +21505 # . epilogue +21506 89/<- %esp 5/r32/ebp +21507 5d/pop-to-ebp +21508 c3/return +21509 +21510 test-compare-mem-with-literal: +21511 # compare var1, 0x34 +21512 # => +21513 # 81 7/subop/compare *(ebp+___) 0x34/imm32 +21514 # +21515 # . prologue +21516 55/push-ebp +21517 89/<- %ebp 4/r32/esp +21518 # setup +21519 (clear-stream _test-output-stream) +21520 (clear-stream $_test-output-buffered-file->buffer) +21521 $test-compare-mem-with-literal:initialize-type: +21522 # var type/ecx: (payload type-tree) = int +21523 68/push 0/imm32/right:null +21524 68/push 0/imm32/right:null +21525 68/push 0/imm32/left:unused +21526 68/push 1/imm32/value:int +21527 68/push 1/imm32/is-atom?:true +21528 68/push 0x11/imm32/alloc-id:fake:payload +21529 89/<- %ecx 4/r32/esp +21530 $test-compare-mem-with-literal:initialize-var1: +21531 # var var1/ecx: (payload var) +21532 68/push 0/imm32/register +21533 68/push 0/imm32/register +21534 68/push 8/imm32/stack-offset +21535 68/push 1/imm32/block-depth +21536 51/push-ecx +21537 68/push 0x11/imm32/alloc-id:fake +21538 68/push 0/imm32/name +21539 68/push 0/imm32/name +21540 68/push 0x11/imm32/alloc-id:fake:payload +21541 89/<- %ecx 4/r32/esp +21542 $test-compare-mem-with-literal:initialize-var1-name: +21543 # var1->name = "var1" +21544 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21545 (copy-array Heap "var1" %eax) +21546 $test-compare-mem-with-literal:initialize-literal-type: +21547 # var type/edx: (payload type-tree) = literal +21548 68/push 0/imm32/right:null +21549 68/push 0/imm32/right:null +21550 68/push 0/imm32/left:unused +21551 68/push 0/imm32/value:literal +21552 68/push 1/imm32/is-atom?:true +21553 68/push 0x11/imm32/alloc-id:fake:payload +21554 89/<- %edx 4/r32/esp +21555 $test-compare-mem-with-literal:initialize-literal: +21556 # var l/edx: (payload var) +21557 68/push 0/imm32/register +21558 68/push 0/imm32/register +21559 68/push 0/imm32/no-stack-offset +21560 68/push 1/imm32/block-depth +21561 52/push-edx +21562 68/push 0x11/imm32/alloc-id:fake +21563 68/push 0/imm32/name +21564 68/push 0/imm32/name +21565 68/push 0x11/imm32/alloc-id:fake:payload +21566 89/<- %edx 4/r32/esp +21567 $test-compare-mem-with-literal:initialize-literal-value: +21568 # l->name = "0x34" +21569 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +21570 (copy-array Heap "0x34" %eax) +21571 $test-compare-mem-with-literal:initialize-inouts: +21572 # var inouts/esi: (payload stmt-var) = [l] +21573 68/push 0/imm32/is-deref:false +21574 68/push 0/imm32/next +21575 68/push 0/imm32/next +21576 52/push-edx/l +21577 68/push 0x11/imm32/alloc-id:fake +21578 68/push 0x11/imm32/alloc-id:fake:payload +21579 89/<- %esi 4/r32/esp +21580 # var inouts = (handle stmt-var) = [var1, var2] +21581 68/push 0/imm32/is-deref:false +21582 56/push-esi/next +21583 68/push 0x11/imm32/alloc-id:fake +21584 51/push-ecx/var1 +21585 68/push 0x11/imm32/alloc-id:fake +21586 68/push 0x11/imm32/alloc-id:fake:payload +21587 89/<- %esi 4/r32/esp +21588 $test-compare-mem-with-literal:initialize-stmt: +21589 # var stmt/esi: (addr statement) +21590 68/push 0/imm32/next +21591 68/push 0/imm32/next +21592 68/push 0/imm32/outputs +21593 68/push 0/imm32/outputs +21594 56/push-esi/inouts +21595 68/push 0x11/imm32/alloc-id:fake +21596 68/push 0/imm32/operation +21597 68/push 0/imm32/operation +21598 68/push 1/imm32/tag:stmt1 +21599 89/<- %esi 4/r32/esp +21600 $test-compare-mem-with-literal:initialize-stmt-operation: +21601 # stmt->operation = "compare" +21602 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21603 (copy-array Heap "compare" %eax) +21604 # convert +21605 c7 0/subop/copy *Curr-block-depth 0/imm32 +21606 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +21607 (flush _test-output-buffered-file) +21608 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +21614 # check output +21615 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal") +21616 # . epilogue +21617 89/<- %esp 5/r32/ebp +21618 5d/pop-to-ebp +21619 c3/return +21620 +21621 test-compare-eax-with-literal: +21622 # compare var1/eax 0x34 +21623 # => +21624 # 3d/compare-eax-with 0x34/imm32 +21625 # +21626 # . prologue +21627 55/push-ebp +21628 89/<- %ebp 4/r32/esp +21629 # setup +21630 (clear-stream _test-output-stream) +21631 (clear-stream $_test-output-buffered-file->buffer) +21632 $test-compare-eax-with-literal:initialize-type: +21633 # var type/ecx: (payload type-tree) = int +21634 68/push 0/imm32/right:null +21635 68/push 0/imm32/right:null +21636 68/push 0/imm32/left:unused +21637 68/push 1/imm32/value:int +21638 68/push 1/imm32/is-atom?:true +21639 68/push 0x11/imm32/alloc-id:fake:payload +21640 89/<- %ecx 4/r32/esp +21641 $test-compare-eax-with-literal:initialize-var1: +21642 # var var1/ecx: (payload var) +21643 68/push 0/imm32/register +21644 68/push 0/imm32/register +21645 68/push 0/imm32/no-stack-offset +21646 68/push 1/imm32/block-depth +21647 51/push-ecx +21648 68/push 0x11/imm32/alloc-id:fake +21649 68/push 0/imm32/name +21650 68/push 0/imm32/name +21651 68/push 0x11/imm32/alloc-id:fake:payload +21652 89/<- %ecx 4/r32/esp +21653 $test-compare-eax-with-literal:initialize-var1-name: +21654 # var1->name = "var1" +21655 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21656 (copy-array Heap "var1" %eax) +21657 $test-compare-eax-with-literal:initialize-var1-register: +21658 # v->register = "eax" +21659 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +21660 (copy-array Heap "eax" %eax) +21661 $test-compare-eax-with-literal:initialize-literal-type: +21662 # var type/edx: (payload type-tree) = literal +21663 68/push 0/imm32/right:null +21664 68/push 0/imm32/right:null +21665 68/push 0/imm32/left:unused +21666 68/push 0/imm32/value:literal +21667 68/push 1/imm32/is-atom?:true +21668 68/push 0x11/imm32/alloc-id:fake:payload +21669 89/<- %edx 4/r32/esp +21670 $test-compare-eax-with-literal:initialize-literal: +21671 # var l/edx: (payload var) +21672 68/push 0/imm32/register +21673 68/push 0/imm32/register +21674 68/push 0/imm32/no-stack-offset +21675 68/push 1/imm32/block-depth +21676 52/push-edx +21677 68/push 0x11/imm32/alloc-id:fake +21678 68/push 0/imm32/name +21679 68/push 0/imm32/name +21680 68/push 0x11/imm32/alloc-id:fake:payload +21681 89/<- %edx 4/r32/esp +21682 $test-compare-eax-with-literal:initialize-literal-value: +21683 # l->name = "0x34" +21684 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +21685 (copy-array Heap "0x34" %eax) +21686 $test-compare-eax-with-literal:initialize-inouts: +21687 # var inouts/esi: (payload stmt-var) = [l] +21688 68/push 0/imm32/is-deref:false +21689 68/push 0/imm32/next +21690 68/push 0/imm32/next +21691 52/push-edx/l +21692 68/push 0x11/imm32/alloc-id:fake +21693 68/push 0x11/imm32/alloc-id:fake:payload +21694 89/<- %esi 4/r32/esp +21695 # var inouts = (handle stmt-var) = [var1, var2] +21696 68/push 0/imm32/is-deref:false +21697 56/push-esi/next +21698 68/push 0x11/imm32/alloc-id:fake +21699 51/push-ecx/var1 +21700 68/push 0x11/imm32/alloc-id:fake +21701 68/push 0x11/imm32/alloc-id:fake:payload +21702 89/<- %esi 4/r32/esp +21703 $test-compare-eax-with-literal:initialize-stmt: +21704 # var stmt/esi: (addr statement) +21705 68/push 0/imm32/next +21706 68/push 0/imm32/next +21707 68/push 0/imm32/outputs +21708 68/push 0/imm32/outputs +21709 56/push-esi/inouts +21710 68/push 0x11/imm32/alloc-id:fake +21711 68/push 0/imm32/operation +21712 68/push 0/imm32/operation +21713 68/push 1/imm32/tag:stmt1 +21714 89/<- %esi 4/r32/esp +21715 $test-compare-eax-with-literal:initialize-stmt-operation: +21716 # stmt->operation = "compare" +21717 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21718 (copy-array Heap "compare" %eax) +21719 # convert +21720 c7 0/subop/copy *Curr-block-depth 0/imm32 +21721 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +21722 (flush _test-output-buffered-file) +21723 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +21729 # check output +21730 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal") +21731 # . epilogue +21732 89/<- %esp 5/r32/ebp +21733 5d/pop-to-ebp +21734 c3/return +21735 +21736 test-compare-reg-with-literal: +21737 # compare var1/ecx 0x34 +21738 # => +21739 # 81 7/subop/compare %ecx 0x34/imm32 +21740 # +21741 # . prologue +21742 55/push-ebp +21743 89/<- %ebp 4/r32/esp +21744 # setup +21745 (clear-stream _test-output-stream) +21746 (clear-stream $_test-output-buffered-file->buffer) +21747 $test-compare-reg-with-literal:initialize-type: +21748 # var type/ecx: (payload type-tree) = int +21749 68/push 0/imm32/right:null +21750 68/push 0/imm32/right:null +21751 68/push 0/imm32/left:unused +21752 68/push 1/imm32/value:int +21753 68/push 1/imm32/is-atom?:true +21754 68/push 0x11/imm32/alloc-id:fake:payload +21755 89/<- %ecx 4/r32/esp +21756 $test-compare-reg-with-literal:initialize-var1: +21757 # var var1/ecx: (payload var) +21758 68/push 0/imm32/register +21759 68/push 0/imm32/register +21760 68/push 0/imm32/no-stack-offset +21761 68/push 1/imm32/block-depth +21762 51/push-ecx +21763 68/push 0x11/imm32/alloc-id:fake +21764 68/push 0/imm32/name +21765 68/push 0/imm32/name +21766 68/push 0x11/imm32/alloc-id:fake:payload +21767 89/<- %ecx 4/r32/esp +21768 $test-compare-reg-with-literal:initialize-var1-name: +21769 # var1->name = "var1" +21770 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21771 (copy-array Heap "var1" %eax) +21772 $test-compare-reg-with-literal:initialize-var1-register: +21773 # v->register = "ecx" +21774 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +21775 (copy-array Heap "ecx" %eax) +21776 $test-compare-reg-with-literal:initialize-literal-type: +21777 # var type/edx: (payload type-tree) = literal +21778 68/push 0/imm32/right:null +21779 68/push 0/imm32/right:null +21780 68/push 0/imm32/left:unused +21781 68/push 0/imm32/value:literal +21782 68/push 1/imm32/is-atom?:true +21783 68/push 0x11/imm32/alloc-id:fake:payload +21784 89/<- %edx 4/r32/esp +21785 $test-compare-reg-with-literal:initialize-literal: +21786 # var l/edx: (payload var) +21787 68/push 0/imm32/register +21788 68/push 0/imm32/register +21789 68/push 0/imm32/no-stack-offset +21790 68/push 1/imm32/block-depth +21791 52/push-edx +21792 68/push 0x11/imm32/alloc-id:fake +21793 68/push 0/imm32/name +21794 68/push 0/imm32/name +21795 68/push 0x11/imm32/alloc-id:fake:payload +21796 89/<- %edx 4/r32/esp +21797 $test-compare-reg-with-literal:initialize-literal-value: +21798 # l->name = "0x34" +21799 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +21800 (copy-array Heap "0x34" %eax) +21801 $test-compare-reg-with-literal:initialize-inouts: +21802 # var inouts/esi: (payload stmt-var) = [l] +21803 68/push 0/imm32/is-deref:false +21804 68/push 0/imm32/next +21805 68/push 0/imm32/next +21806 52/push-edx/l +21807 68/push 0x11/imm32/alloc-id:fake +21808 68/push 0x11/imm32/alloc-id:fake:payload +21809 89/<- %esi 4/r32/esp +21810 # var inouts = (handle stmt-var) = [var1, var2] +21811 68/push 0/imm32/is-deref:false +21812 56/push-esi/next +21813 68/push 0x11/imm32/alloc-id:fake +21814 51/push-ecx/var1 +21815 68/push 0x11/imm32/alloc-id:fake +21816 68/push 0x11/imm32/alloc-id:fake:payload +21817 89/<- %esi 4/r32/esp +21818 $test-compare-reg-with-literal:initialize-stmt: +21819 # var stmt/esi: (addr statement) +21820 68/push 0/imm32/next +21821 68/push 0/imm32/next +21822 68/push 0/imm32/outputs +21823 68/push 0/imm32/outputs +21824 56/push-esi/inouts +21825 68/push 0x11/imm32/alloc-id:fake +21826 68/push 0/imm32/operation +21827 68/push 0/imm32/operation +21828 68/push 1/imm32/tag:stmt1 +21829 89/<- %esi 4/r32/esp +21830 $test-compare-reg-with-literal:initialize-stmt-operation: +21831 # stmt->operation = "compare" +21832 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21833 (copy-array Heap "compare" %eax) +21834 # convert +21835 c7 0/subop/copy *Curr-block-depth 0/imm32 +21836 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +21837 (flush _test-output-buffered-file) +21838 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +21844 # check output +21845 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal") +21846 # . epilogue +21847 89/<- %esp 5/r32/ebp +21848 5d/pop-to-ebp +21849 c3/return +21850 +21851 test-emit-subx-stmt-function-call: +21852 # Call a function on a variable on the stack. +21853 # f foo +21854 # => +21855 # (f *(ebp-8)) +21856 # (Changing the function name supports overloading in general, but here it +21857 # just serves to help disambiguate things.) +21858 # +21859 # There's a variable on the var stack as follows: +21860 # name: 'foo' +21861 # type: int +21862 # stack-offset: -8 +21863 # +21864 # There's nothing in primitives. +21865 # +21866 # We don't perform any checking here on the type of 'f'. +21867 # +21868 # . prologue +21869 55/push-ebp +21870 89/<- %ebp 4/r32/esp +21871 # setup +21872 (clear-stream _test-output-stream) +21873 (clear-stream $_test-output-buffered-file->buffer) +21874 $test-emit-subx-function-call:initialize-type: +21875 # var type/ecx: (payload type-tree) = int +21876 68/push 0/imm32/right:null +21877 68/push 0/imm32/right:null +21878 68/push 0/imm32/left:unused +21879 68/push 1/imm32/value:int +21880 68/push 1/imm32/is-atom?:true +21881 68/push 0x11/imm32/alloc-id:fake:payload +21882 89/<- %ecx 4/r32/esp +21883 $test-emit-subx-function-call:initialize-var: +21884 # var var-foo/ecx: (payload var) = var(type) +21885 68/push 0/imm32/no-register +21886 68/push 0/imm32/no-register +21887 68/push -8/imm32/stack-offset +21888 68/push 1/imm32/block-depth +21889 51/push-ecx/type +21890 68/push 0x11/imm32/alloc-id:fake +21891 68/push 0/imm32/name +21892 68/push 0/imm32/name +21893 68/push 0x11/imm32/alloc-id:fake:payload +21894 89/<- %ecx 4/r32/esp +21895 $test-emit-subx-function-call:initialize-var-name: +21896 # var-foo->name = "foo" +21897 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21898 (copy-array Heap "foo" %eax) +21899 $test-emit-subx-function-call:initialize-stmt-var: +21900 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +21901 68/push 0/imm32/is-deref:false +21902 68/push 0/imm32/next +21903 68/push 0/imm32/next +21904 51/push-ecx/var-foo +21905 68/push 0x11/imm32/alloc-id:fake +21906 68/push 0x11/imm32/alloc-id:fake:payload +21907 89/<- %ebx 4/r32/esp +21908 $test-emit-subx-function-call:initialize-stmt: +21909 # var stmt/esi: (addr statement) +21910 68/push 0/imm32/no-outputs +21911 68/push 0/imm32/no-outputs +21912 53/push-ebx/inouts +21913 68/push 0x11/imm32/alloc-id:fake +21914 68/push 0/imm32/operation +21915 68/push 0/imm32/operation +21916 68/push 1/imm32/tag +21917 89/<- %esi 4/r32/esp +21918 $test-emit-subx-function-call:initialize-stmt-operation: +21919 # stmt->operation = "f" +21920 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21921 (copy-array Heap "f" %eax) +21922 # convert +21923 c7 0/subop/copy *Curr-block-depth 0/imm32 +21924 (emit-subx-stmt _test-output-buffered-file %esi 0 Stderr 0) +21925 (flush _test-output-buffered-file) +21926 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +21932 # check output +21933 (check-next-stream-line-equal _test-output-stream "(f *(ebp+0xfffffff8))" "F - test-emit-subx-stmt-function-call") +21934 # . epilogue +21935 89/<- %esp 5/r32/ebp +21936 5d/pop-to-ebp +21937 c3/return +21938 +21939 test-emit-subx-stmt-function-call-with-literal-arg: +21940 # Call a function on a literal. +21941 # f 0x34 +21942 # => +21943 # (f2 0x34) +21944 # +21945 # . prologue +21946 55/push-ebp +21947 89/<- %ebp 4/r32/esp +21948 # setup +21949 (clear-stream _test-output-stream) +21950 (clear-stream $_test-output-buffered-file->buffer) +21951 $test-emit-subx-function-call-with-literal-arg:initialize-type: +21952 # var type/ecx: (payload type-tree) = int +21953 68/push 0/imm32/right:null +21954 68/push 0/imm32/right:null +21955 68/push 0/imm32/left:unused +21956 68/push 0/imm32/value:literal +21957 68/push 1/imm32/is-atom?:true +21958 68/push 0x11/imm32/alloc-id:fake:payload +21959 89/<- %ecx 4/r32/esp +21960 $test-emit-subx-function-call-with-literal-arg:initialize-var: +21961 # var var-foo/ecx: (payload var) = var(lit) +21962 68/push 0/imm32/no-register +21963 68/push 0/imm32/no-register +21964 68/push 0/imm32/no-stack-offset +21965 68/push 1/imm32/block-depth +21966 51/push-ecx/type +21967 68/push 0x11/imm32/alloc-id:fake +21968 68/push 0/imm32/name +21969 68/push 0/imm32/name +21970 68/push 0x11/imm32/alloc-id:fake:payload +21971 89/<- %ecx 4/r32/esp +21972 $test-emit-subx-function-call-with-literal-arg:initialize-var-name: +21973 # var-foo->name = "0x34" +21974 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +21975 (copy-array Heap "0x34" %eax) +21976 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-var: +21977 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +21978 68/push 0/imm32/is-deref:false +21979 68/push 0/imm32/next +21980 68/push 0/imm32/next +21981 51/push-ecx/var-foo +21982 68/push 0x11/imm32/alloc-id:fake +21983 68/push 0x11/imm32/alloc-id:fake:payload +21984 89/<- %ebx 4/r32/esp +21985 $test-emit-subx-function-call-with-literal-arg:initialize-stmt: +21986 # var stmt/esi: (addr statement) +21987 68/push 0/imm32/no-outputs +21988 68/push 0/imm32/no-outputs +21989 53/push-ebx/inouts +21990 68/push 0x11/imm32/alloc-id:fake +21991 68/push 0/imm32/operation +21992 68/push 0/imm32/operation +21993 68/push 1/imm32/tag +21994 89/<- %esi 4/r32/esp +21995 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-operation: +21996 # stmt->operation = "f" +21997 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +21998 (copy-array Heap "f" %eax) +21999 # convert +22000 c7 0/subop/copy *Curr-block-depth 0/imm32 +22001 (emit-subx-stmt _test-output-buffered-file %esi 0 %ebx Stderr 0) +22002 (flush _test-output-buffered-file) +22003 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +22009 # check output +22010 (check-next-stream-line-equal _test-output-stream "(f 0x34)" "F - test-emit-subx-stmt-function-call-with-literal-arg") +22011 # . epilogue +22012 89/<- %esp 5/r32/ebp +22013 5d/pop-to-ebp +22014 c3/return +22015 +22016 emit-indent: # out: (addr buffered-file), n: int +22017 # . prologue +22018 55/push-ebp +22019 89/<- %ebp 4/r32/esp +22020 # . save registers +22021 50/push-eax +22022 # var i/eax: int = n +22023 8b/-> *(ebp+0xc) 0/r32/eax +22024 { +22025 # if (i <= 0) break +22026 3d/compare-eax-with 0/imm32 +22027 7e/jump-if-<= break/disp8 +22028 (write-buffered *(ebp+8) " ") +22029 48/decrement-eax +22030 eb/jump loop/disp8 +22031 } +22032 $emit-indent:end: +22033 # . restore registers +22034 58/pop-to-eax +22035 # . epilogue +22036 89/<- %esp 5/r32/ebp +22037 5d/pop-to-ebp +22038 c3/return +22039 +22040 emit-subx-prologue: # out: (addr buffered-file) +22041 # . prologue +22042 55/push-ebp +22043 89/<- %ebp 4/r32/esp +22044 # +22045 (write-buffered *(ebp+8) " # . prologue\n") +22046 (write-buffered *(ebp+8) " 55/push-ebp\n") +22047 (write-buffered *(ebp+8) " 89/<- %ebp 4/r32/esp\n") +22048 $emit-subx-prologue:end: +22049 # . epilogue +22050 89/<- %esp 5/r32/ebp +22051 5d/pop-to-ebp +22052 c3/return +22053 +22054 emit-subx-epilogue: # out: (addr buffered-file) +22055 # . prologue +22056 55/push-ebp +22057 89/<- %ebp 4/r32/esp +22058 # +22059 (write-buffered *(ebp+8) " # . epilogue\n") +22060 (write-buffered *(ebp+8) " 89/<- %esp 5/r32/ebp\n") +22061 (write-buffered *(ebp+8) " 5d/pop-to-ebp\n") +22062 (write-buffered *(ebp+8) " c3/return\n") +22063 $emit-subx-epilogue:end: +22064 # . epilogue +22065 89/<- %esp 5/r32/ebp +22066 5d/pop-to-ebp +22067 c3/return -- cgit 1.4.1-2-gfad0