From 40323d3388905b7f709f87ff82a7368f729bf5cd Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sun, 28 Jun 2020 23:36:26 -0700 Subject: 6593 --- html/apps/mu.subx.html | 36571 ++++++++++++++++++++++++----------------------- 1 file changed, 18990 insertions(+), 17581 deletions(-) (limited to 'html/apps/mu.subx.html') diff --git a/html/apps/mu.subx.html b/html/apps/mu.subx.html index d1bca9ae..35b83337 100644 --- a/html/apps/mu.subx.html +++ b/html/apps/mu.subx.html @@ -440,7 +440,7 @@ if ('onhashchange' in window) { 378 379 # TODO: Turn this data structure into valid Mu, with (fake) handles rather than addrs. 380 Type-id: # (stream (addr array byte)) - 381 0x20/imm32/write + 381 0/imm32/write # initialized later from Primitive-type-ids 382 0/imm32/read 383 0x100/imm32/size 384 # data @@ -462,17675 +462,19084 @@ if ('onhashchange' in window) { 400 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 401 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 402 - 403 # == Type definitions - 404 # Program->types contains some typeinfo for each type definition. - 405 # Types contain vars with types, but can't specify registers. - 406 Typeinfo-id: # type-id - 407 0/imm32 - 408 Typeinfo-fields: # (handle table (handle array byte) (handle typeinfo-entry)) - 409 4/imm32 - 410 # Total size must be >= 0 - 411 # During parsing it may take on two additional values: - 412 # -2: not yet initialized - 413 # -1: in process of being computed - 414 # See populate-mu-type-sizes for details. - 415 Typeinfo-total-size-in-bytes: # int - 416 0xc/imm32 - 417 Typeinfo-next: # (handle typeinfo) - 418 0x10/imm32 - 419 Typeinfo-size: # (addr int) - 420 0x18/imm32 - 421 - 422 # Each entry in the typeinfo->fields table has a pointer to a string and a - 423 # pointer to a typeinfo-entry. - 424 Typeinfo-fields-row-size: # (addr int) - 425 0x10/imm32 - 426 - 427 # typeinfo-entry objects have information about a field in a single record type - 428 # - 429 # each field of a type is represented using two var's: - 430 # 1. the input var: expected type of the field; convenient for creating using parse-var-with-type - 431 # 2. the output var: a constant containing the byte offset; convenient for code-generation - 432 # computing the output happens after parsing; in the meantime we preserve the - 433 # order of fields in the 'index' field. - 434 Typeinfo-entry-input-var: # (handle var) - 435 0/imm32 - 436 Typeinfo-entry-index: # int - 437 8/imm32 - 438 Typeinfo-entry-output-var: # (handle var) - 439 0xc/imm32 - 440 Typeinfo-entry-size: # (addr int) - 441 0x14/imm32 - 442 - 443 == code - 444 - 445 Entry: - 446 # . prologue - 447 89/<- %ebp 4/r32/esp - 448 (new-segment *Heap-size Heap) - 449 # if (argv[1] == "test') run-tests() - 450 { - 451 # if (argc <= 1) break - 452 81 7/subop/compare *ebp 1/imm32 - 453 7e/jump-if-<= break/disp8 - 454 # if (argv[1] != "test") break - 455 (kernel-string-equal? *(ebp+8) "test") # => eax - 456 3d/compare-eax-and 0/imm32/false - 457 74/jump-if-= break/disp8 - 458 # - 459 (run-tests) - 460 # syscall(exit, *Num-test-failures) - 461 8b/-> *Num-test-failures 3/r32/ebx - 462 eb/jump $mu-main:end/disp8 - 463 } - 464 # otherwise convert Stdin - 465 (convert-mu Stdin Stdout Stderr 0) - 466 (flush Stdout) - 467 # syscall(exit, 0) - 468 bb/copy-to-ebx 0/imm32 - 469 $mu-main:end: - 470 e8/call syscall_exit/disp32 - 471 - 472 convert-mu: # in: (addr buffered-file), out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) - 473 # . prologue - 474 55/push-ebp - 475 89/<- %ebp 4/r32/esp - 476 # initialize global data structures - 477 c7 0/subop/copy *Next-block-index 1/imm32 - 478 c7 0/subop/copy *Type-id 0x24/imm32 # stream-write - 479 c7 0/subop/copy *_Program-functions 0/imm32 - 480 c7 0/subop/copy *_Program-functions->payload 0/imm32 - 481 c7 0/subop/copy *_Program-types 0/imm32 - 482 c7 0/subop/copy *_Program-types->payload 0/imm32 - 483 # - 484 (parse-mu *(ebp+8) *(ebp+0x10) *(ebp+0x14)) - 485 (populate-mu-type-sizes *(ebp+0x10) *(ebp+0x14)) - 486 #? (dump-typeinfos "=== typeinfos\n") - 487 (check-mu-types *(ebp+0x10) *(ebp+0x14)) - 488 (emit-subx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) - 489 $convert-mu:end: - 490 # . epilogue - 491 89/<- %esp 5/r32/ebp - 492 5d/pop-to-ebp - 493 c3/return - 494 - 495 test-convert-empty-input: - 496 # empty input => empty output - 497 # . prologue - 498 55/push-ebp - 499 89/<- %ebp 4/r32/esp - 500 # setup - 501 (clear-stream _test-input-stream) - 502 (clear-stream $_test-input-buffered-file->buffer) - 503 (clear-stream _test-output-stream) - 504 (clear-stream $_test-output-buffered-file->buffer) - 505 # - 506 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 507 (flush _test-output-buffered-file) - 508 (check-stream-equal _test-output-stream "" "F - test-convert-empty-input") - 509 # . epilogue - 510 89/<- %esp 5/r32/ebp - 511 5d/pop-to-ebp - 512 c3/return - 513 - 514 test-convert-function-skeleton: - 515 # . prologue - 516 55/push-ebp - 517 89/<- %ebp 4/r32/esp - 518 # setup - 519 (clear-stream _test-input-stream) - 520 (clear-stream $_test-input-buffered-file->buffer) - 521 (clear-stream _test-output-stream) - 522 (clear-stream $_test-output-buffered-file->buffer) - 523 # - 524 (write _test-input-stream "fn foo {\n") - 525 (write _test-input-stream "}\n") - 526 # convert - 527 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 528 (flush _test-output-buffered-file) - 529 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 535 # check output - 536 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0") - 537 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-skeleton/1") - 538 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-skeleton/2") - 539 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3") - 540 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-skeleton/4") - 541 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5") - 542 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-skeleton/6") - 543 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-skeleton/7") - 544 # . epilogue - 545 89/<- %esp 5/r32/ebp - 546 5d/pop-to-ebp - 547 c3/return - 548 - 549 test-convert-multiple-function-skeletons: - 550 # . prologue - 551 55/push-ebp - 552 89/<- %ebp 4/r32/esp - 553 # setup - 554 (clear-stream _test-input-stream) - 555 (clear-stream $_test-input-buffered-file->buffer) - 556 (clear-stream _test-output-stream) - 557 (clear-stream $_test-output-buffered-file->buffer) - 558 # - 559 (write _test-input-stream "fn foo {\n") - 560 (write _test-input-stream "}\n") - 561 (write _test-input-stream "fn bar {\n") - 562 (write _test-input-stream "}\n") - 563 # convert - 564 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 565 (flush _test-output-buffered-file) - 566 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 572 # check first function - 573 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-multiple-function-skeletons/0") - 574 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/1") - 575 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/2") - 576 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/3") - 577 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/4") - 578 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/5") - 579 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/6") - 580 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/7") - 581 # check second function - 582 (check-next-stream-line-equal _test-output-stream "bar:" "F - test-convert-multiple-function-skeletons/10") - 583 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/11") - 584 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/12") - 585 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/13") - 586 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/14") - 587 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/15") - 588 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/16") - 589 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/17") - 590 # . epilogue - 591 89/<- %esp 5/r32/ebp - 592 5d/pop-to-ebp - 593 c3/return - 594 - 595 test-convert-function-with-arg: - 596 # . prologue - 597 55/push-ebp - 598 89/<- %ebp 4/r32/esp - 599 # setup - 600 (clear-stream _test-input-stream) - 601 (clear-stream $_test-input-buffered-file->buffer) - 602 (clear-stream _test-output-stream) - 603 (clear-stream $_test-output-buffered-file->buffer) - 604 # - 605 (write _test-input-stream "fn foo n: int {\n") - 606 (write _test-input-stream "}\n") - 607 # convert - 608 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 609 (flush _test-output-buffered-file) - 610 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 616 # check output - 617 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg/0") - 618 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg/1") - 619 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg/2") - 620 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg/3") - 621 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg/4") - 622 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg/5") - 623 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg/6") - 624 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg/7") - 625 # . epilogue - 626 89/<- %esp 5/r32/ebp - 627 5d/pop-to-ebp - 628 c3/return - 629 - 630 test-convert-function-with-arg-and-body: - 631 # . prologue - 632 55/push-ebp - 633 89/<- %ebp 4/r32/esp - 634 # setup - 635 (clear-stream _test-input-stream) - 636 (clear-stream $_test-input-buffered-file->buffer) - 637 (clear-stream _test-output-stream) - 638 (clear-stream $_test-output-buffered-file->buffer) - 639 # - 640 (write _test-input-stream "fn foo n: int {\n") - 641 (write _test-input-stream " increment n\n") - 642 (write _test-input-stream "}\n") - 643 # convert - 644 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 645 (flush _test-output-buffered-file) - 646 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 652 # check output - 653 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg-and-body/0") - 654 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg-and-body/1") - 655 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg-and-body/2") - 656 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg-and-body/3") - 657 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-arg-and-body/4") - 658 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-arg-and-body/5") - 659 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-arg-and-body/6") - 660 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-arg-and-body/7") - 661 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-arg-and-body/8") - 662 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg-and-body/9") - 663 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg-and-body/10") - 664 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg-and-body/11") - 665 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg-and-body/12") - 666 # . epilogue - 667 89/<- %esp 5/r32/ebp - 668 5d/pop-to-ebp - 669 c3/return - 670 - 671 test-convert-function-distinguishes-args: - 672 # . prologue - 673 55/push-ebp - 674 89/<- %ebp 4/r32/esp - 675 # setup - 676 (clear-stream _test-input-stream) - 677 (clear-stream $_test-input-buffered-file->buffer) - 678 (clear-stream _test-output-stream) - 679 (clear-stream $_test-output-buffered-file->buffer) - 680 # - 681 (write _test-input-stream "fn foo a: int, b: int {\n") - 682 (write _test-input-stream " increment b\n") - 683 (write _test-input-stream "}\n") - 684 # convert - 685 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 686 (flush _test-output-buffered-file) - 687 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 693 # check output - 694 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-distinguishes-args/0") - 695 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-distinguishes-args/1") - 696 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-distinguishes-args/2") - 697 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-distinguishes-args/3") - 698 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-distinguishes-args/4") - 699 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-distinguishes-args/5") - 700 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x0000000c)" "F - test-convert-function-distinguishes-args/6") - 701 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-distinguishes-args/7") - 702 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-distinguishes-args/8") - 703 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-distinguishes-args/9") - 704 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-distinguishes-args/10") - 705 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-distinguishes-args/11") - 706 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-distinguishes-args/12") - 707 # . epilogue - 708 89/<- %esp 5/r32/ebp - 709 5d/pop-to-ebp - 710 c3/return - 711 - 712 test-convert-function-returns-result: - 713 # . prologue - 714 55/push-ebp - 715 89/<- %ebp 4/r32/esp - 716 # setup - 717 (clear-stream _test-input-stream) - 718 (clear-stream $_test-input-buffered-file->buffer) - 719 (clear-stream _test-output-stream) - 720 (clear-stream $_test-output-buffered-file->buffer) - 721 # - 722 (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n") - 723 (write _test-input-stream " result <- copy a\n") - 724 (write _test-input-stream " result <- increment\n") - 725 (write _test-input-stream "}\n") - 726 # convert - 727 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 728 (flush _test-output-buffered-file) - 729 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 735 # check output - 736 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-returns-result/0") - 737 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-returns-result/1") - 738 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-returns-result/2") - 739 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-returns-result/3") - 740 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-returns-result/4") - 741 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-returns-result/5") - 742 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-returns-result/6") - 743 (check-next-stream-line-equal _test-output-stream " 40/increment-eax" "F - test-convert-function-returns-result/7") - 744 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-returns-result/8") - 745 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-returns-result/9") - 746 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-returns-result/10") - 747 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-returns-result/11") - 748 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-returns-result/12") - 749 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-returns-result/13") - 750 # . epilogue - 751 89/<- %esp 5/r32/ebp - 752 5d/pop-to-ebp - 753 c3/return - 754 - 755 test-convert-function-with-literal-arg: - 756 # . prologue - 757 55/push-ebp - 758 89/<- %ebp 4/r32/esp - 759 # setup - 760 (clear-stream _test-input-stream) - 761 (clear-stream $_test-input-buffered-file->buffer) - 762 (clear-stream _test-output-stream) - 763 (clear-stream $_test-output-buffered-file->buffer) - 764 # - 765 (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n") - 766 (write _test-input-stream " result <- copy a\n") - 767 (write _test-input-stream " result <- add 1\n") - 768 (write _test-input-stream "}\n") - 769 # convert - 770 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 771 (flush _test-output-buffered-file) - 772 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 778 # check output - 779 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg/0") - 780 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg/1") - 781 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg/2") - 782 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg/3") - 783 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg/4") - 784 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg/5") - 785 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-with-literal-arg/6") - 786 (check-next-stream-line-equal _test-output-stream " 05/add-to-eax 1/imm32" "F - test-convert-function-with-literal-arg/7") - 787 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg/8") - 788 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg/9") - 789 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg/10") - 790 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg/11") - 791 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg/12") - 792 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg/13") - 793 # . epilogue - 794 89/<- %esp 5/r32/ebp - 795 5d/pop-to-ebp - 796 c3/return - 797 - 798 test-convert-function-with-literal-arg-2: - 799 # . prologue - 800 55/push-ebp - 801 89/<- %ebp 4/r32/esp - 802 # setup - 803 (clear-stream _test-input-stream) - 804 (clear-stream $_test-input-buffered-file->buffer) - 805 (clear-stream _test-output-stream) - 806 (clear-stream $_test-output-buffered-file->buffer) - 807 # - 808 (write _test-input-stream "fn foo a: int, b: int -> result/ebx: int {\n") - 809 (write _test-input-stream " result <- copy a\n") - 810 (write _test-input-stream " result <- add 1\n") - 811 (write _test-input-stream "}\n") - 812 # convert - 813 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 814 (flush _test-output-buffered-file) - 815 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 821 # check output - 822 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg-2/0") - 823 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg-2/1") - 824 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg-2/2") - 825 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg-2/3") - 826 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg-2/4") - 827 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg-2/5") - 828 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/6") - 829 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %ebx 1/imm32" "F - test-convert-function-with-literal-arg-2/7") - 830 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg-2/8") - 831 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg-2/9") - 832 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg-2/10") - 833 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg-2/11") - 834 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg-2/12") - 835 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg-2/13") - 836 # . epilogue - 837 89/<- %esp 5/r32/ebp - 838 5d/pop-to-ebp - 839 c3/return - 840 - 841 test-convert-function-call-with-literal-arg: - 842 # . prologue - 843 55/push-ebp - 844 89/<- %ebp 4/r32/esp - 845 # setup - 846 (clear-stream _test-input-stream) - 847 (clear-stream $_test-input-buffered-file->buffer) - 848 (clear-stream _test-output-stream) - 849 (clear-stream $_test-output-buffered-file->buffer) - 850 # - 851 (write _test-input-stream "fn main -> result/ebx: int {\n") - 852 (write _test-input-stream " result <- do-add 3 4\n") - 853 (write _test-input-stream "}\n") - 854 (write _test-input-stream "fn do-add a: int, b: int -> result/ebx: int {\n") - 855 (write _test-input-stream " result <- copy a\n") - 856 (write _test-input-stream " result <- add b\n") - 857 (write _test-input-stream "}\n") - 858 # convert - 859 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 860 (flush _test-output-buffered-file) - 861 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 867 # check output - 868 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-literal-arg/0") - 869 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/1") - 870 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/2") - 871 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/3") - 872 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/4") - 873 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-literal-arg/5") - 874 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-literal-arg/6") - 875 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/7") - 876 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-literal-arg/8") - 877 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/9") - 878 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/10") - 879 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/11") - 880 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/12") - 881 (check-next-stream-line-equal _test-output-stream "do-add:" "F - test-convert-function-call-with-literal-arg/13") - 882 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/14") - 883 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/15") - 884 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/16") - 885 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/17") - 886 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:loop:" "F - test-convert-function-call-with-literal-arg/18") - 887 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/19") - 888 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0x0000000c) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/20") - 889 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/21") - 890 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:break:" "F - test-convert-function-call-with-literal-arg/22") - 891 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/23") - 892 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/24") - 893 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/25") - 894 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/26") - 895 # . epilogue - 896 89/<- %esp 5/r32/ebp - 897 5d/pop-to-ebp - 898 c3/return - 899 - 900 test-convert-function-with-local-var-in-mem: - 901 # . prologue - 902 55/push-ebp - 903 89/<- %ebp 4/r32/esp - 904 # setup - 905 (clear-stream _test-input-stream) - 906 (clear-stream $_test-input-buffered-file->buffer) - 907 (clear-stream _test-output-stream) - 908 (clear-stream $_test-output-buffered-file->buffer) - 909 # - 910 (write _test-input-stream "fn foo {\n") - 911 (write _test-input-stream " var x: int\n") - 912 (write _test-input-stream " increment x\n") - 913 (write _test-input-stream "}\n") - 914 # convert - 915 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 916 (flush _test-output-buffered-file) - 917 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 923 # check output - 924 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-mem/0") - 925 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-mem/1") - 926 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-mem/2") - 927 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-mem/3") - 928 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem/4") - 929 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-mem/5") - 930 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem/6") - 931 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-mem/7") - 932 (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") - 933 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem/9") - 934 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-mem/10") - 935 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-mem/11") - 936 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-mem/12") - 937 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-mem/13") - 938 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-mem/14") - 939 # . epilogue - 940 89/<- %esp 5/r32/ebp - 941 5d/pop-to-ebp - 942 c3/return - 943 - 944 test-local-var-in-mem-has-no-initializer: - 945 # . prologue - 946 55/push-ebp - 947 89/<- %ebp 4/r32/esp - 948 # setup - 949 (clear-stream _test-input-stream) - 950 (clear-stream $_test-input-buffered-file->buffer) - 951 (clear-stream _test-output-stream) - 952 (clear-stream $_test-output-buffered-file->buffer) - 953 (clear-stream _test-error-stream) - 954 (clear-stream $_test-error-buffered-file->buffer) - 955 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 956 68/push 0/imm32 - 957 68/push 0/imm32 - 958 89/<- %edx 4/r32/esp - 959 (tailor-exit-descriptor %edx 0x10) - 960 # - 961 (write _test-input-stream "fn foo {\n") - 962 (write _test-input-stream " var x: int <- copy 0\n") - 963 (write _test-input-stream " increment x\n") - 964 (write _test-input-stream "}\n") - 965 # convert - 966 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 967 # registers except esp clobbered at this point - 968 # restore ed - 969 89/<- %edx 4/r32/esp - 970 (flush _test-output-buffered-file) - 971 (flush _test-error-buffered-file) - 972 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 978 # check output - 979 (check-stream-equal _test-output-stream "" "F - test-var-in-mem-has-no-initializer: output should be empty") - 980 (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") - 981 # check that stop(1) was called - 982 (check-ints-equal *(edx+4) 2 "F - test-var-in-mem-has-no-initializer: exit status") - 983 # don't restore from ebp - 984 81 0/subop/add %esp 8/imm32 - 985 # . epilogue - 986 5d/pop-to-ebp - 987 c3/return - 988 - 989 test-convert-function-with-local-var-with-compound-type-in-mem: - 990 # . prologue - 991 55/push-ebp - 992 89/<- %ebp 4/r32/esp - 993 # setup - 994 (clear-stream _test-input-stream) - 995 (clear-stream $_test-input-buffered-file->buffer) - 996 (clear-stream _test-output-stream) - 997 (clear-stream $_test-output-buffered-file->buffer) - 998 # - 999 (write _test-input-stream "fn foo {\n") - 1000 (write _test-input-stream " var x: (addr int)\n") - 1001 (write _test-input-stream " copy-to x, 0\n") - 1002 (write _test-input-stream "}\n") - 1003 # convert - 1004 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1005 (flush _test-output-buffered-file) - 1006 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1012 # check output - 1013 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/0") - 1014 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/1") - 1015 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/2") - 1016 (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") - 1017 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-compound-type-in-mem/4") - 1018 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/5") - 1019 (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") - 1020 (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") - 1021 (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") - 1022 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-compound-type-in-mem/9") - 1023 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/10") - 1024 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/11") - 1025 (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") - 1026 (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") - 1027 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-compound-type-in-mem/14") - 1028 # . epilogue - 1029 89/<- %esp 5/r32/ebp - 1030 5d/pop-to-ebp - 1031 c3/return - 1032 - 1033 test-convert-function-with-local-var-in-reg: - 1034 # . prologue - 1035 55/push-ebp - 1036 89/<- %ebp 4/r32/esp - 1037 # setup - 1038 (clear-stream _test-input-stream) - 1039 (clear-stream $_test-input-buffered-file->buffer) - 1040 (clear-stream _test-output-stream) - 1041 (clear-stream $_test-output-buffered-file->buffer) - 1042 # - 1043 (write _test-input-stream "fn foo {\n") - 1044 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1045 (write _test-input-stream " x <- increment\n") - 1046 (write _test-input-stream "}\n") - 1047 # convert - 1048 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1049 (flush _test-output-buffered-file) - 1050 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1056 # check output - 1057 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-reg/0") - 1058 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-reg/1") - 1059 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-reg/2") - 1060 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-reg/3") - 1061 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-reg/4") - 1062 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-reg/5") - 1063 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-reg/6") - 1064 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-local-var-in-reg/7") - 1065 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-local-var-in-reg/8") - 1066 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-reg/9") - 1067 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-reg/10") - 1068 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-reg/11") - 1069 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-reg/12") - 1070 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-reg/13") - 1071 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-reg/14") - 1072 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-reg/15") - 1073 # . epilogue - 1074 89/<- %esp 5/r32/ebp - 1075 5d/pop-to-ebp - 1076 c3/return - 1077 - 1078 test-convert-function-with-second-local-var-in-same-reg: - 1079 # . prologue - 1080 55/push-ebp - 1081 89/<- %ebp 4/r32/esp - 1082 # setup - 1083 (clear-stream _test-input-stream) - 1084 (clear-stream $_test-input-buffered-file->buffer) - 1085 (clear-stream _test-output-stream) - 1086 (clear-stream $_test-output-buffered-file->buffer) - 1087 # - 1088 (write _test-input-stream "fn foo {\n") - 1089 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1090 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 1091 (write _test-input-stream " y <- increment\n") - 1092 (write _test-input-stream "}\n") - 1093 # convert - 1094 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1095 (flush _test-output-buffered-file) - 1096 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1102 # check output - 1103 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-second-local-var-in-same-reg/0") - 1104 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-second-local-var-in-same-reg/1") - 1105 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/2") - 1106 (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") - 1107 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-second-local-var-in-same-reg/4") - 1108 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-second-local-var-in-same-reg/5") - 1109 (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") - 1110 (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") - 1111 (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") - 1112 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-second-local-var-in-same-reg/9") - 1113 (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") - 1114 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-second-local-var-in-same-reg/11") - 1115 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-second-local-var-in-same-reg/12") - 1116 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-second-local-var-in-same-reg/13") - 1117 (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") - 1118 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/15") - 1119 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-second-local-var-in-same-reg/16") - 1120 # . epilogue - 1121 89/<- %esp 5/r32/ebp - 1122 5d/pop-to-ebp - 1123 c3/return - 1124 - 1125 test-read-clobbered-reg-var: - 1126 # . prologue - 1127 55/push-ebp - 1128 89/<- %ebp 4/r32/esp - 1129 # setup - 1130 (clear-stream _test-input-stream) - 1131 (clear-stream $_test-input-buffered-file->buffer) - 1132 (clear-stream _test-output-stream) - 1133 (clear-stream $_test-output-buffered-file->buffer) - 1134 (clear-stream _test-error-stream) - 1135 (clear-stream $_test-error-buffered-file->buffer) - 1136 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu - 1137 68/push 0/imm32 - 1138 68/push 0/imm32 - 1139 89/<- %edx 4/r32/esp - 1140 (tailor-exit-descriptor %edx 0x10) - 1141 # - 1142 (write _test-input-stream "fn foo {\n") - 1143 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1144 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 1145 (write _test-input-stream " x <- increment\n") - 1146 (write _test-input-stream "}\n") - 1147 # convert - 1148 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1149 # registers except esp clobbered at this point - 1150 # restore ed - 1151 89/<- %edx 4/r32/esp - 1152 (flush _test-output-buffered-file) - 1153 (flush _test-error-buffered-file) - 1154 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1160 # check output - 1161 (check-stream-equal _test-output-stream "" "F - test-read-clobbered-reg-var: output should be empty") - 1162 (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") - 1163 # check that stop(1) was called - 1164 (check-ints-equal *(edx+4) 2 "F - test-read-clobbered-reg-var: exit status") - 1165 # don't restore from ebp - 1166 81 0/subop/add %esp 8/imm32 - 1167 # . epilogue - 1168 5d/pop-to-ebp - 1169 c3/return - 1170 - 1171 test-convert-function-call: - 1172 # . prologue - 1173 55/push-ebp - 1174 89/<- %ebp 4/r32/esp - 1175 # setup - 1176 (clear-stream _test-input-stream) - 1177 (clear-stream $_test-input-buffered-file->buffer) - 1178 (clear-stream _test-output-stream) - 1179 (clear-stream $_test-output-buffered-file->buffer) - 1180 # - 1181 (write _test-input-stream "fn main -> result/ebx: int {\n") - 1182 (write _test-input-stream " result <- foo\n") - 1183 (write _test-input-stream "}\n") - 1184 (write _test-input-stream "fn foo -> result/ebx: int {\n") - 1185 (write _test-input-stream " result <- copy 3\n") - 1186 (write _test-input-stream "}\n") - 1187 # convert - 1188 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1189 (flush _test-output-buffered-file) - 1190 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1196 # check output - 1197 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call/0") - 1198 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/1") - 1199 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/2") - 1200 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/3") - 1201 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/4") - 1202 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call/5") - 1203 (check-next-stream-line-equal _test-output-stream " (foo)" "F - test-convert-function-call/6") - 1204 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/7") - 1205 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call/8") - 1206 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/9") - 1207 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/10") - 1208 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/11") - 1209 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/12") - 1210 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call/13") - 1211 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/14") - 1212 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/15") - 1213 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/16") - 1214 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/17") - 1215 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call/18") - 1216 (check-next-stream-line-equal _test-output-stream " bb/copy-to-ebx 3/imm32" "F - test-convert-function-call/19") - 1217 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/20") - 1218 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call/21") - 1219 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/22") - 1220 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/23") - 1221 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/24") - 1222 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/25") - 1223 # . epilogue - 1224 89/<- %esp 5/r32/ebp - 1225 5d/pop-to-ebp - 1226 c3/return - 1227 - 1228 test-convert-function-call-with-incorrect-inout-type: - 1229 # . prologue - 1230 55/push-ebp - 1231 89/<- %ebp 4/r32/esp - 1232 # setup - 1233 (clear-stream _test-input-stream) - 1234 (clear-stream $_test-input-buffered-file->buffer) - 1235 (clear-stream _test-output-stream) - 1236 (clear-stream $_test-output-buffered-file->buffer) - 1237 (clear-stream _test-error-stream) - 1238 (clear-stream $_test-error-buffered-file->buffer) - 1239 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1240 68/push 0/imm32 - 1241 68/push 0/imm32 - 1242 89/<- %edx 4/r32/esp - 1243 (tailor-exit-descriptor %edx 0x10) - 1244 # - 1245 (write _test-input-stream "fn f {\n") - 1246 (write _test-input-stream " var x: int\n") - 1247 (write _test-input-stream " g x\n") - 1248 (write _test-input-stream "}\n") - 1249 (write _test-input-stream "fn g a: foo {\n") - 1250 (write _test-input-stream "}\n") - 1251 # convert - 1252 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1253 # registers except esp clobbered at this point - 1254 # restore ed - 1255 89/<- %edx 4/r32/esp - 1256 (flush _test-output-buffered-file) - 1257 (flush _test-error-buffered-file) - 1258 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1264 # check output - 1265 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-inout-type: output should be empty") - 1266 (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") - 1267 # check that stop(1) was called - 1268 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-inout-type: exit status") - 1269 # don't restore from ebp - 1270 81 0/subop/add %esp 8/imm32 - 1271 5d/pop-to-ebp - 1272 c3/return - 1273 - 1274 test-convert-function-call-with-too-few-inouts: - 1275 # . prologue - 1276 55/push-ebp - 1277 89/<- %ebp 4/r32/esp - 1278 # setup - 1279 (clear-stream _test-input-stream) - 1280 (clear-stream $_test-input-buffered-file->buffer) - 1281 (clear-stream _test-output-stream) - 1282 (clear-stream $_test-output-buffered-file->buffer) - 1283 (clear-stream _test-error-stream) - 1284 (clear-stream $_test-error-buffered-file->buffer) - 1285 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1286 68/push 0/imm32 - 1287 68/push 0/imm32 - 1288 89/<- %edx 4/r32/esp - 1289 (tailor-exit-descriptor %edx 0x10) - 1290 # - 1291 (write _test-input-stream "fn f {\n") - 1292 (write _test-input-stream " g\n") - 1293 (write _test-input-stream "}\n") - 1294 (write _test-input-stream "fn g a: int {\n") - 1295 (write _test-input-stream "}\n") - 1296 # convert - 1297 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1298 # registers except esp clobbered at this point - 1299 # restore ed - 1300 89/<- %edx 4/r32/esp - 1301 (flush _test-output-buffered-file) - 1302 (flush _test-error-buffered-file) - 1303 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1309 # check output - 1310 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-inouts: output should be empty") - 1311 (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") - 1312 # check that stop(1) was called - 1313 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-inouts: exit status") - 1314 # don't restore from ebp - 1315 81 0/subop/add %esp 8/imm32 - 1316 5d/pop-to-ebp - 1317 c3/return - 1318 - 1319 test-convert-function-call-with-too-many-inouts: - 1320 # . prologue - 1321 55/push-ebp - 1322 89/<- %ebp 4/r32/esp - 1323 # setup - 1324 (clear-stream _test-input-stream) - 1325 (clear-stream $_test-input-buffered-file->buffer) - 1326 (clear-stream _test-output-stream) - 1327 (clear-stream $_test-output-buffered-file->buffer) - 1328 (clear-stream _test-error-stream) - 1329 (clear-stream $_test-error-buffered-file->buffer) - 1330 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1331 68/push 0/imm32 - 1332 68/push 0/imm32 - 1333 89/<- %edx 4/r32/esp - 1334 (tailor-exit-descriptor %edx 0x10) - 1335 # - 1336 (write _test-input-stream "fn f {\n") - 1337 (write _test-input-stream " var x: int\n") - 1338 (write _test-input-stream " g x\n") - 1339 (write _test-input-stream "}\n") - 1340 (write _test-input-stream "fn g {\n") - 1341 (write _test-input-stream "}\n") - 1342 # convert - 1343 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1344 # registers except esp clobbered at this point - 1345 # restore ed - 1346 89/<- %edx 4/r32/esp - 1347 (flush _test-output-buffered-file) - 1348 (flush _test-error-buffered-file) - 1349 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1355 # check output - 1356 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-inouts: output should be empty") - 1357 (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") - 1358 # check that stop(1) was called - 1359 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-inouts: exit status") - 1360 # don't restore from ebp - 1361 81 0/subop/add %esp 8/imm32 - 1362 5d/pop-to-ebp - 1363 c3/return - 1364 - 1365 test-convert-function-call-with-incorrect-output-type: - 1366 # . prologue - 1367 55/push-ebp - 1368 89/<- %ebp 4/r32/esp - 1369 # setup - 1370 (clear-stream _test-input-stream) - 1371 (clear-stream $_test-input-buffered-file->buffer) - 1372 (clear-stream _test-output-stream) - 1373 (clear-stream $_test-output-buffered-file->buffer) - 1374 (clear-stream _test-error-stream) - 1375 (clear-stream $_test-error-buffered-file->buffer) - 1376 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1377 68/push 0/imm32 - 1378 68/push 0/imm32 - 1379 89/<- %edx 4/r32/esp - 1380 (tailor-exit-descriptor %edx 0x10) - 1381 # - 1382 (write _test-input-stream "fn f {\n") - 1383 (write _test-input-stream " var x/eax: int <- g\n") - 1384 (write _test-input-stream "}\n") - 1385 (write _test-input-stream "fn g -> a/eax: foo {\n") - 1386 (write _test-input-stream "}\n") - 1387 # convert - 1388 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1389 # registers except esp clobbered at this point - 1390 # restore ed - 1391 89/<- %edx 4/r32/esp - 1392 (flush _test-output-buffered-file) - 1393 (flush _test-error-buffered-file) - 1394 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1400 # check output - 1401 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-type: output should be empty") - 1402 (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") - 1403 # check that stop(1) was called - 1404 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-type: exit status") - 1405 # don't restore from ebp - 1406 81 0/subop/add %esp 8/imm32 - 1407 5d/pop-to-ebp - 1408 c3/return - 1409 - 1410 test-convert-function-call-with-too-few-outputs: - 1411 # . prologue - 1412 55/push-ebp - 1413 89/<- %ebp 4/r32/esp - 1414 # setup - 1415 (clear-stream _test-input-stream) - 1416 (clear-stream $_test-input-buffered-file->buffer) - 1417 (clear-stream _test-output-stream) - 1418 (clear-stream $_test-output-buffered-file->buffer) - 1419 (clear-stream _test-error-stream) - 1420 (clear-stream $_test-error-buffered-file->buffer) - 1421 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1422 68/push 0/imm32 - 1423 68/push 0/imm32 - 1424 89/<- %edx 4/r32/esp - 1425 (tailor-exit-descriptor %edx 0x10) - 1426 # - 1427 (write _test-input-stream "fn f {\n") - 1428 (write _test-input-stream " g\n") - 1429 (write _test-input-stream "}\n") - 1430 (write _test-input-stream "fn g -> a/eax: int {\n") - 1431 (write _test-input-stream "}\n") - 1432 # convert - 1433 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1434 # registers except esp clobbered at this point - 1435 # restore ed - 1436 89/<- %edx 4/r32/esp - 1437 (flush _test-output-buffered-file) - 1438 (flush _test-error-buffered-file) - 1439 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1445 # check output - 1446 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-outputs: output should be empty") - 1447 (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") - 1448 # check that stop(1) was called - 1449 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-outputs: exit status") - 1450 # don't restore from ebp - 1451 81 0/subop/add %esp 8/imm32 - 1452 5d/pop-to-ebp - 1453 c3/return - 1454 - 1455 test-convert-function-call-with-too-many-outputs: - 1456 # . prologue - 1457 55/push-ebp - 1458 89/<- %ebp 4/r32/esp - 1459 # setup - 1460 (clear-stream _test-input-stream) - 1461 (clear-stream $_test-input-buffered-file->buffer) - 1462 (clear-stream _test-output-stream) - 1463 (clear-stream $_test-output-buffered-file->buffer) - 1464 (clear-stream _test-error-stream) - 1465 (clear-stream $_test-error-buffered-file->buffer) - 1466 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1467 68/push 0/imm32 - 1468 68/push 0/imm32 - 1469 89/<- %edx 4/r32/esp - 1470 (tailor-exit-descriptor %edx 0x10) - 1471 # - 1472 (write _test-input-stream "fn f {\n") - 1473 (write _test-input-stream " var x/eax: int <- g\n") - 1474 (write _test-input-stream "}\n") - 1475 (write _test-input-stream "fn g {\n") - 1476 (write _test-input-stream "}\n") - 1477 # convert - 1478 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1479 # registers except esp clobbered at this point - 1480 # restore ed - 1481 89/<- %edx 4/r32/esp - 1482 (flush _test-output-buffered-file) - 1483 (flush _test-error-buffered-file) - 1484 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1490 # check output - 1491 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-outputs: output should be empty") - 1492 (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") - 1493 # check that stop(1) was called - 1494 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-outputs: exit status") - 1495 # don't restore from ebp - 1496 81 0/subop/add %esp 8/imm32 - 1497 5d/pop-to-ebp - 1498 c3/return - 1499 - 1500 test-convert-function-call-with-incorrect-output-register: - 1501 # . prologue - 1502 55/push-ebp - 1503 89/<- %ebp 4/r32/esp - 1504 # setup - 1505 (clear-stream _test-input-stream) - 1506 (clear-stream $_test-input-buffered-file->buffer) - 1507 (clear-stream _test-output-stream) - 1508 (clear-stream $_test-output-buffered-file->buffer) - 1509 (clear-stream _test-error-stream) - 1510 (clear-stream $_test-error-buffered-file->buffer) - 1511 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1512 68/push 0/imm32 - 1513 68/push 0/imm32 - 1514 89/<- %edx 4/r32/esp - 1515 (tailor-exit-descriptor %edx 0x10) - 1516 # - 1517 (write _test-input-stream "fn f {\n") - 1518 (write _test-input-stream " var x/ecx: int <- g\n") - 1519 (write _test-input-stream "}\n") - 1520 (write _test-input-stream "fn g -> a/eax: int {\n") - 1521 (write _test-input-stream "}\n") - 1522 # convert - 1523 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1524 # registers except esp clobbered at this point - 1525 # restore ed - 1526 89/<- %edx 4/r32/esp - 1527 (flush _test-output-buffered-file) - 1528 (flush _test-error-buffered-file) - 1529 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1535 # check output - 1536 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-register: output should be empty") - 1537 (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") - 1538 # check that stop(1) was called - 1539 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-register: exit status") - 1540 # don't restore from ebp - 1541 81 0/subop/add %esp 8/imm32 - 1542 5d/pop-to-ebp - 1543 c3/return - 1544 - 1545 test-convert-function-with-local-var-dereferenced: - 1546 # . prologue - 1547 55/push-ebp - 1548 89/<- %ebp 4/r32/esp - 1549 # setup - 1550 (clear-stream _test-input-stream) - 1551 (clear-stream $_test-input-buffered-file->buffer) - 1552 (clear-stream _test-output-stream) - 1553 (clear-stream $_test-output-buffered-file->buffer) - 1554 # - 1555 (write _test-input-stream "fn foo {\n") - 1556 (write _test-input-stream " var x/ecx: (addr int) <- copy 0\n") - 1557 (write _test-input-stream " increment *x\n") - 1558 (write _test-input-stream "}\n") - 1559 # convert - 1560 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1561 (flush _test-output-buffered-file) - 1562 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1568 # check output - 1569 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-dereferenced/0") - 1570 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-dereferenced/1") - 1571 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-dereferenced/2") - 1572 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-dereferenced/3") - 1573 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-dereferenced/4") - 1574 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-dereferenced/5") - 1575 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-dereferenced/6") - 1576 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-local-var-dereferenced/7") - 1577 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-with-local-var-dereferenced/8") - 1578 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-dereferenced/9") - 1579 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-dereferenced/10") - 1580 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-dereferenced/11") - 1581 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-dereferenced/12") - 1582 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-dereferenced/13") - 1583 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-dereferenced/14") - 1584 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-dereferenced/15") - 1585 # . epilogue - 1586 89/<- %esp 5/r32/ebp - 1587 5d/pop-to-ebp - 1588 c3/return - 1589 - 1590 # variables of type 'byte' are not allowed on the stack - 1591 test-convert-function-with-byte-operations: - 1592 # . prologue - 1593 55/push-ebp - 1594 89/<- %ebp 4/r32/esp - 1595 # setup - 1596 (clear-stream _test-input-stream) - 1597 (clear-stream $_test-input-buffered-file->buffer) - 1598 (clear-stream _test-output-stream) - 1599 (clear-stream $_test-output-buffered-file->buffer) - 1600 # - 1601 (write _test-input-stream "fn foo {\n") - 1602 (write _test-input-stream " var x/eax: byte <- copy 0\n") - 1603 (write _test-input-stream " var y/ecx: byte <- copy 0\n") - 1604 (write _test-input-stream " y <- copy-byte x\n") - 1605 (write _test-input-stream " var z/edx: (addr byte) <- copy 0\n") - 1606 (write _test-input-stream " y <- copy-byte *z\n") - 1607 (write _test-input-stream " copy-byte-to *z, x\n") - 1608 (write _test-input-stream "}\n") - 1609 # convert - 1610 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1611 (flush _test-output-buffered-file) - 1612 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1618 # check output - 1619 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-byte-operations/0") - 1620 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-byte-operations/1") - 1621 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-byte-operations/2") - 1622 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-byte-operations/3") - 1623 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-byte-operations/4") - 1624 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-byte-operations/5") - 1625 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-byte-operations/6") - 1626 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-with-byte-operations/7") - 1627 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-byte-operations/8") - 1628 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-byte-operations/9") - 1629 (check-next-stream-line-equal _test-output-stream " 8a/byte-> %eax 0x00000001/r32" "F - test-convert-function-with-byte-operations/10") - 1630 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-function-with-byte-operations/11") - 1631 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 0/imm32" "F - test-convert-function-with-byte-operations/12") - 1632 (check-next-stream-line-equal _test-output-stream " 8a/byte-> *edx 0x00000001/r32" "F - test-convert-function-with-byte-operations/13") - 1633 (check-next-stream-line-equal _test-output-stream " 88/byte<- *edx 0x00000000/r32" "F - test-convert-function-with-byte-operations/14") - 1634 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-function-with-byte-operations/15") - 1635 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-byte-operations/16") - 1636 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-byte-operations/17") - 1637 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-byte-operations/18") - 1638 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-byte-operations/19") - 1639 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-byte-operations/20") - 1640 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-byte-operations/21") - 1641 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-byte-operations/22") - 1642 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-byte-operations/23") - 1643 # . epilogue - 1644 89/<- %esp 5/r32/ebp - 1645 5d/pop-to-ebp - 1646 c3/return - 1647 - 1648 # variables of type 'byte' _can_ be function args. They then occupy 4 bytes. - 1649 test-copy-byte-var-from-fn-arg: - 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 x: byte, y: int {\n") - 1660 (write _test-input-stream " var a/eax: byte <- copy x\n") - 1661 (write _test-input-stream " var b/eax: int <- copy y\n") - 1662 (write _test-input-stream "}\n") - 1663 # convert - 1664 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1665 (flush _test-output-buffered-file) - 1666 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1672 # check output - 1673 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-copy-byte-from-fn-arg/0") - 1674 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-copy-byte-from-fn-arg/1") - 1675 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-copy-byte-from-fn-arg/2") - 1676 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-copy-byte-from-fn-arg/3") - 1677 (check-next-stream-line-equal _test-output-stream " {" "F - test-copy-byte-from-fn-arg/4") - 1678 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-copy-byte-from-fn-arg/5") - 1679 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-copy-byte-from-fn-arg/6") - 1680 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/7") - 1681 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x0000000c) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/8") - 1682 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-copy-byte-from-fn-arg/9") - 1683 (check-next-stream-line-equal _test-output-stream " }" "F - test-copy-byte-from-fn-arg/10") - 1684 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-copy-byte-from-fn-arg/11") - 1685 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-copy-byte-from-fn-arg/12") - 1686 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-copy-byte-from-fn-arg/13") - 1687 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-copy-byte-from-fn-arg/14") - 1688 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-copy-byte-from-fn-arg/15") - 1689 # . epilogue - 1690 89/<- %esp 5/r32/ebp - 1691 5d/pop-to-ebp - 1692 c3/return - 1693 - 1694 test-convert-compare-register-with-literal: - 1695 # . prologue - 1696 55/push-ebp - 1697 89/<- %ebp 4/r32/esp - 1698 # setup - 1699 (clear-stream _test-input-stream) - 1700 (clear-stream $_test-input-buffered-file->buffer) - 1701 (clear-stream _test-output-stream) - 1702 (clear-stream $_test-output-buffered-file->buffer) - 1703 # - 1704 (write _test-input-stream "fn foo {\n") - 1705 (write _test-input-stream " var x/ecx: int <- copy 0\n") - 1706 (write _test-input-stream " compare x, 0\n") - 1707 (write _test-input-stream "}\n") - 1708 # convert - 1709 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1710 (flush _test-output-buffered-file) - 1711 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1717 # check output - 1718 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-compare-register-with-literal/0") - 1719 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-compare-register-with-literal/1") - 1720 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-compare-register-with-literal/2") - 1721 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-compare-register-with-literal/3") - 1722 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-compare-register-with-literal/4") - 1723 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-compare-register-with-literal/5") - 1724 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") - 1725 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-compare-register-with-literal/7") - 1726 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0/imm32" "F - test-convert-compare-register-with-literal/8") - 1727 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") - 1728 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-compare-register-with-literal/10") - 1729 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-compare-register-with-literal/11") - 1730 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-compare-register-with-literal/12") - 1731 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-compare-register-with-literal/13") - 1732 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-compare-register-with-literal/14") - 1733 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-compare-register-with-literal/15") - 1734 # . epilogue - 1735 89/<- %esp 5/r32/ebp - 1736 5d/pop-to-ebp - 1737 c3/return - 1738 - 1739 test-unknown-variable: - 1740 # . prologue - 1741 55/push-ebp - 1742 89/<- %ebp 4/r32/esp - 1743 # setup - 1744 (clear-stream _test-input-stream) - 1745 (clear-stream $_test-input-buffered-file->buffer) - 1746 (clear-stream _test-output-stream) - 1747 (clear-stream $_test-output-buffered-file->buffer) - 1748 (clear-stream _test-error-stream) - 1749 (clear-stream $_test-error-buffered-file->buffer) - 1750 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1751 68/push 0/imm32 - 1752 68/push 0/imm32 - 1753 89/<- %edx 4/r32/esp - 1754 (tailor-exit-descriptor %edx 0x10) - 1755 # - 1756 (write _test-input-stream "fn foo {\n") - 1757 (write _test-input-stream " compare x, 0\n") - 1758 (write _test-input-stream "}\n") - 1759 # convert - 1760 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1761 # registers except esp clobbered at this point - 1762 # restore ed - 1763 89/<- %edx 4/r32/esp - 1764 (flush _test-output-buffered-file) - 1765 (flush _test-error-buffered-file) - 1766 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1772 # check output - 1773 (check-stream-equal _test-output-stream "" "F - test-unknown-variable: output should be empty") - 1774 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable: error message") - 1775 # check that stop(1) was called - 1776 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable: exit status") - 1777 # don't restore from ebp - 1778 81 0/subop/add %esp 8/imm32 - 1779 # . epilogue - 1780 5d/pop-to-ebp - 1781 c3/return - 1782 - 1783 test-convert-function-with-local-var-in-block: - 1784 # . prologue - 1785 55/push-ebp - 1786 89/<- %ebp 4/r32/esp - 1787 # setup - 1788 (clear-stream _test-input-stream) - 1789 (clear-stream $_test-input-buffered-file->buffer) - 1790 (clear-stream _test-output-stream) - 1791 (clear-stream $_test-output-buffered-file->buffer) - 1792 # - 1793 (write _test-input-stream "fn foo {\n") - 1794 (write _test-input-stream " {\n") - 1795 (write _test-input-stream " var x: int\n") - 1796 (write _test-input-stream " increment x\n") - 1797 (write _test-input-stream " }\n") - 1798 (write _test-input-stream "}\n") - 1799 # convert - 1800 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1801 (flush _test-output-buffered-file) - 1802 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1808 # check output - 1809 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-block/0") - 1810 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-block/1") - 1811 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-block/2") - 1812 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-block/3") - 1813 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/4") - 1814 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-block/5") - 1815 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/6") - 1816 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-local-var-in-block/7") - 1817 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-block/8") - 1818 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-block/9") - 1819 (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") - 1820 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/11") - 1821 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-local-var-in-block/12") - 1822 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/13") - 1823 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-block/14") - 1824 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-block/15") - 1825 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-block/16") - 1826 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-block/17") - 1827 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-block/18") - 1828 # . epilogue - 1829 89/<- %esp 5/r32/ebp - 1830 5d/pop-to-ebp - 1831 c3/return - 1832 - 1833 test-convert-function-with-local-var-in-named-block: - 1834 # . prologue - 1835 55/push-ebp - 1836 89/<- %ebp 4/r32/esp - 1837 # setup - 1838 (clear-stream _test-input-stream) - 1839 (clear-stream $_test-input-buffered-file->buffer) - 1840 (clear-stream _test-output-stream) - 1841 (clear-stream $_test-output-buffered-file->buffer) - 1842 # - 1843 (write _test-input-stream "fn foo {\n") - 1844 (write _test-input-stream " $bar: {\n") - 1845 (write _test-input-stream " var x: int\n") - 1846 (write _test-input-stream " increment x\n") - 1847 (write _test-input-stream " }\n") - 1848 (write _test-input-stream "}\n") - 1849 # convert - 1850 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1851 (flush _test-output-buffered-file) - 1852 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1858 # check output - 1859 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-named-block/0") - 1860 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-named-block/1") - 1861 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-named-block/2") - 1862 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-named-block/3") - 1863 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/4") - 1864 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-named-block/5") - 1865 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/6") - 1866 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-local-var-in-named-block/7") - 1867 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-named-block/8") - 1868 (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") - 1869 (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") - 1870 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/11") - 1871 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-local-var-in-named-block/12") - 1872 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/13") - 1873 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-named-block/14") - 1874 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-named-block/15") - 1875 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-named-block/16") - 1876 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-named-block/17") - 1877 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-named-block/18") - 1878 # . epilogue - 1879 89/<- %esp 5/r32/ebp - 1880 5d/pop-to-ebp - 1881 c3/return - 1882 - 1883 test-unknown-variable-in-named-block: - 1884 # . prologue - 1885 55/push-ebp - 1886 89/<- %ebp 4/r32/esp - 1887 # setup - 1888 (clear-stream _test-input-stream) - 1889 (clear-stream $_test-input-buffered-file->buffer) - 1890 (clear-stream _test-output-stream) - 1891 (clear-stream $_test-output-buffered-file->buffer) - 1892 (clear-stream _test-error-stream) - 1893 (clear-stream $_test-error-buffered-file->buffer) - 1894 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 1895 68/push 0/imm32 - 1896 68/push 0/imm32 - 1897 89/<- %edx 4/r32/esp - 1898 (tailor-exit-descriptor %edx 0x10) - 1899 # - 1900 (write _test-input-stream "fn foo {\n") - 1901 (write _test-input-stream " $a: {\n") - 1902 (write _test-input-stream " compare x, 0\n") - 1903 (write _test-input-stream " }\n") - 1904 (write _test-input-stream "}\n") - 1905 # convert - 1906 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 1907 # registers except esp clobbered at this point - 1908 # restore ed - 1909 89/<- %edx 4/r32/esp - 1910 (flush _test-output-buffered-file) - 1911 (flush _test-error-buffered-file) - 1912 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 1918 # check output - 1919 (check-stream-equal _test-output-stream "" "F - test-unknown-variable-in-named-block: output should be empty") - 1920 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable-in-named-block: error message") - 1921 # check that stop(1) was called - 1922 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable-in-named-block: exit status") - 1923 # don't restore from ebp - 1924 81 0/subop/add %esp 8/imm32 - 1925 # . epilogue - 1926 5d/pop-to-ebp - 1927 c3/return - 1928 - 1929 test-always-shadow-outermost-reg-vars-in-function: - 1930 # . prologue - 1931 55/push-ebp - 1932 89/<- %ebp 4/r32/esp - 1933 # setup - 1934 (clear-stream _test-input-stream) - 1935 (clear-stream $_test-input-buffered-file->buffer) - 1936 (clear-stream _test-output-stream) - 1937 (clear-stream $_test-output-buffered-file->buffer) - 1938 # - 1939 (write _test-input-stream "fn foo {\n") - 1940 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1941 (write _test-input-stream "}\n") - 1942 # convert - 1943 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1944 (flush _test-output-buffered-file) - 1945 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1951 # check output - 1952 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-always-shadow-outermost-reg-vars-in-function/0") - 1953 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-always-shadow-outermost-reg-vars-in-function/1") - 1954 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/2") - 1955 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-always-shadow-outermost-reg-vars-in-function/3") - 1956 (check-next-stream-line-equal _test-output-stream " {" "F - test-always-shadow-outermost-reg-vars-in-function/4") - 1957 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-always-shadow-outermost-reg-vars-in-function/5") - 1958 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") - 1959 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-always-shadow-outermost-reg-vars-in-function/8") - 1960 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") - 1961 (check-next-stream-line-equal _test-output-stream " }" "F - test-always-shadow-outermost-reg-vars-in-function/12") - 1962 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-always-shadow-outermost-reg-vars-in-function/13") - 1963 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-always-shadow-outermost-reg-vars-in-function/14") - 1964 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-always-shadow-outermost-reg-vars-in-function/15") - 1965 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/16") - 1966 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-always-shadow-outermost-reg-vars-in-function/17") - 1967 # . epilogue - 1968 89/<- %esp 5/r32/ebp - 1969 5d/pop-to-ebp - 1970 c3/return - 1971 - 1972 _pending-test-clobber-dead-local: - 1973 # . prologue - 1974 55/push-ebp - 1975 89/<- %ebp 4/r32/esp - 1976 # setup - 1977 (clear-stream _test-input-stream) - 1978 (clear-stream $_test-input-buffered-file->buffer) - 1979 (clear-stream _test-output-stream) - 1980 (clear-stream $_test-output-buffered-file->buffer) - 1981 # - 1982 (write _test-input-stream "fn foo {\n") - 1983 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 1984 (write _test-input-stream " {\n") - 1985 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 1986 (write _test-input-stream " }\n") - 1987 (write _test-input-stream "}\n") - 1988 # convert - 1989 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 1990 (flush _test-output-buffered-file) - 1991 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 1997 # check output - 1998 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-clobber-dead-local/0") - 1999 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-clobber-dead-local/1") - 2000 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-clobber-dead-local/2") - 2001 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-clobber-dead-local/3") - 2002 (check-next-stream-line-equal _test-output-stream " {" "F - test-clobber-dead-local/4") - 2003 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-clobber-dead-local/5") - 2004 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-clobber-dead-local/6") - 2005 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-clobber-dead-local/7") - 2006 (check-next-stream-line-equal _test-output-stream " {" "F - test-clobber-dead-local/8") - 2007 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-clobber-dead-local/9") - 2008 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-clobber-dead-local/10") # no push/pop here - 2009 (check-next-stream-line-equal _test-output-stream " }" "F - test-clobber-dead-local/11") - 2010 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-clobber-dead-local/12") - 2011 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-clobber-dead-local/13") - 2012 (check-next-stream-line-equal _test-output-stream " }" "F - test-clobber-dead-local/14") - 2013 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-clobber-dead-local/15") - 2014 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-clobber-dead-local/16") - 2015 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-clobber-dead-local/17") - 2016 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-clobber-dead-local/18") - 2017 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-clobber-dead-local/19") - 2018 # . epilogue - 2019 89/<- %esp 5/r32/ebp - 2020 5d/pop-to-ebp - 2021 c3/return - 2022 - 2023 test-shadow-live-local: - 2024 # . prologue - 2025 55/push-ebp - 2026 89/<- %ebp 4/r32/esp - 2027 # setup - 2028 (clear-stream _test-input-stream) - 2029 (clear-stream $_test-input-buffered-file->buffer) - 2030 (clear-stream _test-output-stream) - 2031 (clear-stream $_test-output-buffered-file->buffer) - 2032 # - 2033 (write _test-input-stream "fn foo {\n") - 2034 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2035 (write _test-input-stream " {\n") - 2036 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2037 (write _test-input-stream " }\n") - 2038 (write _test-input-stream " x <- increment\n") - 2039 (write _test-input-stream "}\n") - 2040 # convert - 2041 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2042 (flush _test-output-buffered-file) - 2043 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2049 # check output - 2050 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-live-local/0") - 2051 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-live-local/1") - 2052 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-live-local/2") - 2053 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-live-local/3") - 2054 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-local/4") - 2055 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-live-local/5") - 2056 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-local/6") - 2057 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-live-local/7") - 2058 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-local/8") - 2059 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-live-local/9") - 2060 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-local/10") - 2061 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-live-local/11") - 2062 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-local/12") - 2063 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-local/13") - 2064 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-live-local/14") - 2065 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-live-local/15") - 2066 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-local/16") - 2067 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-local/17") - 2068 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-live-local/18") - 2069 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-live-local/19") - 2070 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-live-local/20") - 2071 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-live-local/21") - 2072 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-live-local/22") - 2073 # . epilogue - 2074 89/<- %esp 5/r32/ebp - 2075 5d/pop-to-ebp - 2076 c3/return - 2077 - 2078 test-shadow-name: - 2079 # . prologue - 2080 55/push-ebp - 2081 89/<- %ebp 4/r32/esp - 2082 # setup - 2083 (clear-stream _test-input-stream) - 2084 (clear-stream $_test-input-buffered-file->buffer) - 2085 (clear-stream _test-output-stream) - 2086 (clear-stream $_test-output-buffered-file->buffer) - 2087 # - 2088 (write _test-input-stream "fn foo {\n") - 2089 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2090 (write _test-input-stream " {\n") - 2091 (write _test-input-stream " var x/edx: int <- copy 4\n") - 2092 (write _test-input-stream " }\n") - 2093 (write _test-input-stream " x <- increment\n") - 2094 (write _test-input-stream "}\n") - 2095 # convert - 2096 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2097 (flush _test-output-buffered-file) - 2098 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2104 # check output - 2105 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name/0") - 2106 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name/1") - 2107 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name/2") - 2108 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name/3") - 2109 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/4") - 2110 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name/5") - 2111 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name/6") - 2112 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name/7") - 2113 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/8") - 2114 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name/9") - 2115 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name/10") - 2116 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name/11") - 2117 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name/12") - 2118 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/13") - 2119 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name/14") - 2120 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name/15") - 2121 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name/16") - 2122 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/17") - 2123 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name/18") - 2124 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name/19") - 2125 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name/20") - 2126 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name/21") - 2127 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name/22") - 2128 # . epilogue - 2129 89/<- %esp 5/r32/ebp - 2130 5d/pop-to-ebp - 2131 c3/return - 2132 - 2133 test-shadow-name-2: - 2134 # . prologue - 2135 55/push-ebp - 2136 89/<- %ebp 4/r32/esp - 2137 # setup - 2138 (clear-stream _test-input-stream) - 2139 (clear-stream $_test-input-buffered-file->buffer) - 2140 (clear-stream _test-output-stream) - 2141 (clear-stream $_test-output-buffered-file->buffer) - 2142 # - 2143 (write _test-input-stream "fn foo {\n") - 2144 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2145 (write _test-input-stream " {\n") - 2146 (write _test-input-stream " var x/edx: int <- copy 4\n") - 2147 (write _test-input-stream " var y/ecx: int <- copy 5\n") - 2148 (write _test-input-stream " }\n") - 2149 (write _test-input-stream " x <- increment\n") - 2150 (write _test-input-stream "}\n") - 2151 # convert - 2152 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2153 (flush _test-output-buffered-file) - 2154 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2160 # check output - 2161 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name-2/0") - 2162 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name-2/1") - 2163 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name-2/2") - 2164 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name-2/3") - 2165 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/4") - 2166 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name-2/5") - 2167 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/6") - 2168 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name-2/7") - 2169 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/8") - 2170 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name-2/9") - 2171 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name-2/10") - 2172 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name-2/11") - 2173 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/12") - 2174 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 5/imm32" "F - test-shadow-name-2/13") - 2175 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/14") - 2176 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name-2/15") - 2177 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/16") - 2178 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name-2/17") - 2179 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name-2/18") - 2180 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/19") - 2181 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/20") - 2182 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name-2/21") - 2183 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name-2/22") - 2184 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name-2/23") - 2185 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name-2/24") - 2186 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name-2/25") - 2187 # . epilogue - 2188 89/<- %esp 5/r32/ebp - 2189 5d/pop-to-ebp - 2190 c3/return - 2191 - 2192 test-do-not-spill-same-register-in-block: - 2193 # . prologue - 2194 55/push-ebp - 2195 89/<- %ebp 4/r32/esp - 2196 # setup - 2197 (clear-stream _test-input-stream) - 2198 (clear-stream $_test-input-buffered-file->buffer) - 2199 (clear-stream _test-output-stream) - 2200 (clear-stream $_test-output-buffered-file->buffer) - 2201 # - 2202 (write _test-input-stream "fn foo {\n") - 2203 (write _test-input-stream " var x/ecx: int <- copy 3\n") - 2204 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2205 (write _test-input-stream " y <- increment\n") - 2206 (write _test-input-stream "}\n") - 2207 # convert - 2208 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2209 (flush _test-output-buffered-file) - 2210 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2216 # check output - 2217 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-do-not-spill-same-register-in-block/0") - 2218 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-do-not-spill-same-register-in-block/1") - 2219 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-do-not-spill-same-register-in-block/2") - 2220 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-do-not-spill-same-register-in-block/3") - 2221 (check-next-stream-line-equal _test-output-stream " {" "F - test-do-not-spill-same-register-in-block/4") - 2222 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-do-not-spill-same-register-in-block/5") - 2223 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-do-not-spill-same-register-in-block/6") - 2224 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-do-not-spill-same-register-in-block/7") - 2225 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-do-not-spill-same-register-in-block/8") - 2226 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-do-not-spill-same-register-in-block/9") - 2227 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-do-not-spill-same-register-in-block/10") - 2228 (check-next-stream-line-equal _test-output-stream " }" "F - test-do-not-spill-same-register-in-block/11") - 2229 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-do-not-spill-same-register-in-block/12") - 2230 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-do-not-spill-same-register-in-block/13") - 2231 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-do-not-spill-same-register-in-block/14") - 2232 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-do-not-spill-same-register-in-block/15") - 2233 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-do-not-spill-same-register-in-block/16") - 2234 # . epilogue - 2235 89/<- %esp 5/r32/ebp - 2236 5d/pop-to-ebp - 2237 c3/return - 2238 - 2239 test-spill-different-register-in-block: - 2240 # . prologue - 2241 55/push-ebp - 2242 89/<- %ebp 4/r32/esp - 2243 # setup - 2244 (clear-stream _test-input-stream) - 2245 (clear-stream $_test-input-buffered-file->buffer) - 2246 (clear-stream _test-output-stream) - 2247 (clear-stream $_test-output-buffered-file->buffer) - 2248 # - 2249 (write _test-input-stream "fn foo {\n") - 2250 (write _test-input-stream " var x/eax: int <- copy 3\n") - 2251 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2252 (write _test-input-stream " y <- increment\n") - 2253 (write _test-input-stream "}\n") - 2254 # convert - 2255 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2256 (flush _test-output-buffered-file) - 2257 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2263 # check output - 2264 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-spill-different-register-in-block/0") - 2265 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-spill-different-register-in-block/1") - 2266 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-spill-different-register-in-block/2") - 2267 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-spill-different-register-in-block/3") - 2268 (check-next-stream-line-equal _test-output-stream " {" "F - test-spill-different-register-in-block/4") - 2269 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-spill-different-register-in-block/5") - 2270 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-spill-different-register-in-block/6") - 2271 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-spill-different-register-in-block/7") - 2272 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-spill-different-register-in-block/8") - 2273 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-spill-different-register-in-block/9") - 2274 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-spill-different-register-in-block/10") - 2275 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-spill-different-register-in-block/11") - 2276 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-spill-different-register-in-block/12") - 2277 (check-next-stream-line-equal _test-output-stream " }" "F - test-spill-different-register-in-block/13") - 2278 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-spill-different-register-in-block/14") - 2279 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-spill-different-register-in-block/15") - 2280 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-spill-different-register-in-block/16") - 2281 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-spill-different-register-in-block/17") - 2282 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-spill-different-register-in-block/18") - 2283 # . epilogue - 2284 89/<- %esp 5/r32/ebp - 2285 5d/pop-to-ebp - 2286 c3/return - 2287 - 2288 test-shadow-live-output: - 2289 # . prologue - 2290 55/push-ebp - 2291 89/<- %ebp 4/r32/esp - 2292 # setup - 2293 (clear-stream _test-input-stream) - 2294 (clear-stream $_test-input-buffered-file->buffer) - 2295 (clear-stream _test-output-stream) - 2296 (clear-stream $_test-output-buffered-file->buffer) - 2297 # - 2298 (write _test-input-stream "fn foo -> x/ecx: int {\n") - 2299 (write _test-input-stream " x <- copy 3\n") - 2300 (write _test-input-stream " {\n") - 2301 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2302 (write _test-input-stream " }\n") - 2303 (write _test-input-stream " x <- increment\n") - 2304 (write _test-input-stream "}\n") - 2305 # convert - 2306 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2307 (flush _test-output-buffered-file) - 2308 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2314 # check output - 2315 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-live-output/0") - 2316 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-live-output/1") - 2317 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-live-output/2") - 2318 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-live-output/3") - 2319 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-output/4") - 2320 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-live-output/5") - 2321 (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 - 2322 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-output/8") - 2323 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-live-output/9") - 2324 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-output/10") - 2325 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-live-output/11") - 2326 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-output/12") - 2327 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-output/13") - 2328 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-live-output/14") - 2329 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-live-output/15") - 2330 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-output/17") - 2331 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-live-output/18") - 2332 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-live-output/19") - 2333 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-live-output/20") - 2334 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-live-output/21") - 2335 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-live-output/21") - 2336 # . epilogue - 2337 89/<- %esp 5/r32/ebp - 2338 5d/pop-to-ebp - 2339 c3/return - 2340 - 2341 test-stmt-defines-output-in-same-register-as-inout: - 2342 # . prologue - 2343 55/push-ebp - 2344 89/<- %ebp 4/r32/esp - 2345 # setup - 2346 (clear-stream _test-input-stream) - 2347 (clear-stream $_test-input-buffered-file->buffer) - 2348 (clear-stream _test-output-stream) - 2349 (clear-stream $_test-output-buffered-file->buffer) - 2350 (clear-stream _test-error-stream) - 2351 (clear-stream $_test-error-buffered-file->buffer) - 2352 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 2353 68/push 0/imm32 - 2354 68/push 0/imm32 - 2355 89/<- %edx 4/r32/esp - 2356 (tailor-exit-descriptor %edx 0x10) - 2357 # - 2358 (write _test-input-stream "fn foo -> x/ecx: int {\n") - 2359 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2360 (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 - 2361 (write _test-input-stream "}\n") - 2362 # convert - 2363 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 2364 # registers except esp clobbered at this point - 2365 # restore ed - 2366 89/<- %edx 4/r32/esp - 2367 (flush _test-output-buffered-file) - 2368 (flush _test-error-buffered-file) - 2369 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2375 # no error; we looked up 'y' correctly before pushing the binding for 'x' - 2376 (check-stream-equal _test-error-stream "" "F - test-stmt-defines-output-in-same-register-as-inout: error stream should be empty") - 2377 # don't bother checking the generated code; that's in the test 'test-local-clobbered-by-fn-output' below - 2378 # don't restore from ebp - 2379 81 0/subop/add %esp 8/imm32 - 2380 # . epilogue - 2381 5d/pop-to-ebp - 2382 c3/return - 2383 - 2384 test-local-clobbered-by-fn-output: - 2385 # . prologue - 2386 55/push-ebp - 2387 89/<- %ebp 4/r32/esp - 2388 # setup - 2389 (clear-stream _test-input-stream) - 2390 (clear-stream $_test-input-buffered-file->buffer) - 2391 (clear-stream _test-output-stream) - 2392 (clear-stream $_test-output-buffered-file->buffer) - 2393 # - 2394 (write _test-input-stream "fn foo -> x/ecx: int {\n") - 2395 (write _test-input-stream " var y/ecx: int <- copy 4\n") - 2396 (write _test-input-stream " x <- copy y\n") - 2397 (write _test-input-stream "}\n") - 2398 # convert - 2399 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2400 (flush _test-output-buffered-file) - 2401 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2407 # check output - 2408 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-local-clobbered-by-fn-output/0") - 2409 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-local-clobbered-by-fn-output/1") - 2410 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-local-clobbered-by-fn-output/2") - 2411 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-local-clobbered-by-fn-output/3") - 2412 (check-next-stream-line-equal _test-output-stream " {" "F - test-local-clobbered-by-fn-output/4") - 2413 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-local-clobbered-by-fn-output/5") - 2414 (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 - 2415 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0x00000001/r32" "F - test-local-clobbered-by-fn-output/7") - 2416 (check-next-stream-line-equal _test-output-stream " }" "F - test-local-clobbered-by-fn-output/8") - 2417 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-local-clobbered-by-fn-output/9") - 2418 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-local-clobbered-by-fn-output/10") - 2419 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-local-clobbered-by-fn-output/11") - 2420 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-local-clobbered-by-fn-output/12") - 2421 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-local-clobbered-by-fn-output/13") - 2422 # . epilogue - 2423 89/<- %esp 5/r32/ebp - 2424 5d/pop-to-ebp - 2425 c3/return - 2426 - 2427 test-read-output: - 2428 # . prologue - 2429 55/push-ebp - 2430 89/<- %ebp 4/r32/esp - 2431 # setup - 2432 (clear-stream _test-input-stream) - 2433 (clear-stream $_test-input-buffered-file->buffer) - 2434 (clear-stream _test-output-stream) - 2435 (clear-stream $_test-output-buffered-file->buffer) - 2436 # - 2437 (write _test-input-stream "fn foo -> x/ecx: int {\n") - 2438 (write _test-input-stream " x <- copy 0x34\n") - 2439 (write _test-input-stream " compare x, 0x35\n") - 2440 (write _test-input-stream "}\n") - 2441 # convert - 2442 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2443 (flush _test-output-buffered-file) - 2444 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2450 # check output - 2451 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-read-output/0") - 2452 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-read-output/1") - 2453 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-read-output/2") - 2454 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-read-output/3") - 2455 (check-next-stream-line-equal _test-output-stream " {" "F - test-read-output/4") - 2456 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-read-output/5") - 2457 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x34/imm32" "F - test-read-output/6") - 2458 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0x35/imm32" "F - test-read-output/7") - 2459 (check-next-stream-line-equal _test-output-stream " }" "F - test-read-output/8") - 2460 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-read-output/9") - 2461 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-read-output/10") - 2462 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-read-output/11") - 2463 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-read-output/12") - 2464 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-read-output/13") - 2465 # . epilogue - 2466 89/<- %esp 5/r32/ebp - 2467 5d/pop-to-ebp - 2468 c3/return - 2469 - 2470 test-fn-output-written-in-inner-block: - 2471 # . prologue - 2472 55/push-ebp - 2473 89/<- %ebp 4/r32/esp - 2474 # setup - 2475 (clear-stream _test-input-stream) - 2476 (clear-stream $_test-input-buffered-file->buffer) - 2477 (clear-stream _test-output-stream) - 2478 (clear-stream $_test-output-buffered-file->buffer) - 2479 # - 2480 (write _test-input-stream "fn foo -> out/edi: int {\n") - 2481 (write _test-input-stream " var a/eax: int <- copy 3\n") # define outer local - 2482 (write _test-input-stream " {\n") - 2483 (write _test-input-stream " var a/ecx: int <- copy 4\n") # shadow outer local - 2484 (write _test-input-stream " out <- copy a\n") # write to fn output - 2485 (write _test-input-stream " }\n") - 2486 (write _test-input-stream " compare a, 0\n") # use outer local - 2487 (write _test-input-stream "}\n") - 2488 # convert - 2489 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2490 (flush _test-output-buffered-file) - 2491 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2497 # no error; defining 'out' didn't interfere with the reclamation of 'b' - 2498 # check output - 2499 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-fn-output-written-in-inner-block/0") - 2500 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-fn-output-written-in-inner-block/1") - 2501 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-fn-output-written-in-inner-block/2") - 2502 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-fn-output-written-in-inner-block/3") - 2503 (check-next-stream-line-equal _test-output-stream " {" "F - test-fn-output-written-in-inner-block/4") - 2504 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-fn-output-written-in-inner-block/5") - 2505 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-fn-output-written-in-inner-block/6") - 2506 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-fn-output-written-in-inner-block/7") - 2507 (check-next-stream-line-equal _test-output-stream " {" "F - test-fn-output-written-in-inner-block/8") - 2508 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-fn-output-written-in-inner-block/9") - 2509 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-fn-output-written-in-inner-block/10") - 2510 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-fn-output-written-in-inner-block/10") - 2511 (check-next-stream-line-equal _test-output-stream " 89/<- %edi 0x00000001/r32" "F - test-fn-output-written-in-inner-block/11") - 2512 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-fn-output-written-in-inner-block/12") - 2513 (check-next-stream-line-equal _test-output-stream " }" "F - test-fn-output-written-in-inner-block/13") - 2514 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-fn-output-written-in-inner-block/14") - 2515 (check-next-stream-line-equal _test-output-stream " 3d/compare-eax-with 0/imm32" "F - test-fn-output-written-in-inner-block/15") - 2516 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-fn-output-written-in-inner-block/16") - 2517 (check-next-stream-line-equal _test-output-stream " }" "F - test-fn-output-written-in-inner-block/17") - 2518 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-fn-output-written-in-inner-block/18") - 2519 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-fn-output-written-in-inner-block/19") - 2520 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-fn-output-written-in-inner-block/20") - 2521 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-fn-output-written-in-inner-block/21") - 2522 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-fn-output-written-in-inner-block/22") - 2523 # . epilogue - 2524 89/<- %esp 5/r32/ebp - 2525 5d/pop-to-ebp - 2526 c3/return - 2527 - 2528 test-convert-function-with-branches-in-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 x: int {\n") - 2539 (write _test-input-stream " {\n") - 2540 (write _test-input-stream " break-if->=\n") - 2541 (write _test-input-stream " loop-if-addr<\n") - 2542 (write _test-input-stream " increment x\n") - 2543 (write _test-input-stream " loop\n") - 2544 (write _test-input-stream " }\n") - 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 # check output - 2556 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-block/0") - 2557 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1") - 2558 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2") - 2559 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3") - 2560 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4") - 2561 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5") - 2562 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6") - 2563 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7") - 2564 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/8") - 2565 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-block/9") - 2566 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-in-block/10") - 2567 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/11") - 2568 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/12") - 2569 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-block/13") - 2570 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-branches-in-block/14") - 2571 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/15") - 2572 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/16") - 2573 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/17") - 2574 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/18") - 2575 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/19") - 2576 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/20") - 2577 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/21") - 2578 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/22") - 2579 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/23") - 2580 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/24") - 2581 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/25") - 2582 # . epilogue - 2583 89/<- %esp 5/r32/ebp - 2584 5d/pop-to-ebp - 2585 c3/return - 2586 - 2587 test-convert-function-with-branches-in-named-block: - 2588 # . prologue - 2589 55/push-ebp - 2590 89/<- %ebp 4/r32/esp - 2591 # setup - 2592 (clear-stream _test-input-stream) - 2593 (clear-stream $_test-input-buffered-file->buffer) - 2594 (clear-stream _test-output-stream) - 2595 (clear-stream $_test-output-buffered-file->buffer) - 2596 # - 2597 (write _test-input-stream "fn foo x: int {\n") - 2598 (write _test-input-stream " $bar: {\n") - 2599 (write _test-input-stream " break-if->= $bar\n") - 2600 (write _test-input-stream " loop-if-addr< $bar\n") - 2601 (write _test-input-stream " increment x\n") - 2602 (write _test-input-stream " loop\n") - 2603 (write _test-input-stream " }\n") - 2604 (write _test-input-stream "}\n") - 2605 # convert - 2606 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2607 (flush _test-output-buffered-file) - 2608 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2614 # check output - 2615 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-named-block/0") - 2616 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-named-block/1") - 2617 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-named-block/2") - 2618 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-named-block/3") - 2619 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/4") - 2620 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-named-block/5") - 2621 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/6") - 2622 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-branches-in-named-block/7") - 2623 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/8") - 2624 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-named-block/9") - 2625 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:break/disp32" "F - test-convert-function-with-branches-in-named-block/10") - 2626 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/11") - 2627 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/12") - 2628 (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") - 2629 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:loop/disp32" "F - test-convert-function-with-branches-in-named-block/14") - 2630 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/15") - 2631 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-named-block/16") - 2632 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-named-block/17") - 2633 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/18") - 2634 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-branches-in-named-block/19") - 2635 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/20") - 2636 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-named-block/21") - 2637 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-named-block/22") - 2638 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-named-block/23") - 2639 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-named-block/24") - 2640 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-named-block/25") - 2641 # . epilogue - 2642 89/<- %esp 5/r32/ebp - 2643 5d/pop-to-ebp - 2644 c3/return - 2645 - 2646 test-convert-function-with-var-in-nested-block: - 2647 # . prologue - 2648 55/push-ebp - 2649 89/<- %ebp 4/r32/esp - 2650 # setup - 2651 (clear-stream _test-input-stream) - 2652 (clear-stream $_test-input-buffered-file->buffer) - 2653 (clear-stream _test-output-stream) - 2654 (clear-stream $_test-output-buffered-file->buffer) - 2655 # - 2656 (write _test-input-stream "fn foo x: int {\n") - 2657 (write _test-input-stream " {\n") - 2658 (write _test-input-stream " {\n") - 2659 (write _test-input-stream " var x: int\n") - 2660 (write _test-input-stream " increment x\n") - 2661 (write _test-input-stream " }\n") - 2662 (write _test-input-stream " }\n") - 2663 (write _test-input-stream "}\n") - 2664 # convert - 2665 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2666 (flush _test-output-buffered-file) - 2667 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2673 # check output - 2674 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-var-in-nested-block/0") - 2675 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-var-in-nested-block/1") - 2676 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-var-in-nested-block/2") - 2677 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-var-in-nested-block/3") - 2678 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/4") - 2679 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-var-in-nested-block/5") - 2680 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/6") - 2681 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-var-in-nested-block/7") - 2682 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/8") - 2683 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-var-in-nested-block/9") - 2684 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-var-in-nested-block/10") - 2685 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-var-in-nested-block/11") - 2686 (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") - 2687 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/13") - 2688 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-var-in-nested-block/14") - 2689 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/15") - 2690 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-var-in-nested-block/16") - 2691 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/17") - 2692 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-var-in-nested-block/18") - 2693 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-var-in-nested-block/19") - 2694 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-var-in-nested-block/20") - 2695 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-var-in-nested-block/21") - 2696 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-var-in-nested-block/22") - 2697 # . epilogue - 2698 89/<- %esp 5/r32/ebp - 2699 5d/pop-to-ebp - 2700 c3/return - 2701 - 2702 test-convert-function-with-multiple-vars-in-nested-blocks: - 2703 # . prologue - 2704 55/push-ebp - 2705 89/<- %ebp 4/r32/esp - 2706 # setup - 2707 (clear-stream _test-input-stream) - 2708 (clear-stream $_test-input-buffered-file->buffer) - 2709 (clear-stream _test-output-stream) - 2710 (clear-stream $_test-output-buffered-file->buffer) - 2711 # - 2712 (write _test-input-stream "fn foo x: int {\n") - 2713 (write _test-input-stream " {\n") - 2714 (write _test-input-stream " var x/eax: int <- copy 0\n") - 2715 (write _test-input-stream " {\n") - 2716 (write _test-input-stream " var y: int\n") - 2717 (write _test-input-stream " x <- add y\n") - 2718 (write _test-input-stream " }\n") - 2719 (write _test-input-stream " }\n") - 2720 (write _test-input-stream "}\n") - 2721 # convert - 2722 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2723 (flush _test-output-buffered-file) - 2724 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2730 # check output - 2731 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/0") - 2732 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/1") - 2733 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/2") - 2734 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/3") - 2735 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/4") - 2736 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/5") - 2737 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/6") - 2738 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/7") - 2739 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/8") - 2740 (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") - 2741 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/10") - 2742 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/11") - 2743 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/12") - 2744 (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") - 2745 (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") - 2746 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/15") - 2747 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/16") - 2748 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/17") - 2749 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/18") - 2750 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/19") - 2751 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/20") - 2752 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/21") - 2753 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/22") - 2754 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/23") - 2755 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/24") - 2756 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-multiple-vars-in-nested-blocks/25") - 2757 # . epilogue - 2758 89/<- %esp 5/r32/ebp - 2759 5d/pop-to-ebp - 2760 c3/return - 2761 - 2762 test-convert-function-with-branches-and-local-vars: - 2763 # A conditional 'break' after a 'var' in a block is converted into a - 2764 # nested block that performs all necessary cleanup before jumping. This - 2765 # results in some ugly code duplication. - 2766 # . prologue - 2767 55/push-ebp - 2768 89/<- %ebp 4/r32/esp - 2769 # setup - 2770 (clear-stream _test-input-stream) - 2771 (clear-stream $_test-input-buffered-file->buffer) - 2772 (clear-stream _test-output-stream) - 2773 (clear-stream $_test-output-buffered-file->buffer) - 2774 # - 2775 (write _test-input-stream "fn foo {\n") - 2776 (write _test-input-stream " {\n") - 2777 (write _test-input-stream " var x: int\n") - 2778 (write _test-input-stream " break-if->=\n") - 2779 (write _test-input-stream " increment x\n") - 2780 (write _test-input-stream " }\n") - 2781 (write _test-input-stream "}\n") - 2782 # convert - 2783 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2784 (flush _test-output-buffered-file) - 2785 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2791 # check output - 2792 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-local-vars/0") - 2793 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-local-vars/1") - 2794 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-local-vars/2") - 2795 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-local-vars/3") - 2796 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/4") - 2797 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-local-vars/5") - 2798 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/6") - 2799 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-local-vars/7") - 2800 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-local-vars/8") - 2801 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/9") - 2802 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-local-vars/10") - 2803 (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") - 2804 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-local-vars/12") - 2805 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/13") - 2806 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-local-vars/14") - 2807 (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") - 2808 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/16") - 2809 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-local-vars/17") - 2810 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/18") - 2811 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-local-vars/19") - 2812 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-local-vars/20") - 2813 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-local-vars/21") - 2814 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-local-vars/22") - 2815 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-local-vars/23") - 2816 # . epilogue - 2817 89/<- %esp 5/r32/ebp - 2818 5d/pop-to-ebp - 2819 c3/return - 2820 - 2821 test-convert-function-with-conditional-loops-and-local-vars: - 2822 # A conditional 'loop' after a 'var' in a block is converted into a nested - 2823 # block that performs all necessary cleanup before jumping. This results - 2824 # in some ugly code duplication. - 2825 # . prologue - 2826 55/push-ebp - 2827 89/<- %ebp 4/r32/esp - 2828 # setup - 2829 (clear-stream _test-input-stream) - 2830 (clear-stream $_test-input-buffered-file->buffer) - 2831 (clear-stream _test-output-stream) - 2832 (clear-stream $_test-output-buffered-file->buffer) - 2833 # - 2834 (write _test-input-stream "fn foo {\n") - 2835 (write _test-input-stream " {\n") - 2836 (write _test-input-stream " var x: int\n") - 2837 (write _test-input-stream " loop-if->=\n") - 2838 (write _test-input-stream " increment x\n") - 2839 (write _test-input-stream " }\n") - 2840 (write _test-input-stream "}\n") - 2841 # convert - 2842 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2843 (flush _test-output-buffered-file) - 2844 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2850 # check output - 2851 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-conditional-loops-and-local-vars/0") - 2852 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-conditional-loops-and-local-vars/1") - 2853 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/2") - 2854 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-conditional-loops-and-local-vars/3") - 2855 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/4") - 2856 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/5") - 2857 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/6") - 2858 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/7") - 2859 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/8") - 2860 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/9") - 2861 (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") - 2862 (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") - 2863 (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") - 2864 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/13") - 2865 (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") - 2866 (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") - 2867 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/16") - 2868 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/17") - 2869 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/18") - 2870 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/19") - 2871 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-conditional-loops-and-local-vars/20") - 2872 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/21") - 2873 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/22") - 2874 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-conditional-loops-and-local-vars/23") - 2875 # . epilogue - 2876 89/<- %esp 5/r32/ebp - 2877 5d/pop-to-ebp - 2878 c3/return - 2879 - 2880 test-convert-function-with-unconditional-loops-and-local-vars: - 2881 # An unconditional 'loop' after a 'var' in a block is emitted _after_ the - 2882 # regular block cleanup. Any instructions after 'loop' are dead and - 2883 # therefore skipped. - 2884 # . prologue - 2885 55/push-ebp - 2886 89/<- %ebp 4/r32/esp - 2887 # setup - 2888 (clear-stream _test-input-stream) - 2889 (clear-stream $_test-input-buffered-file->buffer) - 2890 (clear-stream _test-output-stream) - 2891 (clear-stream $_test-output-buffered-file->buffer) - 2892 # - 2893 (write _test-input-stream "fn foo {\n") - 2894 (write _test-input-stream " {\n") - 2895 (write _test-input-stream " var x: int\n") - 2896 (write _test-input-stream " loop\n") - 2897 (write _test-input-stream " increment x\n") - 2898 (write _test-input-stream " }\n") - 2899 (write _test-input-stream "}\n") - 2900 # convert - 2901 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2902 (flush _test-output-buffered-file) - 2903 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2909 # check output - 2910 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-loops-and-local-vars/0") - 2911 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-loops-and-local-vars/1") - 2912 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/2") - 2913 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-loops-and-local-vars/3") - 2914 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/4") - 2915 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/5") - 2916 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/6") - 2917 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/7") - 2918 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/8") - 2919 (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") - 2920 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-unconditional-loops-and-local-vars/10") - 2921 # not emitted: ff 0/subop/increment *(ebp+0xfffffffc) - 2922 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/11") - 2923 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/12") - 2924 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/13") - 2925 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/14") - 2926 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-loops-and-local-vars/15") - 2927 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/16") - 2928 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/17") - 2929 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-loops-and-local-vars/18") - 2930 # . epilogue - 2931 89/<- %esp 5/r32/ebp - 2932 5d/pop-to-ebp - 2933 c3/return - 2934 - 2935 test-convert-function-with-branches-and-loops-and-local-vars: - 2936 # . prologue - 2937 55/push-ebp - 2938 89/<- %ebp 4/r32/esp - 2939 # setup - 2940 (clear-stream _test-input-stream) - 2941 (clear-stream $_test-input-buffered-file->buffer) - 2942 (clear-stream _test-output-stream) - 2943 (clear-stream $_test-output-buffered-file->buffer) - 2944 # - 2945 (write _test-input-stream "fn foo {\n") - 2946 (write _test-input-stream " {\n") - 2947 (write _test-input-stream " var x: int\n") - 2948 (write _test-input-stream " break-if->=\n") - 2949 (write _test-input-stream " increment x\n") - 2950 (write _test-input-stream " loop\n") - 2951 (write _test-input-stream " }\n") - 2952 (write _test-input-stream "}\n") - 2953 # convert - 2954 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 2955 (flush _test-output-buffered-file) - 2956 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 2962 # check output - 2963 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-loops-and-local-vars/0") - 2964 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-loops-and-local-vars/1") - 2965 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/2") - 2966 (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") - 2967 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/4") - 2968 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/5") - 2969 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/6") - 2970 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/7") - 2971 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/8") - 2972 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/9") - 2973 (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") - 2974 (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") - 2975 (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") - 2976 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/13") - 2977 (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") - 2978 (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") - 2979 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/16") - 2980 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/17") - 2981 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/18") - 2982 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/19") - 2983 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/20") - 2984 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-loops-and-local-vars/21") - 2985 (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") - 2986 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/23") - 2987 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-loops-and-local-vars/24") - 2988 # . epilogue - 2989 89/<- %esp 5/r32/ebp - 2990 5d/pop-to-ebp - 2991 c3/return - 2992 - 2993 test-convert-function-with-nonlocal-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 " a: {\n") - 3005 (write _test-input-stream " var x: int\n") - 3006 (write _test-input-stream " {\n") - 3007 (write _test-input-stream " var y: int\n") - 3008 (write _test-input-stream " break-if->= a\n") - 3009 (write _test-input-stream " increment x\n") - 3010 (write _test-input-stream " loop\n") - 3011 (write _test-input-stream " }\n") - 3012 (write _test-input-stream " }\n") - 3013 (write _test-input-stream "}\n") - 3014 # convert - 3015 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3016 (flush _test-output-buffered-file) - 3017 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3023 # check output - 3024 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/0") - 3025 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/1") - 3026 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/2") - 3027 (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") - 3028 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/4") - 3029 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/5") - 3030 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/6") - 3031 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/7") - 3032 (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") - 3033 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/9") - 3034 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/10") - 3035 (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") - 3036 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/12") - 3037 (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") - 3038 (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") - 3039 (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") - 3040 (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") - 3041 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/17") - 3042 (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") - 3043 (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") - 3044 (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") - 3045 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/21") - 3046 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/22") - 3047 (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") - 3048 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/24") - 3049 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/25") - 3050 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/26") - 3051 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/27") - 3052 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/28") - 3053 (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") - 3054 (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") - 3055 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/31") - 3056 # . epilogue - 3057 89/<- %esp 5/r32/ebp - 3058 5d/pop-to-ebp - 3059 c3/return - 3060 - 3061 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2: - 3062 # . prologue - 3063 55/push-ebp - 3064 89/<- %ebp 4/r32/esp - 3065 # setup - 3066 (clear-stream _test-input-stream) - 3067 (clear-stream $_test-input-buffered-file->buffer) - 3068 (clear-stream _test-output-stream) - 3069 (clear-stream $_test-output-buffered-file->buffer) - 3070 # non-local conditional branch from a block without a local variable, - 3071 # unwinding a local on the stack - 3072 (write _test-input-stream "fn foo {\n") - 3073 (write _test-input-stream " a: {\n") - 3074 (write _test-input-stream " var x: int\n") - 3075 (write _test-input-stream " {\n") - 3076 (write _test-input-stream " break-if->= a\n") - 3077 (write _test-input-stream " }\n") - 3078 (write _test-input-stream " }\n") - 3079 (write _test-input-stream "}\n") - 3080 # convert - 3081 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3082 (flush _test-output-buffered-file) - 3083 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3089 # check output - 3090 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/0") - 3091 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/1") - 3092 (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") - 3093 (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") - 3094 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/4") - 3095 (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") - 3096 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/6") - 3097 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/7") - 3098 (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") - 3099 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/9") - 3100 (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") - 3101 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/11") - 3102 (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") - 3103 (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") - 3104 (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") - 3105 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/15") - 3106 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/16") - 3107 (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") - 3108 (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") - 3109 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/19") - 3110 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/20") - 3111 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/21") - 3112 (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") - 3113 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/23") - 3114 (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") - 3115 (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") - 3116 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/26") - 3117 # . epilogue - 3118 89/<- %esp 5/r32/ebp - 3119 5d/pop-to-ebp - 3120 c3/return - 3121 - 3122 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3: - 3123 # . prologue - 3124 55/push-ebp - 3125 89/<- %ebp 4/r32/esp - 3126 # setup - 3127 (clear-stream _test-input-stream) - 3128 (clear-stream $_test-input-buffered-file->buffer) - 3129 (clear-stream _test-output-stream) - 3130 (clear-stream $_test-output-buffered-file->buffer) - 3131 # non-local unconditional branch from a block without a local variable, - 3132 # unwinding a local on the stack - 3133 (write _test-input-stream "fn foo {\n") - 3134 (write _test-input-stream " a: {\n") - 3135 (write _test-input-stream " var x: int\n") - 3136 (write _test-input-stream " {\n") - 3137 (write _test-input-stream " break a\n") - 3138 (write _test-input-stream " }\n") - 3139 (write _test-input-stream " }\n") - 3140 (write _test-input-stream "}\n") - 3141 # convert - 3142 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3143 (flush _test-output-buffered-file) - 3144 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3150 # check output - 3151 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/0") - 3152 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/1") - 3153 (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") - 3154 (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") - 3155 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/4") - 3156 (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") - 3157 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/6") - 3158 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/7") - 3159 (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") - 3160 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/9") - 3161 (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") - 3162 (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") - 3163 (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") - 3164 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/14") - 3165 (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") - 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-3/16") - 3167 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/17") - 3168 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/18") - 3169 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/19") - 3170 (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") - 3171 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/21") - 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-3/22") - 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-3/23") - 3174 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/24") - 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-4: - 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 # - 3190 (write _test-input-stream "fn foo {\n") - 3191 (write _test-input-stream " a: {\n") - 3192 (write _test-input-stream " var x/esi: int <- copy 0\n") - 3193 (write _test-input-stream " {\n") - 3194 (write _test-input-stream " break a\n") - 3195 (write _test-input-stream " }\n") - 3196 (write _test-input-stream " }\n") - 3197 (write _test-input-stream "}\n") - 3198 # convert - 3199 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3200 (flush _test-output-buffered-file) - 3201 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3207 # check output - 3208 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/0") - 3209 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/1") - 3210 (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") - 3211 (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") - 3212 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/4") - 3213 (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") - 3214 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/6") - 3215 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/7") - 3216 (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") - 3217 (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") - 3218 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/10") - 3219 (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") - 3220 (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") - 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-4/13") - 3222 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/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-4/15") - 3224 (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") - 3225 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/17") - 3226 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/18") - 3227 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/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-4/20") - 3229 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/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-4/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-4/23") - 3232 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/24") - 3233 # . epilogue - 3234 89/<- %esp 5/r32/ebp - 3235 5d/pop-to-ebp - 3236 c3/return - 3237 - 3238 test-convert-function-with-nonlocal-unconditional-break-and-local-vars: - 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: int\n") - 3251 (write _test-input-stream " {\n") - 3252 (write _test-input-stream " var y: int\n") - 3253 (write _test-input-stream " break a\n") - 3254 (write _test-input-stream " increment x\n") - 3255 (write _test-input-stream " }\n") - 3256 (write _test-input-stream " }\n") - 3257 (write _test-input-stream "}\n") - 3258 # convert - 3259 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3260 (flush _test-output-buffered-file) - 3261 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3267 # check output - 3268 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/0") - 3269 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/1") - 3270 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/2") - 3271 (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") - 3272 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/4") - 3273 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/5") - 3274 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/6") - 3275 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/7") - 3276 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/8") - 3277 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/9") - 3278 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/10") - 3279 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/11") - 3280 (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") - 3281 (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") - 3282 (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") - 3283 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/15") - 3284 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/16") - 3285 (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") - 3286 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/18") - 3287 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/19") - 3288 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/20") - 3289 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/21") - 3290 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/22") - 3291 (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") - 3292 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/24") - 3293 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/25") - 3294 # . epilogue - 3295 89/<- %esp 5/r32/ebp - 3296 5d/pop-to-ebp - 3297 c3/return - 3298 - 3299 test-convert-function-with-unconditional-break-and-local-vars: - 3300 # . prologue - 3301 55/push-ebp - 3302 89/<- %ebp 4/r32/esp - 3303 # setup - 3304 (clear-stream _test-input-stream) - 3305 (clear-stream $_test-input-buffered-file->buffer) - 3306 (clear-stream _test-output-stream) - 3307 (clear-stream $_test-output-buffered-file->buffer) - 3308 # - 3309 (write _test-input-stream "fn foo {\n") - 3310 (write _test-input-stream " {\n") - 3311 (write _test-input-stream " var x: int\n") - 3312 (write _test-input-stream " {\n") - 3313 (write _test-input-stream " var y: int\n") - 3314 (write _test-input-stream " break\n") - 3315 (write _test-input-stream " increment x\n") - 3316 (write _test-input-stream " }\n") - 3317 (write _test-input-stream " }\n") - 3318 (write _test-input-stream "}\n") - 3319 # convert - 3320 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3321 (flush _test-output-buffered-file) - 3322 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3328 # check output - 3329 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-break-and-local-vars/0") - 3330 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-break-and-local-vars/1") - 3331 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/2") - 3332 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-break-and-local-vars/3") - 3333 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/4") - 3334 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/5") - 3335 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/6") - 3336 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/7") - 3337 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/8") - 3338 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/9") - 3339 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/10") - 3340 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/11") - 3341 (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") - 3342 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/13") - 3343 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/14") - 3344 (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") - 3345 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/16") - 3346 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/17") - 3347 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/18") - 3348 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/19") - 3349 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-break-and-local-vars/20") - 3350 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/21") - 3351 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/22") - 3352 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-break-and-local-vars/23") - 3353 # . epilogue - 3354 89/<- %esp 5/r32/ebp - 3355 5d/pop-to-ebp - 3356 c3/return - 3357 - 3358 test-convert-function-with-nonlocal-unconditional-loop-and-local-vars: - 3359 # . prologue - 3360 55/push-ebp - 3361 89/<- %ebp 4/r32/esp - 3362 # setup - 3363 (clear-stream _test-input-stream) - 3364 (clear-stream $_test-input-buffered-file->buffer) - 3365 (clear-stream _test-output-stream) - 3366 (clear-stream $_test-output-buffered-file->buffer) - 3367 # - 3368 (write _test-input-stream "fn foo {\n") - 3369 (write _test-input-stream " a: {\n") - 3370 (write _test-input-stream " var x: int\n") - 3371 (write _test-input-stream " {\n") - 3372 (write _test-input-stream " var y: int\n") - 3373 (write _test-input-stream " loop a\n") - 3374 (write _test-input-stream " increment x\n") - 3375 (write _test-input-stream " }\n") - 3376 (write _test-input-stream " }\n") - 3377 (write _test-input-stream "}\n") - 3378 # convert - 3379 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3380 (flush _test-output-buffered-file) - 3381 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3387 # check output - 3388 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/0") - 3389 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/1") - 3390 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/2") - 3391 (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") - 3392 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/4") - 3393 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/5") - 3394 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/6") - 3395 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/7") - 3396 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/8") - 3397 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/9") - 3398 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/10") - 3399 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/11") - 3400 (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") - 3401 (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") - 3402 (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") - 3403 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/15") - 3404 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/16") - 3405 (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") - 3406 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/18") - 3407 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/19") - 3408 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/20") - 3409 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/21") - 3410 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/22") - 3411 (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") - 3412 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/24") - 3413 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/25") - 3414 # . epilogue - 3415 89/<- %esp 5/r32/ebp - 3416 5d/pop-to-ebp - 3417 c3/return - 3418 - 3419 test-convert-function-with-local-array-var-in-mem: - 3420 # . prologue - 3421 55/push-ebp - 3422 89/<- %ebp 4/r32/esp - 3423 # setup - 3424 (clear-stream _test-input-stream) - 3425 (clear-stream $_test-input-buffered-file->buffer) - 3426 (clear-stream _test-output-stream) - 3427 (clear-stream $_test-output-buffered-file->buffer) - 3428 # - 3429 (write _test-input-stream "fn foo {\n") - 3430 (write _test-input-stream " var x: (array int 3)\n") - 3431 (write _test-input-stream "}\n") - 3432 # convert - 3433 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3434 (flush _test-output-buffered-file) - 3435 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3441 # check output - 3442 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-var-in-mem/0") - 3443 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-var-in-mem/1") - 3444 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-var-in-mem/2") - 3445 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-array-var-in-mem/3") - 3446 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-var-in-mem/4") - 3447 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-var-in-mem/5") - 3448 # define x - 3449 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-function-with-local-array-var-in-mem/7") - 3450 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-function-with-local-array-var-in-mem/8") - 3451 # reclaim x - 3452 (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") - 3453 # - 3454 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-var-in-mem/10") - 3455 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-var-in-mem/11") - 3456 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-var-in-mem/12") - 3457 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-array-var-in-mem/13") - 3458 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-var-in-mem/14") - 3459 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-var-in-mem/15") - 3460 # . epilogue - 3461 89/<- %esp 5/r32/ebp - 3462 5d/pop-to-ebp - 3463 c3/return - 3464 - 3465 # special-case for size(byte) when allocating array - 3466 test-convert-function-with-local-array-of-bytes-in-mem: - 3467 # . prologue - 3468 55/push-ebp - 3469 89/<- %ebp 4/r32/esp - 3470 # setup - 3471 (clear-stream _test-input-stream) - 3472 (clear-stream $_test-input-buffered-file->buffer) - 3473 (clear-stream _test-output-stream) - 3474 (clear-stream $_test-output-buffered-file->buffer) - 3475 # - 3476 (write _test-input-stream "fn foo {\n") - 3477 (write _test-input-stream " var x: (array byte 3)\n") - 3478 (write _test-input-stream "}\n") - 3479 # convert - 3480 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3481 (flush _test-output-buffered-file) - 3482 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3488 # check output - 3489 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-of-bytes-in-mem/0") - 3490 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-of-bytes-in-mem/1") - 3491 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/2") - 3492 (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") - 3493 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-of-bytes-in-mem/4") - 3494 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-of-bytes-in-mem/5") - 3495 # define x - 3496 (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") - 3497 (check-next-stream-line-equal _test-output-stream " 68/push 0x00000003/imm32" "F - test-convert-function-with-local-array-of-bytes-in-mem/8") - 3498 # reclaim x - 3499 (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") - 3500 # - 3501 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-of-bytes-in-mem/10") - 3502 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-of-bytes-in-mem/11") - 3503 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-of-bytes-in-mem/12") - 3504 (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") - 3505 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/14") - 3506 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-of-bytes-in-mem/15") - 3507 # . epilogue - 3508 89/<- %esp 5/r32/ebp - 3509 5d/pop-to-ebp - 3510 c3/return - 3511 - 3512 test-convert-address: - 3513 # . prologue - 3514 55/push-ebp - 3515 89/<- %ebp 4/r32/esp - 3516 # setup - 3517 (clear-stream _test-input-stream) - 3518 (clear-stream $_test-input-buffered-file->buffer) - 3519 (clear-stream _test-output-stream) - 3520 (clear-stream $_test-output-buffered-file->buffer) - 3521 # - 3522 (write _test-input-stream "fn foo {\n") - 3523 (write _test-input-stream " var a: int\n") - 3524 (write _test-input-stream " var b/eax: (addr int) <- address a\n") - 3525 (write _test-input-stream "}\n") - 3526 # convert - 3527 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3528 (flush _test-output-buffered-file) - 3529 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3535 # check output - 3536 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-address/0") - 3537 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-address/1") - 3538 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-address/2") - 3539 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-address/3") - 3540 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-address/4") - 3541 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-address/5") - 3542 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-address/6") - 3543 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-address/7") - 3544 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-address/8") - 3545 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-address/9") - 3546 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-address/10") - 3547 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-address/11") - 3548 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-address/12") - 3549 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-address/13") - 3550 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-address/14") - 3551 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-address/15") - 3552 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-address/16") - 3553 # . epilogue - 3554 89/<- %esp 5/r32/ebp - 3555 5d/pop-to-ebp - 3556 c3/return - 3557 - 3558 test-convert-length-of-array: - 3559 # . prologue - 3560 55/push-ebp - 3561 89/<- %ebp 4/r32/esp - 3562 # setup - 3563 (clear-stream _test-input-stream) - 3564 (clear-stream $_test-input-buffered-file->buffer) - 3565 (clear-stream _test-output-stream) - 3566 (clear-stream $_test-output-buffered-file->buffer) - 3567 # - 3568 (write _test-input-stream "fn foo a: (addr array int) {\n") - 3569 (write _test-input-stream " var b/eax: (addr array int) <- copy a\n") - 3570 (write _test-input-stream " var c/eax: int <- length b\n") - 3571 (write _test-input-stream "}\n") - 3572 # convert - 3573 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3574 (flush _test-output-buffered-file) - 3575 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3581 # check output - 3582 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array/0") - 3583 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array/1") - 3584 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array/2") - 3585 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array/3") - 3586 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array/4") - 3587 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array/5") - 3588 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array/6") - 3589 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array/7") - 3590 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array/8") - 3591 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array/9") - 3592 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array/10") - 3593 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array/11") - 3594 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array/12") - 3595 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array/13") - 3596 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array/14") - 3597 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array/15") - 3598 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array/16") - 3599 # . epilogue - 3600 89/<- %esp 5/r32/ebp - 3601 5d/pop-to-ebp - 3602 c3/return - 3603 - 3604 # special-case for size(byte) when computing array length - 3605 test-convert-length-of-array-of-bytes: - 3606 # . prologue - 3607 55/push-ebp - 3608 89/<- %ebp 4/r32/esp - 3609 # setup - 3610 (clear-stream _test-input-stream) - 3611 (clear-stream $_test-input-buffered-file->buffer) - 3612 (clear-stream _test-output-stream) - 3613 (clear-stream $_test-output-buffered-file->buffer) - 3614 # - 3615 (write _test-input-stream "fn foo a: (addr array byte) {\n") - 3616 (write _test-input-stream " var b/eax: (addr array byte) <- copy a\n") - 3617 (write _test-input-stream " var c/eax: int <- length b\n") - 3618 (write _test-input-stream "}\n") - 3619 # convert - 3620 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3621 (flush _test-output-buffered-file) - 3622 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3628 # check output - 3629 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-bytes/0") - 3630 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-bytes/1") - 3631 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-bytes/2") - 3632 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-bytes/3") - 3633 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-bytes/4") - 3634 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-bytes/5") - 3635 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-bytes/6") - 3636 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/7") - 3637 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/8") - 3638 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-bytes/9") - 3639 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-bytes/10") - 3640 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-bytes/11") - 3641 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-bytes/12") - 3642 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-bytes/13") - 3643 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-bytes/14") - 3644 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-bytes/15") - 3645 # . epilogue - 3646 89/<- %esp 5/r32/ebp - 3647 5d/pop-to-ebp - 3648 c3/return - 3649 - 3650 test-convert-length-of-array-on-stack: - 3651 # . prologue - 3652 55/push-ebp - 3653 89/<- %ebp 4/r32/esp - 3654 # setup - 3655 (clear-stream _test-input-stream) - 3656 (clear-stream $_test-input-buffered-file->buffer) - 3657 (clear-stream _test-output-stream) - 3658 (clear-stream $_test-output-buffered-file->buffer) - 3659 # - 3660 (write _test-input-stream "fn foo {\n") - 3661 (write _test-input-stream " var a: (array int 3)\n") - 3662 (write _test-input-stream " var b/eax: int <- length a\n") - 3663 (write _test-input-stream "}\n") - 3664 # convert - 3665 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3666 (flush _test-output-buffered-file) - 3667 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3673 # check output - 3674 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-on-stack/0") - 3675 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-on-stack/1") - 3676 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-on-stack/2") - 3677 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-on-stack/3") - 3678 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-on-stack/4") - 3679 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-on-stack/5") - 3680 # define x - 3681 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-length-of-array-on-stack/6") - 3682 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-length-of-array-on-stack/7") - 3683 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-on-stack/8") - 3684 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff0) 0x00000000/r32" "F - test-convert-length-of-array-on-stack/9") - 3685 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array-on-stack/10") - 3686 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-on-stack/11") - 3687 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-length-of-array-on-stack/12") - 3688 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-on-stack/13") - 3689 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-on-stack/14") - 3690 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-on-stack/15") - 3691 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-on-stack/16") - 3692 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-on-stack/17") - 3693 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-on-stack/18") - 3694 # . epilogue - 3695 89/<- %esp 5/r32/ebp - 3696 5d/pop-to-ebp - 3697 c3/return - 3698 - 3699 test-reg-var-def-with-read-of-same-register: - 3700 # . prologue - 3701 55/push-ebp - 3702 89/<- %ebp 4/r32/esp - 3703 # setup - 3704 (clear-stream _test-input-stream) - 3705 (clear-stream $_test-input-buffered-file->buffer) - 3706 (clear-stream _test-output-stream) - 3707 (clear-stream $_test-output-buffered-file->buffer) - 3708 (clear-stream _test-error-stream) - 3709 (clear-stream $_test-error-buffered-file->buffer) - 3710 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu - 3711 68/push 0/imm32 - 3712 68/push 0/imm32 - 3713 89/<- %edx 4/r32/esp - 3714 (tailor-exit-descriptor %edx 0x10) - 3715 # - 3716 (write _test-input-stream "fn foo {\n") - 3717 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 3718 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 3719 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 3720 (write _test-input-stream "}\n") - 3721 # convert - 3722 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 3723 # registers except esp could be clobbered at this point (though they shouldn't be) - 3724 # restore ed - 3725 89/<- %edx 4/r32/esp - 3726 (flush _test-output-buffered-file) - 3727 (flush _test-error-buffered-file) - 3728 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3734 (check-stream-equal _test-error-stream "" "F - test-reg-var-def-with-read-of-same-register: error stream should be empty") - 3735 # check output - 3736 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-reg-var-def-with-read-of-same-register/0") - 3737 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-reg-var-def-with-read-of-same-register/1") - 3738 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-reg-var-def-with-read-of-same-register/2") - 3739 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-reg-var-def-with-read-of-same-register/3") - 3740 (check-next-stream-line-equal _test-output-stream " {" "F - test-reg-var-def-with-read-of-same-register/4") - 3741 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-reg-var-def-with-read-of-same-register/5") - 3742 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-reg-var-def-with-read-of-same-register/6") - 3743 (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") - 3744 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-reg-var-def-with-read-of-same-register/8") - 3745 (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") - 3746 (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") - 3747 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-reg-var-def-with-read-of-same-register/13") - 3748 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-reg-var-def-with-read-of-same-register/14") - 3749 (check-next-stream-line-equal _test-output-stream " }" "F - test-reg-var-def-with-read-of-same-register/15") - 3750 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-reg-var-def-with-read-of-same-register/16") - 3751 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-reg-var-def-with-read-of-same-register/17") - 3752 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-reg-var-def-with-read-of-same-register/18") - 3753 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-reg-var-def-with-read-of-same-register/19") - 3754 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-reg-var-def-with-read-of-same-register/20") - 3755 # don't restore from ebp - 3756 81 0/subop/add %esp 8/imm32 - 3757 # . epilogue - 3758 5d/pop-to-ebp - 3759 c3/return - 3760 - 3761 test-convert-index-into-array: - 3762 # . prologue - 3763 55/push-ebp - 3764 89/<- %ebp 4/r32/esp - 3765 # setup - 3766 (clear-stream _test-input-stream) - 3767 (clear-stream $_test-input-buffered-file->buffer) - 3768 (clear-stream _test-output-stream) - 3769 (clear-stream $_test-output-buffered-file->buffer) - 3770 # - 3771 (write _test-input-stream "fn foo {\n") - 3772 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 3773 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 3774 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 3775 (write _test-input-stream "}\n") - 3776 # convert - 3777 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3778 (flush _test-output-buffered-file) - 3779 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3785 # check output - 3786 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array/0") - 3787 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array/1") - 3788 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array/2") - 3789 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array/3") - 3790 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array/4") - 3791 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array/5") - 3792 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array/6") - 3793 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array/7") - 3794 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array/8") - 3795 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array/9") - 3796 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-convert-index-into-array/10") - 3797 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array/11") - 3798 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array/12") - 3799 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array/13") - 3800 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array/14") - 3801 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array/15") - 3802 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array/16") - 3803 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array/17") - 3804 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array/18") - 3805 # . epilogue - 3806 89/<- %esp 5/r32/ebp - 3807 5d/pop-to-ebp - 3808 c3/return - 3809 - 3810 test-convert-index-into-array-of-bytes: - 3811 # . prologue - 3812 55/push-ebp - 3813 89/<- %ebp 4/r32/esp - 3814 # setup - 3815 (clear-stream _test-input-stream) - 3816 (clear-stream $_test-input-buffered-file->buffer) - 3817 (clear-stream _test-output-stream) - 3818 (clear-stream $_test-output-buffered-file->buffer) - 3819 # - 3820 (write _test-input-stream "fn foo {\n") - 3821 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 3822 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 3823 (write _test-input-stream " var x/eax: (addr byte) <- index arr, idx\n") - 3824 (write _test-input-stream "}\n") - 3825 # convert - 3826 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3827 (flush _test-output-buffered-file) - 3828 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3834 # check output - 3835 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes/0") - 3836 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes/1") - 3837 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes/2") - 3838 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes/3") - 3839 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes/4") - 3840 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes/5") - 3841 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes/6") - 3842 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes/7") - 3843 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes/8") - 3844 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes/9") - 3845 (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") - 3846 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes/13") - 3847 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes/14") - 3848 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes/15") - 3849 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes/16") - 3850 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes/17") - 3851 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes/18") - 3852 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes/19") - 3853 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes/20") - 3854 # . epilogue - 3855 89/<- %esp 5/r32/ebp - 3856 5d/pop-to-ebp - 3857 c3/return - 3858 - 3859 test-convert-index-into-array-with-literal: - 3860 # . prologue - 3861 55/push-ebp - 3862 89/<- %ebp 4/r32/esp - 3863 # setup - 3864 (clear-stream _test-input-stream) - 3865 (clear-stream $_test-input-buffered-file->buffer) - 3866 (clear-stream _test-output-stream) - 3867 (clear-stream $_test-output-buffered-file->buffer) - 3868 # - 3869 (write _test-input-stream "fn foo {\n") - 3870 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 3871 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") - 3872 (write _test-input-stream "}\n") - 3873 # convert - 3874 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3875 (flush _test-output-buffered-file) - 3876 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3882 # check output - 3883 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-with-literal/0") - 3884 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-with-literal/1") - 3885 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-with-literal/2") - 3886 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-with-literal/3") - 3887 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-with-literal/4") - 3888 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5") - 3889 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6") - 3890 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7") - 3891 # 2 * 4 bytes/elem + 4 bytes for size = offset 12 - 3892 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/8") - 3893 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/9") - 3894 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/10") - 3895 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-with-literal/11") - 3896 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-with-literal/12") - 3897 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-with-literal/13") - 3898 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-with-literal/14") - 3899 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-with-literal/15") - 3900 # . epilogue - 3901 89/<- %esp 5/r32/ebp - 3902 5d/pop-to-ebp - 3903 c3/return - 3904 - 3905 test-convert-index-into-array-of-bytes-with-literal: - 3906 # . prologue - 3907 55/push-ebp - 3908 89/<- %ebp 4/r32/esp - 3909 # setup - 3910 (clear-stream _test-input-stream) - 3911 (clear-stream $_test-input-buffered-file->buffer) - 3912 (clear-stream _test-output-stream) - 3913 (clear-stream $_test-output-buffered-file->buffer) - 3914 # - 3915 (write _test-input-stream "fn foo {\n") - 3916 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 3917 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") - 3918 (write _test-input-stream "}\n") - 3919 # convert - 3920 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3921 (flush _test-output-buffered-file) - 3922 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3928 # check output - 3929 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-with-literal/0") - 3930 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-with-literal/1") - 3931 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/2") - 3932 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-with-literal/3") - 3933 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-with-literal/4") - 3934 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-with-literal/5") - 3935 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-with-literal/6") - 3936 (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") - 3937 # 2 * 1 byte/elem + 4 bytes for size = offset 6 - 3938 (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") - 3939 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-with-literal/9") - 3940 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-with-literal/10") - 3941 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-with-literal/11") - 3942 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-with-literal/12") - 3943 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-with-literal/13") - 3944 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/14") - 3945 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-with-literal/15") - 3946 # . epilogue - 3947 89/<- %esp 5/r32/ebp - 3948 5d/pop-to-ebp - 3949 c3/return - 3950 - 3951 test-convert-index-into-array-on-stack: - 3952 # . prologue - 3953 55/push-ebp - 3954 89/<- %ebp 4/r32/esp - 3955 # setup - 3956 (clear-stream _test-input-stream) - 3957 (clear-stream $_test-input-buffered-file->buffer) - 3958 (clear-stream _test-output-stream) - 3959 (clear-stream $_test-output-buffered-file->buffer) - 3960 # - 3961 (write _test-input-stream "fn foo {\n") - 3962 (write _test-input-stream " var arr: (array int 3)\n") - 3963 (write _test-input-stream " var idx/eax: int <- copy 2\n") - 3964 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 3965 (write _test-input-stream "}\n") - 3966 # convert - 3967 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 3968 (flush _test-output-buffered-file) - 3969 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 3975 # check output - 3976 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack/0") - 3977 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack/1") - 3978 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack/2") - 3979 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack/3") - 3980 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack/4") - 3981 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack/5") - 3982 # var arr - 3983 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack/6") - 3984 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack/7") - 3985 # var idx - 3986 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack/8") - 3987 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 2/imm32" "F - test-convert-index-into-array-on-stack/9") - 3988 # var x is at (ebp-0x10) + idx<<2 + 4 = ebp + idx<<2 - 0xc - 3989 (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") - 3990 # reclaim idx - 3991 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack/11") - 3992 # reclaim arr - 3993 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack/12") - 3994 # - 3995 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack/13") - 3996 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack/14") - 3997 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack/15") - 3998 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack/16") - 3999 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack/17") - 4000 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack/18") - 4001 # . epilogue - 4002 89/<- %esp 5/r32/ebp - 4003 5d/pop-to-ebp - 4004 c3/return - 4005 - 4006 test-convert-index-into-array-on-stack-with-literal: - 4007 # . prologue - 4008 55/push-ebp - 4009 89/<- %ebp 4/r32/esp - 4010 # setup - 4011 (clear-stream _test-input-stream) - 4012 (clear-stream $_test-input-buffered-file->buffer) - 4013 (clear-stream _test-output-stream) - 4014 (clear-stream $_test-output-buffered-file->buffer) - 4015 # - 4016 (write _test-input-stream "fn foo {\n") - 4017 (write _test-input-stream " var arr: (array int 3)\n") - 4018 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") - 4019 (write _test-input-stream "}\n") - 4020 # convert - 4021 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4022 (flush _test-output-buffered-file) - 4023 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4029 # check output - 4030 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack-with-literal/0") - 4031 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack-with-literal/1") - 4032 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack-with-literal/2") - 4033 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack-with-literal/3") - 4034 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack-with-literal/4") - 4035 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack-with-literal/5") - 4036 # var arr - 4037 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack-with-literal/6") - 4038 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack-with-literal/7") - 4039 # var x - 4040 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack-with-literal/8") - 4041 # x is at (ebp-0x10) + 4 + 2*4 = ebp-4 - 4042 (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") - 4043 # reclaim x - 4044 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack-with-literal/10") - 4045 # reclaim arr - 4046 (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") - 4047 # - 4048 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack-with-literal/12") - 4049 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack-with-literal/13") - 4050 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack-with-literal/14") - 4051 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack-with-literal/15") - 4052 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack-with-literal/16") - 4053 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack-with-literal/17") - 4054 # . epilogue - 4055 89/<- %esp 5/r32/ebp - 4056 5d/pop-to-ebp - 4057 c3/return - 4058 - 4059 test-convert-index-into-array-of-bytes-on-stack-with-literal: - 4060 # . prologue - 4061 55/push-ebp - 4062 89/<- %ebp 4/r32/esp - 4063 # setup - 4064 (clear-stream _test-input-stream) - 4065 (clear-stream $_test-input-buffered-file->buffer) - 4066 (clear-stream _test-output-stream) - 4067 (clear-stream $_test-output-buffered-file->buffer) - 4068 # - 4069 (write _test-input-stream "fn foo {\n") - 4070 (write _test-input-stream " var arr: (array byte 3)\n") - 4071 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") - 4072 (write _test-input-stream "}\n") - 4073 # convert - 4074 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4075 (flush _test-output-buffered-file) - 4076 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4082 # check output - 4083 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/0") - 4084 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/1") - 4085 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/2") - 4086 (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") - 4087 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/4") - 4088 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/5") - 4089 # var arr - 4090 (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") - 4091 (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") - 4092 # var x - 4093 (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") - 4094 # x is at (ebp-7) + 4 + 2 = ebp-1 - 4095 (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") - 4096 # reclaim x - 4097 (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") - 4098 # reclaim arr - 4099 (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") - 4100 # - 4101 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/12") - 4102 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/13") - 4103 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/14") - 4104 (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") - 4105 (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") - 4106 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/17") - 4107 # . epilogue - 4108 89/<- %esp 5/r32/ebp - 4109 5d/pop-to-ebp - 4110 c3/return - 4111 - 4112 test-convert-index-into-array-using-offset: - 4113 # . prologue - 4114 55/push-ebp - 4115 89/<- %ebp 4/r32/esp - 4116 # setup - 4117 (clear-stream _test-input-stream) - 4118 (clear-stream $_test-input-buffered-file->buffer) - 4119 (clear-stream _test-output-stream) - 4120 (clear-stream $_test-output-buffered-file->buffer) - 4121 # - 4122 (write _test-input-stream "fn foo {\n") - 4123 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 4124 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 4125 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") - 4126 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") - 4127 (write _test-input-stream "}\n") - 4128 # convert - 4129 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4130 (flush _test-output-buffered-file) - 4131 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4137 # check output - 4138 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset/0") - 4139 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset/1") - 4140 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset/2") - 4141 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset/3") - 4142 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset/4") - 4143 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset/5") - 4144 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset/6") - 4145 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset/7") - 4146 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset/8") - 4147 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-using-offset/9") - 4148 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10") - 4149 (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") - 4150 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset/12") - 4151 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset/13") - 4152 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset/14") - 4153 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset/15") - 4154 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset/16") - 4155 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset/17") - 4156 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset/18") - 4157 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset/19") - 4158 # . epilogue - 4159 89/<- %esp 5/r32/ebp - 4160 5d/pop-to-ebp - 4161 c3/return - 4162 - 4163 test-convert-index-into-array-of-bytes-using-offset: - 4164 # . prologue - 4165 55/push-ebp - 4166 89/<- %ebp 4/r32/esp - 4167 # setup - 4168 (clear-stream _test-input-stream) - 4169 (clear-stream $_test-input-buffered-file->buffer) - 4170 (clear-stream _test-output-stream) - 4171 (clear-stream $_test-output-buffered-file->buffer) - 4172 # - 4173 (write _test-input-stream "fn foo {\n") - 4174 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 4175 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 4176 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") - 4177 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") - 4178 (write _test-input-stream "}\n") - 4179 # convert - 4180 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4181 (flush _test-output-buffered-file) - 4182 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4188 # check output - 4189 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset/0") - 4190 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset/1") - 4191 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/2") - 4192 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset/3") - 4193 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset/4") - 4194 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset/5") - 4195 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset/6") - 4196 (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") - 4197 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/8") - 4198 (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") - 4199 (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") - 4200 (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") - 4201 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/12") - 4202 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset/13") - 4203 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset/14") - 4204 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset/15") - 4205 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset/16") - 4206 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset/17") - 4207 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/18") - 4208 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset/19") - 4209 # . epilogue - 4210 89/<- %esp 5/r32/ebp - 4211 5d/pop-to-ebp - 4212 c3/return - 4213 - 4214 test-convert-index-into-array-using-offset-on-stack: - 4215 # . prologue - 4216 55/push-ebp - 4217 89/<- %ebp 4/r32/esp - 4218 # setup - 4219 (clear-stream _test-input-stream) - 4220 (clear-stream $_test-input-buffered-file->buffer) - 4221 (clear-stream _test-output-stream) - 4222 (clear-stream $_test-output-buffered-file->buffer) - 4223 # - 4224 (write _test-input-stream "fn foo {\n") - 4225 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") - 4226 (write _test-input-stream " var idx: int\n") - 4227 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") - 4228 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") - 4229 (write _test-input-stream "}\n") - 4230 # convert - 4231 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4232 (flush _test-output-buffered-file) - 4233 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4239 # check output - 4240 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset-on-stack/0") - 4241 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset-on-stack/1") - 4242 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset-on-stack/2") - 4243 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset-on-stack/3") - 4244 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset-on-stack/4") - 4245 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset-on-stack/5") - 4246 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset-on-stack/6") - 4247 (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") - 4248 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/8") - 4249 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset-on-stack/9") - 4250 (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") - 4251 (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") - 4252 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset-on-stack/12") - 4253 (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") - 4254 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset-on-stack/14") - 4255 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset-on-stack/15") - 4256 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset-on-stack/16") - 4257 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset-on-stack/17") - 4258 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset-on-stack/18") - 4259 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset-on-stack/19") - 4260 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset-on-stack/20") - 4261 # . epilogue - 4262 89/<- %esp 5/r32/ebp - 4263 5d/pop-to-ebp - 4264 c3/return - 4265 - 4266 test-convert-index-into-array-of-bytes-using-offset-on-stack: - 4267 # . prologue - 4268 55/push-ebp - 4269 89/<- %ebp 4/r32/esp - 4270 # setup - 4271 (clear-stream _test-input-stream) - 4272 (clear-stream $_test-input-buffered-file->buffer) - 4273 (clear-stream _test-output-stream) - 4274 (clear-stream $_test-output-buffered-file->buffer) - 4275 # - 4276 (write _test-input-stream "fn foo {\n") - 4277 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") - 4278 (write _test-input-stream " var idx: int\n") - 4279 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") - 4280 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") - 4281 (write _test-input-stream "}\n") - 4282 # convert - 4283 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4284 (flush _test-output-buffered-file) - 4285 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4291 # check output - 4292 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/0") - 4293 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/1") - 4294 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/2") - 4295 (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") - 4296 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/4") - 4297 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/5") - 4298 (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") - 4299 (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") - 4300 (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") - 4301 (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") - 4302 (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") - 4303 (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") - 4304 (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") - 4305 (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") - 4306 (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") - 4307 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/15") - 4308 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/16") - 4309 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/17") - 4310 (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") - 4311 (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") - 4312 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/20") - 4313 # . epilogue - 4314 89/<- %esp 5/r32/ebp - 4315 5d/pop-to-ebp - 4316 c3/return - 4317 - 4318 test-convert-function-and-type-definition: - 4319 # . prologue - 4320 55/push-ebp - 4321 89/<- %ebp 4/r32/esp - 4322 # setup - 4323 (clear-stream _test-input-stream) - 4324 (clear-stream $_test-input-buffered-file->buffer) - 4325 (clear-stream _test-output-stream) - 4326 (clear-stream $_test-output-buffered-file->buffer) - 4327 # - 4328 (write _test-input-stream "fn foo a: (addr t) {\n") - 4329 (write _test-input-stream " var _a/eax: (addr t) <- copy a\n") - 4330 (write _test-input-stream " var b/ecx: (addr int) <- get _a, x\n") - 4331 (write _test-input-stream " var c/ecx: (addr int) <- get _a, y\n") - 4332 (write _test-input-stream "}\n") - 4333 (write _test-input-stream "type t {\n") - 4334 (write _test-input-stream " x: int\n") - 4335 (write _test-input-stream " y: int\n") - 4336 (write _test-input-stream "}\n") - 4337 # convert - 4338 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4339 (flush _test-output-buffered-file) - 4340 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4346 # check output - 4347 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-and-type-definition/0") - 4348 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-and-type-definition/1") - 4349 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-and-type-definition/2") - 4350 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-and-type-definition/3") - 4351 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-and-type-definition/4") - 4352 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-and-type-definition/5") - 4353 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-and-type-definition/6") - 4354 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7") - 4355 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-and-type-definition/8") - 4356 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000000) 0x00000001/r32" "F - test-convert-function-and-type-definition/9") - 4357 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000004) 0x00000001/r32" "F - test-convert-function-and-type-definition/11") - 4358 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/13") - 4359 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/14") - 4360 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-and-type-definition/15") - 4361 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-and-type-definition/16") - 4362 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-and-type-definition/17") - 4363 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-and-type-definition/18") - 4364 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-and-type-definition/19") - 4365 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-and-type-definition/20") - 4366 # . epilogue - 4367 89/<- %esp 5/r32/ebp - 4368 5d/pop-to-ebp - 4369 c3/return - 4370 - 4371 test-convert-function-with-local-var-with-user-defined-type: - 4372 # . prologue - 4373 55/push-ebp - 4374 89/<- %ebp 4/r32/esp - 4375 # setup - 4376 (clear-stream _test-input-stream) - 4377 (clear-stream $_test-input-buffered-file->buffer) - 4378 (clear-stream _test-output-stream) - 4379 (clear-stream $_test-output-buffered-file->buffer) - 4380 # - 4381 (write _test-input-stream "fn foo {\n") - 4382 (write _test-input-stream " var a: t\n") - 4383 (write _test-input-stream "}\n") - 4384 (write _test-input-stream "type t {\n") - 4385 (write _test-input-stream " x: int\n") - 4386 (write _test-input-stream " y: int\n") - 4387 (write _test-input-stream "}\n") - 4388 # convert - 4389 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4390 (flush _test-output-buffered-file) - 4391 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4397 # check output - 4398 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type/0") - 4399 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type/1") - 4400 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/2") - 4401 (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") - 4402 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type/4") - 4403 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type/5") - 4404 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/6") - 4405 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/7") - 4406 (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") - 4407 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type/9") - 4408 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type/10") - 4409 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type/11") - 4410 (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") - 4411 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/13") - 4412 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type/14") - 4413 # . epilogue - 4414 89/<- %esp 5/r32/ebp - 4415 5d/pop-to-ebp - 4416 c3/return - 4417 - 4418 test-convert-function-call-with-arg-of-user-defined-type: - 4419 # . prologue - 4420 55/push-ebp - 4421 89/<- %ebp 4/r32/esp - 4422 # setup - 4423 (clear-stream _test-input-stream) - 4424 (clear-stream $_test-input-buffered-file->buffer) - 4425 (clear-stream _test-output-stream) - 4426 (clear-stream $_test-output-buffered-file->buffer) - 4427 # - 4428 (write _test-input-stream "fn f {\n") - 4429 (write _test-input-stream " var a: t\n") - 4430 (write _test-input-stream " foo a\n") - 4431 (write _test-input-stream "}\n") - 4432 (write _test-input-stream "fn foo x: t {\n") - 4433 (write _test-input-stream "}\n") - 4434 (write _test-input-stream "type t {\n") - 4435 (write _test-input-stream " x: int\n") - 4436 (write _test-input-stream " y: int\n") - 4437 (write _test-input-stream "}\n") - 4438 # convert - 4439 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4440 (flush _test-output-buffered-file) - 4441 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4447 # check output - 4448 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") - 4449 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") - 4450 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") - 4451 (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") - 4452 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") - 4453 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") - 4454 # var a: t - 4455 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/6") - 4456 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") - 4457 # foo a - 4458 (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") - 4459 # - 4460 (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") - 4461 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") - 4462 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") - 4463 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") - 4464 (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") - 4465 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") - 4466 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") - 4467 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") - 4468 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") - 4469 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") - 4470 (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") - 4471 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") - 4472 (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") - 4473 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") - 4474 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") - 4475 # . epilogue - 4476 89/<- %esp 5/r32/ebp - 4477 5d/pop-to-ebp - 4478 c3/return - 4479 - 4480 test-convert-function-call-with-arg-of-user-defined-type-register-indirect: - 4481 # . prologue - 4482 55/push-ebp - 4483 89/<- %ebp 4/r32/esp - 4484 # setup - 4485 (clear-stream _test-input-stream) - 4486 (clear-stream $_test-input-buffered-file->buffer) - 4487 (clear-stream _test-output-stream) - 4488 (clear-stream $_test-output-buffered-file->buffer) - 4489 # - 4490 (write _test-input-stream "fn f {\n") - 4491 (write _test-input-stream " var a/eax: (addr t) <- copy 0\n") - 4492 (write _test-input-stream " foo *a\n") - 4493 (write _test-input-stream "}\n") - 4494 (write _test-input-stream "fn foo x: t {\n") - 4495 (write _test-input-stream "}\n") - 4496 (write _test-input-stream "type t {\n") - 4497 (write _test-input-stream " x: int\n") - 4498 (write _test-input-stream " y: int\n") - 4499 (write _test-input-stream "}\n") - 4500 # convert - 4501 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4502 (flush _test-output-buffered-file) - 4503 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4509 # check output - 4510 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") - 4511 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") - 4512 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") - 4513 (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") - 4514 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") - 4515 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") - 4516 # var a - 4517 (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") - 4518 (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") - 4519 # foo a - 4520 (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") - 4521 # - 4522 (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") - 4523 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") - 4524 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") - 4525 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") - 4526 (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") - 4527 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") - 4528 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") - 4529 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") - 4530 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") - 4531 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") - 4532 (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") - 4533 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") - 4534 (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") - 4535 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") - 4536 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") - 4537 # . epilogue - 4538 89/<- %esp 5/r32/ebp - 4539 5d/pop-to-ebp - 4540 c3/return - 4541 - 4542 # we don't have special support for call-by-reference; just explicitly create - 4543 # a new variable with the address of the arg - 4544 test-convert-function-call-with-arg-of-user-defined-type-by-reference: - 4545 # . prologue - 4546 55/push-ebp - 4547 89/<- %ebp 4/r32/esp - 4548 # setup - 4549 (clear-stream _test-input-stream) - 4550 (clear-stream $_test-input-buffered-file->buffer) - 4551 (clear-stream _test-output-stream) - 4552 (clear-stream $_test-output-buffered-file->buffer) - 4553 # - 4554 (write _test-input-stream "fn f {\n") - 4555 (write _test-input-stream " var a: t\n") - 4556 (write _test-input-stream " var b/eax: (addr t) <- address a\n") - 4557 (write _test-input-stream " foo b\n") - 4558 (write _test-input-stream "}\n") - 4559 (write _test-input-stream "fn foo x: (addr t) {\n") - 4560 (write _test-input-stream " var x/ecx: (addr int) <- copy x\n") - 4561 (write _test-input-stream " increment *x\n") - 4562 (write _test-input-stream "}\n") - 4563 (write _test-input-stream "type t {\n") - 4564 (write _test-input-stream " x: int\n") - 4565 (write _test-input-stream " y: int\n") - 4566 (write _test-input-stream "}\n") - 4567 # convert - 4568 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4569 (flush _test-output-buffered-file) - 4570 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4576 # check output - 4577 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/0") - 4578 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/1") - 4579 (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") - 4580 (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") - 4581 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/4") - 4582 (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") - 4583 # var a: t - 4584 (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") - 4585 (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") - 4586 # var b/eax: (addr t) - 4587 (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") - 4588 (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") - 4589 # foo a - 4590 (check-next-stream-line-equal _test-output-stream " (foo %eax)" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/10") - 4591 # - 4592 (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") - 4593 (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") - 4594 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/13") - 4595 (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") - 4596 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/15") - 4597 (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") - 4598 (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") - 4599 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/18") - 4600 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/19") - 4601 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/20") - 4602 (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") - 4603 (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") - 4604 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23") - 4605 (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") - 4606 (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") - 4607 (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") - 4608 (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") - 4609 (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") - 4610 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29") - 4611 (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") - 4612 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/31") - 4613 (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") - 4614 (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") - 4615 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/34") - 4616 # . epilogue - 4617 89/<- %esp 5/r32/ebp - 4618 5d/pop-to-ebp - 4619 c3/return - 4620 - 4621 test-convert-get-on-local-variable: - 4622 # . prologue - 4623 55/push-ebp - 4624 89/<- %ebp 4/r32/esp - 4625 # setup - 4626 (clear-stream _test-input-stream) - 4627 (clear-stream $_test-input-buffered-file->buffer) - 4628 (clear-stream _test-output-stream) - 4629 (clear-stream $_test-output-buffered-file->buffer) - 4630 # - 4631 (write _test-input-stream "fn foo {\n") - 4632 (write _test-input-stream " var a: t\n") - 4633 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 4634 (write _test-input-stream "}\n") - 4635 (write _test-input-stream "type t {\n") - 4636 (write _test-input-stream " x: int\n") - 4637 (write _test-input-stream " y: int\n") - 4638 (write _test-input-stream "}\n") - 4639 # convert - 4640 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4641 (flush _test-output-buffered-file) - 4642 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4648 # check output - 4649 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-local-variable/0") - 4650 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-local-variable/1") - 4651 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-local-variable/2") - 4652 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-local-variable/3") - 4653 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-local-variable/4") - 4654 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-local-variable/5") - 4655 # var a - 4656 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/6") - 4657 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/7") - 4658 # var c - 4659 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-local-variable/8") - 4660 # get - 4661 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000001/r32" "F - test-convert-get-on-local-variable/9") - 4662 # reclaim c - 4663 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-local-variable/10") - 4664 # reclaim a - 4665 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-get-on-local-variable/11") - 4666 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-local-variable/12") - 4667 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-local-variable/13") - 4668 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-local-variable/14") - 4669 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-local-variable/15") - 4670 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-local-variable/16") - 4671 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-local-variable/17") - 4672 # . epilogue - 4673 89/<- %esp 5/r32/ebp - 4674 5d/pop-to-ebp - 4675 c3/return - 4676 - 4677 test-convert-get-on-function-argument: - 4678 # . prologue - 4679 55/push-ebp - 4680 89/<- %ebp 4/r32/esp - 4681 # setup - 4682 (clear-stream _test-input-stream) - 4683 (clear-stream $_test-input-buffered-file->buffer) - 4684 (clear-stream _test-output-stream) - 4685 (clear-stream $_test-output-buffered-file->buffer) - 4686 # - 4687 (write _test-input-stream "fn foo a: t {\n") - 4688 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 4689 (write _test-input-stream "}\n") - 4690 (write _test-input-stream "type t {\n") - 4691 (write _test-input-stream " x: int\n") - 4692 (write _test-input-stream " y: int\n") - 4693 (write _test-input-stream "}\n") - 4694 # convert - 4695 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4696 (flush _test-output-buffered-file) - 4697 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4703 # check output - 4704 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument/0") - 4705 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument/1") - 4706 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument/2") - 4707 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument/3") - 4708 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument/4") - 4709 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument/5") - 4710 # var c - 4711 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument/6") - 4712 # get - 4713 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument/7") - 4714 # reclaim c - 4715 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument/8") - 4716 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument/9") - 4717 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument/10") - 4718 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument/11") - 4719 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument/12") - 4720 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument/13") - 4721 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument/14") - 4722 # . epilogue - 4723 89/<- %esp 5/r32/ebp - 4724 5d/pop-to-ebp - 4725 c3/return - 4726 - 4727 test-convert-get-on-function-argument-with-known-type: - 4728 # . prologue - 4729 55/push-ebp - 4730 89/<- %ebp 4/r32/esp - 4731 # setup - 4732 (clear-stream _test-input-stream) - 4733 (clear-stream $_test-input-buffered-file->buffer) - 4734 (clear-stream _test-output-stream) - 4735 (clear-stream $_test-output-buffered-file->buffer) - 4736 # - 4737 (write _test-input-stream "type t {\n") - 4738 (write _test-input-stream " x: int\n") - 4739 (write _test-input-stream " y: int\n") - 4740 (write _test-input-stream "}\n") - 4741 (write _test-input-stream "fn foo a: t {\n") - 4742 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 4743 (write _test-input-stream "}\n") - 4744 # convert - 4745 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4746 (flush _test-output-buffered-file) - 4747 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4753 # check output - 4754 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument-with-known-type/0") - 4755 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument-with-known-type/1") - 4756 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument-with-known-type/2") - 4757 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument-with-known-type/3") - 4758 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument-with-known-type/4") - 4759 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument-with-known-type/5") - 4760 # var c - 4761 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument-with-known-type/6") - 4762 # get - 4763 (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") - 4764 # reclaim c - 4765 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument-with-known-type/8") - 4766 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument-with-known-type/9") - 4767 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument-with-known-type/10") - 4768 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument-with-known-type/11") - 4769 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument-with-known-type/12") - 4770 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument-with-known-type/13") - 4771 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument-with-known-type/14") - 4772 # . epilogue - 4773 89/<- %esp 5/r32/ebp - 4774 5d/pop-to-ebp - 4775 c3/return - 4776 - 4777 test-get-with-wrong-field: - 4778 # . prologue - 4779 55/push-ebp - 4780 89/<- %ebp 4/r32/esp - 4781 # setup - 4782 (clear-stream _test-input-stream) - 4783 (clear-stream $_test-input-buffered-file->buffer) - 4784 (clear-stream _test-output-stream) - 4785 (clear-stream $_test-output-buffered-file->buffer) - 4786 (clear-stream _test-error-stream) - 4787 (clear-stream $_test-error-buffered-file->buffer) - 4788 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) - 4789 68/push 0/imm32 - 4790 68/push 0/imm32 - 4791 89/<- %edx 4/r32/esp - 4792 (tailor-exit-descriptor %edx 0x10) - 4793 # - 4794 (write _test-input-stream "fn foo {\n") - 4795 (write _test-input-stream " var a: t\n") - 4796 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") - 4797 (write _test-input-stream "}\n") - 4798 (write _test-input-stream "type t {\n") - 4799 (write _test-input-stream " x: int\n") - 4800 (write _test-input-stream "}\n") - 4801 # convert - 4802 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) - 4803 # registers except esp clobbered at this point - 4804 # restore ed - 4805 89/<- %edx 4/r32/esp - 4806 (flush _test-output-buffered-file) - 4807 (flush _test-error-buffered-file) - 4808 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ - 4814 # check output - 4815 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-field: output should be empty") - 4816 (check-next-stream-line-equal _test-error-stream "type 't' has no member called 'y'" "F - test-get-with-wrong-field: error message") - 4817 # check that stop(1) was called - 4818 (check-ints-equal *(edx+4) 2 "F - test-var-in-mem-has-no-initializer: exit status") - 4819 # don't restore from ebp - 4820 81 0/subop/add %esp 8/imm32 - 4821 # . epilogue - 4822 5d/pop-to-ebp - 4823 c3/return - 4824 - 4825 test-convert-array-of-user-defined-types: - 4826 # . prologue - 4827 55/push-ebp - 4828 89/<- %ebp 4/r32/esp - 4829 # setup - 4830 (clear-stream _test-input-stream) - 4831 (clear-stream $_test-input-buffered-file->buffer) - 4832 (clear-stream _test-output-stream) - 4833 (clear-stream $_test-output-buffered-file->buffer) - 4834 # - 4835 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 - 4836 (write _test-input-stream " x: int\n") - 4837 (write _test-input-stream " y: int\n") - 4838 (write _test-input-stream "}\n") - 4839 (write _test-input-stream "fn foo {\n") - 4840 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 4841 (write _test-input-stream " var idx/ecx: int <- copy 3\n") - 4842 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") - 4843 (write _test-input-stream "}\n") - 4844 # convert - 4845 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4846 (flush _test-output-buffered-file) - 4847 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4853 # check output - 4854 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-array-of-user-defined-types/0") - 4855 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-array-of-user-defined-types/1") - 4856 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-array-of-user-defined-types/2") - 4857 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-array-of-user-defined-types/3") - 4858 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-array-of-user-defined-types/4") - 4859 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-array-of-user-defined-types/5") - 4860 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-array-of-user-defined-types/6") - 4861 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-array-of-user-defined-types/7") - 4862 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-array-of-user-defined-types/8") - 4863 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-array-of-user-defined-types/9") - 4864 (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") - 4865 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-array-of-user-defined-types/13") - 4866 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-array-of-user-defined-types/14") - 4867 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-array-of-user-defined-types/15") - 4868 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-array-of-user-defined-types/16") - 4869 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-array-of-user-defined-types/17") - 4870 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-array-of-user-defined-types/18") - 4871 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-array-of-user-defined-types/19") - 4872 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-array-of-user-defined-types/20") - 4873 # . epilogue - 4874 89/<- %esp 5/r32/ebp - 4875 5d/pop-to-ebp - 4876 c3/return - 4877 - 4878 test-convert-length-of-array-of-user-defined-types-to-eax: - 4879 # . prologue - 4880 55/push-ebp - 4881 89/<- %ebp 4/r32/esp - 4882 # setup - 4883 (clear-stream _test-input-stream) - 4884 (clear-stream $_test-input-buffered-file->buffer) - 4885 (clear-stream _test-output-stream) - 4886 (clear-stream $_test-output-buffered-file->buffer) - 4887 # - 4888 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 - 4889 (write _test-input-stream " x: int\n") - 4890 (write _test-input-stream " y: int\n") - 4891 (write _test-input-stream " z: int\n") - 4892 (write _test-input-stream "}\n") + 403 Primitive-type-ids: # (addr int) + 404 0x24 + 405 + 406 # == Type definitions + 407 # Program->types contains some typeinfo for each type definition. + 408 # Types contain vars with types, but can't specify registers. + 409 Typeinfo-id: # type-id + 410 0/imm32 + 411 Typeinfo-fields: # (handle table (handle array byte) (handle typeinfo-entry)) + 412 4/imm32 + 413 # Total size must be >= 0 + 414 # During parsing it may take on two additional values: + 415 # -2: not yet initialized + 416 # -1: in process of being computed + 417 # See populate-mu-type-sizes for details. + 418 Typeinfo-total-size-in-bytes: # int + 419 0xc/imm32 + 420 Typeinfo-next: # (handle typeinfo) + 421 0x10/imm32 + 422 Typeinfo-size: # (addr int) + 423 0x18/imm32 + 424 + 425 # Each entry in the typeinfo->fields table has a pointer to a string and a + 426 # pointer to a typeinfo-entry. + 427 Typeinfo-fields-row-size: # (addr int) + 428 0x10/imm32 + 429 + 430 # typeinfo-entry objects have information about a field in a single record type + 431 # + 432 # each field of a type is represented using two var's: + 433 # 1. the input var: expected type of the field; convenient for creating using parse-var-with-type + 434 # 2. the output var: a constant containing the byte offset; convenient for code-generation + 435 # computing the output happens after parsing; in the meantime we preserve the + 436 # order of fields in the 'index' field. + 437 Typeinfo-entry-input-var: # (handle var) + 438 0/imm32 + 439 Typeinfo-entry-index: # int + 440 8/imm32 + 441 Typeinfo-entry-output-var: # (handle var) + 442 0xc/imm32 + 443 Typeinfo-entry-size: # (addr int) + 444 0x14/imm32 + 445 + 446 == code + 447 + 448 Entry: + 449 # . prologue + 450 89/<- %ebp 4/r32/esp + 451 (new-segment *Heap-size Heap) + 452 # if (argv[1] == "test') run-tests() + 453 { + 454 # if (argc <= 1) break + 455 81 7/subop/compare *ebp 1/imm32 + 456 7e/jump-if-<= break/disp8 + 457 # if (argv[1] != "test") break + 458 (kernel-string-equal? *(ebp+8) "test") # => eax + 459 3d/compare-eax-and 0/imm32/false + 460 74/jump-if-= break/disp8 + 461 # + 462 (run-tests) + 463 # syscall(exit, *Num-test-failures) + 464 8b/-> *Num-test-failures 3/r32/ebx + 465 eb/jump $mu-main:end/disp8 + 466 } + 467 # otherwise convert Stdin + 468 (convert-mu Stdin Stdout Stderr 0) + 469 (flush Stdout) + 470 # syscall(exit, 0) + 471 bb/copy-to-ebx 0/imm32 + 472 $mu-main:end: + 473 e8/call syscall_exit/disp32 + 474 + 475 convert-mu: # in: (addr buffered-file), out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) + 476 # . prologue + 477 55/push-ebp + 478 89/<- %ebp 4/r32/esp + 479 # . save registers + 480 50/push-eax + 481 # initialize global data structures + 482 c7 0/subop/copy *Next-block-index 1/imm32 + 483 8b/-> *Primitive-type-ids 0/r32/eax + 484 89/<- *Type-id 0/r32/eax # stream-write + 485 c7 0/subop/copy *_Program-functions 0/imm32 + 486 c7 0/subop/copy *_Program-functions->payload 0/imm32 + 487 c7 0/subop/copy *_Program-types 0/imm32 + 488 c7 0/subop/copy *_Program-types->payload 0/imm32 + 489 # + 490 (parse-mu *(ebp+8) *(ebp+0x10) *(ebp+0x14)) + 491 (populate-mu-type-sizes *(ebp+0x10) *(ebp+0x14)) + 492 #? (dump-typeinfos "=== typeinfos\n") + 493 (check-mu-types *(ebp+0x10) *(ebp+0x14)) + 494 (emit-subx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) + 495 $convert-mu:end: + 496 # . restore registers + 497 58/pop-to-eax + 498 # . epilogue + 499 89/<- %esp 5/r32/ebp + 500 5d/pop-to-ebp + 501 c3/return + 502 + 503 test-convert-empty-input: + 504 # empty input => empty output + 505 # . prologue + 506 55/push-ebp + 507 89/<- %ebp 4/r32/esp + 508 # setup + 509 (clear-stream _test-input-stream) + 510 (clear-stream $_test-input-buffered-file->buffer) + 511 (clear-stream _test-output-stream) + 512 (clear-stream $_test-output-buffered-file->buffer) + 513 # + 514 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 515 (flush _test-output-buffered-file) + 516 (check-stream-equal _test-output-stream "" "F - test-convert-empty-input") + 517 # . epilogue + 518 89/<- %esp 5/r32/ebp + 519 5d/pop-to-ebp + 520 c3/return + 521 + 522 test-convert-function-skeleton: + 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 (write _test-input-stream "fn foo {\n") + 533 (write _test-input-stream "}\n") + 534 # convert + 535 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 536 (flush _test-output-buffered-file) + 537 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 543 # check output + 544 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-skeleton/0") + 545 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-skeleton/1") + 546 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-skeleton/2") + 547 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-skeleton/3") + 548 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-skeleton/4") + 549 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-skeleton/5") + 550 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-skeleton/6") + 551 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-skeleton/7") + 552 # . epilogue + 553 89/<- %esp 5/r32/ebp + 554 5d/pop-to-ebp + 555 c3/return + 556 + 557 test-convert-multiple-function-skeletons: + 558 # . prologue + 559 55/push-ebp + 560 89/<- %ebp 4/r32/esp + 561 # setup + 562 (clear-stream _test-input-stream) + 563 (clear-stream $_test-input-buffered-file->buffer) + 564 (clear-stream _test-output-stream) + 565 (clear-stream $_test-output-buffered-file->buffer) + 566 # + 567 (write _test-input-stream "fn foo {\n") + 568 (write _test-input-stream "}\n") + 569 (write _test-input-stream "fn bar {\n") + 570 (write _test-input-stream "}\n") + 571 # convert + 572 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 573 (flush _test-output-buffered-file) + 574 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 580 # check first function + 581 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-multiple-function-skeletons/0") + 582 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/1") + 583 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/2") + 584 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/3") + 585 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/4") + 586 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/5") + 587 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/6") + 588 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/7") + 589 # check second function + 590 (check-next-stream-line-equal _test-output-stream "bar:" "F - test-convert-multiple-function-skeletons/10") + 591 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-multiple-function-skeletons/11") + 592 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-multiple-function-skeletons/12") + 593 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-multiple-function-skeletons/13") + 594 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-multiple-function-skeletons/14") + 595 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-multiple-function-skeletons/15") + 596 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-multiple-function-skeletons/16") + 597 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-multiple-function-skeletons/17") + 598 # . epilogue + 599 89/<- %esp 5/r32/ebp + 600 5d/pop-to-ebp + 601 c3/return + 602 + 603 test-convert-function-with-arg: + 604 # . prologue + 605 55/push-ebp + 606 89/<- %ebp 4/r32/esp + 607 # setup + 608 (clear-stream _test-input-stream) + 609 (clear-stream $_test-input-buffered-file->buffer) + 610 (clear-stream _test-output-stream) + 611 (clear-stream $_test-output-buffered-file->buffer) + 612 # + 613 (write _test-input-stream "fn foo n: int {\n") + 614 (write _test-input-stream "}\n") + 615 # convert + 616 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 617 (flush _test-output-buffered-file) + 618 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 624 # check output + 625 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg/0") + 626 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg/1") + 627 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg/2") + 628 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg/3") + 629 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg/4") + 630 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg/5") + 631 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg/6") + 632 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg/7") + 633 # . epilogue + 634 89/<- %esp 5/r32/ebp + 635 5d/pop-to-ebp + 636 c3/return + 637 + 638 test-convert-function-with-arg-and-body: + 639 # . prologue + 640 55/push-ebp + 641 89/<- %ebp 4/r32/esp + 642 # setup + 643 (clear-stream _test-input-stream) + 644 (clear-stream $_test-input-buffered-file->buffer) + 645 (clear-stream _test-output-stream) + 646 (clear-stream $_test-output-buffered-file->buffer) + 647 # + 648 (write _test-input-stream "fn foo n: int {\n") + 649 (write _test-input-stream " increment n\n") + 650 (write _test-input-stream "}\n") + 651 # convert + 652 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 653 (flush _test-output-buffered-file) + 654 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 660 # check output + 661 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-arg-and-body/0") + 662 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-arg-and-body/1") + 663 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-arg-and-body/2") + 664 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-arg-and-body/3") + 665 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-arg-and-body/4") + 666 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-arg-and-body/5") + 667 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-arg-and-body/6") + 668 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-arg-and-body/7") + 669 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-arg-and-body/8") + 670 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-arg-and-body/9") + 671 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-arg-and-body/10") + 672 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-arg-and-body/11") + 673 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-arg-and-body/12") + 674 # . epilogue + 675 89/<- %esp 5/r32/ebp + 676 5d/pop-to-ebp + 677 c3/return + 678 + 679 test-convert-function-distinguishes-args: + 680 # . prologue + 681 55/push-ebp + 682 89/<- %ebp 4/r32/esp + 683 # setup + 684 (clear-stream _test-input-stream) + 685 (clear-stream $_test-input-buffered-file->buffer) + 686 (clear-stream _test-output-stream) + 687 (clear-stream $_test-output-buffered-file->buffer) + 688 # + 689 (write _test-input-stream "fn foo a: int, b: int {\n") + 690 (write _test-input-stream " increment b\n") + 691 (write _test-input-stream "}\n") + 692 # convert + 693 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 694 (flush _test-output-buffered-file) + 695 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 701 # check output + 702 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-distinguishes-args/0") + 703 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-distinguishes-args/1") + 704 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-distinguishes-args/2") + 705 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-distinguishes-args/3") + 706 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-distinguishes-args/4") + 707 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-distinguishes-args/5") + 708 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x0000000c)" "F - test-convert-function-distinguishes-args/6") + 709 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-distinguishes-args/7") + 710 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-distinguishes-args/8") + 711 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-distinguishes-args/9") + 712 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-distinguishes-args/10") + 713 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-distinguishes-args/11") + 714 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-distinguishes-args/12") + 715 # . epilogue + 716 89/<- %esp 5/r32/ebp + 717 5d/pop-to-ebp + 718 c3/return + 719 + 720 test-convert-function-returns-result: + 721 # . prologue + 722 55/push-ebp + 723 89/<- %ebp 4/r32/esp + 724 # setup + 725 (clear-stream _test-input-stream) + 726 (clear-stream $_test-input-buffered-file->buffer) + 727 (clear-stream _test-output-stream) + 728 (clear-stream $_test-output-buffered-file->buffer) + 729 # + 730 (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n") + 731 (write _test-input-stream " result <- copy a\n") + 732 (write _test-input-stream " result <- increment\n") + 733 (write _test-input-stream "}\n") + 734 # convert + 735 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 736 (flush _test-output-buffered-file) + 737 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 743 # check output + 744 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-returns-result/0") + 745 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-returns-result/1") + 746 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-returns-result/2") + 747 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-returns-result/3") + 748 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-returns-result/4") + 749 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-returns-result/5") + 750 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-returns-result/6") + 751 (check-next-stream-line-equal _test-output-stream " 40/increment-eax" "F - test-convert-function-returns-result/7") + 752 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-returns-result/8") + 753 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-returns-result/9") + 754 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-returns-result/10") + 755 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-returns-result/11") + 756 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-returns-result/12") + 757 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-returns-result/13") + 758 # . epilogue + 759 89/<- %esp 5/r32/ebp + 760 5d/pop-to-ebp + 761 c3/return + 762 + 763 test-convert-function-with-literal-arg: + 764 # . prologue + 765 55/push-ebp + 766 89/<- %ebp 4/r32/esp + 767 # setup + 768 (clear-stream _test-input-stream) + 769 (clear-stream $_test-input-buffered-file->buffer) + 770 (clear-stream _test-output-stream) + 771 (clear-stream $_test-output-buffered-file->buffer) + 772 # + 773 (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n") + 774 (write _test-input-stream " result <- copy a\n") + 775 (write _test-input-stream " result <- add 1\n") + 776 (write _test-input-stream "}\n") + 777 # convert + 778 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 779 (flush _test-output-buffered-file) + 780 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 786 # check output + 787 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg/0") + 788 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg/1") + 789 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg/2") + 790 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg/3") + 791 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg/4") + 792 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg/5") + 793 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-with-literal-arg/6") + 794 (check-next-stream-line-equal _test-output-stream " 05/add-to-eax 1/imm32" "F - test-convert-function-with-literal-arg/7") + 795 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg/8") + 796 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg/9") + 797 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg/10") + 798 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg/11") + 799 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg/12") + 800 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg/13") + 801 # . epilogue + 802 89/<- %esp 5/r32/ebp + 803 5d/pop-to-ebp + 804 c3/return + 805 + 806 test-convert-function-with-literal-arg-2: + 807 # . prologue + 808 55/push-ebp + 809 89/<- %ebp 4/r32/esp + 810 # setup + 811 (clear-stream _test-input-stream) + 812 (clear-stream $_test-input-buffered-file->buffer) + 813 (clear-stream _test-output-stream) + 814 (clear-stream $_test-output-buffered-file->buffer) + 815 # + 816 (write _test-input-stream "fn foo a: int, b: int -> result/ebx: int {\n") + 817 (write _test-input-stream " result <- copy a\n") + 818 (write _test-input-stream " result <- add 1\n") + 819 (write _test-input-stream "}\n") + 820 # convert + 821 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 822 (flush _test-output-buffered-file) + 823 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 829 # check output + 830 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-literal-arg-2/0") + 831 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-literal-arg-2/1") + 832 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-literal-arg-2/2") + 833 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg-2/3") + 834 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg-2/4") + 835 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg-2/5") + 836 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/6") + 837 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %ebx 1/imm32" "F - test-convert-function-with-literal-arg-2/7") + 838 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg-2/8") + 839 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg-2/9") + 840 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-literal-arg-2/10") + 841 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-literal-arg-2/11") + 842 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-literal-arg-2/12") + 843 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-literal-arg-2/13") + 844 # . epilogue + 845 89/<- %esp 5/r32/ebp + 846 5d/pop-to-ebp + 847 c3/return + 848 + 849 # HERE + 850 test-convert-function-call-with-literal-arg: + 851 # . prologue + 852 55/push-ebp + 853 89/<- %ebp 4/r32/esp + 854 # setup + 855 (clear-stream _test-input-stream) + 856 (clear-stream $_test-input-buffered-file->buffer) + 857 (clear-stream _test-output-stream) + 858 (clear-stream $_test-output-buffered-file->buffer) + 859 # + 860 (write _test-input-stream "fn main -> result/ebx: int {\n") + 861 (write _test-input-stream " result <- do-add 3 4\n") + 862 (write _test-input-stream "}\n") + 863 (write _test-input-stream "fn do-add a: int, b: int -> result/ebx: int {\n") + 864 (write _test-input-stream " result <- copy a\n") + 865 (write _test-input-stream " result <- add b\n") + 866 (write _test-input-stream "}\n") + 867 # convert + 868 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 869 (flush _test-output-buffered-file) + 870 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 876 # check output + 877 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call-with-literal-arg/0") + 878 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/1") + 879 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/2") + 880 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/3") + 881 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/4") + 882 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call-with-literal-arg/5") + 883 (check-next-stream-line-equal _test-output-stream " (do-add 3 4)" "F - test-convert-function-call-with-literal-arg/6") + 884 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/7") + 885 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-literal-arg/8") + 886 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/9") + 887 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/10") + 888 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/11") + 889 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/12") + 890 (check-next-stream-line-equal _test-output-stream "do-add:" "F - test-convert-function-call-with-literal-arg/13") + 891 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-literal-arg/14") + 892 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-literal-arg/15") + 893 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/16") + 894 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/17") + 895 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:loop:" "F - test-convert-function-call-with-literal-arg/18") + 896 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/19") + 897 (check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0x0000000c) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/20") + 898 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/21") + 899 (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:break:" "F - test-convert-function-call-with-literal-arg/22") + 900 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-literal-arg/23") + 901 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call-with-literal-arg/24") + 902 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-literal-arg/25") + 903 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-literal-arg/26") + 904 # . epilogue + 905 89/<- %esp 5/r32/ebp + 906 5d/pop-to-ebp + 907 c3/return + 908 + 909 test-convert-function-with-local-var-in-mem: + 910 # . prologue + 911 55/push-ebp + 912 89/<- %ebp 4/r32/esp + 913 # setup + 914 (clear-stream _test-input-stream) + 915 (clear-stream $_test-input-buffered-file->buffer) + 916 (clear-stream _test-output-stream) + 917 (clear-stream $_test-output-buffered-file->buffer) + 918 # + 919 (write _test-input-stream "fn foo {\n") + 920 (write _test-input-stream " var x: int\n") + 921 (write _test-input-stream " increment x\n") + 922 (write _test-input-stream "}\n") + 923 # convert + 924 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 925 (flush _test-output-buffered-file) + 926 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 932 # check output + 933 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-mem/0") + 934 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-mem/1") + 935 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-mem/2") + 936 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-mem/3") + 937 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-mem/4") + 938 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-mem/5") + 939 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-mem/6") + 940 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-mem/7") + 941 (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") + 942 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-mem/9") + 943 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-mem/10") + 944 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-mem/11") + 945 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-mem/12") + 946 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-mem/13") + 947 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-mem/14") + 948 # . epilogue + 949 89/<- %esp 5/r32/ebp + 950 5d/pop-to-ebp + 951 c3/return + 952 + 953 test-local-var-in-mem-has-no-initializer: + 954 # . prologue + 955 55/push-ebp + 956 89/<- %ebp 4/r32/esp + 957 # setup + 958 (clear-stream _test-input-stream) + 959 (clear-stream $_test-input-buffered-file->buffer) + 960 (clear-stream _test-output-stream) + 961 (clear-stream $_test-output-buffered-file->buffer) + 962 (clear-stream _test-error-stream) + 963 (clear-stream $_test-error-buffered-file->buffer) + 964 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 965 68/push 0/imm32 + 966 68/push 0/imm32 + 967 89/<- %edx 4/r32/esp + 968 (tailor-exit-descriptor %edx 0x10) + 969 # + 970 (write _test-input-stream "fn foo {\n") + 971 (write _test-input-stream " var x: int <- copy 0\n") + 972 (write _test-input-stream " increment x\n") + 973 (write _test-input-stream "}\n") + 974 # convert + 975 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 976 # registers except esp clobbered at this point + 977 # restore ed + 978 89/<- %edx 4/r32/esp + 979 (flush _test-output-buffered-file) + 980 (flush _test-error-buffered-file) + 981 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 987 # check output + 988 (check-stream-equal _test-output-stream "" "F - test-var-in-mem-has-no-initializer: output should be empty") + 989 (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") + 990 # check that stop(1) was called + 991 (check-ints-equal *(edx+4) 2 "F - test-var-in-mem-has-no-initializer: exit status") + 992 # don't restore from ebp + 993 81 0/subop/add %esp 8/imm32 + 994 # . epilogue + 995 5d/pop-to-ebp + 996 c3/return + 997 + 998 test-convert-function-with-local-var-with-compound-type-in-mem: + 999 # . prologue + 1000 55/push-ebp + 1001 89/<- %ebp 4/r32/esp + 1002 # setup + 1003 (clear-stream _test-input-stream) + 1004 (clear-stream $_test-input-buffered-file->buffer) + 1005 (clear-stream _test-output-stream) + 1006 (clear-stream $_test-output-buffered-file->buffer) + 1007 # + 1008 (write _test-input-stream "fn foo {\n") + 1009 (write _test-input-stream " var x: (addr int)\n") + 1010 (write _test-input-stream " copy-to x, 0\n") + 1011 (write _test-input-stream "}\n") + 1012 # convert + 1013 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1014 (flush _test-output-buffered-file) + 1015 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1021 # check output + 1022 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/0") + 1023 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/1") + 1024 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-compound-type-in-mem/2") + 1025 (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") + 1026 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-compound-type-in-mem/4") + 1027 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/5") + 1028 (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") + 1029 (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") + 1030 (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") + 1031 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-compound-type-in-mem/9") + 1032 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-compound-type-in-mem/10") + 1033 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-compound-type-in-mem/11") + 1034 (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") + 1035 (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") + 1036 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-compound-type-in-mem/14") + 1037 # . epilogue + 1038 89/<- %esp 5/r32/ebp + 1039 5d/pop-to-ebp + 1040 c3/return + 1041 + 1042 test-convert-function-with-local-var-in-reg: + 1043 # . prologue + 1044 55/push-ebp + 1045 89/<- %ebp 4/r32/esp + 1046 # setup + 1047 (clear-stream _test-input-stream) + 1048 (clear-stream $_test-input-buffered-file->buffer) + 1049 (clear-stream _test-output-stream) + 1050 (clear-stream $_test-output-buffered-file->buffer) + 1051 # + 1052 (write _test-input-stream "fn foo {\n") + 1053 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1054 (write _test-input-stream " x <- increment\n") + 1055 (write _test-input-stream "}\n") + 1056 # convert + 1057 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1058 (flush _test-output-buffered-file) + 1059 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1065 # check output + 1066 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-reg/0") + 1067 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-reg/1") + 1068 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-reg/2") + 1069 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-reg/3") + 1070 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-reg/4") + 1071 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-reg/5") + 1072 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-in-reg/6") + 1073 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-function-with-local-var-in-reg/7") + 1074 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-local-var-in-reg/8") + 1075 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-reg/9") + 1076 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-reg/10") + 1077 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-reg/11") + 1078 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-reg/12") + 1079 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-reg/13") + 1080 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-reg/14") + 1081 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-reg/15") + 1082 # . epilogue + 1083 89/<- %esp 5/r32/ebp + 1084 5d/pop-to-ebp + 1085 c3/return + 1086 + 1087 test-convert-function-with-second-local-var-in-same-reg: + 1088 # . prologue + 1089 55/push-ebp + 1090 89/<- %ebp 4/r32/esp + 1091 # setup + 1092 (clear-stream _test-input-stream) + 1093 (clear-stream $_test-input-buffered-file->buffer) + 1094 (clear-stream _test-output-stream) + 1095 (clear-stream $_test-output-buffered-file->buffer) + 1096 # + 1097 (write _test-input-stream "fn foo {\n") + 1098 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1099 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 1100 (write _test-input-stream " y <- increment\n") + 1101 (write _test-input-stream "}\n") + 1102 # convert + 1103 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1104 (flush _test-output-buffered-file) + 1105 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1111 # check output + 1112 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-second-local-var-in-same-reg/0") + 1113 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-second-local-var-in-same-reg/1") + 1114 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/2") + 1115 (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") + 1116 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-second-local-var-in-same-reg/4") + 1117 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-second-local-var-in-same-reg/5") + 1118 (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") + 1119 (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") + 1120 (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") + 1121 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-convert-function-with-second-local-var-in-same-reg/9") + 1122 (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") + 1123 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-second-local-var-in-same-reg/11") + 1124 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-second-local-var-in-same-reg/12") + 1125 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-second-local-var-in-same-reg/13") + 1126 (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") + 1127 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-second-local-var-in-same-reg/15") + 1128 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-second-local-var-in-same-reg/16") + 1129 # . epilogue + 1130 89/<- %esp 5/r32/ebp + 1131 5d/pop-to-ebp + 1132 c3/return + 1133 + 1134 test-read-clobbered-reg-var: + 1135 # . prologue + 1136 55/push-ebp + 1137 89/<- %ebp 4/r32/esp + 1138 # setup + 1139 (clear-stream _test-input-stream) + 1140 (clear-stream $_test-input-buffered-file->buffer) + 1141 (clear-stream _test-output-stream) + 1142 (clear-stream $_test-output-buffered-file->buffer) + 1143 (clear-stream _test-error-stream) + 1144 (clear-stream $_test-error-buffered-file->buffer) + 1145 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu + 1146 68/push 0/imm32 + 1147 68/push 0/imm32 + 1148 89/<- %edx 4/r32/esp + 1149 (tailor-exit-descriptor %edx 0x10) + 1150 # + 1151 (write _test-input-stream "fn foo {\n") + 1152 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1153 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 1154 (write _test-input-stream " x <- increment\n") + 1155 (write _test-input-stream "}\n") + 1156 # convert + 1157 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1158 # registers except esp clobbered at this point + 1159 # restore ed + 1160 89/<- %edx 4/r32/esp + 1161 (flush _test-output-buffered-file) + 1162 (flush _test-error-buffered-file) + 1163 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1169 # check output + 1170 (check-stream-equal _test-output-stream "" "F - test-read-clobbered-reg-var: output should be empty") + 1171 (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") + 1172 # check that stop(1) was called + 1173 (check-ints-equal *(edx+4) 2 "F - test-read-clobbered-reg-var: exit status") + 1174 # don't restore from ebp + 1175 81 0/subop/add %esp 8/imm32 + 1176 # . epilogue + 1177 5d/pop-to-ebp + 1178 c3/return + 1179 + 1180 test-convert-function-call: + 1181 # . prologue + 1182 55/push-ebp + 1183 89/<- %ebp 4/r32/esp + 1184 # setup + 1185 (clear-stream _test-input-stream) + 1186 (clear-stream $_test-input-buffered-file->buffer) + 1187 (clear-stream _test-output-stream) + 1188 (clear-stream $_test-output-buffered-file->buffer) + 1189 # + 1190 (write _test-input-stream "fn main -> result/ebx: int {\n") + 1191 (write _test-input-stream " result <- foo\n") + 1192 (write _test-input-stream "}\n") + 1193 (write _test-input-stream "fn foo -> result/ebx: int {\n") + 1194 (write _test-input-stream " result <- copy 3\n") + 1195 (write _test-input-stream "}\n") + 1196 # convert + 1197 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1198 (flush _test-output-buffered-file) + 1199 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1205 # check output + 1206 (check-next-stream-line-equal _test-output-stream "main:" "F - test-convert-function-call/0") + 1207 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/1") + 1208 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/2") + 1209 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/3") + 1210 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/4") + 1211 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:" "F - test-convert-function-call/5") + 1212 (check-next-stream-line-equal _test-output-stream " (foo)" "F - test-convert-function-call/6") + 1213 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/7") + 1214 (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call/8") + 1215 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/9") + 1216 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/10") + 1217 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/11") + 1218 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/12") + 1219 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call/13") + 1220 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call/14") + 1221 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call/15") + 1222 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call/16") + 1223 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call/17") + 1224 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call/18") + 1225 (check-next-stream-line-equal _test-output-stream " bb/copy-to-ebx 3/imm32" "F - test-convert-function-call/19") + 1226 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call/20") + 1227 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-call/21") + 1228 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call/22") + 1229 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-call/23") + 1230 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call/24") + 1231 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call/25") + 1232 # . epilogue + 1233 89/<- %esp 5/r32/ebp + 1234 5d/pop-to-ebp + 1235 c3/return + 1236 + 1237 test-convert-function-call-with-incorrect-inout-type: + 1238 # . prologue + 1239 55/push-ebp + 1240 89/<- %ebp 4/r32/esp + 1241 # setup + 1242 (clear-stream _test-input-stream) + 1243 (clear-stream $_test-input-buffered-file->buffer) + 1244 (clear-stream _test-output-stream) + 1245 (clear-stream $_test-output-buffered-file->buffer) + 1246 (clear-stream _test-error-stream) + 1247 (clear-stream $_test-error-buffered-file->buffer) + 1248 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1249 68/push 0/imm32 + 1250 68/push 0/imm32 + 1251 89/<- %edx 4/r32/esp + 1252 (tailor-exit-descriptor %edx 0x10) + 1253 # + 1254 (write _test-input-stream "fn f {\n") + 1255 (write _test-input-stream " var x: int\n") + 1256 (write _test-input-stream " g x\n") + 1257 (write _test-input-stream "}\n") + 1258 (write _test-input-stream "fn g a: foo {\n") + 1259 (write _test-input-stream "}\n") + 1260 # convert + 1261 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1262 # registers except esp clobbered at this point + 1263 # restore ed + 1264 89/<- %edx 4/r32/esp + 1265 (flush _test-output-buffered-file) + 1266 (flush _test-error-buffered-file) + 1267 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1273 # check output + 1274 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-inout-type: output should be empty") + 1275 (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") + 1276 # check that stop(1) was called + 1277 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-inout-type: exit status") + 1278 # don't restore from ebp + 1279 81 0/subop/add %esp 8/imm32 + 1280 5d/pop-to-ebp + 1281 c3/return + 1282 + 1283 test-convert-function-call-with-too-few-inouts: + 1284 # . prologue + 1285 55/push-ebp + 1286 89/<- %ebp 4/r32/esp + 1287 # setup + 1288 (clear-stream _test-input-stream) + 1289 (clear-stream $_test-input-buffered-file->buffer) + 1290 (clear-stream _test-output-stream) + 1291 (clear-stream $_test-output-buffered-file->buffer) + 1292 (clear-stream _test-error-stream) + 1293 (clear-stream $_test-error-buffered-file->buffer) + 1294 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1295 68/push 0/imm32 + 1296 68/push 0/imm32 + 1297 89/<- %edx 4/r32/esp + 1298 (tailor-exit-descriptor %edx 0x10) + 1299 # + 1300 (write _test-input-stream "fn f {\n") + 1301 (write _test-input-stream " g\n") + 1302 (write _test-input-stream "}\n") + 1303 (write _test-input-stream "fn g a: int {\n") + 1304 (write _test-input-stream "}\n") + 1305 # convert + 1306 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1307 # registers except esp clobbered at this point + 1308 # restore ed + 1309 89/<- %edx 4/r32/esp + 1310 (flush _test-output-buffered-file) + 1311 (flush _test-error-buffered-file) + 1312 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1318 # check output + 1319 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-inouts: output should be empty") + 1320 (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") + 1321 # check that stop(1) was called + 1322 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-inouts: exit status") + 1323 # don't restore from ebp + 1324 81 0/subop/add %esp 8/imm32 + 1325 5d/pop-to-ebp + 1326 c3/return + 1327 + 1328 test-convert-function-call-with-too-many-inouts: + 1329 # . prologue + 1330 55/push-ebp + 1331 89/<- %ebp 4/r32/esp + 1332 # setup + 1333 (clear-stream _test-input-stream) + 1334 (clear-stream $_test-input-buffered-file->buffer) + 1335 (clear-stream _test-output-stream) + 1336 (clear-stream $_test-output-buffered-file->buffer) + 1337 (clear-stream _test-error-stream) + 1338 (clear-stream $_test-error-buffered-file->buffer) + 1339 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1340 68/push 0/imm32 + 1341 68/push 0/imm32 + 1342 89/<- %edx 4/r32/esp + 1343 (tailor-exit-descriptor %edx 0x10) + 1344 # + 1345 (write _test-input-stream "fn f {\n") + 1346 (write _test-input-stream " var x: int\n") + 1347 (write _test-input-stream " g x\n") + 1348 (write _test-input-stream "}\n") + 1349 (write _test-input-stream "fn g {\n") + 1350 (write _test-input-stream "}\n") + 1351 # convert + 1352 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1353 # registers except esp clobbered at this point + 1354 # restore ed + 1355 89/<- %edx 4/r32/esp + 1356 (flush _test-output-buffered-file) + 1357 (flush _test-error-buffered-file) + 1358 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1364 # check output + 1365 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-inouts: output should be empty") + 1366 (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") + 1367 # check that stop(1) was called + 1368 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-inouts: exit status") + 1369 # don't restore from ebp + 1370 81 0/subop/add %esp 8/imm32 + 1371 5d/pop-to-ebp + 1372 c3/return + 1373 + 1374 test-convert-function-call-with-incorrect-output-type: + 1375 # . prologue + 1376 55/push-ebp + 1377 89/<- %ebp 4/r32/esp + 1378 # setup + 1379 (clear-stream _test-input-stream) + 1380 (clear-stream $_test-input-buffered-file->buffer) + 1381 (clear-stream _test-output-stream) + 1382 (clear-stream $_test-output-buffered-file->buffer) + 1383 (clear-stream _test-error-stream) + 1384 (clear-stream $_test-error-buffered-file->buffer) + 1385 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1386 68/push 0/imm32 + 1387 68/push 0/imm32 + 1388 89/<- %edx 4/r32/esp + 1389 (tailor-exit-descriptor %edx 0x10) + 1390 # + 1391 (write _test-input-stream "fn f {\n") + 1392 (write _test-input-stream " var x/eax: int <- g\n") + 1393 (write _test-input-stream "}\n") + 1394 (write _test-input-stream "fn g -> a/eax: foo {\n") + 1395 (write _test-input-stream "}\n") + 1396 # convert + 1397 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1398 # registers except esp clobbered at this point + 1399 # restore ed + 1400 89/<- %edx 4/r32/esp + 1401 (flush _test-output-buffered-file) + 1402 (flush _test-error-buffered-file) + 1403 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1409 # check output + 1410 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-type: output should be empty") + 1411 (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") + 1412 # check that stop(1) was called + 1413 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-type: exit status") + 1414 # don't restore from ebp + 1415 81 0/subop/add %esp 8/imm32 + 1416 5d/pop-to-ebp + 1417 c3/return + 1418 + 1419 test-convert-function-call-with-too-few-outputs: + 1420 # . prologue + 1421 55/push-ebp + 1422 89/<- %ebp 4/r32/esp + 1423 # setup + 1424 (clear-stream _test-input-stream) + 1425 (clear-stream $_test-input-buffered-file->buffer) + 1426 (clear-stream _test-output-stream) + 1427 (clear-stream $_test-output-buffered-file->buffer) + 1428 (clear-stream _test-error-stream) + 1429 (clear-stream $_test-error-buffered-file->buffer) + 1430 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1431 68/push 0/imm32 + 1432 68/push 0/imm32 + 1433 89/<- %edx 4/r32/esp + 1434 (tailor-exit-descriptor %edx 0x10) + 1435 # + 1436 (write _test-input-stream "fn f {\n") + 1437 (write _test-input-stream " g\n") + 1438 (write _test-input-stream "}\n") + 1439 (write _test-input-stream "fn g -> a/eax: int {\n") + 1440 (write _test-input-stream "}\n") + 1441 # convert + 1442 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1443 # registers except esp clobbered at this point + 1444 # restore ed + 1445 89/<- %edx 4/r32/esp + 1446 (flush _test-output-buffered-file) + 1447 (flush _test-error-buffered-file) + 1448 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1454 # check output + 1455 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-few-outputs: output should be empty") + 1456 (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") + 1457 # check that stop(1) was called + 1458 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-outputs: exit status") + 1459 # don't restore from ebp + 1460 81 0/subop/add %esp 8/imm32 + 1461 5d/pop-to-ebp + 1462 c3/return + 1463 + 1464 test-convert-function-call-with-too-many-outputs: + 1465 # . prologue + 1466 55/push-ebp + 1467 89/<- %ebp 4/r32/esp + 1468 # setup + 1469 (clear-stream _test-input-stream) + 1470 (clear-stream $_test-input-buffered-file->buffer) + 1471 (clear-stream _test-output-stream) + 1472 (clear-stream $_test-output-buffered-file->buffer) + 1473 (clear-stream _test-error-stream) + 1474 (clear-stream $_test-error-buffered-file->buffer) + 1475 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1476 68/push 0/imm32 + 1477 68/push 0/imm32 + 1478 89/<- %edx 4/r32/esp + 1479 (tailor-exit-descriptor %edx 0x10) + 1480 # + 1481 (write _test-input-stream "fn f {\n") + 1482 (write _test-input-stream " var x/eax: int <- g\n") + 1483 (write _test-input-stream "}\n") + 1484 (write _test-input-stream "fn g {\n") + 1485 (write _test-input-stream "}\n") + 1486 # convert + 1487 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1488 # registers except esp clobbered at this point + 1489 # restore ed + 1490 89/<- %edx 4/r32/esp + 1491 (flush _test-output-buffered-file) + 1492 (flush _test-error-buffered-file) + 1493 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1499 # check output + 1500 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-too-many-outputs: output should be empty") + 1501 (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") + 1502 # check that stop(1) was called + 1503 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-outputs: exit status") + 1504 # don't restore from ebp + 1505 81 0/subop/add %esp 8/imm32 + 1506 5d/pop-to-ebp + 1507 c3/return + 1508 + 1509 test-convert-function-call-with-incorrect-output-register: + 1510 # . prologue + 1511 55/push-ebp + 1512 89/<- %ebp 4/r32/esp + 1513 # setup + 1514 (clear-stream _test-input-stream) + 1515 (clear-stream $_test-input-buffered-file->buffer) + 1516 (clear-stream _test-output-stream) + 1517 (clear-stream $_test-output-buffered-file->buffer) + 1518 (clear-stream _test-error-stream) + 1519 (clear-stream $_test-error-buffered-file->buffer) + 1520 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1521 68/push 0/imm32 + 1522 68/push 0/imm32 + 1523 89/<- %edx 4/r32/esp + 1524 (tailor-exit-descriptor %edx 0x10) + 1525 # + 1526 (write _test-input-stream "fn f {\n") + 1527 (write _test-input-stream " var x/ecx: int <- g\n") + 1528 (write _test-input-stream "}\n") + 1529 (write _test-input-stream "fn g -> a/eax: int {\n") + 1530 (write _test-input-stream "}\n") + 1531 # convert + 1532 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1533 # registers except esp clobbered at this point + 1534 # restore ed + 1535 89/<- %edx 4/r32/esp + 1536 (flush _test-output-buffered-file) + 1537 (flush _test-error-buffered-file) + 1538 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1544 # check output + 1545 (check-stream-equal _test-output-stream "" "F - test-convert-function-call-with-incorrect-output-register: output should be empty") + 1546 (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") + 1547 # check that stop(1) was called + 1548 (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-register: exit status") + 1549 # don't restore from ebp + 1550 81 0/subop/add %esp 8/imm32 + 1551 5d/pop-to-ebp + 1552 c3/return + 1553 + 1554 test-convert-function-with-local-var-dereferenced: + 1555 # . prologue + 1556 55/push-ebp + 1557 89/<- %ebp 4/r32/esp + 1558 # setup + 1559 (clear-stream _test-input-stream) + 1560 (clear-stream $_test-input-buffered-file->buffer) + 1561 (clear-stream _test-output-stream) + 1562 (clear-stream $_test-output-buffered-file->buffer) + 1563 # + 1564 (write _test-input-stream "fn foo {\n") + 1565 (write _test-input-stream " var x/ecx: (addr int) <- copy 0\n") + 1566 (write _test-input-stream " increment *x\n") + 1567 (write _test-input-stream "}\n") + 1568 # convert + 1569 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1570 (flush _test-output-buffered-file) + 1571 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1577 # check output + 1578 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-dereferenced/0") + 1579 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-dereferenced/1") + 1580 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-dereferenced/2") + 1581 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-dereferenced/3") + 1582 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-dereferenced/4") + 1583 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-dereferenced/5") + 1584 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-local-var-dereferenced/6") + 1585 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-local-var-dereferenced/7") + 1586 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-with-local-var-dereferenced/8") + 1587 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-dereferenced/9") + 1588 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-dereferenced/10") + 1589 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-dereferenced/11") + 1590 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-dereferenced/12") + 1591 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-dereferenced/13") + 1592 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-dereferenced/14") + 1593 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-dereferenced/15") + 1594 # . epilogue + 1595 89/<- %esp 5/r32/ebp + 1596 5d/pop-to-ebp + 1597 c3/return + 1598 + 1599 # variables of type 'byte' are not allowed on the stack + 1600 test-convert-function-with-byte-operations: + 1601 # . prologue + 1602 55/push-ebp + 1603 89/<- %ebp 4/r32/esp + 1604 # setup + 1605 (clear-stream _test-input-stream) + 1606 (clear-stream $_test-input-buffered-file->buffer) + 1607 (clear-stream _test-output-stream) + 1608 (clear-stream $_test-output-buffered-file->buffer) + 1609 # + 1610 (write _test-input-stream "fn foo {\n") + 1611 (write _test-input-stream " var x/eax: byte <- copy 0\n") + 1612 (write _test-input-stream " var y/ecx: byte <- copy 0\n") + 1613 (write _test-input-stream " y <- copy-byte x\n") + 1614 (write _test-input-stream " var z/edx: (addr byte) <- copy 0\n") + 1615 (write _test-input-stream " y <- copy-byte *z\n") + 1616 (write _test-input-stream " copy-byte-to *z, x\n") + 1617 (write _test-input-stream "}\n") + 1618 # convert + 1619 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1620 (flush _test-output-buffered-file) + 1621 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1627 # check output + 1628 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-byte-operations/0") + 1629 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-byte-operations/1") + 1630 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-byte-operations/2") + 1631 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-byte-operations/3") + 1632 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-byte-operations/4") + 1633 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-byte-operations/5") + 1634 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-byte-operations/6") + 1635 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-function-with-byte-operations/7") + 1636 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-byte-operations/8") + 1637 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-byte-operations/9") + 1638 (check-next-stream-line-equal _test-output-stream " 8a/byte-> %eax 0x00000001/r32" "F - test-convert-function-with-byte-operations/10") + 1639 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-function-with-byte-operations/11") + 1640 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 0/imm32" "F - test-convert-function-with-byte-operations/12") + 1641 (check-next-stream-line-equal _test-output-stream " 8a/byte-> *edx 0x00000001/r32" "F - test-convert-function-with-byte-operations/13") + 1642 (check-next-stream-line-equal _test-output-stream " 88/byte<- *edx 0x00000000/r32" "F - test-convert-function-with-byte-operations/14") + 1643 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-function-with-byte-operations/15") + 1644 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-byte-operations/16") + 1645 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-byte-operations/17") + 1646 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-byte-operations/18") + 1647 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-byte-operations/19") + 1648 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-byte-operations/20") + 1649 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-byte-operations/21") + 1650 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-byte-operations/22") + 1651 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-byte-operations/23") + 1652 # . epilogue + 1653 89/<- %esp 5/r32/ebp + 1654 5d/pop-to-ebp + 1655 c3/return + 1656 + 1657 # variables of type 'byte' _can_ be function args. They then occupy 4 bytes. + 1658 test-copy-byte-var-from-fn-arg: + 1659 # . prologue + 1660 55/push-ebp + 1661 89/<- %ebp 4/r32/esp + 1662 # setup + 1663 (clear-stream _test-input-stream) + 1664 (clear-stream $_test-input-buffered-file->buffer) + 1665 (clear-stream _test-output-stream) + 1666 (clear-stream $_test-output-buffered-file->buffer) + 1667 # + 1668 (write _test-input-stream "fn foo x: byte, y: int {\n") + 1669 (write _test-input-stream " var a/eax: byte <- copy x\n") + 1670 (write _test-input-stream " var b/eax: int <- copy y\n") + 1671 (write _test-input-stream "}\n") + 1672 # convert + 1673 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1674 (flush _test-output-buffered-file) + 1675 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1681 # check output + 1682 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-copy-byte-from-fn-arg/0") + 1683 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-copy-byte-from-fn-arg/1") + 1684 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-copy-byte-from-fn-arg/2") + 1685 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-copy-byte-from-fn-arg/3") + 1686 (check-next-stream-line-equal _test-output-stream " {" "F - test-copy-byte-from-fn-arg/4") + 1687 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-copy-byte-from-fn-arg/5") + 1688 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-copy-byte-from-fn-arg/6") + 1689 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/7") + 1690 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x0000000c) 0x00000000/r32" "F - test-copy-byte-from-fn-arg/8") + 1691 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-copy-byte-from-fn-arg/9") + 1692 (check-next-stream-line-equal _test-output-stream " }" "F - test-copy-byte-from-fn-arg/10") + 1693 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-copy-byte-from-fn-arg/11") + 1694 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-copy-byte-from-fn-arg/12") + 1695 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-copy-byte-from-fn-arg/13") + 1696 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-copy-byte-from-fn-arg/14") + 1697 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-copy-byte-from-fn-arg/15") + 1698 # . epilogue + 1699 89/<- %esp 5/r32/ebp + 1700 5d/pop-to-ebp + 1701 c3/return + 1702 + 1703 test-convert-compare-register-with-literal: + 1704 # . prologue + 1705 55/push-ebp + 1706 89/<- %ebp 4/r32/esp + 1707 # setup + 1708 (clear-stream _test-input-stream) + 1709 (clear-stream $_test-input-buffered-file->buffer) + 1710 (clear-stream _test-output-stream) + 1711 (clear-stream $_test-output-buffered-file->buffer) + 1712 # + 1713 (write _test-input-stream "fn foo {\n") + 1714 (write _test-input-stream " var x/ecx: int <- copy 0\n") + 1715 (write _test-input-stream " compare x, 0\n") + 1716 (write _test-input-stream "}\n") + 1717 # convert + 1718 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1719 (flush _test-output-buffered-file) + 1720 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1726 # check output + 1727 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-compare-register-with-literal/0") + 1728 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-compare-register-with-literal/1") + 1729 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-compare-register-with-literal/2") + 1730 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-compare-register-with-literal/3") + 1731 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-compare-register-with-literal/4") + 1732 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-compare-register-with-literal/5") + 1733 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") + 1734 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-compare-register-with-literal/7") + 1735 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0/imm32" "F - test-convert-compare-register-with-literal/8") + 1736 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") + 1737 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-compare-register-with-literal/10") + 1738 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-compare-register-with-literal/11") + 1739 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-compare-register-with-literal/12") + 1740 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-compare-register-with-literal/13") + 1741 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-compare-register-with-literal/14") + 1742 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-compare-register-with-literal/15") + 1743 # . epilogue + 1744 89/<- %esp 5/r32/ebp + 1745 5d/pop-to-ebp + 1746 c3/return + 1747 + 1748 test-unknown-variable: + 1749 # . prologue + 1750 55/push-ebp + 1751 89/<- %ebp 4/r32/esp + 1752 # setup + 1753 (clear-stream _test-input-stream) + 1754 (clear-stream $_test-input-buffered-file->buffer) + 1755 (clear-stream _test-output-stream) + 1756 (clear-stream $_test-output-buffered-file->buffer) + 1757 (clear-stream _test-error-stream) + 1758 (clear-stream $_test-error-buffered-file->buffer) + 1759 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 1760 68/push 0/imm32 + 1761 68/push 0/imm32 + 1762 89/<- %edx 4/r32/esp + 1763 (tailor-exit-descriptor %edx 0x10) + 1764 # + 1765 (write _test-input-stream "fn foo {\n") + 1766 (write _test-input-stream " compare x, 0\n") + 1767 (write _test-input-stream "}\n") + 1768 # convert + 1769 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 1770 # registers except esp clobbered at this point + 1771 # restore ed + 1772 89/<- %edx 4/r32/esp + 1773 (flush _test-output-buffered-file) + 1774 (flush _test-error-buffered-file) + 1775 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 1781 # check output + 1782 (check-stream-equal _test-output-stream "" "F - test-unknown-variable: output should be empty") + 1783 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable: error message") + 1784 # check that stop(1) was called + 1785 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable: exit status") + 1786 # don't restore from ebp + 1787 81 0/subop/add %esp 8/imm32 + 1788 # . epilogue + 1789 5d/pop-to-ebp + 1790 c3/return + 1791 + 1792 test-convert-function-with-local-var-in-block: + 1793 # . prologue + 1794 55/push-ebp + 1795 89/<- %ebp 4/r32/esp + 1796 # setup + 1797 (clear-stream _test-input-stream) + 1798 (clear-stream $_test-input-buffered-file->buffer) + 1799 (clear-stream _test-output-stream) + 1800 (clear-stream $_test-output-buffered-file->buffer) + 1801 # + 1802 (write _test-input-stream "fn foo {\n") + 1803 (write _test-input-stream " {\n") + 1804 (write _test-input-stream " var x: int\n") + 1805 (write _test-input-stream " increment x\n") + 1806 (write _test-input-stream " }\n") + 1807 (write _test-input-stream "}\n") + 1808 # convert + 1809 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1810 (flush _test-output-buffered-file) + 1811 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1817 # check output + 1818 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-block/0") + 1819 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-block/1") + 1820 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-block/2") + 1821 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-block/3") + 1822 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/4") + 1823 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-block/5") + 1824 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-block/6") + 1825 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-local-var-in-block/7") + 1826 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-block/8") + 1827 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-local-var-in-block/9") + 1828 (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") + 1829 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/11") + 1830 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-local-var-in-block/12") + 1831 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-block/13") + 1832 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-block/14") + 1833 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-block/15") + 1834 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-block/16") + 1835 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-block/17") + 1836 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-block/18") + 1837 # . epilogue + 1838 89/<- %esp 5/r32/ebp + 1839 5d/pop-to-ebp + 1840 c3/return + 1841 + 1842 test-convert-function-with-local-var-in-named-block: + 1843 # . prologue + 1844 55/push-ebp + 1845 89/<- %ebp 4/r32/esp + 1846 # setup + 1847 (clear-stream _test-input-stream) + 1848 (clear-stream $_test-input-buffered-file->buffer) + 1849 (clear-stream _test-output-stream) + 1850 (clear-stream $_test-output-buffered-file->buffer) + 1851 # + 1852 (write _test-input-stream "fn foo {\n") + 1853 (write _test-input-stream " $bar: {\n") + 1854 (write _test-input-stream " var x: int\n") + 1855 (write _test-input-stream " increment x\n") + 1856 (write _test-input-stream " }\n") + 1857 (write _test-input-stream "}\n") + 1858 # convert + 1859 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1860 (flush _test-output-buffered-file) + 1861 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1867 # check output + 1868 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-in-named-block/0") + 1869 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-in-named-block/1") + 1870 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-in-named-block/2") + 1871 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-in-named-block/3") + 1872 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/4") + 1873 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-in-named-block/5") + 1874 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-in-named-block/6") + 1875 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-local-var-in-named-block/7") + 1876 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-in-named-block/8") + 1877 (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") + 1878 (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") + 1879 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/11") + 1880 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-local-var-in-named-block/12") + 1881 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-in-named-block/13") + 1882 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-in-named-block/14") + 1883 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-in-named-block/15") + 1884 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-in-named-block/16") + 1885 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-in-named-block/17") + 1886 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-in-named-block/18") + 1887 # . epilogue + 1888 89/<- %esp 5/r32/ebp + 1889 5d/pop-to-ebp + 1890 c3/return + 1891 + 1892 test-unknown-variable-in-named-block: + 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 foo {\n") + 1910 (write _test-input-stream " $a: {\n") + 1911 (write _test-input-stream " compare x, 0\n") + 1912 (write _test-input-stream " }\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-unknown-variable-in-named-block: output should be empty") + 1929 (check-next-stream-line-equal _test-error-stream "fn foo: unknown variable 'x'" "F - test-unknown-variable-in-named-block: error message") + 1930 # check that stop(1) was called + 1931 (check-ints-equal *(edx+4) 2 "F - test-unknown-variable-in-named-block: exit status") + 1932 # don't restore from ebp + 1933 81 0/subop/add %esp 8/imm32 + 1934 # . epilogue + 1935 5d/pop-to-ebp + 1936 c3/return + 1937 + 1938 test-always-shadow-outermost-reg-vars-in-function: + 1939 # . prologue + 1940 55/push-ebp + 1941 89/<- %ebp 4/r32/esp + 1942 # setup + 1943 (clear-stream _test-input-stream) + 1944 (clear-stream $_test-input-buffered-file->buffer) + 1945 (clear-stream _test-output-stream) + 1946 (clear-stream $_test-output-buffered-file->buffer) + 1947 # + 1948 (write _test-input-stream "fn foo {\n") + 1949 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1950 (write _test-input-stream "}\n") + 1951 # convert + 1952 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1953 (flush _test-output-buffered-file) + 1954 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 1960 # check output + 1961 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-always-shadow-outermost-reg-vars-in-function/0") + 1962 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-always-shadow-outermost-reg-vars-in-function/1") + 1963 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/2") + 1964 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-always-shadow-outermost-reg-vars-in-function/3") + 1965 (check-next-stream-line-equal _test-output-stream " {" "F - test-always-shadow-outermost-reg-vars-in-function/4") + 1966 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-always-shadow-outermost-reg-vars-in-function/5") + 1967 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-compare-register-with-literal/6") + 1968 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-always-shadow-outermost-reg-vars-in-function/8") + 1969 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9") + 1970 (check-next-stream-line-equal _test-output-stream " }" "F - test-always-shadow-outermost-reg-vars-in-function/12") + 1971 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-always-shadow-outermost-reg-vars-in-function/13") + 1972 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-always-shadow-outermost-reg-vars-in-function/14") + 1973 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-always-shadow-outermost-reg-vars-in-function/15") + 1974 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-always-shadow-outermost-reg-vars-in-function/16") + 1975 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-always-shadow-outermost-reg-vars-in-function/17") + 1976 # . epilogue + 1977 89/<- %esp 5/r32/ebp + 1978 5d/pop-to-ebp + 1979 c3/return + 1980 + 1981 _pending-test-clobber-dead-local: + 1982 # . prologue + 1983 55/push-ebp + 1984 89/<- %ebp 4/r32/esp + 1985 # setup + 1986 (clear-stream _test-input-stream) + 1987 (clear-stream $_test-input-buffered-file->buffer) + 1988 (clear-stream _test-output-stream) + 1989 (clear-stream $_test-output-buffered-file->buffer) + 1990 # + 1991 (write _test-input-stream "fn foo {\n") + 1992 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 1993 (write _test-input-stream " {\n") + 1994 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 1995 (write _test-input-stream " }\n") + 1996 (write _test-input-stream "}\n") + 1997 # convert + 1998 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 1999 (flush _test-output-buffered-file) + 2000 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2006 # check output + 2007 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-clobber-dead-local/0") + 2008 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-clobber-dead-local/1") + 2009 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-clobber-dead-local/2") + 2010 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-clobber-dead-local/3") + 2011 (check-next-stream-line-equal _test-output-stream " {" "F - test-clobber-dead-local/4") + 2012 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-clobber-dead-local/5") + 2013 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-clobber-dead-local/6") + 2014 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-clobber-dead-local/7") + 2015 (check-next-stream-line-equal _test-output-stream " {" "F - test-clobber-dead-local/8") + 2016 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-clobber-dead-local/9") + 2017 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-clobber-dead-local/10") # no push/pop here + 2018 (check-next-stream-line-equal _test-output-stream " }" "F - test-clobber-dead-local/11") + 2019 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-clobber-dead-local/12") + 2020 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-clobber-dead-local/13") + 2021 (check-next-stream-line-equal _test-output-stream " }" "F - test-clobber-dead-local/14") + 2022 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-clobber-dead-local/15") + 2023 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-clobber-dead-local/16") + 2024 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-clobber-dead-local/17") + 2025 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-clobber-dead-local/18") + 2026 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-clobber-dead-local/19") + 2027 # . epilogue + 2028 89/<- %esp 5/r32/ebp + 2029 5d/pop-to-ebp + 2030 c3/return + 2031 + 2032 test-shadow-live-local: + 2033 # . prologue + 2034 55/push-ebp + 2035 89/<- %ebp 4/r32/esp + 2036 # setup + 2037 (clear-stream _test-input-stream) + 2038 (clear-stream $_test-input-buffered-file->buffer) + 2039 (clear-stream _test-output-stream) + 2040 (clear-stream $_test-output-buffered-file->buffer) + 2041 # + 2042 (write _test-input-stream "fn foo {\n") + 2043 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2044 (write _test-input-stream " {\n") + 2045 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2046 (write _test-input-stream " }\n") + 2047 (write _test-input-stream " x <- increment\n") + 2048 (write _test-input-stream "}\n") + 2049 # convert + 2050 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2051 (flush _test-output-buffered-file) + 2052 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2058 # check output + 2059 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-live-local/0") + 2060 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-live-local/1") + 2061 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-live-local/2") + 2062 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-live-local/3") + 2063 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-local/4") + 2064 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-live-local/5") + 2065 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-local/6") + 2066 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-live-local/7") + 2067 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-local/8") + 2068 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-live-local/9") + 2069 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-local/10") + 2070 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-live-local/11") + 2071 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-local/12") + 2072 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-local/13") + 2073 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-live-local/14") + 2074 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-live-local/15") + 2075 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-local/16") + 2076 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-local/17") + 2077 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-live-local/18") + 2078 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-live-local/19") + 2079 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-live-local/20") + 2080 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-live-local/21") + 2081 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-live-local/22") + 2082 # . epilogue + 2083 89/<- %esp 5/r32/ebp + 2084 5d/pop-to-ebp + 2085 c3/return + 2086 + 2087 test-shadow-name: + 2088 # . prologue + 2089 55/push-ebp + 2090 89/<- %ebp 4/r32/esp + 2091 # setup + 2092 (clear-stream _test-input-stream) + 2093 (clear-stream $_test-input-buffered-file->buffer) + 2094 (clear-stream _test-output-stream) + 2095 (clear-stream $_test-output-buffered-file->buffer) + 2096 # + 2097 (write _test-input-stream "fn foo {\n") + 2098 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2099 (write _test-input-stream " {\n") + 2100 (write _test-input-stream " var x/edx: int <- copy 4\n") + 2101 (write _test-input-stream " }\n") + 2102 (write _test-input-stream " x <- increment\n") + 2103 (write _test-input-stream "}\n") + 2104 # convert + 2105 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2106 (flush _test-output-buffered-file) + 2107 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2113 # check output + 2114 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name/0") + 2115 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name/1") + 2116 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name/2") + 2117 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name/3") + 2118 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/4") + 2119 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name/5") + 2120 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name/6") + 2121 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name/7") + 2122 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name/8") + 2123 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name/9") + 2124 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name/10") + 2125 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name/11") + 2126 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name/12") + 2127 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/13") + 2128 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name/14") + 2129 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name/15") + 2130 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name/16") + 2131 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name/17") + 2132 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name/18") + 2133 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name/19") + 2134 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name/20") + 2135 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name/21") + 2136 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name/22") + 2137 # . epilogue + 2138 89/<- %esp 5/r32/ebp + 2139 5d/pop-to-ebp + 2140 c3/return + 2141 + 2142 test-shadow-name-2: + 2143 # . prologue + 2144 55/push-ebp + 2145 89/<- %ebp 4/r32/esp + 2146 # setup + 2147 (clear-stream _test-input-stream) + 2148 (clear-stream $_test-input-buffered-file->buffer) + 2149 (clear-stream _test-output-stream) + 2150 (clear-stream $_test-output-buffered-file->buffer) + 2151 # + 2152 (write _test-input-stream "fn foo {\n") + 2153 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2154 (write _test-input-stream " {\n") + 2155 (write _test-input-stream " var x/edx: int <- copy 4\n") + 2156 (write _test-input-stream " var y/ecx: int <- copy 5\n") + 2157 (write _test-input-stream " }\n") + 2158 (write _test-input-stream " x <- increment\n") + 2159 (write _test-input-stream "}\n") + 2160 # convert + 2161 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2162 (flush _test-output-buffered-file) + 2163 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2169 # check output + 2170 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-name-2/0") + 2171 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-name-2/1") + 2172 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-name-2/2") + 2173 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-name-2/3") + 2174 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/4") + 2175 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-name-2/5") + 2176 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/6") + 2177 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-shadow-name-2/7") + 2178 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-name-2/8") + 2179 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-name-2/9") + 2180 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-shadow-name-2/10") + 2181 (check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 4/imm32" "F - test-shadow-name-2/11") + 2182 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-name-2/12") + 2183 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 5/imm32" "F - test-shadow-name-2/13") + 2184 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/14") + 2185 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-shadow-name-2/15") + 2186 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/16") + 2187 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-name-2/17") + 2188 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-name-2/18") + 2189 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-name-2/19") + 2190 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-name-2/20") + 2191 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-name-2/21") + 2192 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-name-2/22") + 2193 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-name-2/23") + 2194 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-name-2/24") + 2195 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-name-2/25") + 2196 # . epilogue + 2197 89/<- %esp 5/r32/ebp + 2198 5d/pop-to-ebp + 2199 c3/return + 2200 + 2201 test-do-not-spill-same-register-in-block: + 2202 # . prologue + 2203 55/push-ebp + 2204 89/<- %ebp 4/r32/esp + 2205 # setup + 2206 (clear-stream _test-input-stream) + 2207 (clear-stream $_test-input-buffered-file->buffer) + 2208 (clear-stream _test-output-stream) + 2209 (clear-stream $_test-output-buffered-file->buffer) + 2210 # + 2211 (write _test-input-stream "fn foo {\n") + 2212 (write _test-input-stream " var x/ecx: int <- copy 3\n") + 2213 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2214 (write _test-input-stream " y <- increment\n") + 2215 (write _test-input-stream "}\n") + 2216 # convert + 2217 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2218 (flush _test-output-buffered-file) + 2219 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2225 # check output + 2226 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-do-not-spill-same-register-in-block/0") + 2227 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-do-not-spill-same-register-in-block/1") + 2228 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-do-not-spill-same-register-in-block/2") + 2229 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-do-not-spill-same-register-in-block/3") + 2230 (check-next-stream-line-equal _test-output-stream " {" "F - test-do-not-spill-same-register-in-block/4") + 2231 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-do-not-spill-same-register-in-block/5") + 2232 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-do-not-spill-same-register-in-block/6") + 2233 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-do-not-spill-same-register-in-block/7") + 2234 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-do-not-spill-same-register-in-block/8") + 2235 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-do-not-spill-same-register-in-block/9") + 2236 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-do-not-spill-same-register-in-block/10") + 2237 (check-next-stream-line-equal _test-output-stream " }" "F - test-do-not-spill-same-register-in-block/11") + 2238 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-do-not-spill-same-register-in-block/12") + 2239 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-do-not-spill-same-register-in-block/13") + 2240 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-do-not-spill-same-register-in-block/14") + 2241 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-do-not-spill-same-register-in-block/15") + 2242 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-do-not-spill-same-register-in-block/16") + 2243 # . epilogue + 2244 89/<- %esp 5/r32/ebp + 2245 5d/pop-to-ebp + 2246 c3/return + 2247 + 2248 test-spill-different-register-in-block: + 2249 # . prologue + 2250 55/push-ebp + 2251 89/<- %ebp 4/r32/esp + 2252 # setup + 2253 (clear-stream _test-input-stream) + 2254 (clear-stream $_test-input-buffered-file->buffer) + 2255 (clear-stream _test-output-stream) + 2256 (clear-stream $_test-output-buffered-file->buffer) + 2257 # + 2258 (write _test-input-stream "fn foo {\n") + 2259 (write _test-input-stream " var x/eax: int <- copy 3\n") + 2260 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2261 (write _test-input-stream " y <- increment\n") + 2262 (write _test-input-stream "}\n") + 2263 # convert + 2264 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2265 (flush _test-output-buffered-file) + 2266 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2272 # check output + 2273 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-spill-different-register-in-block/0") + 2274 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-spill-different-register-in-block/1") + 2275 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-spill-different-register-in-block/2") + 2276 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-spill-different-register-in-block/3") + 2277 (check-next-stream-line-equal _test-output-stream " {" "F - test-spill-different-register-in-block/4") + 2278 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-spill-different-register-in-block/5") + 2279 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-spill-different-register-in-block/6") + 2280 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-spill-different-register-in-block/7") + 2281 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-spill-different-register-in-block/8") + 2282 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-spill-different-register-in-block/9") + 2283 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-spill-different-register-in-block/10") + 2284 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-spill-different-register-in-block/11") + 2285 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-spill-different-register-in-block/12") + 2286 (check-next-stream-line-equal _test-output-stream " }" "F - test-spill-different-register-in-block/13") + 2287 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-spill-different-register-in-block/14") + 2288 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-spill-different-register-in-block/15") + 2289 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-spill-different-register-in-block/16") + 2290 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-spill-different-register-in-block/17") + 2291 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-spill-different-register-in-block/18") + 2292 # . epilogue + 2293 89/<- %esp 5/r32/ebp + 2294 5d/pop-to-ebp + 2295 c3/return + 2296 + 2297 test-shadow-live-output: + 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 -> x/ecx: int {\n") + 2308 (write _test-input-stream " x <- copy 3\n") + 2309 (write _test-input-stream " {\n") + 2310 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2311 (write _test-input-stream " }\n") + 2312 (write _test-input-stream " x <- increment\n") + 2313 (write _test-input-stream "}\n") + 2314 # convert + 2315 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2316 (flush _test-output-buffered-file) + 2317 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2323 # check output + 2324 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-shadow-live-output/0") + 2325 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-shadow-live-output/1") + 2326 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-shadow-live-output/2") + 2327 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-shadow-live-output/3") + 2328 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-output/4") + 2329 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-shadow-live-output/5") + 2330 (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 + 2331 (check-next-stream-line-equal _test-output-stream " {" "F - test-shadow-live-output/8") + 2332 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-shadow-live-output/9") + 2333 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-shadow-live-output/10") + 2334 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-shadow-live-output/11") + 2335 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-shadow-live-output/12") + 2336 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-output/13") + 2337 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-shadow-live-output/14") + 2338 (check-next-stream-line-equal _test-output-stream " 41/increment-ecx" "F - test-shadow-live-output/15") + 2339 (check-next-stream-line-equal _test-output-stream " }" "F - test-shadow-live-output/17") + 2340 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-shadow-live-output/18") + 2341 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-shadow-live-output/19") + 2342 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-shadow-live-output/20") + 2343 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-shadow-live-output/21") + 2344 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-shadow-live-output/21") + 2345 # . epilogue + 2346 89/<- %esp 5/r32/ebp + 2347 5d/pop-to-ebp + 2348 c3/return + 2349 + 2350 test-stmt-defines-output-in-same-register-as-inout: + 2351 # . prologue + 2352 55/push-ebp + 2353 89/<- %ebp 4/r32/esp + 2354 # setup + 2355 (clear-stream _test-input-stream) + 2356 (clear-stream $_test-input-buffered-file->buffer) + 2357 (clear-stream _test-output-stream) + 2358 (clear-stream $_test-output-buffered-file->buffer) + 2359 (clear-stream _test-error-stream) + 2360 (clear-stream $_test-error-buffered-file->buffer) + 2361 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 2362 68/push 0/imm32 + 2363 68/push 0/imm32 + 2364 89/<- %edx 4/r32/esp + 2365 (tailor-exit-descriptor %edx 0x10) + 2366 # + 2367 (write _test-input-stream "fn foo -> x/ecx: int {\n") + 2368 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2369 (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 + 2370 (write _test-input-stream "}\n") + 2371 # convert + 2372 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 2373 # registers except esp clobbered at this point + 2374 # restore ed + 2375 89/<- %edx 4/r32/esp + 2376 (flush _test-output-buffered-file) + 2377 (flush _test-error-buffered-file) + 2378 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2384 # no error; we looked up 'y' correctly before pushing the binding for 'x' + 2385 (check-stream-equal _test-error-stream "" "F - test-stmt-defines-output-in-same-register-as-inout: error stream should be empty") + 2386 # don't bother checking the generated code; that's in the test 'test-local-clobbered-by-fn-output' below + 2387 # don't restore from ebp + 2388 81 0/subop/add %esp 8/imm32 + 2389 # . epilogue + 2390 5d/pop-to-ebp + 2391 c3/return + 2392 + 2393 test-local-clobbered-by-fn-output: + 2394 # . prologue + 2395 55/push-ebp + 2396 89/<- %ebp 4/r32/esp + 2397 # setup + 2398 (clear-stream _test-input-stream) + 2399 (clear-stream $_test-input-buffered-file->buffer) + 2400 (clear-stream _test-output-stream) + 2401 (clear-stream $_test-output-buffered-file->buffer) + 2402 # + 2403 (write _test-input-stream "fn foo -> x/ecx: int {\n") + 2404 (write _test-input-stream " var y/ecx: int <- copy 4\n") + 2405 (write _test-input-stream " x <- copy y\n") + 2406 (write _test-input-stream "}\n") + 2407 # convert + 2408 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2409 (flush _test-output-buffered-file) + 2410 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2416 # check output + 2417 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-local-clobbered-by-fn-output/0") + 2418 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-local-clobbered-by-fn-output/1") + 2419 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-local-clobbered-by-fn-output/2") + 2420 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-local-clobbered-by-fn-output/3") + 2421 (check-next-stream-line-equal _test-output-stream " {" "F - test-local-clobbered-by-fn-output/4") + 2422 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-local-clobbered-by-fn-output/5") + 2423 (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 + 2424 (check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0x00000001/r32" "F - test-local-clobbered-by-fn-output/7") + 2425 (check-next-stream-line-equal _test-output-stream " }" "F - test-local-clobbered-by-fn-output/8") + 2426 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-local-clobbered-by-fn-output/9") + 2427 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-local-clobbered-by-fn-output/10") + 2428 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-local-clobbered-by-fn-output/11") + 2429 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-local-clobbered-by-fn-output/12") + 2430 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-local-clobbered-by-fn-output/13") + 2431 # . epilogue + 2432 89/<- %esp 5/r32/ebp + 2433 5d/pop-to-ebp + 2434 c3/return + 2435 + 2436 test-read-output: + 2437 # . prologue + 2438 55/push-ebp + 2439 89/<- %ebp 4/r32/esp + 2440 # setup + 2441 (clear-stream _test-input-stream) + 2442 (clear-stream $_test-input-buffered-file->buffer) + 2443 (clear-stream _test-output-stream) + 2444 (clear-stream $_test-output-buffered-file->buffer) + 2445 # + 2446 (write _test-input-stream "fn foo -> x/ecx: int {\n") + 2447 (write _test-input-stream " x <- copy 0x34\n") + 2448 (write _test-input-stream " compare x, 0x35\n") + 2449 (write _test-input-stream "}\n") + 2450 # convert + 2451 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2452 (flush _test-output-buffered-file) + 2453 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2459 # check output + 2460 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-read-output/0") + 2461 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-read-output/1") + 2462 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-read-output/2") + 2463 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-read-output/3") + 2464 (check-next-stream-line-equal _test-output-stream " {" "F - test-read-output/4") + 2465 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-read-output/5") + 2466 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0x34/imm32" "F - test-read-output/6") + 2467 (check-next-stream-line-equal _test-output-stream " 81 7/subop/compare %ecx 0x35/imm32" "F - test-read-output/7") + 2468 (check-next-stream-line-equal _test-output-stream " }" "F - test-read-output/8") + 2469 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-read-output/9") + 2470 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-read-output/10") + 2471 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-read-output/11") + 2472 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-read-output/12") + 2473 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-read-output/13") + 2474 # . epilogue + 2475 89/<- %esp 5/r32/ebp + 2476 5d/pop-to-ebp + 2477 c3/return + 2478 + 2479 test-fn-output-written-in-inner-block: + 2480 # . prologue + 2481 55/push-ebp + 2482 89/<- %ebp 4/r32/esp + 2483 # setup + 2484 (clear-stream _test-input-stream) + 2485 (clear-stream $_test-input-buffered-file->buffer) + 2486 (clear-stream _test-output-stream) + 2487 (clear-stream $_test-output-buffered-file->buffer) + 2488 # + 2489 (write _test-input-stream "fn foo -> out/edi: int {\n") + 2490 (write _test-input-stream " var a/eax: int <- copy 3\n") # define outer local + 2491 (write _test-input-stream " {\n") + 2492 (write _test-input-stream " var a/ecx: int <- copy 4\n") # shadow outer local + 2493 (write _test-input-stream " out <- copy a\n") # write to fn output + 2494 (write _test-input-stream " }\n") + 2495 (write _test-input-stream " compare a, 0\n") # use outer local + 2496 (write _test-input-stream "}\n") + 2497 # convert + 2498 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2499 (flush _test-output-buffered-file) + 2500 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2506 # no error; defining 'out' didn't interfere with the reclamation of 'b' + 2507 # check output + 2508 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-fn-output-written-in-inner-block/0") + 2509 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-fn-output-written-in-inner-block/1") + 2510 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-fn-output-written-in-inner-block/2") + 2511 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-fn-output-written-in-inner-block/3") + 2512 (check-next-stream-line-equal _test-output-stream " {" "F - test-fn-output-written-in-inner-block/4") + 2513 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-fn-output-written-in-inner-block/5") + 2514 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-fn-output-written-in-inner-block/6") + 2515 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 3/imm32" "F - test-fn-output-written-in-inner-block/7") + 2516 (check-next-stream-line-equal _test-output-stream " {" "F - test-fn-output-written-in-inner-block/8") + 2517 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-fn-output-written-in-inner-block/9") + 2518 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-fn-output-written-in-inner-block/10") + 2519 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-fn-output-written-in-inner-block/10") + 2520 (check-next-stream-line-equal _test-output-stream " 89/<- %edi 0x00000001/r32" "F - test-fn-output-written-in-inner-block/11") + 2521 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-fn-output-written-in-inner-block/12") + 2522 (check-next-stream-line-equal _test-output-stream " }" "F - test-fn-output-written-in-inner-block/13") + 2523 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-fn-output-written-in-inner-block/14") + 2524 (check-next-stream-line-equal _test-output-stream " 3d/compare-eax-with 0/imm32" "F - test-fn-output-written-in-inner-block/15") + 2525 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-fn-output-written-in-inner-block/16") + 2526 (check-next-stream-line-equal _test-output-stream " }" "F - test-fn-output-written-in-inner-block/17") + 2527 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-fn-output-written-in-inner-block/18") + 2528 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-fn-output-written-in-inner-block/19") + 2529 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-fn-output-written-in-inner-block/20") + 2530 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-fn-output-written-in-inner-block/21") + 2531 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-fn-output-written-in-inner-block/22") + 2532 # . epilogue + 2533 89/<- %esp 5/r32/ebp + 2534 5d/pop-to-ebp + 2535 c3/return + 2536 + 2537 test-convert-function-with-branches-in-block: + 2538 # . prologue + 2539 55/push-ebp + 2540 89/<- %ebp 4/r32/esp + 2541 # setup + 2542 (clear-stream _test-input-stream) + 2543 (clear-stream $_test-input-buffered-file->buffer) + 2544 (clear-stream _test-output-stream) + 2545 (clear-stream $_test-output-buffered-file->buffer) + 2546 # + 2547 (write _test-input-stream "fn foo x: int {\n") + 2548 (write _test-input-stream " {\n") + 2549 (write _test-input-stream " break-if->=\n") + 2550 (write _test-input-stream " loop-if-addr<\n") + 2551 (write _test-input-stream " increment x\n") + 2552 (write _test-input-stream " loop\n") + 2553 (write _test-input-stream " }\n") + 2554 (write _test-input-stream "}\n") + 2555 # convert + 2556 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2557 (flush _test-output-buffered-file) + 2558 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2564 # check output + 2565 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-block/0") + 2566 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1") + 2567 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2") + 2568 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3") + 2569 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4") + 2570 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5") + 2571 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6") + 2572 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7") + 2573 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/8") + 2574 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-block/9") + 2575 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-in-block/10") + 2576 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/11") + 2577 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/12") + 2578 (check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-block/13") + 2579 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-branches-in-block/14") + 2580 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/15") + 2581 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/16") + 2582 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/17") + 2583 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/18") + 2584 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/19") + 2585 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/20") + 2586 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/21") + 2587 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/22") + 2588 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/23") + 2589 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/24") + 2590 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/25") + 2591 # . epilogue + 2592 89/<- %esp 5/r32/ebp + 2593 5d/pop-to-ebp + 2594 c3/return + 2595 + 2596 test-convert-function-with-branches-in-named-block: + 2597 # . prologue + 2598 55/push-ebp + 2599 89/<- %ebp 4/r32/esp + 2600 # setup + 2601 (clear-stream _test-input-stream) + 2602 (clear-stream $_test-input-buffered-file->buffer) + 2603 (clear-stream _test-output-stream) + 2604 (clear-stream $_test-output-buffered-file->buffer) + 2605 # + 2606 (write _test-input-stream "fn foo x: int {\n") + 2607 (write _test-input-stream " $bar: {\n") + 2608 (write _test-input-stream " break-if->= $bar\n") + 2609 (write _test-input-stream " loop-if-addr< $bar\n") + 2610 (write _test-input-stream " increment x\n") + 2611 (write _test-input-stream " loop\n") + 2612 (write _test-input-stream " }\n") + 2613 (write _test-input-stream "}\n") + 2614 # convert + 2615 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2616 (flush _test-output-buffered-file) + 2617 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2623 # check output + 2624 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-in-named-block/0") + 2625 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-named-block/1") + 2626 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-named-block/2") + 2627 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-named-block/3") + 2628 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/4") + 2629 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-named-block/5") + 2630 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/6") + 2631 (check-next-stream-line-equal _test-output-stream "$bar:loop:" "F - test-convert-function-with-branches-in-named-block/7") + 2632 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/8") + 2633 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-named-block/9") + 2634 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:break/disp32" "F - test-convert-function-with-branches-in-named-block/10") + 2635 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/11") + 2636 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-named-block/12") + 2637 (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") + 2638 (check-next-stream-line-equal _test-output-stream " e9/jump $bar:loop/disp32" "F - test-convert-function-with-branches-in-named-block/14") + 2639 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/15") + 2640 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-named-block/16") + 2641 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-named-block/17") + 2642 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/18") + 2643 (check-next-stream-line-equal _test-output-stream "$bar:break:" "F - test-convert-function-with-branches-in-named-block/19") + 2644 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-named-block/20") + 2645 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-named-block/21") + 2646 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-named-block/22") + 2647 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-named-block/23") + 2648 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-named-block/24") + 2649 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-named-block/25") + 2650 # . epilogue + 2651 89/<- %esp 5/r32/ebp + 2652 5d/pop-to-ebp + 2653 c3/return + 2654 + 2655 test-convert-function-with-var-in-nested-block: + 2656 # . prologue + 2657 55/push-ebp + 2658 89/<- %ebp 4/r32/esp + 2659 # setup + 2660 (clear-stream _test-input-stream) + 2661 (clear-stream $_test-input-buffered-file->buffer) + 2662 (clear-stream _test-output-stream) + 2663 (clear-stream $_test-output-buffered-file->buffer) + 2664 # + 2665 (write _test-input-stream "fn foo x: int {\n") + 2666 (write _test-input-stream " {\n") + 2667 (write _test-input-stream " {\n") + 2668 (write _test-input-stream " var x: int\n") + 2669 (write _test-input-stream " increment x\n") + 2670 (write _test-input-stream " }\n") + 2671 (write _test-input-stream " }\n") + 2672 (write _test-input-stream "}\n") + 2673 # convert + 2674 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2675 (flush _test-output-buffered-file) + 2676 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2682 # check output + 2683 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-var-in-nested-block/0") + 2684 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-var-in-nested-block/1") + 2685 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-var-in-nested-block/2") + 2686 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-var-in-nested-block/3") + 2687 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/4") + 2688 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-var-in-nested-block/5") + 2689 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/6") + 2690 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-var-in-nested-block/7") + 2691 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-var-in-nested-block/8") + 2692 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-var-in-nested-block/9") + 2693 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-var-in-nested-block/10") + 2694 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-var-in-nested-block/11") + 2695 (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") + 2696 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/13") + 2697 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-var-in-nested-block/14") + 2698 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/15") + 2699 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-var-in-nested-block/16") + 2700 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-var-in-nested-block/17") + 2701 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-var-in-nested-block/18") + 2702 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-var-in-nested-block/19") + 2703 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-var-in-nested-block/20") + 2704 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-var-in-nested-block/21") + 2705 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-var-in-nested-block/22") + 2706 # . epilogue + 2707 89/<- %esp 5/r32/ebp + 2708 5d/pop-to-ebp + 2709 c3/return + 2710 + 2711 test-convert-function-with-multiple-vars-in-nested-blocks: + 2712 # . prologue + 2713 55/push-ebp + 2714 89/<- %ebp 4/r32/esp + 2715 # setup + 2716 (clear-stream _test-input-stream) + 2717 (clear-stream $_test-input-buffered-file->buffer) + 2718 (clear-stream _test-output-stream) + 2719 (clear-stream $_test-output-buffered-file->buffer) + 2720 # + 2721 (write _test-input-stream "fn foo x: int {\n") + 2722 (write _test-input-stream " {\n") + 2723 (write _test-input-stream " var x/eax: int <- copy 0\n") + 2724 (write _test-input-stream " {\n") + 2725 (write _test-input-stream " var y: int\n") + 2726 (write _test-input-stream " x <- add y\n") + 2727 (write _test-input-stream " }\n") + 2728 (write _test-input-stream " }\n") + 2729 (write _test-input-stream "}\n") + 2730 # convert + 2731 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2732 (flush _test-output-buffered-file) + 2733 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2739 # check output + 2740 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/0") + 2741 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/1") + 2742 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/2") + 2743 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/3") + 2744 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/4") + 2745 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/5") + 2746 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/6") + 2747 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/7") + 2748 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/8") + 2749 (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") + 2750 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-multiple-vars-in-nested-blocks/10") + 2751 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/11") + 2752 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/12") + 2753 (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") + 2754 (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") + 2755 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/15") + 2756 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/16") + 2757 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-multiple-vars-in-nested-blocks/17") + 2758 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/18") + 2759 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/19") + 2760 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-multiple-vars-in-nested-blocks/20") + 2761 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-multiple-vars-in-nested-blocks/21") + 2762 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-multiple-vars-in-nested-blocks/22") + 2763 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/23") + 2764 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-multiple-vars-in-nested-blocks/24") + 2765 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-multiple-vars-in-nested-blocks/25") + 2766 # . epilogue + 2767 89/<- %esp 5/r32/ebp + 2768 5d/pop-to-ebp + 2769 c3/return + 2770 + 2771 test-convert-function-with-branches-and-local-vars: + 2772 # A conditional 'break' after a 'var' in a block is converted into a + 2773 # nested block that performs all necessary cleanup before jumping. This + 2774 # results in some ugly code duplication. + 2775 # . prologue + 2776 55/push-ebp + 2777 89/<- %ebp 4/r32/esp + 2778 # setup + 2779 (clear-stream _test-input-stream) + 2780 (clear-stream $_test-input-buffered-file->buffer) + 2781 (clear-stream _test-output-stream) + 2782 (clear-stream $_test-output-buffered-file->buffer) + 2783 # + 2784 (write _test-input-stream "fn foo {\n") + 2785 (write _test-input-stream " {\n") + 2786 (write _test-input-stream " var x: int\n") + 2787 (write _test-input-stream " break-if->=\n") + 2788 (write _test-input-stream " increment x\n") + 2789 (write _test-input-stream " }\n") + 2790 (write _test-input-stream "}\n") + 2791 # convert + 2792 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2793 (flush _test-output-buffered-file) + 2794 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2800 # check output + 2801 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-local-vars/0") + 2802 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-local-vars/1") + 2803 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-local-vars/2") + 2804 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-and-local-vars/3") + 2805 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/4") + 2806 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-local-vars/5") + 2807 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/6") + 2808 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-local-vars/7") + 2809 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-local-vars/8") + 2810 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-local-vars/9") + 2811 (check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-and-local-vars/10") + 2812 (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") + 2813 (check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-and-local-vars/12") + 2814 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/13") + 2815 (check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0xfffffffc)" "F - test-convert-function-with-branches-and-local-vars/14") + 2816 (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") + 2817 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/16") + 2818 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-local-vars/17") + 2819 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-local-vars/18") + 2820 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-local-vars/19") + 2821 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-local-vars/20") + 2822 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-and-local-vars/21") + 2823 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-local-vars/22") + 2824 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-local-vars/23") + 2825 # . epilogue + 2826 89/<- %esp 5/r32/ebp + 2827 5d/pop-to-ebp + 2828 c3/return + 2829 + 2830 test-convert-function-with-conditional-loops-and-local-vars: + 2831 # A conditional 'loop' after a 'var' in a block is converted into a nested + 2832 # block that performs all necessary cleanup before jumping. This results + 2833 # in some ugly code duplication. + 2834 # . prologue + 2835 55/push-ebp + 2836 89/<- %ebp 4/r32/esp + 2837 # setup + 2838 (clear-stream _test-input-stream) + 2839 (clear-stream $_test-input-buffered-file->buffer) + 2840 (clear-stream _test-output-stream) + 2841 (clear-stream $_test-output-buffered-file->buffer) + 2842 # + 2843 (write _test-input-stream "fn foo {\n") + 2844 (write _test-input-stream " {\n") + 2845 (write _test-input-stream " var x: int\n") + 2846 (write _test-input-stream " loop-if->=\n") + 2847 (write _test-input-stream " increment x\n") + 2848 (write _test-input-stream " }\n") + 2849 (write _test-input-stream "}\n") + 2850 # convert + 2851 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2852 (flush _test-output-buffered-file) + 2853 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2859 # check output + 2860 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-conditional-loops-and-local-vars/0") + 2861 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-conditional-loops-and-local-vars/1") + 2862 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/2") + 2863 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-conditional-loops-and-local-vars/3") + 2864 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/4") + 2865 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/5") + 2866 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/6") + 2867 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-conditional-loops-and-local-vars/7") + 2868 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-conditional-loops-and-local-vars/8") + 2869 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-conditional-loops-and-local-vars/9") + 2870 (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") + 2871 (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") + 2872 (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") + 2873 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/13") + 2874 (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") + 2875 (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") + 2876 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/16") + 2877 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/17") + 2878 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-conditional-loops-and-local-vars/18") + 2879 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-conditional-loops-and-local-vars/19") + 2880 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-conditional-loops-and-local-vars/20") + 2881 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/21") + 2882 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-conditional-loops-and-local-vars/22") + 2883 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-conditional-loops-and-local-vars/23") + 2884 # . epilogue + 2885 89/<- %esp 5/r32/ebp + 2886 5d/pop-to-ebp + 2887 c3/return + 2888 + 2889 test-convert-function-with-unconditional-loops-and-local-vars: + 2890 # An unconditional 'loop' after a 'var' in a block is emitted _after_ the + 2891 # regular block cleanup. Any instructions after 'loop' are dead and + 2892 # therefore skipped. + 2893 # . prologue + 2894 55/push-ebp + 2895 89/<- %ebp 4/r32/esp + 2896 # setup + 2897 (clear-stream _test-input-stream) + 2898 (clear-stream $_test-input-buffered-file->buffer) + 2899 (clear-stream _test-output-stream) + 2900 (clear-stream $_test-output-buffered-file->buffer) + 2901 # + 2902 (write _test-input-stream "fn foo {\n") + 2903 (write _test-input-stream " {\n") + 2904 (write _test-input-stream " var x: int\n") + 2905 (write _test-input-stream " loop\n") + 2906 (write _test-input-stream " increment x\n") + 2907 (write _test-input-stream " }\n") + 2908 (write _test-input-stream "}\n") + 2909 # convert + 2910 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2911 (flush _test-output-buffered-file) + 2912 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2918 # check output + 2919 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-loops-and-local-vars/0") + 2920 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-loops-and-local-vars/1") + 2921 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/2") + 2922 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-loops-and-local-vars/3") + 2923 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/4") + 2924 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/5") + 2925 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-loops-and-local-vars/6") + 2926 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-loops-and-local-vars/7") + 2927 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-loops-and-local-vars/8") + 2928 (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") + 2929 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-unconditional-loops-and-local-vars/10") + 2930 # not emitted: ff 0/subop/increment *(ebp+0xfffffffc) + 2931 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/11") + 2932 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/12") + 2933 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-loops-and-local-vars/13") + 2934 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-loops-and-local-vars/14") + 2935 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-loops-and-local-vars/15") + 2936 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/16") + 2937 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-loops-and-local-vars/17") + 2938 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-loops-and-local-vars/18") + 2939 # . epilogue + 2940 89/<- %esp 5/r32/ebp + 2941 5d/pop-to-ebp + 2942 c3/return + 2943 + 2944 test-convert-function-with-branches-and-loops-and-local-vars: + 2945 # . prologue + 2946 55/push-ebp + 2947 89/<- %ebp 4/r32/esp + 2948 # setup + 2949 (clear-stream _test-input-stream) + 2950 (clear-stream $_test-input-buffered-file->buffer) + 2951 (clear-stream _test-output-stream) + 2952 (clear-stream $_test-output-buffered-file->buffer) + 2953 # + 2954 (write _test-input-stream "fn foo {\n") + 2955 (write _test-input-stream " {\n") + 2956 (write _test-input-stream " var x: int\n") + 2957 (write _test-input-stream " break-if->=\n") + 2958 (write _test-input-stream " increment x\n") + 2959 (write _test-input-stream " loop\n") + 2960 (write _test-input-stream " }\n") + 2961 (write _test-input-stream "}\n") + 2962 # convert + 2963 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 2964 (flush _test-output-buffered-file) + 2965 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 2971 # check output + 2972 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-branches-and-loops-and-local-vars/0") + 2973 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-and-loops-and-local-vars/1") + 2974 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/2") + 2975 (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") + 2976 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/4") + 2977 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/5") + 2978 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/6") + 2979 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-and-loops-and-local-vars/7") + 2980 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-branches-and-loops-and-local-vars/8") + 2981 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-and-loops-and-local-vars/9") + 2982 (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") + 2983 (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") + 2984 (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") + 2985 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/13") + 2986 (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") + 2987 (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") + 2988 (check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-and-loops-and-local-vars/16") + 2989 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/17") + 2990 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/18") + 2991 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-and-loops-and-local-vars/19") + 2992 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-and-loops-and-local-vars/20") + 2993 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-and-loops-and-local-vars/21") + 2994 (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") + 2995 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-and-loops-and-local-vars/23") + 2996 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-and-loops-and-local-vars/24") + 2997 # . epilogue + 2998 89/<- %esp 5/r32/ebp + 2999 5d/pop-to-ebp + 3000 c3/return + 3001 + 3002 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars: + 3003 # . prologue + 3004 55/push-ebp + 3005 89/<- %ebp 4/r32/esp + 3006 # setup + 3007 (clear-stream _test-input-stream) + 3008 (clear-stream $_test-input-buffered-file->buffer) + 3009 (clear-stream _test-output-stream) + 3010 (clear-stream $_test-output-buffered-file->buffer) + 3011 # + 3012 (write _test-input-stream "fn foo {\n") + 3013 (write _test-input-stream " a: {\n") + 3014 (write _test-input-stream " var x: int\n") + 3015 (write _test-input-stream " {\n") + 3016 (write _test-input-stream " var y: int\n") + 3017 (write _test-input-stream " break-if->= a\n") + 3018 (write _test-input-stream " increment x\n") + 3019 (write _test-input-stream " loop\n") + 3020 (write _test-input-stream " }\n") + 3021 (write _test-input-stream " }\n") + 3022 (write _test-input-stream "}\n") + 3023 # convert + 3024 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3025 (flush _test-output-buffered-file) + 3026 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3032 # check output + 3033 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/0") + 3034 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/1") + 3035 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/2") + 3036 (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") + 3037 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/4") + 3038 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/5") + 3039 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/6") + 3040 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/7") + 3041 (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") + 3042 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/9") + 3043 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/10") + 3044 (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") + 3045 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/12") + 3046 (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") + 3047 (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") + 3048 (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") + 3049 (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") + 3050 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/17") + 3051 (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") + 3052 (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") + 3053 (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") + 3054 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/21") + 3055 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/22") + 3056 (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") + 3057 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/24") + 3058 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/25") + 3059 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/26") + 3060 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/27") + 3061 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/28") + 3062 (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") + 3063 (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") + 3064 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/31") + 3065 # . epilogue + 3066 89/<- %esp 5/r32/ebp + 3067 5d/pop-to-ebp + 3068 c3/return + 3069 + 3070 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2: + 3071 # . prologue + 3072 55/push-ebp + 3073 89/<- %ebp 4/r32/esp + 3074 # setup + 3075 (clear-stream _test-input-stream) + 3076 (clear-stream $_test-input-buffered-file->buffer) + 3077 (clear-stream _test-output-stream) + 3078 (clear-stream $_test-output-buffered-file->buffer) + 3079 # non-local conditional branch from a block without a local variable, + 3080 # unwinding a local on the stack + 3081 (write _test-input-stream "fn foo {\n") + 3082 (write _test-input-stream " a: {\n") + 3083 (write _test-input-stream " var x: int\n") + 3084 (write _test-input-stream " {\n") + 3085 (write _test-input-stream " break-if->= a\n") + 3086 (write _test-input-stream " }\n") + 3087 (write _test-input-stream " }\n") + 3088 (write _test-input-stream "}\n") + 3089 # convert + 3090 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3091 (flush _test-output-buffered-file) + 3092 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3098 # check output + 3099 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/0") + 3100 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/1") + 3101 (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") + 3102 (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") + 3103 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/4") + 3104 (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") + 3105 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/6") + 3106 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/7") + 3107 (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") + 3108 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/9") + 3109 (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") + 3110 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/11") + 3111 (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") + 3112 (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") + 3113 (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") + 3114 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/15") + 3115 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/16") + 3116 (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") + 3117 (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") + 3118 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/19") + 3119 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/20") + 3120 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/21") + 3121 (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") + 3122 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/23") + 3123 (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") + 3124 (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") + 3125 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/26") + 3126 # . epilogue + 3127 89/<- %esp 5/r32/ebp + 3128 5d/pop-to-ebp + 3129 c3/return + 3130 + 3131 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3: + 3132 # . prologue + 3133 55/push-ebp + 3134 89/<- %ebp 4/r32/esp + 3135 # setup + 3136 (clear-stream _test-input-stream) + 3137 (clear-stream $_test-input-buffered-file->buffer) + 3138 (clear-stream _test-output-stream) + 3139 (clear-stream $_test-output-buffered-file->buffer) + 3140 # non-local unconditional branch from a block without a local variable, + 3141 # unwinding a local on the stack + 3142 (write _test-input-stream "fn foo {\n") + 3143 (write _test-input-stream " a: {\n") + 3144 (write _test-input-stream " var x: int\n") + 3145 (write _test-input-stream " {\n") + 3146 (write _test-input-stream " break a\n") + 3147 (write _test-input-stream " }\n") + 3148 (write _test-input-stream " }\n") + 3149 (write _test-input-stream "}\n") + 3150 # convert + 3151 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3152 (flush _test-output-buffered-file) + 3153 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3159 # check output + 3160 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/0") + 3161 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/1") + 3162 (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") + 3163 (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") + 3164 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/4") + 3165 (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") + 3166 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/6") + 3167 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/7") + 3168 (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") + 3169 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/9") + 3170 (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") + 3171 (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") + 3172 (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") + 3173 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/14") + 3174 (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") + 3175 (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") + 3176 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/17") + 3177 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/18") + 3178 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/19") + 3179 (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") + 3180 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/21") + 3181 (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") + 3182 (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") + 3183 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/24") + 3184 # . epilogue + 3185 89/<- %esp 5/r32/ebp + 3186 5d/pop-to-ebp + 3187 c3/return + 3188 + 3189 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4: + 3190 # . prologue + 3191 55/push-ebp + 3192 89/<- %ebp 4/r32/esp + 3193 # setup + 3194 (clear-stream _test-input-stream) + 3195 (clear-stream $_test-input-buffered-file->buffer) + 3196 (clear-stream _test-output-stream) + 3197 (clear-stream $_test-output-buffered-file->buffer) + 3198 # + 3199 (write _test-input-stream "fn foo {\n") + 3200 (write _test-input-stream " a: {\n") + 3201 (write _test-input-stream " var x/esi: int <- copy 0\n") + 3202 (write _test-input-stream " {\n") + 3203 (write _test-input-stream " break a\n") + 3204 (write _test-input-stream " }\n") + 3205 (write _test-input-stream " }\n") + 3206 (write _test-input-stream "}\n") + 3207 # convert + 3208 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3209 (flush _test-output-buffered-file) + 3210 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3216 # check output + 3217 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/0") + 3218 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/1") + 3219 (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") + 3220 (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") + 3221 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/4") + 3222 (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") + 3223 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/6") + 3224 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/7") + 3225 (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") + 3226 (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") + 3227 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/10") + 3228 (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") + 3229 (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") + 3230 (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") + 3231 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/14") + 3232 (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") + 3233 (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") + 3234 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/17") + 3235 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/18") + 3236 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/19") + 3237 (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") + 3238 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/21") + 3239 (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") + 3240 (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") + 3241 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/24") + 3242 # . epilogue + 3243 89/<- %esp 5/r32/ebp + 3244 5d/pop-to-ebp + 3245 c3/return + 3246 + 3247 test-convert-function-with-nonlocal-unconditional-break-and-local-vars: + 3248 # . prologue + 3249 55/push-ebp + 3250 89/<- %ebp 4/r32/esp + 3251 # setup + 3252 (clear-stream _test-input-stream) + 3253 (clear-stream $_test-input-buffered-file->buffer) + 3254 (clear-stream _test-output-stream) + 3255 (clear-stream $_test-output-buffered-file->buffer) + 3256 # + 3257 (write _test-input-stream "fn foo {\n") + 3258 (write _test-input-stream " a: {\n") + 3259 (write _test-input-stream " var x: int\n") + 3260 (write _test-input-stream " {\n") + 3261 (write _test-input-stream " var y: int\n") + 3262 (write _test-input-stream " break a\n") + 3263 (write _test-input-stream " increment x\n") + 3264 (write _test-input-stream " }\n") + 3265 (write _test-input-stream " }\n") + 3266 (write _test-input-stream "}\n") + 3267 # convert + 3268 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3269 (flush _test-output-buffered-file) + 3270 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3276 # check output + 3277 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/0") + 3278 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/1") + 3279 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/2") + 3280 (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") + 3281 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/4") + 3282 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/5") + 3283 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/6") + 3284 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/7") + 3285 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/8") + 3286 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/9") + 3287 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/10") + 3288 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/11") + 3289 (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") + 3290 (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") + 3291 (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") + 3292 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/15") + 3293 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/16") + 3294 (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") + 3295 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/18") + 3296 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/19") + 3297 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/20") + 3298 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/21") + 3299 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/22") + 3300 (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") + 3301 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/24") + 3302 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/25") + 3303 # . epilogue + 3304 89/<- %esp 5/r32/ebp + 3305 5d/pop-to-ebp + 3306 c3/return + 3307 + 3308 test-convert-function-with-unconditional-break-and-local-vars: + 3309 # . prologue + 3310 55/push-ebp + 3311 89/<- %ebp 4/r32/esp + 3312 # setup + 3313 (clear-stream _test-input-stream) + 3314 (clear-stream $_test-input-buffered-file->buffer) + 3315 (clear-stream _test-output-stream) + 3316 (clear-stream $_test-output-buffered-file->buffer) + 3317 # + 3318 (write _test-input-stream "fn foo {\n") + 3319 (write _test-input-stream " {\n") + 3320 (write _test-input-stream " var x: int\n") + 3321 (write _test-input-stream " {\n") + 3322 (write _test-input-stream " var y: int\n") + 3323 (write _test-input-stream " break\n") + 3324 (write _test-input-stream " increment x\n") + 3325 (write _test-input-stream " }\n") + 3326 (write _test-input-stream " }\n") + 3327 (write _test-input-stream "}\n") + 3328 # convert + 3329 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3330 (flush _test-output-buffered-file) + 3331 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3337 # check output + 3338 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-unconditional-break-and-local-vars/0") + 3339 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-unconditional-break-and-local-vars/1") + 3340 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/2") + 3341 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-unconditional-break-and-local-vars/3") + 3342 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/4") + 3343 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/5") + 3344 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/6") + 3345 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/7") + 3346 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/8") + 3347 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-unconditional-break-and-local-vars/9") + 3348 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-unconditional-break-and-local-vars/10") + 3349 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/11") + 3350 (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") + 3351 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/13") + 3352 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/14") + 3353 (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") + 3354 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/16") + 3355 (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/17") + 3356 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-unconditional-break-and-local-vars/18") + 3357 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-unconditional-break-and-local-vars/19") + 3358 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-unconditional-break-and-local-vars/20") + 3359 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/21") + 3360 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-unconditional-break-and-local-vars/22") + 3361 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-unconditional-break-and-local-vars/23") + 3362 # . epilogue + 3363 89/<- %esp 5/r32/ebp + 3364 5d/pop-to-ebp + 3365 c3/return + 3366 + 3367 test-convert-function-with-nonlocal-unconditional-loop-and-local-vars: + 3368 # . prologue + 3369 55/push-ebp + 3370 89/<- %ebp 4/r32/esp + 3371 # setup + 3372 (clear-stream _test-input-stream) + 3373 (clear-stream $_test-input-buffered-file->buffer) + 3374 (clear-stream _test-output-stream) + 3375 (clear-stream $_test-output-buffered-file->buffer) + 3376 # + 3377 (write _test-input-stream "fn foo {\n") + 3378 (write _test-input-stream " a: {\n") + 3379 (write _test-input-stream " var x: int\n") + 3380 (write _test-input-stream " {\n") + 3381 (write _test-input-stream " var y: int\n") + 3382 (write _test-input-stream " loop a\n") + 3383 (write _test-input-stream " increment x\n") + 3384 (write _test-input-stream " }\n") + 3385 (write _test-input-stream " }\n") + 3386 (write _test-input-stream "}\n") + 3387 # convert + 3388 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3389 (flush _test-output-buffered-file) + 3390 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3396 # check output + 3397 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/0") + 3398 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/1") + 3399 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/2") + 3400 (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") + 3401 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/4") + 3402 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/5") + 3403 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/6") + 3404 (check-next-stream-line-equal _test-output-stream "a:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/7") + 3405 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/8") + 3406 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/9") + 3407 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/10") + 3408 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/11") + 3409 (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") + 3410 (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") + 3411 (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") + 3412 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/15") + 3413 (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/16") + 3414 (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") + 3415 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/18") + 3416 (check-next-stream-line-equal _test-output-stream "a:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/19") + 3417 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/20") + 3418 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/21") + 3419 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/22") + 3420 (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") + 3421 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/24") + 3422 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/25") + 3423 # . epilogue + 3424 89/<- %esp 5/r32/ebp + 3425 5d/pop-to-ebp + 3426 c3/return + 3427 + 3428 test-convert-function-with-local-array-var-in-mem: + 3429 # . prologue + 3430 55/push-ebp + 3431 89/<- %ebp 4/r32/esp + 3432 # setup + 3433 (clear-stream _test-input-stream) + 3434 (clear-stream $_test-input-buffered-file->buffer) + 3435 (clear-stream _test-output-stream) + 3436 (clear-stream $_test-output-buffered-file->buffer) + 3437 # + 3438 (write _test-input-stream "fn foo {\n") + 3439 (write _test-input-stream " var x: (array int 3)\n") + 3440 (write _test-input-stream "}\n") + 3441 # convert + 3442 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3443 (flush _test-output-buffered-file) + 3444 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3450 # check output + 3451 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-var-in-mem/0") + 3452 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-var-in-mem/1") + 3453 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-var-in-mem/2") + 3454 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-array-var-in-mem/3") + 3455 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-var-in-mem/4") + 3456 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-var-in-mem/5") + 3457 # define x + 3458 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-function-with-local-array-var-in-mem/7") + 3459 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-function-with-local-array-var-in-mem/8") + 3460 # reclaim x + 3461 (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") + 3462 # + 3463 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-var-in-mem/10") + 3464 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-var-in-mem/11") + 3465 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-var-in-mem/12") + 3466 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-array-var-in-mem/13") + 3467 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-var-in-mem/14") + 3468 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-var-in-mem/15") + 3469 # . epilogue + 3470 89/<- %esp 5/r32/ebp + 3471 5d/pop-to-ebp + 3472 c3/return + 3473 + 3474 # special-case for size(byte) when allocating array + 3475 test-convert-function-with-local-array-of-bytes-in-mem: + 3476 # . prologue + 3477 55/push-ebp + 3478 89/<- %ebp 4/r32/esp + 3479 # setup + 3480 (clear-stream _test-input-stream) + 3481 (clear-stream $_test-input-buffered-file->buffer) + 3482 (clear-stream _test-output-stream) + 3483 (clear-stream $_test-output-buffered-file->buffer) + 3484 # + 3485 (write _test-input-stream "fn foo {\n") + 3486 (write _test-input-stream " var x: (array byte 3)\n") + 3487 (write _test-input-stream "}\n") + 3488 # convert + 3489 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3490 (flush _test-output-buffered-file) + 3491 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3497 # check output + 3498 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-array-of-bytes-in-mem/0") + 3499 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-array-of-bytes-in-mem/1") + 3500 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/2") + 3501 (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") + 3502 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-array-of-bytes-in-mem/4") + 3503 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-array-of-bytes-in-mem/5") + 3504 # define x + 3505 (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") + 3506 (check-next-stream-line-equal _test-output-stream " 68/push 0x00000003/imm32" "F - test-convert-function-with-local-array-of-bytes-in-mem/8") + 3507 # reclaim x + 3508 (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") + 3509 # + 3510 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-array-of-bytes-in-mem/10") + 3511 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-array-of-bytes-in-mem/11") + 3512 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-array-of-bytes-in-mem/12") + 3513 (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") + 3514 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-array-of-bytes-in-mem/14") + 3515 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-array-of-bytes-in-mem/15") + 3516 # . epilogue + 3517 89/<- %esp 5/r32/ebp + 3518 5d/pop-to-ebp + 3519 c3/return + 3520 + 3521 test-convert-address: + 3522 # . prologue + 3523 55/push-ebp + 3524 89/<- %ebp 4/r32/esp + 3525 # setup + 3526 (clear-stream _test-input-stream) + 3527 (clear-stream $_test-input-buffered-file->buffer) + 3528 (clear-stream _test-output-stream) + 3529 (clear-stream $_test-output-buffered-file->buffer) + 3530 # + 3531 (write _test-input-stream "fn foo {\n") + 3532 (write _test-input-stream " var a: int\n") + 3533 (write _test-input-stream " var b/eax: (addr int) <- address a\n") + 3534 (write _test-input-stream "}\n") + 3535 # convert + 3536 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3537 (flush _test-output-buffered-file) + 3538 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3544 # check output + 3545 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-address/0") + 3546 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-address/1") + 3547 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-address/2") + 3548 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-address/3") + 3549 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-address/4") + 3550 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-address/5") + 3551 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-address/6") + 3552 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-address/7") + 3553 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000000/r32" "F - test-convert-address/8") + 3554 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-address/9") + 3555 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-address/10") + 3556 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-address/11") + 3557 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-address/12") + 3558 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-address/13") + 3559 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-address/14") + 3560 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-address/15") + 3561 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-address/16") + 3562 # . epilogue + 3563 89/<- %esp 5/r32/ebp + 3564 5d/pop-to-ebp + 3565 c3/return + 3566 + 3567 test-convert-length-of-array: + 3568 # . prologue + 3569 55/push-ebp + 3570 89/<- %ebp 4/r32/esp + 3571 # setup + 3572 (clear-stream _test-input-stream) + 3573 (clear-stream $_test-input-buffered-file->buffer) + 3574 (clear-stream _test-output-stream) + 3575 (clear-stream $_test-output-buffered-file->buffer) + 3576 # + 3577 (write _test-input-stream "fn foo a: (addr array int) {\n") + 3578 (write _test-input-stream " var b/eax: (addr array int) <- copy a\n") + 3579 (write _test-input-stream " var c/eax: int <- length b\n") + 3580 (write _test-input-stream "}\n") + 3581 # convert + 3582 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3583 (flush _test-output-buffered-file) + 3584 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3590 # check output + 3591 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array/0") + 3592 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array/1") + 3593 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array/2") + 3594 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array/3") + 3595 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array/4") + 3596 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array/5") + 3597 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array/6") + 3598 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array/7") + 3599 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array/8") + 3600 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array/9") + 3601 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array/10") + 3602 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array/11") + 3603 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array/12") + 3604 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array/13") + 3605 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array/14") + 3606 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array/15") + 3607 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array/16") + 3608 # . epilogue + 3609 89/<- %esp 5/r32/ebp + 3610 5d/pop-to-ebp + 3611 c3/return + 3612 + 3613 # special-case for size(byte) when computing array length + 3614 test-convert-length-of-array-of-bytes: + 3615 # . prologue + 3616 55/push-ebp + 3617 89/<- %ebp 4/r32/esp + 3618 # setup + 3619 (clear-stream _test-input-stream) + 3620 (clear-stream $_test-input-buffered-file->buffer) + 3621 (clear-stream _test-output-stream) + 3622 (clear-stream $_test-output-buffered-file->buffer) + 3623 # + 3624 (write _test-input-stream "fn foo a: (addr array byte) {\n") + 3625 (write _test-input-stream " var b/eax: (addr array byte) <- copy a\n") + 3626 (write _test-input-stream " var c/eax: int <- length b\n") + 3627 (write _test-input-stream "}\n") + 3628 # convert + 3629 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3630 (flush _test-output-buffered-file) + 3631 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3637 # check output + 3638 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-bytes/0") + 3639 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-bytes/1") + 3640 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-bytes/2") + 3641 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-bytes/3") + 3642 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-bytes/4") + 3643 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-bytes/5") + 3644 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-bytes/6") + 3645 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/7") + 3646 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-bytes/8") + 3647 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-bytes/9") + 3648 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-bytes/10") + 3649 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-bytes/11") + 3650 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-bytes/12") + 3651 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-bytes/13") + 3652 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-bytes/14") + 3653 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-bytes/15") + 3654 # . epilogue + 3655 89/<- %esp 5/r32/ebp + 3656 5d/pop-to-ebp + 3657 c3/return + 3658 + 3659 test-convert-length-of-array-on-stack: + 3660 # . prologue + 3661 55/push-ebp + 3662 89/<- %ebp 4/r32/esp + 3663 # setup + 3664 (clear-stream _test-input-stream) + 3665 (clear-stream $_test-input-buffered-file->buffer) + 3666 (clear-stream _test-output-stream) + 3667 (clear-stream $_test-output-buffered-file->buffer) + 3668 # + 3669 (write _test-input-stream "fn foo {\n") + 3670 (write _test-input-stream " var a: (array int 3)\n") + 3671 (write _test-input-stream " var b/eax: int <- length a\n") + 3672 (write _test-input-stream "}\n") + 3673 # convert + 3674 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3675 (flush _test-output-buffered-file) + 3676 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3682 # check output + 3683 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-on-stack/0") + 3684 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-on-stack/1") + 3685 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-on-stack/2") + 3686 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-on-stack/3") + 3687 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-on-stack/4") + 3688 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-on-stack/5") + 3689 # define x + 3690 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-length-of-array-on-stack/6") + 3691 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-length-of-array-on-stack/7") + 3692 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-on-stack/8") + 3693 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff0) 0x00000000/r32" "F - test-convert-length-of-array-on-stack/9") + 3694 (check-next-stream-line-equal _test-output-stream " c1/shift 5/subop/>> %eax 0x00000002/imm8" "F - test-convert-length-of-array-on-stack/10") + 3695 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-on-stack/11") + 3696 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-length-of-array-on-stack/12") + 3697 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-on-stack/13") + 3698 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-on-stack/14") + 3699 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-on-stack/15") + 3700 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-on-stack/16") + 3701 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-on-stack/17") + 3702 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-on-stack/18") + 3703 # . epilogue + 3704 89/<- %esp 5/r32/ebp + 3705 5d/pop-to-ebp + 3706 c3/return + 3707 + 3708 test-reg-var-def-with-read-of-same-register: + 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 (clear-stream _test-error-stream) + 3718 (clear-stream $_test-error-buffered-file->buffer) + 3719 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) # bytes of args in call to convert-mu + 3720 68/push 0/imm32 + 3721 68/push 0/imm32 + 3722 89/<- %edx 4/r32/esp + 3723 (tailor-exit-descriptor %edx 0x10) + 3724 # + 3725 (write _test-input-stream "fn foo {\n") + 3726 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 3727 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 3728 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 3729 (write _test-input-stream "}\n") + 3730 # convert + 3731 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 3732 # registers except esp could be clobbered at this point (though they shouldn't be) + 3733 # restore ed + 3734 89/<- %edx 4/r32/esp + 3735 (flush _test-output-buffered-file) + 3736 (flush _test-error-buffered-file) + 3737 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3743 (check-stream-equal _test-error-stream "" "F - test-reg-var-def-with-read-of-same-register: error stream should be empty") + 3744 # check output + 3745 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-reg-var-def-with-read-of-same-register/0") + 3746 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-reg-var-def-with-read-of-same-register/1") + 3747 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-reg-var-def-with-read-of-same-register/2") + 3748 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-reg-var-def-with-read-of-same-register/3") + 3749 (check-next-stream-line-equal _test-output-stream " {" "F - test-reg-var-def-with-read-of-same-register/4") + 3750 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-reg-var-def-with-read-of-same-register/5") + 3751 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-reg-var-def-with-read-of-same-register/6") + 3752 (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") + 3753 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-reg-var-def-with-read-of-same-register/8") + 3754 (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") + 3755 (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") + 3756 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-reg-var-def-with-read-of-same-register/13") + 3757 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-reg-var-def-with-read-of-same-register/14") + 3758 (check-next-stream-line-equal _test-output-stream " }" "F - test-reg-var-def-with-read-of-same-register/15") + 3759 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-reg-var-def-with-read-of-same-register/16") + 3760 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-reg-var-def-with-read-of-same-register/17") + 3761 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-reg-var-def-with-read-of-same-register/18") + 3762 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-reg-var-def-with-read-of-same-register/19") + 3763 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-reg-var-def-with-read-of-same-register/20") + 3764 # don't restore from ebp + 3765 81 0/subop/add %esp 8/imm32 + 3766 # . epilogue + 3767 5d/pop-to-ebp + 3768 c3/return + 3769 + 3770 test-convert-index-into-array: + 3771 # . prologue + 3772 55/push-ebp + 3773 89/<- %ebp 4/r32/esp + 3774 # setup + 3775 (clear-stream _test-input-stream) + 3776 (clear-stream $_test-input-buffered-file->buffer) + 3777 (clear-stream _test-output-stream) + 3778 (clear-stream $_test-output-buffered-file->buffer) + 3779 # + 3780 (write _test-input-stream "fn foo {\n") + 3781 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 3782 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 3783 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 3784 (write _test-input-stream "}\n") + 3785 # convert + 3786 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3787 (flush _test-output-buffered-file) + 3788 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3794 # check output + 3795 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array/0") + 3796 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array/1") + 3797 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array/2") + 3798 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array/3") + 3799 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array/4") + 3800 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array/5") + 3801 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array/6") + 3802 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array/7") + 3803 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array/8") + 3804 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array/9") + 3805 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32" "F - test-convert-index-into-array/10") + 3806 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array/11") + 3807 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array/12") + 3808 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array/13") + 3809 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array/14") + 3810 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array/15") + 3811 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array/16") + 3812 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array/17") + 3813 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array/18") + 3814 # . epilogue + 3815 89/<- %esp 5/r32/ebp + 3816 5d/pop-to-ebp + 3817 c3/return + 3818 + 3819 test-convert-index-into-array-of-bytes: + 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 byte) <- copy 0\n") + 3831 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 3832 (write _test-input-stream " var x/eax: (addr byte) <- 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-of-bytes/0") + 3845 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes/1") + 3846 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes/2") + 3847 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes/3") + 3848 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes/4") + 3849 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes/5") + 3850 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes/6") + 3851 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-of-bytes/7") + 3852 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes/8") + 3853 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-of-bytes/9") + 3854 (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") + 3855 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes/13") + 3856 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes/14") + 3857 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes/15") + 3858 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes/16") + 3859 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes/17") + 3860 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes/18") + 3861 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes/19") + 3862 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes/20") + 3863 # . epilogue + 3864 89/<- %esp 5/r32/ebp + 3865 5d/pop-to-ebp + 3866 c3/return + 3867 + 3868 test-convert-index-into-array-with-literal: + 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 int) <- copy 0\n") + 3880 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") + 3881 (write _test-input-stream "}\n") + 3882 # convert + 3883 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3884 (flush _test-output-buffered-file) + 3885 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3891 # check output + 3892 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-with-literal/0") + 3893 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-with-literal/1") + 3894 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-with-literal/2") + 3895 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-with-literal/3") + 3896 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-with-literal/4") + 3897 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5") + 3898 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6") + 3899 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7") + 3900 # 2 * 4 bytes/elem + 4 bytes for size = offset 12 + 3901 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/8") + 3902 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/9") + 3903 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/10") + 3904 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-with-literal/11") + 3905 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-with-literal/12") + 3906 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-with-literal/13") + 3907 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-with-literal/14") + 3908 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-with-literal/15") + 3909 # . epilogue + 3910 89/<- %esp 5/r32/ebp + 3911 5d/pop-to-ebp + 3912 c3/return + 3913 + 3914 test-convert-index-into-array-of-bytes-with-literal: + 3915 # . prologue + 3916 55/push-ebp + 3917 89/<- %ebp 4/r32/esp + 3918 # setup + 3919 (clear-stream _test-input-stream) + 3920 (clear-stream $_test-input-buffered-file->buffer) + 3921 (clear-stream _test-output-stream) + 3922 (clear-stream $_test-output-buffered-file->buffer) + 3923 # + 3924 (write _test-input-stream "fn foo {\n") + 3925 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 3926 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") + 3927 (write _test-input-stream "}\n") + 3928 # convert + 3929 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3930 (flush _test-output-buffered-file) + 3931 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3937 # check output + 3938 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-with-literal/0") + 3939 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-with-literal/1") + 3940 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/2") + 3941 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-with-literal/3") + 3942 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-with-literal/4") + 3943 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-with-literal/5") + 3944 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-with-literal/6") + 3945 (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") + 3946 # 2 * 1 byte/elem + 4 bytes for size = offset 6 + 3947 (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") + 3948 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-with-literal/9") + 3949 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-with-literal/10") + 3950 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-with-literal/11") + 3951 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-with-literal/12") + 3952 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-with-literal/13") + 3953 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-with-literal/14") + 3954 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-with-literal/15") + 3955 # . epilogue + 3956 89/<- %esp 5/r32/ebp + 3957 5d/pop-to-ebp + 3958 c3/return + 3959 + 3960 test-convert-index-into-array-on-stack: + 3961 # . prologue + 3962 55/push-ebp + 3963 89/<- %ebp 4/r32/esp + 3964 # setup + 3965 (clear-stream _test-input-stream) + 3966 (clear-stream $_test-input-buffered-file->buffer) + 3967 (clear-stream _test-output-stream) + 3968 (clear-stream $_test-output-buffered-file->buffer) + 3969 # + 3970 (write _test-input-stream "fn foo {\n") + 3971 (write _test-input-stream " var arr: (array int 3)\n") + 3972 (write _test-input-stream " var idx/eax: int <- copy 2\n") + 3973 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 3974 (write _test-input-stream "}\n") + 3975 # convert + 3976 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 3977 (flush _test-output-buffered-file) + 3978 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 3984 # check output + 3985 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack/0") + 3986 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack/1") + 3987 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack/2") + 3988 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack/3") + 3989 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack/4") + 3990 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack/5") + 3991 # var arr + 3992 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack/6") + 3993 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack/7") + 3994 # var idx + 3995 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack/8") + 3996 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 2/imm32" "F - test-convert-index-into-array-on-stack/9") + 3997 # var x is at (ebp-0x10) + idx<<2 + 4 = ebp + idx<<2 - 0xc + 3998 (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") + 3999 # reclaim idx + 4000 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack/11") + 4001 # reclaim arr + 4002 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-index-into-array-on-stack/12") + 4003 # + 4004 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack/13") + 4005 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack/14") + 4006 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack/15") + 4007 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack/16") + 4008 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack/17") + 4009 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack/18") + 4010 # . epilogue + 4011 89/<- %esp 5/r32/ebp + 4012 5d/pop-to-ebp + 4013 c3/return + 4014 + 4015 test-convert-index-into-array-on-stack-with-literal: + 4016 # . prologue + 4017 55/push-ebp + 4018 89/<- %ebp 4/r32/esp + 4019 # setup + 4020 (clear-stream _test-input-stream) + 4021 (clear-stream $_test-input-buffered-file->buffer) + 4022 (clear-stream _test-output-stream) + 4023 (clear-stream $_test-output-buffered-file->buffer) + 4024 # + 4025 (write _test-input-stream "fn foo {\n") + 4026 (write _test-input-stream " var arr: (array int 3)\n") + 4027 (write _test-input-stream " var x/eax: (addr int) <- index arr, 2\n") + 4028 (write _test-input-stream "}\n") + 4029 # convert + 4030 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4031 (flush _test-output-buffered-file) + 4032 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4038 # check output + 4039 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-on-stack-with-literal/0") + 4040 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-on-stack-with-literal/1") + 4041 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-on-stack-with-literal/2") + 4042 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-on-stack-with-literal/3") + 4043 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-on-stack-with-literal/4") + 4044 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-on-stack-with-literal/5") + 4045 # var arr + 4046 (check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-index-into-array-on-stack-with-literal/6") + 4047 (check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-index-into-array-on-stack-with-literal/7") + 4048 # var x + 4049 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-on-stack-with-literal/8") + 4050 # x is at (ebp-0x10) + 4 + 2*4 = ebp-4 + 4051 (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") + 4052 # reclaim x + 4053 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-on-stack-with-literal/10") + 4054 # reclaim arr + 4055 (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") + 4056 # + 4057 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-on-stack-with-literal/12") + 4058 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-on-stack-with-literal/13") + 4059 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-on-stack-with-literal/14") + 4060 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-on-stack-with-literal/15") + 4061 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-on-stack-with-literal/16") + 4062 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-on-stack-with-literal/17") + 4063 # . epilogue + 4064 89/<- %esp 5/r32/ebp + 4065 5d/pop-to-ebp + 4066 c3/return + 4067 + 4068 test-convert-index-into-array-of-bytes-on-stack-with-literal: + 4069 # . prologue + 4070 55/push-ebp + 4071 89/<- %ebp 4/r32/esp + 4072 # setup + 4073 (clear-stream _test-input-stream) + 4074 (clear-stream $_test-input-buffered-file->buffer) + 4075 (clear-stream _test-output-stream) + 4076 (clear-stream $_test-output-buffered-file->buffer) + 4077 # + 4078 (write _test-input-stream "fn foo {\n") + 4079 (write _test-input-stream " var arr: (array byte 3)\n") + 4080 (write _test-input-stream " var x/eax: (addr byte) <- index arr, 2\n") + 4081 (write _test-input-stream "}\n") + 4082 # convert + 4083 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4084 (flush _test-output-buffered-file) + 4085 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4091 # check output + 4092 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/0") + 4093 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/1") + 4094 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/2") + 4095 (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") + 4096 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/4") + 4097 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/5") + 4098 # var arr + 4099 (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") + 4100 (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") + 4101 # var x + 4102 (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") + 4103 # x is at (ebp-7) + 4 + 2 = ebp-1 + 4104 (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") + 4105 # reclaim x + 4106 (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") + 4107 # reclaim arr + 4108 (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") + 4109 # + 4110 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/12") + 4111 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/13") + 4112 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/14") + 4113 (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") + 4114 (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") + 4115 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/17") + 4116 # . epilogue + 4117 89/<- %esp 5/r32/ebp + 4118 5d/pop-to-ebp + 4119 c3/return + 4120 + 4121 test-convert-index-into-array-using-offset: + 4122 # . prologue + 4123 55/push-ebp + 4124 89/<- %ebp 4/r32/esp + 4125 # setup + 4126 (clear-stream _test-input-stream) + 4127 (clear-stream $_test-input-buffered-file->buffer) + 4128 (clear-stream _test-output-stream) + 4129 (clear-stream $_test-output-buffered-file->buffer) + 4130 # + 4131 (write _test-input-stream "fn foo {\n") + 4132 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 4133 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 4134 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") + 4135 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") + 4136 (write _test-input-stream "}\n") + 4137 # convert + 4138 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4139 (flush _test-output-buffered-file) + 4140 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4146 # check output + 4147 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset/0") + 4148 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset/1") + 4149 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset/2") + 4150 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset/3") + 4151 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset/4") + 4152 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset/5") + 4153 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset/6") + 4154 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset/7") + 4155 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset/8") + 4156 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-using-offset/9") + 4157 (check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10") + 4158 (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") + 4159 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset/12") + 4160 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset/13") + 4161 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset/14") + 4162 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset/15") + 4163 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset/16") + 4164 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset/17") + 4165 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset/18") + 4166 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset/19") + 4167 # . epilogue + 4168 89/<- %esp 5/r32/ebp + 4169 5d/pop-to-ebp + 4170 c3/return + 4171 + 4172 test-convert-index-into-array-of-bytes-using-offset: + 4173 # . prologue + 4174 55/push-ebp + 4175 89/<- %ebp 4/r32/esp + 4176 # setup + 4177 (clear-stream _test-input-stream) + 4178 (clear-stream $_test-input-buffered-file->buffer) + 4179 (clear-stream _test-output-stream) + 4180 (clear-stream $_test-output-buffered-file->buffer) + 4181 # + 4182 (write _test-input-stream "fn foo {\n") + 4183 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 4184 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 4185 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") + 4186 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") + 4187 (write _test-input-stream "}\n") + 4188 # convert + 4189 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4190 (flush _test-output-buffered-file) + 4191 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4197 # check output + 4198 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset/0") + 4199 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset/1") + 4200 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/2") + 4201 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-of-bytes-using-offset/3") + 4202 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset/4") + 4203 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset/5") + 4204 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-of-bytes-using-offset/6") + 4205 (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") + 4206 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/8") + 4207 (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") + 4208 (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") + 4209 (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") + 4210 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-of-bytes-using-offset/12") + 4211 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-of-bytes-using-offset/13") + 4212 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset/14") + 4213 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset/15") + 4214 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset/16") + 4215 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-of-bytes-using-offset/17") + 4216 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-of-bytes-using-offset/18") + 4217 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset/19") + 4218 # . epilogue + 4219 89/<- %esp 5/r32/ebp + 4220 5d/pop-to-ebp + 4221 c3/return + 4222 + 4223 test-convert-index-into-array-using-offset-on-stack: + 4224 # . prologue + 4225 55/push-ebp + 4226 89/<- %ebp 4/r32/esp + 4227 # setup + 4228 (clear-stream _test-input-stream) + 4229 (clear-stream $_test-input-buffered-file->buffer) + 4230 (clear-stream _test-output-stream) + 4231 (clear-stream $_test-output-buffered-file->buffer) + 4232 # + 4233 (write _test-input-stream "fn foo {\n") + 4234 (write _test-input-stream " var arr/eax: (addr array int) <- copy 0\n") + 4235 (write _test-input-stream " var idx: int\n") + 4236 (write _test-input-stream " var off/ecx: (offset int) <- compute-offset arr, idx\n") + 4237 (write _test-input-stream " var x/eax: (addr int) <- index arr, off\n") + 4238 (write _test-input-stream "}\n") + 4239 # convert + 4240 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4241 (flush _test-output-buffered-file) + 4242 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4248 # check output + 4249 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-using-offset-on-stack/0") + 4250 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-using-offset-on-stack/1") + 4251 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-using-offset-on-stack/2") + 4252 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-index-into-array-using-offset-on-stack/3") + 4253 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-using-offset-on-stack/4") + 4254 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-using-offset-on-stack/5") + 4255 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-using-offset-on-stack/6") + 4256 (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") + 4257 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/8") + 4258 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset-on-stack/9") + 4259 (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") + 4260 (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") + 4261 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset-on-stack/12") + 4262 (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") + 4263 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset-on-stack/14") + 4264 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-using-offset-on-stack/15") + 4265 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-using-offset-on-stack/16") + 4266 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-using-offset-on-stack/17") + 4267 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-index-into-array-using-offset-on-stack/18") + 4268 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-index-into-array-using-offset-on-stack/19") + 4269 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-using-offset-on-stack/20") + 4270 # . epilogue + 4271 89/<- %esp 5/r32/ebp + 4272 5d/pop-to-ebp + 4273 c3/return + 4274 + 4275 test-convert-index-into-array-of-bytes-using-offset-on-stack: + 4276 # . prologue + 4277 55/push-ebp + 4278 89/<- %ebp 4/r32/esp + 4279 # setup + 4280 (clear-stream _test-input-stream) + 4281 (clear-stream $_test-input-buffered-file->buffer) + 4282 (clear-stream _test-output-stream) + 4283 (clear-stream $_test-output-buffered-file->buffer) + 4284 # + 4285 (write _test-input-stream "fn foo {\n") + 4286 (write _test-input-stream " var arr/eax: (addr array byte) <- copy 0\n") + 4287 (write _test-input-stream " var idx: int\n") + 4288 (write _test-input-stream " var off/ecx: (offset byte) <- compute-offset arr, idx\n") + 4289 (write _test-input-stream " var x/eax: (addr byte) <- index arr, off\n") + 4290 (write _test-input-stream "}\n") + 4291 # convert + 4292 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4293 (flush _test-output-buffered-file) + 4294 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4300 # check output + 4301 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/0") + 4302 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/1") + 4303 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/2") + 4304 (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") + 4305 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/4") + 4306 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/5") + 4307 (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") + 4308 (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") + 4309 (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") + 4310 (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") + 4311 (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") + 4312 (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") + 4313 (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") + 4314 (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") + 4315 (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") + 4316 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/15") + 4317 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/16") + 4318 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/17") + 4319 (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") + 4320 (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") + 4321 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/20") + 4322 # . epilogue + 4323 89/<- %esp 5/r32/ebp + 4324 5d/pop-to-ebp + 4325 c3/return + 4326 + 4327 test-convert-function-and-type-definition: + 4328 # . prologue + 4329 55/push-ebp + 4330 89/<- %ebp 4/r32/esp + 4331 # setup + 4332 (clear-stream _test-input-stream) + 4333 (clear-stream $_test-input-buffered-file->buffer) + 4334 (clear-stream _test-output-stream) + 4335 (clear-stream $_test-output-buffered-file->buffer) + 4336 # + 4337 (write _test-input-stream "fn foo a: (addr t) {\n") + 4338 (write _test-input-stream " var _a/eax: (addr t) <- copy a\n") + 4339 (write _test-input-stream " var b/ecx: (addr int) <- get _a, x\n") + 4340 (write _test-input-stream " var c/ecx: (addr int) <- get _a, y\n") + 4341 (write _test-input-stream "}\n") + 4342 (write _test-input-stream "type t {\n") + 4343 (write _test-input-stream " x: int\n") + 4344 (write _test-input-stream " y: int\n") + 4345 (write _test-input-stream "}\n") + 4346 # convert + 4347 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4348 (flush _test-output-buffered-file) + 4349 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4355 # check output + 4356 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-and-type-definition/0") + 4357 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-and-type-definition/1") + 4358 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-and-type-definition/2") + 4359 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-and-type-definition/3") + 4360 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-and-type-definition/4") + 4361 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-and-type-definition/5") + 4362 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-and-type-definition/6") + 4363 (check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7") + 4364 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-and-type-definition/8") + 4365 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000000) 0x00000001/r32" "F - test-convert-function-and-type-definition/9") + 4366 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000004) 0x00000001/r32" "F - test-convert-function-and-type-definition/11") + 4367 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/13") + 4368 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/14") + 4369 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-and-type-definition/15") + 4370 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-and-type-definition/16") + 4371 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-and-type-definition/17") + 4372 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-and-type-definition/18") + 4373 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-and-type-definition/19") + 4374 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-and-type-definition/20") + 4375 # . epilogue + 4376 89/<- %esp 5/r32/ebp + 4377 5d/pop-to-ebp + 4378 c3/return + 4379 + 4380 test-convert-function-with-local-var-with-user-defined-type: + 4381 # . prologue + 4382 55/push-ebp + 4383 89/<- %ebp 4/r32/esp + 4384 # setup + 4385 (clear-stream _test-input-stream) + 4386 (clear-stream $_test-input-buffered-file->buffer) + 4387 (clear-stream _test-output-stream) + 4388 (clear-stream $_test-output-buffered-file->buffer) + 4389 # + 4390 (write _test-input-stream "fn foo {\n") + 4391 (write _test-input-stream " var a: t\n") + 4392 (write _test-input-stream "}\n") + 4393 (write _test-input-stream "type t {\n") + 4394 (write _test-input-stream " x: int\n") + 4395 (write _test-input-stream " y: int\n") + 4396 (write _test-input-stream "}\n") + 4397 # convert + 4398 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4399 (flush _test-output-buffered-file) + 4400 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4406 # check output + 4407 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-with-local-var-with-user-defined-type/0") + 4408 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type/1") + 4409 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/2") + 4410 (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") + 4411 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type/4") + 4412 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type/5") + 4413 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/6") + 4414 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/7") + 4415 (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") + 4416 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type/9") + 4417 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type/10") + 4418 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type/11") + 4419 (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") + 4420 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/13") + 4421 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type/14") + 4422 # . epilogue + 4423 89/<- %esp 5/r32/ebp + 4424 5d/pop-to-ebp + 4425 c3/return + 4426 + 4427 test-convert-function-call-with-arg-of-user-defined-type: + 4428 # . prologue + 4429 55/push-ebp + 4430 89/<- %ebp 4/r32/esp + 4431 # setup + 4432 (clear-stream _test-input-stream) + 4433 (clear-stream $_test-input-buffered-file->buffer) + 4434 (clear-stream _test-output-stream) + 4435 (clear-stream $_test-output-buffered-file->buffer) + 4436 # + 4437 (write _test-input-stream "fn f {\n") + 4438 (write _test-input-stream " var a: t\n") + 4439 (write _test-input-stream " foo a\n") + 4440 (write _test-input-stream "}\n") + 4441 (write _test-input-stream "fn foo x: t {\n") + 4442 (write _test-input-stream "}\n") + 4443 (write _test-input-stream "type t {\n") + 4444 (write _test-input-stream " x: int\n") + 4445 (write _test-input-stream " y: int\n") + 4446 (write _test-input-stream "}\n") + 4447 # convert + 4448 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4449 (flush _test-output-buffered-file) + 4450 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4456 # check output + 4457 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") + 4458 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") + 4459 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") + 4460 (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") + 4461 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") + 4462 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") + 4463 # var a: t + 4464 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/6") + 4465 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-call-with-arg-of-user-defined-type/7") + 4466 # foo a + 4467 (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") + 4468 # + 4469 (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") + 4470 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") + 4471 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") + 4472 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") + 4473 (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") + 4474 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") + 4475 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") + 4476 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") + 4477 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") + 4478 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") + 4479 (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") + 4480 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") + 4481 (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") + 4482 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") + 4483 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") + 4484 # . epilogue + 4485 89/<- %esp 5/r32/ebp + 4486 5d/pop-to-ebp + 4487 c3/return + 4488 + 4489 test-convert-function-call-with-arg-of-user-defined-type-register-indirect: + 4490 # . prologue + 4491 55/push-ebp + 4492 89/<- %ebp 4/r32/esp + 4493 # setup + 4494 (clear-stream _test-input-stream) + 4495 (clear-stream $_test-input-buffered-file->buffer) + 4496 (clear-stream _test-output-stream) + 4497 (clear-stream $_test-output-buffered-file->buffer) + 4498 # + 4499 (write _test-input-stream "fn f {\n") + 4500 (write _test-input-stream " var a/eax: (addr t) <- copy 0\n") + 4501 (write _test-input-stream " foo *a\n") + 4502 (write _test-input-stream "}\n") + 4503 (write _test-input-stream "fn foo x: t {\n") + 4504 (write _test-input-stream "}\n") + 4505 (write _test-input-stream "type t {\n") + 4506 (write _test-input-stream " x: int\n") + 4507 (write _test-input-stream " y: int\n") + 4508 (write _test-input-stream "}\n") + 4509 # convert + 4510 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4511 (flush _test-output-buffered-file) + 4512 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4518 # check output + 4519 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type/0") + 4520 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/1") + 4521 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/2") + 4522 (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") + 4523 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type/4") + 4524 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type/5") + 4525 # var a + 4526 (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") + 4527 (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") + 4528 # foo a + 4529 (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") + 4530 # + 4531 (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") + 4532 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type/10") + 4533 (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:" "F - test-convert-function-call-with-arg-of-user-defined-type/11") + 4534 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/12") + 4535 (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") + 4536 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/14") + 4537 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/15") + 4538 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type/16") + 4539 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type/17") + 4540 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/18") + 4541 (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") + 4542 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type/20") + 4543 (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") + 4544 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-call-with-arg-of-user-defined-type/22") + 4545 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type/23") + 4546 # . epilogue + 4547 89/<- %esp 5/r32/ebp + 4548 5d/pop-to-ebp + 4549 c3/return + 4550 + 4551 # we don't have special support for call-by-reference; just explicitly create + 4552 # a new variable with the address of the arg + 4553 test-convert-function-call-with-arg-of-user-defined-type-by-reference: + 4554 # . prologue + 4555 55/push-ebp + 4556 89/<- %ebp 4/r32/esp + 4557 # setup + 4558 (clear-stream _test-input-stream) + 4559 (clear-stream $_test-input-buffered-file->buffer) + 4560 (clear-stream _test-output-stream) + 4561 (clear-stream $_test-output-buffered-file->buffer) + 4562 # + 4563 (write _test-input-stream "fn f {\n") + 4564 (write _test-input-stream " var a: t\n") + 4565 (write _test-input-stream " var b/eax: (addr t) <- address a\n") + 4566 (write _test-input-stream " foo b\n") + 4567 (write _test-input-stream "}\n") + 4568 (write _test-input-stream "fn foo x: (addr t) {\n") + 4569 (write _test-input-stream " var x/ecx: (addr int) <- copy x\n") + 4570 (write _test-input-stream " increment *x\n") + 4571 (write _test-input-stream "}\n") + 4572 (write _test-input-stream "type t {\n") + 4573 (write _test-input-stream " x: int\n") + 4574 (write _test-input-stream " y: int\n") + 4575 (write _test-input-stream "}\n") + 4576 # convert + 4577 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4578 (flush _test-output-buffered-file) + 4579 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4585 # check output + 4586 (check-next-stream-line-equal _test-output-stream "f:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/0") + 4587 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/1") + 4588 (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") + 4589 (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") + 4590 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/4") + 4591 (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") + 4592 # var a: t + 4593 (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") + 4594 (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") + 4595 # var b/eax: (addr t) + 4596 (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") + 4597 (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") + 4598 # foo a + 4599 (check-next-stream-line-equal _test-output-stream " (foo %eax)" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/10") + 4600 # + 4601 (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") + 4602 (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") + 4603 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/13") + 4604 (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") + 4605 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/15") + 4606 (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") + 4607 (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") + 4608 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/18") + 4609 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/19") + 4610 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/20") + 4611 (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") + 4612 (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") + 4613 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23") + 4614 (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") + 4615 (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") + 4616 (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") + 4617 (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") + 4618 (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") + 4619 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29") + 4620 (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") + 4621 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/31") + 4622 (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") + 4623 (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") + 4624 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/34") + 4625 # . epilogue + 4626 89/<- %esp 5/r32/ebp + 4627 5d/pop-to-ebp + 4628 c3/return + 4629 + 4630 test-convert-get-on-local-variable: + 4631 # . prologue + 4632 55/push-ebp + 4633 89/<- %ebp 4/r32/esp + 4634 # setup + 4635 (clear-stream _test-input-stream) + 4636 (clear-stream $_test-input-buffered-file->buffer) + 4637 (clear-stream _test-output-stream) + 4638 (clear-stream $_test-output-buffered-file->buffer) + 4639 # + 4640 (write _test-input-stream "fn foo {\n") + 4641 (write _test-input-stream " var a: t\n") + 4642 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 4643 (write _test-input-stream "}\n") + 4644 (write _test-input-stream "type t {\n") + 4645 (write _test-input-stream " x: int\n") + 4646 (write _test-input-stream " y: int\n") + 4647 (write _test-input-stream "}\n") + 4648 # convert + 4649 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4650 (flush _test-output-buffered-file) + 4651 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4657 # check output + 4658 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-local-variable/0") + 4659 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-local-variable/1") + 4660 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-local-variable/2") + 4661 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-local-variable/3") + 4662 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-local-variable/4") + 4663 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-local-variable/5") + 4664 # var a + 4665 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/6") + 4666 (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-get-on-local-variable/7") + 4667 # var c + 4668 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-local-variable/8") + 4669 # get + 4670 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0xfffffffc) 0x00000001/r32" "F - test-convert-get-on-local-variable/9") + 4671 # reclaim c + 4672 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-local-variable/10") + 4673 # reclaim a + 4674 (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-get-on-local-variable/11") + 4675 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-local-variable/12") + 4676 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-local-variable/13") + 4677 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-local-variable/14") + 4678 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-local-variable/15") + 4679 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-local-variable/16") + 4680 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-local-variable/17") + 4681 # . epilogue + 4682 89/<- %esp 5/r32/ebp + 4683 5d/pop-to-ebp + 4684 c3/return + 4685 + 4686 test-convert-get-on-function-argument: + 4687 # . prologue + 4688 55/push-ebp + 4689 89/<- %ebp 4/r32/esp + 4690 # setup + 4691 (clear-stream _test-input-stream) + 4692 (clear-stream $_test-input-buffered-file->buffer) + 4693 (clear-stream _test-output-stream) + 4694 (clear-stream $_test-output-buffered-file->buffer) + 4695 # + 4696 (write _test-input-stream "fn foo a: t {\n") + 4697 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 4698 (write _test-input-stream "}\n") + 4699 (write _test-input-stream "type t {\n") + 4700 (write _test-input-stream " x: int\n") + 4701 (write _test-input-stream " y: int\n") + 4702 (write _test-input-stream "}\n") + 4703 # convert + 4704 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4705 (flush _test-output-buffered-file) + 4706 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4712 # check output + 4713 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument/0") + 4714 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument/1") + 4715 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument/2") + 4716 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument/3") + 4717 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument/4") + 4718 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument/5") + 4719 # var c + 4720 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument/6") + 4721 # get + 4722 (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(ebp+0x0000000c) 0x00000001/r32" "F - test-convert-get-on-function-argument/7") + 4723 # reclaim c + 4724 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument/8") + 4725 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument/9") + 4726 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument/10") + 4727 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument/11") + 4728 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument/12") + 4729 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument/13") + 4730 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument/14") + 4731 # . epilogue + 4732 89/<- %esp 5/r32/ebp + 4733 5d/pop-to-ebp + 4734 c3/return + 4735 + 4736 test-convert-get-on-function-argument-with-known-type: + 4737 # . prologue + 4738 55/push-ebp + 4739 89/<- %ebp 4/r32/esp + 4740 # setup + 4741 (clear-stream _test-input-stream) + 4742 (clear-stream $_test-input-buffered-file->buffer) + 4743 (clear-stream _test-output-stream) + 4744 (clear-stream $_test-output-buffered-file->buffer) + 4745 # + 4746 (write _test-input-stream "type t {\n") + 4747 (write _test-input-stream " x: int\n") + 4748 (write _test-input-stream " y: int\n") + 4749 (write _test-input-stream "}\n") + 4750 (write _test-input-stream "fn foo a: t {\n") + 4751 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 4752 (write _test-input-stream "}\n") + 4753 # convert + 4754 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4755 (flush _test-output-buffered-file) + 4756 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 4762 # check output + 4763 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-get-on-function-argument-with-known-type/0") + 4764 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-get-on-function-argument-with-known-type/1") + 4765 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-get-on-function-argument-with-known-type/2") + 4766 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-get-on-function-argument-with-known-type/3") + 4767 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-get-on-function-argument-with-known-type/4") + 4768 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-get-on-function-argument-with-known-type/5") + 4769 # var c + 4770 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-get-on-function-argument-with-known-type/6") + 4771 # get + 4772 (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") + 4773 # reclaim c + 4774 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument-with-known-type/8") + 4775 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-get-on-function-argument-with-known-type/9") + 4776 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-get-on-function-argument-with-known-type/10") + 4777 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-get-on-function-argument-with-known-type/11") + 4778 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-get-on-function-argument-with-known-type/12") + 4779 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-get-on-function-argument-with-known-type/13") + 4780 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-get-on-function-argument-with-known-type/14") + 4781 # . epilogue + 4782 89/<- %esp 5/r32/ebp + 4783 5d/pop-to-ebp + 4784 c3/return + 4785 + 4786 test-add-with-too-many-inouts: + 4787 # . prologue + 4788 55/push-ebp + 4789 89/<- %ebp 4/r32/esp + 4790 # setup + 4791 (clear-stream _test-input-stream) + 4792 (clear-stream $_test-input-buffered-file->buffer) + 4793 (clear-stream _test-output-stream) + 4794 (clear-stream $_test-output-buffered-file->buffer) + 4795 (clear-stream _test-error-stream) + 4796 (clear-stream $_test-error-buffered-file->buffer) + 4797 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 4798 68/push 0/imm32 + 4799 68/push 0/imm32 + 4800 89/<- %edx 4/r32/esp + 4801 (tailor-exit-descriptor %edx 0x10) + 4802 # + 4803 (write _test-input-stream "fn foo {\n") + 4804 (write _test-input-stream " var a: int\n") + 4805 (write _test-input-stream " var b/ecx: int <- add a, 0\n") + 4806 (write _test-input-stream "}\n") + 4807 # convert + 4808 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 4809 # registers except esp clobbered at this point + 4810 # restore ed + 4811 89/<- %edx 4/r32/esp + 4812 (flush _test-output-buffered-file) + 4813 (flush _test-error-buffered-file) + 4814 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 4820 # check output + 4821 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts: output should be empty") + 4822 (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") + 4823 # check that stop(1) was called + 4824 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts: exit status") + 4825 # don't restore from ebp + 4826 81 0/subop/add %esp 8/imm32 + 4827 # . epilogue + 4828 5d/pop-to-ebp + 4829 c3/return + 4830 + 4831 test-add-with-too-many-inouts-2: + 4832 # . prologue + 4833 55/push-ebp + 4834 89/<- %ebp 4/r32/esp + 4835 # setup + 4836 (clear-stream _test-input-stream) + 4837 (clear-stream $_test-input-buffered-file->buffer) + 4838 (clear-stream _test-output-stream) + 4839 (clear-stream $_test-output-buffered-file->buffer) + 4840 (clear-stream _test-error-stream) + 4841 (clear-stream $_test-error-buffered-file->buffer) + 4842 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 4843 68/push 0/imm32 + 4844 68/push 0/imm32 + 4845 89/<- %edx 4/r32/esp + 4846 (tailor-exit-descriptor %edx 0x10) + 4847 # + 4848 (write _test-input-stream "fn foo {\n") + 4849 (write _test-input-stream " var a: int\n") + 4850 (write _test-input-stream " add-to a, 0, 1\n") + 4851 (write _test-input-stream "}\n") + 4852 # convert + 4853 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 4854 # registers except esp clobbered at this point + 4855 # restore ed + 4856 89/<- %edx 4/r32/esp + 4857 (flush _test-output-buffered-file) + 4858 (flush _test-error-buffered-file) + 4859 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 4865 # check output + 4866 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-inouts-2: output should be empty") + 4867 (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") + 4868 # check that stop(1) was called + 4869 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts-2: exit status") + 4870 # don't restore from ebp + 4871 81 0/subop/add %esp 8/imm32 + 4872 # . epilogue + 4873 5d/pop-to-ebp + 4874 c3/return + 4875 + 4876 test-add-with-too-many-outputs: + 4877 # . prologue + 4878 55/push-ebp + 4879 89/<- %ebp 4/r32/esp + 4880 # setup + 4881 (clear-stream _test-input-stream) + 4882 (clear-stream $_test-input-buffered-file->buffer) + 4883 (clear-stream _test-output-stream) + 4884 (clear-stream $_test-output-buffered-file->buffer) + 4885 (clear-stream _test-error-stream) + 4886 (clear-stream $_test-error-buffered-file->buffer) + 4887 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 4888 68/push 0/imm32 + 4889 68/push 0/imm32 + 4890 89/<- %edx 4/r32/esp + 4891 (tailor-exit-descriptor %edx 0x10) + 4892 # 4893 (write _test-input-stream "fn foo {\n") - 4894 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 4895 (write _test-input-stream " var x/eax: (addr t) <- length arr\n") - 4896 (write _test-input-stream "}\n") - 4897 # convert - 4898 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4899 (flush _test-output-buffered-file) - 4900 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4906 # check output - 4907 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/0") - 4908 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/1") - 4909 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/2") - 4910 (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") - 4911 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-eax/4") - 4912 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/5") - 4913 # var arr - 4914 (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") - 4915 (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") - 4916 # length instruction - 4917 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/8") - 4918 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/9") - 4919 (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") - 4920 (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") - 4921 (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") - 4922 (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") - 4923 (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") - 4924 (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") - 4925 # reclaim arr - 4926 (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") - 4927 # - 4928 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-eax/17") - 4929 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/18") - 4930 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/19") - 4931 (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") - 4932 (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") - 4933 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-eax/22") - 4934 # . epilogue - 4935 89/<- %esp 5/r32/ebp - 4936 5d/pop-to-ebp - 4937 c3/return - 4938 - 4939 test-convert-length-of-array-of-user-defined-types-to-ecx: - 4940 # . prologue - 4941 55/push-ebp - 4942 89/<- %ebp 4/r32/esp - 4943 # setup - 4944 (clear-stream _test-input-stream) - 4945 (clear-stream $_test-input-buffered-file->buffer) - 4946 (clear-stream _test-output-stream) - 4947 (clear-stream $_test-output-buffered-file->buffer) - 4948 # - 4949 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 - 4950 (write _test-input-stream " x: int\n") - 4951 (write _test-input-stream " y: int\n") - 4952 (write _test-input-stream " z: int\n") - 4953 (write _test-input-stream "}\n") - 4954 (write _test-input-stream "fn foo {\n") - 4955 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 4956 (write _test-input-stream " var x/ecx: (addr t) <- length arr\n") - 4957 (write _test-input-stream "}\n") - 4958 # convert - 4959 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 4960 (flush _test-output-buffered-file) - 4961 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 4967 # check output - 4968 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/0") - 4969 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/1") - 4970 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/2") - 4971 (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") - 4972 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/4") - 4973 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/5") - 4974 # var a - 4975 (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") - 4976 (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") - 4977 # var x - 4978 (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") - 4979 # length instruction - 4980 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/9") - 4981 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/10") - 4982 (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") - 4983 (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") - 4984 (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") - 4985 (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") - 4986 (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") - 4987 (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") - 4988 (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") - 4989 # reclaim x - 4990 (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") - 4991 # reclaim a - 4992 (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") - 4993 # - 4994 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/20") - 4995 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/21") - 4996 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/22") - 4997 (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") - 4998 (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") - 4999 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/25") - 5000 # . epilogue - 5001 89/<- %esp 5/r32/ebp - 5002 5d/pop-to-ebp - 5003 c3/return - 5004 - 5005 test-convert-length-of-array-of-user-defined-types-to-edx: - 5006 # . prologue - 5007 55/push-ebp - 5008 89/<- %ebp 4/r32/esp - 5009 # setup - 5010 (clear-stream _test-input-stream) - 5011 (clear-stream $_test-input-buffered-file->buffer) - 5012 (clear-stream _test-output-stream) - 5013 (clear-stream $_test-output-buffered-file->buffer) - 5014 # - 5015 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 - 5016 (write _test-input-stream " x: int\n") - 5017 (write _test-input-stream " y: int\n") - 5018 (write _test-input-stream " z: int\n") - 5019 (write _test-input-stream "}\n") - 5020 (write _test-input-stream "fn foo {\n") - 5021 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 5022 (write _test-input-stream " var x/edx: (addr t) <- length arr\n") - 5023 (write _test-input-stream "}\n") - 5024 # convert - 5025 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5026 (flush _test-output-buffered-file) - 5027 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5033 # check output - 5034 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/0") - 5035 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/1") - 5036 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/2") - 5037 (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") - 5038 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-edx/4") - 5039 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/5") - 5040 # var a - 5041 (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") - 5042 (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") - 5043 # var x - 5044 (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") - 5045 # length instruction - 5046 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/9") - 5047 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/10") - 5048 (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") - 5049 (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") - 5050 (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") - 5051 (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") - 5052 (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") - 5053 (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") - 5054 (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") - 5055 # reclaim x - 5056 (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") - 5057 # reclaim a - 5058 (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") - 5059 # - 5060 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-edx/20") - 5061 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/21") - 5062 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/22") - 5063 (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") - 5064 (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") - 5065 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-edx/25") - 5066 # . epilogue - 5067 89/<- %esp 5/r32/ebp - 5068 5d/pop-to-ebp - 5069 c3/return - 5070 - 5071 test-convert-length-of-array-of-user-defined-types: - 5072 # . prologue - 5073 55/push-ebp - 5074 89/<- %ebp 4/r32/esp - 5075 # setup - 5076 (clear-stream _test-input-stream) - 5077 (clear-stream $_test-input-buffered-file->buffer) - 5078 (clear-stream _test-output-stream) - 5079 (clear-stream $_test-output-buffered-file->buffer) - 5080 # - 5081 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 - 5082 (write _test-input-stream " x: int\n") - 5083 (write _test-input-stream " y: int\n") - 5084 (write _test-input-stream " z: int\n") - 5085 (write _test-input-stream "}\n") - 5086 (write _test-input-stream "fn foo {\n") - 5087 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") - 5088 (write _test-input-stream " var x/ebx: (addr t) <- length arr\n") - 5089 (write _test-input-stream "}\n") - 5090 # convert - 5091 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) - 5092 (flush _test-output-buffered-file) - 5093 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- - 5099 # check output - 5100 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types/0") - 5101 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types/1") - 5102 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types/2") - 5103 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types/3") - 5104 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types/4") - 5105 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types/5") - 5106 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types/6") - 5107 (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") - 5108 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-length-of-array-of-user-defined-types/8") - 5109 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types/9") - 5110 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types/10") - 5111 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types/11") - 5112 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types/12") - 5113 (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") - 5114 (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") - 5115 (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") - 5116 (check-next-stream-line-equal _test-output-stream " 89/<- %ebx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types/16") - 5117 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types/17") - 5118 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types/18") - 5119 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types/19") - 5120 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ebx" "F - test-convert-length-of-array-of-user-defined-types/20") - 5121 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types/21") - 5122 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types/22") - 5123 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types/23") - 5124 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types/24") - 5125 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types/25") - 5126 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types/26") - 5127 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types/27") + 4894 (write _test-input-stream " var a/eax: int <- copy 0\n") + 4895 (write _test-input-stream " var b/ebx: int <- copy 0\n") + 4896 (write _test-input-stream " var c/ecx: int <- copy 0\n") + 4897 (write _test-input-stream " c, b <- add a\n") + 4898 (write _test-input-stream "}\n") + 4899 # convert + 4900 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 4901 # registers except esp clobbered at this point + 4902 # restore ed + 4903 89/<- %edx 4/r32/esp + 4904 (flush _test-output-buffered-file) + 4905 (flush _test-error-buffered-file) + 4906 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 4912 # check output + 4913 (check-stream-equal _test-output-stream "" "F - test-add-with-too-many-outputs: output should be empty") + 4914 (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") + 4915 # check that stop(1) was called + 4916 (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-outputs: exit status") + 4917 # don't restore from ebp + 4918 81 0/subop/add %esp 8/imm32 + 4919 # . epilogue + 4920 5d/pop-to-ebp + 4921 c3/return + 4922 + 4923 test-add-with-non-number: + 4924 # . prologue + 4925 55/push-ebp + 4926 89/<- %ebp 4/r32/esp + 4927 # setup + 4928 (clear-stream _test-input-stream) + 4929 (clear-stream $_test-input-buffered-file->buffer) + 4930 (clear-stream _test-output-stream) + 4931 (clear-stream $_test-output-buffered-file->buffer) + 4932 (clear-stream _test-error-stream) + 4933 (clear-stream $_test-error-buffered-file->buffer) + 4934 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 4935 68/push 0/imm32 + 4936 68/push 0/imm32 + 4937 89/<- %edx 4/r32/esp + 4938 (tailor-exit-descriptor %edx 0x10) + 4939 # + 4940 (write _test-input-stream "fn foo {\n") + 4941 (write _test-input-stream " var a: int\n") + 4942 (write _test-input-stream " var b/ecx: (addr int) <- add a\n") + 4943 (write _test-input-stream "}\n") + 4944 # convert + 4945 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 4946 # registers except esp clobbered at this point + 4947 # restore ed + 4948 89/<- %edx 4/r32/esp + 4949 (flush _test-output-buffered-file) + 4950 (flush _test-error-buffered-file) + 4951 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 4957 # check output + 4958 (check-stream-equal _test-output-stream "" "F - test-add-with-non-number: output should be empty") + 4959 (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") + 4960 # check that stop(1) was called + 4961 (check-ints-equal *(edx+4) 2 "F - test-add-with-non-number: exit status") + 4962 # don't restore from ebp + 4963 81 0/subop/add %esp 8/imm32 + 4964 # . epilogue + 4965 5d/pop-to-ebp + 4966 c3/return + 4967 + 4968 test-add-with-addr-dereferenced: + 4969 # . prologue + 4970 55/push-ebp + 4971 89/<- %ebp 4/r32/esp + 4972 # setup + 4973 (clear-stream _test-input-stream) + 4974 (clear-stream $_test-input-buffered-file->buffer) + 4975 (clear-stream _test-output-stream) + 4976 (clear-stream $_test-output-buffered-file->buffer) + 4977 # + 4978 (write _test-input-stream "fn foo {\n") + 4979 (write _test-input-stream " var a/eax: (addr int) <- copy 0\n") + 4980 (write _test-input-stream " add-to *a, 1\n") + 4981 (write _test-input-stream "}\n") + 4982 # convert + 4983 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 4984 (flush _test-output-buffered-file) + 4985 # no error + 4986 # . epilogue + 4987 89/<- %esp 5/r32/ebp + 4988 5d/pop-to-ebp + 4989 c3/return + 4990 + 4991 test-get-with-wrong-field: + 4992 # . prologue + 4993 55/push-ebp + 4994 89/<- %ebp 4/r32/esp + 4995 # setup + 4996 (clear-stream _test-input-stream) + 4997 (clear-stream $_test-input-buffered-file->buffer) + 4998 (clear-stream _test-output-stream) + 4999 (clear-stream $_test-output-buffered-file->buffer) + 5000 (clear-stream _test-error-stream) + 5001 (clear-stream $_test-error-buffered-file->buffer) + 5002 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5003 68/push 0/imm32 + 5004 68/push 0/imm32 + 5005 89/<- %edx 4/r32/esp + 5006 (tailor-exit-descriptor %edx 0x10) + 5007 # + 5008 (write _test-input-stream "fn foo {\n") + 5009 (write _test-input-stream " var a: t\n") + 5010 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5011 (write _test-input-stream "}\n") + 5012 (write _test-input-stream "type t {\n") + 5013 (write _test-input-stream " x: int\n") + 5014 (write _test-input-stream "}\n") + 5015 # convert + 5016 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5017 # registers except esp clobbered at this point + 5018 # restore ed + 5019 89/<- %edx 4/r32/esp + 5020 (flush _test-output-buffered-file) + 5021 (flush _test-error-buffered-file) + 5022 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5028 # check output + 5029 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-field: output should be empty") + 5030 (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") + 5031 # check that stop(1) was called + 5032 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-field: exit status") + 5033 # don't restore from ebp + 5034 81 0/subop/add %esp 8/imm32 + 5035 # . epilogue + 5036 5d/pop-to-ebp + 5037 c3/return + 5038 + 5039 test-get-with-wrong-base-type: + 5040 # . prologue + 5041 55/push-ebp + 5042 89/<- %ebp 4/r32/esp + 5043 # setup + 5044 (clear-stream _test-input-stream) + 5045 (clear-stream $_test-input-buffered-file->buffer) + 5046 (clear-stream _test-output-stream) + 5047 (clear-stream $_test-output-buffered-file->buffer) + 5048 (clear-stream _test-error-stream) + 5049 (clear-stream $_test-error-buffered-file->buffer) + 5050 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5051 68/push 0/imm32 + 5052 68/push 0/imm32 + 5053 89/<- %edx 4/r32/esp + 5054 (tailor-exit-descriptor %edx 0x10) + 5055 # + 5056 (write _test-input-stream "fn foo {\n") + 5057 (write _test-input-stream " var a: int\n") + 5058 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5059 (write _test-input-stream "}\n") + 5060 # convert + 5061 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5062 # registers except esp clobbered at this point + 5063 # restore ed + 5064 89/<- %edx 4/r32/esp + 5065 (flush _test-output-buffered-file) + 5066 (flush _test-error-buffered-file) + 5067 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5073 # check output + 5074 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type: output should be empty") + 5075 (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") + 5076 # check that stop(1) was called + 5077 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type: exit status") + 5078 # don't restore from ebp + 5079 81 0/subop/add %esp 8/imm32 + 5080 # . epilogue + 5081 5d/pop-to-ebp + 5082 c3/return + 5083 + 5084 test-get-with-wrong-base-type-2: + 5085 # . prologue + 5086 55/push-ebp + 5087 89/<- %ebp 4/r32/esp + 5088 # setup + 5089 (clear-stream _test-input-stream) + 5090 (clear-stream $_test-input-buffered-file->buffer) + 5091 (clear-stream _test-output-stream) + 5092 (clear-stream $_test-output-buffered-file->buffer) + 5093 (clear-stream _test-error-stream) + 5094 (clear-stream $_test-error-buffered-file->buffer) + 5095 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5096 68/push 0/imm32 + 5097 68/push 0/imm32 + 5098 89/<- %edx 4/r32/esp + 5099 (tailor-exit-descriptor %edx 0x10) + 5100 # + 5101 (write _test-input-stream "fn foo {\n") + 5102 (write _test-input-stream " var a: (addr t)\n") + 5103 (write _test-input-stream " var c/ecx: (addr int) <- get a, y\n") + 5104 (write _test-input-stream "}\n") + 5105 (write _test-input-stream "type t {\n") + 5106 (write _test-input-stream " x: int\n") + 5107 (write _test-input-stream "}\n") + 5108 # convert + 5109 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5110 # registers except esp clobbered at this point + 5111 # restore ed + 5112 89/<- %edx 4/r32/esp + 5113 (flush _test-output-buffered-file) + 5114 (flush _test-error-buffered-file) + 5115 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5121 # check output + 5122 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-base-type-2: output should be empty") + 5123 (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") + 5124 # check that stop(1) was called + 5125 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type-2: exit status") + 5126 # don't restore from ebp + 5127 81 0/subop/add %esp 8/imm32 5128 # . epilogue - 5129 89/<- %esp 5/r32/ebp - 5130 5d/pop-to-ebp - 5131 c3/return - 5132 - 5133 ####################################################### - 5134 # Parsing - 5135 ####################################################### - 5136 - 5137 == data - 5138 - 5139 # Global state added to each var record when parsing a function - 5140 Next-block-index: # (addr int) - 5141 1/imm32 - 5142 - 5143 Curr-block-depth: # (addr int) - 5144 1/imm32 - 5145 - 5146 == code - 5147 - 5148 parse-mu: # in: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) - 5149 # pseudocode - 5150 # var curr-function: (addr handle function) = Program->functions - 5151 # var curr-type: (addr handle typeinfo) = Program->types - 5152 # var line: (stream byte 512) - 5153 # var word-slice: slice - 5154 # while true # line loop - 5155 # clear-stream(line) - 5156 # read-line-buffered(in, line) - 5157 # if (line->write == 0) break # end of file - 5158 # word-slice = next-mu-token(line) - 5159 # if slice-empty?(word-slice) # end of line - 5160 # continue - 5161 # else if slice-starts-with?(word-slice, "#") # comment - 5162 # continue # end of line - 5163 # else if slice-equal?(word-slice, "fn") - 5164 # var new-function: (handle function) = allocate(function) - 5165 # var vars: (stack live-var 256) - 5166 # populate-mu-function-header(line, new-function, vars) - 5167 # populate-mu-function-body(in, new-function, vars) - 5168 # assert(vars->top == 0) - 5169 # *curr-function = new-function - 5170 # curr-function = &new-function->next - 5171 # else if slice-equal?(word-slice, "type") - 5172 # word-slice = next-mu-token(line) - 5173 # type-id = pos-or-insert-slice(Type-id, word-slice) - 5174 # var new-type: (handle typeinfo) = find-or-create-typeinfo(type-id) - 5175 # assert(next-word(line) == "{") - 5176 # populate-mu-type(in, new-type) - 5177 # else - 5178 # abort() - 5179 # - 5180 # . prologue - 5181 55/push-ebp - 5182 89/<- %ebp 4/r32/esp - 5183 # . save registers - 5184 50/push-eax - 5185 51/push-ecx - 5186 52/push-edx - 5187 53/push-ebx - 5188 56/push-esi - 5189 57/push-edi - 5190 # var line/ecx: (stream byte 512) - 5191 81 5/subop/subtract %esp 0x200/imm32 - 5192 68/push 0x200/imm32/size - 5193 68/push 0/imm32/read - 5194 68/push 0/imm32/write - 5195 89/<- %ecx 4/r32/esp - 5196 # var word-slice/edx: slice - 5197 68/push 0/imm32/end - 5198 68/push 0/imm32/start - 5199 89/<- %edx 4/r32/esp - 5200 # var curr-function/edi: (addr handle function) - 5201 bf/copy-to-edi _Program-functions/imm32 - 5202 # var vars/ebx: (stack live-var 256) - 5203 81 5/subop/subtract %esp 0xc00/imm32 - 5204 68/push 0xc00/imm32/size - 5205 68/push 0/imm32/top - 5206 89/<- %ebx 4/r32/esp - 5207 { - 5208 $parse-mu:line-loop: - 5209 (clear-stream %ecx) - 5210 (read-line-buffered *(ebp+8) %ecx) - 5211 # if (line->write == 0) break - 5212 81 7/subop/compare *ecx 0/imm32 - 5213 0f 84/jump-if-= break/disp32 - 5214 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ - 5220 (next-mu-token %ecx %edx) - 5221 # if slice-empty?(word-slice) continue - 5222 (slice-empty? %edx) # => eax - 5223 3d/compare-eax-and 0/imm32/false - 5224 0f 85/jump-if-!= loop/disp32 - 5225 # if (*word-slice->start == "#") continue - 5226 # . eax = *word-slice->start - 5227 8b/-> *edx 0/r32/eax - 5228 8a/copy-byte *eax 0/r32/AL - 5229 81 4/subop/and %eax 0xff/imm32 - 5230 # . if (eax == '#') continue - 5231 3d/compare-eax-and 0x23/imm32/hash - 5232 0f 84/jump-if-= loop/disp32 - 5233 # if (slice-equal?(word-slice, "fn")) parse a function - 5234 { - 5235 $parse-mu:fn: - 5236 (slice-equal? %edx "fn") # => eax - 5237 3d/compare-eax-and 0/imm32/false - 5238 0f 84/jump-if-= break/disp32 - 5239 # var new-function/esi: (handle function) - 5240 68/push 0/imm32 - 5241 68/push 0/imm32 - 5242 89/<- %esi 4/r32/esp - 5243 # populate-mu-function(line, in, vars, new-function) - 5244 (allocate Heap *Function-size %esi) - 5245 # var new-function-addr/eax: (addr function) - 5246 (lookup *esi *(esi+4)) # => eax - 5247 (clear-stack %ebx) - 5248 (populate-mu-function-header %ecx %eax %ebx *(ebp+0xc) *(ebp+0x10)) - 5249 (populate-mu-function-body *(ebp+8) %eax %ebx *(ebp+0xc) *(ebp+0x10)) - 5250 # *curr-function = new-function - 5251 8b/-> *esi 0/r32/eax - 5252 89/<- *edi 0/r32/eax - 5253 8b/-> *(esi+4) 0/r32/eax - 5254 89/<- *(edi+4) 0/r32/eax - 5255 # curr-function = &new-function->next - 5256 # . var tmp/eax: (addr function) = lookup(new-function) - 5257 (lookup *esi *(esi+4)) # => eax - 5258 # . curr-function = &tmp->next - 5259 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next - 5260 # reclaim new-function - 5261 81 0/subop/add %esp 8/imm32 - 5262 # - 5263 e9/jump $parse-mu:line-loop/disp32 - 5264 } - 5265 # if (slice-equal?(word-slice, "type")) parse a type (struct/record) definition - 5266 { - 5267 $parse-mu:type: - 5268 (slice-equal? %edx "type") # => eax - 5269 3d/compare-eax-and 0/imm32 - 5270 0f 84/jump-if-= break/disp32 - 5271 (next-mu-token %ecx %edx) - 5272 # var type-id/eax: int - 5273 (pos-or-insert-slice Type-id %edx) # => eax - 5274 # spill - 5275 51/push-ecx - 5276 # var new-type/ecx: (handle typeinfo) - 5277 68/push 0/imm32 - 5278 68/push 0/imm32 - 5279 89/<- %ecx 4/r32/esp - 5280 (find-or-create-typeinfo %eax %ecx) - 5281 # - 5282 (lookup *ecx *(ecx+4)) # => eax - 5283 # TODO: ensure that 'line' has nothing else but '{' - 5284 #? (dump-typeinfos "=== aaa\n") - 5285 (populate-mu-type *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) # => eax - 5286 #? (dump-typeinfos "=== zzz\n") - 5287 # reclaim new-type - 5288 81 0/subop/add %esp 8/imm32 - 5289 # restore - 5290 59/pop-to-ecx - 5291 e9/jump $parse-mu:line-loop/disp32 - 5292 } - 5293 # otherwise abort - 5294 e9/jump $parse-mu:error1/disp32 - 5295 } # end line loop - 5296 $parse-mu:end: - 5297 # . reclaim locals - 5298 81 0/subop/add %esp 0xe1c/imm32 - 5299 # . restore registers - 5300 5f/pop-to-edi - 5301 5e/pop-to-esi - 5302 5b/pop-to-ebx - 5303 5a/pop-to-edx - 5304 59/pop-to-ecx - 5305 58/pop-to-eax - 5306 # . epilogue - 5307 89/<- %esp 5/r32/ebp - 5308 5d/pop-to-ebp - 5309 c3/return - 5310 - 5311 $parse-mu:error1: - 5312 # error("unexpected top-level command: " word-slice "\n") - 5313 (write-buffered *(ebp+0xc) "unexpected top-level command: ") - 5314 (write-slice-buffered *(ebp+0xc) %edx) - 5315 (write-buffered *(ebp+0xc) "\n") - 5316 (flush *(ebp+0xc)) - 5317 (stop *(ebp+0x10) 1) - 5318 # never gets here - 5319 - 5320 $parse-mu:error2: - 5321 # error(vars->top " vars not reclaimed after fn '" new-function->name "'\n") - 5322 (print-int32-buffered *(ebp+0xc) *ebx) - 5323 (write-buffered *(ebp+0xc) " vars not reclaimed after fn '") - 5324 (write-slice-buffered *(ebp+0xc) *eax) # Function-name - 5325 (write-buffered *(ebp+0xc) "'\n") - 5326 (flush *(ebp+0xc)) - 5327 (stop *(ebp+0x10) 1) - 5328 # never gets here - 5329 - 5330 # scenarios considered: - 5331 # ✗ fn foo # no block - 5332 # ✓ fn foo { - 5333 # ✗ fn foo { { - 5334 # ✗ fn foo { } - 5335 # ✗ fn foo { } { - 5336 # ✗ fn foo x { - 5337 # ✗ fn foo x: { - 5338 # ✓ fn foo x: int { - 5339 # ✓ fn foo x: int { - 5340 # ✓ fn foo x: int -> y/eax: int { - 5341 # TODO: - 5342 # disallow outputs of type `(... addr ...)` - 5343 # disallow inputs of type `(... addr ... addr ...)` - 5344 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) - 5345 # pseudocode: - 5346 # var name: slice - 5347 # next-mu-token(first-line, name) - 5348 # assert(name not in '{' '}' '->') - 5349 # out->name = slice-to-string(name) - 5350 # ## inouts - 5351 # while true - 5352 # ## name - 5353 # name = next-mu-token(first-line) - 5354 # if (name == '{') goto done - 5355 # if (name == '->') break - 5356 # assert(name != '}') - 5357 # var v: (handle var) = parse-var-with-type(name, first-line) - 5358 # assert(v->register == null) - 5359 # # v->block-depth is implicitly 0 - 5360 # out->inouts = append(v, out->inouts) - 5361 # push(vars, {v, false}) - 5362 # ## outputs - 5363 # while true - 5364 # ## name - 5365 # name = next-mu-token(first-line) - 5366 # assert(name not in '{' '}' '->') - 5367 # var v: (handle var) = parse-var-with-type(name, first-line) - 5368 # assert(v->register != null) - 5369 # out->outputs = append(v, out->outputs) - 5370 # done: - 5371 # - 5372 # . prologue - 5373 55/push-ebp - 5374 89/<- %ebp 4/r32/esp - 5375 # . save registers - 5376 50/push-eax - 5377 51/push-ecx - 5378 52/push-edx - 5379 53/push-ebx - 5380 57/push-edi - 5381 # edi = out - 5382 8b/-> *(ebp+0xc) 7/r32/edi - 5383 # var word-slice/ecx: slice - 5384 68/push 0/imm32/end - 5385 68/push 0/imm32/start - 5386 89/<- %ecx 4/r32/esp - 5387 # var v/ebx: (handle var) - 5388 68/push 0/imm32 - 5389 68/push 0/imm32 - 5390 89/<- %ebx 4/r32/esp - 5391 # read function name - 5392 (next-mu-token *(ebp+8) %ecx) - 5393 # error checking - 5394 # TODO: error if name starts with 'break' or 'loop' - 5395 # if (word-slice == '{') abort - 5396 (slice-equal? %ecx "{") # => eax - 5397 3d/compare-eax-and 0/imm32/false - 5398 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 5399 # if (word-slice == '->') abort - 5400 (slice-equal? %ecx "->") # => eax - 5401 3d/compare-eax-and 0/imm32/false - 5402 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 5403 # if (word-slice == '}') abort - 5404 (slice-equal? %ecx "}") # => eax - 5405 3d/compare-eax-and 0/imm32/false - 5406 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 5407 # save function name - 5408 (slice-to-string Heap %ecx %edi) # Function-name - 5409 # save function inouts - 5410 { - 5411 $populate-mu-function-header:check-for-inout: - 5412 (next-mu-token *(ebp+8) %ecx) - 5413 # if (word-slice == '{') goto done - 5414 (slice-equal? %ecx "{") # => eax - 5415 3d/compare-eax-and 0/imm32/false - 5416 0f 85/jump-if-!= $populate-mu-function-header:done/disp32 - 5417 # if (word-slice == '->') break - 5418 (slice-equal? %ecx "->") # => eax - 5419 3d/compare-eax-and 0/imm32/false - 5420 0f 85/jump-if-!= break/disp32 - 5421 # if (word-slice == '}') abort - 5422 (slice-equal? %ecx "}") # => eax - 5423 3d/compare-eax-and 0/imm32/false - 5424 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 5425 # v = parse-var-with-type(word-slice, first-line) - 5426 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x14) *(ebp+0x18)) - 5427 # assert(v->register == null) - 5428 # . eax: (addr var) = lookup(v) - 5429 (lookup *ebx *(ebx+4)) # => eax - 5430 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 5431 0f 85/jump-if-!= $populate-mu-function-header:error2/disp32 - 5432 # v->block-depth is implicitly 0 - 5433 # - 5434 # out->inouts = append(v, out->inouts) - 5435 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts - 5436 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts - 5437 # push(vars, {v, false}) - 5438 (push *(ebp+0x10) *ebx) - 5439 (push *(ebp+0x10) *(ebx+4)) - 5440 (push *(ebp+0x10) 0) # false - 5441 # - 5442 e9/jump loop/disp32 - 5443 } - 5444 # save function outputs - 5445 { - 5446 $populate-mu-function-header:check-for-out: - 5447 (next-mu-token *(ebp+8) %ecx) - 5448 # if (word-slice == '{') break - 5449 (slice-equal? %ecx "{") # => eax - 5450 3d/compare-eax-and 0/imm32/false - 5451 0f 85/jump-if-!= break/disp32 - 5452 # if (word-slice == '->') abort - 5453 (slice-equal? %ecx "->") # => eax - 5454 3d/compare-eax-and 0/imm32/false - 5455 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 5456 # if (word-slice == '}') abort - 5457 (slice-equal? %ecx "}") # => eax - 5458 3d/compare-eax-and 0/imm32/false - 5459 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 - 5460 # v = parse-var-with-type(word-slice, first-line) - 5461 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x14) *(ebp+0x18)) - 5462 # assert(var->register != null) - 5463 # . eax: (addr var) = lookup(v) - 5464 (lookup *ebx *(ebx+4)) # => eax - 5465 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register - 5466 0f 84/jump-if-= $populate-mu-function-header:error3/disp32 - 5467 # out->outputs = append(v, out->outputs) - 5468 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs - 5469 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs - 5470 # - 5471 e9/jump loop/disp32 - 5472 } - 5473 $populate-mu-function-header:done: - 5474 (check-no-tokens-left *(ebp+8)) - 5475 $populate-mu-function-header:end: - 5476 # . reclaim locals - 5477 81 0/subop/add %esp 0x10/imm32 - 5478 # . restore registers - 5479 5f/pop-to-edi - 5480 5b/pop-to-ebx - 5481 5a/pop-to-edx - 5482 59/pop-to-ecx - 5483 58/pop-to-eax - 5484 # . epilogue - 5485 89/<- %esp 5/r32/ebp - 5486 5d/pop-to-ebp - 5487 c3/return - 5488 - 5489 $populate-mu-function-header:error1: - 5490 # error("function header not in form 'fn <name> {'") - 5491 (write-buffered *(ebp+0x14) "function header not in form 'fn <name> [inouts] [-> outputs] {' -- '") - 5492 (flush *(ebp+0x14)) - 5493 (rewind-stream *(ebp+8)) - 5494 (write-stream-data *(ebp+0x14) *(ebp+8)) - 5495 (write-buffered *(ebp+0x14) "'\n") - 5496 (flush *(ebp+0x14)) - 5497 (stop *(ebp+0x18) 1) - 5498 # never gets here - 5499 - 5500 $populate-mu-function-header:error2: - 5501 # error("function inout '" var "' cannot be in a register") - 5502 (write-buffered *(ebp+0x14) "function inout '") - 5503 (write-buffered *(ebp+0x14) *ebx) # Var-name - 5504 (write-buffered *(ebp+0x14) "' cannot be in a register") - 5505 (flush *(ebp+0x14)) - 5506 (stop *(ebp+0x18) 1) - 5507 # never gets here - 5508 - 5509 $populate-mu-function-header:error3: - 5510 # error("function output '" var "' must be in a register") - 5511 (write-buffered *(ebp+0x14) "function output '") - 5512 (lookup *ebx *(ebx+4)) # => eax - 5513 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 5514 (write-buffered *(ebp+0x14) %eax) - 5515 (write-buffered *(ebp+0x14) "' must be in a register, in instruction '") - 5516 (rewind-stream *(ebp+8)) - 5517 (write-stream-data *(ebp+0x14) *(ebp+8)) - 5518 (write-buffered *(ebp+0x14) "'\n") - 5519 (flush *(ebp+0x14)) - 5520 (stop *(ebp+0x18) 1) - 5521 # never gets here - 5522 - 5523 test-function-header-with-arg: - 5524 # . prologue - 5525 55/push-ebp - 5526 89/<- %ebp 4/r32/esp - 5527 # setup - 5528 (clear-stream _test-input-stream) - 5529 (write _test-input-stream "foo n: int {\n") - 5530 # var result/ecx: function - 5531 2b/subtract *Function-size 4/r32/esp - 5532 89/<- %ecx 4/r32/esp - 5533 (zero-out %ecx *Function-size) - 5534 # var vars/ebx: (stack live-var 16) - 5535 81 5/subop/subtract %esp 0xc0/imm32 - 5536 68/push 0xc0/imm32/size - 5537 68/push 0/imm32/top - 5538 89/<- %ebx 4/r32/esp - 5539 # convert - 5540 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) - 5541 # check result->name - 5542 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 5543 (check-strings-equal %eax "foo" "F - test-function-header-with-arg/name") - 5544 # var v/edx: (addr var) = result->inouts->value - 5545 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 5546 (lookup *eax *(eax+4)) # List-value List-value => eax - 5547 89/<- %edx 0/r32/eax - 5548 # check v->name - 5549 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 5550 (check-strings-equal %eax "n" "F - test-function-header-with-arg/inout:0") - 5551 # check v->type - 5552 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 5553 (check-ints-equal *eax 1 "F - test-function-header-with-arg/inout:0/type:0") # Tree-is-atom - 5554 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-arg/inout:0/type:1") # Tree-value - 5555 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-arg/inout:0/type:2") # Tree-right - 5556 # . epilogue - 5557 89/<- %esp 5/r32/ebp - 5558 5d/pop-to-ebp - 5559 c3/return - 5560 - 5561 test-function-header-with-multiple-args: - 5562 # . prologue - 5563 55/push-ebp - 5564 89/<- %ebp 4/r32/esp - 5565 # setup - 5566 (clear-stream _test-input-stream) - 5567 (write _test-input-stream "foo a: int, b: int c: int {\n") - 5568 # result/ecx: function - 5569 2b/subtract *Function-size 4/r32/esp - 5570 89/<- %ecx 4/r32/esp - 5571 (zero-out %ecx *Function-size) - 5572 # var vars/ebx: (stack live-var 16) - 5573 81 5/subop/subtract %esp 0xc0/imm32 - 5574 68/push 0xc0/imm32/size - 5575 68/push 0/imm32/top - 5576 89/<- %ebx 4/r32/esp - 5577 # convert - 5578 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) - 5579 # check result->name - 5580 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 5581 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args/name") - 5582 # var inouts/edx: (addr list var) = lookup(result->inouts) - 5583 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 5584 89/<- %edx 0/r32/eax - 5585 $test-function-header-with-multiple-args:inout0: - 5586 # var v/ebx: (addr var) = lookup(inouts->value) - 5587 (lookup *edx *(edx+4)) # List-value List-value => eax - 5588 89/<- %ebx 0/r32/eax - 5589 # check v->name - 5590 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 5591 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name - 5592 # check v->type - 5593 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 5594 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:0/type:0") # Tree-is-atom - 5595 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:0/type:1") # Tree-value - 5596 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:0/type:2") # Tree-right - 5597 $test-function-header-with-multiple-args:inout1: - 5598 # inouts = lookup(inouts->next) - 5599 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 5600 89/<- %edx 0/r32/eax - 5601 # v = lookup(inouts->value) - 5602 (lookup *edx *(edx+4)) # List-value List-value => eax - 5603 89/<- %ebx 0/r32/eax - 5604 # check v->name - 5605 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 5606 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name - 5607 # check v->type - 5608 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 5609 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:1/type:0") # Tree-is-atom - 5610 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:1/type:1") # Tree-value - 5611 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:1/type:2") # Tree-right - 5612 $test-function-header-with-multiple-args:inout2: - 5613 # inouts = lookup(inouts->next) - 5614 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 5615 89/<- %edx 0/r32/eax - 5616 # v = lookup(inouts->value) - 5617 (lookup *edx *(edx+4)) # List-value List-value => eax - 5618 89/<- %ebx 0/r32/eax - 5619 # check v->name - 5620 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 5621 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name - 5622 # check v->type - 5623 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 5624 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:2/type:0") # Tree-is-atom - 5625 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:2/type:1") # Tree-value - 5626 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:2/type:2") # Tree-right - 5627 # . epilogue - 5628 89/<- %esp 5/r32/ebp - 5629 5d/pop-to-ebp - 5630 c3/return - 5631 - 5632 test-function-header-with-multiple-args-and-outputs: - 5633 # . prologue - 5634 55/push-ebp - 5635 89/<- %ebp 4/r32/esp - 5636 # setup - 5637 (clear-stream _test-input-stream) - 5638 (write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx: int {\n") - 5639 # result/ecx: function - 5640 2b/subtract *Function-size 4/r32/esp - 5641 89/<- %ecx 4/r32/esp - 5642 (zero-out %ecx *Function-size) - 5643 # var vars/ebx: (stack live-var 16) - 5644 81 5/subop/subtract %esp 0xc0/imm32 - 5645 68/push 0xc0/imm32/size - 5646 68/push 0/imm32/top - 5647 89/<- %ebx 4/r32/esp - 5648 # convert - 5649 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) - 5650 # check result->name - 5651 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax - 5652 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args-and-outputs/name") - 5653 # var inouts/edx: (addr list var) = lookup(result->inouts) - 5654 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax - 5655 89/<- %edx 0/r32/eax - 5656 $test-function-header-with-multiple-args-and-outputs:inout0: - 5657 # var v/ebx: (addr var) = lookup(inouts->value) - 5658 (lookup *edx *(edx+4)) # List-value List-value => eax - 5659 89/<- %ebx 0/r32/eax - 5660 # check v->name - 5661 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 5662 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args-and-outputs/inout:0") - 5663 # check v->type - 5664 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 5665 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:0") # Tree-is-atom - 5666 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:1") # Tree-value - 5667 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:2") # Tree-right - 5668 $test-function-header-with-multiple-args-and-outputs:inout1: - 5669 # inouts = lookup(inouts->next) - 5670 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 5671 89/<- %edx 0/r32/eax - 5672 # v = lookup(inouts->value) - 5673 (lookup *edx *(edx+4)) # List-value List-value => eax - 5674 89/<- %ebx 0/r32/eax - 5675 # check v->name - 5676 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 5677 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args-and-outputs/inout:1") - 5678 # check v->type - 5679 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 5680 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:0") # Tree-is-atom - 5681 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:1") # Tree-value - 5682 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:2") # Tree-right - 5683 $test-function-header-with-multiple-args-and-outputs:inout2: - 5684 # inouts = lookup(inouts->next) - 5685 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 5686 89/<- %edx 0/r32/eax - 5687 # v = lookup(inouts->value) - 5688 (lookup *edx *(edx+4)) # List-value List-value => eax - 5689 89/<- %ebx 0/r32/eax - 5690 # check v->name - 5691 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 5692 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args-and-outputs/inout:2") - 5693 # check v->type - 5694 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 5695 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:0") # Tree-is-atom - 5696 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:1") # Tree-value - 5697 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:2") # Tree-right - 5698 $test-function-header-with-multiple-args-and-outputs:out0: - 5699 # var outputs/edx: (addr list var) = lookup(result->outputs) - 5700 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax - 5701 89/<- %edx 0/r32/eax - 5702 # v = lookup(outputs->value) - 5703 (lookup *edx *(edx+4)) # List-value List-value => eax - 5704 89/<- %ebx 0/r32/eax - 5705 # check v->name - 5706 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 5707 (check-strings-equal %eax "x" "F - test-function-header-with-multiple-args-and-outputs/output:0") - 5708 # check v->register - 5709 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax - 5710 (check-strings-equal %eax "ecx" "F - test-function-header-with-multiple-args-and-outputs/output:0/register") - 5711 # check v->type - 5712 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 5713 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:0") # Tree-is-atom - 5714 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:1") # Tree-value - 5715 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:2") # Tree-right - 5716 $test-function-header-with-multiple-args-and-outputs:out1: - 5717 # outputs = lookup(outputs->next) - 5718 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 5719 89/<- %edx 0/r32/eax - 5720 # v = lookup(inouts->value) - 5721 (lookup *edx *(edx+4)) # List-value List-value => eax - 5722 89/<- %ebx 0/r32/eax - 5723 # check v->name - 5724 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax - 5725 (check-strings-equal %eax "y" "F - test-function-header-with-multiple-args-and-outputs/output:1") - 5726 # check v->register - 5727 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax - 5728 (check-strings-equal %eax "edx" "F - test-function-header-with-multiple-args-and-outputs/output:1/register") - 5729 # check v->type - 5730 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax - 5731 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:0") # Tree-is-atom - 5732 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:1") # Tree-value - 5733 (check-ints-equal *(eax+0c) 0 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:2") # Tree-right - 5734 # . epilogue - 5735 89/<- %esp 5/r32/ebp - 5736 5d/pop-to-ebp - 5737 c3/return - 5738 - 5739 # format for variables with types - 5740 # x: int - 5741 # x: int, - 5742 # x/eax: int - 5743 # x/eax: int, - 5744 # ignores at most one trailing comma - 5745 # WARNING: modifies name - 5746 parse-var-with-type: # name: (addr slice), first-line: (addr stream byte), out: (addr handle var), err: (addr buffered-file), ed: (addr exit-descriptor) - 5747 # pseudocode: - 5748 # var s: slice - 5749 # if (!slice-ends-with(name, ":")) - 5750 # abort - 5751 # --name->end to skip ':' - 5752 # next-token-from-slice(name->start, name->end, '/', s) - 5753 # new-var-from-slice(s, out) - 5754 # ## register - 5755 # next-token-from-slice(s->end, name->end, '/', s) - 5756 # if (!slice-empty?(s)) - 5757 # out->register = slice-to-string(s) - 5758 # ## type - 5759 # var type: (handle tree type-id) = parse-type(first-line) - 5760 # out->type = type - 5761 # - 5762 # . prologue - 5763 55/push-ebp - 5764 89/<- %ebp 4/r32/esp - 5765 # . save registers - 5766 50/push-eax - 5767 51/push-ecx - 5768 52/push-edx - 5769 53/push-ebx - 5770 56/push-esi - 5771 57/push-edi - 5772 # esi = name - 5773 8b/-> *(ebp+8) 6/r32/esi - 5774 # if (!slice-ends-with?(name, ":")) abort - 5775 8b/-> *(esi+4) 1/r32/ecx # Slice-end - 5776 49/decrement-ecx - 5777 8a/copy-byte *ecx 1/r32/CL - 5778 81 4/subop/and %ecx 0xff/imm32 - 5779 81 7/subop/compare %ecx 0x3a/imm32/colon - 5780 0f 85/jump-if-!= $parse-var-with-type:abort/disp32 - 5781 # --name->end to skip ':' - 5782 ff 1/subop/decrement *(esi+4) - 5783 # var s/ecx: slice - 5784 68/push 0/imm32/end - 5785 68/push 0/imm32/start - 5786 89/<- %ecx 4/r32/esp - 5787 $parse-var-with-type:parse-name: - 5788 (next-token-from-slice *esi *(esi+4) 0x2f %ecx) # Slice-start, Slice-end, '/' - 5789 $parse-var-with-type:create-var: - 5790 # new-var-from-slice(s, out) - 5791 (new-var-from-slice Heap %ecx *(ebp+0x10)) - 5792 # save out->register - 5793 $parse-var-with-type:save-register: - 5794 # . var out-addr/edi: (addr var) = lookup(*out) - 5795 8b/-> *(ebp+0x10) 7/r32/edi - 5796 (lookup *edi *(edi+4)) # => eax - 5797 89/<- %edi 0/r32/eax - 5798 # . s = next-token(...) - 5799 (next-token-from-slice *(ecx+4) *(esi+4) 0x2f %ecx) # s->end, name->end, '/' - 5800 # . if (!slice-empty?(s)) out->register = slice-to-string(s) - 5801 { - 5802 $parse-var-with-type:write-register: - 5803 (slice-empty? %ecx) # => eax - 5804 3d/compare-eax-and 0/imm32/false - 5805 75/jump-if-!= break/disp8 - 5806 # out->register = slice-to-string(s) - 5807 8d/copy-address *(edi+0x18) 0/r32/eax # Var-register - 5808 (slice-to-string Heap %ecx %eax) - 5809 } - 5810 $parse-var-with-type:save-type: - 5811 8d/copy-address *(edi+8) 0/r32/eax # Var-type - 5812 (parse-type Heap *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) - 5813 $parse-var-with-type:end: - 5814 # . reclaim locals - 5815 81 0/subop/add %esp 8/imm32 - 5816 # . restore registers - 5817 5f/pop-to-edi - 5818 5e/pop-to-esi - 5819 5b/pop-to-ebx - 5820 5a/pop-to-edx - 5821 59/pop-to-ecx - 5822 58/pop-to-eax - 5823 # . epilogue - 5824 89/<- %esp 5/r32/ebp - 5825 5d/pop-to-ebp - 5826 c3/return - 5827 - 5828 $parse-var-with-type:abort: - 5829 # error("var should have form 'name: type' in '" line "'\n") - 5830 (write-buffered *(ebp+0x14) "var should have form 'name: type' in '") - 5831 (flush *(ebp+0x14)) - 5832 (rewind-stream *(ebp+0xc)) - 5833 (write-stream-data *(ebp+0x14) *(ebp+0xc)) - 5834 (write-buffered *(ebp+0x14) "'\n") - 5835 (flush *(ebp+0x14)) - 5836 (stop *(ebp+0x18) 1) - 5837 # never gets here - 5838 - 5839 parse-type: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle tree type-id), err: (addr buffered-file), ed: (addr exit-descriptor) - 5840 # pseudocode: - 5841 # var s: slice = next-mu-token(in) - 5842 # assert s != "" - 5843 # assert s != "->" - 5844 # assert s != "{" - 5845 # assert s != "}" - 5846 # if s == ")" - 5847 # return - 5848 # out = allocate(Tree) - 5849 # if s != "(" - 5850 # HACK: if s is an int, parse and return it - 5851 # out->left-is-atom? = true - 5852 # out->value = pos-or-insert-slice(Type-id, s) - 5853 # return - 5854 # out->left = parse-type(ad, in) - 5855 # out->right = parse-type-tree(ad, in) - 5856 # - 5857 # . prologue - 5858 55/push-ebp - 5859 89/<- %ebp 4/r32/esp - 5860 # . save registers - 5861 50/push-eax - 5862 51/push-ecx - 5863 52/push-edx - 5864 # clear out - 5865 (zero-out *(ebp+0x10) *Handle-size) - 5866 # var s/ecx: slice - 5867 68/push 0/imm32 - 5868 68/push 0/imm32 - 5869 89/<- %ecx 4/r32/esp - 5870 # s = next-mu-token(in) - 5871 (next-mu-token *(ebp+0xc) %ecx) - 5872 #? (write-buffered Stderr "tok: ") - 5873 #? (write-slice-buffered Stderr %ecx) - 5874 #? (write-buffered Stderr "$\n") - 5875 #? (flush Stderr) - 5876 # assert s != "" - 5877 (slice-equal? %ecx "") # => eax - 5878 3d/compare-eax-and 0/imm32/false - 5879 0f 85/jump-if-!= $parse-type:abort/disp32 - 5880 # assert s != "{" - 5881 (slice-equal? %ecx "{") # => eax - 5882 3d/compare-eax-and 0/imm32/false - 5883 0f 85/jump-if-!= $parse-type:abort/disp32 - 5884 # assert s != "}" - 5885 (slice-equal? %ecx "}") # => eax - 5886 3d/compare-eax-and 0/imm32/false - 5887 0f 85/jump-if-!= $parse-type:abort/disp32 - 5888 # assert s != "->" - 5889 (slice-equal? %ecx "->") # => eax - 5890 3d/compare-eax-and 0/imm32/false - 5891 0f 85/jump-if-!= $parse-type:abort/disp32 - 5892 # if (s == ")") return - 5893 (slice-equal? %ecx ")") # => eax - 5894 3d/compare-eax-and 0/imm32/false - 5895 0f 85/jump-if-!= $parse-type:end/disp32 - 5896 # out = new tree - 5897 (allocate *(ebp+8) *Tree-size *(ebp+0x10)) - 5898 # var out-addr/edx: (addr tree type-id) = lookup(*out) - 5899 8b/-> *(ebp+0x10) 2/r32/edx - 5900 (lookup *edx *(edx+4)) # => eax - 5901 89/<- %edx 0/r32/eax - 5902 { - 5903 # if (s != "(") break - 5904 (slice-equal? %ecx "(") # => eax - 5905 3d/compare-eax-and 0/imm32/false - 5906 75/jump-if-!= break/disp8 - 5907 # EGREGIOUS HACK for static array sizes: if s is a number, parse it - 5908 { - 5909 $parse-type:check-for-int: - 5910 (is-hex-int? %ecx) # => eax - 5911 3d/compare-eax-and 0/imm32/false - 5912 74/jump-if-= break/disp8 - 5913 $parse-type:int: - 5914 (parse-hex-int-from-slice %ecx) # => eax - 5915 89/<- *(edx+4) 0/r32/eax # Tree-value - 5916 e9/jump $parse-type:end/disp32 - 5917 } - 5918 $parse-type:atom: - 5919 # out->left-is-atom? = true - 5920 c7 0/subop/copy *edx 1/imm32/true # Tree-is-atom - 5921 # out->value = pos-or-insert-slice(Type-id, s) - 5922 (pos-or-insert-slice Type-id %ecx) # => eax - 5923 89/<- *(edx+4) 0/r32/eax # Tree-value - 5924 e9/jump $parse-type:end/disp32 - 5925 } - 5926 $parse-type:non-atom: - 5927 # otherwise s == "(" - 5928 # out->left = parse-type(ad, in) - 5929 8d/copy-address *(edx+4) 0/r32/eax # Tree-left - 5930 (parse-type *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) - 5931 # out->right = parse-type-tree(ad, in) - 5932 8d/copy-address *(edx+0xc) 0/r32/eax # Tree-right - 5933 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) - 5934 $parse-type:end: - 5935 # . reclaim locals - 5936 81 0/subop/add %esp 8/imm32 - 5937 # . restore registers - 5938 5a/pop-to-edx - 5939 59/pop-to-ecx - 5940 58/pop-to-eax - 5941 # . epilogue - 5942 89/<- %esp 5/r32/ebp - 5943 5d/pop-to-ebp - 5944 c3/return - 5945 - 5946 $parse-type:abort: - 5947 # error("unexpected token when parsing type: '" s "'\n") - 5948 (write-buffered *(ebp+0x14) "unexpected token when parsing type: '") - 5949 (write-slice-buffered *(ebp+0x14) %ecx) - 5950 (write-buffered *(ebp+0x14) "'\n") - 5951 (flush *(ebp+0x14)) - 5952 (stop *(ebp+0x18) 1) - 5953 # never gets here - 5954 - 5955 parse-type-tree: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle tree type-id), err: (addr buffered-file), ed: (addr exit-descriptor) - 5956 # pseudocode: - 5957 # var tmp: (handle tree type-id) = parse-type(ad, in) - 5958 # if tmp == 0 - 5959 # return 0 - 5960 # out = allocate(Tree) - 5961 # out->left = tmp - 5962 # out->right = parse-type-tree(ad, in) - 5963 # - 5964 # . prologue - 5965 55/push-ebp - 5966 89/<- %ebp 4/r32/esp - 5967 # . save registers - 5968 50/push-eax - 5969 51/push-ecx - 5970 52/push-edx - 5971 # - 5972 (zero-out *(ebp+0x10) *Handle-size) - 5973 # var tmp/ecx: (handle tree type-id) - 5974 68/push 0/imm32 - 5975 68/push 0/imm32 - 5976 89/<- %ecx 4/r32/esp - 5977 # tmp = parse-type(ad, in) - 5978 (parse-type *(ebp+8) *(ebp+0xc) %ecx *(ebp+0x14) *(ebp+0x18)) - 5979 # if (tmp == 0) return - 5980 81 7/subop/compare *ecx 0/imm32 - 5981 74/jump-if-= $parse-type-tree:end/disp8 - 5982 # out = new tree - 5983 (allocate *(ebp+8) *Tree-size *(ebp+0x10)) - 5984 # var out-addr/edx: (addr tree) = lookup(*out) - 5985 8b/-> *(ebp+0x10) 2/r32/edx - 5986 (lookup *edx *(edx+4)) # => eax - 5987 89/<- %edx 0/r32/eax - 5988 # out->left = tmp - 5989 8b/-> *ecx 0/r32/eax - 5990 89/<- *(edx+4) 0/r32/eax # Tree-left - 5991 8b/-> *(ecx+4) 0/r32/eax - 5992 89/<- *(edx+8) 0/r32/eax # Tree-left - 5993 # out->right = parse-type-tree(ad, in) - 5994 8d/copy-address *(edx+0xc) 0/r32/eax # Tree-right - 5995 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) - 5996 $parse-type-tree:end: - 5997 # . reclaim locals - 5998 81 0/subop/add %esp 8/imm32 - 5999 # . restore registers - 6000 5a/pop-to-edx - 6001 59/pop-to-ecx - 6002 58/pop-to-eax - 6003 # . epilogue - 6004 89/<- %esp 5/r32/ebp - 6005 5d/pop-to-ebp - 6006 c3/return - 6007 - 6008 next-mu-token: # in: (addr stream byte), out: (addr slice) - 6009 # pseudocode: - 6010 # start: - 6011 # skip-chars-matching-whitespace(in) - 6012 # if in->read >= in->write # end of in - 6013 # out = {0, 0} - 6014 # return - 6015 # out->start = &in->data[in->read] - 6016 # var curr-byte/eax: byte = in->data[in->read] - 6017 # if curr->byte == ',' # comment token - 6018 # ++in->read - 6019 # goto start - 6020 # if curr-byte == '#' # comment - 6021 # goto done # treat as eof - 6022 # if curr-byte == '"' # string literal - 6023 # skip-string(in) - 6024 # goto done # no metadata - 6025 # if curr-byte == '(' - 6026 # ++in->read - 6027 # goto done - 6028 # if curr-byte == ')' - 6029 # ++in->read - 6030 # goto done - 6031 # # read a word - 6032 # while true - 6033 # if in->read >= in->write - 6034 # break - 6035 # curr-byte = in->data[in->read] - 6036 # if curr-byte == ' ' - 6037 # break - 6038 # if curr-byte == '\r' - 6039 # break - 6040 # if curr-byte == '\n' - 6041 # break - 6042 # if curr-byte == '(' - 6043 # break - 6044 # if curr-byte == ')' - 6045 # break - 6046 # if curr-byte == ',' - 6047 # break - 6048 # ++in->read - 6049 # done: - 6050 # out->end = &in->data[in->read] - 6051 # - 6052 # . prologue - 6053 55/push-ebp - 6054 89/<- %ebp 4/r32/esp - 6055 # . save registers - 6056 50/push-eax - 6057 51/push-ecx - 6058 56/push-esi - 6059 57/push-edi - 6060 # esi = in - 6061 8b/-> *(ebp+8) 6/r32/esi - 6062 # edi = out - 6063 8b/-> *(ebp+0xc) 7/r32/edi - 6064 $next-mu-token:start: - 6065 (skip-chars-matching-whitespace %esi) - 6066 $next-mu-token:check0: - 6067 # if (in->read >= in->write) return out = {0, 0} - 6068 # . ecx = in->read - 6069 8b/-> *(esi+4) 1/r32/ecx - 6070 # . if (ecx >= in->write) return out = {0, 0} - 6071 3b/compare<- *esi 1/r32/ecx - 6072 c7 0/subop/copy *edi 0/imm32 - 6073 c7 0/subop/copy *(edi+4) 0/imm32 - 6074 0f 8d/jump-if->= $next-mu-token:end/disp32 - 6075 # out->start = &in->data[in->read] - 6076 8d/copy-address *(esi+ecx+0xc) 0/r32/eax - 6077 89/<- *edi 0/r32/eax - 6078 # var curr-byte/eax: byte = in->data[in->read] - 6079 31/xor-with %eax 0/r32/eax - 6080 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 6081 { - 6082 $next-mu-token:check-for-comma: - 6083 # if (curr-byte != ',') break - 6084 3d/compare-eax-and 0x2c/imm32/comma - 6085 75/jump-if-!= break/disp8 - 6086 # ++in->read - 6087 ff 0/subop/increment *(esi+4) - 6088 # restart - 6089 e9/jump $next-mu-token:start/disp32 - 6090 } - 6091 { - 6092 $next-mu-token:check-for-comment: - 6093 # if (curr-byte != '#') break - 6094 3d/compare-eax-and 0x23/imm32/pound - 6095 75/jump-if-!= break/disp8 - 6096 # return eof - 6097 e9/jump $next-mu-token:done/disp32 - 6098 } - 6099 { - 6100 $next-mu-token:check-for-string-literal: - 6101 # if (curr-byte != '"') break - 6102 3d/compare-eax-and 0x22/imm32/dquote - 6103 75/jump-if-!= break/disp8 - 6104 (skip-string %esi) - 6105 # return - 6106 e9/jump $next-mu-token:done/disp32 - 6107 } - 6108 { - 6109 $next-mu-token:check-for-open-paren: - 6110 # if (curr-byte != '(') break - 6111 3d/compare-eax-and 0x28/imm32/open-paren - 6112 75/jump-if-!= break/disp8 - 6113 # ++in->read - 6114 ff 0/subop/increment *(esi+4) - 6115 # return - 6116 e9/jump $next-mu-token:done/disp32 - 6117 } - 6118 { - 6119 $next-mu-token:check-for-close-paren: - 6120 # if (curr-byte != ')') break - 6121 3d/compare-eax-and 0x29/imm32/close-paren - 6122 75/jump-if-!= break/disp8 - 6123 # ++in->read - 6124 ff 0/subop/increment *(esi+4) - 6125 # return - 6126 e9/jump $next-mu-token:done/disp32 - 6127 } - 6128 { - 6129 $next-mu-token:regular-word-without-metadata: - 6130 # if (in->read >= in->write) break - 6131 # . ecx = in->read - 6132 8b/-> *(esi+4) 1/r32/ecx - 6133 # . if (ecx >= in->write) break - 6134 3b/compare<- *esi 1/r32/ecx - 6135 7d/jump-if->= break/disp8 - 6136 # var c/eax: byte = in->data[in->read] - 6137 31/xor-with %eax 0/r32/eax - 6138 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL - 6139 # if (c == ' ') break - 6140 3d/compare-eax-and 0x20/imm32/space - 6141 74/jump-if-= break/disp8 - 6142 # if (c == '\r') break - 6143 3d/compare-eax-and 0xd/imm32/carriage-return - 6144 74/jump-if-= break/disp8 - 6145 # if (c == '\n') break - 6146 3d/compare-eax-and 0xa/imm32/newline - 6147 74/jump-if-= break/disp8 - 6148 # if (c == '(') break - 6149 3d/compare-eax-and 0x28/imm32/open-paren - 6150 0f 84/jump-if-= break/disp32 - 6151 # if (c == ')') break - 6152 3d/compare-eax-and 0x29/imm32/close-paren - 6153 0f 84/jump-if-= break/disp32 - 6154 # if (c == ',') break - 6155 3d/compare-eax-and 0x2c/imm32/comma - 6156 0f 84/jump-if-= break/disp32 - 6157 # ++in->read - 6158 ff 0/subop/increment *(esi+4) - 6159 # - 6160 e9/jump loop/disp32 - 6161 } - 6162 $next-mu-token:done: - 6163 # out->end = &in->data[in->read] - 6164 8b/-> *(esi+4) 1/r32/ecx - 6165 8d/copy-address *(esi+ecx+0xc) 0/r32/eax - 6166 89/<- *(edi+4) 0/r32/eax - 6167 $next-mu-token:end: - 6168 # . restore registers - 6169 5f/pop-to-edi - 6170 5e/pop-to-esi - 6171 59/pop-to-ecx - 6172 58/pop-to-eax - 6173 # . epilogue - 6174 89/<- %esp 5/r32/ebp - 6175 5d/pop-to-ebp - 6176 c3/return - 6177 - 6178 pos-or-insert-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int - 6179 # . prologue - 6180 55/push-ebp - 6181 89/<- %ebp 4/r32/esp - 6182 # if (pos-slice(arr, s) != -1) return it - 6183 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax - 6184 3d/compare-eax-and -1/imm32 - 6185 75/jump-if-!= $pos-or-insert-slice:end/disp8 - 6186 $pos-or-insert-slice:insert: - 6187 # var s2/eax: (handle array byte) - 6188 68/push 0/imm32 - 6189 68/push 0/imm32 - 6190 89/<- %eax 4/r32/esp - 6191 (slice-to-string Heap *(ebp+0xc) %eax) - 6192 # throw away alloc-id - 6193 (lookup *eax *(eax+4)) # => eax - 6194 (write-int *(ebp+8) %eax) - 6195 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax - 6196 $pos-or-insert-slice:end: - 6197 # . reclaim locals - 6198 81 0/subop/add %esp 8/imm32 - 6199 # . epilogue - 6200 89/<- %esp 5/r32/ebp - 6201 5d/pop-to-ebp - 6202 c3/return - 6203 - 6204 # return the index in an array of strings matching 's', -1 if not found - 6205 # index is denominated in elements, not bytes - 6206 pos-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int - 6207 # . prologue - 6208 55/push-ebp - 6209 89/<- %ebp 4/r32/esp - 6210 # . save registers - 6211 51/push-ecx - 6212 52/push-edx - 6213 53/push-ebx - 6214 56/push-esi - 6215 #? (write-buffered Stderr "pos-slice: ") - 6216 #? (write-slice-buffered Stderr *(ebp+0xc)) - 6217 #? (write-buffered Stderr "\n") - 6218 #? (flush Stderr) - 6219 # esi = arr - 6220 8b/-> *(ebp+8) 6/r32/esi - 6221 # var index/ecx: int = 0 - 6222 b9/copy-to-ecx 0/imm32 - 6223 # var curr/edx: (addr (addr array byte)) = arr->data - 6224 8d/copy-address *(esi+0xc) 2/r32/edx - 6225 # var max/ebx: (addr (addr array byte)) = &arr->data[arr->write] - 6226 8b/-> *esi 3/r32/ebx - 6227 8d/copy-address *(esi+ebx+0xc) 3/r32/ebx - 6228 { - 6229 #? (write-buffered Stderr " ") - 6230 #? (print-int32-buffered Stderr %ecx) - 6231 #? (write-buffered Stderr "\n") - 6232 #? (flush Stderr) - 6233 # if (curr >= max) return -1 - 6234 39/compare %edx 3/r32/ebx - 6235 b8/copy-to-eax -1/imm32 - 6236 73/jump-if-addr>= $pos-slice:end/disp8 - 6237 # if (slice-equal?(s, *curr)) break - 6238 (slice-equal? *(ebp+0xc) *edx) # => eax - 6239 3d/compare-eax-and 0/imm32/false - 6240 75/jump-if-!= break/disp8 - 6241 # ++index - 6242 41/increment-ecx - 6243 # curr += 4 - 6244 81 0/subop/add %edx 4/imm32 - 6245 # - 6246 eb/jump loop/disp8 - 6247 } - 6248 # return index - 6249 89/<- %eax 1/r32/ecx - 6250 $pos-slice:end: - 6251 #? (write-buffered Stderr "=> ") - 6252 #? (print-int32-buffered Stderr %eax) - 6253 #? (write-buffered Stderr "\n") - 6254 # . restore registers - 6255 5e/pop-to-esi - 6256 5b/pop-to-ebx - 6257 5a/pop-to-edx - 6258 59/pop-to-ecx - 6259 # . epilogue - 6260 89/<- %esp 5/r32/ebp - 6261 5d/pop-to-ebp - 6262 c3/return - 6263 - 6264 test-parse-var-with-type: - 6265 # . prologue - 6266 55/push-ebp - 6267 89/<- %ebp 4/r32/esp - 6268 # (eax..ecx) = "x:" - 6269 b8/copy-to-eax "x:"/imm32 - 6270 8b/-> *eax 1/r32/ecx - 6271 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6272 05/add-to-eax 4/imm32 - 6273 # var slice/ecx: slice = {eax, ecx} - 6274 51/push-ecx - 6275 50/push-eax - 6276 89/<- %ecx 4/r32/esp - 6277 # _test-input-stream contains "int" - 6278 (clear-stream _test-input-stream) - 6279 (write _test-input-stream "int") - 6280 # var v/edx: (handle var) - 6281 68/push 0/imm32 - 6282 68/push 0/imm32 - 6283 89/<- %edx 4/r32/esp - 6284 # - 6285 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 6286 # var v-addr/edx: (addr var) = lookup(v) - 6287 (lookup *edx *(edx+4)) # => eax - 6288 89/<- %edx 0/r32/eax - 6289 # check v-addr->name - 6290 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 6291 (check-strings-equal %eax "x" "F - test-parse-var-with-type/name") - 6292 # check v-addr->type - 6293 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 6294 (check-ints-equal *eax 1 "F - test-parse-var-with-type/type:0") # Tree-is-atom - 6295 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type/type:1") # Tree-value - 6296 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type/type:2") # Tree-right - 6297 # . epilogue - 6298 89/<- %esp 5/r32/ebp - 6299 5d/pop-to-ebp - 6300 c3/return - 6301 - 6302 test-parse-var-with-type-and-register: - 6303 # . prologue - 6304 55/push-ebp - 6305 89/<- %ebp 4/r32/esp - 6306 # (eax..ecx) = "x/eax:" - 6307 b8/copy-to-eax "x/eax:"/imm32 - 6308 8b/-> *eax 1/r32/ecx - 6309 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6310 05/add-to-eax 4/imm32 - 6311 # var slice/ecx: slice = {eax, ecx} - 6312 51/push-ecx - 6313 50/push-eax - 6314 89/<- %ecx 4/r32/esp - 6315 # _test-input-stream contains "int" - 6316 (clear-stream _test-input-stream) - 6317 (write _test-input-stream "int") - 6318 # var v/edx: (handle var) - 6319 68/push 0/imm32 - 6320 68/push 0/imm32 - 6321 89/<- %edx 4/r32/esp - 6322 # - 6323 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 6324 # var v-addr/edx: (addr var) = lookup(v) - 6325 (lookup *edx *(edx+4)) # => eax - 6326 89/<- %edx 0/r32/eax - 6327 # check v-addr->name - 6328 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 6329 (check-strings-equal %eax "x" "F - test-parse-var-with-type-and-register/name") - 6330 # check v-addr->register - 6331 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax - 6332 (check-strings-equal %eax "eax" "F - test-parse-var-with-type-and-register/register") - 6333 # check v-addr->type - 6334 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 6335 (check-ints-equal *eax 1 "F - test-parse-var-with-type-and-register/type:0") # Tree-is-atom - 6336 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type-and-register/type:1") # Tree-left - 6337 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type-and-register/type:2") # Tree-right - 6338 # . epilogue - 6339 89/<- %esp 5/r32/ebp - 6340 5d/pop-to-ebp - 6341 c3/return - 6342 - 6343 test-parse-var-with-trailing-characters: - 6344 # . prologue - 6345 55/push-ebp - 6346 89/<- %ebp 4/r32/esp - 6347 # (eax..ecx) = "x:" - 6348 b8/copy-to-eax "x:"/imm32 - 6349 8b/-> *eax 1/r32/ecx - 6350 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6351 05/add-to-eax 4/imm32 - 6352 # var slice/ecx: slice = {eax, ecx} - 6353 51/push-ecx - 6354 50/push-eax - 6355 89/<- %ecx 4/r32/esp - 6356 # _test-input-stream contains "int," - 6357 (clear-stream _test-input-stream) - 6358 (write _test-input-stream "int,") - 6359 # var v/edx: (handle var) - 6360 68/push 0/imm32 - 6361 68/push 0/imm32 - 6362 89/<- %edx 4/r32/esp - 6363 # - 6364 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 6365 # var v-addr/edx: (addr var) = lookup(v) - 6366 (lookup *edx *(edx+4)) # => eax - 6367 89/<- %edx 0/r32/eax - 6368 # check v-addr->name - 6369 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 6370 (check-strings-equal %eax "x" "F - test-parse-var-with-trailing-characters/name") - 6371 # check v-addr->register - 6372 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-trailing-characters/register") # Var-register - 6373 # check v-addr->type - 6374 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 6375 (check-ints-equal *eax 1 "F - test-parse-var-with-trailing-characters/type:0") # Tree-is-atom - 6376 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-trailing-characters/type:1") # Tree-left - 6377 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-trailing-characters/type:1") # Tree-right - 6378 # . epilogue - 6379 89/<- %esp 5/r32/ebp - 6380 5d/pop-to-ebp - 6381 c3/return - 6382 - 6383 test-parse-var-with-register-and-trailing-characters: - 6384 # . prologue - 6385 55/push-ebp - 6386 89/<- %ebp 4/r32/esp - 6387 # (eax..ecx) = "x/eax:" - 6388 b8/copy-to-eax "x/eax:"/imm32 - 6389 8b/-> *eax 1/r32/ecx - 6390 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6391 05/add-to-eax 4/imm32 - 6392 # var slice/ecx: slice = {eax, ecx} - 6393 51/push-ecx - 6394 50/push-eax - 6395 89/<- %ecx 4/r32/esp - 6396 # _test-input-stream contains "int," - 6397 (clear-stream _test-input-stream) - 6398 (write _test-input-stream "int,") - 6399 # var v/edx: (handle var) - 6400 68/push 0/imm32 - 6401 68/push 0/imm32 - 6402 89/<- %edx 4/r32/esp - 6403 # - 6404 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 6405 # var v-addr/edx: (addr var) = lookup(v) - 6406 (lookup *edx *(edx+4)) # => eax - 6407 89/<- %edx 0/r32/eax - 6408 # check v-addr->name - 6409 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 6410 (check-strings-equal %eax "x" "F - test-parse-var-with-register-and-trailing-characters/name") - 6411 # check v-addr->register - 6412 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax - 6413 (check-strings-equal %eax "eax" "F - test-parse-var-with-register-and-trailing-characters/register") - 6414 # check v-addr->type - 6415 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 6416 (check-ints-equal *eax 1 "F - test-parse-var-with-register-and-trailing-characters/type:0") # Tree-is-atom - 6417 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-register-and-trailing-characters/type:1") # Tree-left - 6418 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-register-and-trailing-characters/type:2") # Tree-right - 6419 # . epilogue - 6420 89/<- %esp 5/r32/ebp - 6421 5d/pop-to-ebp - 6422 c3/return - 6423 - 6424 test-parse-var-with-compound-type: - 6425 # . prologue - 6426 55/push-ebp - 6427 89/<- %ebp 4/r32/esp - 6428 # (eax..ecx) = "x:" - 6429 b8/copy-to-eax "x:"/imm32 - 6430 8b/-> *eax 1/r32/ecx - 6431 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6432 05/add-to-eax 4/imm32 - 6433 # var slice/ecx: slice = {eax, ecx} - 6434 51/push-ecx - 6435 50/push-eax - 6436 89/<- %ecx 4/r32/esp - 6437 # _test-input-stream contains "(addr int)" - 6438 (clear-stream _test-input-stream) - 6439 (write _test-input-stream "(addr int)") - 6440 # var v/edx: (handle var) - 6441 68/push 0/imm32 - 6442 68/push 0/imm32 - 6443 89/<- %edx 4/r32/esp - 6444 # - 6445 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) - 6446 # var v-addr/edx: (addr var) = lookup(v) - 6447 (lookup *edx *(edx+4)) # => eax - 6448 89/<- %edx 0/r32/eax - 6449 # check v-addr->name - 6450 (lookup *edx *(edx+4)) # Var-name Var-name => eax - 6451 (check-strings-equal %eax "x" "F - test-parse-var-with-compound-type/name") - 6452 # check v-addr->register - 6453 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-compound-type/register") # Var-register - 6454 # - check v-addr->type - 6455 # var type/edx: (addr tree type-id) = var->type - 6456 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax - 6457 89/<- %edx 0/r32/eax - 6458 # type is a non-atom - 6459 (check-ints-equal *edx 0 "F - test-parse-var-with-compound-type/type:0") # Tree-is-atom - 6460 # type->left == atom(addr) - 6461 (lookup *(edx+4) *(edx+8)) # Tree-left Tree-left => eax - 6462 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:1") # Tree-is-atom - 6463 (check-ints-equal *(eax+4) 2 "F - test-parse-var-with-compound-type/type:2") # Tree-value - 6464 # type->right->left == atom(int) - 6465 (lookup *(edx+0xc) *(edx+0x10)) # Tree-right Tree-right => eax - 6466 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax - 6467 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:3") # Tree-is-atom - 6468 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-compound-type/type:4") # Tree-value - 6469 # type->right->right == null - 6470 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-compound-type/type:5") # Tree-right - 6471 # . epilogue - 6472 89/<- %esp 5/r32/ebp - 6473 5d/pop-to-ebp - 6474 c3/return - 6475 - 6476 # identifier starts with a letter or '$' or '_' - 6477 # no constraints at the moment on later letters - 6478 # all we really want to do so far is exclude '{', '}' and '->' - 6479 is-identifier?: # in: (addr slice) -> result/eax: boolean - 6480 # . prologue - 6481 55/push-ebp - 6482 89/<- %ebp 4/r32/esp - 6483 # if (slice-empty?(in)) return false - 6484 (slice-empty? *(ebp+8)) # => eax - 6485 3d/compare-eax-and 0/imm32/false - 6486 75/jump-if-!= $is-identifier?:false/disp8 - 6487 # var c/eax: byte = *in->start - 6488 8b/-> *(ebp+8) 0/r32/eax - 6489 8b/-> *eax 0/r32/eax - 6490 8a/copy-byte *eax 0/r32/AL - 6491 81 4/subop/and %eax 0xff/imm32 - 6492 # if (c == '$') return true - 6493 3d/compare-eax-and 0x24/imm32/$ - 6494 74/jump-if-= $is-identifier?:true/disp8 - 6495 # if (c == '_') return true - 6496 3d/compare-eax-and 0x5f/imm32/_ - 6497 74/jump-if-= $is-identifier?:true/disp8 - 6498 # drop case - 6499 25/and-eax-with 0x5f/imm32 - 6500 # if (c < 'A') return false - 6501 3d/compare-eax-and 0x41/imm32/A - 6502 7c/jump-if-< $is-identifier?:false/disp8 - 6503 # if (c > 'Z') return false - 6504 3d/compare-eax-and 0x5a/imm32/Z - 6505 7f/jump-if-> $is-identifier?:false/disp8 - 6506 # otherwise return true - 6507 $is-identifier?:true: - 6508 b8/copy-to-eax 1/imm32/true - 6509 eb/jump $is-identifier?:end/disp8 - 6510 $is-identifier?:false: - 6511 b8/copy-to-eax 0/imm32/false - 6512 $is-identifier?:end: - 6513 # . epilogue - 6514 89/<- %esp 5/r32/ebp - 6515 5d/pop-to-ebp - 6516 c3/return - 6517 - 6518 test-is-identifier-dollar: - 6519 # . prologue - 6520 55/push-ebp - 6521 89/<- %ebp 4/r32/esp - 6522 # (eax..ecx) = "$a" - 6523 b8/copy-to-eax "$a"/imm32 - 6524 8b/-> *eax 1/r32/ecx - 6525 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6526 05/add-to-eax 4/imm32 - 6527 # var slice/ecx: slice = {eax, ecx} - 6528 51/push-ecx - 6529 50/push-eax - 6530 89/<- %ecx 4/r32/esp - 6531 # - 6532 (is-identifier? %ecx) - 6533 (check-ints-equal %eax 1 "F - test-is-identifier-dollar") - 6534 # . epilogue - 6535 89/<- %esp 5/r32/ebp - 6536 5d/pop-to-ebp - 6537 c3/return - 6538 - 6539 test-is-identifier-underscore: - 6540 # . prologue - 6541 55/push-ebp - 6542 89/<- %ebp 4/r32/esp - 6543 # (eax..ecx) = "_a" - 6544 b8/copy-to-eax "_a"/imm32 - 6545 8b/-> *eax 1/r32/ecx - 6546 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6547 05/add-to-eax 4/imm32 - 6548 # var slice/ecx: slice = {eax, ecx} - 6549 51/push-ecx - 6550 50/push-eax - 6551 89/<- %ecx 4/r32/esp - 6552 # - 6553 (is-identifier? %ecx) - 6554 (check-ints-equal %eax 1 "F - test-is-identifier-underscore") - 6555 # . epilogue - 6556 89/<- %esp 5/r32/ebp - 6557 5d/pop-to-ebp - 6558 c3/return - 6559 - 6560 test-is-identifier-a: - 6561 # . prologue - 6562 55/push-ebp - 6563 89/<- %ebp 4/r32/esp - 6564 # (eax..ecx) = "a$" - 6565 b8/copy-to-eax "a$"/imm32 - 6566 8b/-> *eax 1/r32/ecx - 6567 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6568 05/add-to-eax 4/imm32 - 6569 # var slice/ecx: slice = {eax, ecx} - 6570 51/push-ecx - 6571 50/push-eax - 6572 89/<- %ecx 4/r32/esp - 6573 # - 6574 (is-identifier? %ecx) - 6575 (check-ints-equal %eax 1 "F - test-is-identifier-a") - 6576 # . epilogue - 6577 89/<- %esp 5/r32/ebp - 6578 5d/pop-to-ebp - 6579 c3/return - 6580 - 6581 test-is-identifier-z: - 6582 # . prologue - 6583 55/push-ebp - 6584 89/<- %ebp 4/r32/esp - 6585 # (eax..ecx) = "z$" - 6586 b8/copy-to-eax "z$"/imm32 - 6587 8b/-> *eax 1/r32/ecx - 6588 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6589 05/add-to-eax 4/imm32 - 6590 # var slice/ecx: slice = {eax, ecx} - 6591 51/push-ecx - 6592 50/push-eax - 6593 89/<- %ecx 4/r32/esp - 6594 # - 6595 (is-identifier? %ecx) - 6596 (check-ints-equal %eax 1 "F - test-is-identifier-z") - 6597 # . epilogue - 6598 89/<- %esp 5/r32/ebp - 6599 5d/pop-to-ebp - 6600 c3/return - 6601 - 6602 test-is-identifier-A: - 6603 # . prologue - 6604 55/push-ebp - 6605 89/<- %ebp 4/r32/esp - 6606 # (eax..ecx) = "A$" - 6607 b8/copy-to-eax "A$"/imm32 - 6608 8b/-> *eax 1/r32/ecx - 6609 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6610 05/add-to-eax 4/imm32 - 6611 # var slice/ecx: slice = {eax, ecx} - 6612 51/push-ecx - 6613 50/push-eax - 6614 89/<- %ecx 4/r32/esp - 6615 # - 6616 (is-identifier? %ecx) - 6617 (check-ints-equal %eax 1 "F - test-is-identifier-A") - 6618 # . epilogue - 6619 89/<- %esp 5/r32/ebp - 6620 5d/pop-to-ebp - 6621 c3/return - 6622 - 6623 test-is-identifier-Z: - 6624 # . prologue - 6625 55/push-ebp - 6626 89/<- %ebp 4/r32/esp - 6627 # (eax..ecx) = "Z$" - 6628 b8/copy-to-eax "Z$"/imm32 - 6629 8b/-> *eax 1/r32/ecx - 6630 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6631 05/add-to-eax 4/imm32 - 6632 # var slice/ecx: slice = {eax, ecx} - 6633 51/push-ecx - 6634 50/push-eax - 6635 89/<- %ecx 4/r32/esp - 6636 # - 6637 (is-identifier? %ecx) - 6638 (check-ints-equal %eax 1 "F - test-is-identifier-Z") - 6639 # . epilogue - 6640 89/<- %esp 5/r32/ebp - 6641 5d/pop-to-ebp - 6642 c3/return - 6643 - 6644 test-is-identifier-at: - 6645 # character before 'A' is invalid - 6646 # . prologue - 6647 55/push-ebp - 6648 89/<- %ebp 4/r32/esp - 6649 # (eax..ecx) = "@a" - 6650 b8/copy-to-eax "@a"/imm32 - 6651 8b/-> *eax 1/r32/ecx - 6652 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6653 05/add-to-eax 4/imm32 - 6654 # var slice/ecx: slice = {eax, ecx} - 6655 51/push-ecx - 6656 50/push-eax - 6657 89/<- %ecx 4/r32/esp - 6658 # - 6659 (is-identifier? %ecx) - 6660 (check-ints-equal %eax 0 "F - test-is-identifier-@") - 6661 # . epilogue - 6662 89/<- %esp 5/r32/ebp - 6663 5d/pop-to-ebp - 6664 c3/return - 6665 - 6666 test-is-identifier-square-bracket: - 6667 # character after 'Z' is invalid - 6668 # . prologue - 6669 55/push-ebp - 6670 89/<- %ebp 4/r32/esp - 6671 # (eax..ecx) = "[a" - 6672 b8/copy-to-eax "[a"/imm32 - 6673 8b/-> *eax 1/r32/ecx - 6674 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6675 05/add-to-eax 4/imm32 - 6676 # var slice/ecx: slice = {eax, ecx} - 6677 51/push-ecx - 6678 50/push-eax - 6679 89/<- %ecx 4/r32/esp - 6680 # - 6681 (is-identifier? %ecx) - 6682 (check-ints-equal %eax 0 "F - test-is-identifier-@") - 6683 # . epilogue - 6684 89/<- %esp 5/r32/ebp - 6685 5d/pop-to-ebp - 6686 c3/return - 6687 - 6688 test-is-identifier-backtick: - 6689 # character before 'a' is invalid - 6690 # . prologue - 6691 55/push-ebp - 6692 89/<- %ebp 4/r32/esp - 6693 # (eax..ecx) = "`a" - 6694 b8/copy-to-eax "`a"/imm32 - 6695 8b/-> *eax 1/r32/ecx - 6696 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6697 05/add-to-eax 4/imm32 - 6698 # var slice/ecx: slice = {eax, ecx} - 6699 51/push-ecx - 6700 50/push-eax - 6701 89/<- %ecx 4/r32/esp - 6702 # - 6703 (is-identifier? %ecx) - 6704 (check-ints-equal %eax 0 "F - test-is-identifier-backtick") - 6705 # . epilogue - 6706 89/<- %esp 5/r32/ebp - 6707 5d/pop-to-ebp - 6708 c3/return - 6709 - 6710 test-is-identifier-curly-brace-open: - 6711 # character after 'z' is invalid; also used for blocks - 6712 # . prologue - 6713 55/push-ebp - 6714 89/<- %ebp 4/r32/esp - 6715 # (eax..ecx) = "{a" - 6716 b8/copy-to-eax "{a"/imm32 - 6717 8b/-> *eax 1/r32/ecx - 6718 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6719 05/add-to-eax 4/imm32 - 6720 # var slice/ecx: slice = {eax, ecx} - 6721 51/push-ecx - 6722 50/push-eax - 6723 89/<- %ecx 4/r32/esp - 6724 # - 6725 (is-identifier? %ecx) - 6726 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-open") - 6727 # . epilogue - 6728 89/<- %esp 5/r32/ebp - 6729 5d/pop-to-ebp - 6730 c3/return - 6731 - 6732 test-is-identifier-curly-brace-close: + 5129 5d/pop-to-ebp + 5130 c3/return + 5131 + 5132 test-get-with-wrong-offset-type: + 5133 # . prologue + 5134 55/push-ebp + 5135 89/<- %ebp 4/r32/esp + 5136 # setup + 5137 (clear-stream _test-input-stream) + 5138 (clear-stream $_test-input-buffered-file->buffer) + 5139 (clear-stream _test-output-stream) + 5140 (clear-stream $_test-output-buffered-file->buffer) + 5141 (clear-stream _test-error-stream) + 5142 (clear-stream $_test-error-buffered-file->buffer) + 5143 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5144 68/push 0/imm32 + 5145 68/push 0/imm32 + 5146 89/<- %edx 4/r32/esp + 5147 (tailor-exit-descriptor %edx 0x10) + 5148 # + 5149 (write _test-input-stream "fn foo {\n") + 5150 (write _test-input-stream " var a: t\n") + 5151 (write _test-input-stream " var b: int\n") + 5152 (write _test-input-stream " var c/ecx: (addr int) <- get a, b\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-offset-type: output should be empty") + 5172 (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") + 5173 # check that stop(1) was called + 5174 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-offset-type: 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-output-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 c: (addr int)\n") + 5201 (write _test-input-stream " c <- get a, x\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-output-type: output should be empty") + 5221 (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") + 5222 # check that stop(1) was called + 5223 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-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-2: + 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/ecx: int <- get a, x\n") + 5250 (write _test-input-stream "}\n") + 5251 (write _test-input-stream "type t {\n") + 5252 (write _test-input-stream " x: int\n") + 5253 (write _test-input-stream "}\n") + 5254 # convert + 5255 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5256 # registers except esp clobbered at this point + 5257 # restore ed + 5258 89/<- %edx 4/r32/esp + 5259 (flush _test-output-buffered-file) + 5260 (flush _test-error-buffered-file) + 5261 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5267 # check output + 5268 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-2: output should be empty") + 5269 (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") + 5270 # check that stop(1) was called + 5271 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-2: exit status") + 5272 # don't restore from ebp + 5273 81 0/subop/add %esp 8/imm32 + 5274 # . epilogue + 5275 5d/pop-to-ebp + 5276 c3/return + 5277 + 5278 test-get-with-wrong-output-type-3: + 5279 # . prologue + 5280 55/push-ebp + 5281 89/<- %ebp 4/r32/esp + 5282 # setup + 5283 (clear-stream _test-input-stream) + 5284 (clear-stream $_test-input-buffered-file->buffer) + 5285 (clear-stream _test-output-stream) + 5286 (clear-stream $_test-output-buffered-file->buffer) + 5287 (clear-stream _test-error-stream) + 5288 (clear-stream $_test-error-buffered-file->buffer) + 5289 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5290 68/push 0/imm32 + 5291 68/push 0/imm32 + 5292 89/<- %edx 4/r32/esp + 5293 (tailor-exit-descriptor %edx 0x10) + 5294 # + 5295 (write _test-input-stream "fn foo {\n") + 5296 (write _test-input-stream " var a: t\n") + 5297 (write _test-input-stream " var c/ecx: (array int) <- get a, x\n") + 5298 (write _test-input-stream "}\n") + 5299 (write _test-input-stream "type t {\n") + 5300 (write _test-input-stream " x: int\n") + 5301 (write _test-input-stream "}\n") + 5302 # convert + 5303 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5304 # registers except esp clobbered at this point + 5305 # restore ed + 5306 89/<- %edx 4/r32/esp + 5307 (flush _test-output-buffered-file) + 5308 (flush _test-error-buffered-file) + 5309 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5315 # check output + 5316 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-3: output should be empty") + 5317 (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") + 5318 # check that stop(1) was called + 5319 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-3: exit status") + 5320 # don't restore from ebp + 5321 81 0/subop/add %esp 8/imm32 + 5322 # . epilogue + 5323 5d/pop-to-ebp + 5324 c3/return + 5325 + 5326 test-get-with-wrong-output-type-4: + 5327 # . prologue + 5328 55/push-ebp + 5329 89/<- %ebp 4/r32/esp + 5330 # setup + 5331 (clear-stream _test-input-stream) + 5332 (clear-stream $_test-input-buffered-file->buffer) + 5333 (clear-stream _test-output-stream) + 5334 (clear-stream $_test-output-buffered-file->buffer) + 5335 (clear-stream _test-error-stream) + 5336 (clear-stream $_test-error-buffered-file->buffer) + 5337 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5338 68/push 0/imm32 + 5339 68/push 0/imm32 + 5340 89/<- %edx 4/r32/esp + 5341 (tailor-exit-descriptor %edx 0x10) + 5342 # + 5343 (write _test-input-stream "fn foo {\n") + 5344 (write _test-input-stream " var a: t\n") + 5345 (write _test-input-stream " var c/ecx: (addr boolean) <- get a, x\n") + 5346 (write _test-input-stream "}\n") + 5347 (write _test-input-stream "type t {\n") + 5348 (write _test-input-stream " x: int\n") + 5349 (write _test-input-stream "}\n") + 5350 # convert + 5351 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5352 # registers except esp clobbered at this point + 5353 # restore ed + 5354 89/<- %edx 4/r32/esp + 5355 (flush _test-output-buffered-file) + 5356 (flush _test-error-buffered-file) + 5357 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5363 # check output + 5364 (check-stream-equal _test-output-stream "" "F - test-get-with-wrong-output-type-4: output should be empty") + 5365 (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") + 5366 # check that stop(1) was called + 5367 (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-4: exit status") + 5368 # don't restore from ebp + 5369 81 0/subop/add %esp 8/imm32 + 5370 # . epilogue + 5371 5d/pop-to-ebp + 5372 c3/return + 5373 + 5374 test-get-with-wrong-output-type-5: + 5375 # . prologue + 5376 55/push-ebp + 5377 89/<- %ebp 4/r32/esp + 5378 # setup + 5379 (clear-stream _test-input-stream) + 5380 (clear-stream $_test-input-buffered-file->buffer) + 5381 (clear-stream _test-output-stream) + 5382 (clear-stream $_test-output-buffered-file->buffer) + 5383 # + 5384 (write _test-input-stream "fn foo {\n") + 5385 (write _test-input-stream " var a: t\n") + 5386 (write _test-input-stream " var c/ecx: (addr handle int) <- get a, x\n") + 5387 (write _test-input-stream "}\n") + 5388 (write _test-input-stream "type t {\n") + 5389 (write _test-input-stream " x: (handle int)\n") + 5390 (write _test-input-stream "}\n") + 5391 # convert + 5392 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5393 (flush _test-output-buffered-file) + 5394 # no errors + 5395 # . epilogue + 5396 89/<- %esp 5/r32/ebp + 5397 5d/pop-to-ebp + 5398 c3/return + 5399 + 5400 test-get-with-too-few-inouts: + 5401 # . prologue + 5402 55/push-ebp + 5403 89/<- %ebp 4/r32/esp + 5404 # setup + 5405 (clear-stream _test-input-stream) + 5406 (clear-stream $_test-input-buffered-file->buffer) + 5407 (clear-stream _test-output-stream) + 5408 (clear-stream $_test-output-buffered-file->buffer) + 5409 (clear-stream _test-error-stream) + 5410 (clear-stream $_test-error-buffered-file->buffer) + 5411 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5412 68/push 0/imm32 + 5413 68/push 0/imm32 + 5414 89/<- %edx 4/r32/esp + 5415 (tailor-exit-descriptor %edx 0x10) + 5416 # + 5417 (write _test-input-stream "fn foo {\n") + 5418 (write _test-input-stream " var a: t\n") + 5419 (write _test-input-stream " var c/ecx: (addr int) <- get a\n") + 5420 (write _test-input-stream "}\n") + 5421 (write _test-input-stream "type t {\n") + 5422 (write _test-input-stream " x: int\n") + 5423 (write _test-input-stream "}\n") + 5424 # convert + 5425 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5426 # registers except esp clobbered at this point + 5427 # restore ed + 5428 89/<- %edx 4/r32/esp + 5429 (flush _test-output-buffered-file) + 5430 (flush _test-error-buffered-file) + 5431 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5437 # check output + 5438 (check-stream-equal _test-output-stream "" "F - test-get-with-too-few-inouts: output should be empty") + 5439 (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") + 5440 # check that stop(1) was called + 5441 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-few-inouts: exit status") + 5442 # don't restore from ebp + 5443 81 0/subop/add %esp 8/imm32 + 5444 # . epilogue + 5445 5d/pop-to-ebp + 5446 c3/return + 5447 + 5448 test-get-with-too-many-inouts: + 5449 # . prologue + 5450 55/push-ebp + 5451 89/<- %ebp 4/r32/esp + 5452 # setup + 5453 (clear-stream _test-input-stream) + 5454 (clear-stream $_test-input-buffered-file->buffer) + 5455 (clear-stream _test-output-stream) + 5456 (clear-stream $_test-output-buffered-file->buffer) + 5457 (clear-stream _test-error-stream) + 5458 (clear-stream $_test-error-buffered-file->buffer) + 5459 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5460 68/push 0/imm32 + 5461 68/push 0/imm32 + 5462 89/<- %edx 4/r32/esp + 5463 (tailor-exit-descriptor %edx 0x10) + 5464 # + 5465 (write _test-input-stream "fn foo {\n") + 5466 (write _test-input-stream " var a: t\n") + 5467 (write _test-input-stream " var c/ecx: (addr int) <- get a, x, 0\n") + 5468 (write _test-input-stream "}\n") + 5469 (write _test-input-stream "type t {\n") + 5470 (write _test-input-stream " x: int\n") + 5471 (write _test-input-stream "}\n") + 5472 # convert + 5473 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5474 # registers except esp clobbered at this point + 5475 # restore ed + 5476 89/<- %edx 4/r32/esp + 5477 (flush _test-output-buffered-file) + 5478 (flush _test-error-buffered-file) + 5479 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5485 # check output + 5486 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-inouts: output should be empty") + 5487 (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") + 5488 # check that stop(1) was called + 5489 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-inouts: exit status") + 5490 # don't restore from ebp + 5491 81 0/subop/add %esp 8/imm32 + 5492 # . epilogue + 5493 5d/pop-to-ebp + 5494 c3/return + 5495 + 5496 test-get-with-no-output: + 5497 # . prologue + 5498 55/push-ebp + 5499 89/<- %ebp 4/r32/esp + 5500 # setup + 5501 (clear-stream _test-input-stream) + 5502 (clear-stream $_test-input-buffered-file->buffer) + 5503 (clear-stream _test-output-stream) + 5504 (clear-stream $_test-output-buffered-file->buffer) + 5505 (clear-stream _test-error-stream) + 5506 (clear-stream $_test-error-buffered-file->buffer) + 5507 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5508 68/push 0/imm32 + 5509 68/push 0/imm32 + 5510 89/<- %edx 4/r32/esp + 5511 (tailor-exit-descriptor %edx 0x10) + 5512 # + 5513 (write _test-input-stream "fn foo {\n") + 5514 (write _test-input-stream " var a: t\n") + 5515 (write _test-input-stream " get a, x\n") + 5516 (write _test-input-stream "}\n") + 5517 (write _test-input-stream "type t {\n") + 5518 (write _test-input-stream " x: int\n") + 5519 (write _test-input-stream "}\n") + 5520 # convert + 5521 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5522 # registers except esp clobbered at this point + 5523 # restore ed + 5524 89/<- %edx 4/r32/esp + 5525 (flush _test-output-buffered-file) + 5526 (flush _test-error-buffered-file) + 5527 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5533 # check output + 5534 (check-stream-equal _test-output-stream "" "F - test-get-with-no-output: output should be empty") + 5535 (check-next-stream-line-equal _test-error-stream "fn foo: stmt get: must have an output" "F - test-get-with-no-output: error message") + 5536 # check that stop(1) was called + 5537 (check-ints-equal *(edx+4) 2 "F - test-get-with-no-output: exit status") + 5538 # don't restore from ebp + 5539 81 0/subop/add %esp 8/imm32 + 5540 # . epilogue + 5541 5d/pop-to-ebp + 5542 c3/return + 5543 + 5544 test-get-with-too-many-outputs: + 5545 # . prologue + 5546 55/push-ebp + 5547 89/<- %ebp 4/r32/esp + 5548 # setup + 5549 (clear-stream _test-input-stream) + 5550 (clear-stream $_test-input-buffered-file->buffer) + 5551 (clear-stream _test-output-stream) + 5552 (clear-stream $_test-output-buffered-file->buffer) + 5553 (clear-stream _test-error-stream) + 5554 (clear-stream $_test-error-buffered-file->buffer) + 5555 # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 5556 68/push 0/imm32 + 5557 68/push 0/imm32 + 5558 89/<- %edx 4/r32/esp + 5559 (tailor-exit-descriptor %edx 0x10) + 5560 # + 5561 (write _test-input-stream "fn foo {\n") + 5562 (write _test-input-stream " var a: t\n") + 5563 (write _test-input-stream " var b: int\n") + 5564 (write _test-input-stream " var c/eax: (addr int) <- copy 0\n") + 5565 (write _test-input-stream " c, b <- get a, x\n") + 5566 (write _test-input-stream "}\n") + 5567 (write _test-input-stream "type t {\n") + 5568 (write _test-input-stream " x: int\n") + 5569 (write _test-input-stream "}\n") + 5570 # convert + 5571 (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + 5572 # registers except esp clobbered at this point + 5573 # restore ed + 5574 89/<- %edx 4/r32/esp + 5575 (flush _test-output-buffered-file) + 5576 (flush _test-error-buffered-file) + 5577 +-- 6 lines: #? # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------ + 5583 # check output + 5584 (check-stream-equal _test-output-stream "" "F - test-get-with-too-many-outputs: output should be empty") + 5585 (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") + 5586 # check that stop(1) was called + 5587 (check-ints-equal *(edx+4) 2 "F - test-get-with-too-many-outputs: exit status") + 5588 # don't restore from ebp + 5589 81 0/subop/add %esp 8/imm32 + 5590 # . epilogue + 5591 5d/pop-to-ebp + 5592 c3/return + 5593 + 5594 test-convert-array-of-user-defined-types: + 5595 # . prologue + 5596 55/push-ebp + 5597 89/<- %ebp 4/r32/esp + 5598 # setup + 5599 (clear-stream _test-input-stream) + 5600 (clear-stream $_test-input-buffered-file->buffer) + 5601 (clear-stream _test-output-stream) + 5602 (clear-stream $_test-output-buffered-file->buffer) + 5603 # + 5604 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 + 5605 (write _test-input-stream " x: int\n") + 5606 (write _test-input-stream " y: int\n") + 5607 (write _test-input-stream "}\n") + 5608 (write _test-input-stream "fn foo {\n") + 5609 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 5610 (write _test-input-stream " var idx/ecx: int <- copy 3\n") + 5611 (write _test-input-stream " var x/eax: (addr int) <- index arr, idx\n") + 5612 (write _test-input-stream "}\n") + 5613 # convert + 5614 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5615 (flush _test-output-buffered-file) + 5616 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5622 # check output + 5623 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-array-of-user-defined-types/0") + 5624 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-array-of-user-defined-types/1") + 5625 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-array-of-user-defined-types/2") + 5626 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-array-of-user-defined-types/3") + 5627 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-array-of-user-defined-types/4") + 5628 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-array-of-user-defined-types/5") + 5629 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-array-of-user-defined-types/6") + 5630 (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-array-of-user-defined-types/7") + 5631 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-array-of-user-defined-types/8") + 5632 (check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-array-of-user-defined-types/9") + 5633 (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") + 5634 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-array-of-user-defined-types/13") + 5635 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-array-of-user-defined-types/14") + 5636 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-array-of-user-defined-types/15") + 5637 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-array-of-user-defined-types/16") + 5638 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-array-of-user-defined-types/17") + 5639 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-array-of-user-defined-types/18") + 5640 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-array-of-user-defined-types/19") + 5641 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-array-of-user-defined-types/20") + 5642 # . epilogue + 5643 89/<- %esp 5/r32/ebp + 5644 5d/pop-to-ebp + 5645 c3/return + 5646 + 5647 test-convert-length-of-array-of-user-defined-types-to-eax: + 5648 # . prologue + 5649 55/push-ebp + 5650 89/<- %ebp 4/r32/esp + 5651 # setup + 5652 (clear-stream _test-input-stream) + 5653 (clear-stream $_test-input-buffered-file->buffer) + 5654 (clear-stream _test-output-stream) + 5655 (clear-stream $_test-output-buffered-file->buffer) + 5656 # + 5657 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 + 5658 (write _test-input-stream " x: int\n") + 5659 (write _test-input-stream " y: int\n") + 5660 (write _test-input-stream " z: int\n") + 5661 (write _test-input-stream "}\n") + 5662 (write _test-input-stream "fn foo {\n") + 5663 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 5664 (write _test-input-stream " var x/eax: (addr t) <- length arr\n") + 5665 (write _test-input-stream "}\n") + 5666 # convert + 5667 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5668 (flush _test-output-buffered-file) + 5669 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5675 # check output + 5676 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/0") + 5677 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/1") + 5678 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-eax/2") + 5679 (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") + 5680 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-eax/4") + 5681 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/5") + 5682 # var arr + 5683 (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") + 5684 (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") + 5685 # length instruction + 5686 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/8") + 5687 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-eax/9") + 5688 (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") + 5689 (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") + 5690 (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") + 5691 (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") + 5692 (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") + 5693 (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") + 5694 # reclaim arr + 5695 (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") + 5696 # + 5697 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-eax/17") + 5698 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-eax/18") + 5699 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-eax/19") + 5700 (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") + 5701 (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") + 5702 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-eax/22") + 5703 # . epilogue + 5704 89/<- %esp 5/r32/ebp + 5705 5d/pop-to-ebp + 5706 c3/return + 5707 + 5708 test-convert-length-of-array-of-user-defined-types-to-ecx: + 5709 # . prologue + 5710 55/push-ebp + 5711 89/<- %ebp 4/r32/esp + 5712 # setup + 5713 (clear-stream _test-input-stream) + 5714 (clear-stream $_test-input-buffered-file->buffer) + 5715 (clear-stream _test-output-stream) + 5716 (clear-stream $_test-output-buffered-file->buffer) + 5717 # + 5718 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 + 5719 (write _test-input-stream " x: int\n") + 5720 (write _test-input-stream " y: int\n") + 5721 (write _test-input-stream " z: int\n") + 5722 (write _test-input-stream "}\n") + 5723 (write _test-input-stream "fn foo {\n") + 5724 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 5725 (write _test-input-stream " var x/ecx: (addr t) <- length arr\n") + 5726 (write _test-input-stream "}\n") + 5727 # convert + 5728 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5729 (flush _test-output-buffered-file) + 5730 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5736 # check output + 5737 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/0") + 5738 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/1") + 5739 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/2") + 5740 (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") + 5741 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/4") + 5742 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/5") + 5743 # var a + 5744 (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") + 5745 (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") + 5746 # var x + 5747 (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") + 5748 # length instruction + 5749 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/9") + 5750 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/10") + 5751 (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") + 5752 (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") + 5753 (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") + 5754 (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") + 5755 (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") + 5756 (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") + 5757 (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") + 5758 # reclaim x + 5759 (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") + 5760 # reclaim a + 5761 (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") + 5762 # + 5763 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/20") + 5764 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/21") + 5765 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/22") + 5766 (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") + 5767 (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") + 5768 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-ecx/25") + 5769 # . epilogue + 5770 89/<- %esp 5/r32/ebp + 5771 5d/pop-to-ebp + 5772 c3/return + 5773 + 5774 test-convert-length-of-array-of-user-defined-types-to-edx: + 5775 # . prologue + 5776 55/push-ebp + 5777 89/<- %ebp 4/r32/esp + 5778 # setup + 5779 (clear-stream _test-input-stream) + 5780 (clear-stream $_test-input-buffered-file->buffer) + 5781 (clear-stream _test-output-stream) + 5782 (clear-stream $_test-output-buffered-file->buffer) + 5783 # + 5784 (write _test-input-stream "type t {\n") # size = 12, which is not a power of 2 + 5785 (write _test-input-stream " x: int\n") + 5786 (write _test-input-stream " y: int\n") + 5787 (write _test-input-stream " z: int\n") + 5788 (write _test-input-stream "}\n") + 5789 (write _test-input-stream "fn foo {\n") + 5790 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 5791 (write _test-input-stream " var x/edx: (addr t) <- length arr\n") + 5792 (write _test-input-stream "}\n") + 5793 # convert + 5794 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5795 (flush _test-output-buffered-file) + 5796 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5802 # check output + 5803 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/0") + 5804 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/1") + 5805 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types-to-edx/2") + 5806 (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") + 5807 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types-to-edx/4") + 5808 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/5") + 5809 # var a + 5810 (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") + 5811 (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") + 5812 # var x + 5813 (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") + 5814 # length instruction + 5815 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types-to-edx/9") + 5816 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types-to-edx/10") + 5817 (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") + 5818 (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") + 5819 (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") + 5820 (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") + 5821 (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") + 5822 (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") + 5823 (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") + 5824 # reclaim x + 5825 (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") + 5826 # reclaim a + 5827 (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") + 5828 # + 5829 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types-to-edx/20") + 5830 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types-to-edx/21") + 5831 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types-to-edx/22") + 5832 (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") + 5833 (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") + 5834 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types-to-edx/25") + 5835 # . epilogue + 5836 89/<- %esp 5/r32/ebp + 5837 5d/pop-to-ebp + 5838 c3/return + 5839 + 5840 test-convert-length-of-array-of-user-defined-types: + 5841 # . prologue + 5842 55/push-ebp + 5843 89/<- %ebp 4/r32/esp + 5844 # setup + 5845 (clear-stream _test-input-stream) + 5846 (clear-stream $_test-input-buffered-file->buffer) + 5847 (clear-stream _test-output-stream) + 5848 (clear-stream $_test-output-buffered-file->buffer) + 5849 # + 5850 (write _test-input-stream "type t {\n") # each t is 8 bytes, which is a power of 2 + 5851 (write _test-input-stream " x: int\n") + 5852 (write _test-input-stream " y: int\n") + 5853 (write _test-input-stream " z: int\n") + 5854 (write _test-input-stream "}\n") + 5855 (write _test-input-stream "fn foo {\n") + 5856 (write _test-input-stream " var arr/eax: (addr array t) <- copy 0\n") + 5857 (write _test-input-stream " var x/ebx: (addr t) <- length arr\n") + 5858 (write _test-input-stream "}\n") + 5859 # convert + 5860 (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0) + 5861 (flush _test-output-buffered-file) + 5862 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- + 5868 # check output + 5869 (check-next-stream-line-equal _test-output-stream "foo:" "F - test-convert-length-of-array-of-user-defined-types/0") + 5870 (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-length-of-array-of-user-defined-types/1") + 5871 (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-length-of-array-of-user-defined-types/2") + 5872 (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-length-of-array-of-user-defined-types/3") + 5873 (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array-of-user-defined-types/4") + 5874 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array-of-user-defined-types/5") + 5875 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-of-user-defined-types/6") + 5876 (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") + 5877 (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ebx" "F - test-convert-length-of-array-of-user-defined-types/8") + 5878 (check-next-stream-line-equal _test-output-stream " 50/push-eax" "F - test-convert-length-of-array-of-user-defined-types/9") + 5879 (check-next-stream-line-equal _test-output-stream " 51/push-ecx" "F - test-convert-length-of-array-of-user-defined-types/10") + 5880 (check-next-stream-line-equal _test-output-stream " 52/push-edx" "F - test-convert-length-of-array-of-user-defined-types/11") + 5881 (check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array-of-user-defined-types/12") + 5882 (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") + 5883 (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") + 5884 (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") + 5885 (check-next-stream-line-equal _test-output-stream " 89/<- %ebx 0/r32/eax" "F - test-convert-length-of-array-of-user-defined-types/16") + 5886 (check-next-stream-line-equal _test-output-stream " 5a/pop-to-edx" "F - test-convert-length-of-array-of-user-defined-types/17") + 5887 (check-next-stream-line-equal _test-output-stream " 59/pop-to-ecx" "F - test-convert-length-of-array-of-user-defined-types/18") + 5888 (check-next-stream-line-equal _test-output-stream " 58/pop-to-eax" "F - test-convert-length-of-array-of-user-defined-types/19") + 5889 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ebx" "F - test-convert-length-of-array-of-user-defined-types/20") + 5890 (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-of-user-defined-types/21") + 5891 (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-of-user-defined-types/22") + 5892 (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array-of-user-defined-types/23") + 5893 (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-length-of-array-of-user-defined-types/24") + 5894 (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-length-of-array-of-user-defined-types/25") + 5895 (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-length-of-array-of-user-defined-types/26") + 5896 (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-length-of-array-of-user-defined-types/27") + 5897 # . epilogue + 5898 89/<- %esp 5/r32/ebp + 5899 5d/pop-to-ebp + 5900 c3/return + 5901 + 5902 ####################################################### + 5903 # Parsing + 5904 ####################################################### + 5905 + 5906 == data + 5907 + 5908 # Global state added to each var record when parsing a function + 5909 Next-block-index: # (addr int) + 5910 1/imm32 + 5911 + 5912 Curr-block-depth: # (addr int) + 5913 1/imm32 + 5914 + 5915 == code + 5916 + 5917 parse-mu: # in: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) + 5918 # pseudocode + 5919 # var curr-function: (addr handle function) = Program->functions + 5920 # var curr-type: (addr handle typeinfo) = Program->types + 5921 # var line: (stream byte 512) + 5922 # var word-slice: slice + 5923 # while true # line loop + 5924 # clear-stream(line) + 5925 # read-line-buffered(in, line) + 5926 # if (line->write == 0) break # end of file + 5927 # word-slice = next-mu-token(line) + 5928 # if slice-empty?(word-slice) # end of line + 5929 # continue + 5930 # else if slice-starts-with?(word-slice, "#") # comment + 5931 # continue # end of line + 5932 # else if slice-equal?(word-slice, "fn") + 5933 # var new-function: (handle function) = allocate(function) + 5934 # var vars: (stack live-var 256) + 5935 # populate-mu-function-header(line, new-function, vars) + 5936 # populate-mu-function-body(in, new-function, vars) + 5937 # assert(vars->top == 0) + 5938 # *curr-function = new-function + 5939 # curr-function = &new-function->next + 5940 # else if slice-equal?(word-slice, "type") + 5941 # word-slice = next-mu-token(line) + 5942 # type-id = pos-or-insert-slice(Type-id, word-slice) + 5943 # var new-type: (handle typeinfo) = find-or-create-typeinfo(type-id) + 5944 # assert(next-word(line) == "{") + 5945 # populate-mu-type(in, new-type) + 5946 # else + 5947 # abort() + 5948 # + 5949 # . prologue + 5950 55/push-ebp + 5951 89/<- %ebp 4/r32/esp + 5952 # . save registers + 5953 50/push-eax + 5954 51/push-ecx + 5955 52/push-edx + 5956 53/push-ebx + 5957 56/push-esi + 5958 57/push-edi + 5959 # var line/ecx: (stream byte 512) + 5960 81 5/subop/subtract %esp 0x200/imm32 + 5961 68/push 0x200/imm32/size + 5962 68/push 0/imm32/read + 5963 68/push 0/imm32/write + 5964 89/<- %ecx 4/r32/esp + 5965 # var word-slice/edx: slice + 5966 68/push 0/imm32/end + 5967 68/push 0/imm32/start + 5968 89/<- %edx 4/r32/esp + 5969 # var curr-function/edi: (addr handle function) + 5970 bf/copy-to-edi _Program-functions/imm32 + 5971 # var vars/ebx: (stack live-var 256) + 5972 81 5/subop/subtract %esp 0xc00/imm32 + 5973 68/push 0xc00/imm32/size + 5974 68/push 0/imm32/top + 5975 89/<- %ebx 4/r32/esp + 5976 { + 5977 $parse-mu:line-loop: + 5978 (clear-stream %ecx) + 5979 (read-line-buffered *(ebp+8) %ecx) + 5980 # if (line->write == 0) break + 5981 81 7/subop/compare *ecx 0/imm32 + 5982 0f 84/jump-if-= break/disp32 + 5983 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ + 5989 (next-mu-token %ecx %edx) + 5990 # if slice-empty?(word-slice) continue + 5991 (slice-empty? %edx) # => eax + 5992 3d/compare-eax-and 0/imm32/false + 5993 0f 85/jump-if-!= loop/disp32 + 5994 # if (*word-slice->start == "#") continue + 5995 # . eax = *word-slice->start + 5996 8b/-> *edx 0/r32/eax + 5997 8a/copy-byte *eax 0/r32/AL + 5998 81 4/subop/and %eax 0xff/imm32 + 5999 # . if (eax == '#') continue + 6000 3d/compare-eax-and 0x23/imm32/hash + 6001 0f 84/jump-if-= loop/disp32 + 6002 # if (slice-equal?(word-slice, "fn")) parse a function + 6003 { + 6004 $parse-mu:fn: + 6005 (slice-equal? %edx "fn") # => eax + 6006 3d/compare-eax-and 0/imm32/false + 6007 0f 84/jump-if-= break/disp32 + 6008 # var new-function/esi: (handle function) + 6009 68/push 0/imm32 + 6010 68/push 0/imm32 + 6011 89/<- %esi 4/r32/esp + 6012 # populate-mu-function(line, in, vars, new-function) + 6013 (allocate Heap *Function-size %esi) + 6014 # var new-function-addr/eax: (addr function) + 6015 (lookup *esi *(esi+4)) # => eax + 6016 (clear-stack %ebx) + 6017 (populate-mu-function-header %ecx %eax %ebx *(ebp+0xc) *(ebp+0x10)) + 6018 (populate-mu-function-body *(ebp+8) %eax %ebx *(ebp+0xc) *(ebp+0x10)) + 6019 # *curr-function = new-function + 6020 8b/-> *esi 0/r32/eax + 6021 89/<- *edi 0/r32/eax + 6022 8b/-> *(esi+4) 0/r32/eax + 6023 89/<- *(edi+4) 0/r32/eax + 6024 # curr-function = &new-function->next + 6025 # . var tmp/eax: (addr function) = lookup(new-function) + 6026 (lookup *esi *(esi+4)) # => eax + 6027 # . curr-function = &tmp->next + 6028 8d/copy-address *(eax+0x20) 7/r32/edi # Function-next + 6029 # reclaim new-function + 6030 81 0/subop/add %esp 8/imm32 + 6031 # + 6032 e9/jump $parse-mu:line-loop/disp32 + 6033 } + 6034 # if (slice-equal?(word-slice, "type")) parse a type (struct/record) definition + 6035 { + 6036 $parse-mu:type: + 6037 (slice-equal? %edx "type") # => eax + 6038 3d/compare-eax-and 0/imm32 + 6039 0f 84/jump-if-= break/disp32 + 6040 (next-mu-token %ecx %edx) + 6041 # var type-id/eax: int + 6042 (pos-or-insert-slice Type-id %edx) # => eax + 6043 # spill + 6044 51/push-ecx + 6045 # var new-type/ecx: (handle typeinfo) + 6046 68/push 0/imm32 + 6047 68/push 0/imm32 + 6048 89/<- %ecx 4/r32/esp + 6049 (find-or-create-typeinfo %eax %ecx) + 6050 # + 6051 (lookup *ecx *(ecx+4)) # => eax + 6052 # TODO: ensure that 'line' has nothing else but '{' + 6053 #? (dump-typeinfos "=== aaa\n") + 6054 (populate-mu-type *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) # => eax + 6055 #? (dump-typeinfos "=== zzz\n") + 6056 # reclaim new-type + 6057 81 0/subop/add %esp 8/imm32 + 6058 # restore + 6059 59/pop-to-ecx + 6060 e9/jump $parse-mu:line-loop/disp32 + 6061 } + 6062 # otherwise abort + 6063 e9/jump $parse-mu:error1/disp32 + 6064 } # end line loop + 6065 $parse-mu:end: + 6066 # . reclaim locals + 6067 81 0/subop/add %esp 0xe1c/imm32 + 6068 # . restore registers + 6069 5f/pop-to-edi + 6070 5e/pop-to-esi + 6071 5b/pop-to-ebx + 6072 5a/pop-to-edx + 6073 59/pop-to-ecx + 6074 58/pop-to-eax + 6075 # . epilogue + 6076 89/<- %esp 5/r32/ebp + 6077 5d/pop-to-ebp + 6078 c3/return + 6079 + 6080 $parse-mu:error1: + 6081 # error("unexpected top-level command: " word-slice "\n") + 6082 (write-buffered *(ebp+0xc) "unexpected top-level command: ") + 6083 (write-slice-buffered *(ebp+0xc) %edx) + 6084 (write-buffered *(ebp+0xc) "\n") + 6085 (flush *(ebp+0xc)) + 6086 (stop *(ebp+0x10) 1) + 6087 # never gets here + 6088 + 6089 $parse-mu:error2: + 6090 # error(vars->top " vars not reclaimed after fn '" new-function->name "'\n") + 6091 (print-int32-buffered *(ebp+0xc) *ebx) + 6092 (write-buffered *(ebp+0xc) " vars not reclaimed after fn '") + 6093 (write-slice-buffered *(ebp+0xc) *eax) # Function-name + 6094 (write-buffered *(ebp+0xc) "'\n") + 6095 (flush *(ebp+0xc)) + 6096 (stop *(ebp+0x10) 1) + 6097 # never gets here + 6098 + 6099 # scenarios considered: + 6100 # ✗ fn foo # no block + 6101 # ✓ fn foo { + 6102 # ✗ fn foo { { + 6103 # ✗ fn foo { } + 6104 # ✗ fn foo { } { + 6105 # ✗ fn foo x { + 6106 # ✗ fn foo x: { + 6107 # ✓ fn foo x: int { + 6108 # ✓ fn foo x: int { + 6109 # ✓ fn foo x: int -> y/eax: int { + 6110 # TODO: + 6111 # disallow outputs of type `(... addr ...)` + 6112 # disallow inputs of type `(... addr ... addr ...)` + 6113 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) + 6114 # pseudocode: + 6115 # var name: slice + 6116 # next-mu-token(first-line, name) + 6117 # assert(name not in '{' '}' '->') + 6118 # out->name = slice-to-string(name) + 6119 # ## inouts + 6120 # while true + 6121 # ## name + 6122 # name = next-mu-token(first-line) + 6123 # if (name == '{') goto done + 6124 # if (name == '->') break + 6125 # assert(name != '}') + 6126 # var v: (handle var) = parse-var-with-type(name, first-line) + 6127 # assert(v->register == null) + 6128 # # v->block-depth is implicitly 0 + 6129 # out->inouts = append(v, out->inouts) + 6130 # push(vars, {v, false}) + 6131 # ## outputs + 6132 # while true + 6133 # ## name + 6134 # name = next-mu-token(first-line) + 6135 # assert(name not in '{' '}' '->') + 6136 # var v: (handle var) = parse-var-with-type(name, first-line) + 6137 # assert(v->register != null) + 6138 # out->outputs = append(v, out->outputs) + 6139 # done: + 6140 # + 6141 # . prologue + 6142 55/push-ebp + 6143 89/<- %ebp 4/r32/esp + 6144 # . save registers + 6145 50/push-eax + 6146 51/push-ecx + 6147 52/push-edx + 6148 53/push-ebx + 6149 57/push-edi + 6150 # edi = out + 6151 8b/-> *(ebp+0xc) 7/r32/edi + 6152 # var word-slice/ecx: slice + 6153 68/push 0/imm32/end + 6154 68/push 0/imm32/start + 6155 89/<- %ecx 4/r32/esp + 6156 # var v/ebx: (handle var) + 6157 68/push 0/imm32 + 6158 68/push 0/imm32 + 6159 89/<- %ebx 4/r32/esp + 6160 # read function name + 6161 (next-mu-token *(ebp+8) %ecx) + 6162 # error checking + 6163 # TODO: error if name starts with 'break' or 'loop' + 6164 # if (word-slice == '{') abort + 6165 (slice-equal? %ecx "{") # => eax + 6166 3d/compare-eax-and 0/imm32/false + 6167 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 6168 # if (word-slice == '->') abort + 6169 (slice-equal? %ecx "->") # => eax + 6170 3d/compare-eax-and 0/imm32/false + 6171 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 6172 # if (word-slice == '}') abort + 6173 (slice-equal? %ecx "}") # => eax + 6174 3d/compare-eax-and 0/imm32/false + 6175 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 6176 # save function name + 6177 (slice-to-string Heap %ecx %edi) # Function-name + 6178 # save function inouts + 6179 { + 6180 $populate-mu-function-header:check-for-inout: + 6181 (next-mu-token *(ebp+8) %ecx) + 6182 # if (word-slice == '{') goto done + 6183 (slice-equal? %ecx "{") # => eax + 6184 3d/compare-eax-and 0/imm32/false + 6185 0f 85/jump-if-!= $populate-mu-function-header:done/disp32 + 6186 # if (word-slice == '->') break + 6187 (slice-equal? %ecx "->") # => eax + 6188 3d/compare-eax-and 0/imm32/false + 6189 0f 85/jump-if-!= break/disp32 + 6190 # if (word-slice == '}') abort + 6191 (slice-equal? %ecx "}") # => eax + 6192 3d/compare-eax-and 0/imm32/false + 6193 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 6194 # v = parse-var-with-type(word-slice, first-line) + 6195 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x14) *(ebp+0x18)) + 6196 # assert(v->register == null) + 6197 # . eax: (addr var) = lookup(v) + 6198 (lookup *ebx *(ebx+4)) # => eax + 6199 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 6200 0f 85/jump-if-!= $populate-mu-function-header:error2/disp32 + 6201 # v->block-depth is implicitly 0 + 6202 # + 6203 # out->inouts = append(v, out->inouts) + 6204 8d/copy-address *(edi+8) 0/r32/eax # Function-inouts + 6205 (append-list Heap *ebx *(ebx+4) *(edi+8) *(edi+0xc) %eax) # Function-inouts, Function-inouts + 6206 # push(vars, {v, false}) + 6207 (push *(ebp+0x10) *ebx) + 6208 (push *(ebp+0x10) *(ebx+4)) + 6209 (push *(ebp+0x10) 0) # false + 6210 # + 6211 e9/jump loop/disp32 + 6212 } + 6213 # save function outputs + 6214 { + 6215 $populate-mu-function-header:check-for-out: + 6216 (next-mu-token *(ebp+8) %ecx) + 6217 # if (word-slice == '{') break + 6218 (slice-equal? %ecx "{") # => eax + 6219 3d/compare-eax-and 0/imm32/false + 6220 0f 85/jump-if-!= break/disp32 + 6221 # if (word-slice == '->') abort + 6222 (slice-equal? %ecx "->") # => eax + 6223 3d/compare-eax-and 0/imm32/false + 6224 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 6225 # if (word-slice == '}') abort + 6226 (slice-equal? %ecx "}") # => eax + 6227 3d/compare-eax-and 0/imm32/false + 6228 0f 85/jump-if-!= $populate-mu-function-header:error1/disp32 + 6229 # v = parse-var-with-type(word-slice, first-line) + 6230 (parse-var-with-type %ecx *(ebp+8) %ebx *(ebp+0x14) *(ebp+0x18)) + 6231 # assert(var->register != null) + 6232 # . eax: (addr var) = lookup(v) + 6233 (lookup *ebx *(ebx+4)) # => eax + 6234 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register + 6235 0f 84/jump-if-= $populate-mu-function-header:error3/disp32 + 6236 # out->outputs = append(v, out->outputs) + 6237 8d/copy-address *(edi+0x10) 0/r32/eax # Function-outputs + 6238 (append-list Heap *ebx *(ebx+4) *(edi+0x10) *(edi+0x14) %eax) # Function-outputs, Function-outputs + 6239 # + 6240 e9/jump loop/disp32 + 6241 } + 6242 $populate-mu-function-header:done: + 6243 (check-no-tokens-left *(ebp+8)) + 6244 $populate-mu-function-header:end: + 6245 # . reclaim locals + 6246 81 0/subop/add %esp 0x10/imm32 + 6247 # . restore registers + 6248 5f/pop-to-edi + 6249 5b/pop-to-ebx + 6250 5a/pop-to-edx + 6251 59/pop-to-ecx + 6252 58/pop-to-eax + 6253 # . epilogue + 6254 89/<- %esp 5/r32/ebp + 6255 5d/pop-to-ebp + 6256 c3/return + 6257 + 6258 $populate-mu-function-header:error1: + 6259 # error("function header not in form 'fn <name> {'") + 6260 (write-buffered *(ebp+0x14) "function header not in form 'fn <name> [inouts] [-> outputs] {' -- '") + 6261 (flush *(ebp+0x14)) + 6262 (rewind-stream *(ebp+8)) + 6263 (write-stream-data *(ebp+0x14) *(ebp+8)) + 6264 (write-buffered *(ebp+0x14) "'\n") + 6265 (flush *(ebp+0x14)) + 6266 (stop *(ebp+0x18) 1) + 6267 # never gets here + 6268 + 6269 $populate-mu-function-header:error2: + 6270 # error("function inout '" var "' cannot be in a register") + 6271 (write-buffered *(ebp+0x14) "function inout '") + 6272 (write-buffered *(ebp+0x14) *ebx) # Var-name + 6273 (write-buffered *(ebp+0x14) "' cannot be in a register") + 6274 (flush *(ebp+0x14)) + 6275 (stop *(ebp+0x18) 1) + 6276 # never gets here + 6277 + 6278 $populate-mu-function-header:error3: + 6279 # error("function output '" var "' must be in a register") + 6280 (write-buffered *(ebp+0x14) "function output '") + 6281 (lookup *ebx *(ebx+4)) # => eax + 6282 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 6283 (write-buffered *(ebp+0x14) %eax) + 6284 (write-buffered *(ebp+0x14) "' must be in a register, in instruction '") + 6285 (rewind-stream *(ebp+8)) + 6286 (write-stream-data *(ebp+0x14) *(ebp+8)) + 6287 (write-buffered *(ebp+0x14) "'\n") + 6288 (flush *(ebp+0x14)) + 6289 (stop *(ebp+0x18) 1) + 6290 # never gets here + 6291 + 6292 test-function-header-with-arg: + 6293 # . prologue + 6294 55/push-ebp + 6295 89/<- %ebp 4/r32/esp + 6296 # setup + 6297 (clear-stream _test-input-stream) + 6298 (write _test-input-stream "foo n: int {\n") + 6299 # var result/ecx: function + 6300 2b/subtract *Function-size 4/r32/esp + 6301 89/<- %ecx 4/r32/esp + 6302 (zero-out %ecx *Function-size) + 6303 # var vars/ebx: (stack live-var 16) + 6304 81 5/subop/subtract %esp 0xc0/imm32 + 6305 68/push 0xc0/imm32/size + 6306 68/push 0/imm32/top + 6307 89/<- %ebx 4/r32/esp + 6308 # convert + 6309 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) + 6310 # check result->name + 6311 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 6312 (check-strings-equal %eax "foo" "F - test-function-header-with-arg/name") + 6313 # var v/edx: (addr var) = result->inouts->value + 6314 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 6315 (lookup *eax *(eax+4)) # List-value List-value => eax + 6316 89/<- %edx 0/r32/eax + 6317 # check v->name + 6318 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 6319 (check-strings-equal %eax "n" "F - test-function-header-with-arg/inout:0") + 6320 # check v->type + 6321 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 6322 (check-ints-equal *eax 1 "F - test-function-header-with-arg/inout:0/type:0") # Tree-is-atom + 6323 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-arg/inout:0/type:1") # Tree-value + 6324 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-arg/inout:0/type:2") # Tree-right + 6325 # . epilogue + 6326 89/<- %esp 5/r32/ebp + 6327 5d/pop-to-ebp + 6328 c3/return + 6329 + 6330 test-function-header-with-multiple-args: + 6331 # . prologue + 6332 55/push-ebp + 6333 89/<- %ebp 4/r32/esp + 6334 # setup + 6335 (clear-stream _test-input-stream) + 6336 (write _test-input-stream "foo a: int, b: int c: int {\n") + 6337 # result/ecx: function + 6338 2b/subtract *Function-size 4/r32/esp + 6339 89/<- %ecx 4/r32/esp + 6340 (zero-out %ecx *Function-size) + 6341 # var vars/ebx: (stack live-var 16) + 6342 81 5/subop/subtract %esp 0xc0/imm32 + 6343 68/push 0xc0/imm32/size + 6344 68/push 0/imm32/top + 6345 89/<- %ebx 4/r32/esp + 6346 # convert + 6347 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) + 6348 # check result->name + 6349 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 6350 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args/name") + 6351 # var inouts/edx: (addr list var) = lookup(result->inouts) + 6352 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 6353 89/<- %edx 0/r32/eax + 6354 $test-function-header-with-multiple-args:inout0: + 6355 # var v/ebx: (addr var) = lookup(inouts->value) + 6356 (lookup *edx *(edx+4)) # List-value List-value => eax + 6357 89/<- %ebx 0/r32/eax + 6358 # check v->name + 6359 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 6360 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name + 6361 # check v->type + 6362 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 6363 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:0/type:0") # Tree-is-atom + 6364 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:0/type:1") # Tree-value + 6365 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:0/type:2") # Tree-right + 6366 $test-function-header-with-multiple-args:inout1: + 6367 # inouts = lookup(inouts->next) + 6368 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 6369 89/<- %edx 0/r32/eax + 6370 # v = lookup(inouts->value) + 6371 (lookup *edx *(edx+4)) # List-value List-value => eax + 6372 89/<- %ebx 0/r32/eax + 6373 # check v->name + 6374 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 6375 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name + 6376 # check v->type + 6377 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 6378 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:1/type:0") # Tree-is-atom + 6379 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:1/type:1") # Tree-value + 6380 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:1/type:2") # Tree-right + 6381 $test-function-header-with-multiple-args:inout2: + 6382 # inouts = lookup(inouts->next) + 6383 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 6384 89/<- %edx 0/r32/eax + 6385 # v = lookup(inouts->value) + 6386 (lookup *edx *(edx+4)) # List-value List-value => eax + 6387 89/<- %ebx 0/r32/eax + 6388 # check v->name + 6389 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 6390 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name + 6391 # check v->type + 6392 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 6393 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args/inout:2/type:0") # Tree-is-atom + 6394 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args/inout:2/type:1") # Tree-value + 6395 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args/inout:2/type:2") # Tree-right + 6396 # . epilogue + 6397 89/<- %esp 5/r32/ebp + 6398 5d/pop-to-ebp + 6399 c3/return + 6400 + 6401 test-function-header-with-multiple-args-and-outputs: + 6402 # . prologue + 6403 55/push-ebp + 6404 89/<- %ebp 4/r32/esp + 6405 # setup + 6406 (clear-stream _test-input-stream) + 6407 (write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx: int {\n") + 6408 # result/ecx: function + 6409 2b/subtract *Function-size 4/r32/esp + 6410 89/<- %ecx 4/r32/esp + 6411 (zero-out %ecx *Function-size) + 6412 # var vars/ebx: (stack live-var 16) + 6413 81 5/subop/subtract %esp 0xc0/imm32 + 6414 68/push 0xc0/imm32/size + 6415 68/push 0/imm32/top + 6416 89/<- %ebx 4/r32/esp + 6417 # convert + 6418 (populate-mu-function-header _test-input-stream %ecx %ebx Stderr 0) + 6419 # check result->name + 6420 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax + 6421 (check-strings-equal %eax "foo" "F - test-function-header-with-multiple-args-and-outputs/name") + 6422 # var inouts/edx: (addr list var) = lookup(result->inouts) + 6423 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax + 6424 89/<- %edx 0/r32/eax + 6425 $test-function-header-with-multiple-args-and-outputs:inout0: + 6426 # var v/ebx: (addr var) = lookup(inouts->value) + 6427 (lookup *edx *(edx+4)) # List-value List-value => eax + 6428 89/<- %ebx 0/r32/eax + 6429 # check v->name + 6430 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 6431 (check-strings-equal %eax "a" "F - test-function-header-with-multiple-args-and-outputs/inout:0") + 6432 # check v->type + 6433 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 6434 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:0") # Tree-is-atom + 6435 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:1") # Tree-value + 6436 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:0/type:2") # Tree-right + 6437 $test-function-header-with-multiple-args-and-outputs:inout1: + 6438 # inouts = lookup(inouts->next) + 6439 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 6440 89/<- %edx 0/r32/eax + 6441 # v = lookup(inouts->value) + 6442 (lookup *edx *(edx+4)) # List-value List-value => eax + 6443 89/<- %ebx 0/r32/eax + 6444 # check v->name + 6445 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 6446 (check-strings-equal %eax "b" "F - test-function-header-with-multiple-args-and-outputs/inout:1") + 6447 # check v->type + 6448 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 6449 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:0") # Tree-is-atom + 6450 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:1") # Tree-value + 6451 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:1/type:2") # Tree-right + 6452 $test-function-header-with-multiple-args-and-outputs:inout2: + 6453 # inouts = lookup(inouts->next) + 6454 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 6455 89/<- %edx 0/r32/eax + 6456 # v = lookup(inouts->value) + 6457 (lookup *edx *(edx+4)) # List-value List-value => eax + 6458 89/<- %ebx 0/r32/eax + 6459 # check v->name + 6460 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 6461 (check-strings-equal %eax "c" "F - test-function-header-with-multiple-args-and-outputs/inout:2") + 6462 # check v->type + 6463 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 6464 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:0") # Tree-is-atom + 6465 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:1") # Tree-value + 6466 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/inout:2/type:2") # Tree-right + 6467 $test-function-header-with-multiple-args-and-outputs:out0: + 6468 # var outputs/edx: (addr list var) = lookup(result->outputs) + 6469 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax + 6470 89/<- %edx 0/r32/eax + 6471 # v = lookup(outputs->value) + 6472 (lookup *edx *(edx+4)) # List-value List-value => eax + 6473 89/<- %ebx 0/r32/eax + 6474 # check v->name + 6475 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 6476 (check-strings-equal %eax "x" "F - test-function-header-with-multiple-args-and-outputs/output:0") + 6477 # check v->register + 6478 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax + 6479 (check-strings-equal %eax "ecx" "F - test-function-header-with-multiple-args-and-outputs/output:0/register") + 6480 # check v->type + 6481 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 6482 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:0") # Tree-is-atom + 6483 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:1") # Tree-value + 6484 (check-ints-equal *(eax+0xc) 0 "F - test-function-header-with-multiple-args-and-outputs/output:0/type:2") # Tree-right + 6485 $test-function-header-with-multiple-args-and-outputs:out1: + 6486 # outputs = lookup(outputs->next) + 6487 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax + 6488 89/<- %edx 0/r32/eax + 6489 # v = lookup(inouts->value) + 6490 (lookup *edx *(edx+4)) # List-value List-value => eax + 6491 89/<- %ebx 0/r32/eax + 6492 # check v->name + 6493 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax + 6494 (check-strings-equal %eax "y" "F - test-function-header-with-multiple-args-and-outputs/output:1") + 6495 # check v->register + 6496 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax + 6497 (check-strings-equal %eax "edx" "F - test-function-header-with-multiple-args-and-outputs/output:1/register") + 6498 # check v->type + 6499 (lookup *(ebx+8) *(ebx+0xc)) # Var-type Var-type => eax + 6500 (check-ints-equal *eax 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:0") # Tree-is-atom + 6501 (check-ints-equal *(eax+4) 1 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:1") # Tree-value + 6502 (check-ints-equal *(eax+0c) 0 "F - test-function-header-with-multiple-args-and-outputs/output:1/type:2") # Tree-right + 6503 # . epilogue + 6504 89/<- %esp 5/r32/ebp + 6505 5d/pop-to-ebp + 6506 c3/return + 6507 + 6508 # format for variables with types + 6509 # x: int + 6510 # x: int, + 6511 # x/eax: int + 6512 # x/eax: int, + 6513 # ignores at most one trailing comma + 6514 # WARNING: modifies name + 6515 parse-var-with-type: # name: (addr slice), first-line: (addr stream byte), out: (addr handle var), err: (addr buffered-file), ed: (addr exit-descriptor) + 6516 # pseudocode: + 6517 # var s: slice + 6518 # if (!slice-ends-with(name, ":")) + 6519 # abort + 6520 # --name->end to skip ':' + 6521 # next-token-from-slice(name->start, name->end, '/', s) + 6522 # new-var-from-slice(s, out) + 6523 # ## register + 6524 # next-token-from-slice(s->end, name->end, '/', s) + 6525 # if (!slice-empty?(s)) + 6526 # out->register = slice-to-string(s) + 6527 # ## type + 6528 # var type: (handle tree type-id) = parse-type(first-line) + 6529 # out->type = type + 6530 # + 6531 # . prologue + 6532 55/push-ebp + 6533 89/<- %ebp 4/r32/esp + 6534 # . save registers + 6535 50/push-eax + 6536 51/push-ecx + 6537 52/push-edx + 6538 53/push-ebx + 6539 56/push-esi + 6540 57/push-edi + 6541 # esi = name + 6542 8b/-> *(ebp+8) 6/r32/esi + 6543 # if (!slice-ends-with?(name, ":")) abort + 6544 8b/-> *(esi+4) 1/r32/ecx # Slice-end + 6545 49/decrement-ecx + 6546 8a/copy-byte *ecx 1/r32/CL + 6547 81 4/subop/and %ecx 0xff/imm32 + 6548 81 7/subop/compare %ecx 0x3a/imm32/colon + 6549 0f 85/jump-if-!= $parse-var-with-type:abort/disp32 + 6550 # --name->end to skip ':' + 6551 ff 1/subop/decrement *(esi+4) + 6552 # var s/ecx: slice + 6553 68/push 0/imm32/end + 6554 68/push 0/imm32/start + 6555 89/<- %ecx 4/r32/esp + 6556 $parse-var-with-type:parse-name: + 6557 (next-token-from-slice *esi *(esi+4) 0x2f %ecx) # Slice-start, Slice-end, '/' + 6558 $parse-var-with-type:create-var: + 6559 # new-var-from-slice(s, out) + 6560 (new-var-from-slice Heap %ecx *(ebp+0x10)) + 6561 # save out->register + 6562 $parse-var-with-type:save-register: + 6563 # . var out-addr/edi: (addr var) = lookup(*out) + 6564 8b/-> *(ebp+0x10) 7/r32/edi + 6565 (lookup *edi *(edi+4)) # => eax + 6566 89/<- %edi 0/r32/eax + 6567 # . s = next-token(...) + 6568 (next-token-from-slice *(ecx+4) *(esi+4) 0x2f %ecx) # s->end, name->end, '/' + 6569 # . if (!slice-empty?(s)) out->register = slice-to-string(s) + 6570 { + 6571 $parse-var-with-type:write-register: + 6572 (slice-empty? %ecx) # => eax + 6573 3d/compare-eax-and 0/imm32/false + 6574 75/jump-if-!= break/disp8 + 6575 # out->register = slice-to-string(s) + 6576 8d/copy-address *(edi+0x18) 0/r32/eax # Var-register + 6577 (slice-to-string Heap %ecx %eax) + 6578 } + 6579 $parse-var-with-type:save-type: + 6580 8d/copy-address *(edi+8) 0/r32/eax # Var-type + 6581 (parse-type Heap *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) + 6582 $parse-var-with-type:end: + 6583 # . reclaim locals + 6584 81 0/subop/add %esp 8/imm32 + 6585 # . restore registers + 6586 5f/pop-to-edi + 6587 5e/pop-to-esi + 6588 5b/pop-to-ebx + 6589 5a/pop-to-edx + 6590 59/pop-to-ecx + 6591 58/pop-to-eax + 6592 # . epilogue + 6593 89/<- %esp 5/r32/ebp + 6594 5d/pop-to-ebp + 6595 c3/return + 6596 + 6597 $parse-var-with-type:abort: + 6598 # error("var should have form 'name: type' in '" line "'\n") + 6599 (write-buffered *(ebp+0x14) "var should have form 'name: type' in '") + 6600 (flush *(ebp+0x14)) + 6601 (rewind-stream *(ebp+0xc)) + 6602 (write-stream-data *(ebp+0x14) *(ebp+0xc)) + 6603 (write-buffered *(ebp+0x14) "'\n") + 6604 (flush *(ebp+0x14)) + 6605 (stop *(ebp+0x18) 1) + 6606 # never gets here + 6607 + 6608 parse-type: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle tree type-id), err: (addr buffered-file), ed: (addr exit-descriptor) + 6609 # pseudocode: + 6610 # var s: slice = next-mu-token(in) + 6611 # assert s != "" + 6612 # assert s != "->" + 6613 # assert s != "{" + 6614 # assert s != "}" + 6615 # if s == ")" + 6616 # return + 6617 # out = allocate(Tree) + 6618 # if s != "(" + 6619 # HACK: if s is an int, parse and return it + 6620 # out->left-is-atom? = true + 6621 # out->value = pos-or-insert-slice(Type-id, s) + 6622 # return + 6623 # out->left = parse-type(ad, in) + 6624 # out->right = parse-type-tree(ad, in) + 6625 # + 6626 # . prologue + 6627 55/push-ebp + 6628 89/<- %ebp 4/r32/esp + 6629 # . save registers + 6630 50/push-eax + 6631 51/push-ecx + 6632 52/push-edx + 6633 # clear out + 6634 (zero-out *(ebp+0x10) *Handle-size) + 6635 # var s/ecx: slice + 6636 68/push 0/imm32 + 6637 68/push 0/imm32 + 6638 89/<- %ecx 4/r32/esp + 6639 # s = next-mu-token(in) + 6640 (next-mu-token *(ebp+0xc) %ecx) + 6641 #? (write-buffered Stderr "tok: ") + 6642 #? (write-slice-buffered Stderr %ecx) + 6643 #? (write-buffered Stderr "$\n") + 6644 #? (flush Stderr) + 6645 # assert s != "" + 6646 (slice-equal? %ecx "") # => eax + 6647 3d/compare-eax-and 0/imm32/false + 6648 0f 85/jump-if-!= $parse-type:abort/disp32 + 6649 # assert s != "{" + 6650 (slice-equal? %ecx "{") # => eax + 6651 3d/compare-eax-and 0/imm32/false + 6652 0f 85/jump-if-!= $parse-type:abort/disp32 + 6653 # assert s != "}" + 6654 (slice-equal? %ecx "}") # => eax + 6655 3d/compare-eax-and 0/imm32/false + 6656 0f 85/jump-if-!= $parse-type:abort/disp32 + 6657 # assert s != "->" + 6658 (slice-equal? %ecx "->") # => eax + 6659 3d/compare-eax-and 0/imm32/false + 6660 0f 85/jump-if-!= $parse-type:abort/disp32 + 6661 # if (s == ")") return + 6662 (slice-equal? %ecx ")") # => eax + 6663 3d/compare-eax-and 0/imm32/false + 6664 0f 85/jump-if-!= $parse-type:end/disp32 + 6665 # out = new tree + 6666 (allocate *(ebp+8) *Tree-size *(ebp+0x10)) + 6667 # var out-addr/edx: (addr tree type-id) = lookup(*out) + 6668 8b/-> *(ebp+0x10) 2/r32/edx + 6669 (lookup *edx *(edx+4)) # => eax + 6670 89/<- %edx 0/r32/eax + 6671 { + 6672 # if (s != "(") break + 6673 (slice-equal? %ecx "(") # => eax + 6674 3d/compare-eax-and 0/imm32/false + 6675 75/jump-if-!= break/disp8 + 6676 # EGREGIOUS HACK for static array sizes: if s is a number, parse it + 6677 { + 6678 $parse-type:check-for-int: + 6679 (is-hex-int? %ecx) # => eax + 6680 3d/compare-eax-and 0/imm32/false + 6681 74/jump-if-= break/disp8 + 6682 $parse-type:int: + 6683 (parse-hex-int-from-slice %ecx) # => eax + 6684 89/<- *(edx+4) 0/r32/eax # Tree-value + 6685 e9/jump $parse-type:end/disp32 + 6686 } + 6687 $parse-type:atom: + 6688 # out->left-is-atom? = true + 6689 c7 0/subop/copy *edx 1/imm32/true # Tree-is-atom + 6690 # out->value = pos-or-insert-slice(Type-id, s) + 6691 (pos-or-insert-slice Type-id %ecx) # => eax + 6692 89/<- *(edx+4) 0/r32/eax # Tree-value + 6693 e9/jump $parse-type:end/disp32 + 6694 } + 6695 $parse-type:non-atom: + 6696 # otherwise s == "(" + 6697 # out->left = parse-type(ad, in) + 6698 8d/copy-address *(edx+4) 0/r32/eax # Tree-left + 6699 (parse-type *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) + 6700 # out->right = parse-type-tree(ad, in) + 6701 8d/copy-address *(edx+0xc) 0/r32/eax # Tree-right + 6702 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) + 6703 $parse-type:end: + 6704 # . reclaim locals + 6705 81 0/subop/add %esp 8/imm32 + 6706 # . restore registers + 6707 5a/pop-to-edx + 6708 59/pop-to-ecx + 6709 58/pop-to-eax + 6710 # . epilogue + 6711 89/<- %esp 5/r32/ebp + 6712 5d/pop-to-ebp + 6713 c3/return + 6714 + 6715 $parse-type:abort: + 6716 # error("unexpected token when parsing type: '" s "'\n") + 6717 (write-buffered *(ebp+0x14) "unexpected token when parsing type: '") + 6718 (write-slice-buffered *(ebp+0x14) %ecx) + 6719 (write-buffered *(ebp+0x14) "'\n") + 6720 (flush *(ebp+0x14)) + 6721 (stop *(ebp+0x18) 1) + 6722 # never gets here + 6723 + 6724 parse-type-tree: # ad: (addr allocation-descriptor), in: (addr stream byte), out: (addr handle tree type-id), err: (addr buffered-file), ed: (addr exit-descriptor) + 6725 # pseudocode: + 6726 # var tmp: (handle tree type-id) = parse-type(ad, in) + 6727 # if tmp == 0 + 6728 # return 0 + 6729 # out = allocate(Tree) + 6730 # out->left = tmp + 6731 # out->right = parse-type-tree(ad, in) + 6732 # 6733 # . prologue 6734 55/push-ebp 6735 89/<- %ebp 4/r32/esp - 6736 # (eax..ecx) = "}a" - 6737 b8/copy-to-eax "}a"/imm32 - 6738 8b/-> *eax 1/r32/ecx - 6739 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6740 05/add-to-eax 4/imm32 - 6741 # var slice/ecx: slice = {eax, ecx} - 6742 51/push-ecx - 6743 50/push-eax - 6744 89/<- %ecx 4/r32/esp - 6745 # - 6746 (is-identifier? %ecx) - 6747 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-close") - 6748 # . epilogue - 6749 89/<- %esp 5/r32/ebp - 6750 5d/pop-to-ebp - 6751 c3/return - 6752 - 6753 test-is-identifier-hyphen: - 6754 # disallow leading '-' since '->' has special meaning - 6755 # . prologue - 6756 55/push-ebp - 6757 89/<- %ebp 4/r32/esp - 6758 # (eax..ecx) = "-a" - 6759 b8/copy-to-eax "-a"/imm32 - 6760 8b/-> *eax 1/r32/ecx - 6761 8d/copy-address *(eax+ecx+4) 1/r32/ecx - 6762 05/add-to-eax 4/imm32 - 6763 # var slice/ecx: slice = {eax, ecx} - 6764 51/push-ecx - 6765 50/push-eax - 6766 89/<- %ecx 4/r32/esp - 6767 # - 6768 (is-identifier? %ecx) - 6769 (check-ints-equal %eax 0 "F - test-is-identifier-hyphen") - 6770 # . epilogue - 6771 89/<- %esp 5/r32/ebp - 6772 5d/pop-to-ebp - 6773 c3/return - 6774 - 6775 populate-mu-function-body: # in: (addr buffered-file), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) - 6776 # . prologue - 6777 55/push-ebp - 6778 89/<- %ebp 4/r32/esp - 6779 # . save registers - 6780 50/push-eax - 6781 56/push-esi - 6782 57/push-edi - 6783 # esi = in - 6784 8b/-> *(ebp+8) 6/r32/esi - 6785 # edi = out - 6786 8b/-> *(ebp+0xc) 7/r32/edi - 6787 # initialize some global state - 6788 c7 0/subop/copy *Curr-block-depth 1/imm32 - 6789 # parse-mu-block(in, vars, out, out->body) - 6790 8d/copy-address *(edi+0x18) 0/r32/eax # Function-body - 6791 (parse-mu-block %esi *(ebp+0x10) %edi %eax *(ebp+0x14) *(ebp+0x18)) - 6792 $populate-mu-function-body:end: - 6793 # . restore registers - 6794 5f/pop-to-edi - 6795 5e/pop-to-esi - 6796 58/pop-to-eax - 6797 # . epilogue - 6798 89/<- %esp 5/r32/ebp - 6799 5d/pop-to-ebp - 6800 c3/return - 6801 - 6802 # parses a block, assuming that the leading '{' has already been read by the caller - 6803 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) - 6804 # pseudocode: - 6805 # var line: (stream byte 512) - 6806 # var word-slice: slice - 6807 # allocate(Heap, Stmt-size, out) - 6808 # var out-addr: (addr block) = lookup(*out) - 6809 # out-addr->tag = 0/block - 6810 # out-addr->var = some unique name - 6811 # push(vars, {out-addr->var, false}) - 6812 # while true # line loop - 6813 # clear-stream(line) - 6814 # read-line-buffered(in, line) - 6815 # if (line->write == 0) break # end of file - 6816 # word-slice = next-mu-token(line) - 6817 # if slice-empty?(word-slice) # end of line - 6818 # continue - 6819 # else if slice-starts-with?(word-slice, "#") - 6820 # continue - 6821 # else if slice-equal?(word-slice, "{") - 6822 # assert(no-tokens-in(line)) - 6823 # block = parse-mu-block(in, vars, fn) - 6824 # append-to-block(out-addr, block) - 6825 # else if slice-equal?(word-slice, "}") - 6826 # break - 6827 # else if slice-ends-with?(word-slice, ":") - 6828 # # TODO: error-check the rest of 'line' - 6829 # --word-slice->end to skip ':' - 6830 # named-block = parse-mu-named-block(word-slice, in, vars, fn) - 6831 # append-to-block(out-addr, named-block) - 6832 # else if slice-equal?(word-slice, "var") - 6833 # var-def = parse-mu-var-def(line, vars, fn) - 6834 # append-to-block(out-addr, var-def) - 6835 # else - 6836 # stmt = parse-mu-stmt(line, vars, fn) - 6837 # append-to-block(out-addr, stmt) - 6838 # pop(vars) - 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 57/push-edi - 6849 # var line/ecx: (stream byte 512) - 6850 81 5/subop/subtract %esp 0x200/imm32 - 6851 68/push 0x200/imm32/size - 6852 68/push 0/imm32/read - 6853 68/push 0/imm32/write - 6854 89/<- %ecx 4/r32/esp - 6855 # var word-slice/edx: slice - 6856 68/push 0/imm32/end - 6857 68/push 0/imm32/start - 6858 89/<- %edx 4/r32/esp - 6859 # allocate into out - 6860 (allocate Heap *Stmt-size *(ebp+0x14)) - 6861 # var out-addr/edi: (addr block) = lookup(*out) - 6862 8b/-> *(ebp+0x14) 7/r32/edi - 6863 (lookup *edi *(edi+4)) # => eax - 6864 89/<- %edi 0/r32/eax - 6865 # out-addr->tag is 0 (block) by default - 6866 # set out-addr->var - 6867 8d/copy-address *(edi+0xc) 0/r32/eax # Block-var - 6868 (new-block-name *(ebp+0x10) %eax) - 6869 # push(vars, out-addr->var) - 6870 (push *(ebp+0xc) *(edi+0xc)) # Block-var - 6871 (push *(ebp+0xc) *(edi+0x10)) # Block-var - 6872 (push *(ebp+0xc) 0) # false - 6873 # increment *Curr-block-depth - 6874 ff 0/subop/increment *Curr-block-depth - 6875 { - 6876 $parse-mu-block:line-loop: - 6877 # line = read-line-buffered(in) - 6878 (clear-stream %ecx) - 6879 (read-line-buffered *(ebp+8) %ecx) - 6880 #? (write-buffered Stderr "line: ") - 6881 #? (write-stream-data Stderr %ecx) - 6882 #? #? (write-buffered Stderr Newline) # line has its own newline - 6883 #? (flush Stderr) - 6884 #? (rewind-stream %ecx) - 6885 # if (line->write == 0) break - 6886 81 7/subop/compare *ecx 0/imm32 - 6887 0f 84/jump-if-= break/disp32 - 6888 #? (write-buffered Stderr "vars:\n") - 6889 #? (dump-vars *(ebp+0xc)) - 6890 # word-slice = next-mu-token(line) - 6891 (next-mu-token %ecx %edx) - 6892 #? (write-buffered Stderr "word: ") - 6893 #? (write-slice-buffered Stderr %edx) - 6894 #? (write-buffered Stderr Newline) - 6895 #? (flush Stderr) - 6896 # if slice-empty?(word-slice) continue - 6897 (slice-empty? %edx) - 6898 3d/compare-eax-and 0/imm32/false - 6899 0f 85/jump-if-!= loop/disp32 - 6900 # if (slice-starts-with?(word-slice, '#') continue - 6901 # . eax = *word-slice->start - 6902 8b/-> *edx 0/r32/eax - 6903 8a/copy-byte *eax 0/r32/AL - 6904 81 4/subop/and %eax 0xff/imm32 - 6905 # . if (eax == '#') continue - 6906 3d/compare-eax-and 0x23/imm32/hash - 6907 0f 84/jump-if-= loop/disp32 - 6908 # if slice-equal?(word-slice, "{") - 6909 { - 6910 $parse-mu-block:check-for-block: - 6911 (slice-equal? %edx "{") - 6912 3d/compare-eax-and 0/imm32/false - 6913 74/jump-if-= break/disp8 - 6914 (check-no-tokens-left %ecx) - 6915 # parse new block and append - 6916 # . var tmp/eax: (handle block) - 6917 68/push 0/imm32 - 6918 68/push 0/imm32 - 6919 89/<- %eax 4/r32/esp - 6920 # . - 6921 (parse-mu-block *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) - 6922 (append-to-block Heap %edi *eax *(eax+4)) - 6923 # . reclaim tmp - 6924 81 0/subop/add %esp 8/imm32 - 6925 # . - 6926 e9/jump $parse-mu-block:line-loop/disp32 - 6927 } - 6928 # if slice-equal?(word-slice, "}") break - 6929 $parse-mu-block:check-for-end: - 6930 (slice-equal? %edx "}") - 6931 3d/compare-eax-and 0/imm32/false - 6932 0f 85/jump-if-!= break/disp32 - 6933 # if slice-ends-with?(word-slice, ":") parse named block and append - 6934 { - 6935 $parse-mu-block:check-for-named-block: - 6936 # . eax = *(word-slice->end-1) - 6937 8b/-> *(edx+4) 0/r32/eax - 6938 48/decrement-eax - 6939 8a/copy-byte *eax 0/r32/AL - 6940 81 4/subop/and %eax 0xff/imm32 - 6941 # . if (eax != ':') break - 6942 3d/compare-eax-and 0x3a/imm32/colon - 6943 0f 85/jump-if-!= break/disp32 - 6944 # TODO: error-check the rest of 'line' - 6945 # - 6946 # skip ':' - 6947 ff 1/subop/decrement *(edx+4) # Slice-end - 6948 # var tmp/eax: (handle block) - 6949 68/push 0/imm32 - 6950 68/push 0/imm32 - 6951 89/<- %eax 4/r32/esp - 6952 # - 6953 (parse-mu-named-block %edx *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) - 6954 (append-to-block Heap %edi *eax *(eax+4)) - 6955 # reclaim tmp - 6956 81 0/subop/add %esp 8/imm32 - 6957 # - 6958 e9/jump $parse-mu-block:line-loop/disp32 - 6959 } - 6960 # if slice-equal?(word-slice, "var") - 6961 { - 6962 $parse-mu-block:check-for-var: - 6963 (slice-equal? %edx "var") - 6964 3d/compare-eax-and 0/imm32/false - 6965 74/jump-if-= break/disp8 - 6966 # var tmp/eax: (handle block) - 6967 68/push 0/imm32 - 6968 68/push 0/imm32 - 6969 89/<- %eax 4/r32/esp - 6970 # - 6971 (parse-mu-var-def %ecx *(ebp+0xc) %eax *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) - 6972 (append-to-block Heap %edi *eax *(eax+4)) - 6973 # reclaim tmp - 6974 81 0/subop/add %esp 8/imm32 - 6975 # - 6976 e9/jump $parse-mu-block:line-loop/disp32 - 6977 } - 6978 $parse-mu-block:regular-stmt: - 6979 # otherwise - 6980 # var tmp/eax: (handle block) - 6981 68/push 0/imm32 - 6982 68/push 0/imm32 - 6983 89/<- %eax 4/r32/esp - 6984 # - 6985 (parse-mu-stmt %ecx *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) - 6986 (append-to-block Heap %edi *eax *(eax+4)) - 6987 # reclaim tmp - 6988 81 0/subop/add %esp 8/imm32 - 6989 # - 6990 e9/jump loop/disp32 - 6991 } # end line loop - 6992 (clean-up-blocks *(ebp+0xc) *Curr-block-depth *(ebp+0x10)) - 6993 # decrement *Curr-block-depth - 6994 ff 1/subop/decrement *Curr-block-depth - 6995 # pop(vars) - 6996 (pop *(ebp+0xc)) # => eax - 6997 (pop *(ebp+0xc)) # => eax - 6998 (pop *(ebp+0xc)) # => eax - 6999 $parse-mu-block:end: - 7000 # . reclaim locals - 7001 81 0/subop/add %esp 0x214/imm32 - 7002 # . restore registers - 7003 5f/pop-to-edi - 7004 5b/pop-to-ebx - 7005 5a/pop-to-edx - 7006 59/pop-to-ecx - 7007 58/pop-to-eax - 7008 # . epilogue - 7009 89/<- %esp 5/r32/ebp - 7010 5d/pop-to-ebp - 7011 c3/return - 7012 - 7013 $parse-mu-block:abort: - 7014 # error("'{' or '}' should be on its own line, but got '") - 7015 (write-buffered *(ebp+0x18) "'{' or '}' should be on its own line, but got '") - 7016 (rewind-stream %ecx) - 7017 (write-stream-data *(ebp+0x18) %ecx) - 7018 (write-buffered *(ebp+0x18) "'\n") - 7019 (flush *(ebp+0x18)) - 7020 (stop *(ebp+0x1c) 1) - 7021 # never gets here - 7022 - 7023 new-block-name: # fn: (addr function), out: (addr handle var) - 7024 # . prologue - 7025 55/push-ebp - 7026 89/<- %ebp 4/r32/esp - 7027 # . save registers - 7028 50/push-eax - 7029 51/push-ecx - 7030 52/push-edx - 7031 # var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:' - 7032 8b/-> *(ebp+8) 0/r32/eax - 7033 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 7034 8b/-> *eax 0/r32/eax # String-size - 7035 05/add-to-eax 0xd/imm32 # 10 + 2 for '$:' - 7036 89/<- %ecx 0/r32/eax - 7037 # var name/edx: (stream byte n) - 7038 29/subtract-from %esp 1/r32/ecx - 7039 ff 6/subop/push %ecx - 7040 68/push 0/imm32/read - 7041 68/push 0/imm32/write - 7042 89/<- %edx 4/r32/esp - 7043 (clear-stream %edx) - 7044 # eax = fn->name - 7045 8b/-> *(ebp+8) 0/r32/eax - 7046 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 7047 # construct result using Next-block-index (and increment it) - 7048 (write %edx "$") - 7049 (write %edx %eax) - 7050 (write %edx ":") - 7051 (print-int32 %edx *Next-block-index) - 7052 ff 0/subop/increment *Next-block-index - 7053 # var s/eax: slice = {name->data, name->data + name->write} (clobbering edx) - 7054 # . eax = name->write - 7055 8b/-> *edx 0/r32/eax - 7056 # . edx = name->data - 7057 8d/copy-address *(edx+0xc) 2/r32/edx - 7058 # . eax = name->write + name->data - 7059 01/add-to %eax 2/r32/edx - 7060 # . push {edx, eax} - 7061 ff 6/subop/push %eax - 7062 ff 6/subop/push %edx - 7063 89/<- %eax 4/r32/esp - 7064 # out = new literal(s) - 7065 (new-literal Heap %eax *(ebp+0xc)) - 7066 #? 8b/-> *(ebp+0xc) 0/r32/eax - 7067 #? (write-buffered Stderr "type allocid in caller after new-literal: ") - 7068 #? (print-int32-buffered Stderr *(eax+8)) - 7069 #? (write-buffered Stderr " for var ") - 7070 #? (print-int32-buffered Stderr %eax) - 7071 #? (write-buffered Stderr Newline) - 7072 #? (flush Stderr) - 7073 $new-block-name:end: - 7074 # . reclaim locals - 7075 81 0/subop/add %ecx 0xc/imm32 # name.{read/write/len} - 7076 81 0/subop/add %ecx 8/imm32 # slice - 7077 01/add-to %esp 1/r32/ecx - 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 check-no-tokens-left: # line: (addr stream byte) - 7088 # . prologue - 7089 55/push-ebp - 7090 89/<- %ebp 4/r32/esp - 7091 # . save registers - 7092 50/push-eax - 7093 51/push-ecx - 7094 # var s/ecx: slice - 7095 68/push 0/imm32/end - 7096 68/push 0/imm32/start - 7097 89/<- %ecx 4/r32/esp - 7098 # - 7099 (next-mu-token *(ebp+8) %ecx) - 7100 # if slice-empty?(s) return - 7101 (slice-empty? %ecx) - 7102 3d/compare-eax-and 0/imm32/false - 7103 75/jump-if-!= $check-no-tokens-left:end/disp8 - 7104 # if (slice-starts-with?(s, '#') return - 7105 # . eax = *s->start - 7106 8b/-> *edx 0/r32/eax - 7107 8a/copy-byte *eax 0/r32/AL - 7108 81 4/subop/and %eax 0xff/imm32 - 7109 # . if (eax == '#') continue - 7110 3d/compare-eax-and 0x23/imm32/hash - 7111 74/jump-if-= $check-no-tokens-left:end/disp8 - 7112 # abort - 7113 (write-buffered Stderr "'{' or '}' should be on its own line, but got '") - 7114 (rewind-stream %ecx) - 7115 (write-stream 2 %ecx) - 7116 (write-buffered Stderr "'\n") - 7117 (flush Stderr) - 7118 # . syscall(exit, 1) - 7119 bb/copy-to-ebx 1/imm32 - 7120 e8/call syscall_exit/disp32 - 7121 # never gets here - 7122 $check-no-tokens-left:end: - 7123 # . reclaim locals - 7124 81 0/subop/add %esp 8/imm32 - 7125 # . restore registers - 7126 59/pop-to-ecx - 7127 58/pop-to-eax - 7128 # . epilogue - 7129 89/<- %esp 5/r32/ebp - 7130 5d/pop-to-ebp - 7131 c3/return - 7132 - 7133 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) - 7134 # pseudocode: - 7135 # var v: (handle var) - 7136 # new-literal(name, v) - 7137 # push(vars, {v, false}) - 7138 # parse-mu-block(in, vars, fn, out) - 7139 # pop(vars) - 7140 # out->tag = block - 7141 # out->var = v - 7142 # - 7143 # . prologue - 7144 55/push-ebp - 7145 89/<- %ebp 4/r32/esp - 7146 # . save registers - 7147 50/push-eax - 7148 51/push-ecx - 7149 57/push-edi - 7150 # var v/ecx: (handle var) - 7151 68/push 0/imm32 - 7152 68/push 0/imm32 - 7153 89/<- %ecx 4/r32/esp - 7154 # - 7155 (new-literal Heap *(ebp+8) %ecx) - 7156 # push(vars, v) - 7157 (push *(ebp+0x10) *ecx) - 7158 (push *(ebp+0x10) *(ecx+4)) - 7159 (push *(ebp+0x10) 0) # false - 7160 # - 7161 (parse-mu-block *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20)) - 7162 # pop v off vars - 7163 (pop *(ebp+0x10)) # => eax - 7164 (pop *(ebp+0x10)) # => eax - 7165 (pop *(ebp+0x10)) # => eax - 7166 # var out-addr/edi: (addr stmt) = lookup(*out) - 7167 8b/-> *(ebp+0x18) 7/r32/edi - 7168 (lookup *edi *(edi+4)) # => eax - 7169 89/<- %edi 0/r32/eax - 7170 # out-addr->tag = named-block - 7171 c7 0/subop/copy *edi 0/imm32/block # Stmt-tag - 7172 # out-addr->var = v - 7173 8b/-> *ecx 0/r32/eax - 7174 89/<- *(edi+0xc) 0/r32/eax # Block-var - 7175 8b/-> *(ecx+4) 0/r32/eax - 7176 89/<- *(edi+0x10) 0/r32/eax # Block-var - 7177 $parse-mu-named-block:end: - 7178 # . reclaim locals - 7179 81 0/subop/add %esp 8/imm32 - 7180 # . restore registers - 7181 5f/pop-to-edi - 7182 59/pop-to-ecx - 7183 58/pop-to-eax - 7184 # . epilogue - 7185 89/<- %esp 5/r32/ebp - 7186 5d/pop-to-ebp - 7187 c3/return - 7188 - 7189 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) - 7190 # . prologue - 7191 55/push-ebp - 7192 89/<- %ebp 4/r32/esp - 7193 # . save registers - 7194 50/push-eax - 7195 51/push-ecx - 7196 52/push-edx - 7197 53/push-ebx - 7198 57/push-edi - 7199 # edi = out - 7200 8b/-> *(ebp+0x10) 7/r32/edi - 7201 # var word-slice/ecx: slice - 7202 68/push 0/imm32/end - 7203 68/push 0/imm32/start - 7204 89/<- %ecx 4/r32/esp - 7205 # var v/edx: (handle var) - 7206 68/push 0/imm32 - 7207 68/push 0/imm32 - 7208 89/<- %edx 4/r32/esp - 7209 # v = parse-var-with-type(next-mu-token(line)) - 7210 (next-mu-token *(ebp+8) %ecx) - 7211 (parse-var-with-type %ecx *(ebp+8) %edx *(ebp+0x18) *(ebp+0x1c)) - 7212 # var v-addr/eax: (addr var) - 7213 (lookup *edx *(edx+4)) # => eax - 7214 # v->block-depth = *Curr-block-depth - 7215 8b/-> *Curr-block-depth 3/r32/ebx - 7216 89/<- *(eax+0x10) 3/r32/ebx # Var-block-depth - 7217 # either v has no register and there's no more to this line - 7218 8b/-> *(eax+0x18) 0/r32/eax # Var-register - 7219 3d/compare-eax-and 0/imm32 - 7220 { - 7221 75/jump-if-!= break/disp8 - 7222 # TODO: disallow vars of type 'byte' on the stack - 7223 # ensure that there's nothing else on this line - 7224 (next-mu-token *(ebp+8) %ecx) - 7225 (slice-empty? %ecx) # => eax - 7226 3d/compare-eax-and 0/imm32/false - 7227 0f 84/jump-if-= $parse-mu-var-def:error2/disp32 - 7228 # - 7229 (new-var-def Heap *edx *(edx+4) %edi) - 7230 e9/jump $parse-mu-var-def:update-vars/disp32 - 7231 } - 7232 # or v has a register and there's more to this line - 7233 { - 7234 0f 84/jump-if-= break/disp32 - 7235 # TODO: disallow vars of type 'byte' in registers 'esi' or 'edi' - 7236 # TODO: vars of type 'byte' should only be initialized by clearing to 0 - 7237 # ensure that the next word is '<-' - 7238 (next-mu-token *(ebp+8) %ecx) - 7239 (slice-equal? %ecx "<-") # => eax - 7240 3d/compare-eax-and 0/imm32/false - 7241 0f 84/jump-if-= $parse-mu-var-def:error1/disp32 - 7242 # - 7243 (new-reg-var-def Heap *edx *(edx+4) %edi) - 7244 (lookup *edi *(edi+4)) # => eax - 7245 (add-operation-and-inputs-to-stmt %eax *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 7246 } - 7247 $parse-mu-var-def:update-vars: - 7248 # push 'v' at end of function - 7249 (push *(ebp+0xc) *edx) - 7250 (push *(ebp+0xc) *(edx+4)) - 7251 (push *(ebp+0xc) 0) # Live-var-register-spilled is unused during parsing - 7252 $parse-mu-var-def:end: - 7253 # . reclaim locals - 7254 81 0/subop/add %esp 0x10/imm32 - 7255 # . restore registers - 7256 5f/pop-to-edi - 7257 5b/pop-to-ebx - 7258 5a/pop-to-edx - 7259 59/pop-to-ecx - 7260 58/pop-to-eax - 7261 # . epilogue - 7262 89/<- %esp 5/r32/ebp - 7263 5d/pop-to-ebp - 7264 c3/return - 7265 - 7266 $parse-mu-var-def:error1: - 7267 (rewind-stream *(ebp+8)) - 7268 # error("register variable requires a valid instruction to initialize but got '" line "'\n") - 7269 (write-buffered *(ebp+0x18) "register variable requires a valid instruction to initialize but got '") - 7270 (flush *(ebp+0x18)) - 7271 (write-stream-data *(ebp+0x18) *(ebp+8)) - 7272 (write-buffered *(ebp+0x18) "'\n") - 7273 (flush *(ebp+0x18)) - 7274 (stop *(ebp+0x1c) 1) - 7275 # never gets here - 7276 - 7277 $parse-mu-var-def:error2: - 7278 (rewind-stream *(ebp+8)) - 7279 # error("fn " fn ": var " var ": variables on the stack can't take an initializer\n") - 7280 (write-buffered *(ebp+0x18) "fn ") - 7281 8b/-> *(ebp+0x14) 0/r32/eax - 7282 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 7283 (write-buffered *(ebp+0x18) %eax) - 7284 (write-buffered *(ebp+0x18) ": var ") - 7285 # var v-addr/eax: (addr var) = lookup(v) - 7286 (lookup *edx *(edx+4)) # => eax - 7287 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 7288 (write-buffered *(ebp+0x18) %eax) - 7289 (write-buffered *(ebp+0x18) ": variables on the stack can't take an initializer\n") - 7290 (flush *(ebp+0x18)) - 7291 (stop *(ebp+0x1c) 1) - 7292 # never gets here - 7293 - 7294 test-parse-mu-var-def: - 7295 # 'var n: int' - 7296 # . prologue - 7297 55/push-ebp - 7298 89/<- %ebp 4/r32/esp - 7299 # setup - 7300 (clear-stream _test-input-stream) - 7301 (write _test-input-stream "n: int\n") # caller has consumed the 'var' - 7302 c7 0/subop/copy *Curr-block-depth 1/imm32 - 7303 # var out/esi: (handle stmt) - 7304 68/push 0/imm32 - 7305 68/push 0/imm32 - 7306 89/<- %esi 4/r32/esp - 7307 # var vars/ecx: (stack (addr var) 16) - 7308 81 5/subop/subtract %esp 0xc0/imm32 - 7309 68/push 0xc0/imm32/size - 7310 68/push 0/imm32/top - 7311 89/<- %ecx 4/r32/esp - 7312 (clear-stack %ecx) - 7313 # convert - 7314 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) - 7315 # var out-addr/esi: (addr stmt) - 7316 (lookup *esi *(esi+4)) # => eax - 7317 89/<- %esi 0/r32/eax - 7318 # - 7319 (check-ints-equal *esi 2 "F - test-parse-mu-var-def/tag") # Stmt-tag is var-def - 7320 # var v/ecx: (addr var) = lookup(out->var) - 7321 (lookup *(esi+4) *(esi+8)) # Vardef-var Vardef-var => eax - 7322 89/<- %ecx 0/r32/eax - 7323 # v->name - 7324 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 7325 (check-strings-equal %eax "n" "F - test-parse-mu-var-def/var-name") - 7326 # v->register - 7327 (check-ints-equal *(ecx+0x18) 0 "F - test-parse-mu-var-def/var-register") # Var-register - 7328 # v->block-depth - 7329 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-var-def/output-block-depth") # Var-block-depth - 7330 # v->type == int - 7331 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 7332 (check-ints-equal *eax 1 "F - test-parse-mu-var-def/var-type:0") # Tree-is-atom - 7333 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-var-def/var-type:1") # Tree-value - 7334 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-var-def/var-type:2") # Tree-right - 7335 # . epilogue - 7336 89/<- %esp 5/r32/ebp - 7337 5d/pop-to-ebp - 7338 c3/return - 7339 - 7340 test-parse-mu-reg-var-def: - 7341 # 'var n/eax: int <- copy 0' - 7342 # . prologue - 7343 55/push-ebp - 7344 89/<- %ebp 4/r32/esp - 7345 # setup - 7346 (clear-stream _test-input-stream) - 7347 (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var' - 7348 c7 0/subop/copy *Curr-block-depth 1/imm32 - 7349 # var out/esi: (handle stmt) - 7350 68/push 0/imm32 - 7351 68/push 0/imm32 - 7352 89/<- %esi 4/r32/esp - 7353 # var vars/ecx: (stack (addr var) 16) - 7354 81 5/subop/subtract %esp 0xc0/imm32 - 7355 68/push 0xc0/imm32/size - 7356 68/push 0/imm32/top - 7357 89/<- %ecx 4/r32/esp - 7358 (clear-stack %ecx) - 7359 # convert - 7360 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) - 7361 # var out-addr/esi: (addr stmt) - 7362 (lookup *esi *(esi+4)) # => eax - 7363 89/<- %esi 0/r32/eax - 7364 # - 7365 (check-ints-equal *esi 3 "F - test-parse-mu-reg-var-def/tag") # Stmt-tag is reg-var-def - 7366 # var v/ecx: (addr var) = lookup(out->outputs->value) - 7367 # . eax: (addr stmt-var) = lookup(out->outputs) - 7368 (lookup *(esi+0x14) *(esi+0x18)) # Regvardef-outputs Regvardef-outputs => eax - 7369 # . - 7370 (check-ints-equal *(eax+8) 0 "F - test-parse-mu-reg-var-def/single-output") # Stmt-var-next - 7371 # . eax: (addr var) = lookup(eax->value) - 7372 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 7373 # . ecx = eax - 7374 89/<- %ecx 0/r32/eax - 7375 # v->name - 7376 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 7377 (check-strings-equal %eax "n" "F - test-parse-mu-reg-var-def/output-name") # Var-name - 7378 # v->register - 7379 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax - 7380 (check-strings-equal %eax "eax" "F - test-parse-mu-reg-var-def/output-register") - 7381 # v->block-depth - 7382 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-reg-var-def/output-block-depth") # Var-block-depth - 7383 # v->type == int - 7384 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 7385 (check-ints-equal *eax 1 "F - test-parse-mu-reg-var-def/output-type:0") # Tree-is-atom - 7386 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-reg-var-def/output-type:1") # Tree-value - 7387 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-reg-var-def/output-type:2") # Tree-right - 7388 # . epilogue - 7389 89/<- %esp 5/r32/ebp - 7390 5d/pop-to-ebp - 7391 c3/return - 7392 - 7393 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) - 7394 # Carefully push any outputs on the vars stack _after_ reading the inputs - 7395 # that may conflict with them. - 7396 # - 7397 # The only situation in which outputs are pushed here (when it's not a - 7398 # 'var' vardef stmt), and so can possibly conflict with inputs, is if the - 7399 # output is a function output. - 7400 # - 7401 # pseudocode: - 7402 # var name: slice - 7403 # allocate(Heap, Stmt-size, out) - 7404 # var out-addr: (addr stmt) = lookup(*out) - 7405 # out-addr->tag = stmt - 7406 # if stmt-has-outputs?(line) - 7407 # while true - 7408 # name = next-mu-token(line) - 7409 # if (name == '<-') break - 7410 # assert(is-identifier?(name)) - 7411 # var v: (handle var) = lookup-var-or-find-in-fn-outputs(name, vars, fn) - 7412 # out-addr->outputs = append(v, out-addr->outputs) - 7413 # add-operation-and-inputs-to-stmt(out-addr, line, vars) - 7414 # for output in stmt->outputs: - 7415 # maybe-define-var(output, vars) - 7416 # - 7417 # . prologue - 7418 55/push-ebp - 7419 89/<- %ebp 4/r32/esp - 7420 # . save registers - 7421 50/push-eax - 7422 51/push-ecx - 7423 52/push-edx - 7424 53/push-ebx - 7425 57/push-edi - 7426 # var name/ecx: slice - 7427 68/push 0/imm32/end - 7428 68/push 0/imm32/start - 7429 89/<- %ecx 4/r32/esp - 7430 # var is-deref?/edx: boolean = false - 7431 ba/copy-to-edx 0/imm32/false - 7432 # var v: (handle var) - 7433 68/push 0/imm32 - 7434 68/push 0/imm32 - 7435 89/<- %ebx 4/r32/esp - 7436 # - 7437 (allocate Heap *Stmt-size *(ebp+0x14)) - 7438 # var out-addr/edi: (addr stmt) = lookup(*out) - 7439 8b/-> *(ebp+0x14) 7/r32/edi - 7440 (lookup *edi *(edi+4)) # => eax - 7441 89/<- %edi 0/r32/eax - 7442 # out-addr->tag = 1/stmt - 7443 c7 0/subop/copy *edi 1/imm32/stmt1 # Stmt-tag - 7444 { - 7445 (stmt-has-outputs? *(ebp+8)) - 7446 3d/compare-eax-and 0/imm32/false - 7447 0f 84/jump-if-= break/disp32 - 7448 { - 7449 $parse-mu-stmt:read-outputs: - 7450 # name = next-mu-token(line) - 7451 (next-mu-token *(ebp+8) %ecx) - 7452 # if slice-empty?(word-slice) break - 7453 (slice-empty? %ecx) # => eax - 7454 3d/compare-eax-and 0/imm32/false - 7455 0f 85/jump-if-!= break/disp32 - 7456 # if (name == "<-") break - 7457 (slice-equal? %ecx "<-") # => eax - 7458 3d/compare-eax-and 0/imm32/false - 7459 0f 85/jump-if-!= break/disp32 - 7460 # is-deref? = false - 7461 ba/copy-to-edx 0/imm32/false - 7462 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? - 7463 8b/-> *ecx 0/r32/eax # Slice-start - 7464 8a/copy-byte *eax 0/r32/AL - 7465 81 4/subop/and %eax 0xff/imm32 - 7466 3d/compare-eax-and 0x2a/imm32/asterisk - 7467 { - 7468 75/jump-if-!= break/disp8 - 7469 ff 0/subop/increment *ecx - 7470 ba/copy-to-edx 1/imm32/true - 7471 } - 7472 # assert(is-identifier?(name)) - 7473 (is-identifier? %ecx) # => eax - 7474 3d/compare-eax-and 0/imm32/false - 7475 0f 84/jump-if-= $parse-mu-stmt:abort/disp32 - 7476 # - 7477 (lookup-var-or-find-in-fn-outputs %ecx *(ebp+0xc) *(ebp+0x10) %ebx *(ebp+0x18) *(ebp+0x1c)) - 7478 8d/copy-address *(edi+0x14) 0/r32/eax # Stmt1-outputs - 7479 (append-stmt-var Heap *ebx *(ebx+4) *(edi+0x14) *(edi+0x18) %edx %eax) # Stmt1-outputs - 7480 # - 7481 e9/jump loop/disp32 - 7482 } - 7483 } - 7484 (add-operation-and-inputs-to-stmt %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) - 7485 $parse-mu-stmt:define-outputs: - 7486 # var output/edi: (addr stmt-var) = lookup(out-addr->outputs) - 7487 (lookup *(edi+0x14) *(edi+0x18)) # Stmt1-outputs Stmt1-outputs => eax - 7488 89/<- %edi 0/r32/eax - 7489 { - 7490 $parse-mu-stmt:define-outputs-loop: - 7491 # if (output == null) break - 7492 81 7/subop/compare %edi 0/imm32 - 7493 74/jump-if-= break/disp8 - 7494 # - 7495 (maybe-define-var *edi *(edi+4) *(ebp+0xc)) # if output is a deref, then it's already been defined, - 7496 # and must be in vars. This call will be a no-op, but safe. - 7497 # output = output->next - 7498 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax - 7499 89/<- %edi 0/r32/eax - 7500 # - 7501 eb/jump loop/disp8 - 7502 } - 7503 $parse-mu-stmt:end: - 7504 # . reclaim locals - 7505 81 0/subop/add %esp 0x10/imm32 - 7506 # . restore registers - 7507 5f/pop-to-edi - 7508 5b/pop-to-ebx - 7509 5a/pop-to-edx - 7510 59/pop-to-ecx - 7511 58/pop-to-eax - 7512 # . epilogue - 7513 89/<- %esp 5/r32/ebp - 7514 5d/pop-to-ebp - 7515 c3/return - 7516 - 7517 $parse-mu-stmt:abort: - 7518 # error("invalid identifier '" name "'\n") - 7519 (write-buffered *(ebp+0x18) "invalid identifier '") - 7520 (write-slice-buffered *(ebp+0x18) %ecx) - 7521 (write-buffered *(ebp+0x18) "'\n") - 7522 (flush *(ebp+0x18)) - 7523 (stop *(ebp+0x1c) 1) - 7524 # never gets here - 7525 - 7526 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) - 7527 # pseudocode: - 7528 # stmt->name = slice-to-string(next-mu-token(line)) - 7529 # while true - 7530 # name = next-mu-token(line) - 7531 # v = lookup-var-or-literal(name) - 7532 # stmt->inouts = append(v, stmt->inouts) - 7533 # - 7534 # . prologue - 7535 55/push-ebp - 7536 89/<- %ebp 4/r32/esp - 7537 # . save registers - 7538 50/push-eax - 7539 51/push-ecx - 7540 52/push-edx - 7541 53/push-ebx - 7542 56/push-esi - 7543 57/push-edi - 7544 # edi = stmt - 7545 8b/-> *(ebp+8) 7/r32/edi - 7546 # var name/ecx: slice - 7547 68/push 0/imm32/end - 7548 68/push 0/imm32/start - 7549 89/<- %ecx 4/r32/esp - 7550 # var is-deref?/edx: boolean = false - 7551 ba/copy-to-edx 0/imm32/false - 7552 # var v/esi: (handle var) - 7553 68/push 0/imm32 - 7554 68/push 0/imm32 - 7555 89/<- %esi 4/r32/esp - 7556 $add-operation-and-inputs-to-stmt:read-operation: - 7557 (next-mu-token *(ebp+0xc) %ecx) - 7558 8d/copy-address *(edi+4) 0/r32/eax # Stmt1-operation or Regvardef-operationStmt1-operation or Regvardef-operation - 7559 (slice-to-string Heap %ecx %eax) - 7560 # var is-get?/ebx: boolean = (name == "get") - 7561 (slice-equal? %ecx "get") # => eax - 7562 89/<- %ebx 0/r32/eax - 7563 { - 7564 $add-operation-and-inputs-to-stmt:read-inouts: - 7565 # name = next-mu-token(line) - 7566 (next-mu-token *(ebp+0xc) %ecx) - 7567 # if slice-empty?(word-slice) break - 7568 (slice-empty? %ecx) # => eax - 7569 3d/compare-eax-and 0/imm32/false - 7570 0f 85/jump-if-!= break/disp32 - 7571 # if (name == "<-") abort - 7572 (slice-equal? %ecx "<-") - 7573 3d/compare-eax-and 0/imm32/false - 7574 0f 85/jump-if-!= $add-operation-and-inputs-to-stmt:abort/disp32 - 7575 # if (is-get? && second operand) lookup or create offset - 7576 { - 7577 81 7/subop/compare %ebx 0/imm32/false - 7578 74/jump-if-= break/disp8 - 7579 (lookup *(edi+0xc) *(edi+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 7580 3d/compare-eax-and 0/imm32 - 7581 74/jump-if-= break/disp8 - 7582 (lookup-or-create-constant %eax %ecx %esi) - 7583 #? (lookup *esi *(esi+4)) - 7584 #? (write-buffered Stderr "creating new output var ") - 7585 #? (print-int32-buffered Stderr %eax) - 7586 #? (write-buffered Stderr " for field called ") - 7587 #? (write-slice-buffered Stderr %ecx) - 7588 #? (write-buffered Stderr "; var name ") - 7589 #? (lookup *eax *(eax+4)) # Var-name - 7590 #? (write-buffered Stderr %eax) - 7591 #? (write-buffered Stderr Newline) - 7592 #? (flush Stderr) - 7593 e9/jump $add-operation-and-inputs-to-stmt:save-var/disp32 - 7594 } - 7595 # is-deref? = false - 7596 ba/copy-to-edx 0/imm32/false - 7597 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? - 7598 8b/-> *ecx 0/r32/eax # Slice-start - 7599 8a/copy-byte *eax 0/r32/AL - 7600 81 4/subop/and %eax 0xff/imm32 - 7601 3d/compare-eax-and 0x2a/imm32/asterisk - 7602 { - 7603 75/jump-if-!= break/disp8 - 7604 $add-operation-and-inputs-to-stmt:inout-is-deref: - 7605 ff 0/subop/increment *ecx - 7606 ba/copy-to-edx 1/imm32/true - 7607 } - 7608 (lookup-var-or-literal %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 7609 $add-operation-and-inputs-to-stmt:save-var: - 7610 8d/copy-address *(edi+0xc) 0/r32/eax - 7611 (append-stmt-var Heap *esi *(esi+4) *(edi+0xc) *(edi+0x10) %edx %eax) # Stmt1-inouts or Regvardef-inouts - 7612 # - 7613 e9/jump loop/disp32 - 7614 } - 7615 $add-operation-and-inputs-to-stmt:end: - 7616 # . reclaim locals - 7617 81 0/subop/add %esp 0x10/imm32 - 7618 # . restore registers - 7619 5f/pop-to-edi - 7620 5e/pop-to-esi - 7621 5b/pop-to-ebx - 7622 5a/pop-to-edx - 7623 59/pop-to-ecx - 7624 58/pop-to-eax - 7625 # . epilogue - 7626 89/<- %esp 5/r32/ebp - 7627 5d/pop-to-ebp - 7628 c3/return - 7629 - 7630 $add-operation-and-inputs-to-stmt:abort: - 7631 # error("fn ___: invalid identifier in '" line "'\n") - 7632 (write-buffered *(ebp+0x18) "fn ") - 7633 8b/-> *(ebp+0x14) 0/r32/eax - 7634 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 7635 (write-buffered *(ebp+0x18) %eax) - 7636 (rewind-stream *(ebp+0xc)) - 7637 (write-buffered *(ebp+0x18) ": invalid identifier in '") - 7638 (write-stream-data *(ebp+0x18) *(ebp+0xc)) - 7639 (write-buffered *(ebp+0x18) "'\n") - 7640 (flush *(ebp+0x18)) - 7641 (stop *(ebp+0x1c) 1) - 7642 # never gets here - 7643 - 7644 stmt-has-outputs?: # line: (addr stream byte) -> result/eax: boolean - 7645 # . prologue - 7646 55/push-ebp - 7647 89/<- %ebp 4/r32/esp - 7648 # . save registers - 7649 51/push-ecx - 7650 # var word-slice/ecx: slice - 7651 68/push 0/imm32/end - 7652 68/push 0/imm32/start - 7653 89/<- %ecx 4/r32/esp - 7654 # result = false - 7655 b8/copy-to-eax 0/imm32/false - 7656 (rewind-stream *(ebp+8)) - 7657 { - 7658 (next-mu-token *(ebp+8) %ecx) - 7659 # if slice-empty?(word-slice) break - 7660 (slice-empty? %ecx) - 7661 3d/compare-eax-and 0/imm32/false - 7662 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) - 7663 0f 85/jump-if-!= break/disp32 - 7664 # if slice-starts-with?(word-slice, '#') break - 7665 # . eax = *word-slice->start - 7666 8b/-> *ecx 0/r32/eax - 7667 8a/copy-byte *eax 0/r32/AL - 7668 81 4/subop/and %eax 0xff/imm32 - 7669 # . if (eax == '#') break - 7670 3d/compare-eax-and 0x23/imm32/hash - 7671 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) - 7672 0f 84/jump-if-= break/disp32 - 7673 # if slice-equal?(word-slice, '<-') return true - 7674 (slice-equal? %ecx "<-") - 7675 3d/compare-eax-and 0/imm32/false - 7676 74/jump-if-= loop/disp8 - 7677 b8/copy-to-eax 1/imm32/true - 7678 } - 7679 $stmt-has-outputs:end: - 7680 (rewind-stream *(ebp+8)) - 7681 # . reclaim locals - 7682 81 0/subop/add %esp 8/imm32 - 7683 # . restore registers - 7684 59/pop-to-ecx - 7685 # . epilogue - 7686 89/<- %esp 5/r32/ebp - 7687 5d/pop-to-ebp - 7688 c3/return - 7689 - 7690 # if 'name' starts with a digit, create a new literal var for it - 7691 # otherwise return first 'name' from the top (back) of 'vars' and abort if not found - 7692 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) - 7693 # . prologue - 7694 55/push-ebp - 7695 89/<- %ebp 4/r32/esp - 7696 # . save registers - 7697 50/push-eax - 7698 51/push-ecx - 7699 56/push-esi - 7700 # esi = name - 7701 8b/-> *(ebp+8) 6/r32/esi - 7702 # if slice-empty?(name) abort - 7703 (slice-empty? %esi) # => eax - 7704 3d/compare-eax-and 0/imm32/false - 7705 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32 - 7706 # var c/ecx: byte = *name->start - 7707 8b/-> *esi 1/r32/ecx - 7708 8a/copy-byte *ecx 1/r32/CL - 7709 81 4/subop/and %ecx 0xff/imm32 - 7710 # if is-decimal-digit?(c) return new var(name) - 7711 { - 7712 (is-decimal-digit? %ecx) # => eax - 7713 3d/compare-eax-and 0/imm32/false - 7714 74/jump-if-= break/disp8 - 7715 $lookup-var-or-literal:literal: - 7716 (new-literal-integer Heap %esi *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) - 7717 eb/jump $lookup-var-or-literal:end/disp8 - 7718 } - 7719 # else if (c == '"') return new var(name) - 7720 { - 7721 81 7/subop/compare %ecx 0x22/imm32/dquote - 7722 75/jump-if-!= break/disp8 - 7723 $lookup-var-or-literal:literal-string: - 7724 (new-literal Heap %esi *(ebp+0x10)) - 7725 eb/jump $lookup-var-or-literal:end/disp8 - 7726 } - 7727 # otherwise return lookup-var(name, vars) - 7728 { - 7729 $lookup-var-or-literal:var: - 7730 (lookup-var %esi *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 7731 } - 7732 $lookup-var-or-literal:end: - 7733 # . restore registers - 7734 5e/pop-to-esi - 7735 59/pop-to-ecx - 7736 58/pop-to-eax - 7737 # . epilogue - 7738 89/<- %esp 5/r32/ebp - 7739 5d/pop-to-ebp - 7740 c3/return - 7741 - 7742 $lookup-var-or-literal:abort: - 7743 (write-buffered *(ebp+0x18) "fn ") - 7744 8b/-> *(ebp+0x14) 0/r32/eax - 7745 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 7746 (write-buffered *(ebp+0x18) %eax) - 7747 (write-buffered *(ebp+0x18) ": empty variable!") - 7748 (flush *(ebp+0x18)) - 7749 (stop *(ebp+0x1c) 1) - 7750 # never gets here - 7751 - 7752 # return first 'name' from the top (back) of 'vars' and abort if not found - 7753 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) - 7754 # . prologue - 7755 55/push-ebp - 7756 89/<- %ebp 4/r32/esp - 7757 # . save registers - 7758 50/push-eax - 7759 # - 7760 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) - 7761 # if (*out == 0) abort - 7762 8b/-> *(ebp+0x10) 0/r32/eax - 7763 81 7/subop/compare *eax 0/imm32 - 7764 74/jump-if-= $lookup-var:abort/disp8 - 7765 $lookup-var:end: - 7766 # . restore registers - 7767 58/pop-to-eax - 7768 # . epilogue - 7769 89/<- %esp 5/r32/ebp - 7770 5d/pop-to-ebp - 7771 c3/return - 7772 - 7773 $lookup-var:abort: - 7774 (write-buffered *(ebp+0x18) "fn ") - 7775 8b/-> *(ebp+0x14) 0/r32/eax - 7776 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 7777 (write-buffered *(ebp+0x18) %eax) - 7778 (write-buffered *(ebp+0x18) ": unknown variable '") - 7779 (write-slice-buffered *(ebp+0x18) *(ebp+8)) - 7780 (write-buffered *(ebp+0x18) "'\n") - 7781 (flush *(ebp+0x18)) - 7782 (stop *(ebp+0x1c) 1) - 7783 # never gets here - 7784 - 7785 # return first 'name' from the top (back) of 'vars', and 0/null if not found - 7786 # ensure that 'name' if in a register is the topmost variable in that register - 7787 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) - 7788 # pseudocode: - 7789 # var curr: (addr handle var) = &vars->data[vars->top - 12] - 7790 # var min = vars->data - 7791 # while curr >= min - 7792 # var v: (handle var) = *curr - 7793 # if v->name == name - 7794 # return - 7795 # curr -= 12 - 7796 # - 7797 # . prologue - 7798 55/push-ebp - 7799 89/<- %ebp 4/r32/esp - 7800 # . save registers - 7801 50/push-eax - 7802 51/push-ecx - 7803 52/push-edx - 7804 53/push-ebx - 7805 56/push-esi - 7806 57/push-edi - 7807 # clear out - 7808 (zero-out *(ebp+0x10) *Handle-size) - 7809 # esi = vars - 7810 8b/-> *(ebp+0xc) 6/r32/esi - 7811 # ebx = vars->top - 7812 8b/-> *esi 3/r32/ebx - 7813 # if (vars->top > vars->size) abort - 7814 3b/compare<- *(esi+4) 0/r32/eax - 7815 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 - 7816 # var min/edx: (addr handle var) = vars->data - 7817 8d/copy-address *(esi+8) 2/r32/edx - 7818 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] - 7819 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 - 7820 # var var-in-reg/edi: 8 addrs - 7821 68/push 0/imm32 - 7822 68/push 0/imm32 - 7823 68/push 0/imm32 - 7824 68/push 0/imm32 - 7825 68/push 0/imm32 - 7826 68/push 0/imm32 - 7827 68/push 0/imm32 - 7828 68/push 0/imm32 - 7829 89/<- %edi 4/r32/esp - 7830 { - 7831 $lookup-var-helper:loop: - 7832 # if (curr < min) return - 7833 39/compare %ebx 2/r32/edx - 7834 0f 82/jump-if-addr< break/disp32 - 7835 # var v/ecx: (addr var) = lookup(*curr) - 7836 (lookup *ebx *(ebx+4)) # => eax - 7837 89/<- %ecx 0/r32/eax - 7838 # var vn/eax: (addr array byte) = lookup(v->name) - 7839 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax - 7840 # if (vn == name) return curr - 7841 (slice-equal? *(ebp+8) %eax) # => eax - 7842 3d/compare-eax-and 0/imm32/false - 7843 { - 7844 74/jump-if-= break/disp8 - 7845 $lookup-var-helper:found: - 7846 # var vr/eax: (addr array byte) = lookup(v->register) - 7847 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax - 7848 3d/compare-eax-and 0/imm32 - 7849 { - 7850 74/jump-if-= break/disp8 - 7851 $lookup-var-helper:found-register: - 7852 # var reg/eax: int = get(Registers, vr) - 7853 (get Mu-registers %eax 0xc "Mu-registers") # => eax - 7854 8b/-> *eax 0/r32/eax - 7855 # if (var-in-reg[reg]) error - 7856 8b/-> *(edi+eax<<2) 0/r32/eax - 7857 3d/compare-eax-and 0/imm32 - 7858 0f 85/jump-if-!= $lookup-var-helper:error2/disp32 - 7859 } - 7860 $lookup-var-helper:return: - 7861 # esi = out - 7862 8b/-> *(ebp+0x10) 6/r32/esi - 7863 # *out = *curr - 7864 8b/-> *ebx 0/r32/eax - 7865 89/<- *esi 0/r32/eax - 7866 8b/-> *(ebx+4) 0/r32/eax - 7867 89/<- *(esi+4) 0/r32/eax - 7868 # return - 7869 eb/jump $lookup-var-helper:end/disp8 - 7870 } - 7871 # 'name' not yet found; update var-in-reg if v in register - 7872 # . var vr/eax: (addr array byte) = lookup(v->register) - 7873 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax - 7874 # . if (var == 0) continue - 7875 3d/compare-eax-and 0/imm32 - 7876 74/jump-if-= $lookup-var-helper:continue/disp8 - 7877 # . var reg/eax: int = get(Registers, vr) - 7878 (get Mu-registers %eax 0xc "Mu-registers") # => eax - 7879 8b/-> *eax 0/r32/eax - 7880 # . if (var-in-reg[reg] == 0) var-in-reg[reg] = v - 7881 81 7/subop/compare *(edi+eax<<2) 0/imm32 - 7882 75/jump-if-!= $lookup-var-helper:continue/disp8 - 7883 89/<- *(edi+eax<<2) 1/r32/ecx - 7884 $lookup-var-helper:continue: - 7885 # curr -= 12 - 7886 81 5/subop/subtract %ebx 0xc/imm32 - 7887 e9/jump loop/disp32 - 7888 } - 7889 $lookup-var-helper:end: - 7890 # . reclaim locals - 7891 81 0/subop/add %esp 0x20/imm32 - 7892 # . restore registers - 7893 5f/pop-to-edi - 7894 5e/pop-to-esi - 7895 5b/pop-to-ebx - 7896 5a/pop-to-edx - 7897 59/pop-to-ecx - 7898 58/pop-to-eax - 7899 # . epilogue - 7900 89/<- %esp 5/r32/ebp - 7901 5d/pop-to-ebp - 7902 c3/return - 7903 - 7904 $lookup-var-helper:error1: - 7905 (write-buffered *(ebp+0x18) "fn ") - 7906 8b/-> *(ebp+0x14) 0/r32/eax - 7907 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 7908 (write-buffered *(ebp+0x18) %eax) - 7909 (write-buffered *(ebp+0x18) ": malformed stack when looking up '") - 7910 (write-slice-buffered *(ebp+0x18) *(ebp+8)) - 7911 (write-buffered *(ebp+0x18) "'\n") - 7912 (flush *(ebp+0x18)) - 7913 (stop *(ebp+0x1c) 1) - 7914 # never gets here - 7915 - 7916 $lookup-var-helper:error2: - 7917 # eax contains the conflicting var at this point - 7918 (write-buffered *(ebp+0x18) "fn ") - 7919 50/push-eax - 7920 8b/-> *(ebp+0x14) 0/r32/eax - 7921 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 7922 (write-buffered *(ebp+0x18) %eax) - 7923 58/pop-eax - 7924 (write-buffered *(ebp+0x18) ": register ") - 7925 50/push-eax - 7926 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax - 7927 (write-buffered *(ebp+0x18) %eax) - 7928 58/pop-to-eax - 7929 (write-buffered *(ebp+0x18) " reads var '") - 7930 (write-slice-buffered *(ebp+0x18) *(ebp+8)) - 7931 (write-buffered *(ebp+0x18) "' after writing var '") - 7932 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 7933 (write-buffered *(ebp+0x18) %eax) - 7934 (write-buffered *(ebp+0x18) "'\n") - 7935 (flush *(ebp+0x18)) - 7936 (stop *(ebp+0x1c) 1) - 7937 # never gets here - 7938 - 7939 dump-vars: # vars: (addr stack live-var) - 7940 # pseudocode: - 7941 # var curr: (addr handle var) = &vars->data[vars->top - 12] - 7942 # var min = vars->data - 7943 # while curr >= min - 7944 # var v: (handle var) = *curr - 7945 # print v - 7946 # curr -= 12 - 7947 # - 7948 # . prologue - 7949 55/push-ebp - 7950 89/<- %ebp 4/r32/esp - 7951 # . save registers - 7952 52/push-edx - 7953 53/push-ebx - 7954 56/push-esi - 7955 # esi = vars - 7956 8b/-> *(ebp+8) 6/r32/esi - 7957 # ebx = vars->top - 7958 8b/-> *esi 3/r32/ebx - 7959 # var min/edx: (addr handle var) = vars->data - 7960 8d/copy-address *(esi+8) 2/r32/edx - 7961 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] - 7962 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 - 7963 { - 7964 $dump-vars:loop: - 7965 # if (curr < min) return - 7966 39/compare %ebx 2/r32/edx - 7967 0f 82/jump-if-addr< break/disp32 - 7968 # - 7969 (write-buffered Stderr " var@") - 7970 (dump-var 2 %ebx) - 7971 # curr -= 12 - 7972 81 5/subop/subtract %ebx 0xc/imm32 - 7973 e9/jump loop/disp32 - 7974 } - 7975 $dump-vars:end: - 7976 # . restore registers - 7977 5e/pop-to-esi - 7978 5b/pop-to-ebx - 7979 5a/pop-to-edx - 7980 # . epilogue - 7981 89/<- %esp 5/r32/ebp - 7982 5d/pop-to-ebp - 7983 c3/return - 7984 - 7985 == data - 7986 # Like Registers, but no esp or ebp - 7987 Mu-registers: # (addr stream {(handle array byte), int}) - 7988 # a table is a stream - 7989 0x48/imm32/write - 7990 0/imm32/read - 7991 0x48/imm32/length - 7992 # data - 7993 # it is perfectly ok to use fake alloc-ids -- as long as you never try to reclaim them - 7994 0x11/imm32/alloc-id $Mu-register-eax/imm32 0/imm32 - 7995 0x11/imm32/alloc-id $Mu-register-ecx/imm32 1/imm32 - 7996 0x11/imm32/alloc-id $Mu-register-edx/imm32 2/imm32 - 7997 0x11/imm32/alloc-id $Mu-register-ebx/imm32 3/imm32 - 7998 0x11/imm32/alloc-id $Mu-register-esi/imm32 6/imm32 - 7999 0x11/imm32/alloc-id $Mu-register-edi/imm32 7/imm32 - 8000 - 8001 $Mu-register-eax: - 8002 0x11/imm32/alloc-id - 8003 3/imm32/size - 8004 0x65/e 0x61/a 0x78/x - 8005 - 8006 $Mu-register-ecx: - 8007 0x11/imm32/alloc-id - 8008 3/imm32/size - 8009 0x65/e 0x63/c 0x78/x - 8010 - 8011 $Mu-register-edx: - 8012 0x11/imm32/alloc-id - 8013 3/imm32/size - 8014 0x65/e 0x64/d 0x78/x - 8015 - 8016 $Mu-register-ebx: - 8017 0x11/imm32/alloc-id - 8018 3/imm32/size - 8019 0x65/e 0x62/b 0x78/x - 8020 - 8021 $Mu-register-esi: - 8022 0x11/imm32/alloc-id - 8023 3/imm32/size - 8024 0x65/e 0x73/s 0x69/i - 8025 - 8026 $Mu-register-edi: - 8027 0x11/imm32/alloc-id - 8028 3/imm32/size - 8029 0x65/e 0x64/d 0x69/i - 8030 - 8031 == code - 8032 - 8033 # return first 'name' from the top (back) of 'vars' and create a new var for a fn output if not found - 8034 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) - 8035 # . prologue - 8036 55/push-ebp - 8037 89/<- %ebp 4/r32/esp - 8038 # . save registers - 8039 50/push-eax - 8040 # - 8041 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) # arg order slightly different; 'fn' is deemphasized - 8042 { - 8043 # if (out != 0) return - 8044 8b/-> *(ebp+0x14) 0/r32/eax - 8045 81 7/subop/compare *eax 0/imm32 - 8046 75/jump-if-!= break/disp8 - 8047 # if name is one of fn's outputs, return it - 8048 (find-in-function-outputs *(ebp+0x10) *(ebp+8) *(ebp+0x14)) - 8049 8b/-> *(ebp+0x14) 0/r32/eax - 8050 81 7/subop/compare *eax 0/imm32 - 8051 # otherwise abort - 8052 0f 84/jump-if-= $lookup-or-define-var:abort/disp32 - 8053 } - 8054 $lookup-or-define-var:end: - 8055 # . restore registers - 8056 58/pop-to-eax - 8057 # . epilogue - 8058 89/<- %esp 5/r32/ebp - 8059 5d/pop-to-ebp - 8060 c3/return - 8061 - 8062 $lookup-or-define-var:abort: - 8063 (write-buffered *(ebp+0x18) "unknown variable '") - 8064 (write-slice-buffered *(ebp+0x18) *(ebp+8)) - 8065 (write-buffered *(ebp+0x18) "'\n") - 8066 (flush *(ebp+0x18)) - 8067 (stop *(ebp+0x1c) 1) - 8068 # never gets here - 8069 - 8070 find-in-function-outputs: # fn: (addr function), name: (addr slice), out: (addr handle var) - 8071 # . prologue - 8072 55/push-ebp - 8073 89/<- %ebp 4/r32/esp - 8074 # . save registers - 8075 50/push-eax - 8076 51/push-ecx - 8077 # var curr/ecx: (addr list var) = lookup(fn->outputs) - 8078 8b/-> *(ebp+8) 1/r32/ecx - 8079 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax - 8080 89/<- %ecx 0/r32/eax - 8081 # while curr != null - 8082 { - 8083 81 7/subop/compare %ecx 0/imm32 - 8084 74/jump-if-= break/disp8 - 8085 # var v/eax: (addr var) = lookup(curr->value) - 8086 (lookup *ecx *(ecx+4)) # List-value List-value => eax - 8087 # var s/eax: (addr array byte) = lookup(v->name) - 8088 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 8089 # if (s == name) return curr->value - 8090 (slice-equal? *(ebp+0xc) %eax) # => eax - 8091 3d/compare-eax-and 0/imm32/false - 8092 { - 8093 74/jump-if-= break/disp8 - 8094 # var edi = out - 8095 57/push-edi - 8096 8b/-> *(ebp+0x10) 7/r32/edi - 8097 # *out = curr->value - 8098 8b/-> *ecx 0/r32/eax - 8099 89/<- *edi 0/r32/eax - 8100 8b/-> *(ecx+4) 0/r32/eax - 8101 89/<- *(edi+4) 0/r32/eax - 8102 # - 8103 5f/pop-to-edi - 8104 eb/jump $find-in-function-outputs:end/disp8 - 8105 } - 8106 # curr = curr->next - 8107 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax - 8108 89/<- %ecx 0/r32/eax - 8109 # - 8110 eb/jump loop/disp8 - 8111 } - 8112 b8/copy-to-eax 0/imm32 - 8113 $find-in-function-outputs:end: - 8114 # . restore registers - 8115 59/pop-to-ecx - 8116 58/pop-to-eax - 8117 # . epilogue - 8118 89/<- %esp 5/r32/ebp - 8119 5d/pop-to-ebp - 8120 c3/return - 8121 - 8122 # push 'out' to 'vars' if not already there; it's assumed to be a fn output - 8123 maybe-define-var: # out: (handle var), vars: (addr stack live-var) - 8124 # . prologue - 8125 55/push-ebp - 8126 89/<- %ebp 4/r32/esp - 8127 # . save registers - 8128 50/push-eax - 8129 # var out-addr/eax: (addr var) - 8130 (lookup *(ebp+8) *(ebp+0xc)) # => eax - 8131 # - 8132 (binding-exists? %eax *(ebp+0x10)) # => eax - 8133 3d/compare-eax-and 0/imm32/false - 8134 75/jump-if-!= $maybe-define-var:end/disp8 - 8135 # otherwise update vars - 8136 (push *(ebp+0x10) *(ebp+8)) - 8137 (push *(ebp+0x10) *(ebp+0xc)) - 8138 (push *(ebp+0x10) 0) # 'out' is always a fn output; never spill it - 8139 $maybe-define-var:end: - 8140 # . restore registers - 8141 58/pop-to-eax - 8142 # . epilogue - 8143 89/<- %esp 5/r32/ebp - 8144 5d/pop-to-ebp - 8145 c3/return - 8146 - 8147 # simpler version of lookup-var-helper - 8148 binding-exists?: # target: (addr var), vars: (addr stack live-var) -> result/eax: boolean - 8149 # pseudocode: - 8150 # var curr: (addr handle var) = &vars->data[vars->top - 12] - 8151 # var min = vars->data - 8152 # while curr >= min - 8153 # var v: (handle var) = *curr - 8154 # if v->name == target->name - 8155 # return true - 8156 # curr -= 12 - 8157 # return false - 8158 # - 8159 # . prologue - 8160 55/push-ebp - 8161 89/<- %ebp 4/r32/esp - 8162 # . save registers - 8163 51/push-ecx - 8164 52/push-edx - 8165 56/push-esi - 8166 # var target-name/ecx: (addr array byte) = lookup(target->name) - 8167 8b/-> *(ebp+8) 0/r32/eax - 8168 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 8169 89/<- %ecx 0/r32/eax - 8170 # esi = vars - 8171 8b/-> *(ebp+0xc) 6/r32/esi - 8172 # eax = vars->top - 8173 8b/-> *esi 0/r32/eax - 8174 # var min/edx: (addr handle var) = vars->data - 8175 8d/copy-address *(esi+8) 2/r32/edx - 8176 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] - 8177 8d/copy-address *(esi+eax-4) 6/r32/esi # vars + 8 + vars->type - 12 - 8178 { - 8179 $binding-exists?:loop: - 8180 # if (curr < min) return - 8181 39/compare %esi 2/r32/edx - 8182 0f 82/jump-if-addr< break/disp32 - 8183 # var v/eax: (addr var) = lookup(*curr) - 8184 (lookup *esi *(esi+4)) # => eax - 8185 # var vn/eax: (addr array byte) = lookup(v->name) - 8186 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 8187 # if (vn == target-name) return true - 8188 (string-equal? %ecx %eax) # => eax - 8189 3d/compare-eax-and 0/imm32/false - 8190 75/jump-if-!= $binding-exists?:end/disp8 # eax already contains true - 8191 # curr -= 12 - 8192 81 5/subop/subtract %esi 0xc/imm32 - 8193 e9/jump loop/disp32 - 8194 } - 8195 b8/copy-to-eax 0/imm32/false - 8196 $binding-exists?:end: - 8197 # . restore registers - 8198 5e/pop-to-esi - 8199 5a/pop-to-edx - 8200 59/pop-to-ecx - 8201 # . epilogue - 8202 89/<- %esp 5/r32/ebp - 8203 5d/pop-to-ebp - 8204 c3/return - 8205 - 8206 test-parse-mu-stmt: - 8207 # . prologue - 8208 55/push-ebp - 8209 89/<- %ebp 4/r32/esp - 8210 # setup - 8211 (clear-stream _test-input-stream) - 8212 (write _test-input-stream "increment n\n") - 8213 # var vars/ecx: (stack (addr var) 16) - 8214 81 5/subop/subtract %esp 0xc0/imm32 - 8215 68/push 0xc0/imm32/size - 8216 68/push 0/imm32/top - 8217 89/<- %ecx 4/r32/esp - 8218 (clear-stack %ecx) - 8219 # var v/edx: (handle var) - 8220 68/push 0/imm32 - 8221 68/push 0/imm32 - 8222 89/<- %edx 4/r32/esp - 8223 # var s/eax: (handle array byte) - 8224 68/push 0/imm32 - 8225 68/push 0/imm32 - 8226 89/<- %eax 4/r32/esp - 8227 # v = new var("n") - 8228 (copy-array Heap "n" %eax) - 8229 (new-var Heap *eax *(eax+4) %edx) - 8230 # - 8231 (push %ecx *edx) - 8232 (push %ecx *(edx+4)) - 8233 (push %ecx 0) - 8234 # var out/eax: (handle stmt) - 8235 68/push 0/imm32 - 8236 68/push 0/imm32 - 8237 89/<- %eax 4/r32/esp - 8238 # convert - 8239 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) - 8240 # var out-addr/edx: (addr stmt) = lookup(*out) - 8241 (lookup *eax *(eax+4)) # => eax - 8242 89/<- %edx 0/r32/eax - 8243 # out->tag - 8244 (check-ints-equal *edx 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 - 8245 # out->operation - 8246 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax - 8247 (check-strings-equal %eax "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation - 8248 # out->inouts->value->name - 8249 # . eax = out->inouts - 8250 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 8251 # . eax = out->inouts->value - 8252 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 8253 # . eax = out->inouts->value->name - 8254 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 8255 # . - 8256 (check-strings-equal %eax "n" "F - test-parse-mu-stmt/inout:0") - 8257 # . epilogue - 8258 89/<- %esp 5/r32/ebp - 8259 5d/pop-to-ebp - 8260 c3/return - 8261 - 8262 test-parse-mu-stmt-with-comma: - 8263 # . prologue - 8264 55/push-ebp - 8265 89/<- %ebp 4/r32/esp - 8266 # setup - 8267 (clear-stream _test-input-stream) - 8268 (write _test-input-stream "copy-to n, 3\n") - 8269 # var vars/ecx: (stack (addr var) 16) - 8270 81 5/subop/subtract %esp 0xc0/imm32 - 8271 68/push 0xc0/imm32/size - 8272 68/push 0/imm32/top - 8273 89/<- %ecx 4/r32/esp - 8274 (clear-stack %ecx) - 8275 # var v/edx: (handle var) - 8276 68/push 0/imm32 - 8277 68/push 0/imm32 - 8278 89/<- %edx 4/r32/esp - 8279 # var s/eax: (handle array byte) - 8280 68/push 0/imm32 - 8281 68/push 0/imm32 - 8282 89/<- %eax 4/r32/esp - 8283 # v = new var("n") - 8284 (copy-array Heap "n" %eax) - 8285 (new-var Heap *eax *(eax+4) %edx) - 8286 # - 8287 (push %ecx *edx) - 8288 (push %ecx *(edx+4)) - 8289 (push %ecx 0) - 8290 # var out/eax: (handle stmt) - 8291 68/push 0/imm32 - 8292 68/push 0/imm32 - 8293 89/<- %eax 4/r32/esp - 8294 # convert - 8295 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) - 8296 # var out-addr/edx: (addr stmt) = lookup(*out) - 8297 (lookup *eax *(eax+4)) # => eax - 8298 89/<- %edx 0/r32/eax - 8299 # out->tag - 8300 (check-ints-equal *edx 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1 - 8301 # out->operation - 8302 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax - 8303 (check-strings-equal %eax "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation - 8304 # out->inouts->value->name - 8305 # . eax = out->inouts - 8306 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 8307 # . eax = out->inouts->value - 8308 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 8309 # . eax = out->inouts->value->name - 8310 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 8311 # . - 8312 (check-strings-equal %eax "n" "F - test-parse-mu-stmt-with-comma/inout:0") - 8313 # . epilogue - 8314 89/<- %esp 5/r32/ebp - 8315 5d/pop-to-ebp - 8316 c3/return - 8317 - 8318 new-var: # ad: (addr allocation-descriptor), name: (handle array byte), out: (addr handle var) - 8319 # . prologue - 8320 55/push-ebp - 8321 89/<- %ebp 4/r32/esp - 8322 # . save registers - 8323 50/push-eax - 8324 51/push-ecx - 8325 # ecx = out - 8326 8b/-> *(ebp+0x14) 1/r32/ecx - 8327 # - 8328 (allocate *(ebp+8) *Var-size %ecx) - 8329 # var out-addr/eax: (addr var) - 8330 (lookup *ecx *(ecx+4)) # => eax - 8331 # out-addr->name = name - 8332 8b/-> *(ebp+0xc) 1/r32/ecx - 8333 89/<- *eax 1/r32/ecx # Var-name - 8334 8b/-> *(ebp+0x10) 1/r32/ecx - 8335 89/<- *(eax+4) 1/r32/ecx # Var-name - 8336 #? (write-buffered Stderr "var ") - 8337 #? (lookup *(ebp+0xc) *(ebp+0x10)) - 8338 #? (write-buffered Stderr %eax) - 8339 #? (write-buffered Stderr " at ") - 8340 #? 8b/-> *(ebp+0x14) 1/r32/ecx - 8341 #? (lookup *ecx *(ecx+4)) # => eax - 8342 #? (print-int32-buffered Stderr %eax) - 8343 #? (write-buffered Stderr Newline) - 8344 #? (flush Stderr) - 8345 $new-var:end: - 8346 # . restore registers - 8347 59/pop-to-ecx - 8348 58/pop-to-eax - 8349 # . epilogue - 8350 89/<- %esp 5/r32/ebp - 8351 5d/pop-to-ebp - 8352 c3/return - 8353 - 8354 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) - 8355 # . prologue - 8356 55/push-ebp - 8357 89/<- %ebp 4/r32/esp - 8358 # . save registers - 8359 50/push-eax - 8360 51/push-ecx - 8361 # if (!is-hex-int?(name)) abort - 8362 (is-hex-int? *(ebp+0xc)) # => eax - 8363 3d/compare-eax-and 0/imm32/false - 8364 0f 84/jump-if-= $new-literal-integer:abort/disp32 - 8365 # out = new var(s) - 8366 (new-var-from-slice *(ebp+8) *(ebp+0xc) *(ebp+0x10)) - 8367 # var out-addr/ecx: (addr var) = lookup(*out) - 8368 8b/-> *(ebp+0x10) 0/r32/eax - 8369 (lookup *eax *(eax+4)) # => eax - 8370 89/<- %ecx 0/r32/eax - 8371 # out-addr->block-depth = *Curr-block-depth - 8372 8b/-> *Curr-block-depth 0/r32/eax - 8373 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth - 8374 # out-addr->type = new tree() - 8375 8d/copy-address *(ecx+8) 0/r32/eax # Var-type - 8376 (allocate *(ebp+8) *Tree-size %eax) - 8377 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 8378 c7 0/subop/copy *eax 1/imm32/true # Tree-is-atom - 8379 # nothing else to do; default type is 'literal' - 8380 $new-literal-integer:end: - 8381 # . reclaim locals - 8382 81 0/subop/add %esp 8/imm32 - 8383 # . restore registers - 8384 59/pop-to-ecx - 8385 58/pop-to-eax - 8386 # . epilogue - 8387 89/<- %esp 5/r32/ebp - 8388 5d/pop-to-ebp - 8389 c3/return - 8390 - 8391 $new-literal-integer:abort: - 8392 (write-buffered *(ebp+0x18) "fn ") - 8393 8b/-> *(ebp+0x14) 0/r32/eax - 8394 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 8395 (write-buffered *(ebp+0x18) %eax) - 8396 (write-buffered *(ebp+0x18) ": variable cannot begin with a digit '") - 8397 (write-slice-buffered *(ebp+0x18) *(ebp+0xc)) - 8398 (write-buffered *(ebp+0x18) "'\n") - 8399 (flush *(ebp+0x18)) - 8400 (stop *(ebp+0x1c) 1) - 8401 # never gets here - 8402 - 8403 new-literal: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) - 8404 # . prologue - 8405 55/push-ebp - 8406 89/<- %ebp 4/r32/esp - 8407 # . save registers - 8408 50/push-eax - 8409 51/push-ecx - 8410 # var s/ecx: (handle array byte) - 8411 68/push 0/imm32 - 8412 68/push 0/imm32 - 8413 89/<- %ecx 4/r32/esp - 8414 # s = slice-to-string(name) - 8415 (slice-to-string Heap *(ebp+0xc) %ecx) - 8416 # allocate to out - 8417 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) - 8418 # var out-addr/ecx: (addr var) = lookup(*out) - 8419 8b/-> *(ebp+0x10) 1/r32/ecx - 8420 (lookup *ecx *(ecx+4)) # => eax - 8421 89/<- %ecx 0/r32/eax - 8422 # out-addr->block-depth = *Curr-block-depth - 8423 8b/-> *Curr-block-depth 0/r32/eax - 8424 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth - 8425 # out-addr->type/eax = new type - 8426 8d/copy-address *(ecx+8) 0/r32/eax # Var-type - 8427 (allocate *(ebp+8) *Tree-size %eax) - 8428 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 8429 # nothing else to do; default type is 'literal' - 8430 c7 0/subop/copy *eax 1/imm32/true # Tree-is-atom - 8431 $new-literal:end: - 8432 # . reclaim locals - 8433 81 0/subop/add %esp 8/imm32 - 8434 # . restore registers - 8435 59/pop-to-ecx - 8436 58/pop-to-eax - 8437 # . epilogue - 8438 89/<- %esp 5/r32/ebp - 8439 5d/pop-to-ebp - 8440 c3/return - 8441 - 8442 new-var-from-slice: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) - 8443 # . prologue - 8444 55/push-ebp - 8445 89/<- %ebp 4/r32/esp - 8446 # . save registers - 8447 51/push-ecx - 8448 # var tmp/ecx: (handle array byte) - 8449 68/push 0/imm32 - 8450 68/push 0/imm32 - 8451 89/<- %ecx 4/r32/esp - 8452 # tmp = slice-to-string(name) - 8453 (slice-to-string Heap *(ebp+0xc) %ecx) - 8454 # out = new-var(tmp) - 8455 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) - 8456 $new-var-from-slice:end: - 8457 # . reclaim locals - 8458 81 0/subop/add %esp 8/imm32 - 8459 # . restore registers - 8460 59/pop-to-ecx - 8461 # . epilogue - 8462 89/<- %esp 5/r32/ebp - 8463 5d/pop-to-ebp - 8464 c3/return - 8465 - 8466 new-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) - 8467 # . prologue - 8468 55/push-ebp - 8469 89/<- %ebp 4/r32/esp - 8470 # . save registers - 8471 50/push-eax - 8472 51/push-ecx - 8473 # - 8474 (allocate *(ebp+8) *Stmt-size *(ebp+0x14)) - 8475 # var out-addr/eax: (addr stmt) = lookup(*out) - 8476 8b/-> *(ebp+0x14) 0/r32/eax - 8477 (lookup *eax *(eax+4)) # => eax - 8478 # out-addr->tag = stmt - 8479 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag - 8480 # result->var = var - 8481 8b/-> *(ebp+0xc) 1/r32/ecx - 8482 89/<- *(eax+4) 1/r32/ecx # Vardef-var - 8483 8b/-> *(ebp+0x10) 1/r32/ecx - 8484 89/<- *(eax+8) 1/r32/ecx # Vardef-var - 8485 $new-var-def:end: - 8486 # . restore registers - 8487 59/pop-to-ecx - 8488 58/pop-to-eax - 8489 # . epilogue - 8490 89/<- %esp 5/r32/ebp - 8491 5d/pop-to-ebp - 8492 c3/return - 8493 - 8494 new-reg-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) - 8495 # . prologue - 8496 55/push-ebp - 8497 89/<- %ebp 4/r32/esp - 8498 # . save registers - 8499 50/push-eax - 8500 # eax = out - 8501 8b/-> *(ebp+0x14) 0/r32/eax - 8502 # - 8503 (allocate *(ebp+8) *Stmt-size %eax) - 8504 # var out-addr/eax: (addr stmt) = lookup(*out) - 8505 (lookup *eax *(eax+4)) # => eax - 8506 # set tag - 8507 c7 0/subop/copy *eax 3/imm32/tag/var-in-register # Stmt-tag - 8508 # set output - 8509 8d/copy-address *(eax+0x14) 0/r32/eax # Regvardef-outputs - 8510 (append-stmt-var Heap *(ebp+0xc) *(ebp+0x10) 0 0 0 %eax) - 8511 $new-reg-var-def:end: - 8512 # . restore registers - 8513 58/pop-to-eax - 8514 # . epilogue - 8515 89/<- %esp 5/r32/ebp - 8516 5d/pop-to-ebp - 8517 c3/return - 8518 - 8519 append-list: # ad: (addr allocation-descriptor), value: (handle _type), list: (handle list _type), out: (addr handle list _type) - 8520 # . prologue - 8521 55/push-ebp - 8522 89/<- %ebp 4/r32/esp - 8523 # . save registers - 8524 50/push-eax - 8525 51/push-ecx - 8526 57/push-edi - 8527 # edi = out - 8528 8b/-> *(ebp+0x1c) 7/r32/edi - 8529 # *out = new list - 8530 (allocate *(ebp+8) *List-size %edi) - 8531 # var out-addr/edi: (addr list _type) = lookup(*out) - 8532 (lookup *edi *(edi+4)) # => eax - 8533 89/<- %edi 0/r32/eax - 8534 # out-addr->value = value - 8535 8b/-> *(ebp+0xc) 0/r32/eax - 8536 89/<- *edi 0/r32/eax # List-value - 8537 8b/-> *(ebp+0x10) 0/r32/eax - 8538 89/<- *(edi+4) 0/r32/eax # List-value - 8539 # if (list == null) return - 8540 81 7/subop/compare *(ebp+0x14) 0/imm32 - 8541 74/jump-if-= $append-list:end/disp8 - 8542 # otherwise append - 8543 $append-list:non-empty-list: - 8544 # var curr/eax: (addr list _type) = lookup(list) - 8545 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax - 8546 # while (curr->next != null) curr = curr->next - 8547 { - 8548 81 7/subop/compare *(eax+8) 0/imm32 # List-next - 8549 74/jump-if-= break/disp8 - 8550 # curr = lookup(curr->next) - 8551 (lookup *(eax+8) *(eax+0xc)) # List-next, List-next => eax - 8552 # - 8553 eb/jump loop/disp8 - 8554 } - 8555 # edi = out - 8556 8b/-> *(ebp+0x1c) 7/r32/edi - 8557 # curr->next = out - 8558 8b/-> *edi 1/r32/ecx - 8559 89/<- *(eax+8) 1/r32/ecx # List-next - 8560 8b/-> *(edi+4) 1/r32/ecx - 8561 89/<- *(eax+0xc) 1/r32/ecx # List-next - 8562 # out = list - 8563 8b/-> *(ebp+0x14) 1/r32/ecx - 8564 89/<- *edi 1/r32/ecx - 8565 8b/-> *(ebp+0x18) 1/r32/ecx - 8566 89/<- *(edi+4) 1/r32/ecx - 8567 $append-list:end: - 8568 # . restore registers - 8569 5f/pop-to-edi - 8570 59/pop-to-ecx - 8571 58/pop-to-eax - 8572 # . epilogue - 8573 89/<- %esp 5/r32/ebp - 8574 5d/pop-to-ebp - 8575 c3/return - 8576 - 8577 append-stmt-var: # ad: (addr allocation-descriptor), v: (handle var), vars: (handle stmt-var), is-deref?: boolean, out: (addr handle stmt-var) - 8578 # . prologue - 8579 55/push-ebp - 8580 89/<- %ebp 4/r32/esp - 8581 # . save registers - 8582 50/push-eax - 8583 51/push-ecx - 8584 57/push-edi - 8585 # edi = out - 8586 8b/-> *(ebp+0x20) 7/r32/edi - 8587 # out = new stmt-var - 8588 (allocate *(ebp+8) *Stmt-var-size %edi) - 8589 # var out-addr/ecx: (addr stmt-var) = lookup(*out) - 8590 (lookup *edi *(edi+4)) # => eax - 8591 89/<- %ecx 0/r32/eax - 8592 # out-addr->value = v - 8593 8b/-> *(ebp+0xc) 0/r32/eax - 8594 89/<- *ecx 0/r32/eax # Stmt-var-value - 8595 8b/-> *(ebp+0x10) 0/r32/eax - 8596 89/<- *(ecx+4) 0/r32/eax # Stmt-var-value - 8597 # out-addr->is-deref? = is-deref? - 8598 8b/-> *(ebp+0x1c) 0/r32/eax - 8599 89/<- *(ecx+0x10) 0/r32/eax # Stmt-var-is-deref - 8600 # if (vars == null) return result - 8601 81 7/subop/compare *(ebp+0x14) 0/imm32/null - 8602 74/jump-if-= $append-stmt-var:end/disp8 - 8603 # otherwise append - 8604 # var curr/eax: (addr stmt-var) = lookup(vars) - 8605 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax - 8606 # while (curr->next != null) curr = curr->next - 8607 { - 8608 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next - 8609 74/jump-if-= break/disp8 - 8610 # curr = lookup(curr->next) - 8611 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next, Stmt-var-next => eax - 8612 # - 8613 eb/jump loop/disp8 - 8614 } - 8615 # curr->next = out - 8616 8b/-> *edi 1/r32/ecx - 8617 89/<- *(eax+8) 1/r32/ecx # Stmt-var-next - 8618 8b/-> *(edi+4) 1/r32/ecx - 8619 89/<- *(eax+0xc) 1/r32/ecx # Stmt-var-next - 8620 # out = vars - 8621 8b/-> *(ebp+0x14) 1/r32/ecx - 8622 89/<- *edi 1/r32/ecx - 8623 8b/-> *(ebp+0x18) 1/r32/ecx - 8624 89/<- *(edi+4) 1/r32/ecx - 8625 $append-stmt-var:end: - 8626 # . restore registers - 8627 5f/pop-to-edi - 8628 59/pop-to-ecx - 8629 58/pop-to-eax - 8630 # . epilogue - 8631 89/<- %esp 5/r32/ebp - 8632 5d/pop-to-ebp - 8633 c3/return - 8634 - 8635 append-to-block: # ad: (addr allocation-descriptor), block: (addr block), x: (handle stmt) - 8636 # . prologue - 8637 55/push-ebp - 8638 89/<- %ebp 4/r32/esp - 8639 # . save registers - 8640 50/push-eax - 8641 56/push-esi - 8642 # esi = block - 8643 8b/-> *(ebp+0xc) 6/r32/esi - 8644 # block->stmts = append(x, block->stmts) - 8645 8d/copy-address *(esi+4) 0/r32/eax # Block-stmts - 8646 (append-list *(ebp+8) *(ebp+0x10) *(ebp+0x14) *(esi+4) *(esi+8) %eax) # ad, x, x, Block-stmts, Block-stmts - 8647 $append-to-block:end: - 8648 # . restore registers - 8649 5e/pop-to-esi - 8650 58/pop-to-eax - 8651 # . epilogue - 8652 89/<- %esp 5/r32/ebp - 8653 5d/pop-to-ebp - 8654 c3/return - 8655 - 8656 ## Parsing types - 8657 # We need to create metadata on user-defined types, and we need to use this - 8658 # metadata as we parse instructions. - 8659 # However, we also want to allow types to be used before their definitions. - 8660 # This means we can't ever assume any type data structures exist. - 8661 - 8662 lookup-or-create-constant: # container: (addr stmt-var), field-name: (addr slice), out: (addr handle var) - 8663 # . prologue - 8664 55/push-ebp - 8665 89/<- %ebp 4/r32/esp - 8666 # . save registers - 8667 50/push-eax - 8668 56/push-esi - 8669 # var container-type/esi: type-id - 8670 (container-type *(ebp+8)) # => eax - 8671 89/<- %esi 0/r32/eax - 8672 # var tmp/eax: (handle typeinfo) = find-or-create-typeinfo(container-type) - 8673 68/push 0/imm32 - 8674 68/push 0/imm32 - 8675 89/<- %eax 4/r32/esp - 8676 (find-or-create-typeinfo %esi %eax) - 8677 # var tmp-addr/eax: (addr typeinfo) = lookup(tmp) - 8678 (lookup *eax *(eax+4)) # => eax - 8679 # result = find-or-create-typeinfo-output-var(typeinfo, field-name) - 8680 #? (write-buffered Stderr "constant: ") - 8681 #? (write-slice-buffered Stderr *(ebp+0xc)) - 8682 #? (write-buffered Stderr Newline) - 8683 #? (flush Stderr) - 8684 (find-or-create-typeinfo-output-var %eax *(ebp+0xc) *(ebp+0x10)) - 8685 #? 8b/-> *(ebp+0x10) 0/r32/eax - 8686 #? (write-buffered Stderr "@") - 8687 #? (lookup *eax *(eax+4)) - 8688 #? (print-int32-buffered Stderr %eax) - 8689 #? (lookup *eax *(eax+4)) - 8690 #? (write-buffered Stderr %eax) - 8691 #? (write-buffered Stderr Newline) - 8692 #? (flush Stderr) - 8693 #? (write-buffered Stderr "offset: ") - 8694 #? 8b/-> *(eax+0x14) 0/r32/eax - 8695 #? (print-int32-buffered Stderr %eax) - 8696 #? (write-buffered Stderr Newline) - 8697 #? (flush Stderr) - 8698 $lookup-or-create-constant:end: - 8699 # . reclaim locals - 8700 81 0/subop/add %esp 8/imm32 - 8701 # . restore registers - 8702 5e/pop-to-esi - 8703 58/pop-to-eax - 8704 # . epilogue - 8705 89/<- %esp 5/r32/ebp - 8706 5d/pop-to-ebp - 8707 c3/return - 8708 - 8709 # if addr var: - 8710 # container->var->type->right->left->value - 8711 # otherwise - 8712 # container->var->type->value - 8713 container-type: # container: (addr stmt-var) -> result/eax: type-id - 8714 # . prologue - 8715 55/push-ebp - 8716 89/<- %ebp 4/r32/esp - 8717 # - 8718 8b/-> *(ebp+8) 0/r32/eax - 8719 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax - 8720 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax - 8721 { - 8722 81 7/subop/compare *(eax+8) 0/imm32 # Tree-right - 8723 74/jump-if-= break/disp8 - 8724 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax - 8725 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax - 8726 } - 8727 8b/-> *(eax+4) 0/r32/eax # Tree-value - 8728 $container-type:end: - 8729 # . epilogue - 8730 89/<- %esp 5/r32/ebp - 8731 5d/pop-to-ebp - 8732 c3/return - 8733 - 8734 find-or-create-typeinfo: # t: type-id, out: (addr handle typeinfo) - 8735 # . prologue - 8736 55/push-ebp - 8737 89/<- %ebp 4/r32/esp - 8738 # . save registers - 8739 50/push-eax - 8740 51/push-ecx - 8741 52/push-edx - 8742 57/push-edi - 8743 # edi = out - 8744 8b/-> *(ebp+0xc) 7/r32/edi - 8745 # var fields/ecx: (handle table (handle array byte) (handle typeinfo-entry)) - 8746 68/push 0/imm32 - 8747 68/push 0/imm32 - 8748 89/<- %ecx 4/r32/esp - 8749 # find-typeinfo(t, out) - 8750 (find-typeinfo *(ebp+8) %edi) - 8751 { - 8752 # if (*out != 0) break - 8753 81 7/subop/compare *edi 0/imm32 - 8754 0f 85/jump-if-!= break/disp32 - 8755 $find-or-create-typeinfo:create: - 8756 # *out = allocate - 8757 (allocate Heap *Typeinfo-size %edi) - 8758 # var tmp/eax: (addr typeinfo) = lookup(*out) - 8759 (lookup *edi *(edi+4)) # => eax - 8760 #? (write-buffered Stderr "created typeinfo at ") - 8761 #? (print-int32-buffered Stderr %eax) - 8762 #? (write-buffered Stderr " for type-id ") - 8763 #? (print-int32-buffered Stderr *(ebp+8)) - 8764 #? (write-buffered Stderr Newline) - 8765 #? (flush Stderr) - 8766 # tmp->id = t - 8767 8b/-> *(ebp+8) 2/r32/edx - 8768 89/<- *eax 2/r32/edx # Typeinfo-id - 8769 # tmp->fields = new table - 8770 # . fields = new table - 8771 (new-stream Heap 0x40 *Typeinfo-fields-row-size %ecx) - 8772 # . tmp->fields = fields - 8773 8b/-> *ecx 2/r32/edx - 8774 89/<- *(eax+4) 2/r32/edx # Typeinfo-fields - 8775 8b/-> *(ecx+4) 2/r32/edx - 8776 89/<- *(eax+8) 2/r32/edx # Typeinfo-fields - 8777 # tmp->next = Program->types - 8778 8b/-> *_Program-types 1/r32/ecx - 8779 89/<- *(eax+0x10) 1/r32/ecx # Typeinfo-next - 8780 8b/-> *_Program-types->payload 1/r32/ecx - 8781 89/<- *(eax+0x14) 1/r32/ecx # Typeinfo-next - 8782 # Program->types = out - 8783 8b/-> *edi 1/r32/ecx - 8784 89/<- *_Program-types 1/r32/ecx - 8785 8b/-> *(edi+4) 1/r32/ecx - 8786 89/<- *_Program-types->payload 1/r32/ecx - 8787 } - 8788 $find-or-create-typeinfo:end: - 8789 # . reclaim locals - 8790 81 0/subop/add %esp 8/imm32 - 8791 # . restore registers - 8792 5f/pop-to-edi - 8793 5a/pop-to-edx - 8794 59/pop-to-ecx - 8795 58/pop-to-eax - 8796 # . epilogue - 8797 89/<- %esp 5/r32/ebp - 8798 5d/pop-to-ebp - 8799 c3/return - 8800 - 8801 find-typeinfo: # t: type-id, out: (addr handle typeinfo) - 8802 # . prologue - 8803 55/push-ebp - 8804 89/<- %ebp 4/r32/esp - 8805 # . save registers - 8806 50/push-eax - 8807 51/push-ecx - 8808 52/push-edx - 8809 57/push-edi - 8810 # ecx = t - 8811 8b/-> *(ebp+8) 1/r32/ecx - 8812 # edi = out - 8813 8b/-> *(ebp+0xc) 7/r32/edi - 8814 # *out = Program->types - 8815 8b/-> *_Program-types 0/r32/eax - 8816 89/<- *edi 0/r32/eax - 8817 8b/-> *_Program-types->payload 0/r32/eax - 8818 89/<- *(edi+4) 0/r32/eax - 8819 { - 8820 # if (*out == 0) break - 8821 81 7/subop/compare *edi 0/imm32 - 8822 74/jump-if-= break/disp8 - 8823 # var tmp/eax: (addr typeinfo) = lookup(*out) - 8824 (lookup *edi *(edi+4)) # => eax - 8825 # if (tmp->id == t) break - 8826 39/compare *eax 1/r32/ecx # Typeinfo-id - 8827 74/jump-if-= break/disp8 - 8828 # *out = tmp->next - 8829 8b/-> *(eax+0x10) 2/r32/edx # Typeinfo-next - 8830 89/<- *edi 2/r32/edx - 8831 8b/-> *(eax+0x14) 2/r32/edx # Typeinfo-next - 8832 89/<- *(edi+4) 2/r32/edx - 8833 # - 8834 eb/jump loop/disp8 - 8835 } - 8836 $find-typeinfo:end: - 8837 # . restore registers - 8838 5f/pop-to-edi - 8839 5a/pop-to-edx - 8840 59/pop-to-ecx - 8841 58/pop-to-eax - 8842 # . epilogue - 8843 89/<- %esp 5/r32/ebp - 8844 5d/pop-to-ebp - 8845 c3/return - 8846 - 8847 find-or-create-typeinfo-output-var: # T: (addr typeinfo), f: (addr slice), out: (addr handle var) - 8848 # . prologue - 8849 55/push-ebp - 8850 89/<- %ebp 4/r32/esp - 8851 # . save registers - 8852 50/push-eax - 8853 52/push-edx - 8854 57/push-edi - 8855 # var dest/edi: (handle typeinfo-entry) - 8856 68/push 0/imm32 - 8857 68/push 0/imm32 - 8858 89/<- %edi 4/r32/esp - 8859 # find-or-create-typeinfo-fields(T, f, dest) - 8860 (find-or-create-typeinfo-fields *(ebp+8) *(ebp+0xc) %edi) - 8861 # var dest-addr/edi: (addr typeinfo-entry) = lookup(dest) - 8862 (lookup *edi *(edi+4)) # => eax - 8863 89/<- %edi 0/r32/eax - 8864 # if dest-addr->output-var doesn't exist, create it - 8865 { - 8866 81 7/subop/compare *(edi+0xc) 0/imm32 # Typeinfo-entry-output-var - 8867 0f 85/jump-if-!= break/disp32 - 8868 # dest-addr->output-var = new var(dummy name, type, -1 offset) - 8869 # . var name/eax: (handle array byte) = "field" - 8870 68/push 0/imm32 - 8871 68/push 0/imm32 - 8872 89/<- %eax 4/r32/esp - 8873 (copy-array Heap "field" %eax) - 8874 # . new var - 8875 8d/copy-address *(edi+0xc) 2/r32/edx - 8876 (new-var Heap *eax *(eax+4) %edx) - 8877 # . reclaim name - 8878 81 0/subop/add %esp 8/imm32 - 8879 # var result/edx: (addr var) = lookup(dest-addr->output-var) - 8880 (lookup *(edi+0xc) *(edi+0x10)) # => eax - 8881 89/<- %edx 0/r32/eax - 8882 # result->type = new constant type - 8883 8d/copy-address *(edx+8) 0/r32/eax # Var-type - 8884 (allocate Heap *Tree-size %eax) - 8885 (lookup *(edx+8) *(edx+0xc)) # => eax - 8886 c7 0/subop/copy *eax 1/imm32/true # Tree-is-atom - 8887 c7 0/subop/copy *(eax+4) 6/imm32/constant # Tree-value - 8888 c7 0/subop/copy *(eax+8) 0/imm32 # Tree-left - 8889 c7 0/subop/copy *(eax+0xc) 0/imm32 # Tree-right - 8890 c7 0/subop/copy *(eax+0x10) 0/imm32 # Tree-right - 8891 # result->offset isn't filled out yet - 8892 c7 0/subop/copy *(edx+0x14) -1/imm32/uninitialized # Var-offset - 8893 } - 8894 # out = dest-addr->output-var - 8895 8b/-> *(ebp+0x10) 2/r32/edx - 8896 8b/-> *(edi+0xc) 0/r32/eax # Typeinfo-entry-output-var - 8897 89/<- *edx 0/r32/eax - 8898 8b/-> *(edi+0x10) 0/r32/eax # Typeinfo-entry-output-var - 8899 89/<- *(edx+4) 0/r32/eax - 8900 $find-or-create-typeinfo-output-var:end: - 8901 # . reclaim locals - 8902 81 0/subop/add %esp 8/imm32 - 8903 # . restore registers - 8904 5f/pop-to-edi - 8905 5a/pop-to-edx - 8906 58/pop-to-eax - 8907 # . epilogue - 8908 89/<- %esp 5/r32/ebp - 8909 5d/pop-to-ebp - 8910 c3/return - 8911 - 8912 find-or-create-typeinfo-fields: # T: (addr typeinfo), f: (addr slice), out: (addr handle typeinfo-entry) - 8913 # . prologue - 8914 55/push-ebp - 8915 89/<- %ebp 4/r32/esp - 8916 # . save registers - 8917 50/push-eax - 8918 56/push-esi - 8919 57/push-edi - 8920 # eax = lookup(T->fields) - 8921 8b/-> *(ebp+8) 0/r32/eax - 8922 (lookup *(eax+4) *(eax+8)) # Typeinfo-fields Typeinfo-fields => eax - 8923 # edi = out - 8924 8b/-> *(ebp+0x10) 7/r32/edi - 8925 # var src/esi: (addr handle typeinfo-entry) = get-or-insert-slice(T->fields, f) - 8926 (get-or-insert-slice %eax *(ebp+0xc) *Typeinfo-fields-row-size Heap) # => eax - 8927 89/<- %esi 0/r32/eax - 8928 # if src doesn't exist, allocate it - 8929 { - 8930 81 7/subop/compare *esi 0/imm32 - 8931 75/jump-if-!= break/disp8 - 8932 (allocate Heap *Typeinfo-entry-size %esi) - 8933 #? (write-buffered Stderr "handle at ") - 8934 #? (print-int32-buffered Stderr %esi) - 8935 #? (write-buffered Stderr ": ") - 8936 #? (print-int32-buffered Stderr *esi) - 8937 #? (write-buffered Stderr " ") - 8938 #? (print-int32-buffered Stderr *(esi+4)) - 8939 #? (write-buffered Stderr Newline) - 8940 #? (flush Stderr) - 8941 #? (lookup *esi *(esi+4)) - 8942 #? (write-buffered Stderr "created typeinfo fields at ") - 8943 #? (print-int32-buffered Stderr %esi) - 8944 #? (write-buffered Stderr " for ") - 8945 #? (print-int32-buffered Stderr *(ebp+8)) - 8946 #? (write-buffered Stderr Newline) - 8947 #? (flush Stderr) - 8948 } - 8949 # *out = src - 8950 # . *edi = *src - 8951 8b/-> *esi 0/r32/eax - 8952 89/<- *edi 0/r32/eax - 8953 8b/-> *(esi+4) 0/r32/eax - 8954 89/<- *(edi+4) 0/r32/eax - 8955 $find-or-create-typeinfo-fields:end: - 8956 # . restore registers - 8957 5f/pop-to-edi - 8958 5e/pop-to-esi - 8959 58/pop-to-eax - 8960 # . epilogue - 8961 89/<- %esp 5/r32/ebp - 8962 5d/pop-to-ebp - 8963 c3/return - 8964 - 8965 populate-mu-type: # in: (addr stream byte), t: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) - 8966 # pseudocode: - 8967 # var line: (stream byte 512) - 8968 # curr-index = 0 - 8969 # while true - 8970 # clear-stream(line) - 8971 # read-line-buffered(in, line) - 8972 # if line->write == 0 - 8973 # abort - 8974 # word-slice = next-mu-token(line) - 8975 # if slice-empty?(word-slice) # end of line - 8976 # continue - 8977 # if slice-equal?(word-slice, "}") - 8978 # break - 8979 # var v: (handle var) = parse-var-with-type(word-slice, line) - 8980 # var r: (handle typeinfo-fields) = find-or-create-typeinfo-fields(t, word-slice/v->name) - 8981 # TODO: ensure that r->first is null - 8982 # r->index = curr-index - 8983 # curr-index++ - 8984 # r->input-var = v - 8985 # if r->output-var == 0 - 8986 # r->output-var = new literal - 8987 # TODO: ensure nothing else in line - 8988 # t->total-size-in-bytes = -2 (not yet initialized) - 8989 # check-input-vars(t, err, ed) - 8990 # - 8991 # . prologue - 8992 55/push-ebp - 8993 89/<- %ebp 4/r32/esp - 8994 # var curr-index: int at *(ebp-4) - 8995 68/push 0/imm32 - 8996 # . save registers - 8997 50/push-eax - 8998 51/push-ecx - 8999 52/push-edx - 9000 53/push-ebx - 9001 56/push-esi - 9002 57/push-edi - 9003 # edi = t - 9004 8b/-> *(ebp+0xc) 7/r32/edi - 9005 # var line/ecx: (stream byte 512) - 9006 81 5/subop/subtract %esp 0x200/imm32 - 9007 68/push 0x200/imm32/size - 9008 68/push 0/imm32/read - 9009 68/push 0/imm32/write - 9010 89/<- %ecx 4/r32/esp - 9011 # var word-slice/edx: slice - 9012 68/push 0/imm32/end - 9013 68/push 0/imm32/start - 9014 89/<- %edx 4/r32/esp - 9015 # var v/esi: (handle var) - 9016 68/push 0/imm32 - 9017 68/push 0/imm32 - 9018 89/<- %esi 4/r32/esp - 9019 # var r/ebx: (handle typeinfo-entry) - 9020 68/push 0/imm32 - 9021 68/push 0/imm32 - 9022 89/<- %ebx 4/r32/esp - 9023 { - 9024 $populate-mu-type:line-loop: - 9025 (clear-stream %ecx) - 9026 (read-line-buffered *(ebp+8) %ecx) - 9027 # if (line->write == 0) abort - 9028 81 7/subop/compare *ecx 0/imm32 - 9029 0f 84/jump-if-= $populate-mu-type:abort/disp32 - 9030 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ - 9036 (next-mu-token %ecx %edx) - 9037 # if slice-empty?(word-slice) continue - 9038 (slice-empty? %edx) # => eax - 9039 3d/compare-eax-and 0/imm32 - 9040 0f 85/jump-if-!= loop/disp32 - 9041 # if slice-equal?(word-slice, "}") break - 9042 (slice-equal? %edx "}") - 9043 3d/compare-eax-and 0/imm32 - 9044 0f 85/jump-if-!= break/disp32 - 9045 $populate-mu-type:parse-element: - 9046 # v = parse-var-with-type(word-slice, first-line) - 9047 # must do this first to strip the trailing ':' from word-slice before - 9048 # using it in find-or-create-typeinfo-fields below - 9049 # TODO: clean up that mutation in parse-var-with-type - 9050 (parse-var-with-type %edx %ecx %esi *(ebp+0x10) *(ebp+0x14)) # => eax - 9051 # var tmp/ecx - 9052 51/push-ecx - 9053 $populate-mu-type:create-typeinfo-fields: - 9054 # var r/ebx: (handle typeinfo-entry) - 9055 (find-or-create-typeinfo-fields %edi %edx %ebx) - 9056 # r->index = curr-index - 9057 (lookup *ebx *(ebx+4)) # => eax - 9058 8b/-> *(ebp-4) 1/r32/ecx - 9059 #? (write-buffered Stderr "saving index ") - 9060 #? (print-int32-buffered Stderr %ecx) - 9061 #? (write-buffered Stderr " at ") - 9062 #? (print-int32-buffered Stderr %edi) - 9063 #? (write-buffered Stderr Newline) - 9064 #? (flush Stderr) - 9065 89/<- *(eax+8) 1/r32/ecx # Typeinfo-entry-index - 9066 # ++curr-index - 9067 ff 0/subop/increment *(ebp-4) - 9068 $populate-mu-type:set-input-type: - 9069 # r->input-var = v - 9070 8b/-> *esi 1/r32/ecx - 9071 89/<- *eax 1/r32/ecx # Typeinfo-entry-input-var - 9072 8b/-> *(esi+4) 1/r32/ecx - 9073 89/<- *(eax+4) 1/r32/ecx # Typeinfo-entry-input-var - 9074 59/pop-to-ecx - 9075 { - 9076 $populate-mu-type:create-output-type: - 9077 # if (r->output-var == 0) create a new var with some placeholder data - 9078 81 7/subop/compare *(eax+0xc) 0/imm32 # Typeinfo-entry-output-var - 9079 75/jump-if-!= break/disp8 - 9080 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var - 9081 (new-literal Heap %edx %eax) - 9082 } - 9083 e9/jump loop/disp32 - 9084 } - 9085 $populate-mu-type:invalidate-total-size-in-bytes: - 9086 # Offsets and total size may not be accurate here since we may not yet - 9087 # have encountered the element types. - 9088 # We'll recompute them separately after parsing the entire program. - 9089 c7 0/subop/copy *(edi+0xc) -2/imm32/uninitialized # Typeinfo-total-size-in-bytes - 9090 $populate-mu-type:validate: - 9091 (check-input-vars *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) - 9092 $populate-mu-type:end: - 9093 # . reclaim locals - 9094 81 0/subop/add %esp 0x224/imm32 - 9095 # . restore registers - 9096 5f/pop-to-edi - 9097 5e/pop-to-esi - 9098 5b/pop-to-ebx - 9099 5a/pop-to-edx - 9100 59/pop-to-ecx - 9101 58/pop-to-eax - 9102 # reclaim curr-index - 9103 81 0/subop/add %esp 4/imm32 - 9104 # . epilogue - 9105 89/<- %esp 5/r32/ebp - 9106 5d/pop-to-ebp - 9107 c3/return - 9108 - 9109 $populate-mu-type:abort: - 9110 # error("unexpected top-level command: " word-slice "\n") - 9111 (write-buffered *(ebp+0x10) "incomplete type definition '") - 9112 (type-name *edi) # Typeinfo-id => eax - 9113 (write-buffered *(ebp+0x10) %eax) - 9114 (write-buffered *(ebp+0x10) "\n") - 9115 (flush *(ebp+0x10)) - 9116 (stop *(ebp+0x14) 1) - 9117 # never gets here - 9118 - 9119 check-input-vars: # t: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) - 9120 # . prologue - 9121 55/push-ebp - 9122 89/<- %ebp 4/r32/esp - 9123 # . save registers - 9124 50/push-eax - 9125 51/push-ecx - 9126 52/push-edx - 9127 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(t->fields) - 9128 8b/-> *(ebp+8) 0/r32/eax - 9129 (lookup *(eax+4) *(eax+8)) # Typeinfo-fields Typeinfo-fields => eax - 9130 89/<- %ecx 0/r32/eax - 9131 # var table-size/edx: int = table->write - 9132 8b/-> *ecx 2/r32/edx # stream-write - 9133 # var curr/ecx: (addr table_row) = table->data - 9134 8d/copy-address *(ecx+0xc) 1/r32/ecx - 9135 # var max/edx: (addr table_row) = table->data + table->write - 9136 8d/copy-address *(ecx+edx) 2/r32/edx - 9137 { - 9138 $check-input-vars:loop: - 9139 # if (curr >= max) break - 9140 39/compare %ecx 2/r32/edx - 9141 73/jump-if-addr>= break/disp8 - 9142 (lookup *ecx *(ecx+4)) # => eax - 9143 # var t2/eax: (addr typeinfo-entry) = lookup(curr->value) - 9144 (lookup *(ecx+8) *(ecx+0xc)) # => eax - 9145 # if (t2->input-var == null) raise an error - 9146 8b/-> *eax 0/r32/eax # Typeinfo-entry-input-var - 9147 3d/compare-eax-and 0/imm32/null - 9148 0f 84/jump-if-= $check-input-vars:abort/disp32 - 9149 # curr += row-size - 9150 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size - 9151 # - 9152 eb/jump loop/disp8 - 9153 } - 9154 $check-input-vars:end: - 9155 # . restore registers - 9156 5a/pop-to-edx - 9157 59/pop-to-ecx - 9158 58/pop-to-eax - 9159 # . epilogue - 9160 89/<- %esp 5/r32/ebp - 9161 5d/pop-to-ebp - 9162 c3/return - 9163 - 9164 $check-input-vars:abort: - 9165 # error("type " type " has no member called '" curr->name "'\n") - 9166 (write-buffered *(ebp+0xc) "type '") - 9167 # . var tmp/edx: int = t->id << 2 - 9168 8b/-> *(ebp+8) 0/r32/eax - 9169 8b/-> *eax 2/r32/edx # Typeinfo-id - 9170 c1/shift 4/subop/left %edx 2/imm8 - 9171 # . var a/edx: (addr array byte) = Type-id->data[tmp] - 9172 b8/copy-to-eax Type-id/imm32 - 9173 8b/-> *(eax+edx+0xc) 2/r32/edx - 9174 (write-buffered *(ebp+0xc) %edx) - 9175 (write-buffered *(ebp+0xc) "' has no member called '") - 9176 (lookup *ecx *(ecx+4)) # => eax - 9177 (write-buffered *(ebp+0xc) %eax) - 9178 (write-buffered *(ebp+0xc) "'\n") - 9179 (flush *(ebp+0xc)) - 9180 (stop *(ebp+0x10) 1) - 9181 # never gets here - 9182 - 9183 type-name: # index: int -> result/eax: (addr array byte) - 9184 # . prologue - 9185 55/push-ebp - 9186 89/<- %ebp 4/r32/esp - 9187 # - 9188 (index Type-id *(ebp+8)) - 9189 $type-name:end: - 9190 # . epilogue - 9191 89/<- %esp 5/r32/ebp - 9192 5d/pop-to-ebp - 9193 c3/return - 9194 - 9195 index: # arr: (addr stream (handle array byte)), index: int -> result/eax: (addr array byte) - 9196 # . prologue - 9197 55/push-ebp - 9198 89/<- %ebp 4/r32/esp - 9199 # . save registers - 9200 56/push-esi - 9201 # TODO: bounds-check index - 9202 # esi = arr - 9203 8b/-> *(ebp+8) 6/r32/esi - 9204 # eax = index - 9205 8b/-> *(ebp+0xc) 0/r32/eax - 9206 # eax = *(arr + 12 + index) - 9207 8b/-> *(esi+eax+0xc) 0/r32/eax - 9208 $index:end: - 9209 # . restore registers - 9210 5e/pop-to-esi - 9211 # . epilogue - 9212 89/<- %esp 5/r32/ebp - 9213 5d/pop-to-ebp - 9214 c3/return - 9215 - 9216 ####################################################### - 9217 # Compute type sizes - 9218 ####################################################### - 9219 - 9220 # Compute the sizes of all user-defined types. - 9221 # We'll need the sizes of their elements, which may be other user-defined - 9222 # types, which we will compute as needed. - 9223 - 9224 # Initially, all user-defined types have their sizes set to -2 (invalid) - 9225 populate-mu-type-sizes: # err: (addr buffered-file), ed: (addr exit-descriptor) - 9226 # . prologue - 9227 55/push-ebp - 9228 89/<- %ebp 4/r32/esp - 9229 $populate-mu-type-sizes:total-sizes: - 9230 # var curr/eax: (addr typeinfo) = lookup(Program->types) - 9231 (lookup *_Program-types *_Program-types->payload) # => eax - 9232 { - 9233 # if (curr == null) break - 9234 3d/compare-eax-and 0/imm32/null - 9235 74/jump-if-= break/disp8 - 9236 (populate-mu-type-sizes-in-type %eax *(ebp+8) *(ebp+0xc)) - 9237 # curr = lookup(curr->next) - 9238 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax - 9239 eb/jump loop/disp8 - 9240 } - 9241 $populate-mu-type-sizes:offsets: - 9242 # curr = *Program->types - 9243 (lookup *_Program-types *_Program-types->payload) # => eax - 9244 { - 9245 # if (curr == null) break - 9246 3d/compare-eax-and 0/imm32/null - 9247 74/jump-if-= break/disp8 - 9248 (populate-mu-type-offsets %eax *(ebp+8) *(ebp+0xc)) - 9249 # curr = curr->next - 9250 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax - 9251 eb/jump loop/disp8 - 9252 } - 9253 $populate-mu-type-sizes:end: - 9254 # . epilogue - 9255 89/<- %esp 5/r32/ebp - 9256 5d/pop-to-ebp - 9257 c3/return - 9258 - 9259 # compute sizes of all fields, recursing as necessary - 9260 # sum up all their sizes to arrive at total size - 9261 # fields may be out of order, but that doesn't affect the answer - 9262 populate-mu-type-sizes-in-type: # T: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) - 9263 # . prologue - 9264 55/push-ebp - 9265 89/<- %ebp 4/r32/esp - 9266 # . save registers - 9267 50/push-eax - 9268 51/push-ecx - 9269 52/push-edx - 9270 56/push-esi - 9271 57/push-edi - 9272 # esi = T - 9273 8b/-> *(ebp+8) 6/r32/esi - 9274 # if T is already computed, return - 9275 81 7/subop/compare *(esi+0xc) 0/imm32 # Typeinfo-total-size-in-bytes - 9276 0f 8d/jump-if->= $populate-mu-type-sizes-in-type:end/disp32 - 9277 # if T is being computed, abort - 9278 81 7/subop/compare *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes - 9279 0f 84/jump-if-= $populate-mu-type-sizes-in-type:abort/disp32 - 9280 # tag T (-2 to -1) to avoid infinite recursion - 9281 c7 0/subop/copy *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes - 9282 # var total-size/edi: int = 0 - 9283 bf/copy-to-edi 0/imm32 - 9284 # - for every field, if it's a user-defined type, compute its size - 9285 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) - 9286 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax - 9287 89/<- %ecx 0/r32/eax - 9288 # var table-size/edx: int = table->write - 9289 8b/-> *ecx 2/r32/edx # stream-write - 9290 # var curr/ecx: (addr table_row) = table->data - 9291 8d/copy-address *(ecx+0xc) 1/r32/ecx - 9292 # var max/edx: (addr table_row) = table->data + table->write - 9293 8d/copy-address *(ecx+edx) 2/r32/edx - 9294 { - 9295 $populate-mu-type-sizes-in-type:loop: - 9296 # if (curr >= max) break - 9297 39/compare %ecx 2/r32/edx - 9298 73/jump-if-addr>= break/disp8 - 9299 # var t/eax: (addr typeinfo-entry) = lookup(curr->value) - 9300 (lookup *(ecx+8) *(ecx+0xc)) # => eax - 9301 # compute size of t->input-var - 9302 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax - 9303 (compute-size-of-var %eax) # => eax - 9304 # result += eax - 9305 01/add-to %edi 0/r32/eax - 9306 # curr += row-size - 9307 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size - 9308 # - 9309 eb/jump loop/disp8 - 9310 } - 9311 # - save result - 9312 89/<- *(esi+0xc) 7/r32/edi # Typeinfo-total-size-in-bytes - 9313 $populate-mu-type-sizes-in-type:end: - 9314 # . restore registers - 9315 5f/pop-to-edi - 9316 5e/pop-to-esi - 9317 5a/pop-to-edx - 9318 59/pop-to-ecx - 9319 58/pop-to-eax - 9320 # . epilogue - 9321 89/<- %esp 5/r32/ebp - 9322 5d/pop-to-ebp - 9323 c3/return - 9324 - 9325 $populate-mu-type-sizes-in-type:abort: - 9326 (write-buffered *(ebp+0xc) "cycle in type definitions\n") - 9327 (flush *(ebp+0xc)) - 9328 (stop *(ebp+0x10) 1) - 9329 # never gets here - 9330 - 9331 # Analogous to size-of, except we need to compute what size-of can just read - 9332 # off the right data structures. - 9333 compute-size-of-var: # in: (addr var) -> result/eax: int - 9334 # . prologue - 9335 55/push-ebp - 9336 89/<- %ebp 4/r32/esp - 9337 # . push registers - 9338 51/push-ecx - 9339 # var t/ecx: (addr tree type-id) = lookup(v->type) - 9340 8b/-> *(ebp+8) 1/r32/ecx - 9341 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax - 9342 89/<- %ecx 0/r32/eax - 9343 # if (t->is-atom == false) t = lookup(t->left) - 9344 { - 9345 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom - 9346 75/jump-if-!= break/disp8 - 9347 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax - 9348 89/<- %ecx 0/r32/eax - 9349 } - 9350 # TODO: ensure t is an atom - 9351 (compute-size-of-type-id *(ecx+4)) # Tree-value => eax - 9352 $compute-size-of-var:end: - 9353 # . restore registers - 9354 59/pop-to-ecx - 9355 # . epilogue - 9356 89/<- %esp 5/r32/ebp - 9357 5d/pop-to-ebp - 9358 c3/return - 9359 - 9360 compute-size-of-type-id: # t: type-id -> result/eax: int - 9361 # . prologue - 9362 55/push-ebp - 9363 89/<- %ebp 4/r32/esp - 9364 # . save registers - 9365 51/push-ecx - 9366 # var out/ecx: (handle typeinfo) - 9367 68/push 0/imm32 - 9368 68/push 0/imm32 - 9369 89/<- %ecx 4/r32/esp - 9370 # eax = t - 9371 8b/-> *(ebp+8) 0/r32/eax - 9372 # if t is a literal, return 0 - 9373 3d/compare-eax-and 0/imm32/literal - 9374 0f 84/jump-if-= $compute-size-of-type-id:end/disp32 # eax changes type from type-id to int - 9375 # if t is a byte, return 4 (because we don't really support non-multiples of 4) - 9376 3d/compare-eax-and 8/imm32/byte - 9377 { - 9378 75/jump-if-!= break/disp8 - 9379 b8/copy-to-eax 4/imm32 - 9380 eb/jump $compute-size-of-type-id:end/disp8 - 9381 } - 9382 # if t is a handle, return 8 - 9383 3d/compare-eax-and 4/imm32/handle - 9384 { - 9385 75/jump-if-!= break/disp8 - 9386 b8/copy-to-eax 8/imm32 - 9387 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int - 9388 } - 9389 # if t is a user-defined type, compute its size - 9390 # TODO: support non-atom type - 9391 (find-typeinfo %eax %ecx) - 9392 { - 9393 81 7/subop/compare *ecx 0/imm32 - 9394 74/jump-if-= break/disp8 - 9395 $compute-size-of-type-id:user-defined: - 9396 (populate-mu-type-sizes %eax) - 9397 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes - 9398 eb/jump $compute-size-of-type-id:end/disp8 - 9399 } - 9400 # otherwise return the word size - 9401 b8/copy-to-eax 4/imm32 - 9402 $compute-size-of-type-id:end: - 9403 # . reclaim locals - 9404 81 0/subop/add %esp 8/imm32 - 9405 # . restore registers - 9406 59/pop-to-ecx - 9407 # . epilogue - 9408 89/<- %esp 5/r32/ebp - 9409 5d/pop-to-ebp - 9410 c3/return - 9411 - 9412 # at this point we have total sizes for all user-defined types - 9413 # compute offsets for each element - 9414 # complication: fields may be out of order - 9415 populate-mu-type-offsets: # in: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) - 9416 # . prologue - 9417 55/push-ebp - 9418 89/<- %ebp 4/r32/esp - 9419 # . save registers - 9420 50/push-eax - 9421 51/push-ecx - 9422 52/push-edx - 9423 53/push-ebx - 9424 56/push-esi - 9425 57/push-edi - 9426 #? (dump-typeinfos "aaa\n") - 9427 # var curr-offset/edi: int = 0 - 9428 bf/copy-to-edi 0/imm32 - 9429 # var table/ecx: (addr table string_key (handle typeinfo-entry)) = lookup(in->fields) - 9430 8b/-> *(ebp+8) 1/r32/ecx - 9431 (lookup *(ecx+4) *(ecx+8)) # Typeinfo-fields Typeinfo-fields => eax - 9432 89/<- %ecx 0/r32/eax - 9433 # var num-elems/edx: int = table->write / Typeinfo-fields-row-size - 9434 8b/-> *ecx 2/r32/edx # stream-write - 9435 c1 5/subop/shift-right-logical %edx 4/imm8 - 9436 # var i/ebx: int = 0 - 9437 bb/copy-to-ebx 0/imm32 - 9438 { - 9439 $populate-mu-type-offsets:loop: - 9440 39/compare %ebx 2/r32/edx - 9441 7d/jump-if->= break/disp8 - 9442 #? (write-buffered Stderr "looking up index ") - 9443 #? (print-int32-buffered Stderr %ebx) - 9444 #? (write-buffered Stderr " in ") - 9445 #? (print-int32-buffered Stderr *(ebp+8)) - 9446 #? (write-buffered Stderr Newline) - 9447 #? (flush Stderr) - 9448 # var v/esi: (addr typeinfo-entry) - 9449 (locate-typeinfo-entry-with-index %ecx %ebx *(ebp+0xc) *(ebp+0x10)) # => eax - 9450 89/<- %esi 0/r32/eax - 9451 # v->output-var->offset = curr-offset - 9452 # . eax: (addr var) - 9453 (lookup *(esi+0xc) *(esi+0x10)) # Typeinfo-entry-output-var Typeinfo-entry-output-var => eax - 9454 89/<- *(eax+0x14) 7/r32/edi # Var-offset - 9455 # curr-offset += size-of(v->input-var) - 9456 (lookup *esi *(esi+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax - 9457 (size-of %eax) # => eax - 9458 01/add-to %edi 0/r32/eax - 9459 # ++i - 9460 43/increment-ebx - 9461 eb/jump loop/disp8 - 9462 } - 9463 $populate-mu-type-offsets:end: - 9464 # . restore registers - 9465 5f/pop-to-edi - 9466 5e/pop-to-esi - 9467 5b/pop-to-ebx - 9468 5a/pop-to-edx - 9469 59/pop-to-ecx - 9470 58/pop-to-eax - 9471 # . epilogue - 9472 89/<- %esp 5/r32/ebp - 9473 5d/pop-to-ebp - 9474 c3/return - 9475 - 9476 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) - 9477 # . prologue - 9478 55/push-ebp - 9479 89/<- %ebp 4/r32/esp - 9480 # . save registers - 9481 51/push-ecx - 9482 52/push-edx - 9483 53/push-ebx - 9484 56/push-esi - 9485 57/push-edi - 9486 # esi = table - 9487 8b/-> *(ebp+8) 6/r32/esi - 9488 # var curr/ecx: (addr row (handle array byte) (handle typeinfo-entry)) = table->data - 9489 8d/copy-address *(esi+0xc) 1/r32/ecx - 9490 # var max/edx: (addr byte) = &table->data[table->write] - 9491 8b/-> *esi 2/r32/edx - 9492 8d/copy-address *(ecx+edx) 2/r32/edx - 9493 { - 9494 $locate-typeinfo-entry-with-index:loop: - 9495 39/compare %ecx 2/r32/edx - 9496 73/jump-if-addr>= $locate-typeinfo-entry-with-index:abort/disp8 - 9497 # var v/eax: (addr typeinfo-entry) - 9498 (lookup *(ecx+8) *(ecx+0xc)) # => eax - 9499 # if (v->index == idx) return v - 9500 8b/-> *(eax+8) 3/r32/ebx # Typeinfo-entry-index - 9501 #? (write-buffered Stderr "comparing ") - 9502 #? (print-int32-buffered Stderr %ebx) - 9503 #? (write-buffered Stderr " and ") - 9504 #? (print-int32-buffered Stderr *(ebp+0xc)) - 9505 #? (write-buffered Stderr Newline) - 9506 #? (flush Stderr) - 9507 39/compare *(ebp+0xc) 3/r32/ebx - 9508 74/jump-if-= $locate-typeinfo-entry-with-index:end/disp8 - 9509 # curr += Typeinfo-entry-size - 9510 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-entry-size - 9511 # - 9512 eb/jump loop/disp8 - 9513 } - 9514 # return 0 - 9515 b8/copy-to-eax 0/imm32 - 9516 $locate-typeinfo-entry-with-index:end: - 9517 #? (write-buffered Stderr "returning ") - 9518 #? (print-int32-buffered Stderr %eax) - 9519 #? (write-buffered Stderr Newline) - 9520 #? (flush Stderr) - 9521 # . restore registers - 9522 5f/pop-to-edi - 9523 5e/pop-to-esi - 9524 5b/pop-to-ebx - 9525 5a/pop-to-edx - 9526 59/pop-to-ecx - 9527 # . epilogue - 9528 89/<- %esp 5/r32/ebp - 9529 5d/pop-to-ebp - 9530 c3/return - 9531 - 9532 $locate-typeinfo-entry-with-index:abort: - 9533 (write-buffered *(ebp+0x10) "overflowing typeinfo-entry->index ") - 9534 (print-int32-buffered *(ebp+0x10) %ecx) - 9535 (write-buffered *(ebp+0x10) "\n") - 9536 (flush *(ebp+0x10)) - 9537 (stop *(ebp+0x14) 1) - 9538 # never gets here - 9539 - 9540 dump-typeinfos: # hdr: (addr array byte) - 9541 # . prologue - 9542 55/push-ebp - 9543 89/<- %ebp 4/r32/esp - 9544 # . save registers - 9545 50/push-eax - 9546 # - 9547 (write-buffered Stderr *(ebp+8)) - 9548 (flush Stderr) - 9549 # var curr/eax: (addr typeinfo) = lookup(Program->types) - 9550 (lookup *_Program-types *_Program-types->payload) # => eax - 9551 { - 9552 # if (curr == null) break - 9553 3d/compare-eax-and 0/imm32 - 9554 74/jump-if-= break/disp8 - 9555 (write-buffered Stderr "---\n") - 9556 (flush Stderr) - 9557 (dump-typeinfo %eax) - 9558 # curr = lookup(curr->next) - 9559 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax - 9560 eb/jump loop/disp8 - 9561 } - 9562 $dump-typeinfos:end: - 9563 # . restore registers - 9564 58/pop-to-eax - 9565 # . epilogue - 9566 89/<- %esp 5/r32/ebp - 9567 5d/pop-to-ebp - 9568 c3/return - 9569 - 9570 dump-typeinfo: # in: (addr typeinfo) - 9571 # . prologue - 9572 55/push-ebp - 9573 89/<- %ebp 4/r32/esp - 9574 # . save registers - 9575 50/push-eax - 9576 51/push-ecx - 9577 52/push-edx - 9578 53/push-ebx - 9579 56/push-esi - 9580 57/push-edi - 9581 # esi = in - 9582 8b/-> *(ebp+8) 6/r32/esi - 9583 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) - 9584 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax - 9585 89/<- %ecx 0/r32/eax - 9586 (write-buffered Stderr "id:") - 9587 (print-int32-buffered Stderr *esi) - 9588 (write-buffered Stderr "\n") - 9589 (write-buffered Stderr "fields @ ") - 9590 (print-int32-buffered Stderr %ecx) - 9591 (write-buffered Stderr Newline) - 9592 (flush Stderr) - 9593 (write-buffered Stderr " write: ") - 9594 (print-int32-buffered Stderr *ecx) - 9595 (write-buffered Stderr Newline) - 9596 (flush Stderr) - 9597 (write-buffered Stderr " read: ") - 9598 (print-int32-buffered Stderr *(ecx+4)) - 9599 (write-buffered Stderr Newline) - 9600 (flush Stderr) - 9601 (write-buffered Stderr " size: ") - 9602 (print-int32-buffered Stderr *(ecx+8)) - 9603 (write-buffered Stderr Newline) - 9604 (flush Stderr) - 9605 # var table-size/edx: int = table->write - 9606 8b/-> *ecx 2/r32/edx # stream-write - 9607 # var curr/ecx: (addr table_row) = table->data - 9608 8d/copy-address *(ecx+0xc) 1/r32/ecx - 9609 # var max/edx: (addr table_row) = table->data + table->write - 9610 8d/copy-address *(ecx+edx) 2/r32/edx - 9611 { - 9612 $dump-typeinfo:loop: - 9613 # if (curr >= max) break - 9614 39/compare %ecx 2/r32/edx - 9615 0f 83/jump-if-addr>= break/disp32 - 9616 (write-buffered Stderr " row:\n") - 9617 (write-buffered Stderr " key: ") - 9618 (print-int32-buffered Stderr *ecx) - 9619 (write-buffered Stderr ",") - 9620 (print-int32-buffered Stderr *(ecx+4)) - 9621 (write-buffered Stderr " = '") - 9622 (lookup *ecx *(ecx+4)) - 9623 (write-buffered Stderr %eax) - 9624 (write-buffered Stderr "' @ ") - 9625 (print-int32-buffered Stderr %eax) - 9626 (write-buffered Stderr Newline) - 9627 (flush Stderr) - 9628 (write-buffered Stderr " value: ") - 9629 (print-int32-buffered Stderr *(ecx+8)) - 9630 (write-buffered Stderr ",") - 9631 (print-int32-buffered Stderr *(ecx+0xc)) - 9632 (write-buffered Stderr " = typeinfo-entry@") - 9633 (lookup *(ecx+8) *(ecx+0xc)) - 9634 (print-int32-buffered Stderr %eax) - 9635 (write-buffered Stderr Newline) - 9636 (flush Stderr) - 9637 (write-buffered Stderr " input var@") - 9638 (dump-var 5 %eax) - 9639 (lookup *(ecx+8) *(ecx+0xc)) - 9640 (write-buffered Stderr " index: ") - 9641 (print-int32-buffered Stderr *(eax+8)) - 9642 (write-buffered Stderr Newline) - 9643 (flush Stderr) - 9644 (write-buffered Stderr " output var@") - 9645 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var - 9646 (dump-var 5 %eax) - 9647 (flush Stderr) - 9648 # curr += row-size - 9649 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size - 9650 # - 9651 e9/jump loop/disp32 - 9652 } - 9653 $dump-typeinfo:end: - 9654 # . restore registers - 9655 5f/pop-to-edi - 9656 5e/pop-to-esi - 9657 5b/pop-to-ebx - 9658 5a/pop-to-edx - 9659 59/pop-to-ecx - 9660 58/pop-to-eax - 9661 # . epilogue - 9662 89/<- %esp 5/r32/ebp - 9663 5d/pop-to-ebp - 9664 c3/return - 9665 - 9666 dump-var: # indent: int, v: (addr handle var) - 9667 # . prologue - 9668 55/push-ebp - 9669 89/<- %ebp 4/r32/esp - 9670 # . save registers - 9671 50/push-eax - 9672 53/push-ebx - 9673 # eax = v - 9674 8b/-> *(ebp+0xc) 0/r32/eax - 9675 # - 9676 (print-int32-buffered Stderr *eax) - 9677 (write-buffered Stderr ",") - 9678 (print-int32-buffered Stderr *(eax+4)) - 9679 (write-buffered Stderr "->") - 9680 (lookup *eax *(eax+4)) - 9681 (print-int32-buffered Stderr %eax) - 9682 (write-buffered Stderr Newline) - 9683 (flush Stderr) - 9684 { - 9685 3d/compare-eax-and 0/imm32 - 9686 0f 84/jump-if-= break/disp32 - 9687 (emit-indent Stderr *(ebp+8)) - 9688 (write-buffered Stderr "name: ") - 9689 89/<- %ebx 0/r32/eax - 9690 (print-int32-buffered Stderr *ebx) # Var-name - 9691 (write-buffered Stderr ",") - 9692 (print-int32-buffered Stderr *(ebx+4)) # Var-name - 9693 (write-buffered Stderr "->") - 9694 (lookup *ebx *(ebx+4)) # Var-name - 9695 (print-int32-buffered Stderr %eax) - 9696 { - 9697 3d/compare-eax-and 0/imm32 - 9698 74/jump-if-= break/disp8 - 9699 (write-buffered Stderr Space) - 9700 (write-buffered Stderr %eax) - 9701 } - 9702 (write-buffered Stderr Newline) - 9703 (flush Stderr) - 9704 (emit-indent Stderr *(ebp+8)) - 9705 (write-buffered Stderr "block depth: ") - 9706 (print-int32-buffered Stderr *(ebx+0x10)) # Var-block-depth - 9707 (write-buffered Stderr Newline) - 9708 (flush Stderr) - 9709 (emit-indent Stderr *(ebp+8)) - 9710 (write-buffered Stderr "stack offset: ") - 9711 (print-int32-buffered Stderr *(ebx+0x14)) # Var-offset - 9712 (write-buffered Stderr Newline) - 9713 (flush Stderr) - 9714 (emit-indent Stderr *(ebp+8)) - 9715 (write-buffered Stderr "reg: ") - 9716 (print-int32-buffered Stderr *(ebx+0x18)) # Var-register - 9717 (write-buffered Stderr ",") - 9718 (print-int32-buffered Stderr *(ebx+0x1c)) # Var-register - 9719 (write-buffered Stderr "->") - 9720 (flush Stderr) - 9721 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register - 9722 (print-int32-buffered Stderr %eax) - 9723 { - 9724 3d/compare-eax-and 0/imm32 - 9725 74/jump-if-= break/disp8 - 9726 (write-buffered Stderr Space) - 9727 (write-buffered Stderr %eax) - 9728 } - 9729 (write-buffered Stderr Newline) - 9730 (flush Stderr) - 9731 } - 9732 $dump-var:end: - 9733 # . restore registers - 9734 5b/pop-to-ebx - 9735 58/pop-to-eax - 9736 # . epilogue - 9737 89/<- %esp 5/r32/ebp - 9738 5d/pop-to-ebp - 9739 c3/return - 9740 - 9741 ####################################################### - 9742 # Type-checking - 9743 ####################################################### - 9744 - 9745 check-mu-types: # err: (addr buffered-file), ed: (addr exit-descriptor) - 9746 # . prologue - 9747 55/push-ebp - 9748 89/<- %ebp 4/r32/esp - 9749 # . save registers - 9750 50/push-eax - 9751 # var curr/eax: (addr function) = *Program->functions - 9752 (lookup *_Program-functions *_Program-functions->payload) # => eax - 9753 { - 9754 $check-mu-types:loop: - 9755 # if (curr == null) break - 9756 3d/compare-eax-and 0/imm32 - 9757 0f 84/jump-if-= break/disp32 - 9758 (check-mu-function %eax *(ebp+8) *(ebp+0xc)) - 9759 # curr = lookup(curr->next) - 9760 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax - 9761 e9/jump loop/disp32 - 9762 } - 9763 $check-mu-types:end: - 9764 # . restore registers - 9765 58/pop-to-eax - 9766 # . epilogue - 9767 89/<- %esp 5/r32/ebp - 9768 5d/pop-to-ebp - 9769 c3/return - 9770 - 9771 check-mu-function: # fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) - 9772 # . prologue - 9773 55/push-ebp - 9774 89/<- %ebp 4/r32/esp - 9775 # . save registers - 9776 50/push-eax - 9777 # eax = f - 9778 8b/-> *(ebp+8) 0/r32/eax - 9779 # TODO: anything to check in header? - 9780 # var body/eax: (addr block) = lookup(f->body) - 9781 (lookup *(eax+0x18) *(eax+0x1c)) # Function-body Function-body => eax - 9782 (check-mu-block %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10)) - 9783 $check-mu-function:end: - 9784 # . restore registers - 9785 58/pop-to-eax - 9786 # . epilogue - 9787 89/<- %esp 5/r32/ebp - 9788 5d/pop-to-ebp - 9789 c3/return - 9790 - 9791 check-mu-block: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) - 9792 # . prologue - 9793 55/push-ebp - 9794 89/<- %ebp 4/r32/esp - 9795 # . save registers - 9796 50/push-eax - 9797 # eax = block - 9798 8b/-> *(ebp+8) 0/r32/eax - 9799 # var stmts/eax: (addr list stmt) = lookup(block->statements) - 9800 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax - 9801 # - 9802 { - 9803 $check-mu-block:check-empty: - 9804 3d/compare-eax-and 0/imm32 - 9805 0f 84/jump-if-= break/disp32 - 9806 # emit block->statements - 9807 (check-mu-stmt-list %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) - 9808 } - 9809 $check-mu-block:end: - 9810 # . restore registers - 9811 58/pop-to-eax - 9812 # . epilogue - 9813 89/<- %esp 5/r32/ebp - 9814 5d/pop-to-ebp - 9815 c3/return - 9816 - 9817 check-mu-stmt-list: # stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) - 9818 # . prologue - 9819 55/push-ebp - 9820 89/<- %ebp 4/r32/esp - 9821 # . save registers - 9822 50/push-eax - 9823 56/push-esi - 9824 # esi = stmts - 9825 8b/-> *(ebp+8) 6/r32/esi - 9826 { - 9827 $check-mu-stmt-list:loop: - 9828 81 7/subop/compare %esi 0/imm32 - 9829 0f 84/jump-if-= break/disp32 - 9830 # var curr-stmt/eax: (addr stmt) = lookup(stmts->value) - 9831 (lookup *esi *(esi+4)) # List-value List-value => eax - 9832 { - 9833 $check-mu-stmt-list:check-for-block: - 9834 81 7/subop/compare *eax 0/imm32/block # Stmt-tag - 9835 75/jump-if-!= break/disp8 - 9836 $check-mu-stmt-list:block: - 9837 (check-mu-block %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) - 9838 eb/jump $check-mu-stmt-list:continue/disp8 - 9839 } - 9840 { - 9841 $check-mu-stmt-list:check-for-stmt1: - 9842 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag - 9843 0f 85/jump-if-!= break/disp32 - 9844 $check-mu-stmt-list:stmt1: - 9845 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) - 9846 eb/jump $check-mu-stmt-list:continue/disp8 - 9847 } - 9848 { - 9849 $check-mu-stmt-list:check-for-reg-var-def: - 9850 81 7/subop/compare *eax 3/imm32/reg-var-def # Stmt-tag - 9851 0f 85/jump-if-!= break/disp32 - 9852 $check-mu-stmt-list:reg-var-def: - 9853 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) - 9854 eb/jump $check-mu-stmt-list:continue/disp8 - 9855 } - 9856 $check-mu-stmt-list:continue: - 9857 # TODO: raise an error on unrecognized Stmt-tag - 9858 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax - 9859 89/<- %esi 0/r32/eax - 9860 e9/jump loop/disp32 - 9861 } - 9862 $check-mu-stmt-list:end: - 9863 # . restore registers - 9864 5e/pop-to-esi - 9865 58/pop-to-eax - 9866 # . epilogue - 9867 89/<- %esp 5/r32/ebp - 9868 5d/pop-to-ebp - 9869 c3/return - 9870 - 9871 check-mu-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) - 9872 # . prologue - 9873 55/push-ebp - 9874 89/<- %ebp 4/r32/esp - 9875 # . save registers - 9876 50/push-eax - 9877 51/push-ecx - 9878 52/push-edx - 9879 53/push-ebx - 9880 56/push-esi - 9881 57/push-edi - 9882 # esi = stmt - 9883 8b/-> *(ebp+8) 6/r32/esi - 9884 # var f/edi: (addr function) = lookup(*Program->functions) - 9885 (lookup *_Program-functions *_Program-functions->payload) # => eax - 9886 (find-matching-function %eax *(ebp+8)) # => eax - 9887 89/<- %edi 0/r32/eax - 9888 { - 9889 $check-mu-stmt:check-for-call: - 9890 81 7/subop/compare %edi 0/imm32 - 9891 0f 84/jump-if-= break/disp32 - 9892 $check-mu-stmt:is-call: - 9893 # var inouts/ecx: (addr stmt-var) = lookup(stmt->inouts) - 9894 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax - 9895 89/<- %ecx 0/r32/eax - 9896 # var expected/edx: (addr list var) = lookup(f->inouts) - 9897 (lookup *(edi+8) *(edi+0xc)) # Function-inouts Function-inouts => eax - 9898 89/<- %edx 0/r32/eax - 9899 { - 9900 $check-mu-stmt:check-for-inouts: - 9901 # if (inouts == 0) break - 9902 81 7/subop/compare %ecx 0/imm32 - 9903 0f 84/jump-if-= break/disp32 - 9904 # if (expected == 0) error - 9905 81 7/subop/compare %edx 0/imm32 - 9906 0f 84/jump-if-= break/disp32 - 9907 $check-mu-stmt:check-inout-type: - 9908 # var v/eax: (addr v) = lookup(inouts->value) - 9909 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax - 9910 # var t/ebx: (addr tree type-id) = lookup(v->type) - 9911 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax - 9912 89/<- %ebx 0/r32/eax - 9913 # if (inouts->is-deref?) t = t->right # TODO: check that t->left is an addr - 9914 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref - 9915 { - 9916 74/jump-if-= break/disp8 - 9917 (lookup *(ebx+0xc) *(ebx+0x10)) # Tree-right Tree-right => eax - 9918 89/<- %ebx 0/r32/eax - 9919 # if t->right is null, t = t->left - 9920 81 7/subop/compare *(ebx+0xc) 0/imm32 # Tree-right - 9921 75/jump-if-!= break/disp8 - 9922 (lookup *(ebx+4) *(ebx+8)) # Tree-left Tree-left => eax - 9923 89/<- %ebx 0/r32/eax - 9924 } - 9925 # var v2/eax: (addr v) = lookup(expected->value) - 9926 (lookup *edx *(edx+4)) # List-value List-value => eax - 9927 # var t2/eax: (addr tree type-id) = lookup(v2->type) - 9928 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax - 9929 # if (t != t2) error - 9930 (type-match? %eax %ebx) # => eax - 9931 3d/compare-eax-and 0/imm32/false - 9932 { - 9933 0f 85/jump-if-!= break/disp32 - 9934 (write-buffered *(ebp+0x10) "fn ") - 9935 8b/-> *(ebp+0xc) 0/r32/eax - 9936 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 9937 (write-buffered *(ebp+0x10) %eax) - 9938 (write-buffered *(ebp+0x10) ": call ") - 9939 (lookup *edi *(edi+4)) # Function-name Function-name => eax - 9940 (write-buffered *(ebp+0x10) %eax) - 9941 (write-buffered *(ebp+0x10) ": type for inout '") - 9942 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax - 9943 (lookup *eax *(eax+4)) # Var-name Var-name => eax - 9944 (write-buffered *(ebp+0x10) %eax) - 9945 (write-buffered *(ebp+0x10) "' is not right\n") - 9946 (flush *(ebp+0x10)) - 9947 (stop *(ebp+0x14) 1) - 9948 } - 9949 $check-mu-stmt:continue-to-next-inout: - 9950 # inouts = lookup(inouts->next) - 9951 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax - 9952 89/<- %ecx 0/r32/eax - 9953 # expected = lookup(expected->next) - 9954 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax - 9955 89/<- %edx 0/r32/eax - 9956 # - 9957 e9/jump loop/disp32 - 9958 } - 9959 $check-mu-stmt:check-inout-count: - 9960 # if (inouts == expected) proceed - 9961 39/compare %ecx 2/r32/edx - 9962 { - 9963 0f 84/jump-if-= break/disp32 - 9964 # exactly one of the two is null - 9965 # if (inouts == 0) error("too many inouts") - 9966 { - 9967 81 7/subop/compare %ecx 0/imm32 - 9968 0f 84/jump-if-= break/disp32 - 9969 (write-buffered *(ebp+0x10) "fn ") - 9970 8b/-> *(ebp+0xc) 0/r32/eax - 9971 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 9972 (write-buffered *(ebp+0x10) %eax) - 9973 (write-buffered *(ebp+0x10) ": call ") - 9974 (lookup *edi *(edi+4)) # Function-name Function-name => eax - 9975 (write-buffered *(ebp+0x10) %eax) - 9976 (write-buffered *(ebp+0x10) ": too many inouts\n") - 9977 (flush *(ebp+0x10)) - 9978 (stop *(ebp+0x14) 1) - 9979 } - 9980 # if (expected == 0) error("too few inouts") - 9981 { - 9982 81 7/subop/compare %edx 0/imm32 - 9983 0f 84/jump-if-= break/disp32 - 9984 (write-buffered *(ebp+0x10) "fn ") - 9985 8b/-> *(ebp+0xc) 0/r32/eax - 9986 (lookup *eax *(eax+4)) # Function-name Function-name => eax - 9987 (write-buffered *(ebp+0x10) %eax) - 9988 (write-buffered *(ebp+0x10) ": call ") - 9989 (lookup *edi *(edi+4)) # Function-name Function-name => eax - 9990 (write-buffered *(ebp+0x10) %eax) - 9991 (write-buffered *(ebp+0x10) ": too few inouts\n") - 9992 (flush *(ebp+0x10)) - 9993 (stop *(ebp+0x14) 1) - 9994 } - 9995 } - 9996 $check-mu-stmt:check-outputs: - 9997 # var outputs/ecx: (addr stmt-var) = lookup(stmt->outputs) - 9998 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax - 9999 89/<- %ecx 0/r32/eax -10000 # var expected/edx: (addr list var) = lookup(f->outputs) -10001 (lookup *(edi+0x10) *(edi+0x14)) # Function-outputs Function-outputs => eax -10002 89/<- %edx 0/r32/eax -10003 { -10004 $check-mu-stmt:check-for-outputs: -10005 # if (outputs == 0) break -10006 81 7/subop/compare %ecx 0/imm32 -10007 0f 84/jump-if-= break/disp32 -10008 # if (expected == 0) error -10009 81 7/subop/compare %edx 0/imm32 -10010 0f 84/jump-if-= break/disp32 -10011 $check-mu-stmt:check-output-type: -10012 # var v/eax: (addr v) = lookup(outputs->value) -10013 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -10014 # var t/ebx: (addr tree type-id) = lookup(v->type) -10015 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -10016 89/<- %ebx 0/r32/eax -10017 # if (outputs->is-deref?) t = t->right # TODO: check that t->left is an addr -10018 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -10019 { -10020 74/jump-if-= break/disp8 -10021 (lookup *(ebx+0xc) *(ebx+0x10)) # Tree-right Tree-right => eax -10022 89/<- %ebx 0/r32/eax -10023 } -10024 # var v2/eax: (addr v) = lookup(expected->value) -10025 (lookup *edx *(edx+4)) # List-value List-value => eax -10026 # var t2/eax: (addr tree type-id) = lookup(v2->type) -10027 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -10028 # if (t != t2) error -10029 (type-equal? %eax %ebx) # => eax -10030 3d/compare-eax-and 0/imm32/false -10031 { -10032 0f 85/jump-if-!= break/disp32 -10033 (write-buffered *(ebp+0x10) "fn ") -10034 8b/-> *(ebp+0xc) 0/r32/eax -10035 (lookup *eax *(eax+4)) # Function-name Function-name => eax -10036 (write-buffered *(ebp+0x10) %eax) -10037 (write-buffered *(ebp+0x10) ": call ") -10038 (lookup *edi *(edi+4)) # Function-name Function-name => eax -10039 (write-buffered *(ebp+0x10) %eax) -10040 (write-buffered *(ebp+0x10) ": type for output '") -10041 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -10042 (lookup *eax *(eax+4)) # Var-name Var-name => eax -10043 (write-buffered *(ebp+0x10) %eax) -10044 (write-buffered *(ebp+0x10) "' is not right\n") -10045 (flush *(ebp+0x10)) -10046 (stop *(ebp+0x14) 1) -10047 } -10048 $check-mu-stmt:check-output-register: -10049 # var v/eax: (addr v) = lookup(outputs->value) -10050 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -10051 # var r/ebx: (addr array byte) = lookup(v->register) -10052 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax -10053 89/<- %ebx 0/r32/eax -10054 # var v2/eax: (addr v) = lookup(expected->value) -10055 (lookup *edx *(edx+4)) # Stmt-var-value Stmt-var-value => eax -10056 # var r2/eax: (addr array byte) = lookup(v2->register) -10057 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax -10058 # if (r != r2) error -10059 (string-equal? %eax %ebx) # => eax -10060 3d/compare-eax-and 0/imm32/false -10061 { -10062 0f 85/jump-if-!= break/disp32 -10063 (write-buffered *(ebp+0x10) "fn ") -10064 8b/-> *(ebp+0xc) 0/r32/eax -10065 (lookup *eax *(eax+4)) # Function-name Function-name => eax -10066 (write-buffered *(ebp+0x10) %eax) -10067 (write-buffered *(ebp+0x10) ": call ") -10068 (lookup *edi *(edi+4)) # Function-name Function-name => eax -10069 (write-buffered *(ebp+0x10) %eax) -10070 (write-buffered *(ebp+0x10) ": register for output '") -10071 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -10072 (lookup *eax *(eax+4)) # Var-name Var-name => eax -10073 (write-buffered *(ebp+0x10) %eax) -10074 (write-buffered *(ebp+0x10) "' is not right\n") -10075 (flush *(ebp+0x10)) -10076 (stop *(ebp+0x14) 1) -10077 } -10078 $check-mu-stmt:continue-to-next-output: -10079 # outputs = lookup(outputs->next) -10080 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -10081 89/<- %ecx 0/r32/eax -10082 # expected = lookup(expected->next) -10083 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax -10084 89/<- %edx 0/r32/eax -10085 # -10086 e9/jump loop/disp32 -10087 } -10088 $check-mu-stmt:check-output-count: -10089 # if (outputs == expected) proceed -10090 39/compare %ecx 2/r32/edx -10091 { -10092 0f 84/jump-if-= break/disp32 -10093 # exactly one of the two is null -10094 # if (outputs == 0) error("too many outputs") -10095 { -10096 81 7/subop/compare %ecx 0/imm32 -10097 0f 84/jump-if-= break/disp32 -10098 (write-buffered *(ebp+0x10) "fn ") -10099 8b/-> *(ebp+0xc) 0/r32/eax -10100 (lookup *eax *(eax+4)) # Function-name Function-name => eax -10101 (write-buffered *(ebp+0x10) %eax) -10102 (write-buffered *(ebp+0x10) ": call ") -10103 (lookup *edi *(edi+4)) # Function-name Function-name => eax -10104 (write-buffered *(ebp+0x10) %eax) -10105 (write-buffered *(ebp+0x10) ": too many outputs\n") -10106 (flush *(ebp+0x10)) -10107 (stop *(ebp+0x14) 1) -10108 } -10109 # if (expected == 0) error("too few outputs") -10110 { -10111 81 7/subop/compare %edx 0/imm32 -10112 0f 84/jump-if-= break/disp32 -10113 (write-buffered *(ebp+0x10) "fn ") -10114 8b/-> *(ebp+0xc) 0/r32/eax -10115 (lookup *eax *(eax+4)) # Function-name Function-name => eax -10116 (write-buffered *(ebp+0x10) %eax) -10117 (write-buffered *(ebp+0x10) ": call ") -10118 (lookup *edi *(edi+4)) # Function-name Function-name => eax -10119 (write-buffered *(ebp+0x10) %eax) -10120 (write-buffered *(ebp+0x10) ": too few outputs\n") -10121 (flush *(ebp+0x10)) -10122 (stop *(ebp+0x14) 1) -10123 } -10124 } -10125 } -10126 $check-mu-stmt:end: -10127 # . restore registers -10128 5f/pop-to-edi -10129 5e/pop-to-esi -10130 5b/pop-to-ebx -10131 5a/pop-to-edx -10132 59/pop-to-ecx -10133 58/pop-to-eax -10134 # . epilogue -10135 89/<- %esp 5/r32/ebp -10136 5d/pop-to-ebp -10137 c3/return -10138 -10139 # like type-equal? but takes literals into account -10140 type-match?: # def: (addr tree type-id), call: (addr tree type-id) -> result/eax: boolean -10141 # . prologue -10142 55/push-ebp -10143 89/<- %ebp 4/r32/esp -10144 # if (call == literal) return true # TODO: more precise -10145 (is-simple-mu-type? *(ebp+0xc) 0) # literal => eax -10146 3d/compare-eax-and 0/imm32/false -10147 b8/copy-to-eax 1/imm32/true -10148 75/jump-if-!= $type-match?:end/disp8 -10149 $type-match?:baseline: -10150 # otherwise fall back -10151 (type-equal? *(ebp+8) *(ebp+0xc)) # => eax -10152 $type-match?:end: -10153 # . epilogue -10154 89/<- %esp 5/r32/ebp -10155 5d/pop-to-ebp -10156 c3/return -10157 -10158 size-of: # v: (addr var) -> result/eax: int -10159 # . prologue -10160 55/push-ebp -10161 89/<- %ebp 4/r32/esp -10162 # . save registers -10163 51/push-ecx -10164 # var t/ecx: (addr tree type-id) = lookup(v->type) -10165 8b/-> *(ebp+8) 1/r32/ecx -10166 #? (write-buffered Stderr "size-of ") -10167 #? (print-int32-buffered Stderr %ecx) -10168 #? (write-buffered Stderr Newline) -10169 #? (write-buffered Stderr "type allocid: ") -10170 #? (print-int32-buffered Stderr *(ecx+8)) -10171 #? (write-buffered Stderr Newline) -10172 #? (flush Stderr) -10173 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -10174 89/<- %ecx 0/r32/eax -10175 # if is-mu-array?(t) return size-of-array(t) -10176 { -10177 (is-mu-array? %ecx) # => eax -10178 3d/compare-eax-and 0/imm32/false -10179 74/jump-if-= break/disp8 -10180 (size-of-array %ecx) # => eax -10181 eb/jump $size-of:end/disp8 -10182 } -10183 # if (!t->is-atom?) t = lookup(t->left) -10184 { -10185 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom -10186 75/jump-if-!= break/disp8 -10187 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax -10188 89/<- %ecx 0/r32/eax -10189 } -10190 # TODO: assert t->is-atom? -10191 (size-of-type-id *(ecx+4)) # Tree-value => eax -10192 $size-of:end: -10193 # . restore registers -10194 59/pop-to-ecx -10195 # . epilogue -10196 89/<- %esp 5/r32/ebp -10197 5d/pop-to-ebp -10198 c3/return -10199 -10200 size-of-deref: # v: (addr var) -> result/eax: int -10201 # . prologue -10202 55/push-ebp -10203 89/<- %ebp 4/r32/esp -10204 # . save registers -10205 51/push-ecx -10206 # var t/ecx: (addr tree type-id) = lookup(v->type) -10207 8b/-> *(ebp+8) 1/r32/ecx -10208 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -10209 89/<- %ecx 0/r32/eax -10210 # TODO: assert(t is an addr) -10211 # t = lookup(t->right) -10212 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax -10213 89/<- %ecx 0/r32/eax -10214 # if is-mu-array?(t) return size-of-array(t) -10215 { -10216 (is-mu-array? %ecx) # => eax -10217 3d/compare-eax-and 0/imm32/false -10218 74/jump-if-= break/disp8 -10219 (size-of-array %ecx) # => eax -10220 eb/jump $size-of:end/disp8 -10221 } -10222 # if (!t->is-atom?) t = lookup(t->left) + 6736 # . save registers + 6737 50/push-eax + 6738 51/push-ecx + 6739 52/push-edx + 6740 # + 6741 (zero-out *(ebp+0x10) *Handle-size) + 6742 # var tmp/ecx: (handle tree type-id) + 6743 68/push 0/imm32 + 6744 68/push 0/imm32 + 6745 89/<- %ecx 4/r32/esp + 6746 # tmp = parse-type(ad, in) + 6747 (parse-type *(ebp+8) *(ebp+0xc) %ecx *(ebp+0x14) *(ebp+0x18)) + 6748 # if (tmp == 0) return + 6749 81 7/subop/compare *ecx 0/imm32 + 6750 74/jump-if-= $parse-type-tree:end/disp8 + 6751 # out = new tree + 6752 (allocate *(ebp+8) *Tree-size *(ebp+0x10)) + 6753 # var out-addr/edx: (addr tree) = lookup(*out) + 6754 8b/-> *(ebp+0x10) 2/r32/edx + 6755 (lookup *edx *(edx+4)) # => eax + 6756 89/<- %edx 0/r32/eax + 6757 # out->left = tmp + 6758 8b/-> *ecx 0/r32/eax + 6759 89/<- *(edx+4) 0/r32/eax # Tree-left + 6760 8b/-> *(ecx+4) 0/r32/eax + 6761 89/<- *(edx+8) 0/r32/eax # Tree-left + 6762 # out->right = parse-type-tree(ad, in) + 6763 8d/copy-address *(edx+0xc) 0/r32/eax # Tree-right + 6764 (parse-type-tree *(ebp+8) *(ebp+0xc) %eax *(ebp+0x14) *(ebp+0x18)) + 6765 $parse-type-tree:end: + 6766 # . reclaim locals + 6767 81 0/subop/add %esp 8/imm32 + 6768 # . restore registers + 6769 5a/pop-to-edx + 6770 59/pop-to-ecx + 6771 58/pop-to-eax + 6772 # . epilogue + 6773 89/<- %esp 5/r32/ebp + 6774 5d/pop-to-ebp + 6775 c3/return + 6776 + 6777 next-mu-token: # in: (addr stream byte), out: (addr slice) + 6778 # pseudocode: + 6779 # start: + 6780 # skip-chars-matching-whitespace(in) + 6781 # if in->read >= in->write # end of in + 6782 # out = {0, 0} + 6783 # return + 6784 # out->start = &in->data[in->read] + 6785 # var curr-byte/eax: byte = in->data[in->read] + 6786 # if curr->byte == ',' # comment token + 6787 # ++in->read + 6788 # goto start + 6789 # if curr-byte == '#' # comment + 6790 # goto done # treat as eof + 6791 # if curr-byte == '"' # string literal + 6792 # skip-string(in) + 6793 # goto done # no metadata + 6794 # if curr-byte == '(' + 6795 # ++in->read + 6796 # goto done + 6797 # if curr-byte == ')' + 6798 # ++in->read + 6799 # goto done + 6800 # # read a word + 6801 # while true + 6802 # if in->read >= in->write + 6803 # break + 6804 # curr-byte = in->data[in->read] + 6805 # if curr-byte == ' ' + 6806 # break + 6807 # if curr-byte == '\r' + 6808 # break + 6809 # if curr-byte == '\n' + 6810 # break + 6811 # if curr-byte == '(' + 6812 # break + 6813 # if curr-byte == ')' + 6814 # break + 6815 # if curr-byte == ',' + 6816 # break + 6817 # ++in->read + 6818 # done: + 6819 # out->end = &in->data[in->read] + 6820 # + 6821 # . prologue + 6822 55/push-ebp + 6823 89/<- %ebp 4/r32/esp + 6824 # . save registers + 6825 50/push-eax + 6826 51/push-ecx + 6827 56/push-esi + 6828 57/push-edi + 6829 # esi = in + 6830 8b/-> *(ebp+8) 6/r32/esi + 6831 # edi = out + 6832 8b/-> *(ebp+0xc) 7/r32/edi + 6833 $next-mu-token:start: + 6834 (skip-chars-matching-whitespace %esi) + 6835 $next-mu-token:check0: + 6836 # if (in->read >= in->write) return out = {0, 0} + 6837 # . ecx = in->read + 6838 8b/-> *(esi+4) 1/r32/ecx + 6839 # . if (ecx >= in->write) return out = {0, 0} + 6840 3b/compare<- *esi 1/r32/ecx + 6841 c7 0/subop/copy *edi 0/imm32 + 6842 c7 0/subop/copy *(edi+4) 0/imm32 + 6843 0f 8d/jump-if->= $next-mu-token:end/disp32 + 6844 # out->start = &in->data[in->read] + 6845 8d/copy-address *(esi+ecx+0xc) 0/r32/eax + 6846 89/<- *edi 0/r32/eax + 6847 # var curr-byte/eax: byte = in->data[in->read] + 6848 31/xor-with %eax 0/r32/eax + 6849 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 6850 { + 6851 $next-mu-token:check-for-comma: + 6852 # if (curr-byte != ',') break + 6853 3d/compare-eax-and 0x2c/imm32/comma + 6854 75/jump-if-!= break/disp8 + 6855 # ++in->read + 6856 ff 0/subop/increment *(esi+4) + 6857 # restart + 6858 e9/jump $next-mu-token:start/disp32 + 6859 } + 6860 { + 6861 $next-mu-token:check-for-comment: + 6862 # if (curr-byte != '#') break + 6863 3d/compare-eax-and 0x23/imm32/pound + 6864 75/jump-if-!= break/disp8 + 6865 # return eof + 6866 e9/jump $next-mu-token:done/disp32 + 6867 } + 6868 { + 6869 $next-mu-token:check-for-string-literal: + 6870 # if (curr-byte != '"') break + 6871 3d/compare-eax-and 0x22/imm32/dquote + 6872 75/jump-if-!= break/disp8 + 6873 (skip-string %esi) + 6874 # return + 6875 e9/jump $next-mu-token:done/disp32 + 6876 } + 6877 { + 6878 $next-mu-token:check-for-open-paren: + 6879 # if (curr-byte != '(') break + 6880 3d/compare-eax-and 0x28/imm32/open-paren + 6881 75/jump-if-!= break/disp8 + 6882 # ++in->read + 6883 ff 0/subop/increment *(esi+4) + 6884 # return + 6885 e9/jump $next-mu-token:done/disp32 + 6886 } + 6887 { + 6888 $next-mu-token:check-for-close-paren: + 6889 # if (curr-byte != ')') break + 6890 3d/compare-eax-and 0x29/imm32/close-paren + 6891 75/jump-if-!= break/disp8 + 6892 # ++in->read + 6893 ff 0/subop/increment *(esi+4) + 6894 # return + 6895 e9/jump $next-mu-token:done/disp32 + 6896 } + 6897 { + 6898 $next-mu-token:regular-word-without-metadata: + 6899 # if (in->read >= in->write) break + 6900 # . ecx = in->read + 6901 8b/-> *(esi+4) 1/r32/ecx + 6902 # . if (ecx >= in->write) break + 6903 3b/compare<- *esi 1/r32/ecx + 6904 7d/jump-if->= break/disp8 + 6905 # var c/eax: byte = in->data[in->read] + 6906 31/xor-with %eax 0/r32/eax + 6907 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL + 6908 # if (c == ' ') break + 6909 3d/compare-eax-and 0x20/imm32/space + 6910 74/jump-if-= break/disp8 + 6911 # if (c == '\r') break + 6912 3d/compare-eax-and 0xd/imm32/carriage-return + 6913 74/jump-if-= break/disp8 + 6914 # if (c == '\n') break + 6915 3d/compare-eax-and 0xa/imm32/newline + 6916 74/jump-if-= break/disp8 + 6917 # if (c == '(') break + 6918 3d/compare-eax-and 0x28/imm32/open-paren + 6919 0f 84/jump-if-= break/disp32 + 6920 # if (c == ')') break + 6921 3d/compare-eax-and 0x29/imm32/close-paren + 6922 0f 84/jump-if-= break/disp32 + 6923 # if (c == ',') break + 6924 3d/compare-eax-and 0x2c/imm32/comma + 6925 0f 84/jump-if-= break/disp32 + 6926 # ++in->read + 6927 ff 0/subop/increment *(esi+4) + 6928 # + 6929 e9/jump loop/disp32 + 6930 } + 6931 $next-mu-token:done: + 6932 # out->end = &in->data[in->read] + 6933 8b/-> *(esi+4) 1/r32/ecx + 6934 8d/copy-address *(esi+ecx+0xc) 0/r32/eax + 6935 89/<- *(edi+4) 0/r32/eax + 6936 $next-mu-token:end: + 6937 # . restore registers + 6938 5f/pop-to-edi + 6939 5e/pop-to-esi + 6940 59/pop-to-ecx + 6941 58/pop-to-eax + 6942 # . epilogue + 6943 89/<- %esp 5/r32/ebp + 6944 5d/pop-to-ebp + 6945 c3/return + 6946 + 6947 pos-or-insert-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int + 6948 # . prologue + 6949 55/push-ebp + 6950 89/<- %ebp 4/r32/esp + 6951 # if (pos-slice(arr, s) != -1) return it + 6952 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax + 6953 3d/compare-eax-and -1/imm32 + 6954 75/jump-if-!= $pos-or-insert-slice:end/disp8 + 6955 $pos-or-insert-slice:insert: + 6956 # var s2/eax: (handle array byte) + 6957 68/push 0/imm32 + 6958 68/push 0/imm32 + 6959 89/<- %eax 4/r32/esp + 6960 (slice-to-string Heap *(ebp+0xc) %eax) + 6961 # throw away alloc-id + 6962 (lookup *eax *(eax+4)) # => eax + 6963 (write-int *(ebp+8) %eax) + 6964 (pos-slice *(ebp+8) *(ebp+0xc)) # => eax + 6965 $pos-or-insert-slice:end: + 6966 # . reclaim locals + 6967 81 0/subop/add %esp 8/imm32 + 6968 # . epilogue + 6969 89/<- %esp 5/r32/ebp + 6970 5d/pop-to-ebp + 6971 c3/return + 6972 + 6973 # return the index in an array of strings matching 's', -1 if not found + 6974 # index is denominated in elements, not bytes + 6975 pos-slice: # arr: (addr stream (addr array byte)), s: (addr slice) -> index/eax: int + 6976 # . prologue + 6977 55/push-ebp + 6978 89/<- %ebp 4/r32/esp + 6979 # . save registers + 6980 51/push-ecx + 6981 52/push-edx + 6982 53/push-ebx + 6983 56/push-esi + 6984 #? (write-buffered Stderr "pos-slice: ") + 6985 #? (write-slice-buffered Stderr *(ebp+0xc)) + 6986 #? (write-buffered Stderr "\n") + 6987 #? (flush Stderr) + 6988 # esi = arr + 6989 8b/-> *(ebp+8) 6/r32/esi + 6990 # var index/ecx: int = 0 + 6991 b9/copy-to-ecx 0/imm32 + 6992 # var curr/edx: (addr (addr array byte)) = arr->data + 6993 8d/copy-address *(esi+0xc) 2/r32/edx + 6994 # var max/ebx: (addr (addr array byte)) = &arr->data[arr->write] + 6995 8b/-> *esi 3/r32/ebx + 6996 8d/copy-address *(esi+ebx+0xc) 3/r32/ebx + 6997 { + 6998 #? (write-buffered Stderr " ") + 6999 #? (print-int32-buffered Stderr %ecx) + 7000 #? (write-buffered Stderr "\n") + 7001 #? (flush Stderr) + 7002 # if (curr >= max) return -1 + 7003 39/compare %edx 3/r32/ebx + 7004 b8/copy-to-eax -1/imm32 + 7005 73/jump-if-addr>= $pos-slice:end/disp8 + 7006 # if (slice-equal?(s, *curr)) break + 7007 (slice-equal? *(ebp+0xc) *edx) # => eax + 7008 3d/compare-eax-and 0/imm32/false + 7009 75/jump-if-!= break/disp8 + 7010 # ++index + 7011 41/increment-ecx + 7012 # curr += 4 + 7013 81 0/subop/add %edx 4/imm32 + 7014 # + 7015 eb/jump loop/disp8 + 7016 } + 7017 # return index + 7018 89/<- %eax 1/r32/ecx + 7019 $pos-slice:end: + 7020 #? (write-buffered Stderr "=> ") + 7021 #? (print-int32-buffered Stderr %eax) + 7022 #? (write-buffered Stderr "\n") + 7023 # . restore registers + 7024 5e/pop-to-esi + 7025 5b/pop-to-ebx + 7026 5a/pop-to-edx + 7027 59/pop-to-ecx + 7028 # . epilogue + 7029 89/<- %esp 5/r32/ebp + 7030 5d/pop-to-ebp + 7031 c3/return + 7032 + 7033 test-parse-var-with-type: + 7034 # . prologue + 7035 55/push-ebp + 7036 89/<- %ebp 4/r32/esp + 7037 # (eax..ecx) = "x:" + 7038 b8/copy-to-eax "x:"/imm32 + 7039 8b/-> *eax 1/r32/ecx + 7040 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7041 05/add-to-eax 4/imm32 + 7042 # var slice/ecx: slice = {eax, ecx} + 7043 51/push-ecx + 7044 50/push-eax + 7045 89/<- %ecx 4/r32/esp + 7046 # _test-input-stream contains "int" + 7047 (clear-stream _test-input-stream) + 7048 (write _test-input-stream "int") + 7049 # var v/edx: (handle var) + 7050 68/push 0/imm32 + 7051 68/push 0/imm32 + 7052 89/<- %edx 4/r32/esp + 7053 # + 7054 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 7055 # var v-addr/edx: (addr var) = lookup(v) + 7056 (lookup *edx *(edx+4)) # => eax + 7057 89/<- %edx 0/r32/eax + 7058 # check v-addr->name + 7059 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 7060 (check-strings-equal %eax "x" "F - test-parse-var-with-type/name") + 7061 # check v-addr->type + 7062 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 7063 (check-ints-equal *eax 1 "F - test-parse-var-with-type/type:0") # Tree-is-atom + 7064 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type/type:1") # Tree-value + 7065 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type/type:2") # Tree-right + 7066 # . epilogue + 7067 89/<- %esp 5/r32/ebp + 7068 5d/pop-to-ebp + 7069 c3/return + 7070 + 7071 test-parse-var-with-type-and-register: + 7072 # . prologue + 7073 55/push-ebp + 7074 89/<- %ebp 4/r32/esp + 7075 # (eax..ecx) = "x/eax:" + 7076 b8/copy-to-eax "x/eax:"/imm32 + 7077 8b/-> *eax 1/r32/ecx + 7078 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7079 05/add-to-eax 4/imm32 + 7080 # var slice/ecx: slice = {eax, ecx} + 7081 51/push-ecx + 7082 50/push-eax + 7083 89/<- %ecx 4/r32/esp + 7084 # _test-input-stream contains "int" + 7085 (clear-stream _test-input-stream) + 7086 (write _test-input-stream "int") + 7087 # var v/edx: (handle var) + 7088 68/push 0/imm32 + 7089 68/push 0/imm32 + 7090 89/<- %edx 4/r32/esp + 7091 # + 7092 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 7093 # var v-addr/edx: (addr var) = lookup(v) + 7094 (lookup *edx *(edx+4)) # => eax + 7095 89/<- %edx 0/r32/eax + 7096 # check v-addr->name + 7097 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 7098 (check-strings-equal %eax "x" "F - test-parse-var-with-type-and-register/name") + 7099 # check v-addr->register + 7100 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax + 7101 (check-strings-equal %eax "eax" "F - test-parse-var-with-type-and-register/register") + 7102 # check v-addr->type + 7103 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 7104 (check-ints-equal *eax 1 "F - test-parse-var-with-type-and-register/type:0") # Tree-is-atom + 7105 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-type-and-register/type:1") # Tree-left + 7106 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-type-and-register/type:2") # Tree-right + 7107 # . epilogue + 7108 89/<- %esp 5/r32/ebp + 7109 5d/pop-to-ebp + 7110 c3/return + 7111 + 7112 test-parse-var-with-trailing-characters: + 7113 # . prologue + 7114 55/push-ebp + 7115 89/<- %ebp 4/r32/esp + 7116 # (eax..ecx) = "x:" + 7117 b8/copy-to-eax "x:"/imm32 + 7118 8b/-> *eax 1/r32/ecx + 7119 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7120 05/add-to-eax 4/imm32 + 7121 # var slice/ecx: slice = {eax, ecx} + 7122 51/push-ecx + 7123 50/push-eax + 7124 89/<- %ecx 4/r32/esp + 7125 # _test-input-stream contains "int," + 7126 (clear-stream _test-input-stream) + 7127 (write _test-input-stream "int,") + 7128 # var v/edx: (handle var) + 7129 68/push 0/imm32 + 7130 68/push 0/imm32 + 7131 89/<- %edx 4/r32/esp + 7132 # + 7133 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 7134 # var v-addr/edx: (addr var) = lookup(v) + 7135 (lookup *edx *(edx+4)) # => eax + 7136 89/<- %edx 0/r32/eax + 7137 # check v-addr->name + 7138 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 7139 (check-strings-equal %eax "x" "F - test-parse-var-with-trailing-characters/name") + 7140 # check v-addr->register + 7141 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-trailing-characters/register") # Var-register + 7142 # check v-addr->type + 7143 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 7144 (check-ints-equal *eax 1 "F - test-parse-var-with-trailing-characters/type:0") # Tree-is-atom + 7145 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-trailing-characters/type:1") # Tree-left + 7146 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-trailing-characters/type:1") # Tree-right + 7147 # . epilogue + 7148 89/<- %esp 5/r32/ebp + 7149 5d/pop-to-ebp + 7150 c3/return + 7151 + 7152 test-parse-var-with-register-and-trailing-characters: + 7153 # . prologue + 7154 55/push-ebp + 7155 89/<- %ebp 4/r32/esp + 7156 # (eax..ecx) = "x/eax:" + 7157 b8/copy-to-eax "x/eax:"/imm32 + 7158 8b/-> *eax 1/r32/ecx + 7159 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7160 05/add-to-eax 4/imm32 + 7161 # var slice/ecx: slice = {eax, ecx} + 7162 51/push-ecx + 7163 50/push-eax + 7164 89/<- %ecx 4/r32/esp + 7165 # _test-input-stream contains "int," + 7166 (clear-stream _test-input-stream) + 7167 (write _test-input-stream "int,") + 7168 # var v/edx: (handle var) + 7169 68/push 0/imm32 + 7170 68/push 0/imm32 + 7171 89/<- %edx 4/r32/esp + 7172 # + 7173 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 7174 # var v-addr/edx: (addr var) = lookup(v) + 7175 (lookup *edx *(edx+4)) # => eax + 7176 89/<- %edx 0/r32/eax + 7177 # check v-addr->name + 7178 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 7179 (check-strings-equal %eax "x" "F - test-parse-var-with-register-and-trailing-characters/name") + 7180 # check v-addr->register + 7181 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax + 7182 (check-strings-equal %eax "eax" "F - test-parse-var-with-register-and-trailing-characters/register") + 7183 # check v-addr->type + 7184 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 7185 (check-ints-equal *eax 1 "F - test-parse-var-with-register-and-trailing-characters/type:0") # Tree-is-atom + 7186 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-register-and-trailing-characters/type:1") # Tree-left + 7187 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-register-and-trailing-characters/type:2") # Tree-right + 7188 # . epilogue + 7189 89/<- %esp 5/r32/ebp + 7190 5d/pop-to-ebp + 7191 c3/return + 7192 + 7193 test-parse-var-with-compound-type: + 7194 # . prologue + 7195 55/push-ebp + 7196 89/<- %ebp 4/r32/esp + 7197 # (eax..ecx) = "x:" + 7198 b8/copy-to-eax "x:"/imm32 + 7199 8b/-> *eax 1/r32/ecx + 7200 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7201 05/add-to-eax 4/imm32 + 7202 # var slice/ecx: slice = {eax, ecx} + 7203 51/push-ecx + 7204 50/push-eax + 7205 89/<- %ecx 4/r32/esp + 7206 # _test-input-stream contains "(addr int)" + 7207 (clear-stream _test-input-stream) + 7208 (write _test-input-stream "(addr int)") + 7209 # var v/edx: (handle var) + 7210 68/push 0/imm32 + 7211 68/push 0/imm32 + 7212 89/<- %edx 4/r32/esp + 7213 # + 7214 (parse-var-with-type %ecx _test-input-stream %edx Stderr 0) + 7215 # var v-addr/edx: (addr var) = lookup(v) + 7216 (lookup *edx *(edx+4)) # => eax + 7217 89/<- %edx 0/r32/eax + 7218 # check v-addr->name + 7219 (lookup *edx *(edx+4)) # Var-name Var-name => eax + 7220 (check-strings-equal %eax "x" "F - test-parse-var-with-compound-type/name") + 7221 # check v-addr->register + 7222 (check-ints-equal *(edx+0x18) 0 "F - test-parse-var-with-compound-type/register") # Var-register + 7223 # - check v-addr->type + 7224 # var type/edx: (addr tree type-id) = var->type + 7225 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax + 7226 89/<- %edx 0/r32/eax + 7227 # type is a non-atom + 7228 (check-ints-equal *edx 0 "F - test-parse-var-with-compound-type/type:0") # Tree-is-atom + 7229 # type->left == atom(addr) + 7230 (lookup *(edx+4) *(edx+8)) # Tree-left Tree-left => eax + 7231 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:1") # Tree-is-atom + 7232 (check-ints-equal *(eax+4) 2 "F - test-parse-var-with-compound-type/type:2") # Tree-value + 7233 # type->right->left == atom(int) + 7234 (lookup *(edx+0xc) *(edx+0x10)) # Tree-right Tree-right => eax + 7235 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax + 7236 (check-ints-equal *eax 1 "F - test-parse-var-with-compound-type/type:3") # Tree-is-atom + 7237 (check-ints-equal *(eax+4) 1 "F - test-parse-var-with-compound-type/type:4") # Tree-value + 7238 # type->right->right == null + 7239 (check-ints-equal *(eax+0xc) 0 "F - test-parse-var-with-compound-type/type:5") # Tree-right + 7240 # . epilogue + 7241 89/<- %esp 5/r32/ebp + 7242 5d/pop-to-ebp + 7243 c3/return + 7244 + 7245 # identifier starts with a letter or '$' or '_' + 7246 # no constraints at the moment on later letters + 7247 # all we really want to do so far is exclude '{', '}' and '->' + 7248 is-identifier?: # in: (addr slice) -> result/eax: boolean + 7249 # . prologue + 7250 55/push-ebp + 7251 89/<- %ebp 4/r32/esp + 7252 # if (slice-empty?(in)) return false + 7253 (slice-empty? *(ebp+8)) # => eax + 7254 3d/compare-eax-and 0/imm32/false + 7255 75/jump-if-!= $is-identifier?:false/disp8 + 7256 # var c/eax: byte = *in->start + 7257 8b/-> *(ebp+8) 0/r32/eax + 7258 8b/-> *eax 0/r32/eax + 7259 8a/copy-byte *eax 0/r32/AL + 7260 81 4/subop/and %eax 0xff/imm32 + 7261 # if (c == '$') return true + 7262 3d/compare-eax-and 0x24/imm32/$ + 7263 74/jump-if-= $is-identifier?:true/disp8 + 7264 # if (c == '_') return true + 7265 3d/compare-eax-and 0x5f/imm32/_ + 7266 74/jump-if-= $is-identifier?:true/disp8 + 7267 # drop case + 7268 25/and-eax-with 0x5f/imm32 + 7269 # if (c < 'A') return false + 7270 3d/compare-eax-and 0x41/imm32/A + 7271 7c/jump-if-< $is-identifier?:false/disp8 + 7272 # if (c > 'Z') return false + 7273 3d/compare-eax-and 0x5a/imm32/Z + 7274 7f/jump-if-> $is-identifier?:false/disp8 + 7275 # otherwise return true + 7276 $is-identifier?:true: + 7277 b8/copy-to-eax 1/imm32/true + 7278 eb/jump $is-identifier?:end/disp8 + 7279 $is-identifier?:false: + 7280 b8/copy-to-eax 0/imm32/false + 7281 $is-identifier?:end: + 7282 # . epilogue + 7283 89/<- %esp 5/r32/ebp + 7284 5d/pop-to-ebp + 7285 c3/return + 7286 + 7287 test-is-identifier-dollar: + 7288 # . prologue + 7289 55/push-ebp + 7290 89/<- %ebp 4/r32/esp + 7291 # (eax..ecx) = "$a" + 7292 b8/copy-to-eax "$a"/imm32 + 7293 8b/-> *eax 1/r32/ecx + 7294 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7295 05/add-to-eax 4/imm32 + 7296 # var slice/ecx: slice = {eax, ecx} + 7297 51/push-ecx + 7298 50/push-eax + 7299 89/<- %ecx 4/r32/esp + 7300 # + 7301 (is-identifier? %ecx) + 7302 (check-ints-equal %eax 1 "F - test-is-identifier-dollar") + 7303 # . epilogue + 7304 89/<- %esp 5/r32/ebp + 7305 5d/pop-to-ebp + 7306 c3/return + 7307 + 7308 test-is-identifier-underscore: + 7309 # . prologue + 7310 55/push-ebp + 7311 89/<- %ebp 4/r32/esp + 7312 # (eax..ecx) = "_a" + 7313 b8/copy-to-eax "_a"/imm32 + 7314 8b/-> *eax 1/r32/ecx + 7315 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7316 05/add-to-eax 4/imm32 + 7317 # var slice/ecx: slice = {eax, ecx} + 7318 51/push-ecx + 7319 50/push-eax + 7320 89/<- %ecx 4/r32/esp + 7321 # + 7322 (is-identifier? %ecx) + 7323 (check-ints-equal %eax 1 "F - test-is-identifier-underscore") + 7324 # . epilogue + 7325 89/<- %esp 5/r32/ebp + 7326 5d/pop-to-ebp + 7327 c3/return + 7328 + 7329 test-is-identifier-a: + 7330 # . prologue + 7331 55/push-ebp + 7332 89/<- %ebp 4/r32/esp + 7333 # (eax..ecx) = "a$" + 7334 b8/copy-to-eax "a$"/imm32 + 7335 8b/-> *eax 1/r32/ecx + 7336 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7337 05/add-to-eax 4/imm32 + 7338 # var slice/ecx: slice = {eax, ecx} + 7339 51/push-ecx + 7340 50/push-eax + 7341 89/<- %ecx 4/r32/esp + 7342 # + 7343 (is-identifier? %ecx) + 7344 (check-ints-equal %eax 1 "F - test-is-identifier-a") + 7345 # . epilogue + 7346 89/<- %esp 5/r32/ebp + 7347 5d/pop-to-ebp + 7348 c3/return + 7349 + 7350 test-is-identifier-z: + 7351 # . prologue + 7352 55/push-ebp + 7353 89/<- %ebp 4/r32/esp + 7354 # (eax..ecx) = "z$" + 7355 b8/copy-to-eax "z$"/imm32 + 7356 8b/-> *eax 1/r32/ecx + 7357 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7358 05/add-to-eax 4/imm32 + 7359 # var slice/ecx: slice = {eax, ecx} + 7360 51/push-ecx + 7361 50/push-eax + 7362 89/<- %ecx 4/r32/esp + 7363 # + 7364 (is-identifier? %ecx) + 7365 (check-ints-equal %eax 1 "F - test-is-identifier-z") + 7366 # . epilogue + 7367 89/<- %esp 5/r32/ebp + 7368 5d/pop-to-ebp + 7369 c3/return + 7370 + 7371 test-is-identifier-A: + 7372 # . prologue + 7373 55/push-ebp + 7374 89/<- %ebp 4/r32/esp + 7375 # (eax..ecx) = "A$" + 7376 b8/copy-to-eax "A$"/imm32 + 7377 8b/-> *eax 1/r32/ecx + 7378 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7379 05/add-to-eax 4/imm32 + 7380 # var slice/ecx: slice = {eax, ecx} + 7381 51/push-ecx + 7382 50/push-eax + 7383 89/<- %ecx 4/r32/esp + 7384 # + 7385 (is-identifier? %ecx) + 7386 (check-ints-equal %eax 1 "F - test-is-identifier-A") + 7387 # . epilogue + 7388 89/<- %esp 5/r32/ebp + 7389 5d/pop-to-ebp + 7390 c3/return + 7391 + 7392 test-is-identifier-Z: + 7393 # . prologue + 7394 55/push-ebp + 7395 89/<- %ebp 4/r32/esp + 7396 # (eax..ecx) = "Z$" + 7397 b8/copy-to-eax "Z$"/imm32 + 7398 8b/-> *eax 1/r32/ecx + 7399 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7400 05/add-to-eax 4/imm32 + 7401 # var slice/ecx: slice = {eax, ecx} + 7402 51/push-ecx + 7403 50/push-eax + 7404 89/<- %ecx 4/r32/esp + 7405 # + 7406 (is-identifier? %ecx) + 7407 (check-ints-equal %eax 1 "F - test-is-identifier-Z") + 7408 # . epilogue + 7409 89/<- %esp 5/r32/ebp + 7410 5d/pop-to-ebp + 7411 c3/return + 7412 + 7413 test-is-identifier-at: + 7414 # character before 'A' is invalid + 7415 # . prologue + 7416 55/push-ebp + 7417 89/<- %ebp 4/r32/esp + 7418 # (eax..ecx) = "@a" + 7419 b8/copy-to-eax "@a"/imm32 + 7420 8b/-> *eax 1/r32/ecx + 7421 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7422 05/add-to-eax 4/imm32 + 7423 # var slice/ecx: slice = {eax, ecx} + 7424 51/push-ecx + 7425 50/push-eax + 7426 89/<- %ecx 4/r32/esp + 7427 # + 7428 (is-identifier? %ecx) + 7429 (check-ints-equal %eax 0 "F - test-is-identifier-@") + 7430 # . epilogue + 7431 89/<- %esp 5/r32/ebp + 7432 5d/pop-to-ebp + 7433 c3/return + 7434 + 7435 test-is-identifier-square-bracket: + 7436 # character after 'Z' is invalid + 7437 # . prologue + 7438 55/push-ebp + 7439 89/<- %ebp 4/r32/esp + 7440 # (eax..ecx) = "[a" + 7441 b8/copy-to-eax "[a"/imm32 + 7442 8b/-> *eax 1/r32/ecx + 7443 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7444 05/add-to-eax 4/imm32 + 7445 # var slice/ecx: slice = {eax, ecx} + 7446 51/push-ecx + 7447 50/push-eax + 7448 89/<- %ecx 4/r32/esp + 7449 # + 7450 (is-identifier? %ecx) + 7451 (check-ints-equal %eax 0 "F - test-is-identifier-@") + 7452 # . epilogue + 7453 89/<- %esp 5/r32/ebp + 7454 5d/pop-to-ebp + 7455 c3/return + 7456 + 7457 test-is-identifier-backtick: + 7458 # character before 'a' is invalid + 7459 # . prologue + 7460 55/push-ebp + 7461 89/<- %ebp 4/r32/esp + 7462 # (eax..ecx) = "`a" + 7463 b8/copy-to-eax "`a"/imm32 + 7464 8b/-> *eax 1/r32/ecx + 7465 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7466 05/add-to-eax 4/imm32 + 7467 # var slice/ecx: slice = {eax, ecx} + 7468 51/push-ecx + 7469 50/push-eax + 7470 89/<- %ecx 4/r32/esp + 7471 # + 7472 (is-identifier? %ecx) + 7473 (check-ints-equal %eax 0 "F - test-is-identifier-backtick") + 7474 # . epilogue + 7475 89/<- %esp 5/r32/ebp + 7476 5d/pop-to-ebp + 7477 c3/return + 7478 + 7479 test-is-identifier-curly-brace-open: + 7480 # character after 'z' is invalid; also used for blocks + 7481 # . prologue + 7482 55/push-ebp + 7483 89/<- %ebp 4/r32/esp + 7484 # (eax..ecx) = "{a" + 7485 b8/copy-to-eax "{a"/imm32 + 7486 8b/-> *eax 1/r32/ecx + 7487 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7488 05/add-to-eax 4/imm32 + 7489 # var slice/ecx: slice = {eax, ecx} + 7490 51/push-ecx + 7491 50/push-eax + 7492 89/<- %ecx 4/r32/esp + 7493 # + 7494 (is-identifier? %ecx) + 7495 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-open") + 7496 # . epilogue + 7497 89/<- %esp 5/r32/ebp + 7498 5d/pop-to-ebp + 7499 c3/return + 7500 + 7501 test-is-identifier-curly-brace-close: + 7502 # . prologue + 7503 55/push-ebp + 7504 89/<- %ebp 4/r32/esp + 7505 # (eax..ecx) = "}a" + 7506 b8/copy-to-eax "}a"/imm32 + 7507 8b/-> *eax 1/r32/ecx + 7508 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7509 05/add-to-eax 4/imm32 + 7510 # var slice/ecx: slice = {eax, ecx} + 7511 51/push-ecx + 7512 50/push-eax + 7513 89/<- %ecx 4/r32/esp + 7514 # + 7515 (is-identifier? %ecx) + 7516 (check-ints-equal %eax 0 "F - test-is-identifier-curly-brace-close") + 7517 # . epilogue + 7518 89/<- %esp 5/r32/ebp + 7519 5d/pop-to-ebp + 7520 c3/return + 7521 + 7522 test-is-identifier-hyphen: + 7523 # disallow leading '-' since '->' has special meaning + 7524 # . prologue + 7525 55/push-ebp + 7526 89/<- %ebp 4/r32/esp + 7527 # (eax..ecx) = "-a" + 7528 b8/copy-to-eax "-a"/imm32 + 7529 8b/-> *eax 1/r32/ecx + 7530 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 7531 05/add-to-eax 4/imm32 + 7532 # var slice/ecx: slice = {eax, ecx} + 7533 51/push-ecx + 7534 50/push-eax + 7535 89/<- %ecx 4/r32/esp + 7536 # + 7537 (is-identifier? %ecx) + 7538 (check-ints-equal %eax 0 "F - test-is-identifier-hyphen") + 7539 # . epilogue + 7540 89/<- %esp 5/r32/ebp + 7541 5d/pop-to-ebp + 7542 c3/return + 7543 + 7544 populate-mu-function-body: # in: (addr buffered-file), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) + 7545 # . prologue + 7546 55/push-ebp + 7547 89/<- %ebp 4/r32/esp + 7548 # . save registers + 7549 50/push-eax + 7550 56/push-esi + 7551 57/push-edi + 7552 # esi = in + 7553 8b/-> *(ebp+8) 6/r32/esi + 7554 # edi = out + 7555 8b/-> *(ebp+0xc) 7/r32/edi + 7556 # initialize some global state + 7557 c7 0/subop/copy *Curr-block-depth 1/imm32 + 7558 # parse-mu-block(in, vars, out, out->body) + 7559 8d/copy-address *(edi+0x18) 0/r32/eax # Function-body + 7560 (parse-mu-block %esi *(ebp+0x10) %edi %eax *(ebp+0x14) *(ebp+0x18)) + 7561 $populate-mu-function-body:end: + 7562 # . restore registers + 7563 5f/pop-to-edi + 7564 5e/pop-to-esi + 7565 58/pop-to-eax + 7566 # . epilogue + 7567 89/<- %esp 5/r32/ebp + 7568 5d/pop-to-ebp + 7569 c3/return + 7570 + 7571 # parses a block, assuming that the leading '{' has already been read by the caller + 7572 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) + 7573 # pseudocode: + 7574 # var line: (stream byte 512) + 7575 # var word-slice: slice + 7576 # allocate(Heap, Stmt-size, out) + 7577 # var out-addr: (addr block) = lookup(*out) + 7578 # out-addr->tag = 0/block + 7579 # out-addr->var = some unique name + 7580 # push(vars, {out-addr->var, false}) + 7581 # while true # line loop + 7582 # clear-stream(line) + 7583 # read-line-buffered(in, line) + 7584 # if (line->write == 0) break # end of file + 7585 # word-slice = next-mu-token(line) + 7586 # if slice-empty?(word-slice) # end of line + 7587 # continue + 7588 # else if slice-starts-with?(word-slice, "#") + 7589 # continue + 7590 # else if slice-equal?(word-slice, "{") + 7591 # assert(no-tokens-in(line)) + 7592 # block = parse-mu-block(in, vars, fn) + 7593 # append-to-block(out-addr, block) + 7594 # else if slice-equal?(word-slice, "}") + 7595 # break + 7596 # else if slice-ends-with?(word-slice, ":") + 7597 # # TODO: error-check the rest of 'line' + 7598 # --word-slice->end to skip ':' + 7599 # named-block = parse-mu-named-block(word-slice, in, vars, fn) + 7600 # append-to-block(out-addr, named-block) + 7601 # else if slice-equal?(word-slice, "var") + 7602 # var-def = parse-mu-var-def(line, vars, fn) + 7603 # append-to-block(out-addr, var-def) + 7604 # else + 7605 # stmt = parse-mu-stmt(line, vars, fn) + 7606 # append-to-block(out-addr, stmt) + 7607 # pop(vars) + 7608 # + 7609 # . prologue + 7610 55/push-ebp + 7611 89/<- %ebp 4/r32/esp + 7612 # . save registers + 7613 50/push-eax + 7614 51/push-ecx + 7615 52/push-edx + 7616 53/push-ebx + 7617 57/push-edi + 7618 # var line/ecx: (stream byte 512) + 7619 81 5/subop/subtract %esp 0x200/imm32 + 7620 68/push 0x200/imm32/size + 7621 68/push 0/imm32/read + 7622 68/push 0/imm32/write + 7623 89/<- %ecx 4/r32/esp + 7624 # var word-slice/edx: slice + 7625 68/push 0/imm32/end + 7626 68/push 0/imm32/start + 7627 89/<- %edx 4/r32/esp + 7628 # allocate into out + 7629 (allocate Heap *Stmt-size *(ebp+0x14)) + 7630 # var out-addr/edi: (addr block) = lookup(*out) + 7631 8b/-> *(ebp+0x14) 7/r32/edi + 7632 (lookup *edi *(edi+4)) # => eax + 7633 89/<- %edi 0/r32/eax + 7634 # out-addr->tag is 0 (block) by default + 7635 # set out-addr->var + 7636 8d/copy-address *(edi+0xc) 0/r32/eax # Block-var + 7637 (new-block-name *(ebp+0x10) %eax) + 7638 # push(vars, out-addr->var) + 7639 (push *(ebp+0xc) *(edi+0xc)) # Block-var + 7640 (push *(ebp+0xc) *(edi+0x10)) # Block-var + 7641 (push *(ebp+0xc) 0) # false + 7642 # increment *Curr-block-depth + 7643 ff 0/subop/increment *Curr-block-depth + 7644 { + 7645 $parse-mu-block:line-loop: + 7646 # line = read-line-buffered(in) + 7647 (clear-stream %ecx) + 7648 (read-line-buffered *(ebp+8) %ecx) + 7649 #? (write-buffered Stderr "line: ") + 7650 #? (write-stream-data Stderr %ecx) + 7651 #? #? (write-buffered Stderr Newline) # line has its own newline + 7652 #? (flush Stderr) + 7653 #? (rewind-stream %ecx) + 7654 # if (line->write == 0) break + 7655 81 7/subop/compare *ecx 0/imm32 + 7656 0f 84/jump-if-= break/disp32 + 7657 #? (write-buffered Stderr "vars:\n") + 7658 #? (dump-vars *(ebp+0xc)) + 7659 # word-slice = next-mu-token(line) + 7660 (next-mu-token %ecx %edx) + 7661 #? (write-buffered Stderr "word: ") + 7662 #? (write-slice-buffered Stderr %edx) + 7663 #? (write-buffered Stderr Newline) + 7664 #? (flush Stderr) + 7665 # if slice-empty?(word-slice) continue + 7666 (slice-empty? %edx) + 7667 3d/compare-eax-and 0/imm32/false + 7668 0f 85/jump-if-!= loop/disp32 + 7669 # if (slice-starts-with?(word-slice, '#') continue + 7670 # . eax = *word-slice->start + 7671 8b/-> *edx 0/r32/eax + 7672 8a/copy-byte *eax 0/r32/AL + 7673 81 4/subop/and %eax 0xff/imm32 + 7674 # . if (eax == '#') continue + 7675 3d/compare-eax-and 0x23/imm32/hash + 7676 0f 84/jump-if-= loop/disp32 + 7677 # if slice-equal?(word-slice, "{") + 7678 { + 7679 $parse-mu-block:check-for-block: + 7680 (slice-equal? %edx "{") + 7681 3d/compare-eax-and 0/imm32/false + 7682 74/jump-if-= break/disp8 + 7683 (check-no-tokens-left %ecx) + 7684 # parse new block and append + 7685 # . var tmp/eax: (handle block) + 7686 68/push 0/imm32 + 7687 68/push 0/imm32 + 7688 89/<- %eax 4/r32/esp + 7689 # . + 7690 (parse-mu-block *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) + 7691 (append-to-block Heap %edi *eax *(eax+4)) + 7692 # . reclaim tmp + 7693 81 0/subop/add %esp 8/imm32 + 7694 # . + 7695 e9/jump $parse-mu-block:line-loop/disp32 + 7696 } + 7697 # if slice-equal?(word-slice, "}") break + 7698 $parse-mu-block:check-for-end: + 7699 (slice-equal? %edx "}") + 7700 3d/compare-eax-and 0/imm32/false + 7701 0f 85/jump-if-!= break/disp32 + 7702 # if slice-ends-with?(word-slice, ":") parse named block and append + 7703 { + 7704 $parse-mu-block:check-for-named-block: + 7705 # . eax = *(word-slice->end-1) + 7706 8b/-> *(edx+4) 0/r32/eax + 7707 48/decrement-eax + 7708 8a/copy-byte *eax 0/r32/AL + 7709 81 4/subop/and %eax 0xff/imm32 + 7710 # . if (eax != ':') break + 7711 3d/compare-eax-and 0x3a/imm32/colon + 7712 0f 85/jump-if-!= break/disp32 + 7713 # TODO: error-check the rest of 'line' + 7714 # + 7715 # skip ':' + 7716 ff 1/subop/decrement *(edx+4) # Slice-end + 7717 # var tmp/eax: (handle block) + 7718 68/push 0/imm32 + 7719 68/push 0/imm32 + 7720 89/<- %eax 4/r32/esp + 7721 # + 7722 (parse-mu-named-block %edx *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) + 7723 (append-to-block Heap %edi *eax *(eax+4)) + 7724 # reclaim tmp + 7725 81 0/subop/add %esp 8/imm32 + 7726 # + 7727 e9/jump $parse-mu-block:line-loop/disp32 + 7728 } + 7729 # if slice-equal?(word-slice, "var") + 7730 { + 7731 $parse-mu-block:check-for-var: + 7732 (slice-equal? %edx "var") + 7733 3d/compare-eax-and 0/imm32/false + 7734 74/jump-if-= break/disp8 + 7735 # var tmp/eax: (handle block) + 7736 68/push 0/imm32 + 7737 68/push 0/imm32 + 7738 89/<- %eax 4/r32/esp + 7739 # + 7740 (parse-mu-var-def %ecx *(ebp+0xc) %eax *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) + 7741 (append-to-block Heap %edi *eax *(eax+4)) + 7742 # reclaim tmp + 7743 81 0/subop/add %esp 8/imm32 + 7744 # + 7745 e9/jump $parse-mu-block:line-loop/disp32 + 7746 } + 7747 $parse-mu-block:regular-stmt: + 7748 # otherwise + 7749 # var tmp/eax: (handle block) + 7750 68/push 0/imm32 + 7751 68/push 0/imm32 + 7752 89/<- %eax 4/r32/esp + 7753 # + 7754 (parse-mu-stmt %ecx *(ebp+0xc) *(ebp+0x10) %eax *(ebp+0x18) *(ebp+0x1c)) + 7755 (append-to-block Heap %edi *eax *(eax+4)) + 7756 # reclaim tmp + 7757 81 0/subop/add %esp 8/imm32 + 7758 # + 7759 e9/jump loop/disp32 + 7760 } # end line loop + 7761 (clean-up-blocks *(ebp+0xc) *Curr-block-depth *(ebp+0x10)) + 7762 # decrement *Curr-block-depth + 7763 ff 1/subop/decrement *Curr-block-depth + 7764 # pop(vars) + 7765 (pop *(ebp+0xc)) # => eax + 7766 (pop *(ebp+0xc)) # => eax + 7767 (pop *(ebp+0xc)) # => eax + 7768 $parse-mu-block:end: + 7769 # . reclaim locals + 7770 81 0/subop/add %esp 0x214/imm32 + 7771 # . restore registers + 7772 5f/pop-to-edi + 7773 5b/pop-to-ebx + 7774 5a/pop-to-edx + 7775 59/pop-to-ecx + 7776 58/pop-to-eax + 7777 # . epilogue + 7778 89/<- %esp 5/r32/ebp + 7779 5d/pop-to-ebp + 7780 c3/return + 7781 + 7782 $parse-mu-block:abort: + 7783 # error("'{' or '}' should be on its own line, but got '") + 7784 (write-buffered *(ebp+0x18) "'{' or '}' should be on its own line, but got '") + 7785 (rewind-stream %ecx) + 7786 (write-stream-data *(ebp+0x18) %ecx) + 7787 (write-buffered *(ebp+0x18) "'\n") + 7788 (flush *(ebp+0x18)) + 7789 (stop *(ebp+0x1c) 1) + 7790 # never gets here + 7791 + 7792 new-block-name: # fn: (addr function), out: (addr handle var) + 7793 # . prologue + 7794 55/push-ebp + 7795 89/<- %ebp 4/r32/esp + 7796 # . save registers + 7797 50/push-eax + 7798 51/push-ecx + 7799 52/push-edx + 7800 # var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:' + 7801 8b/-> *(ebp+8) 0/r32/eax + 7802 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 7803 8b/-> *eax 0/r32/eax # String-size + 7804 05/add-to-eax 0xd/imm32 # 10 + 2 for '$:' + 7805 89/<- %ecx 0/r32/eax + 7806 # var name/edx: (stream byte n) + 7807 29/subtract-from %esp 1/r32/ecx + 7808 ff 6/subop/push %ecx + 7809 68/push 0/imm32/read + 7810 68/push 0/imm32/write + 7811 89/<- %edx 4/r32/esp + 7812 (clear-stream %edx) + 7813 # eax = fn->name + 7814 8b/-> *(ebp+8) 0/r32/eax + 7815 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 7816 # construct result using Next-block-index (and increment it) + 7817 (write %edx "$") + 7818 (write %edx %eax) + 7819 (write %edx ":") + 7820 (print-int32 %edx *Next-block-index) + 7821 ff 0/subop/increment *Next-block-index + 7822 # var s/eax: slice = {name->data, name->data + name->write} (clobbering edx) + 7823 # . eax = name->write + 7824 8b/-> *edx 0/r32/eax + 7825 # . edx = name->data + 7826 8d/copy-address *(edx+0xc) 2/r32/edx + 7827 # . eax = name->write + name->data + 7828 01/add-to %eax 2/r32/edx + 7829 # . push {edx, eax} + 7830 ff 6/subop/push %eax + 7831 ff 6/subop/push %edx + 7832 89/<- %eax 4/r32/esp + 7833 # out = new literal(s) + 7834 (new-literal Heap %eax *(ebp+0xc)) + 7835 #? 8b/-> *(ebp+0xc) 0/r32/eax + 7836 #? (write-buffered Stderr "type allocid in caller after new-literal: ") + 7837 #? (print-int32-buffered Stderr *(eax+8)) + 7838 #? (write-buffered Stderr " for var ") + 7839 #? (print-int32-buffered Stderr %eax) + 7840 #? (write-buffered Stderr Newline) + 7841 #? (flush Stderr) + 7842 $new-block-name:end: + 7843 # . reclaim locals + 7844 81 0/subop/add %ecx 0xc/imm32 # name.{read/write/len} + 7845 81 0/subop/add %ecx 8/imm32 # slice + 7846 01/add-to %esp 1/r32/ecx + 7847 # . restore registers + 7848 5a/pop-to-edx + 7849 59/pop-to-ecx + 7850 58/pop-to-eax + 7851 # . epilogue + 7852 89/<- %esp 5/r32/ebp + 7853 5d/pop-to-ebp + 7854 c3/return + 7855 + 7856 check-no-tokens-left: # line: (addr stream byte) + 7857 # . prologue + 7858 55/push-ebp + 7859 89/<- %ebp 4/r32/esp + 7860 # . save registers + 7861 50/push-eax + 7862 51/push-ecx + 7863 # var s/ecx: slice + 7864 68/push 0/imm32/end + 7865 68/push 0/imm32/start + 7866 89/<- %ecx 4/r32/esp + 7867 # + 7868 (next-mu-token *(ebp+8) %ecx) + 7869 # if slice-empty?(s) return + 7870 (slice-empty? %ecx) + 7871 3d/compare-eax-and 0/imm32/false + 7872 75/jump-if-!= $check-no-tokens-left:end/disp8 + 7873 # if (slice-starts-with?(s, '#') return + 7874 # . eax = *s->start + 7875 8b/-> *edx 0/r32/eax + 7876 8a/copy-byte *eax 0/r32/AL + 7877 81 4/subop/and %eax 0xff/imm32 + 7878 # . if (eax == '#') continue + 7879 3d/compare-eax-and 0x23/imm32/hash + 7880 74/jump-if-= $check-no-tokens-left:end/disp8 + 7881 # abort + 7882 (write-buffered Stderr "'{' or '}' should be on its own line, but got '") + 7883 (rewind-stream %ecx) + 7884 (write-stream 2 %ecx) + 7885 (write-buffered Stderr "'\n") + 7886 (flush Stderr) + 7887 # . syscall(exit, 1) + 7888 bb/copy-to-ebx 1/imm32 + 7889 e8/call syscall_exit/disp32 + 7890 # never gets here + 7891 $check-no-tokens-left:end: + 7892 # . reclaim locals + 7893 81 0/subop/add %esp 8/imm32 + 7894 # . restore registers + 7895 59/pop-to-ecx + 7896 58/pop-to-eax + 7897 # . epilogue + 7898 89/<- %esp 5/r32/ebp + 7899 5d/pop-to-ebp + 7900 c3/return + 7901 + 7902 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) + 7903 # pseudocode: + 7904 # var v: (handle var) + 7905 # new-literal(name, v) + 7906 # push(vars, {v, false}) + 7907 # parse-mu-block(in, vars, fn, out) + 7908 # pop(vars) + 7909 # out->tag = block + 7910 # out->var = v + 7911 # + 7912 # . prologue + 7913 55/push-ebp + 7914 89/<- %ebp 4/r32/esp + 7915 # . save registers + 7916 50/push-eax + 7917 51/push-ecx + 7918 57/push-edi + 7919 # var v/ecx: (handle var) + 7920 68/push 0/imm32 + 7921 68/push 0/imm32 + 7922 89/<- %ecx 4/r32/esp + 7923 # + 7924 (new-literal Heap *(ebp+8) %ecx) + 7925 # push(vars, v) + 7926 (push *(ebp+0x10) *ecx) + 7927 (push *(ebp+0x10) *(ecx+4)) + 7928 (push *(ebp+0x10) 0) # false + 7929 # + 7930 (parse-mu-block *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20)) + 7931 # pop v off vars + 7932 (pop *(ebp+0x10)) # => eax + 7933 (pop *(ebp+0x10)) # => eax + 7934 (pop *(ebp+0x10)) # => eax + 7935 # var out-addr/edi: (addr stmt) = lookup(*out) + 7936 8b/-> *(ebp+0x18) 7/r32/edi + 7937 (lookup *edi *(edi+4)) # => eax + 7938 89/<- %edi 0/r32/eax + 7939 # out-addr->tag = named-block + 7940 c7 0/subop/copy *edi 0/imm32/block # Stmt-tag + 7941 # out-addr->var = v + 7942 8b/-> *ecx 0/r32/eax + 7943 89/<- *(edi+0xc) 0/r32/eax # Block-var + 7944 8b/-> *(ecx+4) 0/r32/eax + 7945 89/<- *(edi+0x10) 0/r32/eax # Block-var + 7946 $parse-mu-named-block:end: + 7947 # . reclaim locals + 7948 81 0/subop/add %esp 8/imm32 + 7949 # . restore registers + 7950 5f/pop-to-edi + 7951 59/pop-to-ecx + 7952 58/pop-to-eax + 7953 # . epilogue + 7954 89/<- %esp 5/r32/ebp + 7955 5d/pop-to-ebp + 7956 c3/return + 7957 + 7958 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) + 7959 # . prologue + 7960 55/push-ebp + 7961 89/<- %ebp 4/r32/esp + 7962 # . save registers + 7963 50/push-eax + 7964 51/push-ecx + 7965 52/push-edx + 7966 53/push-ebx + 7967 57/push-edi + 7968 # edi = out + 7969 8b/-> *(ebp+0x10) 7/r32/edi + 7970 # var word-slice/ecx: slice + 7971 68/push 0/imm32/end + 7972 68/push 0/imm32/start + 7973 89/<- %ecx 4/r32/esp + 7974 # var v/edx: (handle var) + 7975 68/push 0/imm32 + 7976 68/push 0/imm32 + 7977 89/<- %edx 4/r32/esp + 7978 # v = parse-var-with-type(next-mu-token(line)) + 7979 (next-mu-token *(ebp+8) %ecx) + 7980 (parse-var-with-type %ecx *(ebp+8) %edx *(ebp+0x18) *(ebp+0x1c)) + 7981 # var v-addr/eax: (addr var) + 7982 (lookup *edx *(edx+4)) # => eax + 7983 # v->block-depth = *Curr-block-depth + 7984 8b/-> *Curr-block-depth 3/r32/ebx + 7985 89/<- *(eax+0x10) 3/r32/ebx # Var-block-depth + 7986 # either v has no register and there's no more to this line + 7987 8b/-> *(eax+0x18) 0/r32/eax # Var-register + 7988 3d/compare-eax-and 0/imm32 + 7989 { + 7990 75/jump-if-!= break/disp8 + 7991 # TODO: disallow vars of type 'byte' on the stack + 7992 # ensure that there's nothing else on this line + 7993 (next-mu-token *(ebp+8) %ecx) + 7994 (slice-empty? %ecx) # => eax + 7995 3d/compare-eax-and 0/imm32/false + 7996 0f 84/jump-if-= $parse-mu-var-def:error2/disp32 + 7997 # + 7998 (new-var-def Heap *edx *(edx+4) %edi) + 7999 e9/jump $parse-mu-var-def:update-vars/disp32 + 8000 } + 8001 # or v has a register and there's more to this line + 8002 { + 8003 0f 84/jump-if-= break/disp32 + 8004 # TODO: disallow vars of type 'byte' in registers 'esi' or 'edi' + 8005 # TODO: vars of type 'byte' should only be initialized by clearing to 0 + 8006 # ensure that the next word is '<-' + 8007 (next-mu-token *(ebp+8) %ecx) + 8008 (slice-equal? %ecx "<-") # => eax + 8009 3d/compare-eax-and 0/imm32/false + 8010 0f 84/jump-if-= $parse-mu-var-def:error1/disp32 + 8011 # + 8012 (new-reg-var-def Heap *edx *(edx+4) %edi) + 8013 (lookup *edi *(edi+4)) # => eax + 8014 (add-operation-and-inputs-to-stmt %eax *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) + 8015 } + 8016 $parse-mu-var-def:update-vars: + 8017 # push 'v' at end of function + 8018 (push *(ebp+0xc) *edx) + 8019 (push *(ebp+0xc) *(edx+4)) + 8020 (push *(ebp+0xc) 0) # Live-var-register-spilled is unused during parsing + 8021 $parse-mu-var-def:end: + 8022 # . reclaim locals + 8023 81 0/subop/add %esp 0x10/imm32 + 8024 # . restore registers + 8025 5f/pop-to-edi + 8026 5b/pop-to-ebx + 8027 5a/pop-to-edx + 8028 59/pop-to-ecx + 8029 58/pop-to-eax + 8030 # . epilogue + 8031 89/<- %esp 5/r32/ebp + 8032 5d/pop-to-ebp + 8033 c3/return + 8034 + 8035 $parse-mu-var-def:error1: + 8036 (rewind-stream *(ebp+8)) + 8037 # error("register variable requires a valid instruction to initialize but got '" line "'\n") + 8038 (write-buffered *(ebp+0x18) "register variable requires a valid instruction to initialize but got '") + 8039 (flush *(ebp+0x18)) + 8040 (write-stream-data *(ebp+0x18) *(ebp+8)) + 8041 (write-buffered *(ebp+0x18) "'\n") + 8042 (flush *(ebp+0x18)) + 8043 (stop *(ebp+0x1c) 1) + 8044 # never gets here + 8045 + 8046 $parse-mu-var-def:error2: + 8047 (rewind-stream *(ebp+8)) + 8048 # error("fn " fn ": var " var ": variables on the stack can't take an initializer\n") + 8049 (write-buffered *(ebp+0x18) "fn ") + 8050 8b/-> *(ebp+0x14) 0/r32/eax + 8051 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 8052 (write-buffered *(ebp+0x18) %eax) + 8053 (write-buffered *(ebp+0x18) ": var ") + 8054 # var v-addr/eax: (addr var) = lookup(v) + 8055 (lookup *edx *(edx+4)) # => eax + 8056 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 8057 (write-buffered *(ebp+0x18) %eax) + 8058 (write-buffered *(ebp+0x18) ": variables on the stack can't take an initializer\n") + 8059 (flush *(ebp+0x18)) + 8060 (stop *(ebp+0x1c) 1) + 8061 # never gets here + 8062 + 8063 test-parse-mu-var-def: + 8064 # 'var n: int' + 8065 # . prologue + 8066 55/push-ebp + 8067 89/<- %ebp 4/r32/esp + 8068 # setup + 8069 (clear-stream _test-input-stream) + 8070 (write _test-input-stream "n: int\n") # caller has consumed the 'var' + 8071 c7 0/subop/copy *Curr-block-depth 1/imm32 + 8072 # var out/esi: (handle stmt) + 8073 68/push 0/imm32 + 8074 68/push 0/imm32 + 8075 89/<- %esi 4/r32/esp + 8076 # var vars/ecx: (stack (addr var) 16) + 8077 81 5/subop/subtract %esp 0xc0/imm32 + 8078 68/push 0xc0/imm32/size + 8079 68/push 0/imm32/top + 8080 89/<- %ecx 4/r32/esp + 8081 (clear-stack %ecx) + 8082 # convert + 8083 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) + 8084 # var out-addr/esi: (addr stmt) + 8085 (lookup *esi *(esi+4)) # => eax + 8086 89/<- %esi 0/r32/eax + 8087 # + 8088 (check-ints-equal *esi 2 "F - test-parse-mu-var-def/tag") # Stmt-tag is var-def + 8089 # var v/ecx: (addr var) = lookup(out->var) + 8090 (lookup *(esi+4) *(esi+8)) # Vardef-var Vardef-var => eax + 8091 89/<- %ecx 0/r32/eax + 8092 # v->name + 8093 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax + 8094 (check-strings-equal %eax "n" "F - test-parse-mu-var-def/var-name") + 8095 # v->register + 8096 (check-ints-equal *(ecx+0x18) 0 "F - test-parse-mu-var-def/var-register") # Var-register + 8097 # v->block-depth + 8098 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-var-def/output-block-depth") # Var-block-depth + 8099 # v->type == int + 8100 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 8101 (check-ints-equal *eax 1 "F - test-parse-mu-var-def/var-type:0") # Tree-is-atom + 8102 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-var-def/var-type:1") # Tree-value + 8103 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-var-def/var-type:2") # Tree-right + 8104 # . epilogue + 8105 89/<- %esp 5/r32/ebp + 8106 5d/pop-to-ebp + 8107 c3/return + 8108 + 8109 test-parse-mu-reg-var-def: + 8110 # 'var n/eax: int <- copy 0' + 8111 # . prologue + 8112 55/push-ebp + 8113 89/<- %ebp 4/r32/esp + 8114 # setup + 8115 (clear-stream _test-input-stream) + 8116 (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var' + 8117 c7 0/subop/copy *Curr-block-depth 1/imm32 + 8118 # var out/esi: (handle stmt) + 8119 68/push 0/imm32 + 8120 68/push 0/imm32 + 8121 89/<- %esi 4/r32/esp + 8122 # var vars/ecx: (stack (addr var) 16) + 8123 81 5/subop/subtract %esp 0xc0/imm32 + 8124 68/push 0xc0/imm32/size + 8125 68/push 0/imm32/top + 8126 89/<- %ecx 4/r32/esp + 8127 (clear-stack %ecx) + 8128 # convert + 8129 (parse-mu-var-def _test-input-stream %ecx %esi 0 Stderr 0) + 8130 # var out-addr/esi: (addr stmt) + 8131 (lookup *esi *(esi+4)) # => eax + 8132 89/<- %esi 0/r32/eax + 8133 # + 8134 (check-ints-equal *esi 3 "F - test-parse-mu-reg-var-def/tag") # Stmt-tag is reg-var-def + 8135 # var v/ecx: (addr var) = lookup(out->outputs->value) + 8136 # . eax: (addr stmt-var) = lookup(out->outputs) + 8137 (lookup *(esi+0x14) *(esi+0x18)) # Regvardef-outputs Regvardef-outputs => eax + 8138 # . + 8139 (check-ints-equal *(eax+8) 0 "F - test-parse-mu-reg-var-def/single-output") # Stmt-var-next + 8140 # . eax: (addr var) = lookup(eax->value) + 8141 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 8142 # . ecx = eax + 8143 89/<- %ecx 0/r32/eax + 8144 # v->name + 8145 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax + 8146 (check-strings-equal %eax "n" "F - test-parse-mu-reg-var-def/output-name") # Var-name + 8147 # v->register + 8148 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax + 8149 (check-strings-equal %eax "eax" "F - test-parse-mu-reg-var-def/output-register") + 8150 # v->block-depth + 8151 (check-ints-equal *(ecx+0x10) 1 "F - test-parse-mu-reg-var-def/output-block-depth") # Var-block-depth + 8152 # v->type == int + 8153 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 8154 (check-ints-equal *eax 1 "F - test-parse-mu-reg-var-def/output-type:0") # Tree-is-atom + 8155 (check-ints-equal *(eax+4) 1 "F - test-parse-mu-reg-var-def/output-type:1") # Tree-value + 8156 (check-ints-equal *(eax+0xc) 0 "F - test-parse-mu-reg-var-def/output-type:2") # Tree-right + 8157 # . epilogue + 8158 89/<- %esp 5/r32/ebp + 8159 5d/pop-to-ebp + 8160 c3/return + 8161 + 8162 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) + 8163 # Carefully push any outputs on the vars stack _after_ reading the inputs + 8164 # that may conflict with them. + 8165 # + 8166 # The only situation in which outputs are pushed here (when it's not a + 8167 # 'var' vardef stmt), and so can possibly conflict with inputs, is if the + 8168 # output is a function output. + 8169 # + 8170 # pseudocode: + 8171 # var name: slice + 8172 # allocate(Heap, Stmt-size, out) + 8173 # var out-addr: (addr stmt) = lookup(*out) + 8174 # out-addr->tag = stmt + 8175 # if stmt-has-outputs?(line) + 8176 # while true + 8177 # name = next-mu-token(line) + 8178 # if (name == '<-') break + 8179 # assert(is-identifier?(name)) + 8180 # var v: (handle var) = lookup-var-or-find-in-fn-outputs(name, vars, fn) + 8181 # out-addr->outputs = append(v, out-addr->outputs) + 8182 # add-operation-and-inputs-to-stmt(out-addr, line, vars) + 8183 # for output in stmt->outputs: + 8184 # maybe-define-var(output, vars) + 8185 # + 8186 # . prologue + 8187 55/push-ebp + 8188 89/<- %ebp 4/r32/esp + 8189 # . save registers + 8190 50/push-eax + 8191 51/push-ecx + 8192 52/push-edx + 8193 53/push-ebx + 8194 57/push-edi + 8195 # var name/ecx: slice + 8196 68/push 0/imm32/end + 8197 68/push 0/imm32/start + 8198 89/<- %ecx 4/r32/esp + 8199 # var is-deref?/edx: boolean = false + 8200 ba/copy-to-edx 0/imm32/false + 8201 # var v: (handle var) + 8202 68/push 0/imm32 + 8203 68/push 0/imm32 + 8204 89/<- %ebx 4/r32/esp + 8205 # + 8206 (allocate Heap *Stmt-size *(ebp+0x14)) + 8207 # var out-addr/edi: (addr stmt) = lookup(*out) + 8208 8b/-> *(ebp+0x14) 7/r32/edi + 8209 (lookup *edi *(edi+4)) # => eax + 8210 89/<- %edi 0/r32/eax + 8211 # out-addr->tag = 1/stmt + 8212 c7 0/subop/copy *edi 1/imm32/stmt1 # Stmt-tag + 8213 { + 8214 (stmt-has-outputs? *(ebp+8)) + 8215 3d/compare-eax-and 0/imm32/false + 8216 0f 84/jump-if-= break/disp32 + 8217 { + 8218 $parse-mu-stmt:read-outputs: + 8219 # name = next-mu-token(line) + 8220 (next-mu-token *(ebp+8) %ecx) + 8221 # if slice-empty?(word-slice) break + 8222 (slice-empty? %ecx) # => eax + 8223 3d/compare-eax-and 0/imm32/false + 8224 0f 85/jump-if-!= break/disp32 + 8225 # if (name == "<-") break + 8226 (slice-equal? %ecx "<-") # => eax + 8227 3d/compare-eax-and 0/imm32/false + 8228 0f 85/jump-if-!= break/disp32 + 8229 # is-deref? = false + 8230 ba/copy-to-edx 0/imm32/false + 8231 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? + 8232 8b/-> *ecx 0/r32/eax # Slice-start + 8233 8a/copy-byte *eax 0/r32/AL + 8234 81 4/subop/and %eax 0xff/imm32 + 8235 3d/compare-eax-and 0x2a/imm32/asterisk + 8236 { + 8237 75/jump-if-!= break/disp8 + 8238 ff 0/subop/increment *ecx + 8239 ba/copy-to-edx 1/imm32/true + 8240 } + 8241 # assert(is-identifier?(name)) + 8242 (is-identifier? %ecx) # => eax + 8243 3d/compare-eax-and 0/imm32/false + 8244 0f 84/jump-if-= $parse-mu-stmt:abort/disp32 + 8245 # + 8246 (lookup-var-or-find-in-fn-outputs %ecx *(ebp+0xc) *(ebp+0x10) %ebx *(ebp+0x18) *(ebp+0x1c)) + 8247 8d/copy-address *(edi+0x14) 0/r32/eax # Stmt1-outputs + 8248 (append-stmt-var Heap *ebx *(ebx+4) *(edi+0x14) *(edi+0x18) %edx %eax) # Stmt1-outputs + 8249 # + 8250 e9/jump loop/disp32 + 8251 } + 8252 } + 8253 (add-operation-and-inputs-to-stmt %edi *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) + 8254 $parse-mu-stmt:define-outputs: + 8255 # var output/edi: (addr stmt-var) = lookup(out-addr->outputs) + 8256 (lookup *(edi+0x14) *(edi+0x18)) # Stmt1-outputs Stmt1-outputs => eax + 8257 89/<- %edi 0/r32/eax + 8258 { + 8259 $parse-mu-stmt:define-outputs-loop: + 8260 # if (output == null) break + 8261 81 7/subop/compare %edi 0/imm32 + 8262 74/jump-if-= break/disp8 + 8263 # + 8264 (maybe-define-var *edi *(edi+4) *(ebp+0xc)) # if output is a deref, then it's already been defined, + 8265 # and must be in vars. This call will be a no-op, but safe. + 8266 # output = output->next + 8267 (lookup *(edi+8) *(edi+0xc)) # Stmt-var-next Stmt-var-next => eax + 8268 89/<- %edi 0/r32/eax + 8269 # + 8270 eb/jump loop/disp8 + 8271 } + 8272 $parse-mu-stmt:end: + 8273 # . reclaim locals + 8274 81 0/subop/add %esp 0x10/imm32 + 8275 # . restore registers + 8276 5f/pop-to-edi + 8277 5b/pop-to-ebx + 8278 5a/pop-to-edx + 8279 59/pop-to-ecx + 8280 58/pop-to-eax + 8281 # . epilogue + 8282 89/<- %esp 5/r32/ebp + 8283 5d/pop-to-ebp + 8284 c3/return + 8285 + 8286 $parse-mu-stmt:abort: + 8287 # error("invalid identifier '" name "'\n") + 8288 (write-buffered *(ebp+0x18) "invalid identifier '") + 8289 (write-slice-buffered *(ebp+0x18) %ecx) + 8290 (write-buffered *(ebp+0x18) "'\n") + 8291 (flush *(ebp+0x18)) + 8292 (stop *(ebp+0x1c) 1) + 8293 # never gets here + 8294 + 8295 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) + 8296 # pseudocode: + 8297 # stmt->name = slice-to-string(next-mu-token(line)) + 8298 # while true + 8299 # name = next-mu-token(line) + 8300 # v = lookup-var-or-literal(name) + 8301 # stmt->inouts = append(v, stmt->inouts) + 8302 # + 8303 # . prologue + 8304 55/push-ebp + 8305 89/<- %ebp 4/r32/esp + 8306 # . save registers + 8307 50/push-eax + 8308 51/push-ecx + 8309 52/push-edx + 8310 53/push-ebx + 8311 56/push-esi + 8312 57/push-edi + 8313 # edi = stmt + 8314 8b/-> *(ebp+8) 7/r32/edi + 8315 # var name/ecx: slice + 8316 68/push 0/imm32/end + 8317 68/push 0/imm32/start + 8318 89/<- %ecx 4/r32/esp + 8319 # var is-deref?/edx: boolean = false + 8320 ba/copy-to-edx 0/imm32/false + 8321 # var v/esi: (handle var) + 8322 68/push 0/imm32 + 8323 68/push 0/imm32 + 8324 89/<- %esi 4/r32/esp + 8325 $add-operation-and-inputs-to-stmt:read-operation: + 8326 (next-mu-token *(ebp+0xc) %ecx) + 8327 8d/copy-address *(edi+4) 0/r32/eax # Stmt1-operation or Regvardef-operationStmt1-operation or Regvardef-operation + 8328 (slice-to-string Heap %ecx %eax) + 8329 # var is-get?/ebx: boolean = (name == "get") + 8330 (slice-equal? %ecx "get") # => eax + 8331 89/<- %ebx 0/r32/eax + 8332 { + 8333 $add-operation-and-inputs-to-stmt:read-inouts: + 8334 # name = next-mu-token(line) + 8335 (next-mu-token *(ebp+0xc) %ecx) + 8336 # if slice-empty?(word-slice) break + 8337 (slice-empty? %ecx) # => eax + 8338 3d/compare-eax-and 0/imm32/false + 8339 0f 85/jump-if-!= break/disp32 + 8340 # if (name == "<-") abort + 8341 (slice-equal? %ecx "<-") + 8342 3d/compare-eax-and 0/imm32/false + 8343 0f 85/jump-if-!= $add-operation-and-inputs-to-stmt:abort/disp32 + 8344 # if (is-get? && second operand) lookup or create offset + 8345 { + 8346 81 7/subop/compare %ebx 0/imm32/false + 8347 74/jump-if-= break/disp8 + 8348 (lookup *(edi+0xc) *(edi+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 8349 3d/compare-eax-and 0/imm32 + 8350 74/jump-if-= break/disp8 + 8351 (lookup-or-create-constant %eax %ecx %esi) + 8352 #? (lookup *esi *(esi+4)) + 8353 #? (write-buffered Stderr "creating new output var ") + 8354 #? (print-int32-buffered Stderr %eax) + 8355 #? (write-buffered Stderr " for field called ") + 8356 #? (write-slice-buffered Stderr %ecx) + 8357 #? (write-buffered Stderr "; var name ") + 8358 #? (lookup *eax *(eax+4)) # Var-name + 8359 #? (write-buffered Stderr %eax) + 8360 #? (write-buffered Stderr Newline) + 8361 #? (flush Stderr) + 8362 e9/jump $add-operation-and-inputs-to-stmt:save-var/disp32 + 8363 } + 8364 # is-deref? = false + 8365 ba/copy-to-edx 0/imm32/false + 8366 # if (slice-starts-with?(name, '*')) ++name->start and set is-deref? + 8367 8b/-> *ecx 0/r32/eax # Slice-start + 8368 8a/copy-byte *eax 0/r32/AL + 8369 81 4/subop/and %eax 0xff/imm32 + 8370 3d/compare-eax-and 0x2a/imm32/asterisk + 8371 { + 8372 75/jump-if-!= break/disp8 + 8373 $add-operation-and-inputs-to-stmt:inout-is-deref: + 8374 ff 0/subop/increment *ecx + 8375 ba/copy-to-edx 1/imm32/true + 8376 } + 8377 (lookup-var-or-literal %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) + 8378 $add-operation-and-inputs-to-stmt:save-var: + 8379 8d/copy-address *(edi+0xc) 0/r32/eax + 8380 (append-stmt-var Heap *esi *(esi+4) *(edi+0xc) *(edi+0x10) %edx %eax) # Stmt1-inouts or Regvardef-inouts + 8381 # + 8382 e9/jump loop/disp32 + 8383 } + 8384 $add-operation-and-inputs-to-stmt:end: + 8385 # . reclaim locals + 8386 81 0/subop/add %esp 0x10/imm32 + 8387 # . restore registers + 8388 5f/pop-to-edi + 8389 5e/pop-to-esi + 8390 5b/pop-to-ebx + 8391 5a/pop-to-edx + 8392 59/pop-to-ecx + 8393 58/pop-to-eax + 8394 # . epilogue + 8395 89/<- %esp 5/r32/ebp + 8396 5d/pop-to-ebp + 8397 c3/return + 8398 + 8399 $add-operation-and-inputs-to-stmt:abort: + 8400 # error("fn ___: invalid identifier in '" line "'\n") + 8401 (write-buffered *(ebp+0x18) "fn ") + 8402 8b/-> *(ebp+0x14) 0/r32/eax + 8403 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 8404 (write-buffered *(ebp+0x18) %eax) + 8405 (rewind-stream *(ebp+0xc)) + 8406 (write-buffered *(ebp+0x18) ": invalid identifier in '") + 8407 (write-stream-data *(ebp+0x18) *(ebp+0xc)) + 8408 (write-buffered *(ebp+0x18) "'\n") + 8409 (flush *(ebp+0x18)) + 8410 (stop *(ebp+0x1c) 1) + 8411 # never gets here + 8412 + 8413 stmt-has-outputs?: # line: (addr stream byte) -> result/eax: boolean + 8414 # . prologue + 8415 55/push-ebp + 8416 89/<- %ebp 4/r32/esp + 8417 # . save registers + 8418 51/push-ecx + 8419 # var word-slice/ecx: slice + 8420 68/push 0/imm32/end + 8421 68/push 0/imm32/start + 8422 89/<- %ecx 4/r32/esp + 8423 # result = false + 8424 b8/copy-to-eax 0/imm32/false + 8425 (rewind-stream *(ebp+8)) + 8426 { + 8427 (next-mu-token *(ebp+8) %ecx) + 8428 # if slice-empty?(word-slice) break + 8429 (slice-empty? %ecx) + 8430 3d/compare-eax-and 0/imm32/false + 8431 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) + 8432 0f 85/jump-if-!= break/disp32 + 8433 # if slice-starts-with?(word-slice, '#') break + 8434 # . eax = *word-slice->start + 8435 8b/-> *ecx 0/r32/eax + 8436 8a/copy-byte *eax 0/r32/AL + 8437 81 4/subop/and %eax 0xff/imm32 + 8438 # . if (eax == '#') break + 8439 3d/compare-eax-and 0x23/imm32/hash + 8440 b8/copy-to-eax 0/imm32/false/result # restore result (if we're here it's still false) + 8441 0f 84/jump-if-= break/disp32 + 8442 # if slice-equal?(word-slice, '<-') return true + 8443 (slice-equal? %ecx "<-") + 8444 3d/compare-eax-and 0/imm32/false + 8445 74/jump-if-= loop/disp8 + 8446 b8/copy-to-eax 1/imm32/true + 8447 } + 8448 $stmt-has-outputs:end: + 8449 (rewind-stream *(ebp+8)) + 8450 # . reclaim locals + 8451 81 0/subop/add %esp 8/imm32 + 8452 # . restore registers + 8453 59/pop-to-ecx + 8454 # . epilogue + 8455 89/<- %esp 5/r32/ebp + 8456 5d/pop-to-ebp + 8457 c3/return + 8458 + 8459 # if 'name' starts with a digit, create a new literal var for it + 8460 # otherwise return first 'name' from the top (back) of 'vars' and abort if not found + 8461 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) + 8462 # . prologue + 8463 55/push-ebp + 8464 89/<- %ebp 4/r32/esp + 8465 # . save registers + 8466 50/push-eax + 8467 51/push-ecx + 8468 56/push-esi + 8469 # esi = name + 8470 8b/-> *(ebp+8) 6/r32/esi + 8471 # if slice-empty?(name) abort + 8472 (slice-empty? %esi) # => eax + 8473 3d/compare-eax-and 0/imm32/false + 8474 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32 + 8475 # var c/ecx: byte = *name->start + 8476 8b/-> *esi 1/r32/ecx + 8477 8a/copy-byte *ecx 1/r32/CL + 8478 81 4/subop/and %ecx 0xff/imm32 + 8479 # if is-decimal-digit?(c) return new var(name) + 8480 { + 8481 (is-decimal-digit? %ecx) # => eax + 8482 3d/compare-eax-and 0/imm32/false + 8483 74/jump-if-= break/disp8 + 8484 $lookup-var-or-literal:literal: + 8485 (new-literal-integer Heap %esi *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) + 8486 eb/jump $lookup-var-or-literal:end/disp8 + 8487 } + 8488 # else if (c == '"') return new var(name) + 8489 { + 8490 81 7/subop/compare %ecx 0x22/imm32/dquote + 8491 75/jump-if-!= break/disp8 + 8492 $lookup-var-or-literal:literal-string: + 8493 (new-literal Heap %esi *(ebp+0x10)) + 8494 eb/jump $lookup-var-or-literal:end/disp8 + 8495 } + 8496 # otherwise return lookup-var(name, vars) + 8497 { + 8498 $lookup-var-or-literal:var: + 8499 (lookup-var %esi *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) + 8500 } + 8501 $lookup-var-or-literal:end: + 8502 # . restore registers + 8503 5e/pop-to-esi + 8504 59/pop-to-ecx + 8505 58/pop-to-eax + 8506 # . epilogue + 8507 89/<- %esp 5/r32/ebp + 8508 5d/pop-to-ebp + 8509 c3/return + 8510 + 8511 $lookup-var-or-literal:abort: + 8512 (write-buffered *(ebp+0x18) "fn ") + 8513 8b/-> *(ebp+0x14) 0/r32/eax + 8514 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 8515 (write-buffered *(ebp+0x18) %eax) + 8516 (write-buffered *(ebp+0x18) ": empty variable!") + 8517 (flush *(ebp+0x18)) + 8518 (stop *(ebp+0x1c) 1) + 8519 # never gets here + 8520 + 8521 # return first 'name' from the top (back) of 'vars' and abort if not found + 8522 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) + 8523 # . prologue + 8524 55/push-ebp + 8525 89/<- %ebp 4/r32/esp + 8526 # . save registers + 8527 50/push-eax + 8528 # + 8529 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) + 8530 # if (*out == 0) abort + 8531 8b/-> *(ebp+0x10) 0/r32/eax + 8532 81 7/subop/compare *eax 0/imm32 + 8533 74/jump-if-= $lookup-var:abort/disp8 + 8534 $lookup-var:end: + 8535 # . restore registers + 8536 58/pop-to-eax + 8537 # . epilogue + 8538 89/<- %esp 5/r32/ebp + 8539 5d/pop-to-ebp + 8540 c3/return + 8541 + 8542 $lookup-var:abort: + 8543 (write-buffered *(ebp+0x18) "fn ") + 8544 8b/-> *(ebp+0x14) 0/r32/eax + 8545 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 8546 (write-buffered *(ebp+0x18) %eax) + 8547 (write-buffered *(ebp+0x18) ": unknown variable '") + 8548 (write-slice-buffered *(ebp+0x18) *(ebp+8)) + 8549 (write-buffered *(ebp+0x18) "'\n") + 8550 (flush *(ebp+0x18)) + 8551 (stop *(ebp+0x1c) 1) + 8552 # never gets here + 8553 + 8554 # return first 'name' from the top (back) of 'vars', and 0/null if not found + 8555 # ensure that 'name' if in a register is the topmost variable in that register + 8556 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) + 8557 # pseudocode: + 8558 # var curr: (addr handle var) = &vars->data[vars->top - 12] + 8559 # var min = vars->data + 8560 # while curr >= min + 8561 # var v: (handle var) = *curr + 8562 # if v->name == name + 8563 # return + 8564 # curr -= 12 + 8565 # + 8566 # . prologue + 8567 55/push-ebp + 8568 89/<- %ebp 4/r32/esp + 8569 # . save registers + 8570 50/push-eax + 8571 51/push-ecx + 8572 52/push-edx + 8573 53/push-ebx + 8574 56/push-esi + 8575 57/push-edi + 8576 # clear out + 8577 (zero-out *(ebp+0x10) *Handle-size) + 8578 # esi = vars + 8579 8b/-> *(ebp+0xc) 6/r32/esi + 8580 # ebx = vars->top + 8581 8b/-> *esi 3/r32/ebx + 8582 # if (vars->top > vars->size) abort + 8583 3b/compare<- *(esi+4) 0/r32/eax + 8584 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 + 8585 # var min/edx: (addr handle var) = vars->data + 8586 8d/copy-address *(esi+8) 2/r32/edx + 8587 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] + 8588 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 + 8589 # var var-in-reg/edi: 8 addrs + 8590 68/push 0/imm32 + 8591 68/push 0/imm32 + 8592 68/push 0/imm32 + 8593 68/push 0/imm32 + 8594 68/push 0/imm32 + 8595 68/push 0/imm32 + 8596 68/push 0/imm32 + 8597 68/push 0/imm32 + 8598 89/<- %edi 4/r32/esp + 8599 { + 8600 $lookup-var-helper:loop: + 8601 # if (curr < min) return + 8602 39/compare %ebx 2/r32/edx + 8603 0f 82/jump-if-addr< break/disp32 + 8604 # var v/ecx: (addr var) = lookup(*curr) + 8605 (lookup *ebx *(ebx+4)) # => eax + 8606 89/<- %ecx 0/r32/eax + 8607 # var vn/eax: (addr array byte) = lookup(v->name) + 8608 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax + 8609 # if (vn == name) return curr + 8610 (slice-equal? *(ebp+8) %eax) # => eax + 8611 3d/compare-eax-and 0/imm32/false + 8612 { + 8613 74/jump-if-= break/disp8 + 8614 $lookup-var-helper:found: + 8615 # var vr/eax: (addr array byte) = lookup(v->register) + 8616 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax + 8617 3d/compare-eax-and 0/imm32 + 8618 { + 8619 74/jump-if-= break/disp8 + 8620 $lookup-var-helper:found-register: + 8621 # var reg/eax: int = get(Registers, vr) + 8622 (get Mu-registers %eax 0xc "Mu-registers") # => eax + 8623 8b/-> *eax 0/r32/eax + 8624 # if (var-in-reg[reg]) error + 8625 8b/-> *(edi+eax<<2) 0/r32/eax + 8626 3d/compare-eax-and 0/imm32 + 8627 0f 85/jump-if-!= $lookup-var-helper:error2/disp32 + 8628 } + 8629 $lookup-var-helper:return: + 8630 # esi = out + 8631 8b/-> *(ebp+0x10) 6/r32/esi + 8632 # *out = *curr + 8633 8b/-> *ebx 0/r32/eax + 8634 89/<- *esi 0/r32/eax + 8635 8b/-> *(ebx+4) 0/r32/eax + 8636 89/<- *(esi+4) 0/r32/eax + 8637 # return + 8638 eb/jump $lookup-var-helper:end/disp8 + 8639 } + 8640 # 'name' not yet found; update var-in-reg if v in register + 8641 # . var vr/eax: (addr array byte) = lookup(v->register) + 8642 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax + 8643 # . if (var == 0) continue + 8644 3d/compare-eax-and 0/imm32 + 8645 74/jump-if-= $lookup-var-helper:continue/disp8 + 8646 # . var reg/eax: int = get(Registers, vr) + 8647 (get Mu-registers %eax 0xc "Mu-registers") # => eax + 8648 8b/-> *eax 0/r32/eax + 8649 # . if (var-in-reg[reg] == 0) var-in-reg[reg] = v + 8650 81 7/subop/compare *(edi+eax<<2) 0/imm32 + 8651 75/jump-if-!= $lookup-var-helper:continue/disp8 + 8652 89/<- *(edi+eax<<2) 1/r32/ecx + 8653 $lookup-var-helper:continue: + 8654 # curr -= 12 + 8655 81 5/subop/subtract %ebx 0xc/imm32 + 8656 e9/jump loop/disp32 + 8657 } + 8658 $lookup-var-helper:end: + 8659 # . reclaim locals + 8660 81 0/subop/add %esp 0x20/imm32 + 8661 # . restore registers + 8662 5f/pop-to-edi + 8663 5e/pop-to-esi + 8664 5b/pop-to-ebx + 8665 5a/pop-to-edx + 8666 59/pop-to-ecx + 8667 58/pop-to-eax + 8668 # . epilogue + 8669 89/<- %esp 5/r32/ebp + 8670 5d/pop-to-ebp + 8671 c3/return + 8672 + 8673 $lookup-var-helper:error1: + 8674 (write-buffered *(ebp+0x18) "fn ") + 8675 8b/-> *(ebp+0x14) 0/r32/eax + 8676 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 8677 (write-buffered *(ebp+0x18) %eax) + 8678 (write-buffered *(ebp+0x18) ": malformed stack when looking up '") + 8679 (write-slice-buffered *(ebp+0x18) *(ebp+8)) + 8680 (write-buffered *(ebp+0x18) "'\n") + 8681 (flush *(ebp+0x18)) + 8682 (stop *(ebp+0x1c) 1) + 8683 # never gets here + 8684 + 8685 $lookup-var-helper:error2: + 8686 # eax contains the conflicting var at this point + 8687 (write-buffered *(ebp+0x18) "fn ") + 8688 50/push-eax + 8689 8b/-> *(ebp+0x14) 0/r32/eax + 8690 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 8691 (write-buffered *(ebp+0x18) %eax) + 8692 58/pop-eax + 8693 (write-buffered *(ebp+0x18) ": register ") + 8694 50/push-eax + 8695 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax + 8696 (write-buffered *(ebp+0x18) %eax) + 8697 58/pop-to-eax + 8698 (write-buffered *(ebp+0x18) " reads var '") + 8699 (write-slice-buffered *(ebp+0x18) *(ebp+8)) + 8700 (write-buffered *(ebp+0x18) "' after writing var '") + 8701 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 8702 (write-buffered *(ebp+0x18) %eax) + 8703 (write-buffered *(ebp+0x18) "'\n") + 8704 (flush *(ebp+0x18)) + 8705 (stop *(ebp+0x1c) 1) + 8706 # never gets here + 8707 + 8708 dump-vars: # vars: (addr stack live-var) + 8709 # pseudocode: + 8710 # var curr: (addr handle var) = &vars->data[vars->top - 12] + 8711 # var min = vars->data + 8712 # while curr >= min + 8713 # var v: (handle var) = *curr + 8714 # print v + 8715 # curr -= 12 + 8716 # + 8717 # . prologue + 8718 55/push-ebp + 8719 89/<- %ebp 4/r32/esp + 8720 # . save registers + 8721 52/push-edx + 8722 53/push-ebx + 8723 56/push-esi + 8724 # esi = vars + 8725 8b/-> *(ebp+8) 6/r32/esi + 8726 # ebx = vars->top + 8727 8b/-> *esi 3/r32/ebx + 8728 # var min/edx: (addr handle var) = vars->data + 8729 8d/copy-address *(esi+8) 2/r32/edx + 8730 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 12] + 8731 8d/copy-address *(esi+ebx-4) 3/r32/ebx # vars + 8 + vars->type - 12 + 8732 { + 8733 $dump-vars:loop: + 8734 # if (curr < min) return + 8735 39/compare %ebx 2/r32/edx + 8736 0f 82/jump-if-addr< break/disp32 + 8737 # + 8738 (write-buffered Stderr " var@") + 8739 (dump-var 2 %ebx) + 8740 # curr -= 12 + 8741 81 5/subop/subtract %ebx 0xc/imm32 + 8742 e9/jump loop/disp32 + 8743 } + 8744 $dump-vars:end: + 8745 # . restore registers + 8746 5e/pop-to-esi + 8747 5b/pop-to-ebx + 8748 5a/pop-to-edx + 8749 # . epilogue + 8750 89/<- %esp 5/r32/ebp + 8751 5d/pop-to-ebp + 8752 c3/return + 8753 + 8754 == data + 8755 # Like Registers, but no esp or ebp + 8756 Mu-registers: # (addr stream {(handle array byte), int}) + 8757 # a table is a stream + 8758 0x48/imm32/write + 8759 0/imm32/read + 8760 0x48/imm32/length + 8761 # data + 8762 # it is perfectly ok to use fake alloc-ids -- as long as you never try to reclaim them + 8763 0x11/imm32/alloc-id $Mu-register-eax/imm32 0/imm32 + 8764 0x11/imm32/alloc-id $Mu-register-ecx/imm32 1/imm32 + 8765 0x11/imm32/alloc-id $Mu-register-edx/imm32 2/imm32 + 8766 0x11/imm32/alloc-id $Mu-register-ebx/imm32 3/imm32 + 8767 0x11/imm32/alloc-id $Mu-register-esi/imm32 6/imm32 + 8768 0x11/imm32/alloc-id $Mu-register-edi/imm32 7/imm32 + 8769 + 8770 $Mu-register-eax: + 8771 0x11/imm32/alloc-id + 8772 3/imm32/size + 8773 0x65/e 0x61/a 0x78/x + 8774 + 8775 $Mu-register-ecx: + 8776 0x11/imm32/alloc-id + 8777 3/imm32/size + 8778 0x65/e 0x63/c 0x78/x + 8779 + 8780 $Mu-register-edx: + 8781 0x11/imm32/alloc-id + 8782 3/imm32/size + 8783 0x65/e 0x64/d 0x78/x + 8784 + 8785 $Mu-register-ebx: + 8786 0x11/imm32/alloc-id + 8787 3/imm32/size + 8788 0x65/e 0x62/b 0x78/x + 8789 + 8790 $Mu-register-esi: + 8791 0x11/imm32/alloc-id + 8792 3/imm32/size + 8793 0x65/e 0x73/s 0x69/i + 8794 + 8795 $Mu-register-edi: + 8796 0x11/imm32/alloc-id + 8797 3/imm32/size + 8798 0x65/e 0x64/d 0x69/i + 8799 + 8800 == code + 8801 + 8802 # return first 'name' from the top (back) of 'vars' and create a new var for a fn output if not found + 8803 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) + 8804 # . prologue + 8805 55/push-ebp + 8806 89/<- %ebp 4/r32/esp + 8807 # . save registers + 8808 50/push-eax + 8809 # + 8810 (lookup-var-helper *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x10) *(ebp+0x18) *(ebp+0x1c)) # arg order slightly different; 'fn' is deemphasized + 8811 { + 8812 # if (out != 0) return + 8813 8b/-> *(ebp+0x14) 0/r32/eax + 8814 81 7/subop/compare *eax 0/imm32 + 8815 75/jump-if-!= break/disp8 + 8816 # if name is one of fn's outputs, return it + 8817 (find-in-function-outputs *(ebp+0x10) *(ebp+8) *(ebp+0x14)) + 8818 8b/-> *(ebp+0x14) 0/r32/eax + 8819 81 7/subop/compare *eax 0/imm32 + 8820 # otherwise abort + 8821 0f 84/jump-if-= $lookup-or-define-var:abort/disp32 + 8822 } + 8823 $lookup-or-define-var:end: + 8824 # . restore registers + 8825 58/pop-to-eax + 8826 # . epilogue + 8827 89/<- %esp 5/r32/ebp + 8828 5d/pop-to-ebp + 8829 c3/return + 8830 + 8831 $lookup-or-define-var:abort: + 8832 (write-buffered *(ebp+0x18) "unknown variable '") + 8833 (write-slice-buffered *(ebp+0x18) *(ebp+8)) + 8834 (write-buffered *(ebp+0x18) "'\n") + 8835 (flush *(ebp+0x18)) + 8836 (stop *(ebp+0x1c) 1) + 8837 # never gets here + 8838 + 8839 find-in-function-outputs: # fn: (addr function), name: (addr slice), out: (addr handle var) + 8840 # . prologue + 8841 55/push-ebp + 8842 89/<- %ebp 4/r32/esp + 8843 # . save registers + 8844 50/push-eax + 8845 51/push-ecx + 8846 # var curr/ecx: (addr list var) = lookup(fn->outputs) + 8847 8b/-> *(ebp+8) 1/r32/ecx + 8848 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax + 8849 89/<- %ecx 0/r32/eax + 8850 # while curr != null + 8851 { + 8852 81 7/subop/compare %ecx 0/imm32 + 8853 74/jump-if-= break/disp8 + 8854 # var v/eax: (addr var) = lookup(curr->value) + 8855 (lookup *ecx *(ecx+4)) # List-value List-value => eax + 8856 # var s/eax: (addr array byte) = lookup(v->name) + 8857 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 8858 # if (s == name) return curr->value + 8859 (slice-equal? *(ebp+0xc) %eax) # => eax + 8860 3d/compare-eax-and 0/imm32/false + 8861 { + 8862 74/jump-if-= break/disp8 + 8863 # var edi = out + 8864 57/push-edi + 8865 8b/-> *(ebp+0x10) 7/r32/edi + 8866 # *out = curr->value + 8867 8b/-> *ecx 0/r32/eax + 8868 89/<- *edi 0/r32/eax + 8869 8b/-> *(ecx+4) 0/r32/eax + 8870 89/<- *(edi+4) 0/r32/eax + 8871 # + 8872 5f/pop-to-edi + 8873 eb/jump $find-in-function-outputs:end/disp8 + 8874 } + 8875 # curr = curr->next + 8876 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax + 8877 89/<- %ecx 0/r32/eax + 8878 # + 8879 eb/jump loop/disp8 + 8880 } + 8881 b8/copy-to-eax 0/imm32 + 8882 $find-in-function-outputs:end: + 8883 # . restore registers + 8884 59/pop-to-ecx + 8885 58/pop-to-eax + 8886 # . epilogue + 8887 89/<- %esp 5/r32/ebp + 8888 5d/pop-to-ebp + 8889 c3/return + 8890 + 8891 # push 'out' to 'vars' if not already there; it's assumed to be a fn output + 8892 maybe-define-var: # out: (handle var), vars: (addr stack live-var) + 8893 # . prologue + 8894 55/push-ebp + 8895 89/<- %ebp 4/r32/esp + 8896 # . save registers + 8897 50/push-eax + 8898 # var out-addr/eax: (addr var) + 8899 (lookup *(ebp+8) *(ebp+0xc)) # => eax + 8900 # + 8901 (binding-exists? %eax *(ebp+0x10)) # => eax + 8902 3d/compare-eax-and 0/imm32/false + 8903 75/jump-if-!= $maybe-define-var:end/disp8 + 8904 # otherwise update vars + 8905 (push *(ebp+0x10) *(ebp+8)) + 8906 (push *(ebp+0x10) *(ebp+0xc)) + 8907 (push *(ebp+0x10) 0) # 'out' is always a fn output; never spill it + 8908 $maybe-define-var:end: + 8909 # . restore registers + 8910 58/pop-to-eax + 8911 # . epilogue + 8912 89/<- %esp 5/r32/ebp + 8913 5d/pop-to-ebp + 8914 c3/return + 8915 + 8916 # simpler version of lookup-var-helper + 8917 binding-exists?: # target: (addr var), vars: (addr stack live-var) -> result/eax: boolean + 8918 # pseudocode: + 8919 # var curr: (addr handle var) = &vars->data[vars->top - 12] + 8920 # var min = vars->data + 8921 # while curr >= min + 8922 # var v: (handle var) = *curr + 8923 # if v->name == target->name + 8924 # return true + 8925 # curr -= 12 + 8926 # return false + 8927 # + 8928 # . prologue + 8929 55/push-ebp + 8930 89/<- %ebp 4/r32/esp + 8931 # . save registers + 8932 51/push-ecx + 8933 52/push-edx + 8934 56/push-esi + 8935 # var target-name/ecx: (addr array byte) = lookup(target->name) + 8936 8b/-> *(ebp+8) 0/r32/eax + 8937 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 8938 89/<- %ecx 0/r32/eax + 8939 # esi = vars + 8940 8b/-> *(ebp+0xc) 6/r32/esi + 8941 # eax = vars->top + 8942 8b/-> *esi 0/r32/eax + 8943 # var min/edx: (addr handle var) = vars->data + 8944 8d/copy-address *(esi+8) 2/r32/edx + 8945 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] + 8946 8d/copy-address *(esi+eax-4) 6/r32/esi # vars + 8 + vars->type - 12 + 8947 { + 8948 $binding-exists?:loop: + 8949 # if (curr < min) return + 8950 39/compare %esi 2/r32/edx + 8951 0f 82/jump-if-addr< break/disp32 + 8952 # var v/eax: (addr var) = lookup(*curr) + 8953 (lookup *esi *(esi+4)) # => eax + 8954 # var vn/eax: (addr array byte) = lookup(v->name) + 8955 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 8956 # if (vn == target-name) return true + 8957 (string-equal? %ecx %eax) # => eax + 8958 3d/compare-eax-and 0/imm32/false + 8959 75/jump-if-!= $binding-exists?:end/disp8 # eax already contains true + 8960 # curr -= 12 + 8961 81 5/subop/subtract %esi 0xc/imm32 + 8962 e9/jump loop/disp32 + 8963 } + 8964 b8/copy-to-eax 0/imm32/false + 8965 $binding-exists?:end: + 8966 # . restore registers + 8967 5e/pop-to-esi + 8968 5a/pop-to-edx + 8969 59/pop-to-ecx + 8970 # . epilogue + 8971 89/<- %esp 5/r32/ebp + 8972 5d/pop-to-ebp + 8973 c3/return + 8974 + 8975 test-parse-mu-stmt: + 8976 # . prologue + 8977 55/push-ebp + 8978 89/<- %ebp 4/r32/esp + 8979 # setup + 8980 (clear-stream _test-input-stream) + 8981 (write _test-input-stream "increment n\n") + 8982 # var vars/ecx: (stack (addr var) 16) + 8983 81 5/subop/subtract %esp 0xc0/imm32 + 8984 68/push 0xc0/imm32/size + 8985 68/push 0/imm32/top + 8986 89/<- %ecx 4/r32/esp + 8987 (clear-stack %ecx) + 8988 # var v/edx: (handle var) + 8989 68/push 0/imm32 + 8990 68/push 0/imm32 + 8991 89/<- %edx 4/r32/esp + 8992 # var s/eax: (handle array byte) + 8993 68/push 0/imm32 + 8994 68/push 0/imm32 + 8995 89/<- %eax 4/r32/esp + 8996 # v = new var("n") + 8997 (copy-array Heap "n" %eax) + 8998 (new-var Heap *eax *(eax+4) %edx) + 8999 # + 9000 (push %ecx *edx) + 9001 (push %ecx *(edx+4)) + 9002 (push %ecx 0) + 9003 # var out/eax: (handle stmt) + 9004 68/push 0/imm32 + 9005 68/push 0/imm32 + 9006 89/<- %eax 4/r32/esp + 9007 # convert + 9008 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) + 9009 # var out-addr/edx: (addr stmt) = lookup(*out) + 9010 (lookup *eax *(eax+4)) # => eax + 9011 89/<- %edx 0/r32/eax + 9012 # out->tag + 9013 (check-ints-equal *edx 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 + 9014 # out->operation + 9015 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax + 9016 (check-strings-equal %eax "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation + 9017 # out->inouts->value->name + 9018 # . eax = out->inouts + 9019 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 9020 # . eax = out->inouts->value + 9021 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9022 # . eax = out->inouts->value->name + 9023 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 9024 # . + 9025 (check-strings-equal %eax "n" "F - test-parse-mu-stmt/inout:0") + 9026 # . epilogue + 9027 89/<- %esp 5/r32/ebp + 9028 5d/pop-to-ebp + 9029 c3/return + 9030 + 9031 test-parse-mu-stmt-with-comma: + 9032 # . prologue + 9033 55/push-ebp + 9034 89/<- %ebp 4/r32/esp + 9035 # setup + 9036 (clear-stream _test-input-stream) + 9037 (write _test-input-stream "copy-to n, 3\n") + 9038 # var vars/ecx: (stack (addr var) 16) + 9039 81 5/subop/subtract %esp 0xc0/imm32 + 9040 68/push 0xc0/imm32/size + 9041 68/push 0/imm32/top + 9042 89/<- %ecx 4/r32/esp + 9043 (clear-stack %ecx) + 9044 # var v/edx: (handle var) + 9045 68/push 0/imm32 + 9046 68/push 0/imm32 + 9047 89/<- %edx 4/r32/esp + 9048 # var s/eax: (handle array byte) + 9049 68/push 0/imm32 + 9050 68/push 0/imm32 + 9051 89/<- %eax 4/r32/esp + 9052 # v = new var("n") + 9053 (copy-array Heap "n" %eax) + 9054 (new-var Heap *eax *(eax+4) %edx) + 9055 # + 9056 (push %ecx *edx) + 9057 (push %ecx *(edx+4)) + 9058 (push %ecx 0) + 9059 # var out/eax: (handle stmt) + 9060 68/push 0/imm32 + 9061 68/push 0/imm32 + 9062 89/<- %eax 4/r32/esp + 9063 # convert + 9064 (parse-mu-stmt _test-input-stream %ecx 0 %eax Stderr 0) + 9065 # var out-addr/edx: (addr stmt) = lookup(*out) + 9066 (lookup *eax *(eax+4)) # => eax + 9067 89/<- %edx 0/r32/eax + 9068 # out->tag + 9069 (check-ints-equal *edx 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1 + 9070 # out->operation + 9071 (lookup *(edx+4) *(edx+8)) # Stmt1-operation Stmt1-operation => eax + 9072 (check-strings-equal %eax "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation + 9073 # out->inouts->value->name + 9074 # . eax = out->inouts + 9075 (lookup *(edx+0xc) *(edx+0x10)) # Stmt1-inouts Stmt1-inouts => eax + 9076 # . eax = out->inouts->value + 9077 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9078 # . eax = out->inouts->value->name + 9079 (lookup *eax *(eax+4)) # Var-name Var-name => eax + 9080 # . + 9081 (check-strings-equal %eax "n" "F - test-parse-mu-stmt-with-comma/inout:0") + 9082 # . epilogue + 9083 89/<- %esp 5/r32/ebp + 9084 5d/pop-to-ebp + 9085 c3/return + 9086 + 9087 new-var: # ad: (addr allocation-descriptor), name: (handle array byte), out: (addr handle var) + 9088 # . prologue + 9089 55/push-ebp + 9090 89/<- %ebp 4/r32/esp + 9091 # . save registers + 9092 50/push-eax + 9093 51/push-ecx + 9094 # ecx = out + 9095 8b/-> *(ebp+0x14) 1/r32/ecx + 9096 # + 9097 (allocate *(ebp+8) *Var-size %ecx) + 9098 # var out-addr/eax: (addr var) + 9099 (lookup *ecx *(ecx+4)) # => eax + 9100 # out-addr->name = name + 9101 8b/-> *(ebp+0xc) 1/r32/ecx + 9102 89/<- *eax 1/r32/ecx # Var-name + 9103 8b/-> *(ebp+0x10) 1/r32/ecx + 9104 89/<- *(eax+4) 1/r32/ecx # Var-name + 9105 #? (write-buffered Stderr "var ") + 9106 #? (lookup *(ebp+0xc) *(ebp+0x10)) + 9107 #? (write-buffered Stderr %eax) + 9108 #? (write-buffered Stderr " at ") + 9109 #? 8b/-> *(ebp+0x14) 1/r32/ecx + 9110 #? (lookup *ecx *(ecx+4)) # => eax + 9111 #? (print-int32-buffered Stderr %eax) + 9112 #? (write-buffered Stderr Newline) + 9113 #? (flush Stderr) + 9114 $new-var:end: + 9115 # . restore registers + 9116 59/pop-to-ecx + 9117 58/pop-to-eax + 9118 # . epilogue + 9119 89/<- %esp 5/r32/ebp + 9120 5d/pop-to-ebp + 9121 c3/return + 9122 + 9123 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) + 9124 # . prologue + 9125 55/push-ebp + 9126 89/<- %ebp 4/r32/esp + 9127 # . save registers + 9128 50/push-eax + 9129 51/push-ecx + 9130 # if (!is-hex-int?(name)) abort + 9131 (is-hex-int? *(ebp+0xc)) # => eax + 9132 3d/compare-eax-and 0/imm32/false + 9133 0f 84/jump-if-= $new-literal-integer:abort/disp32 + 9134 # out = new var(s) + 9135 (new-var-from-slice *(ebp+8) *(ebp+0xc) *(ebp+0x10)) + 9136 # var out-addr/ecx: (addr var) = lookup(*out) + 9137 8b/-> *(ebp+0x10) 0/r32/eax + 9138 (lookup *eax *(eax+4)) # => eax + 9139 89/<- %ecx 0/r32/eax + 9140 # out-addr->block-depth = *Curr-block-depth + 9141 8b/-> *Curr-block-depth 0/r32/eax + 9142 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth + 9143 # out-addr->type = new tree() + 9144 8d/copy-address *(ecx+8) 0/r32/eax # Var-type + 9145 (allocate *(ebp+8) *Tree-size %eax) + 9146 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 9147 c7 0/subop/copy *eax 1/imm32/true # Tree-is-atom + 9148 # nothing else to do; default type is 'literal' + 9149 $new-literal-integer:end: + 9150 # . reclaim locals + 9151 81 0/subop/add %esp 8/imm32 + 9152 # . restore registers + 9153 59/pop-to-ecx + 9154 58/pop-to-eax + 9155 # . epilogue + 9156 89/<- %esp 5/r32/ebp + 9157 5d/pop-to-ebp + 9158 c3/return + 9159 + 9160 $new-literal-integer:abort: + 9161 (write-buffered *(ebp+0x18) "fn ") + 9162 8b/-> *(ebp+0x14) 0/r32/eax + 9163 (lookup *eax *(eax+4)) # Function-name Function-name => eax + 9164 (write-buffered *(ebp+0x18) %eax) + 9165 (write-buffered *(ebp+0x18) ": variable cannot begin with a digit '") + 9166 (write-slice-buffered *(ebp+0x18) *(ebp+0xc)) + 9167 (write-buffered *(ebp+0x18) "'\n") + 9168 (flush *(ebp+0x18)) + 9169 (stop *(ebp+0x1c) 1) + 9170 # never gets here + 9171 + 9172 new-literal: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) + 9173 # . prologue + 9174 55/push-ebp + 9175 89/<- %ebp 4/r32/esp + 9176 # . save registers + 9177 50/push-eax + 9178 51/push-ecx + 9179 # var s/ecx: (handle array byte) + 9180 68/push 0/imm32 + 9181 68/push 0/imm32 + 9182 89/<- %ecx 4/r32/esp + 9183 # s = slice-to-string(name) + 9184 (slice-to-string Heap *(ebp+0xc) %ecx) + 9185 # allocate to out + 9186 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) + 9187 # var out-addr/ecx: (addr var) = lookup(*out) + 9188 8b/-> *(ebp+0x10) 1/r32/ecx + 9189 (lookup *ecx *(ecx+4)) # => eax + 9190 89/<- %ecx 0/r32/eax + 9191 # out-addr->block-depth = *Curr-block-depth + 9192 8b/-> *Curr-block-depth 0/r32/eax + 9193 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth + 9194 # out-addr->type/eax = new type + 9195 8d/copy-address *(ecx+8) 0/r32/eax # Var-type + 9196 (allocate *(ebp+8) *Tree-size %eax) + 9197 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax + 9198 # nothing else to do; default type is 'literal' + 9199 c7 0/subop/copy *eax 1/imm32/true # Tree-is-atom + 9200 $new-literal:end: + 9201 # . reclaim locals + 9202 81 0/subop/add %esp 8/imm32 + 9203 # . restore registers + 9204 59/pop-to-ecx + 9205 58/pop-to-eax + 9206 # . epilogue + 9207 89/<- %esp 5/r32/ebp + 9208 5d/pop-to-ebp + 9209 c3/return + 9210 + 9211 new-var-from-slice: # ad: (addr allocation-descriptor), name: (addr slice), out: (addr handle var) + 9212 # . prologue + 9213 55/push-ebp + 9214 89/<- %ebp 4/r32/esp + 9215 # . save registers + 9216 51/push-ecx + 9217 # var tmp/ecx: (handle array byte) + 9218 68/push 0/imm32 + 9219 68/push 0/imm32 + 9220 89/<- %ecx 4/r32/esp + 9221 # tmp = slice-to-string(name) + 9222 (slice-to-string Heap *(ebp+0xc) %ecx) + 9223 # out = new-var(tmp) + 9224 (new-var *(ebp+8) *ecx *(ecx+4) *(ebp+0x10)) + 9225 $new-var-from-slice:end: + 9226 # . reclaim locals + 9227 81 0/subop/add %esp 8/imm32 + 9228 # . restore registers + 9229 59/pop-to-ecx + 9230 # . epilogue + 9231 89/<- %esp 5/r32/ebp + 9232 5d/pop-to-ebp + 9233 c3/return + 9234 + 9235 new-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) + 9236 # . prologue + 9237 55/push-ebp + 9238 89/<- %ebp 4/r32/esp + 9239 # . save registers + 9240 50/push-eax + 9241 51/push-ecx + 9242 # + 9243 (allocate *(ebp+8) *Stmt-size *(ebp+0x14)) + 9244 # var out-addr/eax: (addr stmt) = lookup(*out) + 9245 8b/-> *(ebp+0x14) 0/r32/eax + 9246 (lookup *eax *(eax+4)) # => eax + 9247 # out-addr->tag = stmt + 9248 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag + 9249 # result->var = var + 9250 8b/-> *(ebp+0xc) 1/r32/ecx + 9251 89/<- *(eax+4) 1/r32/ecx # Vardef-var + 9252 8b/-> *(ebp+0x10) 1/r32/ecx + 9253 89/<- *(eax+8) 1/r32/ecx # Vardef-var + 9254 $new-var-def:end: + 9255 # . restore registers + 9256 59/pop-to-ecx + 9257 58/pop-to-eax + 9258 # . epilogue + 9259 89/<- %esp 5/r32/ebp + 9260 5d/pop-to-ebp + 9261 c3/return + 9262 + 9263 new-reg-var-def: # ad: (addr allocation-descriptor), var: (handle var), out: (addr handle stmt) + 9264 # . prologue + 9265 55/push-ebp + 9266 89/<- %ebp 4/r32/esp + 9267 # . save registers + 9268 50/push-eax + 9269 # eax = out + 9270 8b/-> *(ebp+0x14) 0/r32/eax + 9271 # + 9272 (allocate *(ebp+8) *Stmt-size %eax) + 9273 # var out-addr/eax: (addr stmt) = lookup(*out) + 9274 (lookup *eax *(eax+4)) # => eax + 9275 # set tag + 9276 c7 0/subop/copy *eax 3/imm32/tag/var-in-register # Stmt-tag + 9277 # set output + 9278 8d/copy-address *(eax+0x14) 0/r32/eax # Regvardef-outputs + 9279 (append-stmt-var Heap *(ebp+0xc) *(ebp+0x10) 0 0 0 %eax) + 9280 $new-reg-var-def:end: + 9281 # . restore registers + 9282 58/pop-to-eax + 9283 # . epilogue + 9284 89/<- %esp 5/r32/ebp + 9285 5d/pop-to-ebp + 9286 c3/return + 9287 + 9288 append-list: # ad: (addr allocation-descriptor), value: (handle _type), list: (handle list _type), out: (addr handle list _type) + 9289 # . prologue + 9290 55/push-ebp + 9291 89/<- %ebp 4/r32/esp + 9292 # . save registers + 9293 50/push-eax + 9294 51/push-ecx + 9295 57/push-edi + 9296 # edi = out + 9297 8b/-> *(ebp+0x1c) 7/r32/edi + 9298 # *out = new list + 9299 (allocate *(ebp+8) *List-size %edi) + 9300 # var out-addr/edi: (addr list _type) = lookup(*out) + 9301 (lookup *edi *(edi+4)) # => eax + 9302 89/<- %edi 0/r32/eax + 9303 # out-addr->value = value + 9304 8b/-> *(ebp+0xc) 0/r32/eax + 9305 89/<- *edi 0/r32/eax # List-value + 9306 8b/-> *(ebp+0x10) 0/r32/eax + 9307 89/<- *(edi+4) 0/r32/eax # List-value + 9308 # if (list == null) return + 9309 81 7/subop/compare *(ebp+0x14) 0/imm32 + 9310 74/jump-if-= $append-list:end/disp8 + 9311 # otherwise append + 9312 $append-list:non-empty-list: + 9313 # var curr/eax: (addr list _type) = lookup(list) + 9314 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax + 9315 # while (curr->next != null) curr = curr->next + 9316 { + 9317 81 7/subop/compare *(eax+8) 0/imm32 # List-next + 9318 74/jump-if-= break/disp8 + 9319 # curr = lookup(curr->next) + 9320 (lookup *(eax+8) *(eax+0xc)) # List-next, List-next => eax + 9321 # + 9322 eb/jump loop/disp8 + 9323 } + 9324 # edi = out + 9325 8b/-> *(ebp+0x1c) 7/r32/edi + 9326 # curr->next = out + 9327 8b/-> *edi 1/r32/ecx + 9328 89/<- *(eax+8) 1/r32/ecx # List-next + 9329 8b/-> *(edi+4) 1/r32/ecx + 9330 89/<- *(eax+0xc) 1/r32/ecx # List-next + 9331 # out = list + 9332 8b/-> *(ebp+0x14) 1/r32/ecx + 9333 89/<- *edi 1/r32/ecx + 9334 8b/-> *(ebp+0x18) 1/r32/ecx + 9335 89/<- *(edi+4) 1/r32/ecx + 9336 $append-list:end: + 9337 # . restore registers + 9338 5f/pop-to-edi + 9339 59/pop-to-ecx + 9340 58/pop-to-eax + 9341 # . epilogue + 9342 89/<- %esp 5/r32/ebp + 9343 5d/pop-to-ebp + 9344 c3/return + 9345 + 9346 append-stmt-var: # ad: (addr allocation-descriptor), v: (handle var), vars: (handle stmt-var), is-deref?: boolean, out: (addr handle stmt-var) + 9347 # . prologue + 9348 55/push-ebp + 9349 89/<- %ebp 4/r32/esp + 9350 # . save registers + 9351 50/push-eax + 9352 51/push-ecx + 9353 57/push-edi + 9354 # edi = out + 9355 8b/-> *(ebp+0x20) 7/r32/edi + 9356 # out = new stmt-var + 9357 (allocate *(ebp+8) *Stmt-var-size %edi) + 9358 # var out-addr/ecx: (addr stmt-var) = lookup(*out) + 9359 (lookup *edi *(edi+4)) # => eax + 9360 89/<- %ecx 0/r32/eax + 9361 # out-addr->value = v + 9362 8b/-> *(ebp+0xc) 0/r32/eax + 9363 89/<- *ecx 0/r32/eax # Stmt-var-value + 9364 8b/-> *(ebp+0x10) 0/r32/eax + 9365 89/<- *(ecx+4) 0/r32/eax # Stmt-var-value + 9366 # out-addr->is-deref? = is-deref? + 9367 8b/-> *(ebp+0x1c) 0/r32/eax + 9368 89/<- *(ecx+0x10) 0/r32/eax # Stmt-var-is-deref + 9369 # if (vars == null) return result + 9370 81 7/subop/compare *(ebp+0x14) 0/imm32/null + 9371 74/jump-if-= $append-stmt-var:end/disp8 + 9372 # otherwise append + 9373 # var curr/eax: (addr stmt-var) = lookup(vars) + 9374 (lookup *(ebp+0x14) *(ebp+0x18)) # => eax + 9375 # while (curr->next != null) curr = curr->next + 9376 { + 9377 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next + 9378 74/jump-if-= break/disp8 + 9379 # curr = lookup(curr->next) + 9380 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next, Stmt-var-next => eax + 9381 # + 9382 eb/jump loop/disp8 + 9383 } + 9384 # curr->next = out + 9385 8b/-> *edi 1/r32/ecx + 9386 89/<- *(eax+8) 1/r32/ecx # Stmt-var-next + 9387 8b/-> *(edi+4) 1/r32/ecx + 9388 89/<- *(eax+0xc) 1/r32/ecx # Stmt-var-next + 9389 # out = vars + 9390 8b/-> *(ebp+0x14) 1/r32/ecx + 9391 89/<- *edi 1/r32/ecx + 9392 8b/-> *(ebp+0x18) 1/r32/ecx + 9393 89/<- *(edi+4) 1/r32/ecx + 9394 $append-stmt-var:end: + 9395 # . restore registers + 9396 5f/pop-to-edi + 9397 59/pop-to-ecx + 9398 58/pop-to-eax + 9399 # . epilogue + 9400 89/<- %esp 5/r32/ebp + 9401 5d/pop-to-ebp + 9402 c3/return + 9403 + 9404 append-to-block: # ad: (addr allocation-descriptor), block: (addr block), x: (handle stmt) + 9405 # . prologue + 9406 55/push-ebp + 9407 89/<- %ebp 4/r32/esp + 9408 # . save registers + 9409 50/push-eax + 9410 56/push-esi + 9411 # esi = block + 9412 8b/-> *(ebp+0xc) 6/r32/esi + 9413 # block->stmts = append(x, block->stmts) + 9414 8d/copy-address *(esi+4) 0/r32/eax # Block-stmts + 9415 (append-list *(ebp+8) *(ebp+0x10) *(ebp+0x14) *(esi+4) *(esi+8) %eax) # ad, x, x, Block-stmts, Block-stmts + 9416 $append-to-block:end: + 9417 # . restore registers + 9418 5e/pop-to-esi + 9419 58/pop-to-eax + 9420 # . epilogue + 9421 89/<- %esp 5/r32/ebp + 9422 5d/pop-to-ebp + 9423 c3/return + 9424 + 9425 ## Parsing types + 9426 # We need to create metadata on user-defined types, and we need to use this + 9427 # metadata as we parse instructions. + 9428 # However, we also want to allow types to be used before their definitions. + 9429 # This means we can't ever assume any type data structures exist. + 9430 + 9431 lookup-or-create-constant: # container: (addr stmt-var), field-name: (addr slice), out: (addr handle var) + 9432 # . prologue + 9433 55/push-ebp + 9434 89/<- %ebp 4/r32/esp + 9435 # . save registers + 9436 50/push-eax + 9437 56/push-esi + 9438 # var container-type/esi: type-id + 9439 (container-type *(ebp+8)) # => eax + 9440 89/<- %esi 0/r32/eax + 9441 # var tmp/eax: (handle typeinfo) = find-or-create-typeinfo(container-type) + 9442 68/push 0/imm32 + 9443 68/push 0/imm32 + 9444 89/<- %eax 4/r32/esp + 9445 (find-or-create-typeinfo %esi %eax) + 9446 # var tmp-addr/eax: (addr typeinfo) = lookup(tmp) + 9447 (lookup *eax *(eax+4)) # => eax + 9448 # result = find-or-create-typeinfo-output-var(typeinfo, field-name) + 9449 #? (write-buffered Stderr "constant: ") + 9450 #? (write-slice-buffered Stderr *(ebp+0xc)) + 9451 #? (write-buffered Stderr Newline) + 9452 #? (flush Stderr) + 9453 (find-or-create-typeinfo-output-var %eax *(ebp+0xc) *(ebp+0x10)) + 9454 #? 8b/-> *(ebp+0x10) 0/r32/eax + 9455 #? (write-buffered Stderr "@") + 9456 #? (lookup *eax *(eax+4)) + 9457 #? (print-int32-buffered Stderr %eax) + 9458 #? (lookup *eax *(eax+4)) + 9459 #? (write-buffered Stderr %eax) + 9460 #? (write-buffered Stderr Newline) + 9461 #? (flush Stderr) + 9462 #? (write-buffered Stderr "offset: ") + 9463 #? 8b/-> *(eax+0x14) 0/r32/eax + 9464 #? (print-int32-buffered Stderr %eax) + 9465 #? (write-buffered Stderr Newline) + 9466 #? (flush Stderr) + 9467 $lookup-or-create-constant:end: + 9468 # . reclaim locals + 9469 81 0/subop/add %esp 8/imm32 + 9470 # . restore registers + 9471 5e/pop-to-esi + 9472 58/pop-to-eax + 9473 # . epilogue + 9474 89/<- %esp 5/r32/ebp + 9475 5d/pop-to-ebp + 9476 c3/return + 9477 + 9478 # if addr var: + 9479 # container->var->type->right->left->value + 9480 # otherwise + 9481 # container->var->type->value + 9482 container-type: # container: (addr stmt-var) -> result/eax: type-id + 9483 # . prologue + 9484 55/push-ebp + 9485 89/<- %ebp 4/r32/esp + 9486 # + 9487 8b/-> *(ebp+8) 0/r32/eax + 9488 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax + 9489 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax + 9490 { + 9491 81 7/subop/compare *(eax+8) 0/imm32 # Tree-right + 9492 74/jump-if-= break/disp8 + 9493 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax + 9494 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax + 9495 } + 9496 8b/-> *(eax+4) 0/r32/eax # Tree-value + 9497 $container-type:end: + 9498 # . epilogue + 9499 89/<- %esp 5/r32/ebp + 9500 5d/pop-to-ebp + 9501 c3/return + 9502 + 9503 is-container?: # t: type-id -> result/eax: boolean + 9504 # . prologue + 9505 55/push-ebp + 9506 89/<- %ebp 4/r32/esp + 9507 # + 9508 8b/-> *(ebp+8) 0/r32/eax + 9509 c1/shift 4/subop/left %eax 2/imm8 + 9510 3b/compare 0/r32/eax *Primitive-type-ids + 9511 0f 9d/set-if->= %al + 9512 81 4/subop/and %eax 0xff/imm32 + 9513 $is-container?:end: + 9514 # . epilogue + 9515 89/<- %esp 5/r32/ebp + 9516 5d/pop-to-ebp + 9517 c3/return + 9518 + 9519 find-or-create-typeinfo: # t: type-id, out: (addr handle typeinfo) + 9520 # . prologue + 9521 55/push-ebp + 9522 89/<- %ebp 4/r32/esp + 9523 # . save registers + 9524 50/push-eax + 9525 51/push-ecx + 9526 52/push-edx + 9527 57/push-edi + 9528 # edi = out + 9529 8b/-> *(ebp+0xc) 7/r32/edi + 9530 # var fields/ecx: (handle table (handle array byte) (handle typeinfo-entry)) + 9531 68/push 0/imm32 + 9532 68/push 0/imm32 + 9533 89/<- %ecx 4/r32/esp + 9534 # find-typeinfo(t, out) + 9535 (find-typeinfo *(ebp+8) %edi) + 9536 { + 9537 # if (*out != 0) break + 9538 81 7/subop/compare *edi 0/imm32 + 9539 0f 85/jump-if-!= break/disp32 + 9540 $find-or-create-typeinfo:create: + 9541 # *out = allocate + 9542 (allocate Heap *Typeinfo-size %edi) + 9543 # var tmp/eax: (addr typeinfo) = lookup(*out) + 9544 (lookup *edi *(edi+4)) # => eax + 9545 #? (write-buffered Stderr "created typeinfo at ") + 9546 #? (print-int32-buffered Stderr %eax) + 9547 #? (write-buffered Stderr " for type-id ") + 9548 #? (print-int32-buffered Stderr *(ebp+8)) + 9549 #? (write-buffered Stderr Newline) + 9550 #? (flush Stderr) + 9551 # tmp->id = t + 9552 8b/-> *(ebp+8) 2/r32/edx + 9553 89/<- *eax 2/r32/edx # Typeinfo-id + 9554 # tmp->fields = new table + 9555 # . fields = new table + 9556 (new-stream Heap 0x40 *Typeinfo-fields-row-size %ecx) + 9557 # . tmp->fields = fields + 9558 8b/-> *ecx 2/r32/edx + 9559 89/<- *(eax+4) 2/r32/edx # Typeinfo-fields + 9560 8b/-> *(ecx+4) 2/r32/edx + 9561 89/<- *(eax+8) 2/r32/edx # Typeinfo-fields + 9562 # tmp->next = Program->types + 9563 8b/-> *_Program-types 1/r32/ecx + 9564 89/<- *(eax+0x10) 1/r32/ecx # Typeinfo-next + 9565 8b/-> *_Program-types->payload 1/r32/ecx + 9566 89/<- *(eax+0x14) 1/r32/ecx # Typeinfo-next + 9567 # Program->types = out + 9568 8b/-> *edi 1/r32/ecx + 9569 89/<- *_Program-types 1/r32/ecx + 9570 8b/-> *(edi+4) 1/r32/ecx + 9571 89/<- *_Program-types->payload 1/r32/ecx + 9572 } + 9573 $find-or-create-typeinfo:end: + 9574 # . reclaim locals + 9575 81 0/subop/add %esp 8/imm32 + 9576 # . restore registers + 9577 5f/pop-to-edi + 9578 5a/pop-to-edx + 9579 59/pop-to-ecx + 9580 58/pop-to-eax + 9581 # . epilogue + 9582 89/<- %esp 5/r32/ebp + 9583 5d/pop-to-ebp + 9584 c3/return + 9585 + 9586 find-typeinfo: # t: type-id, out: (addr handle typeinfo) + 9587 # . prologue + 9588 55/push-ebp + 9589 89/<- %ebp 4/r32/esp + 9590 # . save registers + 9591 50/push-eax + 9592 51/push-ecx + 9593 52/push-edx + 9594 57/push-edi + 9595 # ecx = t + 9596 8b/-> *(ebp+8) 1/r32/ecx + 9597 # edi = out + 9598 8b/-> *(ebp+0xc) 7/r32/edi + 9599 # *out = Program->types + 9600 8b/-> *_Program-types 0/r32/eax + 9601 89/<- *edi 0/r32/eax + 9602 8b/-> *_Program-types->payload 0/r32/eax + 9603 89/<- *(edi+4) 0/r32/eax + 9604 { + 9605 $find-typeinfo:loop: + 9606 # if (*out == 0) break + 9607 81 7/subop/compare *edi 0/imm32 + 9608 74/jump-if-= break/disp8 + 9609 $find-typeinfo:check: + 9610 # var tmp/eax: (addr typeinfo) = lookup(*out) + 9611 (lookup *edi *(edi+4)) # => eax + 9612 # if (tmp->id == t) break + 9613 39/compare *eax 1/r32/ecx # Typeinfo-id + 9614 74/jump-if-= break/disp8 + 9615 $find-typeinfo:continue: + 9616 # *out = tmp->next + 9617 8b/-> *(eax+0x10) 2/r32/edx # Typeinfo-next + 9618 89/<- *edi 2/r32/edx + 9619 8b/-> *(eax+0x14) 2/r32/edx # Typeinfo-next + 9620 89/<- *(edi+4) 2/r32/edx + 9621 # + 9622 eb/jump loop/disp8 + 9623 } + 9624 $find-typeinfo:end: + 9625 # . restore registers + 9626 5f/pop-to-edi + 9627 5a/pop-to-edx + 9628 59/pop-to-ecx + 9629 58/pop-to-eax + 9630 # . epilogue + 9631 89/<- %esp 5/r32/ebp + 9632 5d/pop-to-ebp + 9633 c3/return + 9634 + 9635 find-or-create-typeinfo-output-var: # T: (addr typeinfo), f: (addr slice), out: (addr handle var) + 9636 # . prologue + 9637 55/push-ebp + 9638 89/<- %ebp 4/r32/esp + 9639 # . save registers + 9640 50/push-eax + 9641 52/push-edx + 9642 57/push-edi + 9643 # var dest/edi: (handle typeinfo-entry) + 9644 68/push 0/imm32 + 9645 68/push 0/imm32 + 9646 89/<- %edi 4/r32/esp + 9647 # find-or-create-typeinfo-fields(T, f, dest) + 9648 (find-or-create-typeinfo-fields *(ebp+8) *(ebp+0xc) %edi) + 9649 # var dest-addr/edi: (addr typeinfo-entry) = lookup(dest) + 9650 (lookup *edi *(edi+4)) # => eax + 9651 89/<- %edi 0/r32/eax + 9652 # if dest-addr->output-var doesn't exist, create it + 9653 { + 9654 81 7/subop/compare *(edi+0xc) 0/imm32 # Typeinfo-entry-output-var + 9655 0f 85/jump-if-!= break/disp32 + 9656 # dest-addr->output-var = new var(dummy name, type, -1 offset) + 9657 # . var name/eax: (handle array byte) = "field" + 9658 68/push 0/imm32 + 9659 68/push 0/imm32 + 9660 89/<- %eax 4/r32/esp + 9661 (slice-to-string Heap *(ebp+0xc) %eax) + 9662 # . new var + 9663 8d/copy-address *(edi+0xc) 2/r32/edx + 9664 (new-var Heap *eax *(eax+4) %edx) + 9665 # . reclaim name + 9666 81 0/subop/add %esp 8/imm32 + 9667 # var result/edx: (addr var) = lookup(dest-addr->output-var) + 9668 (lookup *(edi+0xc) *(edi+0x10)) # => eax + 9669 89/<- %edx 0/r32/eax + 9670 # result->type = new constant type + 9671 8d/copy-address *(edx+8) 0/r32/eax # Var-type + 9672 (allocate Heap *Tree-size %eax) + 9673 (lookup *(edx+8) *(edx+0xc)) # => eax + 9674 c7 0/subop/copy *eax 1/imm32/true # Tree-is-atom + 9675 c7 0/subop/copy *(eax+4) 6/imm32/constant # Tree-value + 9676 c7 0/subop/copy *(eax+8) 0/imm32 # Tree-left + 9677 c7 0/subop/copy *(eax+0xc) 0/imm32 # Tree-right + 9678 c7 0/subop/copy *(eax+0x10) 0/imm32 # Tree-right + 9679 # result->offset isn't filled out yet + 9680 c7 0/subop/copy *(edx+0x14) -1/imm32/uninitialized # Var-offset + 9681 } + 9682 # out = dest-addr->output-var + 9683 8b/-> *(ebp+0x10) 2/r32/edx + 9684 8b/-> *(edi+0xc) 0/r32/eax # Typeinfo-entry-output-var + 9685 89/<- *edx 0/r32/eax + 9686 8b/-> *(edi+0x10) 0/r32/eax # Typeinfo-entry-output-var + 9687 89/<- *(edx+4) 0/r32/eax + 9688 $find-or-create-typeinfo-output-var:end: + 9689 # . reclaim locals + 9690 81 0/subop/add %esp 8/imm32 + 9691 # . restore registers + 9692 5f/pop-to-edi + 9693 5a/pop-to-edx + 9694 58/pop-to-eax + 9695 # . epilogue + 9696 89/<- %esp 5/r32/ebp + 9697 5d/pop-to-ebp + 9698 c3/return + 9699 + 9700 find-or-create-typeinfo-fields: # T: (addr typeinfo), f: (addr slice), out: (addr handle typeinfo-entry) + 9701 # . prologue + 9702 55/push-ebp + 9703 89/<- %ebp 4/r32/esp + 9704 # . save registers + 9705 50/push-eax + 9706 56/push-esi + 9707 57/push-edi + 9708 # eax = lookup(T->fields) + 9709 8b/-> *(ebp+8) 0/r32/eax + 9710 (lookup *(eax+4) *(eax+8)) # Typeinfo-fields Typeinfo-fields => eax + 9711 # edi = out + 9712 8b/-> *(ebp+0x10) 7/r32/edi + 9713 # var src/esi: (addr handle typeinfo-entry) = get-or-insert-slice(T->fields, f) + 9714 (get-or-insert-slice %eax *(ebp+0xc) *Typeinfo-fields-row-size Heap) # => eax + 9715 89/<- %esi 0/r32/eax + 9716 # if src doesn't exist, allocate it + 9717 { + 9718 81 7/subop/compare *esi 0/imm32 + 9719 75/jump-if-!= break/disp8 + 9720 (allocate Heap *Typeinfo-entry-size %esi) + 9721 #? (write-buffered Stderr "handle at ") + 9722 #? (print-int32-buffered Stderr %esi) + 9723 #? (write-buffered Stderr ": ") + 9724 #? (print-int32-buffered Stderr *esi) + 9725 #? (write-buffered Stderr " ") + 9726 #? (print-int32-buffered Stderr *(esi+4)) + 9727 #? (write-buffered Stderr Newline) + 9728 #? (flush Stderr) + 9729 #? (lookup *esi *(esi+4)) + 9730 #? (write-buffered Stderr "created typeinfo fields at ") + 9731 #? (print-int32-buffered Stderr %esi) + 9732 #? (write-buffered Stderr " for ") + 9733 #? (print-int32-buffered Stderr *(ebp+8)) + 9734 #? (write-buffered Stderr Newline) + 9735 #? (flush Stderr) + 9736 } + 9737 # *out = src + 9738 # . *edi = *src + 9739 8b/-> *esi 0/r32/eax + 9740 89/<- *edi 0/r32/eax + 9741 8b/-> *(esi+4) 0/r32/eax + 9742 89/<- *(edi+4) 0/r32/eax + 9743 $find-or-create-typeinfo-fields:end: + 9744 # . restore registers + 9745 5f/pop-to-edi + 9746 5e/pop-to-esi + 9747 58/pop-to-eax + 9748 # . epilogue + 9749 89/<- %esp 5/r32/ebp + 9750 5d/pop-to-ebp + 9751 c3/return + 9752 + 9753 populate-mu-type: # in: (addr stream byte), t: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) + 9754 # pseudocode: + 9755 # var line: (stream byte 512) + 9756 # curr-index = 0 + 9757 # while true + 9758 # clear-stream(line) + 9759 # read-line-buffered(in, line) + 9760 # if line->write == 0 + 9761 # abort + 9762 # word-slice = next-mu-token(line) + 9763 # if slice-empty?(word-slice) # end of line + 9764 # continue + 9765 # if slice-equal?(word-slice, "}") + 9766 # break + 9767 # var v: (handle var) = parse-var-with-type(word-slice, line) + 9768 # var r: (handle typeinfo-fields) = find-or-create-typeinfo-fields(t, word-slice/v->name) + 9769 # TODO: ensure that r->first is null + 9770 # r->index = curr-index + 9771 # curr-index++ + 9772 # r->input-var = v + 9773 # if r->output-var == 0 + 9774 # r->output-var = new literal + 9775 # TODO: ensure nothing else in line + 9776 # t->total-size-in-bytes = -2 (not yet initialized) + 9777 # + 9778 # . prologue + 9779 55/push-ebp + 9780 89/<- %ebp 4/r32/esp + 9781 # var curr-index: int at *(ebp-4) + 9782 68/push 0/imm32 + 9783 # . save registers + 9784 50/push-eax + 9785 51/push-ecx + 9786 52/push-edx + 9787 53/push-ebx + 9788 56/push-esi + 9789 57/push-edi + 9790 # edi = t + 9791 8b/-> *(ebp+0xc) 7/r32/edi + 9792 # var line/ecx: (stream byte 512) + 9793 81 5/subop/subtract %esp 0x200/imm32 + 9794 68/push 0x200/imm32/size + 9795 68/push 0/imm32/read + 9796 68/push 0/imm32/write + 9797 89/<- %ecx 4/r32/esp + 9798 # var word-slice/edx: slice + 9799 68/push 0/imm32/end + 9800 68/push 0/imm32/start + 9801 89/<- %edx 4/r32/esp + 9802 # var v/esi: (handle var) + 9803 68/push 0/imm32 + 9804 68/push 0/imm32 + 9805 89/<- %esi 4/r32/esp + 9806 # var r/ebx: (handle typeinfo-entry) + 9807 68/push 0/imm32 + 9808 68/push 0/imm32 + 9809 89/<- %ebx 4/r32/esp + 9810 { + 9811 $populate-mu-type:line-loop: + 9812 (clear-stream %ecx) + 9813 (read-line-buffered *(ebp+8) %ecx) + 9814 # if (line->write == 0) abort + 9815 81 7/subop/compare *ecx 0/imm32 + 9816 0f 84/jump-if-= $populate-mu-type:abort/disp32 + 9817 +-- 6 lines: #? # dump line ------------------------------------------------------------------------------------------------------------------------------------------------------ + 9823 (next-mu-token %ecx %edx) + 9824 # if slice-empty?(word-slice) continue + 9825 (slice-empty? %edx) # => eax + 9826 3d/compare-eax-and 0/imm32 + 9827 0f 85/jump-if-!= loop/disp32 + 9828 # if slice-equal?(word-slice, "}") break + 9829 (slice-equal? %edx "}") + 9830 3d/compare-eax-and 0/imm32 + 9831 0f 85/jump-if-!= break/disp32 + 9832 $populate-mu-type:parse-element: + 9833 # v = parse-var-with-type(word-slice, first-line) + 9834 # must do this first to strip the trailing ':' from word-slice before + 9835 # using it in find-or-create-typeinfo-fields below + 9836 # TODO: clean up that mutation in parse-var-with-type + 9837 (parse-var-with-type %edx %ecx %esi *(ebp+0x10) *(ebp+0x14)) # => eax + 9838 # var tmp/ecx + 9839 51/push-ecx + 9840 $populate-mu-type:create-typeinfo-fields: + 9841 # var r/ebx: (handle typeinfo-entry) + 9842 (find-or-create-typeinfo-fields %edi %edx %ebx) + 9843 # r->index = curr-index + 9844 (lookup *ebx *(ebx+4)) # => eax + 9845 8b/-> *(ebp-4) 1/r32/ecx + 9846 #? (write-buffered Stderr "saving index ") + 9847 #? (print-int32-buffered Stderr %ecx) + 9848 #? (write-buffered Stderr " at ") + 9849 #? (print-int32-buffered Stderr %edi) + 9850 #? (write-buffered Stderr Newline) + 9851 #? (flush Stderr) + 9852 89/<- *(eax+8) 1/r32/ecx # Typeinfo-entry-index + 9853 # ++curr-index + 9854 ff 0/subop/increment *(ebp-4) + 9855 $populate-mu-type:set-input-type: + 9856 # r->input-var = v + 9857 8b/-> *esi 1/r32/ecx + 9858 89/<- *eax 1/r32/ecx # Typeinfo-entry-input-var + 9859 8b/-> *(esi+4) 1/r32/ecx + 9860 89/<- *(eax+4) 1/r32/ecx # Typeinfo-entry-input-var + 9861 59/pop-to-ecx + 9862 { + 9863 $populate-mu-type:create-output-type: + 9864 # if (r->output-var == 0) create a new var with some placeholder data + 9865 81 7/subop/compare *(eax+0xc) 0/imm32 # Typeinfo-entry-output-var + 9866 75/jump-if-!= break/disp8 + 9867 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var + 9868 (new-literal Heap %edx %eax) + 9869 } + 9870 e9/jump loop/disp32 + 9871 } + 9872 $populate-mu-type:invalidate-total-size-in-bytes: + 9873 # Offsets and total size may not be accurate here since we may not yet + 9874 # have encountered the element types. + 9875 # We'll recompute them separately after parsing the entire program. + 9876 c7 0/subop/copy *(edi+0xc) -2/imm32/uninitialized # Typeinfo-total-size-in-bytes + 9877 $populate-mu-type:end: + 9878 # . reclaim locals + 9879 81 0/subop/add %esp 0x224/imm32 + 9880 # . restore registers + 9881 5f/pop-to-edi + 9882 5e/pop-to-esi + 9883 5b/pop-to-ebx + 9884 5a/pop-to-edx + 9885 59/pop-to-ecx + 9886 58/pop-to-eax + 9887 # reclaim curr-index + 9888 81 0/subop/add %esp 4/imm32 + 9889 # . epilogue + 9890 89/<- %esp 5/r32/ebp + 9891 5d/pop-to-ebp + 9892 c3/return + 9893 + 9894 $populate-mu-type:abort: + 9895 # error("unexpected top-level command: " word-slice "\n") + 9896 (write-buffered *(ebp+0x10) "incomplete type definition '") + 9897 (type-name *edi) # Typeinfo-id => eax + 9898 (write-buffered *(ebp+0x10) %eax) + 9899 (write-buffered *(ebp+0x10) "\n") + 9900 (flush *(ebp+0x10)) + 9901 (stop *(ebp+0x14) 1) + 9902 # never gets here + 9903 + 9904 type-name: # index: int -> result/eax: (addr array byte) + 9905 # . prologue + 9906 55/push-ebp + 9907 89/<- %ebp 4/r32/esp + 9908 # + 9909 (index Type-id *(ebp+8)) + 9910 $type-name:end: + 9911 # . epilogue + 9912 89/<- %esp 5/r32/ebp + 9913 5d/pop-to-ebp + 9914 c3/return + 9915 + 9916 index: # arr: (addr stream (handle array byte)), index: int -> result/eax: (addr array byte) + 9917 # . prologue + 9918 55/push-ebp + 9919 89/<- %ebp 4/r32/esp + 9920 # . save registers + 9921 56/push-esi + 9922 # TODO: bounds-check index + 9923 # esi = arr + 9924 8b/-> *(ebp+8) 6/r32/esi + 9925 # eax = index + 9926 8b/-> *(ebp+0xc) 0/r32/eax + 9927 # eax = *(arr + 12 + index) + 9928 8b/-> *(esi+eax+0xc) 0/r32/eax + 9929 $index:end: + 9930 # . restore registers + 9931 5e/pop-to-esi + 9932 # . epilogue + 9933 89/<- %esp 5/r32/ebp + 9934 5d/pop-to-ebp + 9935 c3/return + 9936 + 9937 ####################################################### + 9938 # Compute type sizes + 9939 ####################################################### + 9940 + 9941 # Compute the sizes of all user-defined types. + 9942 # We'll need the sizes of their elements, which may be other user-defined + 9943 # types, which we will compute as needed. + 9944 + 9945 # Initially, all user-defined types have their sizes set to -2 (invalid) + 9946 populate-mu-type-sizes: # err: (addr buffered-file), ed: (addr exit-descriptor) + 9947 # . prologue + 9948 55/push-ebp + 9949 89/<- %ebp 4/r32/esp + 9950 $populate-mu-type-sizes:total-sizes: + 9951 # var curr/eax: (addr typeinfo) = lookup(Program->types) + 9952 (lookup *_Program-types *_Program-types->payload) # => eax + 9953 { + 9954 # if (curr == null) break + 9955 3d/compare-eax-and 0/imm32/null + 9956 74/jump-if-= break/disp8 + 9957 (populate-mu-type-sizes-in-type %eax *(ebp+8) *(ebp+0xc)) + 9958 # curr = lookup(curr->next) + 9959 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax + 9960 eb/jump loop/disp8 + 9961 } + 9962 $populate-mu-type-sizes:offsets: + 9963 # curr = *Program->types + 9964 (lookup *_Program-types *_Program-types->payload) # => eax + 9965 { + 9966 # if (curr == null) break + 9967 3d/compare-eax-and 0/imm32/null + 9968 74/jump-if-= break/disp8 + 9969 (populate-mu-type-offsets %eax *(ebp+8) *(ebp+0xc)) + 9970 # curr = curr->next + 9971 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax + 9972 eb/jump loop/disp8 + 9973 } + 9974 $populate-mu-type-sizes:end: + 9975 # . epilogue + 9976 89/<- %esp 5/r32/ebp + 9977 5d/pop-to-ebp + 9978 c3/return + 9979 + 9980 # compute sizes of all fields, recursing as necessary + 9981 # sum up all their sizes to arrive at total size + 9982 # fields may be out of order, but that doesn't affect the answer + 9983 populate-mu-type-sizes-in-type: # T: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) + 9984 # . prologue + 9985 55/push-ebp + 9986 89/<- %ebp 4/r32/esp + 9987 # . save registers + 9988 50/push-eax + 9989 51/push-ecx + 9990 52/push-edx + 9991 56/push-esi + 9992 57/push-edi + 9993 # esi = T + 9994 8b/-> *(ebp+8) 6/r32/esi + 9995 # if T is already computed, return + 9996 81 7/subop/compare *(esi+0xc) 0/imm32 # Typeinfo-total-size-in-bytes + 9997 0f 8d/jump-if->= $populate-mu-type-sizes-in-type:end/disp32 + 9998 # if T is being computed, abort + 9999 81 7/subop/compare *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes +10000 0f 84/jump-if-= $populate-mu-type-sizes-in-type:abort/disp32 +10001 # tag T (-2 to -1) to avoid infinite recursion +10002 c7 0/subop/copy *(esi+0xc) -1/imm32/being-computed # Typeinfo-total-size-in-bytes +10003 # var total-size/edi: int = 0 +10004 bf/copy-to-edi 0/imm32 +10005 # - for every field, if it's a user-defined type, compute its size +10006 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) +10007 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax +10008 89/<- %ecx 0/r32/eax +10009 # var table-size/edx: int = table->write +10010 8b/-> *ecx 2/r32/edx # stream-write +10011 # var curr/ecx: (addr table_row) = table->data +10012 8d/copy-address *(ecx+0xc) 1/r32/ecx +10013 # var max/edx: (addr table_row) = table->data + table->write +10014 8d/copy-address *(ecx+edx) 2/r32/edx +10015 { +10016 $populate-mu-type-sizes-in-type:loop: +10017 # if (curr >= max) break +10018 39/compare %ecx 2/r32/edx +10019 73/jump-if-addr>= break/disp8 +10020 # var t/eax: (addr typeinfo-entry) = lookup(curr->value) +10021 (lookup *(ecx+8) *(ecx+0xc)) # => eax +10022 # if (t->input-var == 0) silently ignore it; we'll emit a nice error message while type-checking +10023 81 7/subop/compare *eax 0/imm32 # Typeinfo-entry-input-var +10024 74/jump-if-= $populate-mu-type-sizes-in-type:end/disp8 +10025 # compute size of t->input-var +10026 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax +10027 (compute-size-of-var %eax) # => eax +10028 # result += eax +10029 01/add-to %edi 0/r32/eax +10030 # curr += row-size +10031 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size +10032 # +10033 eb/jump loop/disp8 +10034 } +10035 # - save result +10036 89/<- *(esi+0xc) 7/r32/edi # Typeinfo-total-size-in-bytes +10037 $populate-mu-type-sizes-in-type:end: +10038 # . restore registers +10039 5f/pop-to-edi +10040 5e/pop-to-esi +10041 5a/pop-to-edx +10042 59/pop-to-ecx +10043 58/pop-to-eax +10044 # . epilogue +10045 89/<- %esp 5/r32/ebp +10046 5d/pop-to-ebp +10047 c3/return +10048 +10049 $populate-mu-type-sizes-in-type:abort: +10050 (write-buffered *(ebp+0xc) "cycle in type definitions\n") +10051 (flush *(ebp+0xc)) +10052 (stop *(ebp+0x10) 1) +10053 # never gets here +10054 +10055 # Analogous to size-of, except we need to compute what size-of can just read +10056 # off the right data structures. +10057 compute-size-of-var: # in: (addr var) -> result/eax: int +10058 # . prologue +10059 55/push-ebp +10060 89/<- %ebp 4/r32/esp +10061 # . push registers +10062 51/push-ecx +10063 # var t/ecx: (addr tree type-id) = lookup(v->type) +10064 8b/-> *(ebp+8) 1/r32/ecx +10065 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +10066 89/<- %ecx 0/r32/eax +10067 # if (t->is-atom == false) t = lookup(t->left) +10068 { +10069 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom +10070 75/jump-if-!= break/disp8 +10071 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax +10072 89/<- %ecx 0/r32/eax +10073 } +10074 # TODO: ensure t is an atom +10075 (compute-size-of-type-id *(ecx+4)) # Tree-value => eax +10076 $compute-size-of-var:end: +10077 # . restore registers +10078 59/pop-to-ecx +10079 # . epilogue +10080 89/<- %esp 5/r32/ebp +10081 5d/pop-to-ebp +10082 c3/return +10083 +10084 compute-size-of-type-id: # t: type-id -> result/eax: int +10085 # . prologue +10086 55/push-ebp +10087 89/<- %ebp 4/r32/esp +10088 # . save registers +10089 51/push-ecx +10090 # var out/ecx: (handle typeinfo) +10091 68/push 0/imm32 +10092 68/push 0/imm32 +10093 89/<- %ecx 4/r32/esp +10094 # eax = t +10095 8b/-> *(ebp+8) 0/r32/eax +10096 # if t is a literal, return 0 +10097 3d/compare-eax-and 0/imm32/literal +10098 0f 84/jump-if-= $compute-size-of-type-id:end/disp32 # eax changes type from type-id to int +10099 # if t is a byte, return 4 (because we don't really support non-multiples of 4) +10100 3d/compare-eax-and 8/imm32/byte +10101 { +10102 75/jump-if-!= break/disp8 +10103 b8/copy-to-eax 4/imm32 +10104 eb/jump $compute-size-of-type-id:end/disp8 +10105 } +10106 # if t is a handle, return 8 +10107 3d/compare-eax-and 4/imm32/handle +10108 { +10109 75/jump-if-!= break/disp8 +10110 b8/copy-to-eax 8/imm32 +10111 eb/jump $compute-size-of-type-id:end/disp8 # eax changes type from type-id to int +10112 } +10113 # if t is a user-defined type, compute its size +10114 # TODO: support non-atom type +10115 (find-typeinfo %eax %ecx) +10116 { +10117 81 7/subop/compare *ecx 0/imm32 +10118 74/jump-if-= break/disp8 +10119 $compute-size-of-type-id:user-defined: +10120 (populate-mu-type-sizes %eax) +10121 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes +10122 eb/jump $compute-size-of-type-id:end/disp8 +10123 } +10124 # otherwise return the word size +10125 b8/copy-to-eax 4/imm32 +10126 $compute-size-of-type-id:end: +10127 # . reclaim locals +10128 81 0/subop/add %esp 8/imm32 +10129 # . restore registers +10130 59/pop-to-ecx +10131 # . epilogue +10132 89/<- %esp 5/r32/ebp +10133 5d/pop-to-ebp +10134 c3/return +10135 +10136 # at this point we have total sizes for all user-defined types +10137 # compute offsets for each element +10138 # complication: fields may be out of order +10139 populate-mu-type-offsets: # in: (addr typeinfo), err: (addr buffered-file), ed: (addr exit-descriptor) +10140 # . prologue +10141 55/push-ebp +10142 89/<- %ebp 4/r32/esp +10143 # . save registers +10144 50/push-eax +10145 51/push-ecx +10146 52/push-edx +10147 53/push-ebx +10148 56/push-esi +10149 57/push-edi +10150 #? (dump-typeinfos "aaa\n") +10151 # var curr-offset/edi: int = 0 +10152 bf/copy-to-edi 0/imm32 +10153 # var table/ecx: (addr table string_key (handle typeinfo-entry)) = lookup(in->fields) +10154 8b/-> *(ebp+8) 1/r32/ecx +10155 (lookup *(ecx+4) *(ecx+8)) # Typeinfo-fields Typeinfo-fields => eax +10156 89/<- %ecx 0/r32/eax +10157 # var num-elems/edx: int = table->write / Typeinfo-fields-row-size +10158 8b/-> *ecx 2/r32/edx # stream-write +10159 c1 5/subop/shift-right-logical %edx 4/imm8 +10160 # var i/ebx: int = 0 +10161 bb/copy-to-ebx 0/imm32 +10162 { +10163 $populate-mu-type-offsets:loop: +10164 39/compare %ebx 2/r32/edx +10165 0f 8d/jump-if->= break/disp32 +10166 #? (write-buffered Stderr "looking up index ") +10167 #? (print-int32-buffered Stderr %ebx) +10168 #? (write-buffered Stderr " in ") +10169 #? (print-int32-buffered Stderr *(ebp+8)) +10170 #? (write-buffered Stderr Newline) +10171 #? (flush Stderr) +10172 # var v/esi: (addr typeinfo-entry) +10173 (locate-typeinfo-entry-with-index %ecx %ebx *(ebp+0xc) *(ebp+0x10)) # => eax +10174 89/<- %esi 0/r32/eax +10175 # if v is null, silently move on; we'll emit a nice error message while type-checking +10176 81 7/subop/compare %esi 0/imm32 # Typeinfo-entry-input-var +10177 74/jump-if-= $populate-mu-type-offsets:end/disp8 +10178 # if (v->input-var == 0) silently ignore v; we'll emit a nice error message while type-checking +10179 81 7/subop/compare *esi 0/imm32 # Typeinfo-entry-input-var +10180 74/jump-if-= $populate-mu-type-offsets:end/disp8 +10181 # v->output-var->offset = curr-offset +10182 # . eax: (addr var) +10183 (lookup *(esi+0xc) *(esi+0x10)) # Typeinfo-entry-output-var Typeinfo-entry-output-var => eax +10184 89/<- *(eax+0x14) 7/r32/edi # Var-offset +10185 # curr-offset += size-of(v->input-var) +10186 (lookup *esi *(esi+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax +10187 (size-of %eax) # => eax +10188 01/add-to %edi 0/r32/eax +10189 # ++i +10190 43/increment-ebx +10191 e9/jump loop/disp32 +10192 } +10193 $populate-mu-type-offsets:end: +10194 # . restore registers +10195 5f/pop-to-edi +10196 5e/pop-to-esi +10197 5b/pop-to-ebx +10198 5a/pop-to-edx +10199 59/pop-to-ecx +10200 58/pop-to-eax +10201 # . epilogue +10202 89/<- %esp 5/r32/ebp +10203 5d/pop-to-ebp +10204 c3/return +10205 +10206 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) +10207 # . prologue +10208 55/push-ebp +10209 89/<- %ebp 4/r32/esp +10210 # . save registers +10211 51/push-ecx +10212 52/push-edx +10213 53/push-ebx +10214 56/push-esi +10215 57/push-edi +10216 # esi = table +10217 8b/-> *(ebp+8) 6/r32/esi +10218 # var curr/ecx: (addr row (handle array byte) (handle typeinfo-entry)) = table->data +10219 8d/copy-address *(esi+0xc) 1/r32/ecx +10220 # var max/edx: (addr byte) = &table->data[table->write] +10221 8b/-> *esi 2/r32/edx +10222 8d/copy-address *(ecx+edx) 2/r32/edx 10223 { -10224 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom -10225 75/jump-if-!= break/disp8 -10226 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax -10227 89/<- %ecx 0/r32/eax -10228 } -10229 # TODO: assert t->is-atom? -10230 (size-of-type-id *(ecx+4)) # Tree-value => eax -10231 $size-of-deref:end: -10232 # . restore registers -10233 59/pop-to-ecx -10234 # . epilogue -10235 89/<- %esp 5/r32/ebp -10236 5d/pop-to-ebp -10237 c3/return -10238 -10239 is-mu-array?: # t: (addr tree type-id) -> result/eax: boolean -10240 # . prologue -10241 55/push-ebp -10242 89/<- %ebp 4/r32/esp -10243 # . save registers -10244 51/push-ecx -10245 # ecx = t -10246 8b/-> *(ebp+8) 1/r32/ecx -10247 # if t->is-atom?, return false -10248 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom -10249 75/jump-if-!= $is-mu-array?:return-false/disp8 -10250 # if !t->left->is-atom?, return false -10251 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax -10252 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom -10253 74/jump-if-= $is-mu-array?:return-false/disp8 -10254 # return t->left->value == array -10255 81 7/subop/compare *(eax+4) 3/imm32/array-type-id # Tree-value -10256 0f 94/set-if-= %al -10257 81 4/subop/and %eax 0xff/imm32 -10258 eb/jump $is-mu-array?:end/disp8 -10259 $is-mu-array?:return-false: -10260 b8/copy-to-eax 0/imm32/false -10261 $is-mu-array?:end: -10262 # . restore registers -10263 59/pop-to-ecx -10264 # . epilogue -10265 89/<- %esp 5/r32/ebp -10266 5d/pop-to-ebp -10267 c3/return -10268 -10269 size-of-array: # a: (addr tree type-id) -> result/eax: int -10270 # . prologue -10271 55/push-ebp -10272 89/<- %ebp 4/r32/esp -10273 # . save registers -10274 51/push-ecx -10275 52/push-edx -10276 # -10277 8b/-> *(ebp+8) 1/r32/ecx -10278 # TODO: assert that a->left is 'array' -10279 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax -10280 89/<- %ecx 0/r32/eax -10281 # var elem-type/edx: type-id = a->right->left->value -10282 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax -10283 8b/-> *(eax+4) 2/r32/edx # Tree-value -10284 # var array-size/ecx: int = a->right->right->left->value -10285 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax -10286 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax -10287 8b/-> *(eax+4) 1/r32/ecx # Tree-value -10288 # return array-size * size-of(elem-type) -10289 (size-of-type-id-as-array-element %edx) # => eax -10290 f7 4/subop/multiply-into-eax %ecx -10291 05/add-to-eax 4/imm32 # for array size -10292 $size-of-array:end: -10293 # . restore registers -10294 5a/pop-to-edx -10295 59/pop-to-ecx -10296 # . epilogue -10297 89/<- %esp 5/r32/ebp -10298 5d/pop-to-ebp -10299 c3/return -10300 -10301 size-of-type-id: # t: type-id -> result/eax: int -10302 # . prologue -10303 55/push-ebp -10304 89/<- %ebp 4/r32/esp -10305 # . save registers -10306 51/push-ecx -10307 # var out/ecx: (handle typeinfo) -10308 68/push 0/imm32 -10309 68/push 0/imm32 -10310 89/<- %ecx 4/r32/esp -10311 # eax = t -10312 8b/-> *(ebp+8) 0/r32/eax -10313 # if t is a literal, return 0 -10314 3d/compare-eax-and 0/imm32 -10315 0f 84/jump-if-= $size-of-type-id:end/disp32 # eax changes type from type-id to int -10316 # if t is a byte, return 4 (because we don't really support non-multiples of 4) -10317 3d/compare-eax-and 8/imm32/byte -10318 { -10319 75/jump-if-!= break/disp8 -10320 b8/copy-to-eax 4/imm32 -10321 eb/jump $size-of-type-id:end/disp8 -10322 } -10323 # if t is a handle, return 8 -10324 3d/compare-eax-and 4/imm32/handle -10325 { -10326 75/jump-if-!= break/disp8 -10327 b8/copy-to-eax 8/imm32 -10328 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int -10329 } -10330 # if t is a user-defined type, return its size -10331 # TODO: support non-atom type -10332 (find-typeinfo %eax %ecx) +10224 $locate-typeinfo-entry-with-index:loop: +10225 39/compare %ecx 2/r32/edx +10226 73/jump-if-addr>= break/disp8 +10227 # var v/eax: (addr typeinfo-entry) +10228 (lookup *(ecx+8) *(ecx+0xc)) # => eax +10229 # if (v->index == idx) return v +10230 8b/-> *(eax+8) 3/r32/ebx # Typeinfo-entry-index +10231 #? (write-buffered Stderr "comparing ") +10232 #? (print-int32-buffered Stderr %ebx) +10233 #? (write-buffered Stderr " and ") +10234 #? (print-int32-buffered Stderr *(ebp+0xc)) +10235 #? (write-buffered Stderr Newline) +10236 #? (flush Stderr) +10237 39/compare *(ebp+0xc) 3/r32/ebx +10238 74/jump-if-= $locate-typeinfo-entry-with-index:end/disp8 +10239 # curr += Typeinfo-entry-size +10240 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-entry-size +10241 # +10242 eb/jump loop/disp8 +10243 } +10244 # return 0 +10245 b8/copy-to-eax 0/imm32 +10246 $locate-typeinfo-entry-with-index:end: +10247 #? (write-buffered Stderr "returning ") +10248 #? (print-int32-buffered Stderr %eax) +10249 #? (write-buffered Stderr Newline) +10250 #? (flush Stderr) +10251 # . restore registers +10252 5f/pop-to-edi +10253 5e/pop-to-esi +10254 5b/pop-to-ebx +10255 5a/pop-to-edx +10256 59/pop-to-ecx +10257 # . epilogue +10258 89/<- %esp 5/r32/ebp +10259 5d/pop-to-ebp +10260 c3/return +10261 +10262 dump-typeinfos: # hdr: (addr array byte) +10263 # . prologue +10264 55/push-ebp +10265 89/<- %ebp 4/r32/esp +10266 # . save registers +10267 50/push-eax +10268 # +10269 (write-buffered Stderr *(ebp+8)) +10270 (flush Stderr) +10271 # var curr/eax: (addr typeinfo) = lookup(Program->types) +10272 (lookup *_Program-types *_Program-types->payload) # => eax +10273 { +10274 # if (curr == null) break +10275 3d/compare-eax-and 0/imm32 +10276 74/jump-if-= break/disp8 +10277 (write-buffered Stderr "---\n") +10278 (flush Stderr) +10279 (dump-typeinfo %eax) +10280 # curr = lookup(curr->next) +10281 (lookup *(eax+0x10) *(eax+0x14)) # Typeinfo-next Typeinfo-next => eax +10282 eb/jump loop/disp8 +10283 } +10284 $dump-typeinfos:end: +10285 # . restore registers +10286 58/pop-to-eax +10287 # . epilogue +10288 89/<- %esp 5/r32/ebp +10289 5d/pop-to-ebp +10290 c3/return +10291 +10292 dump-typeinfo: # in: (addr typeinfo) +10293 # . prologue +10294 55/push-ebp +10295 89/<- %ebp 4/r32/esp +10296 # . save registers +10297 50/push-eax +10298 51/push-ecx +10299 52/push-edx +10300 53/push-ebx +10301 56/push-esi +10302 57/push-edi +10303 # esi = in +10304 8b/-> *(ebp+8) 6/r32/esi +10305 # var table/ecx: (addr table (handle array byte) (handle typeinfo-entry)) = lookup(T->fields) +10306 (lookup *(esi+4) *(esi+8)) # Typeinfo-fields Typeinfo-fields => eax +10307 89/<- %ecx 0/r32/eax +10308 (write-buffered Stderr "id:") +10309 (print-int32-buffered Stderr *esi) +10310 (write-buffered Stderr "\n") +10311 (write-buffered Stderr "fields @ ") +10312 (print-int32-buffered Stderr %ecx) +10313 (write-buffered Stderr Newline) +10314 (flush Stderr) +10315 (write-buffered Stderr " write: ") +10316 (print-int32-buffered Stderr *ecx) +10317 (write-buffered Stderr Newline) +10318 (flush Stderr) +10319 (write-buffered Stderr " read: ") +10320 (print-int32-buffered Stderr *(ecx+4)) +10321 (write-buffered Stderr Newline) +10322 (flush Stderr) +10323 (write-buffered Stderr " size: ") +10324 (print-int32-buffered Stderr *(ecx+8)) +10325 (write-buffered Stderr Newline) +10326 (flush Stderr) +10327 # var table-size/edx: int = table->write +10328 8b/-> *ecx 2/r32/edx # stream-write +10329 # var curr/ecx: (addr table_row) = table->data +10330 8d/copy-address *(ecx+0xc) 1/r32/ecx +10331 # var max/edx: (addr table_row) = table->data + table->write +10332 8d/copy-address *(ecx+edx) 2/r32/edx 10333 { -10334 81 7/subop/compare *ecx 0/imm32 -10335 74/jump-if-= break/disp8 -10336 $size-of-type-id:user-defined: -10337 (lookup *ecx *(ecx+4)) # => eax -10338 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes -10339 eb/jump $size-of-type-id:end/disp8 -10340 } -10341 # otherwise return the word size -10342 b8/copy-to-eax 4/imm32 -10343 $size-of-type-id:end: -10344 # . reclaim locals -10345 81 0/subop/add %esp 8/imm32 -10346 # . restore registers -10347 59/pop-to-ecx -10348 # . epilogue -10349 89/<- %esp 5/r32/ebp -10350 5d/pop-to-ebp -10351 c3/return -10352 -10353 type-equal?: # a: (addr tree type-id), b: (addr tree type-id) -> result/eax: boolean -10354 # . prologue -10355 55/push-ebp -10356 89/<- %ebp 4/r32/esp -10357 # . save registers -10358 51/push-ecx -10359 52/push-edx -10360 53/push-ebx -10361 # ecx = a -10362 8b/-> *(ebp+8) 1/r32/ecx -10363 # edx = b -10364 8b/-> *(ebp+0xc) 2/r32/edx -10365 $type-equal?:compare-addr: -10366 # if (a == b) return true -10367 8b/-> %ecx 0/r32/eax # Var-type -10368 39/compare %edx 0/r32/eax # Var-type -10369 b8/copy-to-eax 1/imm32/true -10370 0f 84/jump-if-= $type-equal?:end/disp32 -10371 $type-equal?:compare-atom-state: -10372 # if (a->is-atom? != b->is-atom?) return false -10373 8b/-> *ecx 3/r32/ebx # Tree-value -10374 39/compare *edx 3/r32/ebx # Tree-value -10375 b8/copy-to-eax 0/imm32/false -10376 0f 85/jump-if-!= $type-equal?:end/disp32 -10377 # if a->is-atom? return (a->value == b->value) -10378 { -10379 $type-equal?:check-atom: -10380 81 7/subop/compare %ebx 0/imm32/false -10381 74/jump-if-= break/disp8 -10382 $type-equal?:is-atom: -10383 8b/-> *(ecx+4) 0/r32/eax # Tree-value -10384 39/compare *(edx+4) 0/r32/eax # Tree-value -10385 0f 94/set-if-= %al -10386 81 4/subop/and %eax 0xff/imm32 -10387 e9/jump $type-equal?:end/disp32 -10388 } -10389 $type-equal?:check-left: -10390 # if (!type-equal?(a->left, b->left)) return false -10391 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax -10392 89/<- %ebx 0/r32/eax -10393 (lookup *(edx+4) *(edx+8)) # Tree-left Tree-left => eax -10394 (type-equal? %eax %ebx) # => eax -10395 3d/compare-eax-and 0/imm32/false -10396 74/jump-if-= $type-equal?:end/disp8 -10397 $type-equal?:check-right: -10398 # return type-equal?(a->right, b->right) -10399 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax -10400 89/<- %ebx 0/r32/eax -10401 (lookup *(edx+0xc) *(edx+0x10)) # Tree-right Tree-right => eax -10402 (type-equal? %eax %ebx) # => eax -10403 $type-equal?:end: -10404 # . restore registers -10405 5b/pop-to-ebx -10406 5a/pop-to-edx -10407 59/pop-to-ecx -10408 # . epilogue -10409 89/<- %esp 5/r32/ebp -10410 5d/pop-to-ebp -10411 c3/return -10412 -10413 ####################################################### -10414 # Code-generation -10415 ####################################################### -10416 -10417 == data -10418 -10419 # Global state added to each var record when performing code-generation. -10420 Curr-local-stack-offset: # (addr int) -10421 0/imm32 -10422 -10423 == code -10424 -10425 emit-subx: # out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) -10426 # . prologue -10427 55/push-ebp -10428 89/<- %ebp 4/r32/esp -10429 # . save registers -10430 50/push-eax -10431 # var curr/eax: (addr function) = *Program->functions -10432 (lookup *_Program-functions *_Program-functions->payload) # => eax -10433 { -10434 # if (curr == null) break -10435 3d/compare-eax-and 0/imm32 -10436 0f 84/jump-if-= break/disp32 -10437 (emit-subx-function *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) -10438 # curr = lookup(curr->next) -10439 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax -10440 e9/jump loop/disp32 -10441 } -10442 $emit-subx:end: -10443 # . restore registers -10444 58/pop-to-eax -10445 # . epilogue -10446 89/<- %esp 5/r32/ebp -10447 5d/pop-to-ebp -10448 c3/return -10449 -10450 emit-subx-function: # out: (addr buffered-file), f: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) -10451 # . prologue -10452 55/push-ebp -10453 89/<- %ebp 4/r32/esp -10454 # some preprocessing -10455 (populate-mu-type-offsets-in-inouts *(ebp+0xc)) -10456 # . save registers -10457 50/push-eax -10458 51/push-ecx -10459 52/push-edx -10460 # initialize some global state -10461 c7 0/subop/copy *Curr-block-depth 1/imm32 # Important: keep this in sync with the parse phase -10462 c7 0/subop/copy *Curr-local-stack-offset 0/imm32 -10463 # ecx = f -10464 8b/-> *(ebp+0xc) 1/r32/ecx -10465 # var vars/edx: (stack (addr var) 256) -10466 81 5/subop/subtract %esp 0xc00/imm32 -10467 68/push 0xc00/imm32/size -10468 68/push 0/imm32/top -10469 89/<- %edx 4/r32/esp -10470 # var name/eax: (addr array byte) = lookup(f->name) -10471 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax -10472 # -10473 (write-buffered *(ebp+8) %eax) -10474 (write-buffered *(ebp+8) ":\n") -10475 (emit-subx-prologue *(ebp+8)) -10476 # var body/eax: (addr block) = lookup(f->body) -10477 (lookup *(ecx+0x18) *(ecx+0x1c)) # Function-body Function-body => eax -10478 # -10479 (emit-subx-block *(ebp+8) %eax %edx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -10480 (emit-subx-epilogue *(ebp+8)) -10481 # TODO: validate that *Curr-block-depth and *Curr-local-stack-offset have -10482 # been cleaned up -10483 $emit-subx-function:end: -10484 # . reclaim locals -10485 81 0/subop/add %esp 0xc08/imm32 +10334 $dump-typeinfo:loop: +10335 # if (curr >= max) break +10336 39/compare %ecx 2/r32/edx +10337 0f 83/jump-if-addr>= break/disp32 +10338 (write-buffered Stderr " row:\n") +10339 (write-buffered Stderr " key: ") +10340 (print-int32-buffered Stderr *ecx) +10341 (write-buffered Stderr ",") +10342 (print-int32-buffered Stderr *(ecx+4)) +10343 (write-buffered Stderr " = '") +10344 (lookup *ecx *(ecx+4)) +10345 (write-buffered Stderr %eax) +10346 (write-buffered Stderr "' @ ") +10347 (print-int32-buffered Stderr %eax) +10348 (write-buffered Stderr Newline) +10349 (flush Stderr) +10350 (write-buffered Stderr " value: ") +10351 (print-int32-buffered Stderr *(ecx+8)) +10352 (write-buffered Stderr ",") +10353 (print-int32-buffered Stderr *(ecx+0xc)) +10354 (write-buffered Stderr " = typeinfo-entry@") +10355 (lookup *(ecx+8) *(ecx+0xc)) +10356 (print-int32-buffered Stderr %eax) +10357 (write-buffered Stderr Newline) +10358 (flush Stderr) +10359 (write-buffered Stderr " input var@") +10360 (dump-var 5 %eax) +10361 (lookup *(ecx+8) *(ecx+0xc)) +10362 (write-buffered Stderr " index: ") +10363 (print-int32-buffered Stderr *(eax+8)) +10364 (write-buffered Stderr Newline) +10365 (flush Stderr) +10366 (write-buffered Stderr " output var@") +10367 8d/copy-address *(eax+0xc) 0/r32/eax # Typeinfo-entry-output-var +10368 (dump-var 5 %eax) +10369 (flush Stderr) +10370 # curr += row-size +10371 81 0/subop/add %ecx 0x10/imm32 # Typeinfo-fields-row-size +10372 # +10373 e9/jump loop/disp32 +10374 } +10375 $dump-typeinfo:end: +10376 # . restore registers +10377 5f/pop-to-edi +10378 5e/pop-to-esi +10379 5b/pop-to-ebx +10380 5a/pop-to-edx +10381 59/pop-to-ecx +10382 58/pop-to-eax +10383 # . epilogue +10384 89/<- %esp 5/r32/ebp +10385 5d/pop-to-ebp +10386 c3/return +10387 +10388 dump-var: # indent: int, v: (addr handle var) +10389 # . prologue +10390 55/push-ebp +10391 89/<- %ebp 4/r32/esp +10392 # . save registers +10393 50/push-eax +10394 53/push-ebx +10395 # eax = v +10396 8b/-> *(ebp+0xc) 0/r32/eax +10397 # +10398 (print-int32-buffered Stderr *eax) +10399 (write-buffered Stderr ",") +10400 (print-int32-buffered Stderr *(eax+4)) +10401 (write-buffered Stderr "->") +10402 (lookup *eax *(eax+4)) +10403 (print-int32-buffered Stderr %eax) +10404 (write-buffered Stderr Newline) +10405 (flush Stderr) +10406 { +10407 3d/compare-eax-and 0/imm32 +10408 0f 84/jump-if-= break/disp32 +10409 (emit-indent Stderr *(ebp+8)) +10410 (write-buffered Stderr "name: ") +10411 89/<- %ebx 0/r32/eax +10412 (print-int32-buffered Stderr *ebx) # Var-name +10413 (write-buffered Stderr ",") +10414 (print-int32-buffered Stderr *(ebx+4)) # Var-name +10415 (write-buffered Stderr "->") +10416 (lookup *ebx *(ebx+4)) # Var-name +10417 (print-int32-buffered Stderr %eax) +10418 { +10419 3d/compare-eax-and 0/imm32 +10420 74/jump-if-= break/disp8 +10421 (write-buffered Stderr Space) +10422 (write-buffered Stderr %eax) +10423 } +10424 (write-buffered Stderr Newline) +10425 (flush Stderr) +10426 (emit-indent Stderr *(ebp+8)) +10427 (write-buffered Stderr "block depth: ") +10428 (print-int32-buffered Stderr *(ebx+0x10)) # Var-block-depth +10429 (write-buffered Stderr Newline) +10430 (flush Stderr) +10431 (emit-indent Stderr *(ebp+8)) +10432 (write-buffered Stderr "stack offset: ") +10433 (print-int32-buffered Stderr *(ebx+0x14)) # Var-offset +10434 (write-buffered Stderr Newline) +10435 (flush Stderr) +10436 (emit-indent Stderr *(ebp+8)) +10437 (write-buffered Stderr "reg: ") +10438 (print-int32-buffered Stderr *(ebx+0x18)) # Var-register +10439 (write-buffered Stderr ",") +10440 (print-int32-buffered Stderr *(ebx+0x1c)) # Var-register +10441 (write-buffered Stderr "->") +10442 (flush Stderr) +10443 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register +10444 (print-int32-buffered Stderr %eax) +10445 { +10446 3d/compare-eax-and 0/imm32 +10447 74/jump-if-= break/disp8 +10448 (write-buffered Stderr Space) +10449 (write-buffered Stderr %eax) +10450 } +10451 (write-buffered Stderr Newline) +10452 (flush Stderr) +10453 } +10454 $dump-var:end: +10455 # . restore registers +10456 5b/pop-to-ebx +10457 58/pop-to-eax +10458 # . epilogue +10459 89/<- %esp 5/r32/ebp +10460 5d/pop-to-ebp +10461 c3/return +10462 +10463 ####################################################### +10464 # Type-checking +10465 ####################################################### +10466 +10467 check-mu-types: # err: (addr buffered-file), ed: (addr exit-descriptor) +10468 # . prologue +10469 55/push-ebp +10470 89/<- %ebp 4/r32/esp +10471 # . save registers +10472 50/push-eax +10473 # var curr/eax: (addr function) = *Program->functions +10474 (lookup *_Program-functions *_Program-functions->payload) # => eax +10475 { +10476 $check-mu-types:loop: +10477 # if (curr == null) break +10478 3d/compare-eax-and 0/imm32 +10479 0f 84/jump-if-= break/disp32 +10480 (check-mu-function %eax *(ebp+8) *(ebp+0xc)) +10481 # curr = lookup(curr->next) +10482 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax +10483 e9/jump loop/disp32 +10484 } +10485 $check-mu-types:end: 10486 # . restore registers -10487 5a/pop-to-edx -10488 59/pop-to-ecx -10489 58/pop-to-eax -10490 # . epilogue -10491 89/<- %esp 5/r32/ebp -10492 5d/pop-to-ebp -10493 c3/return -10494 -10495 populate-mu-type-offsets-in-inouts: # f: (addr function) -10496 # . prologue -10497 55/push-ebp -10498 89/<- %ebp 4/r32/esp -10499 # . save registers -10500 50/push-eax -10501 51/push-ecx -10502 52/push-edx -10503 53/push-ebx -10504 57/push-edi -10505 # var next-offset/edx: int = 8 -10506 ba/copy-to-edx 8/imm32 -10507 # var curr/ecx: (addr list var) = lookup(f->inouts) -10508 8b/-> *(ebp+8) 1/r32/ecx -10509 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax -10510 89/<- %ecx 0/r32/eax -10511 { -10512 $populate-mu-type-offsets-in-inouts:loop: -10513 81 7/subop/compare %ecx 0/imm32 -10514 74/jump-if-= break/disp8 -10515 # var v/ebx: (addr var) = lookup(curr->value) -10516 (lookup *ecx *(ecx+4)) # List-value List-value => eax -10517 89/<- %ebx 0/r32/eax -10518 #? (lookup *ebx *(ebx+4)) -10519 #? (write-buffered Stderr "setting offset of fn inout ") -10520 #? (write-buffered Stderr %eax) -10521 #? (write-buffered Stderr "@") -10522 #? (print-int32-buffered Stderr %ebx) -10523 #? (write-buffered Stderr " to ") -10524 #? (print-int32-buffered Stderr %edx) -10525 #? (write-buffered Stderr Newline) -10526 #? (flush Stderr) -10527 # v->offset = next-offset -10528 89/<- *(ebx+0x14) 2/r32/edx # Var-offset -10529 # next-offset += size-of(v) -10530 (size-of %ebx) # => eax -10531 01/add-to %edx 0/r32/eax -10532 # curr = lookup(curr->next) -10533 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -10534 89/<- %ecx 0/r32/eax -10535 # -10536 eb/jump loop/disp8 -10537 } -10538 $populate-mu-type-offsets-in-inouts:end: -10539 # . restore registers -10540 5f/pop-to-edi -10541 5b/pop-to-ebx -10542 5a/pop-to-edx -10543 59/pop-to-ecx -10544 58/pop-to-eax -10545 # . epilogue -10546 89/<- %esp 5/r32/ebp -10547 5d/pop-to-ebp -10548 c3/return -10549 -10550 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) -10551 # . prologue -10552 55/push-ebp -10553 89/<- %ebp 4/r32/esp -10554 # . save registers -10555 50/push-eax -10556 51/push-ecx -10557 53/push-ebx -10558 56/push-esi -10559 # esi = stmts -10560 8b/-> *(ebp+0xc) 6/r32/esi -10561 # -10562 { -10563 $emit-subx-stmt-list:loop: -10564 81 7/subop/compare %esi 0/imm32 -10565 0f 84/jump-if-= break/disp32 -10566 # var curr-stmt/ecx: (addr stmt) = lookup(stmts->value) -10567 (lookup *esi *(esi+4)) # List-value List-value => eax -10568 89/<- %ecx 0/r32/eax -10569 { -10570 $emit-subx-stmt-list:check-for-block: -10571 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag -10572 75/jump-if-!= break/disp8 -10573 $emit-subx-stmt-list:block: -10574 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -10575 } -10576 { -10577 $emit-subx-stmt-list:check-for-stmt: -10578 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag -10579 0f 85/jump-if-!= break/disp32 -10580 $emit-subx-stmt-list:stmt1: -10581 { -10582 (is-mu-branch? %ecx) # => eax -10583 3d/compare-eax-and 0/imm32/false -10584 0f 84/jump-if-= break/disp32 -10585 $emit-subx-stmt-list:branch-stmt: -10586 +-- 27 lines: # unconditional loops ----------------------------------------------------------------------------------------------------------------------------------------------------- -10613 +-- 16 lines: # unconditional breaks ---------------------------------------------------------------------------------------------------------------------------------------------------- -10629 +-- 38 lines: # simple conditional branches without a target ---------------------------------------------------------------------------------------------------------------------------- -10667 +-- 19 lines: # conditional branches with an explicit target ---------------------------------------------------------------------------------------------------------------------------- -10686 } -10687 $emit-subx-stmt-list:1-to-1: -10688 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x18) *(ebp+0x1c)) -10689 e9/jump $emit-subx-stmt-list:continue/disp32 -10690 } -10691 { -10692 $emit-subx-stmt-list:check-for-var-def: -10693 81 7/subop/compare *ecx 2/imm32/var-def # Stmt-tag -10694 75/jump-if-!= break/disp8 -10695 $emit-subx-stmt-list:var-def: -10696 (emit-subx-var-def *(ebp+8) %ecx) -10697 (push *(ebp+0x10) *(ecx+4)) # Vardef-var -10698 (push *(ebp+0x10) *(ecx+8)) # Vardef-var -10699 (push *(ebp+0x10) 0) # Live-var-register-spilled = 0 for vars on the stack -10700 # -10701 eb/jump $emit-subx-stmt-list:continue/disp8 -10702 } -10703 { -10704 $emit-subx-stmt-list:check-for-reg-var-def: -10705 81 7/subop/compare *ecx 3/imm32/reg-var-def # Stmt-tag -10706 0f 85/jump-if-!= break/disp32 -10707 $emit-subx-stmt-list:reg-var-def: -10708 # TODO: ensure that there's exactly one output -10709 (push-output-and-maybe-emit-spill *(ebp+8) %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -10710 # emit the instruction as usual -10711 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x18) *(ebp+0x1c)) -10712 # -10713 eb/jump $emit-subx-stmt-list:continue/disp8 -10714 } -10715 $emit-subx-stmt-list:continue: -10716 # TODO: raise an error on unrecognized Stmt-tag -10717 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax -10718 89/<- %esi 0/r32/eax -10719 e9/jump loop/disp32 -10720 } -10721 $emit-subx-stmt-list:emit-cleanup: -10722 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) *Curr-block-depth) -10723 $emit-subx-stmt-list:clean-up: -10724 (clean-up-blocks *(ebp+0x10) *Curr-block-depth *(ebp+0x14)) -10725 $emit-subx-stmt-list:end: -10726 # . restore registers -10727 5e/pop-to-esi -10728 5b/pop-to-ebx -10729 59/pop-to-ecx -10730 58/pop-to-eax -10731 # . epilogue -10732 89/<- %esp 5/r32/ebp -10733 5d/pop-to-ebp -10734 c3/return -10735 -10736 # 'later-stmts' includes 'stmt', but will behave the same even without it; reg-var-def stmts are guaranteed not to write to function outputs. -10737 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) -10738 # . prologue -10739 55/push-ebp -10740 89/<- %ebp 4/r32/esp -10741 # . save registers -10742 50/push-eax -10743 51/push-ecx -10744 52/push-edx -10745 # ecx = stmt -10746 8b/-> *(ebp+0xc) 1/r32/ecx -10747 # var sv/eax: (addr stmt-var) = lookup(curr-stmt->outputs) -10748 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax -10749 # TODO: assert !sv->is-deref? -10750 # var v/ecx: (addr var) = lookup(sv->value) -10751 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -10752 89/<- %ecx 0/r32/eax -10753 # v->block-depth = *Curr-block-depth -10754 8b/-> *Curr-block-depth 0/r32/eax -10755 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -10756 #? (write-buffered Stderr "var ") -10757 #? (lookup *ecx *(ecx+4)) -10758 #? (write-buffered Stderr %eax) -10759 #? (write-buffered Stderr " at depth ") -10760 #? (print-int32-buffered Stderr *(ecx+0x10)) -10761 #? (write-buffered Stderr Newline) -10762 #? (flush Stderr) -10763 # ensure that v is in a register -10764 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -10765 0f 84/jump-if-= $push-output-and-maybe-emit-spill:abort/disp32 -10766 # var emit-spill?/edx: boolean = not-yet-spilled-this-block? && will-not-write-some-register?(fn) -10767 (not-yet-spilled-this-block? %ecx *(ebp+0x10)) # => eax -10768 89/<- %edx 0/r32/eax -10769 3d/compare-eax-and 0/imm32/false -10770 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 -10771 (will-not-write-some-register? %ecx *(ebp+0x14) *(ebp+0x18)) # => eax -10772 89/<- %edx 0/r32/eax -10773 # check emit-spill? -10774 3d/compare-eax-and 0/imm32/false -10775 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 -10776 # TODO: assert(size-of(output) == 4) -10777 # *Curr-local-stack-offset -= 4 -10778 81 5/subop/subtract *Curr-local-stack-offset 4/imm32 -10779 # emit spill -10780 (emit-indent *(ebp+8) *Curr-block-depth) -10781 (write-buffered *(ebp+8) "ff 6/subop/push %") -10782 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax -10783 (write-buffered *(ebp+8) %eax) -10784 (write-buffered *(ebp+8) Newline) -10785 $push-output-and-maybe-emit-spill:push: -10786 8b/-> *(ebp+0xc) 1/r32/ecx -10787 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax -10788 # push(vars, {sv->value, emit-spill?}) -10789 (push *(ebp+0x10) *eax) # Stmt-var-value -10790 (push *(ebp+0x10) *(eax+4)) # Stmt-var-value -10791 (push *(ebp+0x10) %edx) -10792 $push-output-and-maybe-emit-spill:end: -10793 # . restore registers -10794 5a/pop-to-edx -10795 59/pop-to-ecx -10796 58/pop-to-eax -10797 # . epilogue -10798 89/<- %esp 5/r32/ebp -10799 5d/pop-to-ebp -10800 c3/return -10801 -10802 $push-output-and-maybe-emit-spill:abort: -10803 # error("var '" var->name "' initialized from an instruction must live in a register\n") -10804 (write-buffered *(ebp+0x1c) "var '") -10805 (write-buffered *(ebp+0x1c) *eax) # Var-name -10806 (write-buffered *(ebp+0x1c) "' initialized from an instruction must live in a register\n") -10807 (flush *(ebp+0x1c)) -10808 (stop *(ebp+0x20) 1) -10809 # never gets here -10810 -10811 emit-subx-cleanup-and-unconditional-nonlocal-branch: # out: (addr buffered-file), stmt: (addr stmt1), vars: (addr stack live-var) -10812 # . prologue -10813 55/push-ebp -10814 89/<- %ebp 4/r32/esp -10815 # . save registers -10816 50/push-eax -10817 51/push-ecx -10818 # ecx = stmt -10819 8b/-> *(ebp+0xc) 1/r32/ecx -10820 # var target/eax: (addr array byte) = curr-stmt->inouts->value->name -10821 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -10822 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -10823 (lookup *eax *(eax+4)) # Var-name Var-name => eax -10824 # clean up until target block -10825 (emit-cleanup-code-until-target *(ebp+8) *(ebp+0x10) %eax) -10826 # emit jump to target block -10827 (emit-indent *(ebp+8) *Curr-block-depth) -10828 (write-buffered *(ebp+8) "e9/jump ") -10829 (write-buffered *(ebp+8) %eax) -10830 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -10831 (string-starts-with? %eax "break") -10832 3d/compare-eax-and 0/imm32/false -10833 { -10834 74/jump-if-= break/disp8 -10835 (write-buffered *(ebp+8) ":break/disp32\n") -10836 } -10837 3d/compare-eax-and 0/imm32/false # just in case the function call modified flags -10838 { -10839 75/jump-if-!= break/disp8 -10840 (write-buffered *(ebp+8) ":loop/disp32\n") -10841 } -10842 $emit-subx-cleanup-and-unconditional-nonlocal-branch:end: -10843 # . restore registers -10844 59/pop-to-ecx -10845 58/pop-to-eax -10846 # . epilogue -10847 89/<- %esp 5/r32/ebp -10848 5d/pop-to-ebp -10849 c3/return -10850 -10851 is-mu-branch?: # stmt: (addr stmt1) -> result/eax: boolean -10852 # . prologue -10853 55/push-ebp -10854 89/<- %ebp 4/r32/esp -10855 # . save registers -10856 51/push-ecx -10857 # ecx = lookup(stmt->operation) -10858 8b/-> *(ebp+8) 1/r32/ecx -10859 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -10860 89/<- %ecx 0/r32/eax -10861 # if (stmt->operation starts with "loop") return true -10862 (string-starts-with? %ecx "loop") # => eax -10863 3d/compare-eax-and 0/imm32/false -10864 75/jump-if-not-equal $is-mu-branch?:end/disp8 -10865 # otherwise return (stmt->operation starts with "break") -10866 (string-starts-with? %ecx "break") # => eax -10867 $is-mu-branch?:end: -10868 # . restore registers -10869 59/pop-to-ecx -10870 # . epilogue -10871 89/<- %esp 5/r32/ebp -10872 5d/pop-to-ebp -10873 c3/return -10874 -10875 emit-reverse-break: # out: (addr buffered-file), stmt: (addr stmt1) -10876 # . prologue -10877 55/push-ebp -10878 89/<- %ebp 4/r32/esp -10879 # . save registers -10880 50/push-eax -10881 # eax = stmt -10882 8b/-> *(ebp+0xc) 0/r32/eax -10883 # -10884 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -10885 (get Reverse-branch %eax 0x10 "reverse-branch: ") # => eax: (addr handle array byte) -10886 (emit-indent *(ebp+8) *Curr-block-depth) -10887 (lookup *eax *(eax+4)) # => eax -10888 (write-buffered *(ebp+8) %eax) -10889 (write-buffered *(ebp+8) " break/disp32\n") -10890 $emit-reverse-break:end: -10891 # . restore registers -10892 58/pop-to-eax -10893 # . epilogue -10894 89/<- %esp 5/r32/ebp -10895 5d/pop-to-ebp -10896 c3/return -10897 -10898 == data -10899 -10900 # Table from Mu branch instructions to the reverse SubX opcodes for them. -10901 Reverse-branch: # (table (handle array byte) (handle array byte)) -10902 # a table is a stream -10903 0x140/imm32/write -10904 0/imm32/read -10905 0x140/imm32/size -10906 # data -10907 0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 -10908 0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 -10909 0x11/imm32/alloc-id _string-break-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 -10910 0x11/imm32/alloc-id _string-loop-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 -10911 0x11/imm32/alloc-id _string-break-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 -10912 0x11/imm32/alloc-id _string-loop-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 -10913 0x11/imm32/alloc-id _string-break-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 -10914 0x11/imm32/alloc-id _string-loop-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 -10915 0x11/imm32/alloc-id _string-break-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -10916 0x11/imm32/alloc-id _string-loop-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -10917 0x11/imm32/alloc-id _string-break-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 -10918 0x11/imm32/alloc-id _string-loop-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 -10919 0x11/imm32/alloc-id _string-break-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 -10920 0x11/imm32/alloc-id _string-loop-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 -10921 0x11/imm32/alloc-id _string-break-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 -10922 0x11/imm32/alloc-id _string-loop-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 -10923 0x11/imm32/alloc-id _string-break-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -10924 0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 -10925 0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 -10926 0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 -10927 -10928 == code -10929 -10930 emit-unconditional-jump-to-depth: # out: (addr buffered-file), vars: (addr stack live-var), depth: int, label-suffix: (addr array byte) -10931 # . prologue -10932 55/push-ebp -10933 89/<- %ebp 4/r32/esp -10934 # . save registers -10935 50/push-eax -10936 51/push-ecx -10937 52/push-edx -10938 53/push-ebx -10939 56/push-esi -10940 # ecx = vars -10941 8b/-> *(ebp+0xc) 1/r32/ecx -10942 # var eax: int = vars->top -10943 8b/-> *ecx 0/r32/eax -10944 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] -10945 8d/copy-address *(ecx+eax-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size -10946 # var min/ecx: (addr handle var) = vars->data -10947 8d/copy-address *(ecx+8) 1/r32/ecx -10948 # edx = depth -10949 8b/-> *(ebp+0x10) 2/r32/edx -10950 { -10951 $emit-unconditional-jump-to-depth:loop: -10952 # if (curr < min) break -10953 39/compare %esi 1/r32/ecx -10954 0f 82/jump-if-addr< break/disp32 -10955 # var v/ebx: (addr var) = lookup(*curr) -10956 (lookup *esi *(esi+4)) # => eax -10957 89/<- %ebx 0/r32/eax -10958 # if (v->block-depth < until-block-depth) break -10959 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -10960 0f 8c/jump-if-< break/disp32 -10961 { -10962 $emit-unconditional-jump-to-depth:check: -10963 # if v->block-depth != until-block-depth, continue -10964 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -10965 0f 85/jump-if-!= break/disp32 -10966 $emit-unconditional-jump-to-depth:depth-found: -10967 # if v is not a literal, continue -10968 (size-of %ebx) # => eax -10969 3d/compare-eax-and 0/imm32 -10970 0f 85/jump-if-!= break/disp32 -10971 $emit-unconditional-jump-to-depth:label-found: -10972 # emit unconditional jump, then return -10973 (emit-indent *(ebp+8) *Curr-block-depth) -10974 (write-buffered *(ebp+8) "e9/jump ") -10975 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -10976 (write-buffered *(ebp+8) %eax) -10977 (write-buffered *(ebp+8) ":") -10978 (write-buffered *(ebp+8) *(ebp+0x14)) -10979 (write-buffered *(ebp+8) "/disp32\n") -10980 eb/jump $emit-unconditional-jump-to-depth:end/disp8 -10981 } -10982 # curr -= 12 -10983 81 5/subop/subtract %esi 0xc/imm32 -10984 e9/jump loop/disp32 -10985 } -10986 # TODO: error if no label at 'depth' was found -10987 $emit-unconditional-jump-to-depth:end: -10988 # . restore registers -10989 5e/pop-to-esi -10990 5b/pop-to-ebx -10991 5a/pop-to-edx -10992 59/pop-to-ecx -10993 58/pop-to-eax -10994 # . epilogue -10995 89/<- %esp 5/r32/ebp -10996 5d/pop-to-ebp -10997 c3/return -10998 -10999 # emit clean-up code for 'vars' until some block depth -11000 # doesn't actually modify 'vars' so we need traverse manually inside the stack -11001 emit-cleanup-code-until-depth: # out: (addr buffered-file), vars: (addr stack live-var), until-block-depth: int -11002 # . prologue -11003 55/push-ebp -11004 89/<- %ebp 4/r32/esp -11005 # . save registers -11006 50/push-eax -11007 51/push-ecx -11008 52/push-edx -11009 53/push-ebx -11010 56/push-esi -11011 #? (write-buffered Stderr "--- cleanup\n") -11012 #? (flush Stderr) -11013 # ecx = vars -11014 8b/-> *(ebp+0xc) 1/r32/ecx -11015 # var esi: int = vars->top -11016 8b/-> *ecx 6/r32/esi -11017 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] -11018 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size -11019 # var min/ecx: (addr handle var) = vars->data -11020 81 0/subop/add %ecx 8/imm32 -11021 # edx = until-block-depth -11022 8b/-> *(ebp+0x10) 2/r32/edx -11023 { -11024 $emit-cleanup-code-until-depth:loop: -11025 # if (curr < min) break -11026 39/compare %esi 1/r32/ecx -11027 0f 82/jump-if-addr< break/disp32 -11028 # var v/ebx: (addr var) = lookup(*curr) -11029 (lookup *esi *(esi+4)) # => eax -11030 89/<- %ebx 0/r32/eax -11031 #? (lookup *ebx *(ebx+4)) # Var-name -11032 #? (write-buffered Stderr "var ") -11033 #? (write-buffered Stderr %eax) -11034 #? (write-buffered Stderr Newline) -11035 #? (flush Stderr) -11036 # if (v->block-depth < until-block-depth) break -11037 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth -11038 0f 8c/jump-if-< break/disp32 -11039 # if v is in a register -11040 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register -11041 { -11042 0f 84/jump-if-= break/disp32 -11043 { -11044 $emit-cleanup-code-until-depth:check-for-previous-spill: -11045 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled -11046 3d/compare-eax-and 0/imm32/false -11047 74/jump-if-= break/disp8 -11048 $emit-cleanup-code-until-depth:reclaim-var-in-register: -11049 (emit-indent *(ebp+8) *Curr-block-depth) -11050 (write-buffered *(ebp+8) "8f 0/subop/pop %") -11051 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -11052 (write-buffered *(ebp+8) %eax) -11053 (write-buffered *(ebp+8) Newline) -11054 } -11055 eb/jump $emit-cleanup-code-until-depth:continue/disp8 -11056 } -11057 # otherwise v is on the stack -11058 { -11059 75/jump-if-!= break/disp8 -11060 $emit-cleanup-code-until-depth:var-on-stack: -11061 (size-of %ebx) # => eax -11062 # don't emit code for labels -11063 3d/compare-eax-and 0/imm32 -11064 74/jump-if-= break/disp8 -11065 $emit-cleanup-code-until-depth:reclaim-var-on-stack: -11066 (emit-indent *(ebp+8) *Curr-block-depth) -11067 (write-buffered *(ebp+8) "81 0/subop/add %esp ") -11068 (print-int32-buffered *(ebp+8) %eax) -11069 (write-buffered *(ebp+8) "/imm32\n") -11070 } -11071 $emit-cleanup-code-until-depth:continue: -11072 # curr -= 12 -11073 81 5/subop/subtract %esi 0xc/imm32 -11074 e9/jump loop/disp32 -11075 } -11076 $emit-cleanup-code-until-depth:end: -11077 # . restore registers -11078 5e/pop-to-esi -11079 5b/pop-to-ebx -11080 5a/pop-to-edx -11081 59/pop-to-ecx -11082 58/pop-to-eax -11083 # . epilogue -11084 89/<- %esp 5/r32/ebp -11085 5d/pop-to-ebp -11086 c3/return -11087 -11088 # emit clean-up code for 'vars' until a given label is encountered -11089 # doesn't actually modify 'vars' so we need traverse manually inside the stack -11090 emit-cleanup-code-until-target: # out: (addr buffered-file), vars: (addr stack live-var), until-block-label: (addr array byte) -11091 # . prologue -11092 55/push-ebp -11093 89/<- %ebp 4/r32/esp -11094 # . save registers -11095 50/push-eax -11096 51/push-ecx -11097 52/push-edx -11098 53/push-ebx -11099 # ecx = vars -11100 8b/-> *(ebp+0xc) 1/r32/ecx -11101 # var eax: int = vars->top -11102 8b/-> *ecx 0/r32/eax -11103 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] -11104 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size -11105 # var min/ecx: (addr handle var) = vars->data -11106 81 0/subop/add %ecx 8/imm32 -11107 { -11108 $emit-cleanup-code-until-target:loop: -11109 # if (curr < min) break -11110 39/compare %edx 1/r32/ecx -11111 0f 82/jump-if-addr< break/disp32 -11112 # var v/ebx: (handle var) = lookup(*curr) -11113 (lookup *edx *(edx+4)) # => eax -11114 89/<- %ebx 0/r32/eax -11115 # if (v->name == until-block-label) break -11116 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax -11117 (string-equal? %eax *(ebp+0x10)) # => eax -11118 3d/compare-eax-and 0/imm32/false -11119 0f 85/jump-if-!= break/disp32 -11120 # if v is in a register -11121 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register -11122 { -11123 0f 84/jump-if-= break/disp32 -11124 { -11125 $emit-cleanup-code-until-target:check-for-previous-spill: -11126 8b/-> *(edx+8) 0/r32/eax # Live-var-register-spilled -11127 3d/compare-eax-and 0/imm32/false -11128 74/jump-if-= break/disp8 -11129 $emit-cleanup-code-until-target:reclaim-var-in-register: -11130 (emit-indent *(ebp+8) *Curr-block-depth) -11131 (write-buffered *(ebp+8) "8f 0/subop/pop %") -11132 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -11133 (write-buffered *(ebp+8) %eax) -11134 (write-buffered *(ebp+8) Newline) -11135 } -11136 eb/jump $emit-cleanup-code-until-target:continue/disp8 -11137 } -11138 # otherwise v is on the stack -11139 { -11140 75/jump-if-!= break/disp8 -11141 $emit-cleanup-code-until-target:reclaim-var-on-stack: -11142 (size-of %ebx) # => eax -11143 # don't emit code for labels -11144 3d/compare-eax-and 0/imm32 -11145 74/jump-if-= break/disp8 -11146 # -11147 (emit-indent *(ebp+8) *Curr-block-depth) -11148 (write-buffered *(ebp+8) "81 0/subop/add %esp ") -11149 (print-int32-buffered *(ebp+8) %eax) -11150 (write-buffered *(ebp+8) "/imm32\n") -11151 } -11152 $emit-cleanup-code-until-target:continue: -11153 # curr -= 12 -11154 81 5/subop/subtract %edx 0xc/imm32 -11155 e9/jump loop/disp32 -11156 } -11157 $emit-cleanup-code-until-target:end: -11158 # . restore registers -11159 5b/pop-to-ebx -11160 5a/pop-to-edx -11161 59/pop-to-ecx -11162 58/pop-to-eax -11163 # . epilogue -11164 89/<- %esp 5/r32/ebp -11165 5d/pop-to-ebp -11166 c3/return -11167 -11168 # Return true if there isn't a variable in 'vars' with the same block-depth -11169 # and register as 'v'. -11170 # 'v' is guaranteed not to be within 'vars'. -11171 not-yet-spilled-this-block?: # v: (addr var), vars: (addr stack live-var) -> result/eax: boolean -11172 # . prologue -11173 55/push-ebp -11174 89/<- %ebp 4/r32/esp -11175 # . save registers -11176 51/push-ecx -11177 52/push-edx -11178 53/push-ebx -11179 56/push-esi -11180 57/push-edi -11181 # ecx = vars -11182 8b/-> *(ebp+0xc) 1/r32/ecx -11183 # var eax: int = vars->top -11184 8b/-> *ecx 0/r32/eax -11185 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] -11186 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size -11187 # var min/ecx: (addr handle var) = vars->data -11188 8d/copy-address *(ecx+8) 1/r32/ecx -11189 # var depth/ebx: int = v->block-depth -11190 8b/-> *(ebp+8) 3/r32/ebx -11191 8b/-> *(ebx+0x10) 3/r32/ebx # Var-block-depth -11192 # var needle/esi: (addr array byte) = v->register -11193 8b/-> *(ebp+8) 6/r32/esi -11194 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -11195 89/<- %esi 0/r32/eax -11196 { -11197 $not-yet-spilled-this-block?:loop: -11198 # if (curr < min) break -11199 39/compare %edx 1/r32/ecx -11200 0f 82/jump-if-addr< break/disp32 -11201 # var cand/edi: (addr var) = lookup(*curr) -11202 (lookup *edx *(edx+4)) # => eax -11203 89/<- %edi 0/r32/eax -11204 # if (cand->block-depth < depth) break -11205 39/compare *(edi+0x10) 3/r32/ebx # Var-block-depth -11206 0f 8c/jump-if-< break/disp32 -11207 # var cand-reg/edi: (array array byte) = cand->reg -11208 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -11209 89/<- %edi 0/r32/eax -11210 # if (cand-reg == null) continue -11211 { -11212 $not-yet-spilled-this-block?:check-reg: -11213 81 7/subop/compare %edi 0/imm32 -11214 0f 84/jump-if-= break/disp32 -11215 # if (cand-reg == needle) return true -11216 (string-equal? %esi %edi) # => eax -11217 3d/compare-eax-and 0/imm32/false -11218 74/jump-if-= break/disp8 -11219 $not-yet-spilled-this-block?:return-false: -11220 b8/copy-to-eax 0/imm32/false -11221 eb/jump $not-yet-spilled-this-block?:end/disp8 -11222 } -11223 $not-yet-spilled-this-block?:continue: -11224 # curr -= 12 -11225 81 5/subop/subtract %edx 0xc/imm32 -11226 e9/jump loop/disp32 -11227 } -11228 $not-yet-spilled-this-block?:return-true: -11229 # return true -11230 b8/copy-to-eax 1/imm32/true -11231 $not-yet-spilled-this-block?:end: -11232 # . restore registers -11233 5f/pop-to-edi -11234 5e/pop-to-esi -11235 5b/pop-to-ebx -11236 5a/pop-to-edx -11237 59/pop-to-ecx -11238 # . epilogue -11239 89/<- %esp 5/r32/ebp -11240 5d/pop-to-ebp -11241 c3/return -11242 -11243 # could the register of 'v' ever be written to by one of the vars in fn-outputs? -11244 will-not-write-some-register?: # v: (addr var), stmts: (addr list stmt), fn: (addr function) -> result/eax: boolean -11245 # . prologue -11246 55/push-ebp -11247 89/<- %ebp 4/r32/esp -11248 # eax = v -11249 8b/-> *(ebp+8) 0/r32/eax -11250 # var reg/eax: (addr array byte) = lookup(v->register) -11251 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -11252 # var target/eax: (addr var) = find-register(fn-outputs, reg) -11253 (find-register *(ebp+0x10) %eax) # => eax -11254 # if (target == 0) return true -11255 { -11256 3d/compare-eax-and 0/imm32 -11257 75/jump-if-!= break/disp8 -11258 b8/copy-to-eax 1/imm32/true -11259 eb/jump $will-not-write-some-register?:end/disp8 -11260 } -11261 # return !assigns-in-stmts?(stmts, target) -11262 (assigns-in-stmts? *(ebp+0xc) %eax) # => eax -11263 3d/compare-eax-and 0/imm32/false -11264 # assume: true = 1, so no need to mask with 0x000000ff -11265 0f 94/set-if-= %al -11266 $will-not-write-some-register?:end: -11267 # . epilogue -11268 89/<- %esp 5/r32/ebp -11269 5d/pop-to-ebp -11270 c3/return -11271 -11272 # return fn output with matching register -11273 # always returns false if 'reg' is null -11274 find-register: # fn: (addr function), reg: (addr array byte) -> result/eax: (addr var) -11275 # . prologue -11276 55/push-ebp -11277 89/<- %ebp 4/r32/esp -11278 # . save registers -11279 51/push-ecx -11280 # var curr/ecx: (addr list var) = lookup(fn->outputs) -11281 8b/-> *(ebp+8) 1/r32/ecx -11282 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax -11283 89/<- %ecx 0/r32/eax -11284 { -11285 $find-register:loop: -11286 # if (curr == 0) break -11287 81 7/subop/compare %ecx 0/imm32 -11288 74/jump-if-= break/disp8 -11289 # eax = curr->value->register -11290 (lookup *ecx *(ecx+4)) # List-value List-value => eax -11291 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -11292 # if (eax == reg) return curr->value -11293 $find-register:compare: -11294 (string-equal? *(ebp+0xc) %eax) # => eax -11295 { -11296 3d/compare-eax-and 0/imm32/false -11297 74/jump-if-= break/disp8 -11298 $find-register:found: -11299 (lookup *ecx *(ecx+4)) # List-value List-value => eax -11300 eb/jump $find-register:end/disp8 -11301 } -11302 # curr = lookup(curr->next) -11303 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -11304 89/<- %ecx 0/r32/eax -11305 # -11306 eb/jump loop/disp8 -11307 } -11308 $find-register:end: +10487 58/pop-to-eax +10488 # . epilogue +10489 89/<- %esp 5/r32/ebp +10490 5d/pop-to-ebp +10491 c3/return +10492 +10493 check-mu-function: # fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10494 # . prologue +10495 55/push-ebp +10496 89/<- %ebp 4/r32/esp +10497 # . save registers +10498 50/push-eax +10499 # eax = f +10500 8b/-> *(ebp+8) 0/r32/eax +10501 # TODO: anything to check in header? +10502 # var body/eax: (addr block) = lookup(f->body) +10503 (lookup *(eax+0x18) *(eax+0x1c)) # Function-body Function-body => eax +10504 (check-mu-block %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10)) +10505 $check-mu-function:end: +10506 # . restore registers +10507 58/pop-to-eax +10508 # . epilogue +10509 89/<- %esp 5/r32/ebp +10510 5d/pop-to-ebp +10511 c3/return +10512 +10513 check-mu-block: # block: (addr block), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10514 # . prologue +10515 55/push-ebp +10516 89/<- %ebp 4/r32/esp +10517 # . save registers +10518 50/push-eax +10519 # eax = block +10520 8b/-> *(ebp+8) 0/r32/eax +10521 # var stmts/eax: (addr list stmt) = lookup(block->statements) +10522 (lookup *(eax+4) *(eax+8)) # Block-stmts Block-stmts => eax +10523 # +10524 { +10525 $check-mu-block:check-empty: +10526 3d/compare-eax-and 0/imm32 +10527 0f 84/jump-if-= break/disp32 +10528 # emit block->statements +10529 (check-mu-stmt-list %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10530 } +10531 $check-mu-block:end: +10532 # . restore registers +10533 58/pop-to-eax +10534 # . epilogue +10535 89/<- %esp 5/r32/ebp +10536 5d/pop-to-ebp +10537 c3/return +10538 +10539 check-mu-stmt-list: # stmts: (addr list stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10540 # . prologue +10541 55/push-ebp +10542 89/<- %ebp 4/r32/esp +10543 # . save registers +10544 50/push-eax +10545 56/push-esi +10546 # esi = stmts +10547 8b/-> *(ebp+8) 6/r32/esi +10548 { +10549 $check-mu-stmt-list:loop: +10550 81 7/subop/compare %esi 0/imm32 +10551 0f 84/jump-if-= break/disp32 +10552 # var curr-stmt/eax: (addr stmt) = lookup(stmts->value) +10553 (lookup *esi *(esi+4)) # List-value List-value => eax +10554 { +10555 $check-mu-stmt-list:check-for-block: +10556 81 7/subop/compare *eax 0/imm32/block # Stmt-tag +10557 75/jump-if-!= break/disp8 +10558 $check-mu-stmt-list:block: +10559 (check-mu-block %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10560 eb/jump $check-mu-stmt-list:continue/disp8 +10561 } +10562 { +10563 $check-mu-stmt-list:check-for-stmt1: +10564 81 7/subop/compare *eax 1/imm32/stmt1 # Stmt-tag +10565 0f 85/jump-if-!= break/disp32 +10566 $check-mu-stmt-list:stmt1: +10567 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10568 eb/jump $check-mu-stmt-list:continue/disp8 +10569 } +10570 { +10571 $check-mu-stmt-list:check-for-reg-var-def: +10572 81 7/subop/compare *eax 3/imm32/reg-var-def # Stmt-tag +10573 0f 85/jump-if-!= break/disp32 +10574 $check-mu-stmt-list:reg-var-def: +10575 (check-mu-stmt %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10576 eb/jump $check-mu-stmt-list:continue/disp8 +10577 } +10578 $check-mu-stmt-list:continue: +10579 # TODO: raise an error on unrecognized Stmt-tag +10580 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax +10581 89/<- %esi 0/r32/eax +10582 e9/jump loop/disp32 +10583 } +10584 $check-mu-stmt-list:end: +10585 # . restore registers +10586 5e/pop-to-esi +10587 58/pop-to-eax +10588 # . epilogue +10589 89/<- %esp 5/r32/ebp +10590 5d/pop-to-ebp +10591 c3/return +10592 +10593 check-mu-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10594 # . prologue +10595 55/push-ebp +10596 89/<- %ebp 4/r32/esp +10597 # . save registers +10598 50/push-eax +10599 # if stmt's operation matches a primitive, check against it +10600 (has-primitive-name? *(ebp+8)) # => eax +10601 3d/compare-eax-and 0/imm32/false +10602 { +10603 74/jump-if-= break/disp8 +10604 (check-mu-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10605 eb/jump $check-mu-stmt:end/disp8 +10606 } +10607 # otherwise find a function to check against +10608 { +10609 # var f/edi: (addr function) = lookup(*Program->functions) +10610 (lookup *_Program-functions *_Program-functions->payload) # => eax +10611 (find-matching-function %eax *(ebp+8)) # => eax +10612 3d/compare-eax-and 0/imm32 +10613 { +10614 74/jump-if-= break/disp8 +10615 (check-mu-call *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10616 eb/jump $check-mu-stmt:end/disp8 +10617 } +10618 # TODO: error on unknown function. We need to first type-check calls to SubX functions. +10619 } +10620 $check-mu-stmt:end: +10621 # . restore registers +10622 58/pop-to-eax +10623 # . epilogue +10624 89/<- %esp 5/r32/ebp +10625 5d/pop-to-ebp +10626 c3/return +10627 +10628 has-primitive-name?: # stmt: (addr stmt) -> result/eax: boolean +10629 # . prologue +10630 55/push-ebp +10631 89/<- %ebp 4/r32/esp +10632 # . save registers +10633 51/push-ecx +10634 56/push-esi +10635 # var name/esi: (addr array byte) = lookup(stmt->operation) +10636 8b/-> *(ebp+8) 6/r32/esi +10637 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +10638 89/<- %esi 0/r32/eax +10639 # if (name == "get") return true +10640 (string-equal? %esi "get") # => eax +10641 3d/compare-eax-and 0/imm32/false +10642 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +10643 # if (name == "index") return true +10644 (string-equal? %esi "index") # => eax +10645 3d/compare-eax-and 0/imm32/false +10646 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +10647 # if (name == "length") return true +10648 (string-equal? %esi "length") # => eax +10649 3d/compare-eax-and 0/imm32/false +10650 0f 85/jump-if-!= $has-primitive-name?:end/disp32 +10651 # if (name == "compute-offset") return true +10652 (string-equal? %esi "compute-offset") # => eax +10653 3d/compare-eax-and 0/imm32/false +10654 75/jump-if-!= $has-primitive-name?:end/disp8 +10655 # if (name == "lookup") return true +10656 (string-equal? %esi "lookup") # => eax +10657 3d/compare-eax-and 0/imm32/false +10658 75/jump-if-!= $has-primitive-name?:end/disp8 +10659 # var curr/ecx: (addr primitive) = Primitives +10660 b9/copy-to-ecx Primitives/imm32 +10661 { +10662 $has-primitive-name?:loop: +10663 # if (curr == null) break +10664 81 7/subop/compare %ecx 0/imm32 +10665 74/jump-if-= break/disp8 +10666 # if (primitive->name == name) return true +10667 (lookup *ecx *(ecx+4)) # Primitive-name Primitive-name => eax +10668 (string-equal? %esi %eax) # => eax +10669 3d/compare-eax-and 0/imm32/false +10670 75/jump-if-!= $has-primitive-name?:end/disp8 +10671 $has-primitive-name?:next-primitive: +10672 # curr = curr->next +10673 (lookup *(ecx+0x34) *(ecx+0x38)) # Primitive-next Primitive-next => eax +10674 89/<- %ecx 0/r32/eax +10675 # +10676 e9/jump loop/disp32 +10677 } +10678 # return null +10679 b8/copy-to-eax 0/imm32 +10680 $has-primitive-name?:end: +10681 # . restore registers +10682 5e/pop-to-esi +10683 59/pop-to-ecx +10684 # . epilogue +10685 89/<- %esp 5/r32/ebp +10686 5d/pop-to-ebp +10687 c3/return +10688 +10689 check-mu-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10690 # . prologue +10691 55/push-ebp +10692 89/<- %ebp 4/r32/esp +10693 # . save registers +10694 50/push-eax +10695 51/push-ecx +10696 # var op/ecx: (addr array byte) = lookup(stmt->operation) +10697 8b/-> *(ebp+8) 0/r32/eax +10698 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +10699 89/<- %ecx 0/r32/eax +10700 # if (op == "copy") check-mu-copy-stmt +10701 { +10702 (string-equal? %ecx "copy") # => eax +10703 3d/compare-eax-and 0/imm32/false +10704 74/jump-if-= break/disp8 +10705 (check-mu-copy-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10706 e9/jump $check-mu-primitive:end/disp32 +10707 } +10708 # if (op == "copy-to") check-mu-copy-to-stmt +10709 { +10710 (string-equal? %ecx "copy-to") # => eax +10711 3d/compare-eax-and 0/imm32/false +10712 74/jump-if-= break/disp8 +10713 (check-mu-copy-to-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10714 e9/jump $check-mu-primitive:end/disp32 +10715 } +10716 # if (op == "compare") check-mu-compare-stmt +10717 { +10718 (string-equal? %ecx "compare") # => eax +10719 3d/compare-eax-and 0/imm32/false +10720 74/jump-if-= break/disp8 +10721 (check-mu-compare-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10722 e9/jump $check-mu-primitive:end/disp32 +10723 } +10724 # if (op == "address") check-mu-address-stmt +10725 { +10726 (string-equal? %ecx "address") # => eax +10727 3d/compare-eax-and 0/imm32/false +10728 74/jump-if-= break/disp8 +10729 (check-mu-address-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10730 e9/jump $check-mu-primitive:end/disp32 +10731 } +10732 # if (op == "get") check-mu-get-stmt +10733 { +10734 (string-equal? %ecx "get") # => eax +10735 3d/compare-eax-and 0/imm32/false +10736 74/jump-if-= break/disp8 +10737 (check-mu-get-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10738 e9/jump $check-mu-primitive:end/disp32 +10739 } +10740 # if (op == "index") check-mu-index-stmt +10741 { +10742 (string-equal? %ecx "index") # => eax +10743 3d/compare-eax-and 0/imm32/false +10744 74/jump-if-= break/disp8 +10745 (check-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10746 e9/jump $check-mu-primitive:end/disp32 +10747 } +10748 # if (op == "length") check-mu-length-stmt +10749 { +10750 (string-equal? %ecx "length") # => eax +10751 3d/compare-eax-and 0/imm32/false +10752 74/jump-if-= break/disp8 +10753 (check-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10754 e9/jump $check-mu-primitive:end/disp32 +10755 } +10756 # if (op == "compute-offset") check-mu-compute-offset-stmt +10757 { +10758 (string-equal? %ecx "compute-offset") # => eax +10759 3d/compare-eax-and 0/imm32/false +10760 74/jump-if-= break/disp8 +10761 (check-mu-compute-offset-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10762 e9/jump $check-mu-primitive:end/disp32 +10763 } +10764 # if (op == "lookup") check-mu-lookup-stmt +10765 { +10766 (string-equal? %ecx "lookup") # => eax +10767 3d/compare-eax-and 0/imm32/false +10768 74/jump-if-= break/disp8 +10769 (check-mu-lookup-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10770 e9/jump $check-mu-primitive:end/disp32 +10771 } +10772 # otherwise check-numberlike-stmt +10773 (check-mu-numberlike-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10774 $check-mu-primitive:end: +10775 # . restore registers +10776 59/pop-to-ecx +10777 58/pop-to-eax +10778 # . epilogue +10779 89/<- %esp 5/r32/ebp +10780 5d/pop-to-ebp +10781 c3/return +10782 +10783 # by default, Mu primitives should only operate on 'number-like' types +10784 check-mu-numberlike-primitive: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10785 # . prologue +10786 55/push-ebp +10787 89/<- %ebp 4/r32/esp +10788 # . save registers +10789 50/push-eax +10790 51/push-ecx +10791 56/push-esi +10792 # esi = stmt +10793 8b/-> *(ebp+8) 6/r32/esi +10794 # var gas/ecx: int = 2 +10795 b9/copy-to-ecx 2/imm32 +10796 # - check at most 1 output +10797 # var output/eax: (addr stmt-var) = stmt->outputs +10798 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +10799 { +10800 3d/compare-eax-and 0/imm32 +10801 74/jump-if-= break/disp8 +10802 $check-mu-numberlike-primitive:output: +10803 (check-mu-numberlike-output %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10804 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +10805 3d/compare-eax-and 0/imm32 +10806 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-outputs/disp32 +10807 # check output is in a register +10808 # --gas +10809 49/decrement-ecx +10810 } +10811 # - check first inout +10812 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +10813 { +10814 3d/compare-eax-and 0/imm32 +10815 0f 84/jump-if-= $check-mu-numberlike-primitive:end/disp32 +10816 $check-mu-numberlike-primitive:first-inout: +10817 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10818 # --gas +10819 49/decrement-ecx +10820 } +10821 # - check second inout +10822 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +10823 { +10824 3d/compare-eax-and 0/imm32 +10825 74/jump-if-= $check-mu-numberlike-primitive:end/disp8 +10826 $check-mu-numberlike-primitive:second-inout: +10827 # is a second inout allowed? +10828 81 7/subop/compare %ecx 0/imm32 +10829 0f 84/jump-if-= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 +10830 $check-mu-numberlike-primitive:second-inout-permitted: +10831 (check-mu-numberlike-arg %eax *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +10832 } +10833 $check-mu-numberlike-primitive:third-inout: +10834 # if there's a third arg, raise an error +10835 81 7/subop/compare *(eax+8) 0/imm32 # Stmt-var-next +10836 0f 85/jump-if-!= $check-mu-numberlike-primitive:error-too-many-inouts/disp32 +10837 $check-mu-numberlike-primitive:end: +10838 # . restore registers +10839 5e/pop-to-esi +10840 59/pop-to-ecx +10841 58/pop-to-eax +10842 # . epilogue +10843 89/<- %esp 5/r32/ebp +10844 5d/pop-to-ebp +10845 c3/return +10846 +10847 $check-mu-numberlike-primitive:error-too-many-inouts: +10848 (write-buffered *(ebp+0x10) "fn ") +10849 8b/-> *(ebp+0xc) 0/r32/eax +10850 (lookup *eax *(eax+4)) # Function-name Function-name => eax +10851 (write-buffered *(ebp+0x10) %eax) +10852 (write-buffered *(ebp+0x10) ": stmt ") +10853 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +10854 (write-buffered *(ebp+0x10) %eax) +10855 (write-buffered *(ebp+0x10) ": too many inouts; most primitives support at most two arguments, across inouts and outputs\n") +10856 (flush *(ebp+0x10)) +10857 (stop *(ebp+0x14) 1) +10858 # never gets here +10859 +10860 $check-mu-numberlike-primitive:error-too-many-outputs: +10861 (write-buffered *(ebp+0x10) "fn ") +10862 8b/-> *(ebp+0xc) 0/r32/eax +10863 (lookup *eax *(eax+4)) # Function-name Function-name => eax +10864 (write-buffered *(ebp+0x10) %eax) +10865 (write-buffered *(ebp+0x10) ": stmt ") +10866 (lookup *(esi+4) *(esi+8)) # Stmt1-operation Stmt1-operation => eax +10867 (write-buffered *(ebp+0x10) %eax) +10868 (write-buffered *(ebp+0x10) ": too many outputs; most primitives support at most one output\n") +10869 (flush *(ebp+0x10)) +10870 (stop *(ebp+0x14) 1) +10871 # never gets here +10872 +10873 check-mu-numberlike-arg: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10874 # . prologue +10875 55/push-ebp +10876 89/<- %ebp 4/r32/esp +10877 # . save registers +10878 50/push-eax +10879 56/push-esi +10880 # var t/esi: (addr tree type-id) = lookup(v->value->type) +10881 8b/-> *(ebp+8) 0/r32/eax +10882 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +10883 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +10884 89/<- %esi 0/r32/eax +10885 $check-mu-numberlike-arg:check-literal: +10886 # if t is an int, return +10887 (is-simple-mu-type? %esi 0) # literal => eax +10888 3d/compare-eax-and 0/imm32/false +10889 75/jump-if-!= $check-mu-numberlike-arg:end/disp8 +10890 $check-mu-numberlike-arg:check-addr: +10891 # if t is an addr and v is dereferenced, return +10892 { +10893 (is-mu-addr-type? %esi) # => eax +10894 3d/compare-eax-and 0/imm32/false +10895 74/jump-if-= break/disp8 +10896 8b/-> *(ebp+8) 0/r32/eax +10897 8b/-> *(eax+0x10) 0/r32/eax +10898 3d/compare-eax-and 0/imm32/false +10899 75/jump-if-!= $check-mu-numberlike-arg:end/disp8 +10900 } +10901 $check-mu-numberlike-arg:output-checks: +10902 (check-mu-numberlike-output *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18)) +10903 $check-mu-numberlike-arg:end: +10904 # . restore registers +10905 5e/pop-to-esi +10906 58/pop-to-eax +10907 # . epilogue +10908 89/<- %esp 5/r32/ebp +10909 5d/pop-to-ebp +10910 c3/return +10911 +10912 check-mu-numberlike-output: # v: (addr stmt-var), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10913 # . prologue +10914 55/push-ebp +10915 89/<- %ebp 4/r32/esp +10916 # . save registers +10917 50/push-eax +10918 56/push-esi +10919 # var t/esi: (addr tree type-id) = lookup(v->value->type) +10920 8b/-> *(ebp+8) 0/r32/eax +10921 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +10922 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +10923 89/<- %esi 0/r32/eax +10924 $check-mu-numberlike-output:check-int: +10925 # if t is an int, return +10926 (is-simple-mu-type? %esi 1) # int => eax +10927 3d/compare-eax-and 0/imm32/false +10928 75/jump-if-!= $check-mu-numberlike-output:end/disp8 +10929 $check-mu-numberlike-output:check-boolean: +10930 # if t is a boolean, return +10931 (is-simple-mu-type? %esi 5) # boolean => eax +10932 3d/compare-eax-and 0/imm32/false +10933 75/jump-if-!= $check-mu-numberlike-output:end/disp8 +10934 $check-mu-numberlike-output:check-byte: +10935 # if t is a byte, return +10936 (is-simple-mu-type? %esi 8) # byte => eax +10937 3d/compare-eax-and 0/imm32/false +10938 75/jump-if-!= $check-mu-numberlike-output:end/disp8 +10939 e9/jump $check-mu-numberlike-output:fail/disp32 +10940 $check-mu-numberlike-output:end: +10941 # . restore registers +10942 5e/pop-to-esi +10943 58/pop-to-eax +10944 # . epilogue +10945 89/<- %esp 5/r32/ebp +10946 5d/pop-to-ebp +10947 c3/return +10948 +10949 $check-mu-numberlike-output:fail: +10950 # otherwise raise an error +10951 (write-buffered *(ebp+0x14) "fn ") +10952 8b/-> *(ebp+0x10) 0/r32/eax +10953 (lookup *eax *(eax+4)) # Function-name Function-name => eax +10954 (write-buffered *(ebp+0x14) %eax) +10955 (write-buffered *(ebp+0x14) ": stmt ") +10956 8b/-> *(ebp+0xc) 0/r32/eax +10957 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +10958 (write-buffered *(ebp+0x14) %eax) +10959 (write-buffered *(ebp+0x14) ": only non-addr scalar args permitted\n") +10960 (flush *(ebp+0x14)) +10961 (stop *(ebp+0x18) 1) +10962 # never gets here +10963 +10964 check-mu-copy-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10965 # . prologue +10966 55/push-ebp +10967 89/<- %ebp 4/r32/esp +10968 # . save registers +10969 $check-mu-copy-stmt:end: +10970 # . restore registers +10971 # . epilogue +10972 89/<- %esp 5/r32/ebp +10973 5d/pop-to-ebp +10974 c3/return +10975 +10976 check-mu-copy-to-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10977 # . prologue +10978 55/push-ebp +10979 89/<- %ebp 4/r32/esp +10980 # . save registers +10981 $check-mu-copy-to-stmt:end: +10982 # . restore registers +10983 # . epilogue +10984 89/<- %esp 5/r32/ebp +10985 5d/pop-to-ebp +10986 c3/return +10987 +10988 check-mu-compare-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +10989 # . prologue +10990 55/push-ebp +10991 89/<- %ebp 4/r32/esp +10992 # . save registers +10993 $check-mu-compare-stmt:end: +10994 # . restore registers +10995 # . epilogue +10996 89/<- %esp 5/r32/ebp +10997 5d/pop-to-ebp +10998 c3/return +10999 +11000 check-mu-address-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11001 # . prologue +11002 55/push-ebp +11003 89/<- %ebp 4/r32/esp +11004 # . save registers +11005 $check-mu-address-stmt:end: +11006 # . restore registers +11007 # . epilogue +11008 89/<- %esp 5/r32/ebp +11009 5d/pop-to-ebp +11010 c3/return +11011 +11012 check-mu-get-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11013 # . prologue +11014 55/push-ebp +11015 89/<- %ebp 4/r32/esp +11016 # . save registers +11017 50/push-eax +11018 51/push-ecx +11019 52/push-edx +11020 53/push-ebx +11021 56/push-esi +11022 57/push-edi +11023 # esi = stmt +11024 8b/-> *(ebp+8) 6/r32/esi +11025 # - check for 0 inouts +11026 # var base/ecx: (addr var) = stmt->inouts->value +11027 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +11028 3d/compare-eax-and 0/imm32/false +11029 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 +11030 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +11031 89/<- %ecx 0/r32/eax +11032 $check-mu-get-stmt:check-base: +11033 # - check base type +11034 # if it's an 'addr', check that it's in a register +11035 # var base-type/ebx: (addr tree type-id) = lookup(base->type) +11036 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +11037 89/<- %ebx 0/r32/eax +11038 { +11039 81 7/subop/compare *ebx 0/imm32/false # Tree-is-atom +11040 0f 85/jump-if-!= break/disp32 +11041 $check-mu-get-stmt:base-is-compound: +11042 # if (type->left != addr) break +11043 (lookup *(ebx+4) *(ebx+8)) # Tree-left Tree-left => eax +11044 (is-simple-mu-type? %eax 2) # => eax +11045 3d/compare-eax-and 0/imm32/false +11046 74/jump-if-= break/disp8 +11047 $check-mu-get-stmt:base-is-addr: +11048 # now check for register +11049 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +11050 0f 84/jump-if-= $check-mu-get-stmt:error-base-type-addr-but-not-register/disp32 +11051 $check-mu-get-stmt:base-is-addr-in-register: +11052 # type->left is now an addr; skip it +11053 (lookup *(ebx+0xc) *(ebx+0x10)) # Tree-right Tree-right => eax +11054 81 7/subop/compare *(eax+0xc) 0/imm32 # Tree-right +11055 0f 85/jump-if-!= $check-mu-get-stmt:error-bad-base/disp32 +11056 $check-mu-get-stmt:base-is-addr-to-atom-in-register: +11057 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax +11058 89/<- %ebx 0/r32/eax +11059 } +11060 $check-mu-get-stmt:check-base-typeinfo: +11061 # ensure type is a container +11062 # var base-type-id/ebx: type-id = base-type->value +11063 8b/-> *(ebx+4) 3/r32/ebx # Tree-value +11064 (is-container? %ebx) # => eax +11065 3d/compare-eax-and 0/imm32/false +11066 0f 84/jump-if-= $check-mu-get-stmt:error-bad-base/disp32 +11067 # var base-typeinfo/edx: (addr typeinfo) = find-typeinfo(base-type-id) +11068 # . var container/ecx: (handle typeinfo) +11069 68/push 0/imm32 +11070 68/push 0/imm32 +11071 89/<- %ecx 4/r32/esp +11072 # . +11073 (find-typeinfo %ebx %ecx) +11074 (lookup *ecx *(ecx+4)) # => eax +11075 # . reclaim container +11076 81 0/subop/add %esp 8/imm32 +11077 # . +11078 89/<- %edx 0/r32/eax +11079 # var offset/ecx: (addr stmt-var) = stmt->inouts->next +11080 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +11081 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +11082 89/<- %ecx 0/r32/eax +11083 # - check for 1 inout +11084 3d/compare-eax-and 0/imm32/false +11085 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-inouts/disp32 +11086 # var offset/ecx: (addr var) = lookup(offset->value) +11087 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +11088 89/<- %ecx 0/r32/eax +11089 # - check for valid field +11090 81 7/subop/compare *(ecx+0x14) -1/imm32/uninitialized # Var-offset +11091 0f 84/jump-if-= $check-mu-get-stmt:error-bad-field/disp32 +11092 # - check for too many inouts +11093 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +11094 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +11095 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +11096 3d/compare-eax-and 0/imm32/false +11097 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-inouts/disp32 +11098 # var output/edi: (addr var) = stmt->outputs->value +11099 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +11100 # - check for 0 outputs +11101 3d/compare-eax-and 0/imm32/false +11102 0f 84/jump-if-= $check-mu-get-stmt:error-too-few-outputs/disp32 +11103 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +11104 89/<- %edi 0/r32/eax +11105 $check-mu-get-stmt:check-output-type: +11106 # - check output type +11107 # must be in register +11108 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +11109 3d/compare-eax-and 0/imm32 +11110 0f 84/jump-if-= $check-mu-get-stmt:error-output-not-in-register/disp32 +11111 # must have a non-atomic type +11112 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +11113 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom +11114 0f 85/jump-if-!= $check-mu-get-stmt:error-output-type-not-address/disp32 +11115 # type must start with (addr ...) +11116 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax +11117 (is-simple-mu-type? %eax 2) # => eax +11118 3d/compare-eax-and 0/imm32/false +11119 0f 84/jump-if-= $check-mu-get-stmt:error-output-type-not-address/disp32 +11120 $check-mu-get-stmt:check-output-type-match: +11121 # payload of addr type must match 'type' definition +11122 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +11123 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax +11124 # if (payload->right == null) payload = payload->left +11125 81 7/subop/compare *(eax+0xc) 0/imm32/null # Tree-right +11126 { +11127 75/jump-if-!= break/disp8 +11128 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax +11129 } +11130 89/<- %edi 0/r32/eax +11131 # . var output-name/ecx: (addr array byte) +11132 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +11133 89/<- %ecx 0/r32/eax +11134 # . var base-typeinfo-entry/eax: (addr handle typeinfo-entry) +11135 (lookup *(edx+4) *(edx+8)) # Typeinfo-fields Typeinfo-fields => eax +11136 (get %eax %ecx 0x10) # => eax +11137 # . +11138 (lookup *eax *(eax+4)) # => eax +11139 (lookup *eax *(eax+4)) # Typeinfo-entry-input-var Typeinfo-entry-input-var => eax +11140 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11141 # . +11142 (type-equal? %edi %eax) # => eax +11143 3d/compare-eax-and 0/imm32/false +11144 0f 84/jump-if-= $check-mu-get-stmt:error-bad-output-type/disp32 +11145 # - check for too many outputs +11146 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +11147 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +11148 3d/compare-eax-and 0/imm32/false +11149 0f 85/jump-if-!= $check-mu-get-stmt:error-too-many-outputs/disp32 +11150 $check-mu-get-stmt:end: +11151 # . restore registers +11152 5f/pop-to-edi +11153 5e/pop-to-esi +11154 5b/pop-to-ebx +11155 5a/pop-to-edx +11156 59/pop-to-ecx +11157 58/pop-to-eax +11158 # . epilogue +11159 89/<- %esp 5/r32/ebp +11160 5d/pop-to-ebp +11161 c3/return +11162 +11163 $check-mu-get-stmt:error-too-few-inouts: +11164 (write-buffered *(ebp+0x10) "fn ") +11165 8b/-> *(ebp+0xc) 0/r32/eax +11166 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11167 (write-buffered *(ebp+0x10) %eax) +11168 (write-buffered *(ebp+0x10) ": stmt get: too few inouts (2 required)\n") +11169 (flush *(ebp+0x10)) +11170 (stop *(ebp+0x14) 1) +11171 # never gets here +11172 +11173 $check-mu-get-stmt:error-too-many-inouts: +11174 (write-buffered *(ebp+0x10) "fn ") +11175 8b/-> *(ebp+0xc) 0/r32/eax +11176 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11177 (write-buffered *(ebp+0x10) %eax) +11178 (write-buffered *(ebp+0x10) ": stmt get: too many inouts (2 required)\n") +11179 (flush *(ebp+0x10)) +11180 (stop *(ebp+0x14) 1) +11181 # never gets here +11182 +11183 $check-mu-get-stmt:error-too-few-outputs: +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 get: must have an output\n") +11189 (flush *(ebp+0x10)) +11190 (stop *(ebp+0x14) 1) +11191 # never gets here +11192 +11193 $check-mu-get-stmt:error-too-many-outputs: +11194 (write-buffered *(ebp+0x10) "fn ") +11195 8b/-> *(ebp+0xc) 0/r32/eax +11196 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11197 (write-buffered *(ebp+0x10) %eax) +11198 (write-buffered *(ebp+0x10) ": stmt get: too many outputs (1 required)\n") +11199 (flush *(ebp+0x10)) +11200 (stop *(ebp+0x14) 1) +11201 # never gets here +11202 +11203 $check-mu-get-stmt:error-bad-base: +11204 # error("fn " fn ": stmt get: var '" base->name "' must have a 'type' definition\n") +11205 (write-buffered *(ebp+0x10) "fn ") +11206 8b/-> *(ebp+0xc) 0/r32/eax +11207 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11208 (write-buffered *(ebp+0x10) %eax) +11209 (write-buffered *(ebp+0x10) ": stmt get: var '") +11210 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +11211 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +11212 (lookup *eax *(eax+4)) # Var-name Var-name => eax +11213 (write-buffered *(ebp+0x10) %eax) +11214 (write-buffered *(ebp+0x10) "' must have a 'type' definition\n") +11215 (flush *(ebp+0x10)) +11216 (stop *(ebp+0x14) 1) +11217 # never gets here +11218 +11219 $check-mu-get-stmt:error-base-type-addr-but-not-register: +11220 (write-buffered *(ebp+0x10) "fn ") +11221 8b/-> *(ebp+0xc) 0/r32/eax +11222 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11223 (write-buffered *(ebp+0x10) %eax) +11224 (write-buffered *(ebp+0x10) ": stmt get: var '") +11225 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +11226 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +11227 (lookup *eax *(eax+4)) # Var-name Var-name => eax +11228 (write-buffered *(ebp+0x10) %eax) +11229 (write-buffered *(ebp+0x10) "' is an 'addr' type, and so must live in a register\n") +11230 (flush *(ebp+0x10)) +11231 (stop *(ebp+0x14) 1) +11232 # never gets here +11233 +11234 $check-mu-get-stmt:error-bad-field: +11235 # error("fn " fn ": stmt get: type " type " has no member called '" curr->name "'\n") +11236 (write-buffered *(ebp+0x10) "fn ") +11237 8b/-> *(ebp+0xc) 0/r32/eax +11238 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11239 (write-buffered *(ebp+0x10) %eax) +11240 (write-buffered *(ebp+0x10) ": stmt get: type '") +11241 # . write(Type-id->data[tmp]) +11242 bf/copy-to-edi Type-id/imm32 +11243 (write-buffered *(ebp+0x10) *(edi+ebx<<2+0xc)) +11244 # . +11245 (write-buffered *(ebp+0x10) "' has no member called '") +11246 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +11247 (write-buffered *(ebp+0x10) %eax) +11248 (write-buffered *(ebp+0x10) "'\n") +11249 (flush *(ebp+0x10)) +11250 (stop *(ebp+0x14) 1) +11251 # never gets here +11252 +11253 $check-mu-get-stmt:error-output-not-in-register: +11254 (write-buffered *(ebp+0x10) "fn ") +11255 8b/-> *(ebp+0xc) 0/r32/eax +11256 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11257 (write-buffered *(ebp+0x10) %eax) +11258 (write-buffered *(ebp+0x10) ": stmt get: output '") +11259 (lookup *edi *(edi+4)) # Var-name Var-name => eax +11260 (write-buffered *(ebp+0x10) %eax) +11261 (write-buffered *(ebp+0x10) "' is not in a register\n") +11262 (flush *(ebp+0x10)) +11263 (stop *(ebp+0x14) 1) +11264 # never gets here +11265 +11266 $check-mu-get-stmt:error-output-type-not-address: +11267 (write-buffered *(ebp+0x10) "fn ") +11268 8b/-> *(ebp+0xc) 0/r32/eax +11269 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11270 (write-buffered *(ebp+0x10) %eax) +11271 (write-buffered *(ebp+0x10) ": stmt get: output must be an address\n") +11272 (flush *(ebp+0x10)) +11273 (stop *(ebp+0x14) 1) +11274 # never gets here +11275 +11276 $check-mu-get-stmt:error-bad-output-type: +11277 (write-buffered *(ebp+0x10) "fn ") +11278 8b/-> *(ebp+0xc) 0/r32/eax +11279 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11280 (write-buffered *(ebp+0x10) %eax) +11281 (write-buffered *(ebp+0x10) ": stmt get: wrong output type for member '") +11282 (write-buffered *(ebp+0x10) %ecx) +11283 (write-buffered *(ebp+0x10) "' of type '") +11284 bf/copy-to-edi Type-id/imm32 +11285 (write-buffered *(ebp+0x10) *(edi+ebx<<2+0xc)) +11286 (write-buffered *(ebp+0x10) "'\n") +11287 (flush *(ebp+0x10)) +11288 (stop *(ebp+0x14) 1) +11289 # never gets here +11290 +11291 check-mu-index-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11292 # . prologue +11293 55/push-ebp +11294 89/<- %ebp 4/r32/esp +11295 # . save registers +11296 $check-mu-index-stmt:end: +11297 # . restore registers +11298 # . epilogue +11299 89/<- %esp 5/r32/ebp +11300 5d/pop-to-ebp +11301 c3/return +11302 +11303 check-mu-length-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11304 # . prologue +11305 55/push-ebp +11306 89/<- %ebp 4/r32/esp +11307 # . save registers +11308 $check-mu-length-stmt:end: 11309 # . restore registers -11310 59/pop-to-ecx -11311 # . epilogue -11312 89/<- %esp 5/r32/ebp -11313 5d/pop-to-ebp -11314 c3/return -11315 -11316 assigns-in-stmts?: # stmts: (addr list stmt), v: (addr var) -> result/eax: boolean -11317 # . prologue -11318 55/push-ebp -11319 89/<- %ebp 4/r32/esp -11320 # . save registers -11321 51/push-ecx -11322 # var curr/ecx: (addr list stmt) = stmts -11323 8b/-> *(ebp+8) 1/r32/ecx -11324 { -11325 # if (curr == 0) break -11326 81 7/subop/compare %ecx 0/imm32 -11327 74/jump-if-= break/disp8 -11328 # if assigns-in-stmt?(curr->value, v) return true -11329 (lookup *ecx *(ecx+4)) # List-value List-value => eax -11330 (assigns-in-stmt? %eax *(ebp+0xc)) # => eax -11331 3d/compare-eax-and 0/imm32/false -11332 75/jump-if-!= break/disp8 -11333 # curr = lookup(curr->next) -11334 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -11335 89/<- %ecx 0/r32/eax -11336 # -11337 eb/jump loop/disp8 -11338 } -11339 $assigns-in-stmts?:end: -11340 # . restore registers -11341 59/pop-to-ecx -11342 # . epilogue -11343 89/<- %esp 5/r32/ebp -11344 5d/pop-to-ebp -11345 c3/return -11346 -11347 assigns-in-stmt?: # stmt: (addr stmt), v: (addr var) -> result/eax: boolean -11348 # . prologue -11349 55/push-ebp -11350 89/<- %ebp 4/r32/esp -11351 # . save registers -11352 51/push-ecx -11353 # ecx = stmt -11354 8b/-> *(ebp+8) 1/r32/ecx -11355 # if stmt is a stmt1, return assigns-in-stmt-vars?(stmt->outputs, v) -11356 { -11357 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag -11358 75/jump-if-!= break/disp8 -11359 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -11360 (assigns-in-stmt-vars? %eax *(ebp+0xc)) # => eax -11361 eb/jump $assigns-in-stmt?:end/disp8 -11362 } -11363 # if stmt is a block, return assigns-in-stmts?(stmt->stmts, v) -11364 { -11365 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag -11366 75/jump-if-!= break/disp8 -11367 (lookup *(ecx+4) *(ecx+8)) # Block-stmts Block-stmts => eax -11368 (assigns-in-stmts? %eax *(ebp+0xc)) # => eax -11369 eb/jump $assigns-in-stmt?:end/disp8 -11370 } -11371 # otherwise return false -11372 b8/copy 0/imm32/false -11373 $assigns-in-stmt?:end: -11374 # . restore registers -11375 59/pop-to-ecx -11376 # . epilogue -11377 89/<- %esp 5/r32/ebp -11378 5d/pop-to-ebp -11379 c3/return -11380 -11381 assigns-in-stmt-vars?: # stmt-var: (addr stmt-var), v: (addr var) -> result/eax: boolean -11382 # . prologue -11383 55/push-ebp -11384 89/<- %ebp 4/r32/esp -11385 # . save registers -11386 51/push-ecx -11387 # var curr/ecx: (addr stmt-var) = stmt-var -11388 8b/-> *(ebp+8) 1/r32/ecx -11389 { -11390 # if (curr == 0) break -11391 81 7/subop/compare %ecx 0/imm32 -11392 74/jump-if-= break/disp8 -11393 # eax = lookup(curr->value) -11394 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -11395 # if (eax == v && curr->is-deref? == false) return true -11396 { -11397 39/compare *(ebp+0xc) 0/r32/eax -11398 75/jump-if-!= break/disp8 -11399 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -11400 75/jump-if-!= break/disp8 -11401 b8/copy-to-eax 1/imm32/true -11402 eb/jump $assigns-in-stmt-vars?:end/disp8 -11403 } -11404 # curr = lookup(curr->next) -11405 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax -11406 89/<- %ecx 0/r32/eax -11407 # -11408 eb/jump loop/disp8 -11409 } -11410 $assigns-in-stmt-vars?:end: -11411 # . restore registers -11412 59/pop-to-ecx -11413 # . epilogue -11414 89/<- %esp 5/r32/ebp -11415 5d/pop-to-ebp -11416 c3/return -11417 -11418 # is there a var before 'v' with the same block-depth and register on the 'vars' stack? -11419 # v is guaranteed to be within vars -11420 # 'start' is provided as an optimization, a pointer within vars -11421 # *start == v -11422 same-register-spilled-before?: # v: (addr var), vars: (addr stack (handle var)), start: (addr var) -> result/eax: boolean -11423 # . prologue -11424 55/push-ebp -11425 89/<- %ebp 4/r32/esp -11426 # . save registers -11427 51/push-ecx -11428 52/push-edx -11429 53/push-ebx -11430 56/push-esi -11431 57/push-edi -11432 # ecx = v -11433 8b/-> *(ebp+8) 1/r32/ecx -11434 # var reg/edx: (addr array byte) = lookup(v->register) -11435 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax -11436 89/<- %edx 0/r32/eax -11437 # var depth/ebx: int = v->block-depth -11438 8b/-> *(ecx+0x10) 3/r32/ebx # Var-block-depth -11439 # var min/ecx: (addr handle var) = vars->data -11440 8b/-> *(ebp+0xc) 1/r32/ecx -11441 81 0/subop/add %ecx 8/imm32 -11442 # TODO: check that start >= min and start < &vars->data[top] -11443 # TODO: check that *start == v -11444 # var curr/esi: (addr handle var) = start -11445 8b/-> *(ebp+0x10) 6/r32/esi -11446 # curr -= 8 -11447 81 5/subop/subtract %esi 8/imm32 -11448 { -11449 $same-register-spilled-before?:loop: -11450 # if (curr < min) break -11451 39/compare %esi 1/r32/ecx -11452 0f 82/jump-if-addr< break/disp32 -11453 # var x/eax: (addr var) = lookup(*curr) -11454 (lookup *esi *(esi+4)) # => eax -11455 # if (x->block-depth < depth) break -11456 39/compare *(eax+0x10) 3/r32/ebx # Var-block-depth -11457 0f 8c/jump-if-< break/disp32 -11458 # if (x->register == 0) continue -11459 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -11460 74/jump-if-= $same-register-spilled-before?:continue/disp8 -11461 # if (x->register == reg) return true -11462 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -11463 (string-equal? %eax %edx) # => eax -11464 3d/compare-eax-and 0/imm32/false -11465 b8/copy-to-eax 1/imm32/true -11466 75/jump-if-!= $same-register-spilled-before?:end/disp8 -11467 $same-register-spilled-before?:continue: -11468 # curr -= 8 -11469 81 5/subop/subtract %esi 8/imm32 -11470 e9/jump loop/disp32 -11471 } -11472 $same-register-spilled-before?:false: -11473 b8/copy-to-eax 0/imm32/false -11474 $same-register-spilled-before?:end: -11475 # . restore registers -11476 5f/pop-to-edi -11477 5e/pop-to-esi -11478 5b/pop-to-ebx -11479 5a/pop-to-edx -11480 59/pop-to-ecx -11481 # . epilogue -11482 89/<- %esp 5/r32/ebp -11483 5d/pop-to-ebp -11484 c3/return -11485 -11486 # Clean up global state for 'vars' until some block depth (inclusive). -11487 # -11488 # This would be a simple series of pops, if it wasn't for fn outputs, which -11489 # can occur anywhere in the stack. -11490 # So we have to _compact_ the entire array underlying the stack. -11491 # -11492 # We want to allow a fn output register to be written to by locals before the -11493 # output is set. -11494 # So fn outputs can't just be pushed at the start of the function. -11495 # -11496 # We want to allow other locals to shadow a fn output register after the -11497 # output is set. -11498 # So the output can't just always override anything in the stack. Sequence matters. -11499 clean-up-blocks: # vars: (addr stack live-var), until-block-depth: int, fn: (addr function) -11500 # pseudocode: -11501 # to = vars->top (which points outside the stack) -11502 # while true -11503 # if to <= 0 -11504 # break -11505 # var v = vars->data[to-1] -11506 # if v.depth < until and !in-function-outputs?(fn, v) -11507 # break -11508 # --to -11509 # from = to -11510 # while true -11511 # if from >= vars->top -11512 # break -11513 # assert(from >= to) -11514 # v = vars->data[from] -11515 # if in-function-outputs?(fn, v) -11516 # if from > to -11517 # vars->data[to] = vars->data[from] -11518 # ++to -11519 # ++from -11520 # vars->top = to -11521 # -11522 # . prologue -11523 55/push-ebp -11524 89/<- %ebp 4/r32/esp -11525 # . save registers -11526 50/push-eax -11527 52/push-edx -11528 53/push-ebx -11529 56/push-esi -11530 57/push-edi -11531 # ebx = vars -11532 8b/-> *(ebp+8) 3/r32/ebx -11533 # edx = until-block-depth -11534 8b/-> *(ebp+0xc) 2/r32/edx -11535 $clean-up-blocks:phase1: -11536 # var to/edi: int = vars->top -11537 8b/-> *ebx 7/r32/edi -11538 { -11539 $clean-up-blocks:loop1: -11540 # if (to <= 0) break -11541 81 7/subop/compare %edi 0/imm32 -11542 7e/jump-if-<= break/disp8 -11543 # var v/eax: (addr var) = lookup(vars->data[to-1]->var) -11544 8d/copy-address *(ebx+edi-4) 0/r32/eax # vars + 8 + to - 12 -11545 (lookup *eax *(eax+4)) # => eax -11546 # if (v->block-depth >= until-block-depth) continue -11547 39/compare *(eax+0x10) 2/r32/edx # Var-block-depth -11548 { -11549 7d/jump-if->= break/disp8 -11550 # if (!in-function-outputs?(fn, v)) break -11551 (in-function-outputs? *(ebp+0x10) %eax) # => eax -11552 3d/compare-eax-and 0/imm32/false -11553 74/jump-if-= $clean-up-blocks:phase2/disp8 -11554 } -11555 $clean-up-blocks:loop1-continue: -11556 # --to -11557 81 5/subop/subtract %edi 0xc/imm32 -11558 # -11559 eb/jump loop/disp8 -11560 } -11561 $clean-up-blocks:phase2: -11562 # var from/esi: int = to -11563 89/<- %esi 7/r32/edi -11564 { -11565 $clean-up-blocks:loop2: -11566 # if (from >= vars->top) break -11567 3b/compare 6/r32/esi *ebx -11568 7d/jump-if->= break/disp8 -11569 # var v/eax: (addr var) = lookup(vars->data[from]->var) -11570 8d/copy-address *(ebx+esi+8) 0/r32/eax -11571 (lookup *eax *(eax+4)) # => eax -11572 # if !in-function-outputs?(fn, v) continue -11573 (in-function-outputs? *(ebp+0x10) %eax) # => eax -11574 3d/compare-eax-and 0/imm32/false -11575 74/jump-if-= $clean-up-blocks:loop2-continue/disp8 -11576 # invariant: from >= to -11577 # if (from > to) vars->data[to] = vars->data[from] -11578 { -11579 39/compare %esi 7/r32/edi -11580 7e/jump-if-<= break/disp8 -11581 56/push-esi -11582 57/push-edi -11583 # . var from/esi: (addr byte) = &vars->data[from] -11584 8d/copy-address *(ebx+esi+8) 6/r32/esi -11585 # . var to/edi: (addr byte) = &vars->data[to] -11586 8d/copy-address *(ebx+edi+8) 7/r32/edi -11587 # . -11588 8b/-> *esi 0/r32/eax -11589 89/<- *edi 0/r32/eax -11590 8b/-> *(esi+4) 0/r32/eax -11591 89/<- *(edi+4) 0/r32/eax -11592 8b/-> *(esi+8) 0/r32/eax -11593 89/<- *(edi+8) 0/r32/eax -11594 5f/pop-to-edi -11595 5e/pop-to-esi -11596 } -11597 # ++to -11598 81 0/subop/add %edi 0xc/imm32 -11599 $clean-up-blocks:loop2-continue: -11600 # ++from -11601 81 0/subop/add %esi 0xc/imm32 -11602 # -11603 eb/jump loop/disp8 -11604 } -11605 89/<- *ebx 7/r32/edi -11606 $clean-up-blocks:end: -11607 # . restore registers -11608 5f/pop-to-edi -11609 5e/pop-to-esi -11610 5b/pop-to-ebx -11611 5a/pop-to-edx -11612 58/pop-to-eax +11310 # . epilogue +11311 89/<- %esp 5/r32/ebp +11312 5d/pop-to-ebp +11313 c3/return +11314 +11315 check-mu-compute-offset-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11316 # . prologue +11317 55/push-ebp +11318 89/<- %ebp 4/r32/esp +11319 # . save registers +11320 $check-mu-compute-offset-stmt:end: +11321 # . restore registers +11322 # . epilogue +11323 89/<- %esp 5/r32/ebp +11324 5d/pop-to-ebp +11325 c3/return +11326 +11327 check-mu-lookup-stmt: # stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11328 # . prologue +11329 55/push-ebp +11330 89/<- %ebp 4/r32/esp +11331 # . save registers +11332 $check-mu-lookup-stmt:end: +11333 # . restore registers +11334 # . epilogue +11335 89/<- %esp 5/r32/ebp +11336 5d/pop-to-ebp +11337 c3/return +11338 +11339 check-mu-call: # stmt: (addr stmt), callee: (addr function), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11340 # . prologue +11341 55/push-ebp +11342 89/<- %ebp 4/r32/esp +11343 # . save registers +11344 50/push-eax +11345 51/push-ecx +11346 52/push-edx +11347 53/push-ebx +11348 56/push-esi +11349 57/push-edi +11350 # esi = stmt +11351 8b/-> *(ebp+8) 6/r32/esi +11352 # edi = callee +11353 8b/-> *(ebp+0xc) 7/r32/edi +11354 # var inouts/ecx: (addr stmt-var) = lookup(stmt->inouts) +11355 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +11356 89/<- %ecx 0/r32/eax +11357 # var expected/edx: (addr list var) = lookup(f->inouts) +11358 (lookup *(edi+8) *(edi+0xc)) # Function-inouts Function-inouts => eax +11359 89/<- %edx 0/r32/eax +11360 { +11361 $check-mu-call:check-for-inouts: +11362 # if (inouts == 0) break +11363 81 7/subop/compare %ecx 0/imm32 +11364 0f 84/jump-if-= break/disp32 +11365 # if (expected == 0) error +11366 81 7/subop/compare %edx 0/imm32 +11367 0f 84/jump-if-= break/disp32 +11368 $check-mu-call:check-inout-type: +11369 # var v/eax: (addr v) = lookup(inouts->value) +11370 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +11371 # var t/ebx: (addr tree type-id) = lookup(v->type) +11372 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11373 89/<- %ebx 0/r32/eax +11374 # if (inouts->is-deref?) t = t->right # TODO: check that t->left is an addr +11375 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +11376 { +11377 74/jump-if-= break/disp8 +11378 (lookup *(ebx+0xc) *(ebx+0x10)) # Tree-right Tree-right => eax +11379 89/<- %ebx 0/r32/eax +11380 # if t->right is null, t = t->left +11381 81 7/subop/compare *(ebx+0xc) 0/imm32 # Tree-right +11382 75/jump-if-!= break/disp8 +11383 (lookup *(ebx+4) *(ebx+8)) # Tree-left Tree-left => eax +11384 89/<- %ebx 0/r32/eax +11385 } +11386 # var v2/eax: (addr v) = lookup(expected->value) +11387 (lookup *edx *(edx+4)) # List-value List-value => eax +11388 # var t2/eax: (addr tree type-id) = lookup(v2->type) +11389 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11390 # if (t != t2) error +11391 (type-match? %eax %ebx) # => eax +11392 3d/compare-eax-and 0/imm32/false +11393 { +11394 0f 85/jump-if-!= break/disp32 +11395 (write-buffered *(ebp+0x14) "fn ") +11396 8b/-> *(ebp+0x10) 0/r32/eax +11397 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11398 (write-buffered *(ebp+0x14) %eax) +11399 (write-buffered *(ebp+0x14) ": call ") +11400 (lookup *edi *(edi+4)) # Function-name Function-name => eax +11401 (write-buffered *(ebp+0x14) %eax) +11402 (write-buffered *(ebp+0x14) ": type for inout '") +11403 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +11404 (lookup *eax *(eax+4)) # Var-name Var-name => eax +11405 (write-buffered *(ebp+0x14) %eax) +11406 (write-buffered *(ebp+0x14) "' is not right\n") +11407 (flush *(ebp+0x14)) +11408 (stop *(ebp+0x18) 1) +11409 } +11410 $check-mu-call:continue-to-next-inout: +11411 # inouts = lookup(inouts->next) +11412 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +11413 89/<- %ecx 0/r32/eax +11414 # expected = lookup(expected->next) +11415 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +11416 89/<- %edx 0/r32/eax +11417 # +11418 e9/jump loop/disp32 +11419 } +11420 $check-mu-call:check-inout-count: +11421 # if (inouts == expected) proceed +11422 39/compare %ecx 2/r32/edx +11423 { +11424 0f 84/jump-if-= break/disp32 +11425 # exactly one of the two is null +11426 # if (inouts == 0) error("too many inouts") +11427 { +11428 81 7/subop/compare %ecx 0/imm32 +11429 0f 84/jump-if-= break/disp32 +11430 (write-buffered *(ebp+0x14) "fn ") +11431 8b/-> *(ebp+0x10) 0/r32/eax +11432 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11433 (write-buffered *(ebp+0x14) %eax) +11434 (write-buffered *(ebp+0x14) ": call ") +11435 (lookup *edi *(edi+4)) # Function-name Function-name => eax +11436 (write-buffered *(ebp+0x14) %eax) +11437 (write-buffered *(ebp+0x14) ": too many inouts\n") +11438 (flush *(ebp+0x14)) +11439 (stop *(ebp+0x18) 1) +11440 } +11441 # if (expected == 0) error("too few inouts") +11442 { +11443 81 7/subop/compare %edx 0/imm32 +11444 0f 84/jump-if-= break/disp32 +11445 (write-buffered *(ebp+0x14) "fn ") +11446 8b/-> *(ebp+0x10) 0/r32/eax +11447 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11448 (write-buffered *(ebp+0x14) %eax) +11449 (write-buffered *(ebp+0x14) ": call ") +11450 (lookup *edi *(edi+4)) # Function-name Function-name => eax +11451 (write-buffered *(ebp+0x14) %eax) +11452 (write-buffered *(ebp+0x14) ": too few inouts\n") +11453 (flush *(ebp+0x14)) +11454 (stop *(ebp+0x18) 1) +11455 } +11456 } +11457 $check-mu-call:check-outputs: +11458 # var outputs/ecx: (addr stmt-var) = lookup(stmt->outputs) +11459 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +11460 89/<- %ecx 0/r32/eax +11461 # var expected/edx: (addr list var) = lookup(f->outputs) +11462 (lookup *(edi+0x10) *(edi+0x14)) # Function-outputs Function-outputs => eax +11463 89/<- %edx 0/r32/eax +11464 { +11465 $check-mu-call:check-for-outputs: +11466 # if (outputs == 0) break +11467 81 7/subop/compare %ecx 0/imm32 +11468 0f 84/jump-if-= break/disp32 +11469 # if (expected == 0) error +11470 81 7/subop/compare %edx 0/imm32 +11471 0f 84/jump-if-= break/disp32 +11472 $check-mu-call:check-output-type: +11473 # var v/eax: (addr v) = lookup(outputs->value) +11474 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +11475 # var t/ebx: (addr tree type-id) = lookup(v->type) +11476 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11477 89/<- %ebx 0/r32/eax +11478 # if (outputs->is-deref?) t = t->right # TODO: check that t->left is an addr +11479 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +11480 { +11481 74/jump-if-= break/disp8 +11482 (lookup *(ebx+0xc) *(ebx+0x10)) # Tree-right Tree-right => eax +11483 89/<- %ebx 0/r32/eax +11484 } +11485 # var v2/eax: (addr v) = lookup(expected->value) +11486 (lookup *edx *(edx+4)) # List-value List-value => eax +11487 # var t2/eax: (addr tree type-id) = lookup(v2->type) +11488 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +11489 # if (t != t2) error +11490 (type-equal? %eax %ebx) # => eax +11491 3d/compare-eax-and 0/imm32/false +11492 { +11493 0f 85/jump-if-!= break/disp32 +11494 (write-buffered *(ebp+0x14) "fn ") +11495 8b/-> *(ebp+0x10) 0/r32/eax +11496 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11497 (write-buffered *(ebp+0x14) %eax) +11498 (write-buffered *(ebp+0x14) ": call ") +11499 (lookup *edi *(edi+4)) # Function-name Function-name => eax +11500 (write-buffered *(ebp+0x14) %eax) +11501 (write-buffered *(ebp+0x14) ": type for output '") +11502 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +11503 (lookup *eax *(eax+4)) # Var-name Var-name => eax +11504 (write-buffered *(ebp+0x14) %eax) +11505 (write-buffered *(ebp+0x14) "' is not right\n") +11506 (flush *(ebp+0x14)) +11507 (stop *(ebp+0x18) 1) +11508 } +11509 $check-mu-call:check-output-register: +11510 # var v/eax: (addr v) = lookup(outputs->value) +11511 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +11512 # var r/ebx: (addr array byte) = lookup(v->register) +11513 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax +11514 89/<- %ebx 0/r32/eax +11515 # var v2/eax: (addr v) = lookup(expected->value) +11516 (lookup *edx *(edx+4)) # Stmt-var-value Stmt-var-value => eax +11517 # var r2/eax: (addr array byte) = lookup(v2->register) +11518 (lookup *(eax+18) *(eax+0x1c)) # Var-register Var-register => eax +11519 # if (r != r2) error +11520 (string-equal? %eax %ebx) # => eax +11521 3d/compare-eax-and 0/imm32/false +11522 { +11523 0f 85/jump-if-!= break/disp32 +11524 (write-buffered *(ebp+0x14) "fn ") +11525 8b/-> *(ebp+0x10) 0/r32/eax +11526 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11527 (write-buffered *(ebp+0x14) %eax) +11528 (write-buffered *(ebp+0x14) ": call ") +11529 (lookup *edi *(edi+4)) # Function-name Function-name => eax +11530 (write-buffered *(ebp+0x14) %eax) +11531 (write-buffered *(ebp+0x14) ": register for output '") +11532 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +11533 (lookup *eax *(eax+4)) # Var-name Var-name => eax +11534 (write-buffered *(ebp+0x14) %eax) +11535 (write-buffered *(ebp+0x14) "' is not right\n") +11536 (flush *(ebp+0x14)) +11537 (stop *(ebp+0x18) 1) +11538 } +11539 $check-mu-call:continue-to-next-output: +11540 # outputs = lookup(outputs->next) +11541 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +11542 89/<- %ecx 0/r32/eax +11543 # expected = lookup(expected->next) +11544 (lookup *(edx+8) *(edx+0xc)) # List-next List-next => eax +11545 89/<- %edx 0/r32/eax +11546 # +11547 e9/jump loop/disp32 +11548 } +11549 $check-mu-call:check-output-count: +11550 # if (outputs == expected) proceed +11551 39/compare %ecx 2/r32/edx +11552 { +11553 0f 84/jump-if-= break/disp32 +11554 # exactly one of the two is null +11555 # if (outputs == 0) error("too many outputs") +11556 { +11557 81 7/subop/compare %ecx 0/imm32 +11558 0f 84/jump-if-= break/disp32 +11559 (write-buffered *(ebp+0x14) "fn ") +11560 8b/-> *(ebp+0x10) 0/r32/eax +11561 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11562 (write-buffered *(ebp+0x14) %eax) +11563 (write-buffered *(ebp+0x14) ": call ") +11564 (lookup *edi *(edi+4)) # Function-name Function-name => eax +11565 (write-buffered *(ebp+0x14) %eax) +11566 (write-buffered *(ebp+0x14) ": too many outputs\n") +11567 (flush *(ebp+0x14)) +11568 (stop *(ebp+0x18) 1) +11569 } +11570 # if (expected == 0) error("too few outputs") +11571 { +11572 81 7/subop/compare %edx 0/imm32 +11573 0f 84/jump-if-= break/disp32 +11574 (write-buffered *(ebp+0x14) "fn ") +11575 8b/-> *(ebp+0x10) 0/r32/eax +11576 (lookup *eax *(eax+4)) # Function-name Function-name => eax +11577 (write-buffered *(ebp+0x14) %eax) +11578 (write-buffered *(ebp+0x14) ": call ") +11579 (lookup *edi *(edi+4)) # Function-name Function-name => eax +11580 (write-buffered *(ebp+0x14) %eax) +11581 (write-buffered *(ebp+0x14) ": too few outputs\n") +11582 (flush *(ebp+0x14)) +11583 (stop *(ebp+0x18) 1) +11584 } +11585 } +11586 $check-mu-call:end: +11587 # . restore registers +11588 5f/pop-to-edi +11589 5e/pop-to-esi +11590 5b/pop-to-ebx +11591 5a/pop-to-edx +11592 59/pop-to-ecx +11593 58/pop-to-eax +11594 # . epilogue +11595 89/<- %esp 5/r32/ebp +11596 5d/pop-to-ebp +11597 c3/return +11598 +11599 # like type-equal? but takes literals into account +11600 type-match?: # def: (addr tree type-id), call: (addr tree type-id) -> result/eax: boolean +11601 # . prologue +11602 55/push-ebp +11603 89/<- %ebp 4/r32/esp +11604 # if (call == literal) return true # TODO: more precise +11605 (is-simple-mu-type? *(ebp+0xc) 0) # literal => eax +11606 3d/compare-eax-and 0/imm32/false +11607 b8/copy-to-eax 1/imm32/true +11608 75/jump-if-!= $type-match?:end/disp8 +11609 $type-match?:baseline: +11610 # otherwise fall back +11611 (type-equal? *(ebp+8) *(ebp+0xc)) # => eax +11612 $type-match?:end: 11613 # . epilogue 11614 89/<- %esp 5/r32/ebp 11615 5d/pop-to-ebp 11616 c3/return 11617 -11618 in-function-outputs?: # fn: (addr function), target: (addr var) -> result/eax: boolean +11618 size-of: # v: (addr var) -> result/eax: int 11619 # . prologue 11620 55/push-ebp 11621 89/<- %ebp 4/r32/esp 11622 # . save registers 11623 51/push-ecx -11624 # var curr/ecx: (addr list var) = lookup(fn->outputs) +11624 # var t/ecx: (addr tree type-id) = lookup(v->type) 11625 8b/-> *(ebp+8) 1/r32/ecx -11626 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax -11627 89/<- %ecx 0/r32/eax -11628 # while curr != null -11629 { -11630 81 7/subop/compare %ecx 0/imm32 -11631 74/jump-if-= break/disp8 -11632 # var v/eax: (addr var) = lookup(curr->value) -11633 (lookup *ecx *(ecx+4)) # List-value List-value => eax -11634 # if (v == target) return true -11635 39/compare *(ebp+0xc) 0/r32/eax -11636 b8/copy-to-eax 1/imm32/true -11637 74/jump-if-= $in-function-outputs?:end/disp8 -11638 # curr = curr->next -11639 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax -11640 89/<- %ecx 0/r32/eax -11641 # -11642 eb/jump loop/disp8 -11643 } -11644 b8/copy-to-eax 0/imm32 -11645 $in-function-outputs?:end: -11646 # . restore registers -11647 59/pop-to-ecx -11648 # . epilogue -11649 89/<- %esp 5/r32/ebp -11650 5d/pop-to-ebp -11651 c3/return -11652 -11653 emit-subx-var-def: # out: (addr buffered-file), stmt: (addr stmt) -11654 # . prologue -11655 55/push-ebp -11656 89/<- %ebp 4/r32/esp -11657 # . save registers -11658 50/push-eax -11659 51/push-ecx -11660 52/push-edx -11661 # eax = stmt -11662 8b/-> *(ebp+0xc) 0/r32/eax -11663 # var v/ecx: (addr var) -11664 (lookup *(eax+4) *(eax+8)) # Vardef-var Vardef-var => eax -11665 89/<- %ecx 0/r32/eax -11666 # v->block-depth = *Curr-block-depth -11667 8b/-> *Curr-block-depth 0/r32/eax -11668 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth -11669 # var n/edx: int = size-of(stmt->var) -11670 (size-of %ecx) # => eax -11671 89/<- %edx 0/r32/eax -11672 # *Curr-local-stack-offset -= n -11673 29/subtract-from *Curr-local-stack-offset 2/r32/edx -11674 # v->offset = *Curr-local-stack-offset -11675 8b/-> *Curr-local-stack-offset 0/r32/eax -11676 89/<- *(ecx+0x14) 0/r32/eax # Var-offset -11677 # if v is an array, do something special -11678 { -11679 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax -11680 (is-mu-array? %eax) # => eax -11681 3d/compare-eax-and 0/imm32/false -11682 0f 84/jump-if-= break/disp32 -11683 # var array-size-without-size/edx: int = n-4 -11684 81 5/subop/subtract %edx 4/imm32 -11685 (emit-indent *(ebp+8) *Curr-block-depth) -11686 (write-buffered *(ebp+8) "(push-n-zero-bytes ") -11687 (print-int32-buffered *(ebp+8) %edx) -11688 (write-buffered *(ebp+8) ")\n") -11689 (emit-indent *(ebp+8) *Curr-block-depth) -11690 (write-buffered *(ebp+8) "68/push ") -11691 (print-int32-buffered *(ebp+8) %edx) -11692 (write-buffered *(ebp+8) "/imm32\n") -11693 eb/jump $emit-subx-var-def:end/disp8 -11694 } -11695 # while n > 0 -11696 { -11697 81 7/subop/compare %edx 0/imm32 -11698 7e/jump-if-<= break/disp8 -11699 (emit-indent *(ebp+8) *Curr-block-depth) -11700 (write-buffered *(ebp+8) "68/push 0/imm32\n") -11701 # n -= 4 -11702 81 5/subop/subtract %edx 4/imm32 -11703 # -11704 eb/jump loop/disp8 -11705 } -11706 $emit-subx-var-def:end: -11707 # . restore registers -11708 5a/pop-to-edx -11709 59/pop-to-ecx -11710 58/pop-to-eax -11711 # . epilogue -11712 89/<- %esp 5/r32/ebp -11713 5d/pop-to-ebp -11714 c3/return -11715 -11716 emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) -11717 # . prologue -11718 55/push-ebp -11719 89/<- %ebp 4/r32/esp -11720 # . save registers -11721 50/push-eax -11722 51/push-ecx -11723 # - some special-case primitives that don't actually use the 'primitives' data structure -11724 # var op/ecx: (addr array byte) = lookup(stmt->operation) -11725 8b/-> *(ebp+0xc) 1/r32/ecx -11726 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -11727 89/<- %ecx 0/r32/eax -11728 # array size -11729 { -11730 # if (!string-equal?(stmt->operation, "length")) break -11731 (string-equal? %ecx "length") # => eax -11732 3d/compare-eax-and 0/imm32 -11733 0f 84/jump-if-= break/disp32 -11734 (translate-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -11735 e9/jump $emit-subx-stmt:end/disp32 -11736 } -11737 # index into array -11738 { -11739 # if (!string-equal?(stmt->operation, "index")) break -11740 (string-equal? %ecx "index") # => eax -11741 3d/compare-eax-and 0/imm32 -11742 0f 84/jump-if-= break/disp32 -11743 (translate-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -11744 e9/jump $emit-subx-stmt:end/disp32 -11745 } -11746 # compute-offset for index into array -11747 { -11748 # if (!string-equal?(stmt->operation, "compute-offset")) break -11749 (string-equal? %ecx "compute-offset") # => eax -11750 3d/compare-eax-and 0/imm32 -11751 0f 84/jump-if-= break/disp32 -11752 (translate-mu-compute-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) -11753 e9/jump $emit-subx-stmt:end/disp32 -11754 } -11755 # get field from record -11756 { -11757 # if (!string-equal?(stmt->operation, "get")) break -11758 (string-equal? %ecx "get") # => eax -11759 3d/compare-eax-and 0/imm32 -11760 0f 84/jump-if-= break/disp32 -11761 (translate-mu-get-stmt *(ebp+8) *(ebp+0xc)) -11762 e9/jump $emit-subx-stmt:end/disp32 -11763 } -11764 # - if stmt matches a primitive, emit it -11765 { -11766 $emit-subx-stmt:check-for-primitive: -11767 # var curr/eax: (addr primitive) -11768 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => eax -11769 3d/compare-eax-and 0/imm32 -11770 74/jump-if-= break/disp8 -11771 $emit-subx-stmt:primitive: -11772 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr -11773 e9/jump $emit-subx-stmt:end/disp32 -11774 } -11775 # - otherwise emit a call -11776 # TODO: type-checking -11777 $emit-subx-stmt:call: -11778 (emit-call *(ebp+8) *(ebp+0xc)) -11779 $emit-subx-stmt:end: -11780 # . restore registers -11781 59/pop-to-ecx -11782 58/pop-to-eax -11783 # . epilogue -11784 89/<- %esp 5/r32/ebp -11785 5d/pop-to-ebp -11786 c3/return -11787 -11788 translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -11789 # . prologue -11790 55/push-ebp -11791 89/<- %ebp 4/r32/esp -11792 # . save registers -11793 50/push-eax -11794 51/push-ecx -11795 52/push-edx -11796 53/push-ebx -11797 56/push-esi -11798 # esi = stmt -11799 8b/-> *(ebp+0xc) 6/r32/esi -11800 # var base/ebx: (addr var) = stmt->inouts[0]->value -11801 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax -11802 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -11803 89/<- %ebx 0/r32/eax -11804 # var elemsize/ecx: int = array-element-size(base) -11805 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -11806 89/<- %ecx 0/r32/eax -11807 # var outreg/edx: (addr array byte) = stmt->outputs[0]->value->register -11808 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax -11809 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -11810 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -11811 89/<- %edx 0/r32/eax -11812 # if elemsize == 1 -11813 { -11814 81 7/subop/compare %ecx 1/imm32 -11815 75/jump-if-!= break/disp8 -11816 $translate-mu-length-stmt:size-1: -11817 (emit-save-size-to *(ebp+8) %ebx %edx) -11818 e9/jump $translate-mu-length-stmt:end/disp32 -11819 } -11820 # if elemsize is a power of 2 less than 256 -11821 { -11822 (power-of-2? %ecx *(ebp+0x10) *(ebp+0x14)) # => eax -11823 3d/compare-eax-and 0/imm32/false -11824 74/jump-if-= break/disp8 -11825 81 7/subop/compare %ecx 0xff/imm32 -11826 7f/jump-if-> break/disp8 -11827 $translate-mu-length-stmt:size-power-of-2: -11828 (emit-save-size-to *(ebp+8) %ebx %edx) -11829 (emit-divide-by-shift-right *(ebp+8) %edx %ecx) -11830 e9/jump $translate-mu-length-stmt:end/disp32 -11831 } -11832 # otherwise, the complex case -11833 # . emit register spills -11834 { -11835 $translate-mu-length-stmt:complex: -11836 (string-equal? %edx "eax") # => eax -11837 3d/compare-eax-and 0/imm32/false -11838 75/break-if-!= break/disp8 -11839 (emit-indent *(ebp+8) *Curr-block-depth) -11840 (write-buffered *(ebp+8) "50/push-eax\n") -11841 } -11842 { -11843 (string-equal? %edx "ecx") # => eax -11844 3d/compare-eax-and 0/imm32/false -11845 75/break-if-!= break/disp8 -11846 (emit-indent *(ebp+8) *Curr-block-depth) -11847 (write-buffered *(ebp+8) "51/push-ecx\n") +11626 #? (write-buffered Stderr "size-of ") +11627 #? (print-int32-buffered Stderr %ecx) +11628 #? (write-buffered Stderr Newline) +11629 #? (write-buffered Stderr "type allocid: ") +11630 #? (print-int32-buffered Stderr *(ecx+8)) +11631 #? (write-buffered Stderr Newline) +11632 #? (flush Stderr) +11633 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +11634 89/<- %ecx 0/r32/eax +11635 # if is-mu-array?(t) return size-of-array(t) +11636 { +11637 (is-mu-array? %ecx) # => eax +11638 3d/compare-eax-and 0/imm32/false +11639 74/jump-if-= break/disp8 +11640 (size-of-array %ecx) # => eax +11641 eb/jump $size-of:end/disp8 +11642 } +11643 # if (!t->is-atom?) t = lookup(t->left) +11644 { +11645 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom +11646 75/jump-if-!= break/disp8 +11647 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax +11648 89/<- %ecx 0/r32/eax +11649 } +11650 # TODO: assert t->is-atom? +11651 (size-of-type-id *(ecx+4)) # Tree-value => eax +11652 $size-of:end: +11653 # . restore registers +11654 59/pop-to-ecx +11655 # . epilogue +11656 89/<- %esp 5/r32/ebp +11657 5d/pop-to-ebp +11658 c3/return +11659 +11660 size-of-deref: # v: (addr var) -> result/eax: int +11661 # . prologue +11662 55/push-ebp +11663 89/<- %ebp 4/r32/esp +11664 # . save registers +11665 51/push-ecx +11666 # var t/ecx: (addr tree type-id) = lookup(v->type) +11667 8b/-> *(ebp+8) 1/r32/ecx +11668 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +11669 89/<- %ecx 0/r32/eax +11670 # TODO: assert(t is an addr) +11671 # t = lookup(t->right) +11672 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax +11673 89/<- %ecx 0/r32/eax +11674 # if is-mu-array?(t) return size-of-array(t) +11675 { +11676 (is-mu-array? %ecx) # => eax +11677 3d/compare-eax-and 0/imm32/false +11678 74/jump-if-= break/disp8 +11679 (size-of-array %ecx) # => eax +11680 eb/jump $size-of:end/disp8 +11681 } +11682 # if (!t->is-atom?) t = lookup(t->left) +11683 { +11684 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom +11685 75/jump-if-!= break/disp8 +11686 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax +11687 89/<- %ecx 0/r32/eax +11688 } +11689 # TODO: assert t->is-atom? +11690 (size-of-type-id *(ecx+4)) # Tree-value => eax +11691 $size-of-deref:end: +11692 # . restore registers +11693 59/pop-to-ecx +11694 # . epilogue +11695 89/<- %esp 5/r32/ebp +11696 5d/pop-to-ebp +11697 c3/return +11698 +11699 is-mu-array?: # t: (addr tree type-id) -> result/eax: boolean +11700 # . prologue +11701 55/push-ebp +11702 89/<- %ebp 4/r32/esp +11703 # . save registers +11704 51/push-ecx +11705 # ecx = t +11706 8b/-> *(ebp+8) 1/r32/ecx +11707 # if t->is-atom?, return false +11708 81 7/subop/compare *ecx 0/imm32/false # Tree-is-atom +11709 75/jump-if-!= $is-mu-array?:return-false/disp8 +11710 # if !t->left->is-atom?, return false +11711 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax +11712 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom +11713 74/jump-if-= $is-mu-array?:return-false/disp8 +11714 # return t->left->value == array +11715 81 7/subop/compare *(eax+4) 3/imm32/array-type-id # Tree-value +11716 0f 94/set-if-= %al +11717 81 4/subop/and %eax 0xff/imm32 +11718 eb/jump $is-mu-array?:end/disp8 +11719 $is-mu-array?:return-false: +11720 b8/copy-to-eax 0/imm32/false +11721 $is-mu-array?:end: +11722 # . restore registers +11723 59/pop-to-ecx +11724 # . epilogue +11725 89/<- %esp 5/r32/ebp +11726 5d/pop-to-ebp +11727 c3/return +11728 +11729 size-of-array: # a: (addr tree type-id) -> result/eax: int +11730 # . prologue +11731 55/push-ebp +11732 89/<- %ebp 4/r32/esp +11733 # . save registers +11734 51/push-ecx +11735 52/push-edx +11736 # +11737 8b/-> *(ebp+8) 1/r32/ecx +11738 # TODO: assert that a->left is 'array' +11739 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax +11740 89/<- %ecx 0/r32/eax +11741 # var elem-type/edx: type-id = a->right->left->value +11742 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax +11743 8b/-> *(eax+4) 2/r32/edx # Tree-value +11744 # var array-size/ecx: int = a->right->right->left->value +11745 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax +11746 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax +11747 8b/-> *(eax+4) 1/r32/ecx # Tree-value +11748 # return array-size * size-of(elem-type) +11749 (size-of-type-id-as-array-element %edx) # => eax +11750 f7 4/subop/multiply-into-eax %ecx +11751 05/add-to-eax 4/imm32 # for array size +11752 $size-of-array:end: +11753 # . restore registers +11754 5a/pop-to-edx +11755 59/pop-to-ecx +11756 # . epilogue +11757 89/<- %esp 5/r32/ebp +11758 5d/pop-to-ebp +11759 c3/return +11760 +11761 size-of-type-id: # t: type-id -> result/eax: int +11762 # . prologue +11763 55/push-ebp +11764 89/<- %ebp 4/r32/esp +11765 # . save registers +11766 51/push-ecx +11767 # var out/ecx: (handle typeinfo) +11768 68/push 0/imm32 +11769 68/push 0/imm32 +11770 89/<- %ecx 4/r32/esp +11771 # eax = t +11772 8b/-> *(ebp+8) 0/r32/eax +11773 # if t is a literal, return 0 +11774 3d/compare-eax-and 0/imm32 +11775 0f 84/jump-if-= $size-of-type-id:end/disp32 # eax changes type from type-id to int +11776 # if t is a byte, return 4 (because we don't really support non-multiples of 4) +11777 3d/compare-eax-and 8/imm32/byte +11778 { +11779 75/jump-if-!= break/disp8 +11780 b8/copy-to-eax 4/imm32 +11781 eb/jump $size-of-type-id:end/disp8 +11782 } +11783 # if t is a handle, return 8 +11784 3d/compare-eax-and 4/imm32/handle +11785 { +11786 75/jump-if-!= break/disp8 +11787 b8/copy-to-eax 8/imm32 +11788 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int +11789 } +11790 # if t is a user-defined type, return its size +11791 # TODO: support non-atom type +11792 (find-typeinfo %eax %ecx) +11793 { +11794 81 7/subop/compare *ecx 0/imm32 +11795 74/jump-if-= break/disp8 +11796 $size-of-type-id:user-defined: +11797 (lookup *ecx *(ecx+4)) # => eax +11798 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-total-size-in-bytes +11799 eb/jump $size-of-type-id:end/disp8 +11800 } +11801 # otherwise return the word size +11802 b8/copy-to-eax 4/imm32 +11803 $size-of-type-id:end: +11804 # . reclaim locals +11805 81 0/subop/add %esp 8/imm32 +11806 # . restore registers +11807 59/pop-to-ecx +11808 # . epilogue +11809 89/<- %esp 5/r32/ebp +11810 5d/pop-to-ebp +11811 c3/return +11812 +11813 type-equal?: # a: (addr tree type-id), b: (addr tree type-id) -> result/eax: boolean +11814 # . prologue +11815 55/push-ebp +11816 89/<- %ebp 4/r32/esp +11817 # . save registers +11818 51/push-ecx +11819 52/push-edx +11820 53/push-ebx +11821 # ecx = a +11822 8b/-> *(ebp+8) 1/r32/ecx +11823 # edx = b +11824 8b/-> *(ebp+0xc) 2/r32/edx +11825 $type-equal?:compare-addr: +11826 # if (a == b) return true +11827 8b/-> %ecx 0/r32/eax # Var-type +11828 39/compare %edx 0/r32/eax # Var-type +11829 b8/copy-to-eax 1/imm32/true +11830 0f 84/jump-if-= $type-equal?:end/disp32 +11831 $type-equal?:compare-atom-state: +11832 # if (a->is-atom? != b->is-atom?) return false +11833 8b/-> *ecx 3/r32/ebx # Tree-value +11834 39/compare *edx 3/r32/ebx # Tree-value +11835 b8/copy-to-eax 0/imm32/false +11836 0f 85/jump-if-!= $type-equal?:end/disp32 +11837 # if a->is-atom? return (a->value == b->value) +11838 { +11839 $type-equal?:check-atom: +11840 81 7/subop/compare %ebx 0/imm32/false +11841 74/jump-if-= break/disp8 +11842 $type-equal?:is-atom: +11843 8b/-> *(ecx+4) 0/r32/eax # Tree-value +11844 39/compare *(edx+4) 0/r32/eax # Tree-value +11845 0f 94/set-if-= %al +11846 81 4/subop/and %eax 0xff/imm32 +11847 e9/jump $type-equal?:end/disp32 11848 } -11849 { -11850 (string-equal? %edx "edx") # => eax -11851 3d/compare-eax-and 0/imm32/false -11852 75/break-if-!= break/disp8 -11853 (emit-indent *(ebp+8) *Curr-block-depth) -11854 (write-buffered *(ebp+8) "52/push-edx\n") -11855 } -11856 # . -11857 (emit-save-size-to *(ebp+8) %ebx "eax") -11858 (emit-indent *(ebp+8) *Curr-block-depth) -11859 (write-buffered *(ebp+8) "31/xor %edx 2/r32/edx\n") -11860 (emit-indent *(ebp+8) *Curr-block-depth) -11861 (write-buffered *(ebp+8) "b9/copy-to-ecx ") -11862 (print-int32-buffered *(ebp+8) %ecx) -11863 (write-buffered *(ebp+8) "/imm32\n") -11864 (emit-indent *(ebp+8) *Curr-block-depth) -11865 (write-buffered *(ebp+8) "f7 7/subop/idiv-eax-edx-by %ecx\n") -11866 { -11867 (string-equal? %edx "eax") # => eax -11868 3d/compare-eax-and 0/imm32/false -11869 75/break-if-!= break/disp8 -11870 (emit-indent *(ebp+8) *Curr-block-depth) -11871 (write-buffered *(ebp+8) "89/<- %") -11872 (write-buffered *(ebp+8) %edx) -11873 (write-buffered *(ebp+8) " 0/r32/eax\n") -11874 } -11875 # . emit register restores -11876 { -11877 (string-equal? %edx "edx") # => eax -11878 3d/compare-eax-and 0/imm32/false -11879 75/break-if-!= break/disp8 -11880 (emit-indent *(ebp+8) *Curr-block-depth) -11881 (write-buffered *(ebp+8) "5a/pop-to-edx\n") -11882 } -11883 { -11884 (string-equal? %edx "ecx") # => eax -11885 3d/compare-eax-and 0/imm32/false -11886 75/break-if-!= break/disp8 -11887 (emit-indent *(ebp+8) *Curr-block-depth) -11888 (write-buffered *(ebp+8) "59/pop-to-ecx\n") -11889 } -11890 { -11891 (string-equal? %edx "eax") # => eax -11892 3d/compare-eax-and 0/imm32/false -11893 75/break-if-!= break/disp8 -11894 (emit-indent *(ebp+8) *Curr-block-depth) -11895 (write-buffered *(ebp+8) "58/pop-to-eax\n") -11896 } -11897 $translate-mu-length-stmt:end: -11898 # . restore registers -11899 5e/pop-to-esi -11900 5b/pop-to-ebx -11901 5a/pop-to-edx -11902 59/pop-to-ecx -11903 58/pop-to-eax -11904 # . epilogue -11905 89/<- %esp 5/r32/ebp -11906 5d/pop-to-ebp -11907 c3/return -11908 -11909 array-element-size: # arr: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int -11910 # . prologue -11911 55/push-ebp -11912 89/<- %ebp 4/r32/esp -11913 # -11914 (array-element-type-id *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax -11915 (size-of-type-id-as-array-element %eax) # => eax -11916 $array-element-size:end: -11917 # . epilogue -11918 89/<- %esp 5/r32/ebp -11919 5d/pop-to-ebp -11920 c3/return -11921 -11922 size-of-type-id-as-array-element: # t: type-id -> result/eax: int -11923 # . prologue -11924 55/push-ebp -11925 89/<- %ebp 4/r32/esp -11926 # eax = t -11927 8b/-> *(ebp+8) 0/r32/eax -11928 # if t is 'byte', size is 1 -11929 3d/compare-eax-and 8/imm32/byte -11930 { -11931 75/jump-if-!= break/disp8 -11932 b8/copy-to-eax 1/imm32 -11933 eb/jump $array-element-size:end/disp8 -11934 } -11935 # otherwise proceed as usual -11936 (size-of-type-id %eax) # => eax -11937 $size-of-type-id-as-array-element:end: -11938 # . epilogue -11939 89/<- %esp 5/r32/ebp -11940 5d/pop-to-ebp -11941 c3/return -11942 -11943 emit-save-size-to: # out: (addr buffered-file), base: (addr var), outreg: (addr array byte) -11944 # . prologue -11945 55/push-ebp -11946 89/<- %ebp 4/r32/esp -11947 # . save registers -11948 50/push-eax -11949 53/push-ebx -11950 # ebx = base -11951 8b/-> *(ebp+0xc) 3/r32/ebx -11952 (emit-indent *(ebp+8) *Curr-block-depth) -11953 (write-buffered *(ebp+8) "8b/-> *") -11954 # if base is an (addr array ...) in a register -11955 { -11956 81 7/subop/compare *(ebx+0x18)) 0/imm32 # Var-register -11957 74/jump-if-= break/disp8 -11958 $emit-save-size-to:emit-base-from-register: -11959 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -11960 (write-buffered *(ebp+8) %eax) -11961 eb/jump $emit-save-size-to:emit-output/disp8 -11962 } -11963 # otherwise if base is an (array ...) on the stack -11964 { -11965 81 7/subop/compare *(ebx+0x14)) 0/imm32 # Var-offset -11966 74/jump-if-= break/disp8 -11967 $emit-save-size-to:emit-base-from-stack: -11968 (write-buffered *(ebp+8) "(ebp+") -11969 (print-int32-buffered *(ebp+8) *(ebx+0x14)) # Var-offset -11970 (write-buffered *(ebp+8) ")") -11971 } -11972 $emit-save-size-to:emit-output: -11973 (write-buffered *(ebp+8) " ") -11974 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax -11975 (print-int32-buffered *(ebp+8) *eax) -11976 (write-buffered *(ebp+8) "/r32\n") -11977 $emit-save-size-to:end: -11978 # . restore registers -11979 5b/pop-to-ebx -11980 58/pop-to-eax -11981 # . epilogue -11982 89/<- %esp 5/r32/ebp -11983 5d/pop-to-ebp -11984 c3/return -11985 -11986 emit-divide-by-shift-right: # out: (addr buffered-file), reg: (addr array byte), size: int -11987 # . prologue -11988 55/push-ebp -11989 89/<- %ebp 4/r32/esp -11990 # . save registers -11991 50/push-eax -11992 # -11993 (emit-indent *(ebp+8) *Curr-block-depth) -11994 (write-buffered *(ebp+8) "c1/shift 5/subop/>> %") -11995 (write-buffered *(ebp+8) *(ebp+0xc)) -11996 (write-buffered *(ebp+8) Space) -11997 (num-shift-rights *(ebp+0x10)) # => eax -11998 (print-int32-buffered *(ebp+8) %eax) -11999 (write-buffered *(ebp+8) "/imm8\n") -12000 $emit-divide-by-shift-right:end: -12001 # . restore registers -12002 58/pop-to-eax -12003 # . epilogue -12004 89/<- %esp 5/r32/ebp -12005 5d/pop-to-ebp -12006 c3/return -12007 -12008 translate-mu-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -12009 # . prologue -12010 55/push-ebp -12011 89/<- %ebp 4/r32/esp -12012 # . save registers -12013 51/push-ecx -12014 # ecx = stmt -12015 8b/-> *(ebp+0xc) 1/r32/ecx -12016 # var base/ecx: (addr var) = stmt->inouts[0] -12017 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12018 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12019 89/<- %ecx 0/r32/eax -12020 # if (var->register) do one thing -12021 { -12022 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register -12023 74/jump-if-= break/disp8 -12024 # TODO: ensure there's no dereference -12025 (translate-mu-index-stmt-with-array-in-register *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -12026 eb/jump $translate-mu-index-stmt:end/disp8 -12027 } -12028 # if (var->offset) do a different thing -12029 { -12030 81 7/subop/compare *(ecx+0x14) 0/imm32 # Var-offset -12031 74/jump-if-= break/disp8 -12032 # TODO: ensure there's no dereference -12033 (translate-mu-index-stmt-with-array-on-stack *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) -12034 eb/jump $translate-mu-index-stmt:end/disp8 -12035 } -12036 $translate-mu-index-stmt:end: -12037 # . restore registers -12038 59/pop-to-ecx -12039 # . epilogue -12040 89/<- %esp 5/r32/ebp -12041 5d/pop-to-ebp -12042 c3/return -12043 -12044 $translate-mu-index-stmt-with-array:error1: -12045 (write-buffered *(ebp+0x10) "couldn't translate an index instruction. second (index) input must either lie in a register or be a literal\n") -12046 (flush *(ebp+0x10)) -12047 (stop *(ebp+0x14) 1) -12048 # never gets here -12049 -12050 $translate-mu-index-stmt-with-array:error2: -12051 (write-buffered *(ebp+0x10) "couldn't translate an index instruction. second (index) input when in a register must be an int or offset\n") -12052 (flush *(ebp+0x10)) -12053 (stop *(ebp+0x14) 1) -12054 # never gets here -12055 -12056 translate-mu-index-stmt-with-array-in-register: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -12057 # . prologue -12058 55/push-ebp -12059 89/<- %ebp 4/r32/esp -12060 # . save registers -12061 50/push-eax -12062 51/push-ecx -12063 52/push-edx -12064 53/push-ebx -12065 # -12066 (emit-indent *(ebp+8) *Curr-block-depth) -12067 (write-buffered *(ebp+8) "8d/copy-address *(") -12068 # TODO: ensure inouts[0] is in a register and not dereferenced -12069 $translate-mu-index-stmt-with-array-in-register:emit-base: -12070 # ecx = stmt -12071 8b/-> *(ebp+0xc) 1/r32/ecx -12072 # var base/ebx: (addr var) = inouts[0] -12073 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12074 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12075 89/<- %ebx 0/r32/eax -12076 # print base->register " + " -12077 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax -12078 (write-buffered *(ebp+8) %eax) -12079 (write-buffered *(ebp+8) " + ") -12080 # var index/edx: (addr var) = inouts[1] -12081 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12082 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -12083 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12084 89/<- %edx 0/r32/eax -12085 # if index->register -12086 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register -12087 { -12088 0f 84/jump-if-= break/disp32 -12089 $translate-mu-index-stmt-with-array-in-register:emit-register-index: -12090 # if index is an int -12091 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -12092 (is-simple-mu-type? %eax 1) # int => eax -12093 3d/compare-eax-and 0/imm32/false -12094 { -12095 0f 84/jump-if-= break/disp32 -12096 $translate-mu-index-stmt-with-array-in-register:emit-int-register-index: -12097 # print index->register "<<" log2(array-element-size(base)) " + 4) " -12098 # . index->register "<<" -12099 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -12100 (write-buffered *(ebp+8) %eax) -12101 (write-buffered *(ebp+8) "<<") -12102 # . log2(array-element-size(base->type)) -12103 # TODO: ensure size is a power of 2 -12104 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -12105 (num-shift-rights %eax) # => eax -12106 (print-int32-buffered *(ebp+8) %eax) -12107 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-register-index-done/disp32 -12108 } -12109 # if index->type is any other atom, abort -12110 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -12111 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom -12112 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 -12113 # if index has type (offset ...) -12114 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax -12115 (is-simple-mu-type? %eax 7) # => eax -12116 3d/compare-eax-and 0/imm32/false -12117 { -12118 0f 84/jump-if-= break/disp32 -12119 # print index->register -12120 $translate-mu-index-stmt-with-array-in-register:emit-offset-register-index: -12121 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -12122 (write-buffered *(ebp+8) %eax) -12123 } -12124 $translate-mu-index-stmt-with-array-in-register:emit-register-index-done: -12125 (write-buffered *(ebp+8) " + 4) ") -12126 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 -12127 } -12128 # otherwise if index is a literal -12129 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -12130 (is-simple-mu-type? %eax 0) # => eax -12131 3d/compare-eax-and 0/imm32/false -12132 { -12133 0f 84/jump-if-= break/disp32 -12134 $translate-mu-index-stmt-with-array-in-register:emit-literal-index: -12135 # var index-value/edx: int = parse-hex-int(index->name) -12136 (lookup *edx *(edx+4)) # Var-name Var-name => eax -12137 (parse-hex-int %eax) # => eax -12138 89/<- %edx 0/r32/eax -12139 # offset = idx-value * array-element-size(base->type) -12140 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -12141 f7 4/subop/multiply-into-eax %edx # clobbers edx -12142 # offset += 4 for array size -12143 05/add-to-eax 4/imm32 -12144 # TODO: check edx for overflow -12145 # print offset -12146 (print-int32-buffered *(ebp+8) %eax) -12147 (write-buffered *(ebp+8) ") ") -12148 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 -12149 } -12150 # otherwise abort -12151 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 -12152 $translate-mu-index-stmt-with-array-in-register:emit-output: -12153 # outputs[0] "/r32" -12154 8b/-> *(ebp+0xc) 1/r32/ecx -12155 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -12156 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12157 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -12158 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -12159 (print-int32-buffered *(ebp+8) *eax) -12160 (write-buffered *(ebp+8) "/r32\n") -12161 $translate-mu-index-stmt-with-array-in-register:end: -12162 # . restore registers -12163 5b/pop-to-ebx -12164 5a/pop-to-edx -12165 59/pop-to-ecx -12166 58/pop-to-eax -12167 # . epilogue -12168 89/<- %esp 5/r32/ebp -12169 5d/pop-to-ebp -12170 c3/return -12171 -12172 translate-mu-index-stmt-with-array-on-stack: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -12173 # . prologue -12174 55/push-ebp -12175 89/<- %ebp 4/r32/esp -12176 # . save registers -12177 50/push-eax -12178 51/push-ecx -12179 52/push-edx -12180 53/push-ebx -12181 # -12182 (emit-indent *(ebp+8) *Curr-block-depth) -12183 (write-buffered *(ebp+8) "8d/copy-address *(ebp + ") -12184 # var curr/edx: (addr stmt-var) = lookup(stmt->inouts) -12185 8b/-> *(ebp+0xc) 0/r32/eax -12186 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12187 89/<- %edx 0/r32/eax -12188 # var base/ecx: (addr var) = lookup(curr->value) -12189 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12190 89/<- %ecx 0/r32/eax -12191 # var curr2/eax: (addr stmt-var) = lookup(curr->next) -12192 (lookup *(edx+8) *(edx+0xc)) # Stmt-var-next Stmt-var-next => eax -12193 # var index/edx: (handle var) = curr2->value -12194 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12195 89/<- %edx 0/r32/eax -12196 # if index->register -12197 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register -12198 { -12199 0f 84/jump-if-= break/disp32 -12200 $translate-mu-index-stmt-with-array-on-stack:emit-register-index: -12201 # if index is an int -12202 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -12203 (is-simple-mu-type? %eax 1) # int => eax -12204 3d/compare-eax-and 0/imm32/false -12205 { -12206 0f 84/jump-if-= break/disp32 -12207 $translate-mu-index-stmt-with-array-on-stack:emit-int-register-index: -12208 # print index->register "<<" log2(array-element-size(base)) " + " base->offset+4 -12209 # . inouts[1]->register "<<" -12210 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -12211 (write-buffered *(ebp+8) %eax) -12212 (write-buffered *(ebp+8) "<<") -12213 # . log2(array-element-size(base)) -12214 # TODO: ensure size is a power of 2 -12215 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax -12216 (num-shift-rights %eax) # => eax -12217 (print-int32-buffered *(ebp+8) %eax) -12218 # -12219 (write-buffered *(ebp+8) " + ") -12220 # -12221 8b/-> *(ecx+0x14) 0/r32/eax # Var-offset -12222 05/add-to-eax 4/imm32 # for array length -12223 (print-int32-buffered *(ebp+8) %eax) -12224 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done/disp32 -12225 } -12226 # if index->type is any other atom, abort -12227 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -12228 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom -12229 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 -12230 # if index has type (offset ...) -12231 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax -12232 (is-simple-mu-type? %eax 7) # => eax -12233 3d/compare-eax-and 0/imm32/false -12234 { -12235 0f 84/jump-if-= break/disp32 -12236 # print index->register -12237 $translate-mu-index-stmt-with-array-on-stack:emit-offset-register-index: -12238 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax -12239 (write-buffered *(ebp+8) %eax) -12240 } -12241 $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done: -12242 (write-buffered *(ebp+8) ") ") -12243 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 -12244 } -12245 # otherwise if index is a literal -12246 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax -12247 (is-simple-mu-type? %eax 0) # => eax -12248 3d/compare-eax-and 0/imm32/false -12249 { -12250 0f 84/jump-if-= break/disp32 -12251 $translate-mu-index-stmt-with-array-on-stack:emit-literal-index: -12252 # var idx-value/edx: int = parse-hex-int(index->name) -12253 (lookup *edx *(edx+4)) # Var-name Var-name => eax -12254 (parse-hex-int %eax) # Var-name => eax -12255 89/<- %edx 0/r32/eax -12256 # offset = idx-value * array-element-size(base) -12257 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax -12258 f7 4/subop/multiply-into-eax %edx # clobbers edx -12259 # offset += base->offset -12260 03/add *(ecx+0x14) 0/r32/eax # Var-offset -12261 # offset += 4 for array size -12262 05/add-to-eax 4/imm32 -12263 # TODO: check edx for overflow -12264 # print offset -12265 (print-int32-buffered *(ebp+8) %eax) -12266 (write-buffered *(ebp+8) ") ") -12267 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 -12268 } -12269 # otherwise abort -12270 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 -12271 $translate-mu-index-stmt-with-array-on-stack:emit-output: -12272 # outputs[0] "/r32" -12273 8b/-> *(ebp+0xc) 0/r32/eax -12274 (lookup *(eax+0x14) *(eax+0x18)) # Stmt1-outputs Stmt1-outputs => eax -12275 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12276 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -12277 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -12278 (print-int32-buffered *(ebp+8) *eax) -12279 (write-buffered *(ebp+8) "/r32\n") -12280 $translate-mu-index-stmt-with-array-on-stack:end: -12281 # . restore registers -12282 5b/pop-to-ebx -12283 5a/pop-to-edx -12284 59/pop-to-ecx -12285 58/pop-to-eax -12286 # . epilogue -12287 89/<- %esp 5/r32/ebp -12288 5d/pop-to-ebp -12289 c3/return -12290 -12291 translate-mu-compute-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -12292 # . prologue -12293 55/push-ebp -12294 89/<- %ebp 4/r32/esp -12295 # . save registers -12296 50/push-eax -12297 51/push-ecx -12298 52/push-edx -12299 53/push-ebx -12300 # -12301 (emit-indent *(ebp+8) *Curr-block-depth) -12302 (write-buffered *(ebp+8) "69/multiply") -12303 # ecx = stmt -12304 8b/-> *(ebp+0xc) 1/r32/ecx -12305 # var first-inout/ebx: (addr stmt-var) = stmt->inouts[0] -12306 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12307 89/<- %ebx 0/r32/eax -12308 $translate-mu-compute-index-stmt:emit-index: -12309 (lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax -12310 (emit-subx-var-as-rm32 *(ebp+8) %eax) -12311 (write-buffered *(ebp+8) Space) -12312 $translate-mu-compute-index-stmt:emit-elem-size: -12313 # var base/ebx: (addr var) -12314 (lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax -12315 89/<- %ebx 0/r32/eax -12316 # print array-element-size(base) -12317 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax -12318 (print-int32-buffered *(ebp+8) %eax) -12319 (write-buffered *(ebp+8) "/imm32 ") -12320 $translate-mu-compute-index-stmt:emit-output: -12321 # outputs[0] "/r32" -12322 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -12323 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12324 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -12325 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -12326 (print-int32-buffered *(ebp+8) *eax) -12327 (write-buffered *(ebp+8) "/r32\n") -12328 $translate-mu-compute-index-stmt:end: -12329 # . restore registers -12330 5b/pop-to-ebx -12331 5a/pop-to-edx -12332 59/pop-to-ecx -12333 58/pop-to-eax -12334 # . epilogue -12335 89/<- %esp 5/r32/ebp -12336 5d/pop-to-ebp -12337 c3/return -12338 -12339 translate-mu-get-stmt: # out: (addr buffered-file), stmt: (addr stmt) -12340 # . prologue -12341 55/push-ebp -12342 89/<- %ebp 4/r32/esp -12343 # . save registers -12344 50/push-eax -12345 51/push-ecx -12346 52/push-edx -12347 # -12348 (emit-indent *(ebp+8) *Curr-block-depth) -12349 (write-buffered *(ebp+8) "8d/copy-address ") -12350 # ecx = stmt -12351 8b/-> *(ebp+0xc) 1/r32/ecx -12352 # var offset/edx: int = get offset of stmt -12353 (mu-get-offset %ecx) # => eax -12354 89/<- %edx 0/r32/eax -12355 # var base/eax: (addr var) = stmt->inouts->value -12356 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12357 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12358 # if base is in a register -12359 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register -12360 { -12361 0f 84/jump-if-= break/disp32 -12362 $translate-mu-get-stmt:emit-register-input: -12363 # emit "*(" base->register " + " offset ") " -12364 (write-buffered *(ebp+8) "*(") -12365 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -12366 (write-buffered *(ebp+8) %eax) -12367 (write-buffered *(ebp+8) " + ") -12368 (print-int32-buffered *(ebp+8) %edx) -12369 (write-buffered *(ebp+8) ") ") -12370 e9/jump $translate-mu-get-stmt:emit-output/disp32 -12371 } -12372 # otherwise base is on the stack -12373 { -12374 $translate-mu-get-stmt:emit-stack-input: -12375 # emit "*(ebp + " inouts[0]->stack-offset + offset ") " -12376 (write-buffered *(ebp+8) "*(ebp+") -12377 03/add *(eax+0x14) 2/r32/edx # Var-offset -12378 (print-int32-buffered *(ebp+8) %edx) -12379 (write-buffered *(ebp+8) ") ") -12380 eb/jump $translate-mu-get-stmt:emit-output/disp8 -12381 } -12382 $translate-mu-get-stmt:emit-output: -12383 # var output/eax: (addr var) = stmt->outputs->value -12384 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -12385 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12386 # emit offset->register "/r32" -12387 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -12388 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) -12389 (print-int32-buffered *(ebp+8) *eax) -12390 (write-buffered *(ebp+8) "/r32\n") -12391 $translate-mu-get-stmt:end: -12392 # . restore registers -12393 5a/pop-to-edx -12394 59/pop-to-ecx -12395 58/pop-to-eax -12396 # . epilogue -12397 89/<- %esp 5/r32/ebp -12398 5d/pop-to-ebp -12399 c3/return -12400 -12401 array-element-type-id: # v: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: type-id -12402 # precondition: n is positive -12403 # . prologue -12404 55/push-ebp -12405 89/<- %ebp 4/r32/esp -12406 # -12407 8b/-> *(ebp+8) 0/r32/eax -12408 # var t/eax: (addr tree type-id) -12409 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax -12410 # if t == 0 abort -12411 3d/compare-eax-with 0/imm32 -12412 0f 84/jump-if-== $array-element-type-id:error0/disp32 -12413 # if t->is-atom? abort -12414 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom -12415 0f 85/jump-if-!= $array-element-type-id:error1/disp32 -12416 # if (t->left == addr) t = t->right -12417 { -12418 50/push-eax -12419 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax -12420 (is-simple-mu-type? %eax 2) # addr => eax -12421 3d/compare-eax-with 0/imm32/false -12422 58/pop-to-eax -12423 74/jump-if-= break/disp8 -12424 $array-element-type-id:skip-addr: -12425 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax -12426 } -12427 # if t == 0 abort -12428 3d/compare-eax-with 0/imm32 -12429 0f 84/jump-if-= $array-element-type-id:error2/disp32 -12430 # if t->is-atom? abort -12431 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom -12432 0f 85/jump-if-!= $array-element-type-id:error2/disp32 -12433 # if t->left != array abort -12434 { -12435 50/push-eax -12436 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax -12437 (is-simple-mu-type? %eax 3) # array => eax -12438 3d/compare-eax-with 0/imm32/false -12439 58/pop-to-eax -12440 $array-element-type-id:no-array: -12441 0f 84/jump-if-= $array-element-type-id:error2/disp32 -12442 } -12443 $array-element-type-id:skip-array: -12444 # t = t->right -12445 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax -12446 # if t == 0 abort -12447 3d/compare-eax-with 0/imm32 -12448 0f 84/jump-if-= $array-element-type-id:error2/disp32 -12449 # if t->is-atom? abort -12450 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom -12451 0f 85/jump-if-!= $array-element-type-id:error2/disp32 -12452 # return t->left->value -12453 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax -12454 8b/-> *(eax+4) 0/r32/eax # Tree-value -12455 $array-element-type-id:end: -12456 # . epilogue -12457 89/<- %esp 5/r32/ebp -12458 5d/pop-to-ebp -12459 c3/return -12460 -12461 $array-element-type-id:error0: -12462 (write-buffered *(ebp+0xc) "array-element-type-id: var '") -12463 50/push-eax -12464 8b/-> *(ebp+8) 0/r32/eax -12465 (lookup *eax *(eax+4)) # Var-name Var-name => eax -12466 (write-buffered *(ebp+0xc) %eax) -12467 58/pop-to-eax -12468 (write-buffered *(ebp+0xc) "' has no type\n") -12469 (flush *(ebp+0xc)) -12470 (stop *(ebp+0x10) 1) -12471 # never gets here -12472 -12473 $array-element-type-id:error1: -12474 (write-buffered *(ebp+0xc) "array-element-type-id: var '") -12475 50/push-eax -12476 8b/-> *(ebp+8) 0/r32/eax -12477 (lookup *eax *(eax+4)) # Var-name Var-name => eax -12478 (write-buffered *(ebp+0xc) %eax) -12479 58/pop-to-eax -12480 (write-buffered *(ebp+0xc) "' has atomic type ") -12481 (print-int32-buffered *(ebp+0xc) *(eax+4)) # Tree-value -12482 (write-buffered *(ebp+0xc) Newline) -12483 (flush *(ebp+0xc)) -12484 (stop *(ebp+0x10) 1) -12485 # never gets here -12486 -12487 $array-element-type-id:error2: -12488 (write-buffered *(ebp+0xc) "array-element-type-id: var '") -12489 50/push-eax -12490 8b/-> *(ebp+8) 0/r32/eax -12491 (lookup *eax *(eax+4)) # Var-name Var-name => eax -12492 (write-buffered *(ebp+0xc) %eax) -12493 58/pop-to-eax -12494 (write-buffered *(ebp+0xc) "' has non-array type\n") -12495 (flush *(ebp+0xc)) -12496 (stop *(ebp+0x10) 1) -12497 # never gets here -12498 -12499 power-of-2?: # n: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: boolean -12500 # precondition: n is positive -12501 # . prologue -12502 55/push-ebp -12503 89/<- %ebp 4/r32/esp -12504 # eax = n -12505 8b/-> *(ebp+8) 0/r32/eax -12506 # if (n < 0) abort -12507 3d/compare-eax-with 0/imm32 -12508 0f 8c/jump-if-< $power-of-2?:abort/disp32 -12509 # var tmp/eax: int = n-1 -12510 48/decrement-eax -12511 # var tmp2/eax: int = n & tmp -12512 23/and-> *(ebp+8) 0/r32/eax -12513 # return (tmp2 == 0) -12514 3d/compare-eax-and 0/imm32 -12515 0f 94/set-byte-if-= %al -12516 81 4/subop/and %eax 0xff/imm32 -12517 $power-of-2?:end: -12518 # . epilogue -12519 89/<- %esp 5/r32/ebp -12520 5d/pop-to-ebp -12521 c3/return -12522 -12523 $power-of-2?:abort: -12524 (write-buffered *(ebp+0xc) "power-of-2?: negative number\n") -12525 (flush *(ebp+0xc)) -12526 (stop *(ebp+0x10) 1) -12527 # never gets here -12528 -12529 num-shift-rights: # n: int -> result/eax: int -12530 # precondition: n is a positive power of 2 -12531 # . prologue -12532 55/push-ebp -12533 89/<- %ebp 4/r32/esp -12534 # . save registers -12535 51/push-ecx -12536 # var curr/ecx: int = n -12537 8b/-> *(ebp+8) 1/r32/ecx -12538 # result = 0 -12539 b8/copy-to-eax 0/imm32 -12540 { -12541 # if (curr <= 1) break -12542 81 7/subop/compare %ecx 1/imm32 -12543 7e/jump-if-<= break/disp8 -12544 40/increment-eax -12545 c1/shift 5/subop/arithmetic-right %ecx 1/imm8 -12546 eb/jump loop/disp8 -12547 } -12548 $num-shift-rights:end: -12549 # . restore registers -12550 59/pop-to-ecx -12551 # . epilogue -12552 89/<- %esp 5/r32/ebp -12553 5d/pop-to-ebp -12554 c3/return -12555 -12556 mu-get-offset: # stmt: (addr stmt) -> result/eax: int -12557 # . prologue -12558 55/push-ebp -12559 89/<- %ebp 4/r32/esp -12560 # var second-inout/eax: (addr stmt-var) = stmt->inouts->next -12561 8b/-> *(ebp+8) 0/r32/eax -12562 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax -12563 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -12564 # var output-var/eax: (addr var) = second-inout->value -12565 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -12566 #? (write-buffered Stderr "mu-get-offset: ") -12567 #? (print-int32-buffered Stderr %eax) -12568 #? (write-buffered Stderr " name: ") -12569 #? 50/push-eax -12570 #? (lookup *eax *(eax+4)) # Var-name -12571 #? (write-buffered Stderr %eax) -12572 #? 58/pop-to-eax -12573 #? (write-buffered Stderr Newline) -12574 #? (flush Stderr) -12575 # return output-var->stack-offset -12576 8b/-> *(eax+0x14) 0/r32/eax # Var-offset -12577 #? (write-buffered Stderr "=> ") -12578 #? (print-int32-buffered Stderr %eax) -12579 #? (write-buffered Stderr Newline) -12580 #? (flush Stderr) -12581 $emit-get-offset:end: -12582 # . epilogue -12583 89/<- %esp 5/r32/ebp -12584 5d/pop-to-ebp -12585 c3/return -12586 -12587 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) -12588 # . prologue -12589 55/push-ebp -12590 89/<- %ebp 4/r32/esp -12591 # . save registers -12592 50/push-eax -12593 51/push-ecx -12594 56/push-esi -12595 # esi = block -12596 8b/-> *(ebp+0xc) 6/r32/esi -12597 # block->var->block-depth = *Curr-block-depth -12598 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax -12599 8b/-> *Curr-block-depth 1/r32/ecx -12600 89/<- *(eax+0x10) 1/r32/ecx # Var-block-depth -12601 # var stmts/eax: (addr list stmt) = lookup(block->statements) -12602 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax -12603 # -12604 { -12605 $emit-subx-block:check-empty: -12606 3d/compare-eax-and 0/imm32 -12607 0f 84/jump-if-= break/disp32 -12608 (emit-indent *(ebp+8) *Curr-block-depth) -12609 (write-buffered *(ebp+8) "{\n") -12610 # var v/ecx: (addr var) = lookup(block->var) -12611 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax -12612 89/<- %ecx 0/r32/eax -12613 # -12614 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -12615 (write-buffered *(ebp+8) %eax) -12616 (write-buffered *(ebp+8) ":loop:\n") -12617 ff 0/subop/increment *Curr-block-depth -12618 (push *(ebp+0x10) *(esi+0xc)) # Block-var -12619 (push *(ebp+0x10) *(esi+0x10)) # Block-var -12620 (push *(ebp+0x10) 0) # false -12621 # emit block->statements -12622 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax -12623 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) -12624 (pop *(ebp+0x10)) # => eax -12625 (pop *(ebp+0x10)) # => eax -12626 (pop *(ebp+0x10)) # => eax -12627 ff 1/subop/decrement *Curr-block-depth -12628 (emit-indent *(ebp+8) *Curr-block-depth) -12629 (write-buffered *(ebp+8) "}\n") -12630 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax -12631 (write-buffered *(ebp+8) %eax) -12632 (write-buffered *(ebp+8) ":break:\n") -12633 } -12634 $emit-subx-block:end: -12635 # . restore registers -12636 5e/pop-to-esi -12637 59/pop-to-ecx -12638 58/pop-to-eax -12639 # . epilogue -12640 89/<- %esp 5/r32/ebp -12641 5d/pop-to-ebp -12642 c3/return -12643 -12644 # Primitives supported -12645 # See mu_instructions for a summary of this linked-list data structure. -12646 # -12647 # For each operation, put variants with hard-coded registers before flexible ones. -12648 # -12649 # Unfortunately, our restrictions on addresses require that various fields in -12650 # primitives be handles, which complicates these definitions. -12651 # - we need to insert dummy fields all over the place for fake alloc-ids -12652 # - we can't use our syntax sugar of quoted literals for string fields -12653 # -12654 # Fake alloc-ids are needed because our type definitions up top require -12655 # handles but it's clearer to statically allocate these long-lived objects. -12656 # Fake alloc-ids are perfectly safe, but they can't be reclaimed. -12657 # -12658 # Every 'object' below starts with a fake alloc-id. It may also contain other -12659 # fake alloc-ids for various handle fields. -12660 # -12661 # I think of objects starting with a fake alloc-id as having type 'payload'. -12662 # It's not really intended to be created dynamically; for that use `allocate` -12663 # as usual. -12664 # -12665 # Idea for a notation to simplify such definitions: -12666 # _Primitive-increment-eax: # (payload primitive) -12667 # 0x11/alloc-id:fake:payload -12668 # 0x11 @(0x11 "increment") # name -12669 # 0 0 # inouts -12670 # 0x11 @(0x11/payload -12671 # 0x11 @(0x11/payload # List-value -12672 # 0 0 # Var-name -12673 # 0x11 @(0x11 # Var-type -12674 # 1/is-atom -12675 # 1/value 0/unused # Tree-left -12676 # 0 0 # Tree-right -12677 # ) -12678 # 1 # block-depth -12679 # 0 # stack-offset -12680 # 0x11 @(0x11 "eax") # Var-register -12681 # ) -12682 # 0 0) # List-next -12683 # ... -12684 # _Primitive-increment-ecx/imm32/next -12685 # ... -12686 # Awfully complex and non-obvious. But also clearly signals there's something -12687 # to learn here, so may be worth trying. -12688 # -12689 # '@' is just an initial thought. Punctuation used so far in Mu: () * % # / " -12690 # -12691 # For now we'll continue to just use comments and manually ensure they stay up -12692 # to date. -12693 == data -12694 Primitives: # (addr primitive) -12695 # - increment/decrement -12696 _Primitive-increment-eax: # (addr primitive) -12697 # var/eax <- increment => 40/increment-eax -12698 0x11/imm32/alloc-id:fake -12699 _string-increment/imm32/name -12700 0/imm32/no-inouts -12701 0/imm32/no-inouts -12702 0x11/imm32/alloc-id:fake -12703 Single-int-var-in-eax/imm32/outputs -12704 0x11/imm32/alloc-id:fake -12705 _string_40_increment_eax/imm32/subx-name -12706 0/imm32/no-rm32 -12707 0/imm32/no-r32 -12708 0/imm32/no-imm32 -12709 0/imm32/no-disp32 -12710 0/imm32/output-is-write-only -12711 0x11/imm32/alloc-id:fake -12712 _Primitive-increment-ecx/imm32/next -12713 _Primitive-increment-ecx: # (payload primitive) -12714 0x11/imm32/alloc-id:fake:payload -12715 # var/ecx <- increment => 41/increment-ecx -12716 0x11/imm32/alloc-id:fake -12717 _string-increment/imm32/name -12718 0/imm32/no-inouts -12719 0/imm32/no-inouts -12720 0x11/imm32/alloc-id:fake -12721 Single-int-var-in-ecx/imm32/outputs -12722 0x11/imm32/alloc-id:fake -12723 _string_41_increment_ecx/imm32/subx-name -12724 0/imm32/no-rm32 -12725 0/imm32/no-r32 -12726 0/imm32/no-imm32 -12727 0/imm32/no-disp32 -12728 0/imm32/output-is-write-only -12729 0x11/imm32/alloc-id:fake -12730 _Primitive-increment-edx/imm32/next -12731 _Primitive-increment-edx: # (payload primitive) -12732 0x11/imm32/alloc-id:fake:payload -12733 # var/edx <- increment => 42/increment-edx -12734 0x11/imm32/alloc-id:fake -12735 _string-increment/imm32/name -12736 0/imm32/no-inouts -12737 0/imm32/no-inouts -12738 0x11/imm32/alloc-id:fake -12739 Single-int-var-in-edx/imm32/outputs -12740 0x11/imm32/alloc-id:fake -12741 _string_42_increment_edx/imm32/subx-name -12742 0/imm32/no-rm32 -12743 0/imm32/no-r32 -12744 0/imm32/no-imm32 -12745 0/imm32/no-disp32 -12746 0/imm32/output-is-write-only -12747 0x11/imm32/alloc-id:fake -12748 _Primitive-increment-ebx/imm32/next -12749 _Primitive-increment-ebx: # (payload primitive) -12750 0x11/imm32/alloc-id:fake:payload -12751 # var/ebx <- increment => 43/increment-ebx -12752 0x11/imm32/alloc-id:fake -12753 _string-increment/imm32/name -12754 0/imm32/no-inouts -12755 0/imm32/no-inouts -12756 0x11/imm32/alloc-id:fake -12757 Single-int-var-in-ebx/imm32/outputs -12758 0x11/imm32/alloc-id:fake -12759 _string_43_increment_ebx/imm32/subx-name -12760 0/imm32/no-rm32 -12761 0/imm32/no-r32 -12762 0/imm32/no-imm32 -12763 0/imm32/no-disp32 -12764 0/imm32/output-is-write-only -12765 0x11/imm32/alloc-id:fake -12766 _Primitive-increment-esi/imm32/next -12767 _Primitive-increment-esi: # (payload primitive) -12768 0x11/imm32/alloc-id:fake:payload -12769 # var/esi <- increment => 46/increment-esi -12770 0x11/imm32/alloc-id:fake -12771 _string-increment/imm32/name -12772 0/imm32/no-inouts -12773 0/imm32/no-inouts -12774 0x11/imm32/alloc-id:fake -12775 Single-int-var-in-esi/imm32/outputs -12776 0x11/imm32/alloc-id:fake -12777 _string_46_increment_esi/imm32/subx-name -12778 0/imm32/no-rm32 -12779 0/imm32/no-r32 -12780 0/imm32/no-imm32 -12781 0/imm32/no-disp32 -12782 0/imm32/output-is-write-only -12783 0x11/imm32/alloc-id:fake -12784 _Primitive-increment-edi/imm32/next -12785 _Primitive-increment-edi: # (payload primitive) -12786 0x11/imm32/alloc-id:fake:payload -12787 # var/edi <- increment => 47/increment-edi -12788 0x11/imm32/alloc-id:fake -12789 _string-increment/imm32/name -12790 0/imm32/no-inouts -12791 0/imm32/no-inouts -12792 0x11/imm32/alloc-id:fake -12793 Single-int-var-in-edi/imm32/outputs -12794 0x11/imm32/alloc-id:fake -12795 _string_47_increment_edi/imm32/subx-name -12796 0/imm32/no-rm32 -12797 0/imm32/no-r32 -12798 0/imm32/no-imm32 -12799 0/imm32/no-disp32 -12800 0/imm32/output-is-write-only -12801 0x11/imm32/alloc-id:fake -12802 _Primitive-decrement-eax/imm32/next -12803 _Primitive-decrement-eax: # (payload primitive) -12804 0x11/imm32/alloc-id:fake:payload -12805 # var/eax <- decrement => 48/decrement-eax -12806 0x11/imm32/alloc-id:fake -12807 _string-decrement/imm32/name -12808 0/imm32/no-inouts -12809 0/imm32/no-inouts -12810 0x11/imm32/alloc-id:fake -12811 Single-int-var-in-eax/imm32/outputs -12812 0x11/imm32/alloc-id:fake -12813 _string_48_decrement_eax/imm32/subx-name -12814 0/imm32/no-rm32 -12815 0/imm32/no-r32 -12816 0/imm32/no-imm32 -12817 0/imm32/no-disp32 -12818 0/imm32/output-is-write-only -12819 0x11/imm32/alloc-id:fake -12820 _Primitive-decrement-ecx/imm32/next -12821 _Primitive-decrement-ecx: # (payload primitive) -12822 0x11/imm32/alloc-id:fake:payload -12823 # var/ecx <- decrement => 49/decrement-ecx -12824 0x11/imm32/alloc-id:fake -12825 _string-decrement/imm32/name -12826 0/imm32/no-inouts -12827 0/imm32/no-inouts -12828 0x11/imm32/alloc-id:fake -12829 Single-int-var-in-ecx/imm32/outputs -12830 0x11/imm32/alloc-id:fake -12831 _string_49_decrement_ecx/imm32/subx-name -12832 0/imm32/no-rm32 -12833 0/imm32/no-r32 -12834 0/imm32/no-imm32 -12835 0/imm32/no-disp32 -12836 0/imm32/output-is-write-only -12837 0x11/imm32/alloc-id:fake -12838 _Primitive-decrement-edx/imm32/next -12839 _Primitive-decrement-edx: # (payload primitive) -12840 0x11/imm32/alloc-id:fake:payload -12841 # var/edx <- decrement => 4a/decrement-edx -12842 0x11/imm32/alloc-id:fake -12843 _string-decrement/imm32/name -12844 0/imm32/no-inouts -12845 0/imm32/no-inouts -12846 0x11/imm32/alloc-id:fake -12847 Single-int-var-in-edx/imm32/outputs -12848 0x11/imm32/alloc-id:fake -12849 _string_4a_decrement_edx/imm32/subx-name -12850 0/imm32/no-rm32 -12851 0/imm32/no-r32 -12852 0/imm32/no-imm32 -12853 0/imm32/no-disp32 -12854 0/imm32/output-is-write-only -12855 0x11/imm32/alloc-id:fake -12856 _Primitive-decrement-ebx/imm32/next -12857 _Primitive-decrement-ebx: # (payload primitive) -12858 0x11/imm32/alloc-id:fake:payload -12859 # var/ebx <- decrement => 4b/decrement-ebx -12860 0x11/imm32/alloc-id:fake -12861 _string-decrement/imm32/name -12862 0/imm32/no-inouts -12863 0/imm32/no-inouts -12864 0x11/imm32/alloc-id:fake -12865 Single-int-var-in-ebx/imm32/outputs -12866 0x11/imm32/alloc-id:fake -12867 _string_4b_decrement_ebx/imm32/subx-name -12868 0/imm32/no-rm32 -12869 0/imm32/no-r32 -12870 0/imm32/no-imm32 -12871 0/imm32/no-disp32 -12872 0/imm32/output-is-write-only -12873 0x11/imm32/alloc-id:fake -12874 _Primitive-decrement-esi/imm32/next -12875 _Primitive-decrement-esi: # (payload primitive) -12876 0x11/imm32/alloc-id:fake:payload -12877 # var/esi <- decrement => 4e/decrement-esi -12878 0x11/imm32/alloc-id:fake -12879 _string-decrement/imm32/name -12880 0/imm32/no-inouts -12881 0/imm32/no-inouts -12882 0x11/imm32/alloc-id:fake -12883 Single-int-var-in-esi/imm32/outputs -12884 0x11/imm32/alloc-id:fake -12885 _string_4e_decrement_esi/imm32/subx-name -12886 0/imm32/no-rm32 -12887 0/imm32/no-r32 -12888 0/imm32/no-imm32 -12889 0/imm32/no-disp32 -12890 0/imm32/output-is-write-only -12891 0x11/imm32/alloc-id:fake -12892 _Primitive-decrement-edi/imm32/next -12893 _Primitive-decrement-edi: # (payload primitive) -12894 0x11/imm32/alloc-id:fake:payload -12895 # var/edi <- decrement => 4f/decrement-edi -12896 0x11/imm32/alloc-id:fake -12897 _string-decrement/imm32/name -12898 0/imm32/no-inouts -12899 0/imm32/no-inouts -12900 0x11/imm32/alloc-id:fake -12901 Single-int-var-in-edi/imm32/outputs -12902 0x11/imm32/alloc-id:fake -12903 _string_4f_decrement_edi/imm32/subx-name -12904 0/imm32/no-rm32 -12905 0/imm32/no-r32 -12906 0/imm32/no-imm32 -12907 0/imm32/no-disp32 -12908 0/imm32/output-is-write-only -12909 0x11/imm32/alloc-id:fake -12910 _Primitive-increment-mem/imm32/next -12911 _Primitive-increment-mem: # (payload primitive) -12912 0x11/imm32/alloc-id:fake:payload -12913 # increment var => ff 0/subop/increment *(ebp+__) -12914 0x11/imm32/alloc-id:fake -12915 _string-increment/imm32/name -12916 0x11/imm32/alloc-id:fake -12917 Single-int-var-in-mem/imm32/inouts -12918 0/imm32/no-outputs -12919 0/imm32/no-outputs -12920 0x11/imm32/alloc-id:fake -12921 _string_ff_subop_increment/imm32/subx-name -12922 1/imm32/rm32-is-first-inout -12923 0/imm32/no-r32 -12924 0/imm32/no-imm32 -12925 0/imm32/no-disp32 -12926 0/imm32/output-is-write-only -12927 0x11/imm32/alloc-id:fake -12928 _Primitive-increment-reg/imm32/next -12929 _Primitive-increment-reg: # (payload primitive) -12930 0x11/imm32/alloc-id:fake:payload -12931 # var/reg <- increment => ff 0/subop/increment %__ -12932 0x11/imm32/alloc-id:fake -12933 _string-increment/imm32/name -12934 0/imm32/no-inouts -12935 0/imm32/no-inouts -12936 0x11/imm32/alloc-id:fake -12937 Single-int-var-in-some-register/imm32/outputs -12938 0x11/imm32/alloc-id:fake -12939 _string_ff_subop_increment/imm32/subx-name -12940 3/imm32/rm32-is-first-output -12941 0/imm32/no-r32 -12942 0/imm32/no-imm32 -12943 0/imm32/no-disp32 -12944 0/imm32/output-is-write-only -12945 0x11/imm32/alloc-id:fake -12946 _Primitive-decrement-mem/imm32/next -12947 _Primitive-decrement-mem: # (payload primitive) -12948 0x11/imm32/alloc-id:fake:payload -12949 # decrement var => ff 1/subop/decrement *(ebp+__) -12950 0x11/imm32/alloc-id:fake -12951 _string-decrement/imm32/name -12952 0x11/imm32/alloc-id:fake -12953 Single-int-var-in-mem/imm32/inouts -12954 0/imm32/no-outputs -12955 0/imm32/no-outputs -12956 0x11/imm32/alloc-id:fake -12957 _string_ff_subop_decrement/imm32/subx-name -12958 1/imm32/rm32-is-first-inout -12959 0/imm32/no-r32 -12960 0/imm32/no-imm32 -12961 0/imm32/no-disp32 -12962 0/imm32/output-is-write-only -12963 0x11/imm32/alloc-id:fake -12964 _Primitive-decrement-reg/imm32/next -12965 _Primitive-decrement-reg: # (payload primitive) -12966 0x11/imm32/alloc-id:fake:payload -12967 # var/reg <- decrement => ff 1/subop/decrement %__ -12968 0x11/imm32/alloc-id:fake -12969 _string-decrement/imm32/name -12970 0/imm32/no-inouts -12971 0/imm32/no-inouts -12972 0x11/imm32/alloc-id:fake -12973 Single-int-var-in-some-register/imm32/outputs -12974 0x11/imm32/alloc-id:fake -12975 _string_ff_subop_decrement/imm32/subx-name -12976 3/imm32/rm32-is-first-output -12977 0/imm32/no-r32 -12978 0/imm32/no-imm32 -12979 0/imm32/no-disp32 -12980 0/imm32/output-is-write-only -12981 0x11/imm32/alloc-id:fake -12982 _Primitive-add-to-eax/imm32/next -12983 # - add -12984 _Primitive-add-to-eax: # (payload primitive) -12985 0x11/imm32/alloc-id:fake:payload -12986 # var/eax <- add lit => 05/add-to-eax lit/imm32 -12987 0x11/imm32/alloc-id:fake -12988 _string-add/imm32/name -12989 0x11/imm32/alloc-id:fake -12990 Single-lit-var/imm32/inouts -12991 0x11/imm32/alloc-id:fake -12992 Single-int-var-in-eax/imm32/outputs -12993 0x11/imm32/alloc-id:fake -12994 _string_05_add_to_eax/imm32/subx-name -12995 0/imm32/no-rm32 -12996 0/imm32/no-r32 -12997 1/imm32/imm32-is-first-inout -12998 0/imm32/no-disp32 -12999 0/imm32/output-is-write-only -13000 0x11/imm32/alloc-id:fake -13001 _Primitive-add-reg-to-reg/imm32/next -13002 _Primitive-add-reg-to-reg: # (payload primitive) -13003 0x11/imm32/alloc-id:fake:payload -13004 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 -13005 0x11/imm32/alloc-id:fake -13006 _string-add/imm32/name -13007 0x11/imm32/alloc-id:fake -13008 Single-int-var-in-some-register/imm32/inouts -13009 0x11/imm32/alloc-id:fake -13010 Single-int-var-in-some-register/imm32/outputs -13011 0x11/imm32/alloc-id:fake -13012 _string_01_add_to/imm32/subx-name -13013 3/imm32/rm32-is-first-output -13014 1/imm32/r32-is-first-inout -13015 0/imm32/no-imm32 -13016 0/imm32/no-disp32 -13017 0/imm32/output-is-write-only -13018 0x11/imm32/alloc-id:fake -13019 _Primitive-add-reg-to-mem/imm32/next -13020 _Primitive-add-reg-to-mem: # (payload primitive) -13021 0x11/imm32/alloc-id:fake:payload -13022 # add-to var1 var2/reg => 01/add-to var1 var2/r32 -13023 0x11/imm32/alloc-id:fake -13024 _string-add-to/imm32/name -13025 0x11/imm32/alloc-id:fake -13026 Two-args-int-stack-int-reg/imm32/inouts -13027 0/imm32/no-outputs -13028 0/imm32/no-outputs -13029 0x11/imm32/alloc-id:fake -13030 _string_01_add_to/imm32/subx-name -13031 1/imm32/rm32-is-first-inout -13032 2/imm32/r32-is-second-inout -13033 0/imm32/no-imm32 -13034 0/imm32/no-disp32 -13035 0/imm32/output-is-write-only -13036 0x11/imm32/alloc-id:fake -13037 _Primitive-add-mem-to-reg/imm32/next -13038 _Primitive-add-mem-to-reg: # (payload primitive) -13039 0x11/imm32/alloc-id:fake:payload -13040 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 -13041 0x11/imm32/alloc-id:fake -13042 _string-add/imm32/name -13043 0x11/imm32/alloc-id:fake -13044 Single-int-var-in-mem/imm32/inouts -13045 0x11/imm32/alloc-id:fake -13046 Single-int-var-in-some-register/imm32/outputs -13047 0x11/imm32/alloc-id:fake -13048 _string_03_add/imm32/subx-name -13049 1/imm32/rm32-is-first-inout -13050 3/imm32/r32-is-first-output -13051 0/imm32/no-imm32 -13052 0/imm32/no-disp32 -13053 0/imm32/output-is-write-only -13054 0x11/imm32/alloc-id:fake -13055 _Primitive-add-lit-to-reg/imm32/next -13056 _Primitive-add-lit-to-reg: # (payload primitive) -13057 0x11/imm32/alloc-id:fake:payload -13058 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 -13059 0x11/imm32/alloc-id:fake -13060 _string-add/imm32/name -13061 0x11/imm32/alloc-id:fake -13062 Single-lit-var/imm32/inouts -13063 0x11/imm32/alloc-id:fake -13064 Single-int-var-in-some-register/imm32/outputs -13065 0x11/imm32/alloc-id:fake -13066 _string_81_subop_add/imm32/subx-name -13067 3/imm32/rm32-is-first-output -13068 0/imm32/no-r32 -13069 1/imm32/imm32-is-first-inout -13070 0/imm32/no-disp32 -13071 0/imm32/output-is-write-only -13072 0x11/imm32/alloc-id:fake -13073 _Primitive-add-lit-to-mem/imm32/next -13074 _Primitive-add-lit-to-mem: # (payload primitive) -13075 0x11/imm32/alloc-id:fake:payload -13076 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 -13077 0x11/imm32/alloc-id:fake -13078 _string-add-to/imm32/name -13079 0x11/imm32/alloc-id:fake -13080 Int-var-and-literal/imm32/inouts -13081 0/imm32/no-outputs -13082 0/imm32/no-outputs -13083 0x11/imm32/alloc-id:fake -13084 _string_81_subop_add/imm32/subx-name -13085 1/imm32/rm32-is-first-inout -13086 0/imm32/no-r32 -13087 2/imm32/imm32-is-second-inout -13088 0/imm32/no-disp32 -13089 0/imm32/output-is-write-only -13090 0x11/imm32/alloc-id:fake -13091 _Primitive-subtract-from-eax/imm32/next -13092 # - subtract -13093 _Primitive-subtract-from-eax: # (payload primitive) -13094 0x11/imm32/alloc-id:fake:payload -13095 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 -13096 0x11/imm32/alloc-id:fake -13097 _string-subtract/imm32/name -13098 0x11/imm32/alloc-id:fake -13099 Single-lit-var/imm32/inouts -13100 0x11/imm32/alloc-id:fake -13101 Single-int-var-in-eax/imm32/outputs -13102 0x11/imm32/alloc-id:fake -13103 _string_2d_subtract_from_eax/imm32/subx-name -13104 0/imm32/no-rm32 -13105 0/imm32/no-r32 -13106 1/imm32/imm32-is-first-inout -13107 0/imm32/no-disp32 -13108 0/imm32/output-is-write-only -13109 0x11/imm32/alloc-id:fake -13110 _Primitive-subtract-reg-from-reg/imm32/next -13111 _Primitive-subtract-reg-from-reg: # (payload primitive) -13112 0x11/imm32/alloc-id:fake:payload -13113 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 -13114 0x11/imm32/alloc-id:fake -13115 _string-subtract/imm32/name -13116 0x11/imm32/alloc-id:fake -13117 Single-int-var-in-some-register/imm32/inouts -13118 0x11/imm32/alloc-id:fake -13119 Single-int-var-in-some-register/imm32/outputs -13120 0x11/imm32/alloc-id:fake -13121 _string_29_subtract_from/imm32/subx-name -13122 3/imm32/rm32-is-first-output -13123 1/imm32/r32-is-first-inout -13124 0/imm32/no-imm32 -13125 0/imm32/no-disp32 -13126 0/imm32/output-is-write-only -13127 0x11/imm32/alloc-id:fake -13128 _Primitive-subtract-reg-from-mem/imm32/next -13129 _Primitive-subtract-reg-from-mem: # (payload primitive) -13130 0x11/imm32/alloc-id:fake:payload -13131 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 -13132 0x11/imm32/alloc-id:fake -13133 _string-subtract-from/imm32/name -13134 0x11/imm32/alloc-id:fake -13135 Two-args-int-stack-int-reg/imm32/inouts -13136 0/imm32/no-outputs -13137 0/imm32/no-outputs -13138 0x11/imm32/alloc-id:fake -13139 _string_29_subtract_from/imm32/subx-name -13140 1/imm32/rm32-is-first-inout -13141 2/imm32/r32-is-second-inout -13142 0/imm32/no-imm32 -13143 0/imm32/no-disp32 -13144 0/imm32/output-is-write-only -13145 0x11/imm32/alloc-id:fake -13146 _Primitive-subtract-mem-from-reg/imm32/next -13147 _Primitive-subtract-mem-from-reg: # (payload primitive) -13148 0x11/imm32/alloc-id:fake:payload -13149 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 -13150 0x11/imm32/alloc-id:fake -13151 _string-subtract/imm32/name -13152 0x11/imm32/alloc-id:fake -13153 Single-int-var-in-mem/imm32/inouts -13154 0x11/imm32/alloc-id:fake -13155 Single-int-var-in-some-register/imm32/outputs -13156 0x11/imm32/alloc-id:fake -13157 _string_2b_subtract/imm32/subx-name -13158 1/imm32/rm32-is-first-inout -13159 3/imm32/r32-is-first-output -13160 0/imm32/no-imm32 -13161 0/imm32/no-disp32 -13162 0/imm32/output-is-write-only -13163 0x11/imm32/alloc-id:fake -13164 _Primitive-subtract-lit-from-reg/imm32/next -13165 _Primitive-subtract-lit-from-reg: # (payload primitive) -13166 0x11/imm32/alloc-id:fake:payload -13167 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 -13168 0x11/imm32/alloc-id:fake -13169 _string-subtract/imm32/name -13170 0x11/imm32/alloc-id:fake -13171 Single-lit-var/imm32/inouts -13172 0x11/imm32/alloc-id:fake -13173 Single-int-var-in-some-register/imm32/outputs -13174 0x11/imm32/alloc-id:fake -13175 _string_81_subop_subtract/imm32/subx-name -13176 3/imm32/rm32-is-first-output -13177 0/imm32/no-r32 -13178 1/imm32/imm32-is-first-inout -13179 0/imm32/no-disp32 -13180 0/imm32/output-is-write-only -13181 0x11/imm32/alloc-id:fake -13182 _Primitive-subtract-lit-from-mem/imm32/next -13183 _Primitive-subtract-lit-from-mem: # (payload primitive) -13184 0x11/imm32/alloc-id:fake:payload -13185 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 -13186 0x11/imm32/alloc-id:fake -13187 _string-subtract-from/imm32/name -13188 0x11/imm32/alloc-id:fake -13189 Int-var-and-literal/imm32/inouts -13190 0/imm32/no-outputs -13191 0/imm32/no-outputs -13192 0x11/imm32/alloc-id:fake -13193 _string_81_subop_subtract/imm32/subx-name -13194 1/imm32/rm32-is-first-inout -13195 0/imm32/no-r32 -13196 2/imm32/imm32-is-first-inout -13197 0/imm32/no-disp32 -13198 0/imm32/output-is-write-only -13199 0x11/imm32/alloc-id:fake -13200 _Primitive-and-with-eax/imm32/next -13201 # - and -13202 _Primitive-and-with-eax: # (payload primitive) -13203 0x11/imm32/alloc-id:fake:payload -13204 # var/eax <- and lit => 25/and-with-eax lit/imm32 -13205 0x11/imm32/alloc-id:fake -13206 _string-and/imm32/name -13207 0x11/imm32/alloc-id:fake -13208 Single-lit-var/imm32/inouts -13209 0x11/imm32/alloc-id:fake -13210 Single-int-var-in-eax/imm32/outputs -13211 0x11/imm32/alloc-id:fake -13212 _string_25_and_with_eax/imm32/subx-name -13213 0/imm32/no-rm32 -13214 0/imm32/no-r32 -13215 1/imm32/imm32-is-first-inout -13216 0/imm32/no-disp32 -13217 0/imm32/output-is-write-only -13218 0x11/imm32/alloc-id:fake -13219 _Primitive-and-reg-with-reg/imm32/next -13220 _Primitive-and-reg-with-reg: # (payload primitive) -13221 0x11/imm32/alloc-id:fake:payload -13222 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 -13223 0x11/imm32/alloc-id:fake -13224 _string-and/imm32/name -13225 0x11/imm32/alloc-id:fake -13226 Single-int-var-in-some-register/imm32/inouts -13227 0x11/imm32/alloc-id:fake -13228 Single-int-var-in-some-register/imm32/outputs -13229 0x11/imm32/alloc-id:fake -13230 _string_21_and_with/imm32/subx-name -13231 3/imm32/rm32-is-first-output -13232 1/imm32/r32-is-first-inout -13233 0/imm32/no-imm32 -13234 0/imm32/no-disp32 -13235 0/imm32/output-is-write-only -13236 0x11/imm32/alloc-id:fake -13237 _Primitive-and-reg-with-mem/imm32/next -13238 _Primitive-and-reg-with-mem: # (payload primitive) -13239 0x11/imm32/alloc-id:fake:payload -13240 # and-with var1 var2/reg => 21/and-with var1 var2/r32 -13241 0x11/imm32/alloc-id:fake -13242 _string-and-with/imm32/name -13243 0x11/imm32/alloc-id:fake -13244 Two-args-int-stack-int-reg/imm32/inouts -13245 0/imm32/no-outputs -13246 0/imm32/no-outputs -13247 0x11/imm32/alloc-id:fake -13248 _string_21_and_with/imm32/subx-name -13249 1/imm32/rm32-is-first-inout -13250 2/imm32/r32-is-second-inout -13251 0/imm32/no-imm32 -13252 0/imm32/no-disp32 -13253 0/imm32/output-is-write-only -13254 0x11/imm32/alloc-id:fake -13255 _Primitive-and-mem-with-reg/imm32/next -13256 _Primitive-and-mem-with-reg: # (payload primitive) -13257 0x11/imm32/alloc-id:fake:payload -13258 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 -13259 0x11/imm32/alloc-id:fake -13260 _string-and/imm32/name -13261 0x11/imm32/alloc-id:fake -13262 Single-int-var-in-mem/imm32/inouts -13263 0x11/imm32/alloc-id:fake -13264 Single-int-var-in-some-register/imm32/outputs -13265 0x11/imm32/alloc-id:fake -13266 _string_23_and/imm32/subx-name -13267 1/imm32/rm32-is-first-inout -13268 3/imm32/r32-is-first-output -13269 0/imm32/no-imm32 -13270 0/imm32/no-disp32 -13271 0/imm32/output-is-write-only -13272 0x11/imm32/alloc-id:fake -13273 _Primitive-and-lit-with-reg/imm32/next -13274 _Primitive-and-lit-with-reg: # (payload primitive) -13275 0x11/imm32/alloc-id:fake:payload -13276 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 -13277 0x11/imm32/alloc-id:fake -13278 _string-and/imm32/name -13279 0x11/imm32/alloc-id:fake -13280 Single-lit-var/imm32/inouts -13281 0x11/imm32/alloc-id:fake -13282 Single-int-var-in-some-register/imm32/outputs -13283 0x11/imm32/alloc-id:fake -13284 _string_81_subop_and/imm32/subx-name -13285 3/imm32/rm32-is-first-output -13286 0/imm32/no-r32 -13287 1/imm32/imm32-is-first-inout -13288 0/imm32/no-disp32 -13289 0/imm32/output-is-write-only -13290 0x11/imm32/alloc-id:fake -13291 _Primitive-and-lit-with-mem/imm32/next -13292 _Primitive-and-lit-with-mem: # (payload primitive) -13293 0x11/imm32/alloc-id:fake:payload -13294 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 -13295 0x11/imm32/alloc-id:fake -13296 _string-and-with/imm32/name -13297 0x11/imm32/alloc-id:fake -13298 Int-var-and-literal/imm32/inouts -13299 0/imm32/no-outputs -13300 0/imm32/no-outputs -13301 0x11/imm32/alloc-id:fake -13302 _string_81_subop_and/imm32/subx-name -13303 1/imm32/rm32-is-first-inout -13304 0/imm32/no-r32 -13305 2/imm32/imm32-is-first-inout -13306 0/imm32/no-disp32 -13307 0/imm32/output-is-write-only -13308 0x11/imm32/alloc-id:fake -13309 _Primitive-or-with-eax/imm32/next -13310 # - or -13311 _Primitive-or-with-eax: # (payload primitive) -13312 0x11/imm32/alloc-id:fake:payload -13313 # var/eax <- or lit => 0d/or-with-eax lit/imm32 -13314 0x11/imm32/alloc-id:fake -13315 _string-or/imm32/name -13316 0x11/imm32/alloc-id:fake -13317 Single-lit-var/imm32/inouts -13318 0x11/imm32/alloc-id:fake -13319 Single-int-var-in-eax/imm32/outputs -13320 0x11/imm32/alloc-id:fake -13321 _string_0d_or_with_eax/imm32/subx-name -13322 0/imm32/no-rm32 -13323 0/imm32/no-r32 -13324 1/imm32/imm32-is-first-inout -13325 0/imm32/no-disp32 -13326 0/imm32/output-is-write-only -13327 0x11/imm32/alloc-id:fake -13328 _Primitive-or-reg-with-reg/imm32/next -13329 _Primitive-or-reg-with-reg: # (payload primitive) -13330 0x11/imm32/alloc-id:fake:payload -13331 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 -13332 0x11/imm32/alloc-id:fake -13333 _string-or/imm32/name -13334 0x11/imm32/alloc-id:fake -13335 Single-int-var-in-some-register/imm32/inouts -13336 0x11/imm32/alloc-id:fake -13337 Single-int-var-in-some-register/imm32/outputs -13338 0x11/imm32/alloc-id:fake -13339 _string_09_or_with/imm32/subx-name -13340 3/imm32/rm32-is-first-output -13341 1/imm32/r32-is-first-inout -13342 0/imm32/no-imm32 -13343 0/imm32/no-disp32 -13344 0/imm32/output-is-write-only -13345 0x11/imm32/alloc-id:fake -13346 _Primitive-or-reg-with-mem/imm32/next -13347 _Primitive-or-reg-with-mem: # (payload primitive) -13348 0x11/imm32/alloc-id:fake:payload -13349 # or-with var1 var2/reg => 09/or-with var1 var2/r32 -13350 0x11/imm32/alloc-id:fake -13351 _string-or-with/imm32/name -13352 0x11/imm32/alloc-id:fake -13353 Two-args-int-stack-int-reg/imm32/inouts -13354 0/imm32/no-outputs -13355 0/imm32/no-outputs -13356 0x11/imm32/alloc-id:fake -13357 _string_09_or_with/imm32/subx-name -13358 1/imm32/rm32-is-first-inout -13359 2/imm32/r32-is-second-inout -13360 0/imm32/no-imm32 -13361 0/imm32/no-disp32 -13362 0/imm32/output-is-write-only -13363 0x11/imm32/alloc-id:fake -13364 _Primitive-or-mem-with-reg/imm32/next -13365 _Primitive-or-mem-with-reg: # (payload primitive) -13366 0x11/imm32/alloc-id:fake:payload -13367 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 -13368 0x11/imm32/alloc-id:fake -13369 _string-or/imm32/name -13370 0x11/imm32/alloc-id:fake -13371 Single-int-var-in-mem/imm32/inouts -13372 0x11/imm32/alloc-id:fake -13373 Single-int-var-in-some-register/imm32/outputs -13374 0x11/imm32/alloc-id:fake -13375 _string_0b_or/imm32/subx-name -13376 1/imm32/rm32-is-first-inout -13377 3/imm32/r32-is-first-output -13378 0/imm32/no-imm32 -13379 0/imm32/no-disp32 -13380 0/imm32/output-is-write-only -13381 0x11/imm32/alloc-id:fake -13382 _Primitive-or-lit-with-reg/imm32/next -13383 _Primitive-or-lit-with-reg: # (payload primitive) -13384 0x11/imm32/alloc-id:fake:payload -13385 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 -13386 0x11/imm32/alloc-id:fake -13387 _string-or/imm32/name -13388 0x11/imm32/alloc-id:fake -13389 Single-lit-var/imm32/inouts -13390 0x11/imm32/alloc-id:fake -13391 Single-int-var-in-some-register/imm32/outputs -13392 0x11/imm32/alloc-id:fake -13393 _string_81_subop_or/imm32/subx-name -13394 3/imm32/rm32-is-first-output -13395 0/imm32/no-r32 -13396 1/imm32/imm32-is-first-inout -13397 0/imm32/no-disp32 -13398 0/imm32/output-is-write-only -13399 0x11/imm32/alloc-id:fake -13400 _Primitive-or-lit-with-mem/imm32/next -13401 _Primitive-or-lit-with-mem: # (payload primitive) -13402 0x11/imm32/alloc-id:fake:payload -13403 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 -13404 0x11/imm32/alloc-id:fake -13405 _string-or-with/imm32/name -13406 0x11/imm32/alloc-id:fake -13407 Int-var-and-literal/imm32/inouts -13408 0/imm32/no-outputs -13409 0/imm32/no-outputs -13410 0x11/imm32/alloc-id:fake -13411 _string_81_subop_or/imm32/subx-name -13412 1/imm32/rm32-is-first-inout -13413 0/imm32/no-r32 -13414 2/imm32/imm32-is-second-inout -13415 0/imm32/no-disp32 -13416 0/imm32/output-is-write-only -13417 0x11/imm32/alloc-id:fake -13418 _Primitive-xor-with-eax/imm32/next -13419 # - xor -13420 _Primitive-xor-with-eax: # (payload primitive) -13421 0x11/imm32/alloc-id:fake:payload -13422 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 -13423 0x11/imm32/alloc-id:fake -13424 _string-xor/imm32/name -13425 0x11/imm32/alloc-id:fake -13426 Single-lit-var/imm32/inouts -13427 0x11/imm32/alloc-id:fake -13428 Single-int-var-in-eax/imm32/outputs -13429 0x11/imm32/alloc-id:fake -13430 _string_35_xor_with_eax/imm32/subx-name -13431 0/imm32/no-rm32 -13432 0/imm32/no-r32 -13433 1/imm32/imm32-is-first-inout -13434 0/imm32/no-disp32 -13435 0/imm32/output-is-write-only -13436 0x11/imm32/alloc-id:fake -13437 _Primitive-xor-reg-with-reg/imm32/next -13438 _Primitive-xor-reg-with-reg: # (payload primitive) -13439 0x11/imm32/alloc-id:fake:payload -13440 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 -13441 0x11/imm32/alloc-id:fake -13442 _string-xor/imm32/name -13443 0x11/imm32/alloc-id:fake -13444 Single-int-var-in-some-register/imm32/inouts -13445 0x11/imm32/alloc-id:fake -13446 Single-int-var-in-some-register/imm32/outputs -13447 0x11/imm32/alloc-id:fake -13448 _string_31_xor_with/imm32/subx-name -13449 3/imm32/rm32-is-first-output -13450 1/imm32/r32-is-first-inout -13451 0/imm32/no-imm32 -13452 0/imm32/no-disp32 -13453 0/imm32/output-is-write-only -13454 0x11/imm32/alloc-id:fake -13455 _Primitive-xor-reg-with-mem/imm32/next -13456 _Primitive-xor-reg-with-mem: # (payload primitive) -13457 0x11/imm32/alloc-id:fake:payload -13458 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 -13459 0x11/imm32/alloc-id:fake -13460 _string-xor-with/imm32/name -13461 0x11/imm32/alloc-id:fake -13462 Two-args-int-stack-int-reg/imm32/inouts -13463 0/imm32/no-outputs -13464 0/imm32/no-outputs -13465 0x11/imm32/alloc-id:fake -13466 _string_31_xor_with/imm32/subx-name -13467 1/imm32/rm32-is-first-inout -13468 2/imm32/r32-is-second-inout -13469 0/imm32/no-imm32 -13470 0/imm32/no-disp32 -13471 0/imm32/output-is-write-only -13472 0x11/imm32/alloc-id:fake -13473 _Primitive-xor-mem-with-reg/imm32/next -13474 _Primitive-xor-mem-with-reg: # (payload primitive) -13475 0x11/imm32/alloc-id:fake:payload -13476 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 -13477 0x11/imm32/alloc-id:fake -13478 _string-xor/imm32/name -13479 0x11/imm32/alloc-id:fake -13480 Single-int-var-in-mem/imm32/inouts -13481 0x11/imm32/alloc-id:fake -13482 Single-int-var-in-some-register/imm32/outputs -13483 0x11/imm32/alloc-id:fake -13484 _string_33_xor/imm32/subx-name -13485 1/imm32/rm32-is-first-inout -13486 3/imm32/r32-is-first-output -13487 0/imm32/no-imm32 -13488 0/imm32/no-disp32 -13489 0/imm32/output-is-write-only -13490 0x11/imm32/alloc-id:fake -13491 _Primitive-xor-lit-with-reg/imm32/next -13492 _Primitive-xor-lit-with-reg: # (payload primitive) -13493 0x11/imm32/alloc-id:fake:payload -13494 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 -13495 0x11/imm32/alloc-id:fake -13496 _string-xor/imm32/name -13497 0x11/imm32/alloc-id:fake -13498 Single-lit-var/imm32/inouts -13499 0x11/imm32/alloc-id:fake -13500 Single-int-var-in-some-register/imm32/outputs -13501 0x11/imm32/alloc-id:fake -13502 _string_81_subop_xor/imm32/subx-name -13503 3/imm32/rm32-is-first-output -13504 0/imm32/no-r32 -13505 1/imm32/imm32-is-first-inout -13506 0/imm32/no-disp32 -13507 0/imm32/output-is-write-only -13508 0x11/imm32/alloc-id:fake -13509 _Primitive-xor-lit-with-mem/imm32/next -13510 _Primitive-xor-lit-with-mem: # (payload primitive) -13511 0x11/imm32/alloc-id:fake:payload -13512 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 -13513 0x11/imm32/alloc-id:fake -13514 _string-xor-with/imm32/name -13515 0x11/imm32/alloc-id:fake -13516 Int-var-and-literal/imm32/inouts -13517 0/imm32/no-outputs -13518 0/imm32/no-outputs -13519 0x11/imm32/alloc-id:fake -13520 _string_81_subop_xor/imm32/subx-name -13521 1/imm32/rm32-is-first-inout -13522 0/imm32/no-r32 -13523 2/imm32/imm32-is-first-inout -13524 0/imm32/no-disp32 -13525 0/imm32/output-is-write-only -13526 0x11/imm32/alloc-id:fake -13527 _Primitive-copy-to-eax/imm32/next -13528 # - copy -13529 _Primitive-copy-to-eax: # (payload primitive) -13530 0x11/imm32/alloc-id:fake:payload -13531 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 -13532 0x11/imm32/alloc-id:fake -13533 _string-copy/imm32/name -13534 0x11/imm32/alloc-id:fake -13535 Single-lit-var/imm32/inouts -13536 0x11/imm32/alloc-id:fake -13537 Single-int-var-in-eax/imm32/outputs -13538 0x11/imm32/alloc-id:fake -13539 _string_b8_copy_to_eax/imm32/subx-name -13540 0/imm32/no-rm32 -13541 0/imm32/no-r32 -13542 1/imm32/imm32-is-first-inout -13543 0/imm32/no-disp32 -13544 1/imm32/output-is-write-only -13545 0x11/imm32/alloc-id:fake -13546 _Primitive-copy-to-ecx/imm32/next -13547 _Primitive-copy-to-ecx: # (payload primitive) -13548 0x11/imm32/alloc-id:fake:payload -13549 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 -13550 0x11/imm32/alloc-id:fake -13551 _string-copy/imm32/name -13552 0x11/imm32/alloc-id:fake -13553 Single-lit-var/imm32/inouts -13554 0x11/imm32/alloc-id:fake -13555 Single-int-var-in-ecx/imm32/outputs -13556 0x11/imm32/alloc-id:fake -13557 _string_b9_copy_to_ecx/imm32/subx-name -13558 0/imm32/no-rm32 -13559 0/imm32/no-r32 -13560 1/imm32/imm32-is-first-inout -13561 0/imm32/no-disp32 -13562 1/imm32/output-is-write-only -13563 0x11/imm32/alloc-id:fake -13564 _Primitive-copy-to-edx/imm32/next -13565 _Primitive-copy-to-edx: # (payload primitive) -13566 0x11/imm32/alloc-id:fake:payload -13567 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 -13568 0x11/imm32/alloc-id:fake -13569 _string-copy/imm32/name -13570 0x11/imm32/alloc-id:fake -13571 Single-lit-var/imm32/inouts -13572 0x11/imm32/alloc-id:fake -13573 Single-int-var-in-edx/imm32/outputs -13574 0x11/imm32/alloc-id:fake -13575 _string_ba_copy_to_edx/imm32/subx-name -13576 0/imm32/no-rm32 -13577 0/imm32/no-r32 -13578 1/imm32/imm32-is-first-inout -13579 0/imm32/no-disp32 -13580 1/imm32/output-is-write-only -13581 0x11/imm32/alloc-id:fake -13582 _Primitive-copy-to-ebx/imm32/next -13583 _Primitive-copy-to-ebx: # (payload primitive) -13584 0x11/imm32/alloc-id:fake:payload -13585 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 -13586 0x11/imm32/alloc-id:fake -13587 _string-copy/imm32/name -13588 0x11/imm32/alloc-id:fake -13589 Single-lit-var/imm32/inouts -13590 0x11/imm32/alloc-id:fake -13591 Single-int-var-in-ebx/imm32/outputs -13592 0x11/imm32/alloc-id:fake -13593 _string_bb_copy_to_ebx/imm32/subx-name -13594 0/imm32/no-rm32 -13595 0/imm32/no-r32 -13596 1/imm32/imm32-is-first-inout -13597 0/imm32/no-disp32 -13598 1/imm32/output-is-write-only -13599 0x11/imm32/alloc-id:fake -13600 _Primitive-copy-to-esi/imm32/next -13601 _Primitive-copy-to-esi: # (payload primitive) -13602 0x11/imm32/alloc-id:fake:payload -13603 # var/esi <- copy lit => be/copy-to-esi lit/imm32 -13604 0x11/imm32/alloc-id:fake -13605 _string-copy/imm32/name -13606 0x11/imm32/alloc-id:fake -13607 Single-lit-var/imm32/inouts -13608 0x11/imm32/alloc-id:fake -13609 Single-int-var-in-esi/imm32/outputs -13610 0x11/imm32/alloc-id:fake -13611 _string_be_copy_to_esi/imm32/subx-name -13612 0/imm32/no-rm32 -13613 0/imm32/no-r32 -13614 1/imm32/imm32-is-first-inout -13615 0/imm32/no-disp32 -13616 1/imm32/output-is-write-only -13617 0x11/imm32/alloc-id:fake -13618 _Primitive-copy-to-edi/imm32/next -13619 _Primitive-copy-to-edi: # (payload primitive) -13620 0x11/imm32/alloc-id:fake:payload -13621 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 -13622 0x11/imm32/alloc-id:fake -13623 _string-copy/imm32/name -13624 0x11/imm32/alloc-id:fake -13625 Single-lit-var/imm32/inouts -13626 0x11/imm32/alloc-id:fake -13627 Single-int-var-in-edi/imm32/outputs -13628 0x11/imm32/alloc-id:fake -13629 _string_bf_copy_to_edi/imm32/subx-name -13630 0/imm32/no-rm32 -13631 0/imm32/no-r32 -13632 1/imm32/imm32-is-first-inout -13633 0/imm32/no-disp32 -13634 1/imm32/output-is-write-only -13635 0x11/imm32/alloc-id:fake -13636 _Primitive-copy-reg-to-reg/imm32/next -13637 _Primitive-copy-reg-to-reg: # (payload primitive) -13638 0x11/imm32/alloc-id:fake:payload -13639 # var1/reg <- copy var2/reg => 89/<- var1/rm32 var2/r32 -13640 0x11/imm32/alloc-id:fake -13641 _string-copy/imm32/name -13642 0x11/imm32/alloc-id:fake -13643 Single-int-var-in-some-register/imm32/inouts -13644 0x11/imm32/alloc-id:fake -13645 Single-int-var-in-some-register/imm32/outputs -13646 0x11/imm32/alloc-id:fake -13647 _string_89_<-/imm32/subx-name -13648 3/imm32/rm32-is-first-output -13649 1/imm32/r32-is-first-inout -13650 0/imm32/no-imm32 -13651 0/imm32/no-disp32 -13652 1/imm32/output-is-write-only -13653 0x11/imm32/alloc-id:fake -13654 _Primitive-copy-reg-to-mem/imm32/next -13655 _Primitive-copy-reg-to-mem: # (payload primitive) -13656 0x11/imm32/alloc-id:fake:payload -13657 # copy-to var1 var2/reg => 89/<- var1 var2/r32 -13658 0x11/imm32/alloc-id:fake -13659 _string-copy-to/imm32/name -13660 0x11/imm32/alloc-id:fake -13661 Two-args-int-stack-int-reg/imm32/inouts -13662 0/imm32/no-outputs -13663 0/imm32/no-outputs -13664 0x11/imm32/alloc-id:fake -13665 _string_89_<-/imm32/subx-name -13666 1/imm32/rm32-is-first-inout -13667 2/imm32/r32-is-second-inout -13668 0/imm32/no-imm32 -13669 0/imm32/no-disp32 -13670 1/imm32/output-is-write-only -13671 0x11/imm32/alloc-id:fake -13672 _Primitive-copy-mem-to-reg/imm32/next -13673 _Primitive-copy-mem-to-reg: # (payload primitive) -13674 0x11/imm32/alloc-id:fake:payload -13675 # var1/reg <- copy var2 => 8b/-> var2/rm32 var1/r32 -13676 0x11/imm32/alloc-id:fake -13677 _string-copy/imm32/name -13678 0x11/imm32/alloc-id:fake -13679 Single-int-var-in-mem/imm32/inouts -13680 0x11/imm32/alloc-id:fake -13681 Single-int-var-in-some-register/imm32/outputs -13682 0x11/imm32/alloc-id:fake -13683 _string_8b_->/imm32/subx-name -13684 1/imm32/rm32-is-first-inout -13685 3/imm32/r32-is-first-output -13686 0/imm32/no-imm32 -13687 0/imm32/no-disp32 -13688 1/imm32/output-is-write-only -13689 0x11/imm32/alloc-id:fake -13690 _Primitive-copy-lit-to-reg/imm32/next -13691 _Primitive-copy-lit-to-reg: # (payload primitive) -13692 0x11/imm32/alloc-id:fake:payload -13693 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 -13694 0x11/imm32/alloc-id:fake -13695 _string-copy/imm32/name -13696 0x11/imm32/alloc-id:fake -13697 Single-lit-var/imm32/inouts -13698 0x11/imm32/alloc-id:fake -13699 Single-int-var-in-some-register/imm32/outputs -13700 0x11/imm32/alloc-id:fake -13701 _string_c7_subop_copy/imm32/subx-name -13702 3/imm32/rm32-is-first-output -13703 0/imm32/no-r32 -13704 1/imm32/imm32-is-first-inout -13705 0/imm32/no-disp32 -13706 1/imm32/output-is-write-only -13707 0x11/imm32/alloc-id:fake -13708 _Primitive-copy-lit-to-mem/imm32/next -13709 _Primitive-copy-lit-to-mem: # (payload primitive) -13710 0x11/imm32/alloc-id:fake:payload -13711 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 -13712 0x11/imm32/alloc-id:fake -13713 _string-copy-to/imm32/name -13714 0x11/imm32/alloc-id:fake -13715 Int-var-and-literal/imm32/inouts -13716 0/imm32/no-outputs -13717 0/imm32/no-outputs -13718 0x11/imm32/alloc-id:fake -13719 _string_c7_subop_copy/imm32/subx-name -13720 1/imm32/rm32-is-first-inout -13721 0/imm32/no-r32 -13722 2/imm32/imm32-is-first-inout -13723 0/imm32/no-disp32 -13724 1/imm32/output-is-write-only -13725 0x11/imm32/alloc-id:fake -13726 _Primitive-copy-byte-from-reg/imm32/next -13727 # - copy byte -13728 _Primitive-copy-byte-from-reg: -13729 0x11/imm32/alloc-id:fake:payload -13730 # var/reg <- copy-byte var2/reg2 => 8a/byte-> %var2 var/r32 -13731 0x11/imm32/alloc-id:fake -13732 _string-copy-byte/imm32/name -13733 0x11/imm32/alloc-id:fake -13734 Single-byte-var-in-some-register/imm32/inouts -13735 0x11/imm32/alloc-id:fake -13736 Single-byte-var-in-some-register/imm32/outputs -13737 0x11/imm32/alloc-id:fake -13738 _string_8a_copy_byte/imm32/subx-name -13739 1/imm32/rm32-is-first-inout -13740 3/imm32/r32-is-first-output -13741 0/imm32/no-imm32 -13742 0/imm32/no-disp32 -13743 1/imm32/output-is-write-only -13744 0x11/imm32/alloc-id:fake -13745 _Primitive-copy-byte-from-mem/imm32/next -13746 _Primitive-copy-byte-from-mem: -13747 0x11/imm32/alloc-id:fake:payload -13748 # var/reg <- copy-byte *var2/reg2 => 8a/byte-> *var2 var/r32 -13749 0x11/imm32/alloc-id:fake -13750 _string-copy-byte/imm32/name -13751 0x11/imm32/alloc-id:fake -13752 Single-byte-var-in-mem/imm32/inouts -13753 0x11/imm32/alloc-id:fake -13754 Single-byte-var-in-some-register/imm32/outputs -13755 0x11/imm32/alloc-id:fake -13756 _string_8a_copy_byte/imm32/subx-name -13757 1/imm32/rm32-is-first-inout -13758 3/imm32/r32-is-first-output -13759 0/imm32/no-imm32 -13760 0/imm32/no-disp32 -13761 1/imm32/output-is-write-only -13762 0x11/imm32/alloc-id:fake -13763 _Primitive-copy-byte-to-mem/imm32/next -13764 _Primitive-copy-byte-to-mem: -13765 0x11/imm32/alloc-id:fake:payload -13766 # copy-byte-to *var1/reg1, var2/reg2 => 88/byte<- *reg1 reg2/r32 -13767 0x11/imm32/alloc-id:fake -13768 _string-copy-byte-to/imm32/name -13769 0x11/imm32/alloc-id:fake -13770 Two-args-byte-stack-byte-reg/imm32/inouts -13771 0/imm32/no-outputs -13772 0/imm32/no-outputs -13773 0x11/imm32/alloc-id:fake -13774 _string_88_copy_byte/imm32/subx-name -13775 1/imm32/rm32-is-first-inout -13776 2/imm32/r32-is-second-inout -13777 0/imm32/no-imm32 -13778 0/imm32/no-disp32 -13779 0/imm32/output-is-write-only -13780 0x11/imm32/alloc-id:fake -13781 _Primitive-address/imm32/next -13782 # - address -13783 _Primitive-address: # (payload primitive) -13784 0x11/imm32/alloc-id:fake:payload -13785 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32 -13786 0x11/imm32/alloc-id:fake -13787 _string-address/imm32/name -13788 0x11/imm32/alloc-id:fake -13789 Single-int-var-in-mem/imm32/inouts -13790 0x11/imm32/alloc-id:fake -13791 Single-addr-var-in-some-register/imm32/outputs -13792 0x11/imm32/alloc-id:fake -13793 _string_8d_copy_address/imm32/subx-name -13794 1/imm32/rm32-is-first-inout -13795 3/imm32/r32-is-first-output -13796 0/imm32/no-imm32 -13797 0/imm32/no-disp32 -13798 1/imm32/output-is-write-only -13799 0x11/imm32/alloc-id:fake -13800 _Primitive-compare-reg-with-reg/imm32/next -13801 # - compare -13802 _Primitive-compare-reg-with-reg: # (payload primitive) -13803 0x11/imm32/alloc-id:fake:payload -13804 # compare var1/reg1 var2/reg2 => 39/compare var1/rm32 var2/r32 -13805 0x11/imm32/alloc-id:fake -13806 _string-compare/imm32/name -13807 0x11/imm32/alloc-id:fake -13808 Two-int-args-in-regs/imm32/inouts -13809 0/imm32/no-outputs -13810 0/imm32/no-outputs -13811 0x11/imm32/alloc-id:fake -13812 _string_39_compare->/imm32/subx-name -13813 1/imm32/rm32-is-first-inout -13814 2/imm32/r32-is-second-inout -13815 0/imm32/no-imm32 -13816 0/imm32/no-disp32 -13817 0/imm32/output-is-write-only -13818 0x11/imm32/alloc-id:fake -13819 _Primitive-compare-mem-with-reg/imm32/next -13820 _Primitive-compare-mem-with-reg: # (payload primitive) -13821 0x11/imm32/alloc-id:fake:payload -13822 # compare var1 var2/reg => 39/compare var1/rm32 var2/r32 -13823 0x11/imm32/alloc-id:fake -13824 _string-compare/imm32/name -13825 0x11/imm32/alloc-id:fake -13826 Two-args-int-stack-int-reg/imm32/inouts -13827 0/imm32/no-outputs -13828 0/imm32/no-outputs -13829 0x11/imm32/alloc-id:fake -13830 _string_39_compare->/imm32/subx-name -13831 1/imm32/rm32-is-first-inout -13832 2/imm32/r32-is-second-inout -13833 0/imm32/no-imm32 -13834 0/imm32/no-disp32 -13835 0/imm32/output-is-write-only -13836 0x11/imm32/alloc-id:fake -13837 _Primitive-compare-reg-with-mem/imm32/next -13838 _Primitive-compare-reg-with-mem: # (payload primitive) -13839 0x11/imm32/alloc-id:fake:payload -13840 # compare var1/reg var2 => 3b/compare<- var2/rm32 var1/r32 -13841 0x11/imm32/alloc-id:fake -13842 _string-compare/imm32/name -13843 0x11/imm32/alloc-id:fake -13844 Two-args-int-reg-int-stack/imm32/inouts -13845 0/imm32/no-outputs -13846 0/imm32/no-outputs -13847 0x11/imm32/alloc-id:fake -13848 _string_3b_compare<-/imm32/subx-name -13849 2/imm32/rm32-is-second-inout -13850 1/imm32/r32-is-first-inout -13851 0/imm32/no-imm32 -13852 0/imm32/no-disp32 -13853 0/imm32/output-is-write-only -13854 0x11/imm32/alloc-id:fake -13855 _Primitive-compare-eax-with-literal/imm32/next -13856 _Primitive-compare-eax-with-literal: # (payload primitive) -13857 0x11/imm32/alloc-id:fake:payload -13858 # compare var1/eax n => 3d/compare-eax-with n/imm32 -13859 0x11/imm32/alloc-id:fake -13860 _string-compare/imm32/name -13861 0x11/imm32/alloc-id:fake -13862 Two-args-int-eax-int-literal/imm32/inouts -13863 0/imm32/no-outputs -13864 0/imm32/no-outputs -13865 0x11/imm32/alloc-id:fake -13866 _string_3d_compare_eax_with/imm32/subx-name -13867 0/imm32/no-rm32 -13868 0/imm32/no-r32 -13869 2/imm32/imm32-is-second-inout -13870 0/imm32/no-disp32 -13871 0/imm32/output-is-write-only -13872 0x11/imm32/alloc-id:fake -13873 _Primitive-compare-reg-with-literal/imm32/next -13874 _Primitive-compare-reg-with-literal: # (payload primitive) -13875 0x11/imm32/alloc-id:fake:payload -13876 # compare var1/reg n => 81 7/subop/compare %reg n/imm32 -13877 0x11/imm32/alloc-id:fake -13878 _string-compare/imm32/name -13879 0x11/imm32/alloc-id:fake -13880 Int-var-in-register-and-literal/imm32/inouts -13881 0/imm32/no-outputs -13882 0/imm32/no-outputs -13883 0x11/imm32/alloc-id:fake -13884 _string_81_subop_compare/imm32/subx-name -13885 1/imm32/rm32-is-first-inout -13886 0/imm32/no-r32 -13887 2/imm32/imm32-is-second-inout -13888 0/imm32/no-disp32 -13889 0/imm32/output-is-write-only -13890 0x11/imm32/alloc-id:fake -13891 _Primitive-compare-mem-with-literal/imm32/next -13892 _Primitive-compare-mem-with-literal: # (payload primitive) -13893 0x11/imm32/alloc-id:fake:payload -13894 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32 -13895 0x11/imm32/alloc-id:fake -13896 _string-compare/imm32/name -13897 0x11/imm32/alloc-id:fake -13898 Int-var-and-literal/imm32/inouts -13899 0/imm32/no-outputs -13900 0/imm32/no-outputs -13901 0x11/imm32/alloc-id:fake -13902 _string_81_subop_compare/imm32/subx-name -13903 1/imm32/rm32-is-first-inout -13904 0/imm32/no-r32 -13905 2/imm32/imm32-is-second-inout -13906 0/imm32/no-disp32 -13907 0/imm32/output-is-write-only -13908 0x11/imm32/alloc-id:fake -13909 _Primitive-multiply-reg-by-reg/imm32/next -13910 # - multiply -13911 _Primitive-multiply-reg-by-reg: # (payload primitive) -13912 0x11/imm32/alloc-id:fake:payload -13913 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 -13914 0x11/imm32/alloc-id:fake -13915 _string-multiply/imm32/name -13916 0x11/imm32/alloc-id:fake -13917 Single-int-var-in-some-register/imm32/inouts -13918 0x11/imm32/alloc-id:fake -13919 Single-int-var-in-some-register/imm32/outputs -13920 0x11/imm32/alloc-id:fake -13921 _string_0f_af_multiply/imm32/subx-name -13922 1/imm32/rm32-is-first-inout -13923 3/imm32/r32-is-first-output -13924 0/imm32/no-imm32 -13925 0/imm32/no-disp32 -13926 0/imm32/output-is-write-only -13927 0x11/imm32/alloc-id:fake -13928 _Primitive-multiply-reg-by-mem/imm32/next -13929 _Primitive-multiply-reg-by-mem: # (payload primitive) -13930 0x11/imm32/alloc-id:fake:payload -13931 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 -13932 0x11/imm32/alloc-id:fake -13933 _string-multiply/imm32/name -13934 0x11/imm32/alloc-id:fake -13935 Single-int-var-in-mem/imm32/inouts -13936 0x11/imm32/alloc-id:fake -13937 Single-int-var-in-some-register/imm32/outputs -13938 0x11/imm32/alloc-id:fake -13939 _string_0f_af_multiply/imm32/subx-name -13940 1/imm32/rm32-is-first-inout -13941 3/imm32/r32-is-first-output -13942 0/imm32/no-imm32 -13943 0/imm32/no-disp32 -13944 0/imm32/output-is-write-only -13945 0x11/imm32/alloc-id:fake -13946 _Primitive-break-if-addr</imm32/next -13947 # - branches -13948 _Primitive-break-if-addr<: # (payload primitive) -13949 0x11/imm32/alloc-id:fake:payload -13950 0x11/imm32/alloc-id:fake -13951 _string-break-if-addr</imm32/name -13952 0/imm32/no-inouts -13953 0/imm32/no-inouts -13954 0/imm32/no-outputs -13955 0/imm32/no-outputs -13956 0x11/imm32/alloc-id:fake -13957 _string_0f_82_jump_break/imm32/subx-name -13958 0/imm32/no-rm32 -13959 0/imm32/no-r32 -13960 0/imm32/no-imm32 -13961 0/imm32/no-disp32 -13962 0/imm32/no-output -13963 0x11/imm32/alloc-id:fake -13964 _Primitive-break-if-addr>=/imm32/next -13965 _Primitive-break-if-addr>=: # (payload primitive) -13966 0x11/imm32/alloc-id:fake:payload -13967 0x11/imm32/alloc-id:fake -13968 _string-break-if-addr>=/imm32/name -13969 0/imm32/no-inouts -13970 0/imm32/no-inouts -13971 0/imm32/no-outputs -13972 0/imm32/no-outputs -13973 0x11/imm32/alloc-id:fake -13974 _string_0f_83_jump_break/imm32/subx-name -13975 0/imm32/no-rm32 -13976 0/imm32/no-r32 -13977 0/imm32/no-imm32 -13978 0/imm32/no-disp32 -13979 0/imm32/no-output -13980 0x11/imm32/alloc-id:fake -13981 _Primitive-break-if-=/imm32/next -13982 _Primitive-break-if-=: # (payload primitive) -13983 0x11/imm32/alloc-id:fake:payload -13984 0x11/imm32/alloc-id:fake -13985 _string-break-if-=/imm32/name -13986 0/imm32/no-inouts -13987 0/imm32/no-inouts -13988 0/imm32/no-outputs -13989 0/imm32/no-outputs -13990 0x11/imm32/alloc-id:fake -13991 _string_0f_84_jump_break/imm32/subx-name -13992 0/imm32/no-rm32 -13993 0/imm32/no-r32 -13994 0/imm32/no-imm32 -13995 0/imm32/no-disp32 -13996 0/imm32/no-output -13997 0x11/imm32/alloc-id:fake -13998 _Primitive-break-if-!=/imm32/next -13999 _Primitive-break-if-!=: # (payload primitive) -14000 0x11/imm32/alloc-id:fake:payload -14001 0x11/imm32/alloc-id:fake -14002 _string-break-if-!=/imm32/name -14003 0/imm32/no-inouts -14004 0/imm32/no-inouts -14005 0/imm32/no-outputs -14006 0/imm32/no-outputs -14007 0x11/imm32/alloc-id:fake -14008 _string_0f_85_jump_break/imm32/subx-name -14009 0/imm32/no-rm32 -14010 0/imm32/no-r32 -14011 0/imm32/no-imm32 -14012 0/imm32/no-disp32 -14013 0/imm32/no-output -14014 0x11/imm32/alloc-id:fake -14015 _Primitive-break-if-addr<=/imm32/next -14016 _Primitive-break-if-addr<=: # (payload primitive) -14017 0x11/imm32/alloc-id:fake:payload -14018 0x11/imm32/alloc-id:fake -14019 _string-break-if-addr<=/imm32/name -14020 0/imm32/no-inouts -14021 0/imm32/no-inouts -14022 0/imm32/no-outputs -14023 0/imm32/no-outputs -14024 0x11/imm32/alloc-id:fake -14025 _string_0f_86_jump_break/imm32/subx-name -14026 0/imm32/no-rm32 -14027 0/imm32/no-r32 -14028 0/imm32/no-imm32 -14029 0/imm32/no-disp32 -14030 0/imm32/no-output -14031 0x11/imm32/alloc-id:fake -14032 _Primitive-break-if-addr>/imm32/next -14033 _Primitive-break-if-addr>: # (payload primitive) -14034 0x11/imm32/alloc-id:fake:payload -14035 0x11/imm32/alloc-id:fake -14036 _string-break-if-addr>/imm32/name -14037 0/imm32/no-inouts -14038 0/imm32/no-inouts -14039 0/imm32/no-outputs -14040 0/imm32/no-outputs -14041 0x11/imm32/alloc-id:fake -14042 _string_0f_87_jump_break/imm32/subx-name -14043 0/imm32/no-rm32 -14044 0/imm32/no-r32 -14045 0/imm32/no-imm32 -14046 0/imm32/no-disp32 -14047 0/imm32/no-output -14048 0x11/imm32/alloc-id:fake -14049 _Primitive-break-if-</imm32/next -14050 _Primitive-break-if-<: # (payload primitive) -14051 0x11/imm32/alloc-id:fake:payload -14052 0x11/imm32/alloc-id:fake -14053 _string-break-if-</imm32/name -14054 0/imm32/no-inouts -14055 0/imm32/no-inouts -14056 0/imm32/no-outputs -14057 0/imm32/no-outputs -14058 0x11/imm32/alloc-id:fake -14059 _string_0f_8c_jump_break/imm32/subx-name -14060 0/imm32/no-rm32 -14061 0/imm32/no-r32 -14062 0/imm32/no-imm32 -14063 0/imm32/no-disp32 -14064 0/imm32/no-output -14065 0x11/imm32/alloc-id:fake -14066 _Primitive-break-if->=/imm32/next -14067 _Primitive-break-if->=: # (payload primitive) -14068 0x11/imm32/alloc-id:fake:payload -14069 0x11/imm32/alloc-id:fake -14070 _string-break-if->=/imm32/name -14071 0/imm32/no-inouts -14072 0/imm32/no-inouts -14073 0/imm32/no-outputs -14074 0/imm32/no-outputs -14075 0x11/imm32/alloc-id:fake -14076 _string_0f_8d_jump_break/imm32/subx-name -14077 0/imm32/no-rm32 -14078 0/imm32/no-r32 -14079 0/imm32/no-imm32 -14080 0/imm32/no-disp32 -14081 0/imm32/no-output -14082 0x11/imm32/alloc-id:fake -14083 _Primitive-break-if-<=/imm32/next -14084 _Primitive-break-if-<=: # (payload primitive) -14085 0x11/imm32/alloc-id:fake:payload -14086 0x11/imm32/alloc-id:fake -14087 _string-break-if-<=/imm32/name -14088 0/imm32/no-inouts -14089 0/imm32/no-inouts -14090 0/imm32/no-outputs -14091 0/imm32/no-outputs -14092 0x11/imm32/alloc-id:fake -14093 _string_0f_8e_jump_break/imm32/subx-name -14094 0/imm32/no-rm32 -14095 0/imm32/no-r32 -14096 0/imm32/no-imm32 -14097 0/imm32/no-disp32 -14098 0/imm32/no-output -14099 0x11/imm32/alloc-id:fake -14100 _Primitive-break-if->/imm32/next -14101 _Primitive-break-if->: # (payload primitive) -14102 0x11/imm32/alloc-id:fake:payload -14103 0x11/imm32/alloc-id:fake -14104 _string-break-if->/imm32/name -14105 0/imm32/no-inouts -14106 0/imm32/no-inouts -14107 0/imm32/no-outputs -14108 0/imm32/no-outputs -14109 0x11/imm32/alloc-id:fake -14110 _string_0f_8f_jump_break/imm32/subx-name -14111 0/imm32/no-rm32 -14112 0/imm32/no-r32 -14113 0/imm32/no-imm32 -14114 0/imm32/no-disp32 -14115 0/imm32/no-output -14116 0x11/imm32/alloc-id:fake -14117 _Primitive-break/imm32/next -14118 _Primitive-break: # (payload primitive) -14119 0x11/imm32/alloc-id:fake:payload -14120 0x11/imm32/alloc-id:fake -14121 _string-break/imm32/name -14122 0/imm32/no-inouts -14123 0/imm32/no-inouts -14124 0/imm32/no-outputs -14125 0/imm32/no-outputs -14126 0x11/imm32/alloc-id:fake -14127 _string_e9_jump_break/imm32/subx-name -14128 0/imm32/no-rm32 -14129 0/imm32/no-r32 -14130 0/imm32/no-imm32 -14131 0/imm32/no-disp32 -14132 0/imm32/no-output -14133 0x11/imm32/alloc-id:fake -14134 _Primitive-loop-if-addr</imm32/next -14135 _Primitive-loop-if-addr<: # (payload primitive) -14136 0x11/imm32/alloc-id:fake:payload -14137 0x11/imm32/alloc-id:fake -14138 _string-loop-if-addr</imm32/name -14139 0/imm32/no-inouts -14140 0/imm32/no-inouts -14141 0/imm32/no-outputs -14142 0/imm32/no-outputs -14143 0x11/imm32/alloc-id:fake -14144 _string_0f_82_jump_loop/imm32/subx-name -14145 0/imm32/no-rm32 -14146 0/imm32/no-r32 -14147 0/imm32/no-imm32 -14148 0/imm32/no-disp32 -14149 0/imm32/no-output -14150 0x11/imm32/alloc-id:fake -14151 _Primitive-loop-if-addr>=/imm32/next -14152 _Primitive-loop-if-addr>=: # (payload primitive) -14153 0x11/imm32/alloc-id:fake:payload -14154 0x11/imm32/alloc-id:fake -14155 _string-loop-if-addr>=/imm32/name -14156 0/imm32/no-inouts -14157 0/imm32/no-inouts -14158 0/imm32/no-outputs -14159 0/imm32/no-outputs -14160 0x11/imm32/alloc-id:fake -14161 _string_0f_83_jump_loop/imm32/subx-name -14162 0/imm32/no-rm32 -14163 0/imm32/no-r32 -14164 0/imm32/no-imm32 -14165 0/imm32/no-disp32 -14166 0/imm32/no-output -14167 0x11/imm32/alloc-id:fake -14168 _Primitive-loop-if-=/imm32/next -14169 _Primitive-loop-if-=: # (payload primitive) -14170 0x11/imm32/alloc-id:fake:payload +11849 $type-equal?:check-left: +11850 # if (!type-equal?(a->left, b->left)) return false +11851 (lookup *(ecx+4) *(ecx+8)) # Tree-left Tree-left => eax +11852 89/<- %ebx 0/r32/eax +11853 (lookup *(edx+4) *(edx+8)) # Tree-left Tree-left => eax +11854 (type-equal? %eax %ebx) # => eax +11855 3d/compare-eax-and 0/imm32/false +11856 74/jump-if-= $type-equal?:end/disp8 +11857 $type-equal?:check-right: +11858 # return type-equal?(a->right, b->right) +11859 (lookup *(ecx+0xc) *(ecx+0x10)) # Tree-right Tree-right => eax +11860 89/<- %ebx 0/r32/eax +11861 (lookup *(edx+0xc) *(edx+0x10)) # Tree-right Tree-right => eax +11862 (type-equal? %eax %ebx) # => eax +11863 $type-equal?:end: +11864 # . restore registers +11865 5b/pop-to-ebx +11866 5a/pop-to-edx +11867 59/pop-to-ecx +11868 # . epilogue +11869 89/<- %esp 5/r32/ebp +11870 5d/pop-to-ebp +11871 c3/return +11872 +11873 ####################################################### +11874 # Code-generation +11875 ####################################################### +11876 +11877 == data +11878 +11879 # Global state added to each var record when performing code-generation. +11880 Curr-local-stack-offset: # (addr int) +11881 0/imm32 +11882 +11883 == code +11884 +11885 emit-subx: # out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) +11886 # . prologue +11887 55/push-ebp +11888 89/<- %ebp 4/r32/esp +11889 # . save registers +11890 50/push-eax +11891 # var curr/eax: (addr function) = *Program->functions +11892 (lookup *_Program-functions *_Program-functions->payload) # => eax +11893 { +11894 # if (curr == null) break +11895 3d/compare-eax-and 0/imm32 +11896 0f 84/jump-if-= break/disp32 +11897 (emit-subx-function *(ebp+8) %eax *(ebp+0xc) *(ebp+0x10)) +11898 # curr = lookup(curr->next) +11899 (lookup *(eax+0x20) *(eax+0x24)) # Function-next Function-next => eax +11900 e9/jump loop/disp32 +11901 } +11902 $emit-subx:end: +11903 # . restore registers +11904 58/pop-to-eax +11905 # . epilogue +11906 89/<- %esp 5/r32/ebp +11907 5d/pop-to-ebp +11908 c3/return +11909 +11910 emit-subx-function: # out: (addr buffered-file), f: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor) +11911 # . prologue +11912 55/push-ebp +11913 89/<- %ebp 4/r32/esp +11914 # some preprocessing +11915 (populate-mu-type-offsets-in-inouts *(ebp+0xc)) +11916 # . save registers +11917 50/push-eax +11918 51/push-ecx +11919 52/push-edx +11920 # initialize some global state +11921 c7 0/subop/copy *Curr-block-depth 1/imm32 # Important: keep this in sync with the parse phase +11922 c7 0/subop/copy *Curr-local-stack-offset 0/imm32 +11923 # ecx = f +11924 8b/-> *(ebp+0xc) 1/r32/ecx +11925 # var vars/edx: (stack (addr var) 256) +11926 81 5/subop/subtract %esp 0xc00/imm32 +11927 68/push 0xc00/imm32/size +11928 68/push 0/imm32/top +11929 89/<- %edx 4/r32/esp +11930 # var name/eax: (addr array byte) = lookup(f->name) +11931 (lookup *ecx *(ecx+4)) # Function-name Function-name => eax +11932 # +11933 (write-buffered *(ebp+8) %eax) +11934 (write-buffered *(ebp+8) ":\n") +11935 (emit-subx-prologue *(ebp+8)) +11936 # var body/eax: (addr block) = lookup(f->body) +11937 (lookup *(ecx+0x18) *(ecx+0x1c)) # Function-body Function-body => eax +11938 # +11939 (emit-subx-block *(ebp+8) %eax %edx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +11940 (emit-subx-epilogue *(ebp+8)) +11941 # TODO: validate that *Curr-block-depth and *Curr-local-stack-offset have +11942 # been cleaned up +11943 $emit-subx-function:end: +11944 # . reclaim locals +11945 81 0/subop/add %esp 0xc08/imm32 +11946 # . restore registers +11947 5a/pop-to-edx +11948 59/pop-to-ecx +11949 58/pop-to-eax +11950 # . epilogue +11951 89/<- %esp 5/r32/ebp +11952 5d/pop-to-ebp +11953 c3/return +11954 +11955 populate-mu-type-offsets-in-inouts: # f: (addr function) +11956 # . prologue +11957 55/push-ebp +11958 89/<- %ebp 4/r32/esp +11959 # . save registers +11960 50/push-eax +11961 51/push-ecx +11962 52/push-edx +11963 53/push-ebx +11964 57/push-edi +11965 # var next-offset/edx: int = 8 +11966 ba/copy-to-edx 8/imm32 +11967 # var curr/ecx: (addr list var) = lookup(f->inouts) +11968 8b/-> *(ebp+8) 1/r32/ecx +11969 (lookup *(ecx+8) *(ecx+0xc)) # Function-inouts Function-inouts => eax +11970 89/<- %ecx 0/r32/eax +11971 { +11972 $populate-mu-type-offsets-in-inouts:loop: +11973 81 7/subop/compare %ecx 0/imm32 +11974 74/jump-if-= break/disp8 +11975 # var v/ebx: (addr var) = lookup(curr->value) +11976 (lookup *ecx *(ecx+4)) # List-value List-value => eax +11977 89/<- %ebx 0/r32/eax +11978 #? (lookup *ebx *(ebx+4)) +11979 #? (write-buffered Stderr "setting offset of fn inout ") +11980 #? (write-buffered Stderr %eax) +11981 #? (write-buffered Stderr "@") +11982 #? (print-int32-buffered Stderr %ebx) +11983 #? (write-buffered Stderr " to ") +11984 #? (print-int32-buffered Stderr %edx) +11985 #? (write-buffered Stderr Newline) +11986 #? (flush Stderr) +11987 # v->offset = next-offset +11988 89/<- *(ebx+0x14) 2/r32/edx # Var-offset +11989 # next-offset += size-of(v) +11990 (size-of %ebx) # => eax +11991 01/add-to %edx 0/r32/eax +11992 # curr = lookup(curr->next) +11993 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +11994 89/<- %ecx 0/r32/eax +11995 # +11996 eb/jump loop/disp8 +11997 } +11998 $populate-mu-type-offsets-in-inouts:end: +11999 # . restore registers +12000 5f/pop-to-edi +12001 5b/pop-to-ebx +12002 5a/pop-to-edx +12003 59/pop-to-ecx +12004 58/pop-to-eax +12005 # . epilogue +12006 89/<- %esp 5/r32/ebp +12007 5d/pop-to-ebp +12008 c3/return +12009 +12010 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) +12011 # . prologue +12012 55/push-ebp +12013 89/<- %ebp 4/r32/esp +12014 # . save registers +12015 50/push-eax +12016 51/push-ecx +12017 53/push-ebx +12018 56/push-esi +12019 # esi = stmts +12020 8b/-> *(ebp+0xc) 6/r32/esi +12021 # +12022 { +12023 $emit-subx-stmt-list:loop: +12024 81 7/subop/compare %esi 0/imm32 +12025 0f 84/jump-if-= break/disp32 +12026 # var curr-stmt/ecx: (addr stmt) = lookup(stmts->value) +12027 (lookup *esi *(esi+4)) # List-value List-value => eax +12028 89/<- %ecx 0/r32/eax +12029 { +12030 $emit-subx-stmt-list:check-for-block: +12031 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag +12032 75/jump-if-!= break/disp8 +12033 $emit-subx-stmt-list:block: +12034 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +12035 } +12036 { +12037 $emit-subx-stmt-list:check-for-stmt: +12038 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag +12039 0f 85/jump-if-!= break/disp32 +12040 $emit-subx-stmt-list:stmt1: +12041 { +12042 (is-mu-branch? %ecx) # => eax +12043 3d/compare-eax-and 0/imm32/false +12044 0f 84/jump-if-= break/disp32 +12045 $emit-subx-stmt-list:branch-stmt: +12046 +-- 27 lines: # unconditional loops ----------------------------------------------------------------------------------------------------------------------------------------------------- +12073 +-- 16 lines: # unconditional breaks ---------------------------------------------------------------------------------------------------------------------------------------------------- +12089 +-- 38 lines: # simple conditional branches without a target ---------------------------------------------------------------------------------------------------------------------------- +12127 +-- 19 lines: # conditional branches with an explicit target ---------------------------------------------------------------------------------------------------------------------------- +12146 } +12147 $emit-subx-stmt-list:1-to-1: +12148 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x18) *(ebp+0x1c)) +12149 e9/jump $emit-subx-stmt-list:continue/disp32 +12150 } +12151 { +12152 $emit-subx-stmt-list:check-for-var-def: +12153 81 7/subop/compare *ecx 2/imm32/var-def # Stmt-tag +12154 75/jump-if-!= break/disp8 +12155 $emit-subx-stmt-list:var-def: +12156 (emit-subx-var-def *(ebp+8) %ecx) +12157 (push *(ebp+0x10) *(ecx+4)) # Vardef-var +12158 (push *(ebp+0x10) *(ecx+8)) # Vardef-var +12159 (push *(ebp+0x10) 0) # Live-var-register-spilled = 0 for vars on the stack +12160 # +12161 eb/jump $emit-subx-stmt-list:continue/disp8 +12162 } +12163 { +12164 $emit-subx-stmt-list:check-for-reg-var-def: +12165 81 7/subop/compare *ecx 3/imm32/reg-var-def # Stmt-tag +12166 0f 85/jump-if-!= break/disp32 +12167 $emit-subx-stmt-list:reg-var-def: +12168 # TODO: ensure that there's exactly one output +12169 (push-output-and-maybe-emit-spill *(ebp+8) %ecx *(ebp+0x10) %esi *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +12170 # emit the instruction as usual +12171 (emit-subx-stmt *(ebp+8) %ecx Primitives *(ebp+0x18) *(ebp+0x1c)) +12172 # +12173 eb/jump $emit-subx-stmt-list:continue/disp8 +12174 } +12175 $emit-subx-stmt-list:continue: +12176 # TODO: raise an error on unrecognized Stmt-tag +12177 (lookup *(esi+8) *(esi+0xc)) # List-next List-next => eax +12178 89/<- %esi 0/r32/eax +12179 e9/jump loop/disp32 +12180 } +12181 $emit-subx-stmt-list:emit-cleanup: +12182 (emit-cleanup-code-until-depth *(ebp+8) *(ebp+0x10) *Curr-block-depth) +12183 $emit-subx-stmt-list:clean-up: +12184 (clean-up-blocks *(ebp+0x10) *Curr-block-depth *(ebp+0x14)) +12185 $emit-subx-stmt-list:end: +12186 # . restore registers +12187 5e/pop-to-esi +12188 5b/pop-to-ebx +12189 59/pop-to-ecx +12190 58/pop-to-eax +12191 # . epilogue +12192 89/<- %esp 5/r32/ebp +12193 5d/pop-to-ebp +12194 c3/return +12195 +12196 # 'later-stmts' includes 'stmt', but will behave the same even without it; reg-var-def stmts are guaranteed not to write to function outputs. +12197 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) +12198 # . prologue +12199 55/push-ebp +12200 89/<- %ebp 4/r32/esp +12201 # . save registers +12202 50/push-eax +12203 51/push-ecx +12204 52/push-edx +12205 # ecx = stmt +12206 8b/-> *(ebp+0xc) 1/r32/ecx +12207 # var sv/eax: (addr stmt-var) = lookup(curr-stmt->outputs) +12208 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax +12209 # TODO: assert !sv->is-deref? +12210 # var v/ecx: (addr var) = lookup(sv->value) +12211 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +12212 89/<- %ecx 0/r32/eax +12213 # v->block-depth = *Curr-block-depth +12214 8b/-> *Curr-block-depth 0/r32/eax +12215 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +12216 #? (write-buffered Stderr "var ") +12217 #? (lookup *ecx *(ecx+4)) +12218 #? (write-buffered Stderr %eax) +12219 #? (write-buffered Stderr " at depth ") +12220 #? (print-int32-buffered Stderr *(ecx+0x10)) +12221 #? (write-buffered Stderr Newline) +12222 #? (flush Stderr) +12223 # ensure that v is in a register +12224 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +12225 0f 84/jump-if-= $push-output-and-maybe-emit-spill:abort/disp32 +12226 # var emit-spill?/edx: boolean = not-yet-spilled-this-block? && will-not-write-some-register?(fn) +12227 (not-yet-spilled-this-block? %ecx *(ebp+0x10)) # => eax +12228 89/<- %edx 0/r32/eax +12229 3d/compare-eax-and 0/imm32/false +12230 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 +12231 (will-not-write-some-register? %ecx *(ebp+0x14) *(ebp+0x18)) # => eax +12232 89/<- %edx 0/r32/eax +12233 # check emit-spill? +12234 3d/compare-eax-and 0/imm32/false +12235 0f 84/jump-if-= $push-output-and-maybe-emit-spill:push/disp32 +12236 # TODO: assert(size-of(output) == 4) +12237 # *Curr-local-stack-offset -= 4 +12238 81 5/subop/subtract *Curr-local-stack-offset 4/imm32 +12239 # emit spill +12240 (emit-indent *(ebp+8) *Curr-block-depth) +12241 (write-buffered *(ebp+8) "ff 6/subop/push %") +12242 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +12243 (write-buffered *(ebp+8) %eax) +12244 (write-buffered *(ebp+8) Newline) +12245 $push-output-and-maybe-emit-spill:push: +12246 8b/-> *(ebp+0xc) 1/r32/ecx +12247 (lookup *(ecx+0x14) *(ecx+0x18)) # Regvardef-outputs Regvardef-outputs => eax +12248 # push(vars, {sv->value, emit-spill?}) +12249 (push *(ebp+0x10) *eax) # Stmt-var-value +12250 (push *(ebp+0x10) *(eax+4)) # Stmt-var-value +12251 (push *(ebp+0x10) %edx) +12252 $push-output-and-maybe-emit-spill:end: +12253 # . restore registers +12254 5a/pop-to-edx +12255 59/pop-to-ecx +12256 58/pop-to-eax +12257 # . epilogue +12258 89/<- %esp 5/r32/ebp +12259 5d/pop-to-ebp +12260 c3/return +12261 +12262 $push-output-and-maybe-emit-spill:abort: +12263 # error("var '" var->name "' initialized from an instruction must live in a register\n") +12264 (write-buffered *(ebp+0x1c) "var '") +12265 (write-buffered *(ebp+0x1c) *eax) # Var-name +12266 (write-buffered *(ebp+0x1c) "' initialized from an instruction must live in a register\n") +12267 (flush *(ebp+0x1c)) +12268 (stop *(ebp+0x20) 1) +12269 # never gets here +12270 +12271 emit-subx-cleanup-and-unconditional-nonlocal-branch: # out: (addr buffered-file), stmt: (addr stmt1), vars: (addr stack live-var) +12272 # . prologue +12273 55/push-ebp +12274 89/<- %ebp 4/r32/esp +12275 # . save registers +12276 50/push-eax +12277 51/push-ecx +12278 # ecx = stmt +12279 8b/-> *(ebp+0xc) 1/r32/ecx +12280 # var target/eax: (addr array byte) = curr-stmt->inouts->value->name +12281 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +12282 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +12283 (lookup *eax *(eax+4)) # Var-name Var-name => eax +12284 # clean up until target block +12285 (emit-cleanup-code-until-target *(ebp+8) *(ebp+0x10) %eax) +12286 # emit jump to target block +12287 (emit-indent *(ebp+8) *Curr-block-depth) +12288 (write-buffered *(ebp+8) "e9/jump ") +12289 (write-buffered *(ebp+8) %eax) +12290 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +12291 (string-starts-with? %eax "break") +12292 3d/compare-eax-and 0/imm32/false +12293 { +12294 74/jump-if-= break/disp8 +12295 (write-buffered *(ebp+8) ":break/disp32\n") +12296 } +12297 3d/compare-eax-and 0/imm32/false # just in case the function call modified flags +12298 { +12299 75/jump-if-!= break/disp8 +12300 (write-buffered *(ebp+8) ":loop/disp32\n") +12301 } +12302 $emit-subx-cleanup-and-unconditional-nonlocal-branch:end: +12303 # . restore registers +12304 59/pop-to-ecx +12305 58/pop-to-eax +12306 # . epilogue +12307 89/<- %esp 5/r32/ebp +12308 5d/pop-to-ebp +12309 c3/return +12310 +12311 is-mu-branch?: # stmt: (addr stmt1) -> result/eax: boolean +12312 # . prologue +12313 55/push-ebp +12314 89/<- %ebp 4/r32/esp +12315 # . save registers +12316 51/push-ecx +12317 # ecx = lookup(stmt->operation) +12318 8b/-> *(ebp+8) 1/r32/ecx +12319 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +12320 89/<- %ecx 0/r32/eax +12321 # if (stmt->operation starts with "loop") return true +12322 (string-starts-with? %ecx "loop") # => eax +12323 3d/compare-eax-and 0/imm32/false +12324 75/jump-if-not-equal $is-mu-branch?:end/disp8 +12325 # otherwise return (stmt->operation starts with "break") +12326 (string-starts-with? %ecx "break") # => eax +12327 $is-mu-branch?:end: +12328 # . restore registers +12329 59/pop-to-ecx +12330 # . epilogue +12331 89/<- %esp 5/r32/ebp +12332 5d/pop-to-ebp +12333 c3/return +12334 +12335 emit-reverse-break: # out: (addr buffered-file), stmt: (addr stmt1) +12336 # . prologue +12337 55/push-ebp +12338 89/<- %ebp 4/r32/esp +12339 # . save registers +12340 50/push-eax +12341 # eax = stmt +12342 8b/-> *(ebp+0xc) 0/r32/eax +12343 # +12344 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +12345 (get Reverse-branch %eax 0x10 "reverse-branch: ") # => eax: (addr handle array byte) +12346 (emit-indent *(ebp+8) *Curr-block-depth) +12347 (lookup *eax *(eax+4)) # => eax +12348 (write-buffered *(ebp+8) %eax) +12349 (write-buffered *(ebp+8) " break/disp32\n") +12350 $emit-reverse-break:end: +12351 # . restore registers +12352 58/pop-to-eax +12353 # . epilogue +12354 89/<- %esp 5/r32/ebp +12355 5d/pop-to-ebp +12356 c3/return +12357 +12358 == data +12359 +12360 # Table from Mu branch instructions to the reverse SubX opcodes for them. +12361 Reverse-branch: # (table (handle array byte) (handle array byte)) +12362 # a table is a stream +12363 0x140/imm32/write +12364 0/imm32/read +12365 0x140/imm32/size +12366 # data +12367 0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 +12368 0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 +12369 0x11/imm32/alloc-id _string-break-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 +12370 0x11/imm32/alloc-id _string-loop-if-!=/imm32 0x11/imm32/alloc-id _string_0f_84_jump_label/imm32 +12371 0x11/imm32/alloc-id _string-break-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 +12372 0x11/imm32/alloc-id _string-loop-if-</imm32 0x11/imm32/alloc-id _string_0f_8d_jump_label/imm32 +12373 0x11/imm32/alloc-id _string-break-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 +12374 0x11/imm32/alloc-id _string-loop-if->/imm32 0x11/imm32/alloc-id _string_0f_8e_jump_label/imm32 +12375 0x11/imm32/alloc-id _string-break-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +12376 0x11/imm32/alloc-id _string-loop-if-<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +12377 0x11/imm32/alloc-id _string-break-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 +12378 0x11/imm32/alloc-id _string-loop-if->=/imm32 0x11/imm32/alloc-id _string_0f_8c_jump_label/imm32 +12379 0x11/imm32/alloc-id _string-break-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 +12380 0x11/imm32/alloc-id _string-loop-if-addr</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32 +12381 0x11/imm32/alloc-id _string-break-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 +12382 0x11/imm32/alloc-id _string-loop-if-addr>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32 +12383 0x11/imm32/alloc-id _string-break-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +12384 0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 +12385 0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 +12386 0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 +12387 +12388 == code +12389 +12390 emit-unconditional-jump-to-depth: # out: (addr buffered-file), vars: (addr stack live-var), depth: int, label-suffix: (addr array byte) +12391 # . prologue +12392 55/push-ebp +12393 89/<- %ebp 4/r32/esp +12394 # . save registers +12395 50/push-eax +12396 51/push-ecx +12397 52/push-edx +12398 53/push-ebx +12399 56/push-esi +12400 # ecx = vars +12401 8b/-> *(ebp+0xc) 1/r32/ecx +12402 # var eax: int = vars->top +12403 8b/-> *ecx 0/r32/eax +12404 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] +12405 8d/copy-address *(ecx+eax-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size +12406 # var min/ecx: (addr handle var) = vars->data +12407 8d/copy-address *(ecx+8) 1/r32/ecx +12408 # edx = depth +12409 8b/-> *(ebp+0x10) 2/r32/edx +12410 { +12411 $emit-unconditional-jump-to-depth:loop: +12412 # if (curr < min) break +12413 39/compare %esi 1/r32/ecx +12414 0f 82/jump-if-addr< break/disp32 +12415 # var v/ebx: (addr var) = lookup(*curr) +12416 (lookup *esi *(esi+4)) # => eax +12417 89/<- %ebx 0/r32/eax +12418 # if (v->block-depth < until-block-depth) break +12419 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +12420 0f 8c/jump-if-< break/disp32 +12421 { +12422 $emit-unconditional-jump-to-depth:check: +12423 # if v->block-depth != until-block-depth, continue +12424 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +12425 0f 85/jump-if-!= break/disp32 +12426 $emit-unconditional-jump-to-depth:depth-found: +12427 # if v is not a literal, continue +12428 (size-of %ebx) # => eax +12429 3d/compare-eax-and 0/imm32 +12430 0f 85/jump-if-!= break/disp32 +12431 $emit-unconditional-jump-to-depth:label-found: +12432 # emit unconditional jump, then return +12433 (emit-indent *(ebp+8) *Curr-block-depth) +12434 (write-buffered *(ebp+8) "e9/jump ") +12435 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +12436 (write-buffered *(ebp+8) %eax) +12437 (write-buffered *(ebp+8) ":") +12438 (write-buffered *(ebp+8) *(ebp+0x14)) +12439 (write-buffered *(ebp+8) "/disp32\n") +12440 eb/jump $emit-unconditional-jump-to-depth:end/disp8 +12441 } +12442 # curr -= 12 +12443 81 5/subop/subtract %esi 0xc/imm32 +12444 e9/jump loop/disp32 +12445 } +12446 # TODO: error if no label at 'depth' was found +12447 $emit-unconditional-jump-to-depth:end: +12448 # . restore registers +12449 5e/pop-to-esi +12450 5b/pop-to-ebx +12451 5a/pop-to-edx +12452 59/pop-to-ecx +12453 58/pop-to-eax +12454 # . epilogue +12455 89/<- %esp 5/r32/ebp +12456 5d/pop-to-ebp +12457 c3/return +12458 +12459 # emit clean-up code for 'vars' until some block depth +12460 # doesn't actually modify 'vars' so we need traverse manually inside the stack +12461 emit-cleanup-code-until-depth: # out: (addr buffered-file), vars: (addr stack live-var), until-block-depth: int +12462 # . prologue +12463 55/push-ebp +12464 89/<- %ebp 4/r32/esp +12465 # . save registers +12466 50/push-eax +12467 51/push-ecx +12468 52/push-edx +12469 53/push-ebx +12470 56/push-esi +12471 #? (write-buffered Stderr "--- cleanup\n") +12472 #? (flush Stderr) +12473 # ecx = vars +12474 8b/-> *(ebp+0xc) 1/r32/ecx +12475 # var esi: int = vars->top +12476 8b/-> *ecx 6/r32/esi +12477 # var curr/esi: (addr handle var) = &vars->data[vars->top - 12] +12478 8d/copy-address *(ecx+esi-4) 6/r32/esi # vars + 8 + vars->top - 12/Live-var-size +12479 # var min/ecx: (addr handle var) = vars->data +12480 81 0/subop/add %ecx 8/imm32 +12481 # edx = until-block-depth +12482 8b/-> *(ebp+0x10) 2/r32/edx +12483 { +12484 $emit-cleanup-code-until-depth:loop: +12485 # if (curr < min) break +12486 39/compare %esi 1/r32/ecx +12487 0f 82/jump-if-addr< break/disp32 +12488 # var v/ebx: (addr var) = lookup(*curr) +12489 (lookup *esi *(esi+4)) # => eax +12490 89/<- %ebx 0/r32/eax +12491 #? (lookup *ebx *(ebx+4)) # Var-name +12492 #? (write-buffered Stderr "var ") +12493 #? (write-buffered Stderr %eax) +12494 #? (write-buffered Stderr Newline) +12495 #? (flush Stderr) +12496 # if (v->block-depth < until-block-depth) break +12497 39/compare *(ebx+0x10) 2/r32/edx # Var-block-depth +12498 0f 8c/jump-if-< break/disp32 +12499 # if v is in a register +12500 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register +12501 { +12502 0f 84/jump-if-= break/disp32 +12503 { +12504 $emit-cleanup-code-until-depth:check-for-previous-spill: +12505 8b/-> *(esi+8) 0/r32/eax # Live-var-register-spilled +12506 3d/compare-eax-and 0/imm32/false +12507 74/jump-if-= break/disp8 +12508 $emit-cleanup-code-until-depth:reclaim-var-in-register: +12509 (emit-indent *(ebp+8) *Curr-block-depth) +12510 (write-buffered *(ebp+8) "8f 0/subop/pop %") +12511 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +12512 (write-buffered *(ebp+8) %eax) +12513 (write-buffered *(ebp+8) Newline) +12514 } +12515 eb/jump $emit-cleanup-code-until-depth:continue/disp8 +12516 } +12517 # otherwise v is on the stack +12518 { +12519 75/jump-if-!= break/disp8 +12520 $emit-cleanup-code-until-depth:var-on-stack: +12521 (size-of %ebx) # => eax +12522 # don't emit code for labels +12523 3d/compare-eax-and 0/imm32 +12524 74/jump-if-= break/disp8 +12525 $emit-cleanup-code-until-depth:reclaim-var-on-stack: +12526 (emit-indent *(ebp+8) *Curr-block-depth) +12527 (write-buffered *(ebp+8) "81 0/subop/add %esp ") +12528 (print-int32-buffered *(ebp+8) %eax) +12529 (write-buffered *(ebp+8) "/imm32\n") +12530 } +12531 $emit-cleanup-code-until-depth:continue: +12532 # curr -= 12 +12533 81 5/subop/subtract %esi 0xc/imm32 +12534 e9/jump loop/disp32 +12535 } +12536 $emit-cleanup-code-until-depth:end: +12537 # . restore registers +12538 5e/pop-to-esi +12539 5b/pop-to-ebx +12540 5a/pop-to-edx +12541 59/pop-to-ecx +12542 58/pop-to-eax +12543 # . epilogue +12544 89/<- %esp 5/r32/ebp +12545 5d/pop-to-ebp +12546 c3/return +12547 +12548 # emit clean-up code for 'vars' until a given label is encountered +12549 # doesn't actually modify 'vars' so we need traverse manually inside the stack +12550 emit-cleanup-code-until-target: # out: (addr buffered-file), vars: (addr stack live-var), until-block-label: (addr array byte) +12551 # . prologue +12552 55/push-ebp +12553 89/<- %ebp 4/r32/esp +12554 # . save registers +12555 50/push-eax +12556 51/push-ecx +12557 52/push-edx +12558 53/push-ebx +12559 # ecx = vars +12560 8b/-> *(ebp+0xc) 1/r32/ecx +12561 # var eax: int = vars->top +12562 8b/-> *ecx 0/r32/eax +12563 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] +12564 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size +12565 # var min/ecx: (addr handle var) = vars->data +12566 81 0/subop/add %ecx 8/imm32 +12567 { +12568 $emit-cleanup-code-until-target:loop: +12569 # if (curr < min) break +12570 39/compare %edx 1/r32/ecx +12571 0f 82/jump-if-addr< break/disp32 +12572 # var v/ebx: (handle var) = lookup(*curr) +12573 (lookup *edx *(edx+4)) # => eax +12574 89/<- %ebx 0/r32/eax +12575 # if (v->name == until-block-label) break +12576 (lookup *ebx *(ebx+4)) # Var-name Var-name => eax +12577 (string-equal? %eax *(ebp+0x10)) # => eax +12578 3d/compare-eax-and 0/imm32/false +12579 0f 85/jump-if-!= break/disp32 +12580 # if v is in a register +12581 81 7/subop/compare *(ebx+0x18) 0/imm32 # Var-register +12582 { +12583 0f 84/jump-if-= break/disp32 +12584 { +12585 $emit-cleanup-code-until-target:check-for-previous-spill: +12586 8b/-> *(edx+8) 0/r32/eax # Live-var-register-spilled +12587 3d/compare-eax-and 0/imm32/false +12588 74/jump-if-= break/disp8 +12589 $emit-cleanup-code-until-target:reclaim-var-in-register: +12590 (emit-indent *(ebp+8) *Curr-block-depth) +12591 (write-buffered *(ebp+8) "8f 0/subop/pop %") +12592 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +12593 (write-buffered *(ebp+8) %eax) +12594 (write-buffered *(ebp+8) Newline) +12595 } +12596 eb/jump $emit-cleanup-code-until-target:continue/disp8 +12597 } +12598 # otherwise v is on the stack +12599 { +12600 75/jump-if-!= break/disp8 +12601 $emit-cleanup-code-until-target:reclaim-var-on-stack: +12602 (size-of %ebx) # => eax +12603 # don't emit code for labels +12604 3d/compare-eax-and 0/imm32 +12605 74/jump-if-= break/disp8 +12606 # +12607 (emit-indent *(ebp+8) *Curr-block-depth) +12608 (write-buffered *(ebp+8) "81 0/subop/add %esp ") +12609 (print-int32-buffered *(ebp+8) %eax) +12610 (write-buffered *(ebp+8) "/imm32\n") +12611 } +12612 $emit-cleanup-code-until-target:continue: +12613 # curr -= 12 +12614 81 5/subop/subtract %edx 0xc/imm32 +12615 e9/jump loop/disp32 +12616 } +12617 $emit-cleanup-code-until-target:end: +12618 # . restore registers +12619 5b/pop-to-ebx +12620 5a/pop-to-edx +12621 59/pop-to-ecx +12622 58/pop-to-eax +12623 # . epilogue +12624 89/<- %esp 5/r32/ebp +12625 5d/pop-to-ebp +12626 c3/return +12627 +12628 # Return true if there isn't a variable in 'vars' with the same block-depth +12629 # and register as 'v'. +12630 # 'v' is guaranteed not to be within 'vars'. +12631 not-yet-spilled-this-block?: # v: (addr var), vars: (addr stack live-var) -> result/eax: boolean +12632 # . prologue +12633 55/push-ebp +12634 89/<- %ebp 4/r32/esp +12635 # . save registers +12636 51/push-ecx +12637 52/push-edx +12638 53/push-ebx +12639 56/push-esi +12640 57/push-edi +12641 # ecx = vars +12642 8b/-> *(ebp+0xc) 1/r32/ecx +12643 # var eax: int = vars->top +12644 8b/-> *ecx 0/r32/eax +12645 # var curr/edx: (addr handle var) = &vars->data[vars->top - 12] +12646 8d/copy-address *(ecx+eax-4) 2/r32/edx # vars + 8 + vars->top - 12/Live-var-size +12647 # var min/ecx: (addr handle var) = vars->data +12648 8d/copy-address *(ecx+8) 1/r32/ecx +12649 # var depth/ebx: int = v->block-depth +12650 8b/-> *(ebp+8) 3/r32/ebx +12651 8b/-> *(ebx+0x10) 3/r32/ebx # Var-block-depth +12652 # var needle/esi: (addr array byte) = v->register +12653 8b/-> *(ebp+8) 6/r32/esi +12654 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +12655 89/<- %esi 0/r32/eax +12656 { +12657 $not-yet-spilled-this-block?:loop: +12658 # if (curr < min) break +12659 39/compare %edx 1/r32/ecx +12660 0f 82/jump-if-addr< break/disp32 +12661 # var cand/edi: (addr var) = lookup(*curr) +12662 (lookup *edx *(edx+4)) # => eax +12663 89/<- %edi 0/r32/eax +12664 # if (cand->block-depth < depth) break +12665 39/compare *(edi+0x10) 3/r32/ebx # Var-block-depth +12666 0f 8c/jump-if-< break/disp32 +12667 # var cand-reg/edi: (array array byte) = cand->reg +12668 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +12669 89/<- %edi 0/r32/eax +12670 # if (cand-reg == null) continue +12671 { +12672 $not-yet-spilled-this-block?:check-reg: +12673 81 7/subop/compare %edi 0/imm32 +12674 0f 84/jump-if-= break/disp32 +12675 # if (cand-reg == needle) return true +12676 (string-equal? %esi %edi) # => eax +12677 3d/compare-eax-and 0/imm32/false +12678 74/jump-if-= break/disp8 +12679 $not-yet-spilled-this-block?:return-false: +12680 b8/copy-to-eax 0/imm32/false +12681 eb/jump $not-yet-spilled-this-block?:end/disp8 +12682 } +12683 $not-yet-spilled-this-block?:continue: +12684 # curr -= 12 +12685 81 5/subop/subtract %edx 0xc/imm32 +12686 e9/jump loop/disp32 +12687 } +12688 $not-yet-spilled-this-block?:return-true: +12689 # return true +12690 b8/copy-to-eax 1/imm32/true +12691 $not-yet-spilled-this-block?:end: +12692 # . restore registers +12693 5f/pop-to-edi +12694 5e/pop-to-esi +12695 5b/pop-to-ebx +12696 5a/pop-to-edx +12697 59/pop-to-ecx +12698 # . epilogue +12699 89/<- %esp 5/r32/ebp +12700 5d/pop-to-ebp +12701 c3/return +12702 +12703 # could the register of 'v' ever be written to by one of the vars in fn-outputs? +12704 will-not-write-some-register?: # v: (addr var), stmts: (addr list stmt), fn: (addr function) -> result/eax: boolean +12705 # . prologue +12706 55/push-ebp +12707 89/<- %ebp 4/r32/esp +12708 # eax = v +12709 8b/-> *(ebp+8) 0/r32/eax +12710 # var reg/eax: (addr array byte) = lookup(v->register) +12711 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +12712 # var target/eax: (addr var) = find-register(fn-outputs, reg) +12713 (find-register *(ebp+0x10) %eax) # => eax +12714 # if (target == 0) return true +12715 { +12716 3d/compare-eax-and 0/imm32 +12717 75/jump-if-!= break/disp8 +12718 b8/copy-to-eax 1/imm32/true +12719 eb/jump $will-not-write-some-register?:end/disp8 +12720 } +12721 # return !assigns-in-stmts?(stmts, target) +12722 (assigns-in-stmts? *(ebp+0xc) %eax) # => eax +12723 3d/compare-eax-and 0/imm32/false +12724 # assume: true = 1, so no need to mask with 0x000000ff +12725 0f 94/set-if-= %al +12726 $will-not-write-some-register?:end: +12727 # . epilogue +12728 89/<- %esp 5/r32/ebp +12729 5d/pop-to-ebp +12730 c3/return +12731 +12732 # return fn output with matching register +12733 # always returns false if 'reg' is null +12734 find-register: # fn: (addr function), reg: (addr array byte) -> result/eax: (addr var) +12735 # . prologue +12736 55/push-ebp +12737 89/<- %ebp 4/r32/esp +12738 # . save registers +12739 51/push-ecx +12740 # var curr/ecx: (addr list var) = lookup(fn->outputs) +12741 8b/-> *(ebp+8) 1/r32/ecx +12742 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax +12743 89/<- %ecx 0/r32/eax +12744 { +12745 $find-register:loop: +12746 # if (curr == 0) break +12747 81 7/subop/compare %ecx 0/imm32 +12748 74/jump-if-= break/disp8 +12749 # eax = curr->value->register +12750 (lookup *ecx *(ecx+4)) # List-value List-value => eax +12751 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +12752 # if (eax == reg) return curr->value +12753 $find-register:compare: +12754 (string-equal? *(ebp+0xc) %eax) # => eax +12755 { +12756 3d/compare-eax-and 0/imm32/false +12757 74/jump-if-= break/disp8 +12758 $find-register:found: +12759 (lookup *ecx *(ecx+4)) # List-value List-value => eax +12760 eb/jump $find-register:end/disp8 +12761 } +12762 # curr = lookup(curr->next) +12763 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +12764 89/<- %ecx 0/r32/eax +12765 # +12766 eb/jump loop/disp8 +12767 } +12768 $find-register:end: +12769 # . restore registers +12770 59/pop-to-ecx +12771 # . epilogue +12772 89/<- %esp 5/r32/ebp +12773 5d/pop-to-ebp +12774 c3/return +12775 +12776 assigns-in-stmts?: # stmts: (addr list stmt), v: (addr var) -> result/eax: boolean +12777 # . prologue +12778 55/push-ebp +12779 89/<- %ebp 4/r32/esp +12780 # . save registers +12781 51/push-ecx +12782 # var curr/ecx: (addr list stmt) = stmts +12783 8b/-> *(ebp+8) 1/r32/ecx +12784 { +12785 # if (curr == 0) break +12786 81 7/subop/compare %ecx 0/imm32 +12787 74/jump-if-= break/disp8 +12788 # if assigns-in-stmt?(curr->value, v) return true +12789 (lookup *ecx *(ecx+4)) # List-value List-value => eax +12790 (assigns-in-stmt? %eax *(ebp+0xc)) # => eax +12791 3d/compare-eax-and 0/imm32/false +12792 75/jump-if-!= break/disp8 +12793 # curr = lookup(curr->next) +12794 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +12795 89/<- %ecx 0/r32/eax +12796 # +12797 eb/jump loop/disp8 +12798 } +12799 $assigns-in-stmts?:end: +12800 # . restore registers +12801 59/pop-to-ecx +12802 # . epilogue +12803 89/<- %esp 5/r32/ebp +12804 5d/pop-to-ebp +12805 c3/return +12806 +12807 assigns-in-stmt?: # stmt: (addr stmt), v: (addr var) -> result/eax: boolean +12808 # . prologue +12809 55/push-ebp +12810 89/<- %ebp 4/r32/esp +12811 # . save registers +12812 51/push-ecx +12813 # ecx = stmt +12814 8b/-> *(ebp+8) 1/r32/ecx +12815 # if stmt is a stmt1, return assigns-in-stmt-vars?(stmt->outputs, v) +12816 { +12817 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag +12818 75/jump-if-!= break/disp8 +12819 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +12820 (assigns-in-stmt-vars? %eax *(ebp+0xc)) # => eax +12821 eb/jump $assigns-in-stmt?:end/disp8 +12822 } +12823 # if stmt is a block, return assigns-in-stmts?(stmt->stmts, v) +12824 { +12825 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag +12826 75/jump-if-!= break/disp8 +12827 (lookup *(ecx+4) *(ecx+8)) # Block-stmts Block-stmts => eax +12828 (assigns-in-stmts? %eax *(ebp+0xc)) # => eax +12829 eb/jump $assigns-in-stmt?:end/disp8 +12830 } +12831 # otherwise return false +12832 b8/copy 0/imm32/false +12833 $assigns-in-stmt?:end: +12834 # . restore registers +12835 59/pop-to-ecx +12836 # . epilogue +12837 89/<- %esp 5/r32/ebp +12838 5d/pop-to-ebp +12839 c3/return +12840 +12841 assigns-in-stmt-vars?: # stmt-var: (addr stmt-var), v: (addr var) -> result/eax: boolean +12842 # . prologue +12843 55/push-ebp +12844 89/<- %ebp 4/r32/esp +12845 # . save registers +12846 51/push-ecx +12847 # var curr/ecx: (addr stmt-var) = stmt-var +12848 8b/-> *(ebp+8) 1/r32/ecx +12849 { +12850 # if (curr == 0) break +12851 81 7/subop/compare %ecx 0/imm32 +12852 74/jump-if-= break/disp8 +12853 # eax = lookup(curr->value) +12854 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +12855 # if (eax == v && curr->is-deref? == false) return true +12856 { +12857 39/compare *(ebp+0xc) 0/r32/eax +12858 75/jump-if-!= break/disp8 +12859 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +12860 75/jump-if-!= break/disp8 +12861 b8/copy-to-eax 1/imm32/true +12862 eb/jump $assigns-in-stmt-vars?:end/disp8 +12863 } +12864 # curr = lookup(curr->next) +12865 (lookup *(ecx+8) *(ecx+0xc)) # Stmt-var-next Stmt-var-next => eax +12866 89/<- %ecx 0/r32/eax +12867 # +12868 eb/jump loop/disp8 +12869 } +12870 $assigns-in-stmt-vars?:end: +12871 # . restore registers +12872 59/pop-to-ecx +12873 # . epilogue +12874 89/<- %esp 5/r32/ebp +12875 5d/pop-to-ebp +12876 c3/return +12877 +12878 # is there a var before 'v' with the same block-depth and register on the 'vars' stack? +12879 # v is guaranteed to be within vars +12880 # 'start' is provided as an optimization, a pointer within vars +12881 # *start == v +12882 same-register-spilled-before?: # v: (addr var), vars: (addr stack (handle var)), start: (addr var) -> result/eax: boolean +12883 # . prologue +12884 55/push-ebp +12885 89/<- %ebp 4/r32/esp +12886 # . save registers +12887 51/push-ecx +12888 52/push-edx +12889 53/push-ebx +12890 56/push-esi +12891 57/push-edi +12892 # ecx = v +12893 8b/-> *(ebp+8) 1/r32/ecx +12894 # var reg/edx: (addr array byte) = lookup(v->register) +12895 (lookup *(ecx+0x18) *(ecx+0x1c)) # Var-register Var-register => eax +12896 89/<- %edx 0/r32/eax +12897 # var depth/ebx: int = v->block-depth +12898 8b/-> *(ecx+0x10) 3/r32/ebx # Var-block-depth +12899 # var min/ecx: (addr handle var) = vars->data +12900 8b/-> *(ebp+0xc) 1/r32/ecx +12901 81 0/subop/add %ecx 8/imm32 +12902 # TODO: check that start >= min and start < &vars->data[top] +12903 # TODO: check that *start == v +12904 # var curr/esi: (addr handle var) = start +12905 8b/-> *(ebp+0x10) 6/r32/esi +12906 # curr -= 8 +12907 81 5/subop/subtract %esi 8/imm32 +12908 { +12909 $same-register-spilled-before?:loop: +12910 # if (curr < min) break +12911 39/compare %esi 1/r32/ecx +12912 0f 82/jump-if-addr< break/disp32 +12913 # var x/eax: (addr var) = lookup(*curr) +12914 (lookup *esi *(esi+4)) # => eax +12915 # if (x->block-depth < depth) break +12916 39/compare *(eax+0x10) 3/r32/ebx # Var-block-depth +12917 0f 8c/jump-if-< break/disp32 +12918 # if (x->register == 0) continue +12919 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +12920 74/jump-if-= $same-register-spilled-before?:continue/disp8 +12921 # if (x->register == reg) return true +12922 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +12923 (string-equal? %eax %edx) # => eax +12924 3d/compare-eax-and 0/imm32/false +12925 b8/copy-to-eax 1/imm32/true +12926 75/jump-if-!= $same-register-spilled-before?:end/disp8 +12927 $same-register-spilled-before?:continue: +12928 # curr -= 8 +12929 81 5/subop/subtract %esi 8/imm32 +12930 e9/jump loop/disp32 +12931 } +12932 $same-register-spilled-before?:false: +12933 b8/copy-to-eax 0/imm32/false +12934 $same-register-spilled-before?:end: +12935 # . restore registers +12936 5f/pop-to-edi +12937 5e/pop-to-esi +12938 5b/pop-to-ebx +12939 5a/pop-to-edx +12940 59/pop-to-ecx +12941 # . epilogue +12942 89/<- %esp 5/r32/ebp +12943 5d/pop-to-ebp +12944 c3/return +12945 +12946 # Clean up global state for 'vars' until some block depth (inclusive). +12947 # +12948 # This would be a simple series of pops, if it wasn't for fn outputs, which +12949 # can occur anywhere in the stack. +12950 # So we have to _compact_ the entire array underlying the stack. +12951 # +12952 # We want to allow a fn output register to be written to by locals before the +12953 # output is set. +12954 # So fn outputs can't just be pushed at the start of the function. +12955 # +12956 # We want to allow other locals to shadow a fn output register after the +12957 # output is set. +12958 # So the output can't just always override anything in the stack. Sequence matters. +12959 clean-up-blocks: # vars: (addr stack live-var), until-block-depth: int, fn: (addr function) +12960 # pseudocode: +12961 # to = vars->top (which points outside the stack) +12962 # while true +12963 # if to <= 0 +12964 # break +12965 # var v = vars->data[to-1] +12966 # if v.depth < until and !in-function-outputs?(fn, v) +12967 # break +12968 # --to +12969 # from = to +12970 # while true +12971 # if from >= vars->top +12972 # break +12973 # assert(from >= to) +12974 # v = vars->data[from] +12975 # if in-function-outputs?(fn, v) +12976 # if from > to +12977 # vars->data[to] = vars->data[from] +12978 # ++to +12979 # ++from +12980 # vars->top = to +12981 # +12982 # . prologue +12983 55/push-ebp +12984 89/<- %ebp 4/r32/esp +12985 # . save registers +12986 50/push-eax +12987 52/push-edx +12988 53/push-ebx +12989 56/push-esi +12990 57/push-edi +12991 # ebx = vars +12992 8b/-> *(ebp+8) 3/r32/ebx +12993 # edx = until-block-depth +12994 8b/-> *(ebp+0xc) 2/r32/edx +12995 $clean-up-blocks:phase1: +12996 # var to/edi: int = vars->top +12997 8b/-> *ebx 7/r32/edi +12998 { +12999 $clean-up-blocks:loop1: +13000 # if (to <= 0) break +13001 81 7/subop/compare %edi 0/imm32 +13002 7e/jump-if-<= break/disp8 +13003 # var v/eax: (addr var) = lookup(vars->data[to-1]->var) +13004 8d/copy-address *(ebx+edi-4) 0/r32/eax # vars + 8 + to - 12 +13005 (lookup *eax *(eax+4)) # => eax +13006 # if (v->block-depth >= until-block-depth) continue +13007 39/compare *(eax+0x10) 2/r32/edx # Var-block-depth +13008 { +13009 7d/jump-if->= break/disp8 +13010 # if (!in-function-outputs?(fn, v)) break +13011 (in-function-outputs? *(ebp+0x10) %eax) # => eax +13012 3d/compare-eax-and 0/imm32/false +13013 74/jump-if-= $clean-up-blocks:phase2/disp8 +13014 } +13015 $clean-up-blocks:loop1-continue: +13016 # --to +13017 81 5/subop/subtract %edi 0xc/imm32 +13018 # +13019 eb/jump loop/disp8 +13020 } +13021 $clean-up-blocks:phase2: +13022 # var from/esi: int = to +13023 89/<- %esi 7/r32/edi +13024 { +13025 $clean-up-blocks:loop2: +13026 # if (from >= vars->top) break +13027 3b/compare 6/r32/esi *ebx +13028 7d/jump-if->= break/disp8 +13029 # var v/eax: (addr var) = lookup(vars->data[from]->var) +13030 8d/copy-address *(ebx+esi+8) 0/r32/eax +13031 (lookup *eax *(eax+4)) # => eax +13032 # if !in-function-outputs?(fn, v) continue +13033 (in-function-outputs? *(ebp+0x10) %eax) # => eax +13034 3d/compare-eax-and 0/imm32/false +13035 74/jump-if-= $clean-up-blocks:loop2-continue/disp8 +13036 # invariant: from >= to +13037 # if (from > to) vars->data[to] = vars->data[from] +13038 { +13039 39/compare %esi 7/r32/edi +13040 7e/jump-if-<= break/disp8 +13041 56/push-esi +13042 57/push-edi +13043 # . var from/esi: (addr byte) = &vars->data[from] +13044 8d/copy-address *(ebx+esi+8) 6/r32/esi +13045 # . var to/edi: (addr byte) = &vars->data[to] +13046 8d/copy-address *(ebx+edi+8) 7/r32/edi +13047 # . +13048 8b/-> *esi 0/r32/eax +13049 89/<- *edi 0/r32/eax +13050 8b/-> *(esi+4) 0/r32/eax +13051 89/<- *(edi+4) 0/r32/eax +13052 8b/-> *(esi+8) 0/r32/eax +13053 89/<- *(edi+8) 0/r32/eax +13054 5f/pop-to-edi +13055 5e/pop-to-esi +13056 } +13057 # ++to +13058 81 0/subop/add %edi 0xc/imm32 +13059 $clean-up-blocks:loop2-continue: +13060 # ++from +13061 81 0/subop/add %esi 0xc/imm32 +13062 # +13063 eb/jump loop/disp8 +13064 } +13065 89/<- *ebx 7/r32/edi +13066 $clean-up-blocks:end: +13067 # . restore registers +13068 5f/pop-to-edi +13069 5e/pop-to-esi +13070 5b/pop-to-ebx +13071 5a/pop-to-edx +13072 58/pop-to-eax +13073 # . epilogue +13074 89/<- %esp 5/r32/ebp +13075 5d/pop-to-ebp +13076 c3/return +13077 +13078 in-function-outputs?: # fn: (addr function), target: (addr var) -> result/eax: boolean +13079 # . prologue +13080 55/push-ebp +13081 89/<- %ebp 4/r32/esp +13082 # . save registers +13083 51/push-ecx +13084 # var curr/ecx: (addr list var) = lookup(fn->outputs) +13085 8b/-> *(ebp+8) 1/r32/ecx +13086 (lookup *(ecx+0x10) *(ecx+0x14)) # Function-outputs Function-outputs => eax +13087 89/<- %ecx 0/r32/eax +13088 # while curr != null +13089 { +13090 81 7/subop/compare %ecx 0/imm32 +13091 74/jump-if-= break/disp8 +13092 # var v/eax: (addr var) = lookup(curr->value) +13093 (lookup *ecx *(ecx+4)) # List-value List-value => eax +13094 # if (v == target) return true +13095 39/compare *(ebp+0xc) 0/r32/eax +13096 b8/copy-to-eax 1/imm32/true +13097 74/jump-if-= $in-function-outputs?:end/disp8 +13098 # curr = curr->next +13099 (lookup *(ecx+8) *(ecx+0xc)) # List-next List-next => eax +13100 89/<- %ecx 0/r32/eax +13101 # +13102 eb/jump loop/disp8 +13103 } +13104 b8/copy-to-eax 0/imm32 +13105 $in-function-outputs?:end: +13106 # . restore registers +13107 59/pop-to-ecx +13108 # . epilogue +13109 89/<- %esp 5/r32/ebp +13110 5d/pop-to-ebp +13111 c3/return +13112 +13113 emit-subx-var-def: # out: (addr buffered-file), stmt: (addr stmt) +13114 # . prologue +13115 55/push-ebp +13116 89/<- %ebp 4/r32/esp +13117 # . save registers +13118 50/push-eax +13119 51/push-ecx +13120 52/push-edx +13121 # eax = stmt +13122 8b/-> *(ebp+0xc) 0/r32/eax +13123 # var v/ecx: (addr var) +13124 (lookup *(eax+4) *(eax+8)) # Vardef-var Vardef-var => eax +13125 89/<- %ecx 0/r32/eax +13126 # v->block-depth = *Curr-block-depth +13127 8b/-> *Curr-block-depth 0/r32/eax +13128 89/<- *(ecx+0x10) 0/r32/eax # Var-block-depth +13129 # var n/edx: int = size-of(stmt->var) +13130 (size-of %ecx) # => eax +13131 89/<- %edx 0/r32/eax +13132 # *Curr-local-stack-offset -= n +13133 29/subtract-from *Curr-local-stack-offset 2/r32/edx +13134 # v->offset = *Curr-local-stack-offset +13135 8b/-> *Curr-local-stack-offset 0/r32/eax +13136 89/<- *(ecx+0x14) 0/r32/eax # Var-offset +13137 # if v is an array, do something special +13138 { +13139 (lookup *(ecx+8) *(ecx+0xc)) # Var-type Var-type => eax +13140 (is-mu-array? %eax) # => eax +13141 3d/compare-eax-and 0/imm32/false +13142 0f 84/jump-if-= break/disp32 +13143 # var array-size-without-size/edx: int = n-4 +13144 81 5/subop/subtract %edx 4/imm32 +13145 (emit-indent *(ebp+8) *Curr-block-depth) +13146 (write-buffered *(ebp+8) "(push-n-zero-bytes ") +13147 (print-int32-buffered *(ebp+8) %edx) +13148 (write-buffered *(ebp+8) ")\n") +13149 (emit-indent *(ebp+8) *Curr-block-depth) +13150 (write-buffered *(ebp+8) "68/push ") +13151 (print-int32-buffered *(ebp+8) %edx) +13152 (write-buffered *(ebp+8) "/imm32\n") +13153 eb/jump $emit-subx-var-def:end/disp8 +13154 } +13155 # while n > 0 +13156 { +13157 81 7/subop/compare %edx 0/imm32 +13158 7e/jump-if-<= break/disp8 +13159 (emit-indent *(ebp+8) *Curr-block-depth) +13160 (write-buffered *(ebp+8) "68/push 0/imm32\n") +13161 # n -= 4 +13162 81 5/subop/subtract %edx 4/imm32 +13163 # +13164 eb/jump loop/disp8 +13165 } +13166 $emit-subx-var-def:end: +13167 # . restore registers +13168 5a/pop-to-edx +13169 59/pop-to-ecx +13170 58/pop-to-eax +13171 # . epilogue +13172 89/<- %esp 5/r32/ebp +13173 5d/pop-to-ebp +13174 c3/return +13175 +13176 emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) +13177 # . prologue +13178 55/push-ebp +13179 89/<- %ebp 4/r32/esp +13180 # . save registers +13181 50/push-eax +13182 51/push-ecx +13183 # - some special-case primitives that don't actually use the 'primitives' data structure +13184 # var op/ecx: (addr array byte) = lookup(stmt->operation) +13185 8b/-> *(ebp+0xc) 1/r32/ecx +13186 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +13187 89/<- %ecx 0/r32/eax +13188 # array size +13189 { +13190 # if (!string-equal?(stmt->operation, "length")) break +13191 (string-equal? %ecx "length") # => eax +13192 3d/compare-eax-and 0/imm32 +13193 0f 84/jump-if-= break/disp32 +13194 (translate-mu-length-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +13195 e9/jump $emit-subx-stmt:end/disp32 +13196 } +13197 # index into array +13198 { +13199 # if (!string-equal?(stmt->operation, "index")) break +13200 (string-equal? %ecx "index") # => eax +13201 3d/compare-eax-and 0/imm32 +13202 0f 84/jump-if-= break/disp32 +13203 (translate-mu-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +13204 e9/jump $emit-subx-stmt:end/disp32 +13205 } +13206 # compute-offset for index into array +13207 { +13208 # if (!string-equal?(stmt->operation, "compute-offset")) break +13209 (string-equal? %ecx "compute-offset") # => eax +13210 3d/compare-eax-and 0/imm32 +13211 0f 84/jump-if-= break/disp32 +13212 (translate-mu-compute-index-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) +13213 e9/jump $emit-subx-stmt:end/disp32 +13214 } +13215 # get field from record +13216 { +13217 # if (!string-equal?(stmt->operation, "get")) break +13218 (string-equal? %ecx "get") # => eax +13219 3d/compare-eax-and 0/imm32 +13220 0f 84/jump-if-= break/disp32 +13221 (translate-mu-get-stmt *(ebp+8) *(ebp+0xc)) +13222 e9/jump $emit-subx-stmt:end/disp32 +13223 } +13224 # - if stmt matches a primitive, emit it +13225 { +13226 $emit-subx-stmt:check-for-primitive: +13227 # var curr/eax: (addr primitive) +13228 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => eax +13229 3d/compare-eax-and 0/imm32 +13230 74/jump-if-= break/disp8 +13231 $emit-subx-stmt:primitive: +13232 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr +13233 e9/jump $emit-subx-stmt:end/disp32 +13234 } +13235 # - otherwise emit a call +13236 # TODO: type-checking +13237 $emit-subx-stmt:call: +13238 (emit-call *(ebp+8) *(ebp+0xc)) +13239 $emit-subx-stmt:end: +13240 # . restore registers +13241 59/pop-to-ecx +13242 58/pop-to-eax +13243 # . epilogue +13244 89/<- %esp 5/r32/ebp +13245 5d/pop-to-ebp +13246 c3/return +13247 +13248 translate-mu-length-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +13249 # . prologue +13250 55/push-ebp +13251 89/<- %ebp 4/r32/esp +13252 # . save registers +13253 50/push-eax +13254 51/push-ecx +13255 52/push-edx +13256 53/push-ebx +13257 56/push-esi +13258 # esi = stmt +13259 8b/-> *(ebp+0xc) 6/r32/esi +13260 # var base/ebx: (addr var) = stmt->inouts[0]->value +13261 (lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13262 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13263 89/<- %ebx 0/r32/eax +13264 # var elemsize/ecx: int = array-element-size(base) +13265 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +13266 89/<- %ecx 0/r32/eax +13267 # var outreg/edx: (addr array byte) = stmt->outputs[0]->value->register +13268 (lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13269 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13270 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +13271 89/<- %edx 0/r32/eax +13272 # if elemsize == 1 +13273 { +13274 81 7/subop/compare %ecx 1/imm32 +13275 75/jump-if-!= break/disp8 +13276 $translate-mu-length-stmt:size-1: +13277 (emit-save-size-to *(ebp+8) %ebx %edx) +13278 e9/jump $translate-mu-length-stmt:end/disp32 +13279 } +13280 # if elemsize is a power of 2 less than 256 +13281 { +13282 (power-of-2? %ecx *(ebp+0x10) *(ebp+0x14)) # => eax +13283 3d/compare-eax-and 0/imm32/false +13284 74/jump-if-= break/disp8 +13285 81 7/subop/compare %ecx 0xff/imm32 +13286 7f/jump-if-> break/disp8 +13287 $translate-mu-length-stmt:size-power-of-2: +13288 (emit-save-size-to *(ebp+8) %ebx %edx) +13289 (emit-divide-by-shift-right *(ebp+8) %edx %ecx) +13290 e9/jump $translate-mu-length-stmt:end/disp32 +13291 } +13292 # otherwise, the complex case +13293 # . emit register spills +13294 { +13295 $translate-mu-length-stmt:complex: +13296 (string-equal? %edx "eax") # => eax +13297 3d/compare-eax-and 0/imm32/false +13298 75/break-if-!= break/disp8 +13299 (emit-indent *(ebp+8) *Curr-block-depth) +13300 (write-buffered *(ebp+8) "50/push-eax\n") +13301 } +13302 { +13303 (string-equal? %edx "ecx") # => eax +13304 3d/compare-eax-and 0/imm32/false +13305 75/break-if-!= break/disp8 +13306 (emit-indent *(ebp+8) *Curr-block-depth) +13307 (write-buffered *(ebp+8) "51/push-ecx\n") +13308 } +13309 { +13310 (string-equal? %edx "edx") # => eax +13311 3d/compare-eax-and 0/imm32/false +13312 75/break-if-!= break/disp8 +13313 (emit-indent *(ebp+8) *Curr-block-depth) +13314 (write-buffered *(ebp+8) "52/push-edx\n") +13315 } +13316 # . +13317 (emit-save-size-to *(ebp+8) %ebx "eax") +13318 (emit-indent *(ebp+8) *Curr-block-depth) +13319 (write-buffered *(ebp+8) "31/xor %edx 2/r32/edx\n") +13320 (emit-indent *(ebp+8) *Curr-block-depth) +13321 (write-buffered *(ebp+8) "b9/copy-to-ecx ") +13322 (print-int32-buffered *(ebp+8) %ecx) +13323 (write-buffered *(ebp+8) "/imm32\n") +13324 (emit-indent *(ebp+8) *Curr-block-depth) +13325 (write-buffered *(ebp+8) "f7 7/subop/idiv-eax-edx-by %ecx\n") +13326 { +13327 (string-equal? %edx "eax") # => eax +13328 3d/compare-eax-and 0/imm32/false +13329 75/break-if-!= break/disp8 +13330 (emit-indent *(ebp+8) *Curr-block-depth) +13331 (write-buffered *(ebp+8) "89/<- %") +13332 (write-buffered *(ebp+8) %edx) +13333 (write-buffered *(ebp+8) " 0/r32/eax\n") +13334 } +13335 # . emit register restores +13336 { +13337 (string-equal? %edx "edx") # => eax +13338 3d/compare-eax-and 0/imm32/false +13339 75/break-if-!= break/disp8 +13340 (emit-indent *(ebp+8) *Curr-block-depth) +13341 (write-buffered *(ebp+8) "5a/pop-to-edx\n") +13342 } +13343 { +13344 (string-equal? %edx "ecx") # => eax +13345 3d/compare-eax-and 0/imm32/false +13346 75/break-if-!= break/disp8 +13347 (emit-indent *(ebp+8) *Curr-block-depth) +13348 (write-buffered *(ebp+8) "59/pop-to-ecx\n") +13349 } +13350 { +13351 (string-equal? %edx "eax") # => eax +13352 3d/compare-eax-and 0/imm32/false +13353 75/break-if-!= break/disp8 +13354 (emit-indent *(ebp+8) *Curr-block-depth) +13355 (write-buffered *(ebp+8) "58/pop-to-eax\n") +13356 } +13357 $translate-mu-length-stmt:end: +13358 # . restore registers +13359 5e/pop-to-esi +13360 5b/pop-to-ebx +13361 5a/pop-to-edx +13362 59/pop-to-ecx +13363 58/pop-to-eax +13364 # . epilogue +13365 89/<- %esp 5/r32/ebp +13366 5d/pop-to-ebp +13367 c3/return +13368 +13369 array-element-size: # arr: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: int +13370 # . prologue +13371 55/push-ebp +13372 89/<- %ebp 4/r32/esp +13373 # +13374 (array-element-type-id *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax +13375 (size-of-type-id-as-array-element %eax) # => eax +13376 $array-element-size:end: +13377 # . epilogue +13378 89/<- %esp 5/r32/ebp +13379 5d/pop-to-ebp +13380 c3/return +13381 +13382 size-of-type-id-as-array-element: # t: type-id -> result/eax: int +13383 # . prologue +13384 55/push-ebp +13385 89/<- %ebp 4/r32/esp +13386 # eax = t +13387 8b/-> *(ebp+8) 0/r32/eax +13388 # if t is 'byte', size is 1 +13389 3d/compare-eax-and 8/imm32/byte +13390 { +13391 75/jump-if-!= break/disp8 +13392 b8/copy-to-eax 1/imm32 +13393 eb/jump $array-element-size:end/disp8 +13394 } +13395 # otherwise proceed as usual +13396 (size-of-type-id %eax) # => eax +13397 $size-of-type-id-as-array-element:end: +13398 # . epilogue +13399 89/<- %esp 5/r32/ebp +13400 5d/pop-to-ebp +13401 c3/return +13402 +13403 emit-save-size-to: # out: (addr buffered-file), base: (addr var), outreg: (addr array byte) +13404 # . prologue +13405 55/push-ebp +13406 89/<- %ebp 4/r32/esp +13407 # . save registers +13408 50/push-eax +13409 53/push-ebx +13410 # ebx = base +13411 8b/-> *(ebp+0xc) 3/r32/ebx +13412 (emit-indent *(ebp+8) *Curr-block-depth) +13413 (write-buffered *(ebp+8) "8b/-> *") +13414 # if base is an (addr array ...) in a register +13415 { +13416 81 7/subop/compare *(ebx+0x18)) 0/imm32 # Var-register +13417 74/jump-if-= break/disp8 +13418 $emit-save-size-to:emit-base-from-register: +13419 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +13420 (write-buffered *(ebp+8) %eax) +13421 eb/jump $emit-save-size-to:emit-output/disp8 +13422 } +13423 # otherwise if base is an (array ...) on the stack +13424 { +13425 81 7/subop/compare *(ebx+0x14)) 0/imm32 # Var-offset +13426 74/jump-if-= break/disp8 +13427 $emit-save-size-to:emit-base-from-stack: +13428 (write-buffered *(ebp+8) "(ebp+") +13429 (print-int32-buffered *(ebp+8) *(ebx+0x14)) # Var-offset +13430 (write-buffered *(ebp+8) ")") +13431 } +13432 $emit-save-size-to:emit-output: +13433 (write-buffered *(ebp+8) " ") +13434 (get Mu-registers *(ebp+0x10) 0xc "Mu-registers") # => eax +13435 (print-int32-buffered *(ebp+8) *eax) +13436 (write-buffered *(ebp+8) "/r32\n") +13437 $emit-save-size-to:end: +13438 # . restore registers +13439 5b/pop-to-ebx +13440 58/pop-to-eax +13441 # . epilogue +13442 89/<- %esp 5/r32/ebp +13443 5d/pop-to-ebp +13444 c3/return +13445 +13446 emit-divide-by-shift-right: # out: (addr buffered-file), reg: (addr array byte), size: int +13447 # . prologue +13448 55/push-ebp +13449 89/<- %ebp 4/r32/esp +13450 # . save registers +13451 50/push-eax +13452 # +13453 (emit-indent *(ebp+8) *Curr-block-depth) +13454 (write-buffered *(ebp+8) "c1/shift 5/subop/>> %") +13455 (write-buffered *(ebp+8) *(ebp+0xc)) +13456 (write-buffered *(ebp+8) Space) +13457 (num-shift-rights *(ebp+0x10)) # => eax +13458 (print-int32-buffered *(ebp+8) %eax) +13459 (write-buffered *(ebp+8) "/imm8\n") +13460 $emit-divide-by-shift-right:end: +13461 # . restore registers +13462 58/pop-to-eax +13463 # . epilogue +13464 89/<- %esp 5/r32/ebp +13465 5d/pop-to-ebp +13466 c3/return +13467 +13468 translate-mu-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +13469 # . prologue +13470 55/push-ebp +13471 89/<- %ebp 4/r32/esp +13472 # . save registers +13473 51/push-ecx +13474 # ecx = stmt +13475 8b/-> *(ebp+0xc) 1/r32/ecx +13476 # var base/ecx: (addr var) = stmt->inouts[0] +13477 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13478 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13479 89/<- %ecx 0/r32/eax +13480 # if (var->register) do one thing +13481 { +13482 81 7/subop/compare *(ecx+0x18) 0/imm32 # Var-register +13483 74/jump-if-= break/disp8 +13484 # TODO: ensure there's no dereference +13485 (translate-mu-index-stmt-with-array-in-register *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +13486 eb/jump $translate-mu-index-stmt:end/disp8 +13487 } +13488 # if (var->offset) do a different thing +13489 { +13490 81 7/subop/compare *(ecx+0x14) 0/imm32 # Var-offset +13491 74/jump-if-= break/disp8 +13492 # TODO: ensure there's no dereference +13493 (translate-mu-index-stmt-with-array-on-stack *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14)) +13494 eb/jump $translate-mu-index-stmt:end/disp8 +13495 } +13496 $translate-mu-index-stmt:end: +13497 # . restore registers +13498 59/pop-to-ecx +13499 # . epilogue +13500 89/<- %esp 5/r32/ebp +13501 5d/pop-to-ebp +13502 c3/return +13503 +13504 $translate-mu-index-stmt-with-array:error1: +13505 (write-buffered *(ebp+0x10) "couldn't translate an index instruction. second (index) input must either lie in a register or be a literal\n") +13506 (flush *(ebp+0x10)) +13507 (stop *(ebp+0x14) 1) +13508 # never gets here +13509 +13510 $translate-mu-index-stmt-with-array:error2: +13511 (write-buffered *(ebp+0x10) "couldn't translate an index instruction. second (index) input when in a register must be an int or offset\n") +13512 (flush *(ebp+0x10)) +13513 (stop *(ebp+0x14) 1) +13514 # never gets here +13515 +13516 translate-mu-index-stmt-with-array-in-register: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +13517 # . prologue +13518 55/push-ebp +13519 89/<- %ebp 4/r32/esp +13520 # . save registers +13521 50/push-eax +13522 51/push-ecx +13523 52/push-edx +13524 53/push-ebx +13525 # +13526 (emit-indent *(ebp+8) *Curr-block-depth) +13527 (write-buffered *(ebp+8) "8d/copy-address *(") +13528 # TODO: ensure inouts[0] is in a register and not dereferenced +13529 $translate-mu-index-stmt-with-array-in-register:emit-base: +13530 # ecx = stmt +13531 8b/-> *(ebp+0xc) 1/r32/ecx +13532 # var base/ebx: (addr var) = inouts[0] +13533 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13534 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13535 89/<- %ebx 0/r32/eax +13536 # print base->register " + " +13537 (lookup *(ebx+0x18) *(ebx+0x1c)) # Var-register Var-register => eax +13538 (write-buffered *(ebp+8) %eax) +13539 (write-buffered *(ebp+8) " + ") +13540 # var index/edx: (addr var) = inouts[1] +13541 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13542 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +13543 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13544 89/<- %edx 0/r32/eax +13545 # if index->register +13546 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register +13547 { +13548 0f 84/jump-if-= break/disp32 +13549 $translate-mu-index-stmt-with-array-in-register:emit-register-index: +13550 # if index is an int +13551 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +13552 (is-simple-mu-type? %eax 1) # int => eax +13553 3d/compare-eax-and 0/imm32/false +13554 { +13555 0f 84/jump-if-= break/disp32 +13556 $translate-mu-index-stmt-with-array-in-register:emit-int-register-index: +13557 # print index->register "<<" log2(array-element-size(base)) " + 4) " +13558 # . index->register "<<" +13559 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +13560 (write-buffered *(ebp+8) %eax) +13561 (write-buffered *(ebp+8) "<<") +13562 # . log2(array-element-size(base->type)) +13563 # TODO: ensure size is a power of 2 +13564 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +13565 (num-shift-rights %eax) # => eax +13566 (print-int32-buffered *(ebp+8) %eax) +13567 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-register-index-done/disp32 +13568 } +13569 # if index->type is any other atom, abort +13570 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +13571 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom +13572 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 +13573 # if index has type (offset ...) +13574 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax +13575 (is-simple-mu-type? %eax 7) # => eax +13576 3d/compare-eax-and 0/imm32/false +13577 { +13578 0f 84/jump-if-= break/disp32 +13579 # print index->register +13580 $translate-mu-index-stmt-with-array-in-register:emit-offset-register-index: +13581 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +13582 (write-buffered *(ebp+8) %eax) +13583 } +13584 $translate-mu-index-stmt-with-array-in-register:emit-register-index-done: +13585 (write-buffered *(ebp+8) " + 4) ") +13586 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 +13587 } +13588 # otherwise if index is a literal +13589 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +13590 (is-simple-mu-type? %eax 0) # => eax +13591 3d/compare-eax-and 0/imm32/false +13592 { +13593 0f 84/jump-if-= break/disp32 +13594 $translate-mu-index-stmt-with-array-in-register:emit-literal-index: +13595 # var index-value/edx: int = parse-hex-int(index->name) +13596 (lookup *edx *(edx+4)) # Var-name Var-name => eax +13597 (parse-hex-int %eax) # => eax +13598 89/<- %edx 0/r32/eax +13599 # offset = idx-value * array-element-size(base->type) +13600 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +13601 f7 4/subop/multiply-into-eax %edx # clobbers edx +13602 # offset += 4 for array size +13603 05/add-to-eax 4/imm32 +13604 # TODO: check edx for overflow +13605 # print offset +13606 (print-int32-buffered *(ebp+8) %eax) +13607 (write-buffered *(ebp+8) ") ") +13608 e9/jump $translate-mu-index-stmt-with-array-in-register:emit-output/disp32 +13609 } +13610 # otherwise abort +13611 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 +13612 $translate-mu-index-stmt-with-array-in-register:emit-output: +13613 # outputs[0] "/r32" +13614 8b/-> *(ebp+0xc) 1/r32/ecx +13615 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13616 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13617 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +13618 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +13619 (print-int32-buffered *(ebp+8) *eax) +13620 (write-buffered *(ebp+8) "/r32\n") +13621 $translate-mu-index-stmt-with-array-in-register:end: +13622 # . restore registers +13623 5b/pop-to-ebx +13624 5a/pop-to-edx +13625 59/pop-to-ecx +13626 58/pop-to-eax +13627 # . epilogue +13628 89/<- %esp 5/r32/ebp +13629 5d/pop-to-ebp +13630 c3/return +13631 +13632 translate-mu-index-stmt-with-array-on-stack: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +13633 # . prologue +13634 55/push-ebp +13635 89/<- %ebp 4/r32/esp +13636 # . save registers +13637 50/push-eax +13638 51/push-ecx +13639 52/push-edx +13640 53/push-ebx +13641 # +13642 (emit-indent *(ebp+8) *Curr-block-depth) +13643 (write-buffered *(ebp+8) "8d/copy-address *(ebp + ") +13644 # var curr/edx: (addr stmt-var) = lookup(stmt->inouts) +13645 8b/-> *(ebp+0xc) 0/r32/eax +13646 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13647 89/<- %edx 0/r32/eax +13648 # var base/ecx: (addr var) = lookup(curr->value) +13649 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13650 89/<- %ecx 0/r32/eax +13651 # var curr2/eax: (addr stmt-var) = lookup(curr->next) +13652 (lookup *(edx+8) *(edx+0xc)) # Stmt-var-next Stmt-var-next => eax +13653 # var index/edx: (handle var) = curr2->value +13654 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13655 89/<- %edx 0/r32/eax +13656 # if index->register +13657 81 7/subop/compare *(edx+0x18) 0/imm32 # Var-register +13658 { +13659 0f 84/jump-if-= break/disp32 +13660 $translate-mu-index-stmt-with-array-on-stack:emit-register-index: +13661 # if index is an int +13662 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +13663 (is-simple-mu-type? %eax 1) # int => eax +13664 3d/compare-eax-and 0/imm32/false +13665 { +13666 0f 84/jump-if-= break/disp32 +13667 $translate-mu-index-stmt-with-array-on-stack:emit-int-register-index: +13668 # print index->register "<<" log2(array-element-size(base)) " + " base->offset+4 +13669 # . inouts[1]->register "<<" +13670 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +13671 (write-buffered *(ebp+8) %eax) +13672 (write-buffered *(ebp+8) "<<") +13673 # . log2(array-element-size(base)) +13674 # TODO: ensure size is a power of 2 +13675 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax +13676 (num-shift-rights %eax) # => eax +13677 (print-int32-buffered *(ebp+8) %eax) +13678 # +13679 (write-buffered *(ebp+8) " + ") +13680 # +13681 8b/-> *(ecx+0x14) 0/r32/eax # Var-offset +13682 05/add-to-eax 4/imm32 # for array length +13683 (print-int32-buffered *(ebp+8) %eax) +13684 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done/disp32 +13685 } +13686 # if index->type is any other atom, abort +13687 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +13688 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom +13689 0f 85/jump-if-!= $translate-mu-index-stmt-with-array:error2/disp32 +13690 # if index has type (offset ...) +13691 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax +13692 (is-simple-mu-type? %eax 7) # => eax +13693 3d/compare-eax-and 0/imm32/false +13694 { +13695 0f 84/jump-if-= break/disp32 +13696 # print index->register +13697 $translate-mu-index-stmt-with-array-on-stack:emit-offset-register-index: +13698 (lookup *(edx+0x18) *(edx+0x1c)) # Var-register Var-register => eax +13699 (write-buffered *(ebp+8) %eax) +13700 } +13701 $translate-mu-index-stmt-with-array-on-stack:emit-register-index-done: +13702 (write-buffered *(ebp+8) ") ") +13703 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 +13704 } +13705 # otherwise if index is a literal +13706 (lookup *(edx+8) *(edx+0xc)) # Var-type Var-type => eax +13707 (is-simple-mu-type? %eax 0) # => eax +13708 3d/compare-eax-and 0/imm32/false +13709 { +13710 0f 84/jump-if-= break/disp32 +13711 $translate-mu-index-stmt-with-array-on-stack:emit-literal-index: +13712 # var idx-value/edx: int = parse-hex-int(index->name) +13713 (lookup *edx *(edx+4)) # Var-name Var-name => eax +13714 (parse-hex-int %eax) # Var-name => eax +13715 89/<- %edx 0/r32/eax +13716 # offset = idx-value * array-element-size(base) +13717 (array-element-size %ecx *(ebp+0x10) *(ebp+0x14)) # => eax +13718 f7 4/subop/multiply-into-eax %edx # clobbers edx +13719 # offset += base->offset +13720 03/add *(ecx+0x14) 0/r32/eax # Var-offset +13721 # offset += 4 for array size +13722 05/add-to-eax 4/imm32 +13723 # TODO: check edx for overflow +13724 # print offset +13725 (print-int32-buffered *(ebp+8) %eax) +13726 (write-buffered *(ebp+8) ") ") +13727 e9/jump $translate-mu-index-stmt-with-array-on-stack:emit-output/disp32 +13728 } +13729 # otherwise abort +13730 e9/jump $translate-mu-index-stmt-with-array:error1/disp32 +13731 $translate-mu-index-stmt-with-array-on-stack:emit-output: +13732 # outputs[0] "/r32" +13733 8b/-> *(ebp+0xc) 0/r32/eax +13734 (lookup *(eax+0x14) *(eax+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13735 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13736 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +13737 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +13738 (print-int32-buffered *(ebp+8) *eax) +13739 (write-buffered *(ebp+8) "/r32\n") +13740 $translate-mu-index-stmt-with-array-on-stack:end: +13741 # . restore registers +13742 5b/pop-to-ebx +13743 5a/pop-to-edx +13744 59/pop-to-ecx +13745 58/pop-to-eax +13746 # . epilogue +13747 89/<- %esp 5/r32/ebp +13748 5d/pop-to-ebp +13749 c3/return +13750 +13751 translate-mu-compute-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +13752 # . prologue +13753 55/push-ebp +13754 89/<- %ebp 4/r32/esp +13755 # . save registers +13756 50/push-eax +13757 51/push-ecx +13758 52/push-edx +13759 53/push-ebx +13760 # +13761 (emit-indent *(ebp+8) *Curr-block-depth) +13762 (write-buffered *(ebp+8) "69/multiply") +13763 # ecx = stmt +13764 8b/-> *(ebp+0xc) 1/r32/ecx +13765 # var first-inout/ebx: (addr stmt-var) = stmt->inouts[0] +13766 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13767 89/<- %ebx 0/r32/eax +13768 $translate-mu-compute-index-stmt:emit-index: +13769 (lookup *(ebx+8) *(ebx+0xc)) # Stmt-var-next Stmt-var-next => eax +13770 (emit-subx-var-as-rm32 *(ebp+8) %eax) +13771 (write-buffered *(ebp+8) Space) +13772 $translate-mu-compute-index-stmt:emit-elem-size: +13773 # var base/ebx: (addr var) +13774 (lookup *ebx *(ebx+4)) # Stmt-var-value Stmt-var-value => eax +13775 89/<- %ebx 0/r32/eax +13776 # print array-element-size(base) +13777 (array-element-size %ebx *(ebp+0x10) *(ebp+0x14)) # => eax +13778 (print-int32-buffered *(ebp+8) %eax) +13779 (write-buffered *(ebp+8) "/imm32 ") +13780 $translate-mu-compute-index-stmt:emit-output: +13781 # outputs[0] "/r32" +13782 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13783 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13784 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +13785 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +13786 (print-int32-buffered *(ebp+8) *eax) +13787 (write-buffered *(ebp+8) "/r32\n") +13788 $translate-mu-compute-index-stmt:end: +13789 # . restore registers +13790 5b/pop-to-ebx +13791 5a/pop-to-edx +13792 59/pop-to-ecx +13793 58/pop-to-eax +13794 # . epilogue +13795 89/<- %esp 5/r32/ebp +13796 5d/pop-to-ebp +13797 c3/return +13798 +13799 translate-mu-get-stmt: # out: (addr buffered-file), stmt: (addr stmt) +13800 # . prologue +13801 55/push-ebp +13802 89/<- %ebp 4/r32/esp +13803 # . save registers +13804 50/push-eax +13805 51/push-ecx +13806 52/push-edx +13807 # +13808 (emit-indent *(ebp+8) *Curr-block-depth) +13809 (write-buffered *(ebp+8) "8d/copy-address ") +13810 # ecx = stmt +13811 8b/-> *(ebp+0xc) 1/r32/ecx +13812 # var offset/edx: int = get offset of stmt +13813 (mu-get-offset %ecx) # => eax +13814 89/<- %edx 0/r32/eax +13815 # var base/eax: (addr var) = stmt->inouts->value +13816 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +13817 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13818 # if base is in a register +13819 81 7/subop/compare *(eax+0x18) 0/imm32 # Var-register +13820 { +13821 0f 84/jump-if-= break/disp32 +13822 $translate-mu-get-stmt:emit-register-input: +13823 # emit "*(" base->register " + " offset ") " +13824 (write-buffered *(ebp+8) "*(") +13825 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +13826 (write-buffered *(ebp+8) %eax) +13827 (write-buffered *(ebp+8) " + ") +13828 (print-int32-buffered *(ebp+8) %edx) +13829 (write-buffered *(ebp+8) ") ") +13830 e9/jump $translate-mu-get-stmt:emit-output/disp32 +13831 } +13832 # otherwise base is on the stack +13833 { +13834 $translate-mu-get-stmt:emit-stack-input: +13835 # emit "*(ebp + " inouts[0]->stack-offset + offset ") " +13836 (write-buffered *(ebp+8) "*(ebp+") +13837 03/add *(eax+0x14) 2/r32/edx # Var-offset +13838 (print-int32-buffered *(ebp+8) %edx) +13839 (write-buffered *(ebp+8) ") ") +13840 eb/jump $translate-mu-get-stmt:emit-output/disp8 +13841 } +13842 $translate-mu-get-stmt:emit-output: +13843 # var output/eax: (addr var) = stmt->outputs->value +13844 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +13845 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +13846 # emit offset->register "/r32" +13847 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +13848 (get Mu-registers %eax 0xc "Mu-registers") # => eax: (addr int) +13849 (print-int32-buffered *(ebp+8) *eax) +13850 (write-buffered *(ebp+8) "/r32\n") +13851 $translate-mu-get-stmt:end: +13852 # . restore registers +13853 5a/pop-to-edx +13854 59/pop-to-ecx +13855 58/pop-to-eax +13856 # . epilogue +13857 89/<- %esp 5/r32/ebp +13858 5d/pop-to-ebp +13859 c3/return +13860 +13861 array-element-type-id: # v: (addr var), err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: type-id +13862 # precondition: n is positive +13863 # . prologue +13864 55/push-ebp +13865 89/<- %ebp 4/r32/esp +13866 # +13867 8b/-> *(ebp+8) 0/r32/eax +13868 # var t/eax: (addr tree type-id) +13869 (lookup *(eax+8) *(eax+0xc)) # Var-type Var-type => eax +13870 # if t == 0 abort +13871 3d/compare-eax-with 0/imm32 +13872 0f 84/jump-if-== $array-element-type-id:error0/disp32 +13873 # if t->is-atom? abort +13874 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom +13875 0f 85/jump-if-!= $array-element-type-id:error1/disp32 +13876 # if (t->left == addr) t = t->right +13877 { +13878 50/push-eax +13879 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax +13880 (is-simple-mu-type? %eax 2) # addr => eax +13881 3d/compare-eax-with 0/imm32/false +13882 58/pop-to-eax +13883 74/jump-if-= break/disp8 +13884 $array-element-type-id:skip-addr: +13885 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax +13886 } +13887 # if t == 0 abort +13888 3d/compare-eax-with 0/imm32 +13889 0f 84/jump-if-= $array-element-type-id:error2/disp32 +13890 # if t->is-atom? abort +13891 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom +13892 0f 85/jump-if-!= $array-element-type-id:error2/disp32 +13893 # if t->left != array abort +13894 { +13895 50/push-eax +13896 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax +13897 (is-simple-mu-type? %eax 3) # array => eax +13898 3d/compare-eax-with 0/imm32/false +13899 58/pop-to-eax +13900 $array-element-type-id:no-array: +13901 0f 84/jump-if-= $array-element-type-id:error2/disp32 +13902 } +13903 $array-element-type-id:skip-array: +13904 # t = t->right +13905 (lookup *(eax+0xc) *(eax+0x10)) # Tree-right Tree-right => eax +13906 # if t == 0 abort +13907 3d/compare-eax-with 0/imm32 +13908 0f 84/jump-if-= $array-element-type-id:error2/disp32 +13909 # if t->is-atom? abort +13910 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom +13911 0f 85/jump-if-!= $array-element-type-id:error2/disp32 +13912 # return t->left->value +13913 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax +13914 8b/-> *(eax+4) 0/r32/eax # Tree-value +13915 $array-element-type-id:end: +13916 # . epilogue +13917 89/<- %esp 5/r32/ebp +13918 5d/pop-to-ebp +13919 c3/return +13920 +13921 $array-element-type-id:error0: +13922 (write-buffered *(ebp+0xc) "array-element-type-id: var '") +13923 50/push-eax +13924 8b/-> *(ebp+8) 0/r32/eax +13925 (lookup *eax *(eax+4)) # Var-name Var-name => eax +13926 (write-buffered *(ebp+0xc) %eax) +13927 58/pop-to-eax +13928 (write-buffered *(ebp+0xc) "' has no type\n") +13929 (flush *(ebp+0xc)) +13930 (stop *(ebp+0x10) 1) +13931 # never gets here +13932 +13933 $array-element-type-id:error1: +13934 (write-buffered *(ebp+0xc) "array-element-type-id: var '") +13935 50/push-eax +13936 8b/-> *(ebp+8) 0/r32/eax +13937 (lookup *eax *(eax+4)) # Var-name Var-name => eax +13938 (write-buffered *(ebp+0xc) %eax) +13939 58/pop-to-eax +13940 (write-buffered *(ebp+0xc) "' has atomic type ") +13941 (print-int32-buffered *(ebp+0xc) *(eax+4)) # Tree-value +13942 (write-buffered *(ebp+0xc) Newline) +13943 (flush *(ebp+0xc)) +13944 (stop *(ebp+0x10) 1) +13945 # never gets here +13946 +13947 $array-element-type-id:error2: +13948 (write-buffered *(ebp+0xc) "array-element-type-id: var '") +13949 50/push-eax +13950 8b/-> *(ebp+8) 0/r32/eax +13951 (lookup *eax *(eax+4)) # Var-name Var-name => eax +13952 (write-buffered *(ebp+0xc) %eax) +13953 58/pop-to-eax +13954 (write-buffered *(ebp+0xc) "' has non-array type\n") +13955 (flush *(ebp+0xc)) +13956 (stop *(ebp+0x10) 1) +13957 # never gets here +13958 +13959 power-of-2?: # n: int, err: (addr buffered-file), ed: (addr exit-descriptor) -> result/eax: boolean +13960 # precondition: n is positive +13961 # . prologue +13962 55/push-ebp +13963 89/<- %ebp 4/r32/esp +13964 # eax = n +13965 8b/-> *(ebp+8) 0/r32/eax +13966 # if (n < 0) abort +13967 3d/compare-eax-with 0/imm32 +13968 0f 8c/jump-if-< $power-of-2?:abort/disp32 +13969 # var tmp/eax: int = n-1 +13970 48/decrement-eax +13971 # var tmp2/eax: int = n & tmp +13972 23/and-> *(ebp+8) 0/r32/eax +13973 # return (tmp2 == 0) +13974 3d/compare-eax-and 0/imm32 +13975 0f 94/set-byte-if-= %al +13976 81 4/subop/and %eax 0xff/imm32 +13977 $power-of-2?:end: +13978 # . epilogue +13979 89/<- %esp 5/r32/ebp +13980 5d/pop-to-ebp +13981 c3/return +13982 +13983 $power-of-2?:abort: +13984 (write-buffered *(ebp+0xc) "power-of-2?: negative number\n") +13985 (flush *(ebp+0xc)) +13986 (stop *(ebp+0x10) 1) +13987 # never gets here +13988 +13989 num-shift-rights: # n: int -> result/eax: int +13990 # precondition: n is a positive power of 2 +13991 # . prologue +13992 55/push-ebp +13993 89/<- %ebp 4/r32/esp +13994 # . save registers +13995 51/push-ecx +13996 # var curr/ecx: int = n +13997 8b/-> *(ebp+8) 1/r32/ecx +13998 # result = 0 +13999 b8/copy-to-eax 0/imm32 +14000 { +14001 # if (curr <= 1) break +14002 81 7/subop/compare %ecx 1/imm32 +14003 7e/jump-if-<= break/disp8 +14004 40/increment-eax +14005 c1/shift 5/subop/arithmetic-right %ecx 1/imm8 +14006 eb/jump loop/disp8 +14007 } +14008 $num-shift-rights:end: +14009 # . restore registers +14010 59/pop-to-ecx +14011 # . epilogue +14012 89/<- %esp 5/r32/ebp +14013 5d/pop-to-ebp +14014 c3/return +14015 +14016 mu-get-offset: # stmt: (addr stmt) -> result/eax: int +14017 # . prologue +14018 55/push-ebp +14019 89/<- %ebp 4/r32/esp +14020 # var second-inout/eax: (addr stmt-var) = stmt->inouts->next +14021 8b/-> *(ebp+8) 0/r32/eax +14022 (lookup *(eax+0xc) *(eax+0x10)) # Stmt1-inouts Stmt1-inouts => eax +14023 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +14024 # var output-var/eax: (addr var) = second-inout->value +14025 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +14026 #? (write-buffered Stderr "mu-get-offset: ") +14027 #? (print-int32-buffered Stderr %eax) +14028 #? (write-buffered Stderr " name: ") +14029 #? 50/push-eax +14030 #? (lookup *eax *(eax+4)) # Var-name +14031 #? (write-buffered Stderr %eax) +14032 #? 58/pop-to-eax +14033 #? (write-buffered Stderr Newline) +14034 #? (flush Stderr) +14035 # return output-var->stack-offset +14036 8b/-> *(eax+0x14) 0/r32/eax # Var-offset +14037 #? (write-buffered Stderr "=> ") +14038 #? (print-int32-buffered Stderr %eax) +14039 #? (write-buffered Stderr Newline) +14040 #? (flush Stderr) +14041 $emit-get-offset:end: +14042 # . epilogue +14043 89/<- %esp 5/r32/ebp +14044 5d/pop-to-ebp +14045 c3/return +14046 +14047 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) +14048 # . prologue +14049 55/push-ebp +14050 89/<- %ebp 4/r32/esp +14051 # . save registers +14052 50/push-eax +14053 51/push-ecx +14054 56/push-esi +14055 # esi = block +14056 8b/-> *(ebp+0xc) 6/r32/esi +14057 # block->var->block-depth = *Curr-block-depth +14058 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax +14059 8b/-> *Curr-block-depth 1/r32/ecx +14060 89/<- *(eax+0x10) 1/r32/ecx # Var-block-depth +14061 # var stmts/eax: (addr list stmt) = lookup(block->statements) +14062 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax +14063 # +14064 { +14065 $emit-subx-block:check-empty: +14066 3d/compare-eax-and 0/imm32 +14067 0f 84/jump-if-= break/disp32 +14068 (emit-indent *(ebp+8) *Curr-block-depth) +14069 (write-buffered *(ebp+8) "{\n") +14070 # var v/ecx: (addr var) = lookup(block->var) +14071 (lookup *(esi+0xc) *(esi+0x10)) # Block-var Block-var => eax +14072 89/<- %ecx 0/r32/eax +14073 # +14074 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +14075 (write-buffered *(ebp+8) %eax) +14076 (write-buffered *(ebp+8) ":loop:\n") +14077 ff 0/subop/increment *Curr-block-depth +14078 (push *(ebp+0x10) *(esi+0xc)) # Block-var +14079 (push *(ebp+0x10) *(esi+0x10)) # Block-var +14080 (push *(ebp+0x10) 0) # false +14081 # emit block->statements +14082 (lookup *(esi+4) *(esi+8)) # Block-stmts Block-stmts => eax +14083 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c)) +14084 (pop *(ebp+0x10)) # => eax +14085 (pop *(ebp+0x10)) # => eax +14086 (pop *(ebp+0x10)) # => eax +14087 ff 1/subop/decrement *Curr-block-depth +14088 (emit-indent *(ebp+8) *Curr-block-depth) +14089 (write-buffered *(ebp+8) "}\n") +14090 (lookup *ecx *(ecx+4)) # Var-name Var-name => eax +14091 (write-buffered *(ebp+8) %eax) +14092 (write-buffered *(ebp+8) ":break:\n") +14093 } +14094 $emit-subx-block:end: +14095 # . restore registers +14096 5e/pop-to-esi +14097 59/pop-to-ecx +14098 58/pop-to-eax +14099 # . epilogue +14100 89/<- %esp 5/r32/ebp +14101 5d/pop-to-ebp +14102 c3/return +14103 +14104 # Primitives supported +14105 # See mu_instructions for a summary of this linked-list data structure. +14106 # +14107 # For each operation, put variants with hard-coded registers before flexible ones. +14108 # +14109 # Unfortunately, our restrictions on addresses require that various fields in +14110 # primitives be handles, which complicates these definitions. +14111 # - we need to insert dummy fields all over the place for fake alloc-ids +14112 # - we can't use our syntax sugar of quoted literals for string fields +14113 # +14114 # Fake alloc-ids are needed because our type definitions up top require +14115 # handles but it's clearer to statically allocate these long-lived objects. +14116 # Fake alloc-ids are perfectly safe, but they can't be reclaimed. +14117 # +14118 # Every 'object' below starts with a fake alloc-id. It may also contain other +14119 # fake alloc-ids for various handle fields. +14120 # +14121 # I think of objects starting with a fake alloc-id as having type 'payload'. +14122 # It's not really intended to be created dynamically; for that use `allocate` +14123 # as usual. +14124 # +14125 # Idea for a notation to simplify such definitions: +14126 # _Primitive-increment-eax: # (payload primitive) +14127 # 0x11/alloc-id:fake:payload +14128 # 0x11 @(0x11 "increment") # name +14129 # 0 0 # inouts +14130 # 0x11 @(0x11/payload +14131 # 0x11 @(0x11/payload # List-value +14132 # 0 0 # Var-name +14133 # 0x11 @(0x11 # Var-type +14134 # 1/is-atom +14135 # 1/value 0/unused # Tree-left +14136 # 0 0 # Tree-right +14137 # ) +14138 # 1 # block-depth +14139 # 0 # stack-offset +14140 # 0x11 @(0x11 "eax") # Var-register +14141 # ) +14142 # 0 0) # List-next +14143 # ... +14144 # _Primitive-increment-ecx/imm32/next +14145 # ... +14146 # Awfully complex and non-obvious. But also clearly signals there's something +14147 # to learn here, so may be worth trying. +14148 # +14149 # '@' is just an initial thought. Punctuation used so far in Mu: () * % # / " +14150 # +14151 # For now we'll continue to just use comments and manually ensure they stay up +14152 # to date. +14153 == data +14154 Primitives: # (addr primitive) +14155 # - increment/decrement +14156 _Primitive-increment-eax: # (addr primitive) +14157 # var/eax <- increment => 40/increment-eax +14158 0x11/imm32/alloc-id:fake +14159 _string-increment/imm32/name +14160 0/imm32/no-inouts +14161 0/imm32/no-inouts +14162 0x11/imm32/alloc-id:fake +14163 Single-int-var-in-eax/imm32/outputs +14164 0x11/imm32/alloc-id:fake +14165 _string_40_increment_eax/imm32/subx-name +14166 0/imm32/no-rm32 +14167 0/imm32/no-r32 +14168 0/imm32/no-imm32 +14169 0/imm32/no-disp32 +14170 0/imm32/output-is-write-only 14171 0x11/imm32/alloc-id:fake -14172 _string-loop-if-=/imm32/name -14173 0/imm32/no-inouts -14174 0/imm32/no-inouts -14175 0/imm32/no-outputs -14176 0/imm32/no-outputs -14177 0x11/imm32/alloc-id:fake -14178 _string_0f_84_jump_loop/imm32/subx-name -14179 0/imm32/no-rm32 -14180 0/imm32/no-r32 -14181 0/imm32/no-imm32 -14182 0/imm32/no-disp32 -14183 0/imm32/no-output -14184 0x11/imm32/alloc-id:fake -14185 _Primitive-loop-if-!=/imm32/next -14186 _Primitive-loop-if-!=: # (payload primitive) -14187 0x11/imm32/alloc-id:fake:payload -14188 0x11/imm32/alloc-id:fake -14189 _string-loop-if-!=/imm32/name -14190 0/imm32/no-inouts -14191 0/imm32/no-inouts -14192 0/imm32/no-outputs -14193 0/imm32/no-outputs +14172 _Primitive-increment-ecx/imm32/next +14173 _Primitive-increment-ecx: # (payload primitive) +14174 0x11/imm32/alloc-id:fake:payload +14175 # var/ecx <- increment => 41/increment-ecx +14176 0x11/imm32/alloc-id:fake +14177 _string-increment/imm32/name +14178 0/imm32/no-inouts +14179 0/imm32/no-inouts +14180 0x11/imm32/alloc-id:fake +14181 Single-int-var-in-ecx/imm32/outputs +14182 0x11/imm32/alloc-id:fake +14183 _string_41_increment_ecx/imm32/subx-name +14184 0/imm32/no-rm32 +14185 0/imm32/no-r32 +14186 0/imm32/no-imm32 +14187 0/imm32/no-disp32 +14188 0/imm32/output-is-write-only +14189 0x11/imm32/alloc-id:fake +14190 _Primitive-increment-edx/imm32/next +14191 _Primitive-increment-edx: # (payload primitive) +14192 0x11/imm32/alloc-id:fake:payload +14193 # var/edx <- increment => 42/increment-edx 14194 0x11/imm32/alloc-id:fake -14195 _string_0f_85_jump_loop/imm32/subx-name -14196 0/imm32/no-rm32 -14197 0/imm32/no-r32 -14198 0/imm32/no-imm32 -14199 0/imm32/no-disp32 -14200 0/imm32/no-output -14201 0x11/imm32/alloc-id:fake -14202 _Primitive-loop-if-addr<=/imm32/next -14203 _Primitive-loop-if-addr<=: # (payload primitive) -14204 0x11/imm32/alloc-id:fake:payload -14205 0x11/imm32/alloc-id:fake -14206 _string-loop-if-addr<=/imm32/name -14207 0/imm32/no-inouts -14208 0/imm32/no-inouts -14209 0/imm32/no-outputs -14210 0/imm32/no-outputs -14211 0x11/imm32/alloc-id:fake -14212 _string_0f_86_jump_loop/imm32/subx-name -14213 0/imm32/no-rm32 -14214 0/imm32/no-r32 -14215 0/imm32/no-imm32 -14216 0/imm32/no-disp32 -14217 0/imm32/no-output +14195 _string-increment/imm32/name +14196 0/imm32/no-inouts +14197 0/imm32/no-inouts +14198 0x11/imm32/alloc-id:fake +14199 Single-int-var-in-edx/imm32/outputs +14200 0x11/imm32/alloc-id:fake +14201 _string_42_increment_edx/imm32/subx-name +14202 0/imm32/no-rm32 +14203 0/imm32/no-r32 +14204 0/imm32/no-imm32 +14205 0/imm32/no-disp32 +14206 0/imm32/output-is-write-only +14207 0x11/imm32/alloc-id:fake +14208 _Primitive-increment-ebx/imm32/next +14209 _Primitive-increment-ebx: # (payload primitive) +14210 0x11/imm32/alloc-id:fake:payload +14211 # var/ebx <- increment => 43/increment-ebx +14212 0x11/imm32/alloc-id:fake +14213 _string-increment/imm32/name +14214 0/imm32/no-inouts +14215 0/imm32/no-inouts +14216 0x11/imm32/alloc-id:fake +14217 Single-int-var-in-ebx/imm32/outputs 14218 0x11/imm32/alloc-id:fake -14219 _Primitive-loop-if-addr>/imm32/next -14220 _Primitive-loop-if-addr>: # (payload primitive) -14221 0x11/imm32/alloc-id:fake:payload -14222 0x11/imm32/alloc-id:fake -14223 _string-loop-if-addr>/imm32/name -14224 0/imm32/no-inouts -14225 0/imm32/no-inouts -14226 0/imm32/no-outputs -14227 0/imm32/no-outputs -14228 0x11/imm32/alloc-id:fake -14229 _string_0f_87_jump_loop/imm32/subx-name -14230 0/imm32/no-rm32 -14231 0/imm32/no-r32 -14232 0/imm32/no-imm32 -14233 0/imm32/no-disp32 -14234 0/imm32/no-output -14235 0x11/imm32/alloc-id:fake -14236 _Primitive-loop-if-</imm32/next -14237 _Primitive-loop-if-<: # (payload primitive) -14238 0x11/imm32/alloc-id:fake:payload -14239 0x11/imm32/alloc-id:fake -14240 _string-loop-if-</imm32/name -14241 0/imm32/no-inouts -14242 0/imm32/no-inouts -14243 0/imm32/no-outputs -14244 0/imm32/no-outputs -14245 0x11/imm32/alloc-id:fake -14246 _string_0f_8c_jump_loop/imm32/subx-name -14247 0/imm32/no-rm32 -14248 0/imm32/no-r32 -14249 0/imm32/no-imm32 -14250 0/imm32/no-disp32 -14251 0/imm32/no-output +14219 _string_43_increment_ebx/imm32/subx-name +14220 0/imm32/no-rm32 +14221 0/imm32/no-r32 +14222 0/imm32/no-imm32 +14223 0/imm32/no-disp32 +14224 0/imm32/output-is-write-only +14225 0x11/imm32/alloc-id:fake +14226 _Primitive-increment-esi/imm32/next +14227 _Primitive-increment-esi: # (payload primitive) +14228 0x11/imm32/alloc-id:fake:payload +14229 # var/esi <- increment => 46/increment-esi +14230 0x11/imm32/alloc-id:fake +14231 _string-increment/imm32/name +14232 0/imm32/no-inouts +14233 0/imm32/no-inouts +14234 0x11/imm32/alloc-id:fake +14235 Single-int-var-in-esi/imm32/outputs +14236 0x11/imm32/alloc-id:fake +14237 _string_46_increment_esi/imm32/subx-name +14238 0/imm32/no-rm32 +14239 0/imm32/no-r32 +14240 0/imm32/no-imm32 +14241 0/imm32/no-disp32 +14242 0/imm32/output-is-write-only +14243 0x11/imm32/alloc-id:fake +14244 _Primitive-increment-edi/imm32/next +14245 _Primitive-increment-edi: # (payload primitive) +14246 0x11/imm32/alloc-id:fake:payload +14247 # var/edi <- increment => 47/increment-edi +14248 0x11/imm32/alloc-id:fake +14249 _string-increment/imm32/name +14250 0/imm32/no-inouts +14251 0/imm32/no-inouts 14252 0x11/imm32/alloc-id:fake -14253 _Primitive-loop-if->=/imm32/next -14254 _Primitive-loop-if->=: # (payload primitive) -14255 0x11/imm32/alloc-id:fake:payload -14256 0x11/imm32/alloc-id:fake -14257 _string-loop-if->=/imm32/name -14258 0/imm32/no-inouts -14259 0/imm32/no-inouts -14260 0/imm32/no-outputs -14261 0/imm32/no-outputs -14262 0x11/imm32/alloc-id:fake -14263 _string_0f_8d_jump_loop/imm32/subx-name -14264 0/imm32/no-rm32 -14265 0/imm32/no-r32 -14266 0/imm32/no-imm32 -14267 0/imm32/no-disp32 -14268 0/imm32/no-output -14269 0x11/imm32/alloc-id:fake -14270 _Primitive-loop-if-<=/imm32/next -14271 _Primitive-loop-if-<=: # (payload primitive) -14272 0x11/imm32/alloc-id:fake:payload -14273 0x11/imm32/alloc-id:fake -14274 _string-loop-if-<=/imm32/name -14275 0/imm32/no-inouts -14276 0/imm32/no-inouts -14277 0/imm32/no-outputs -14278 0/imm32/no-outputs +14253 Single-int-var-in-edi/imm32/outputs +14254 0x11/imm32/alloc-id:fake +14255 _string_47_increment_edi/imm32/subx-name +14256 0/imm32/no-rm32 +14257 0/imm32/no-r32 +14258 0/imm32/no-imm32 +14259 0/imm32/no-disp32 +14260 0/imm32/output-is-write-only +14261 0x11/imm32/alloc-id:fake +14262 _Primitive-decrement-eax/imm32/next +14263 _Primitive-decrement-eax: # (payload primitive) +14264 0x11/imm32/alloc-id:fake:payload +14265 # var/eax <- decrement => 48/decrement-eax +14266 0x11/imm32/alloc-id:fake +14267 _string-decrement/imm32/name +14268 0/imm32/no-inouts +14269 0/imm32/no-inouts +14270 0x11/imm32/alloc-id:fake +14271 Single-int-var-in-eax/imm32/outputs +14272 0x11/imm32/alloc-id:fake +14273 _string_48_decrement_eax/imm32/subx-name +14274 0/imm32/no-rm32 +14275 0/imm32/no-r32 +14276 0/imm32/no-imm32 +14277 0/imm32/no-disp32 +14278 0/imm32/output-is-write-only 14279 0x11/imm32/alloc-id:fake -14280 _string_0f_8e_jump_loop/imm32/subx-name -14281 0/imm32/no-rm32 -14282 0/imm32/no-r32 -14283 0/imm32/no-imm32 -14284 0/imm32/no-disp32 -14285 0/imm32/no-output -14286 0x11/imm32/alloc-id:fake -14287 _Primitive-loop-if->/imm32/next -14288 _Primitive-loop-if->: # (payload primitive) -14289 0x11/imm32/alloc-id:fake:payload +14280 _Primitive-decrement-ecx/imm32/next +14281 _Primitive-decrement-ecx: # (payload primitive) +14282 0x11/imm32/alloc-id:fake:payload +14283 # var/ecx <- decrement => 49/decrement-ecx +14284 0x11/imm32/alloc-id:fake +14285 _string-decrement/imm32/name +14286 0/imm32/no-inouts +14287 0/imm32/no-inouts +14288 0x11/imm32/alloc-id:fake +14289 Single-int-var-in-ecx/imm32/outputs 14290 0x11/imm32/alloc-id:fake -14291 _string-loop-if->/imm32/name -14292 0/imm32/no-inouts -14293 0/imm32/no-inouts -14294 0/imm32/no-outputs -14295 0/imm32/no-outputs -14296 0x11/imm32/alloc-id:fake -14297 _string_0f_8f_jump_loop/imm32/subx-name -14298 0/imm32/no-rm32 -14299 0/imm32/no-r32 -14300 0/imm32/no-imm32 -14301 0/imm32/no-disp32 -14302 0/imm32/no-output -14303 0x11/imm32/alloc-id:fake -14304 _Primitive-loop/imm32/next # we probably don't need an unconditional break -14305 _Primitive-loop: # (payload primitive) -14306 0x11/imm32/alloc-id:fake:payload -14307 0x11/imm32/alloc-id:fake -14308 _string-loop/imm32/name -14309 0/imm32/no-inouts -14310 0/imm32/no-inouts -14311 0/imm32/no-outputs -14312 0/imm32/no-outputs -14313 0x11/imm32/alloc-id:fake -14314 _string_e9_jump_loop/imm32/subx-name -14315 0/imm32/no-rm32 -14316 0/imm32/no-r32 -14317 0/imm32/no-imm32 -14318 0/imm32/no-disp32 -14319 0/imm32/no-output +14291 _string_49_decrement_ecx/imm32/subx-name +14292 0/imm32/no-rm32 +14293 0/imm32/no-r32 +14294 0/imm32/no-imm32 +14295 0/imm32/no-disp32 +14296 0/imm32/output-is-write-only +14297 0x11/imm32/alloc-id:fake +14298 _Primitive-decrement-edx/imm32/next +14299 _Primitive-decrement-edx: # (payload primitive) +14300 0x11/imm32/alloc-id:fake:payload +14301 # var/edx <- decrement => 4a/decrement-edx +14302 0x11/imm32/alloc-id:fake +14303 _string-decrement/imm32/name +14304 0/imm32/no-inouts +14305 0/imm32/no-inouts +14306 0x11/imm32/alloc-id:fake +14307 Single-int-var-in-edx/imm32/outputs +14308 0x11/imm32/alloc-id:fake +14309 _string_4a_decrement_edx/imm32/subx-name +14310 0/imm32/no-rm32 +14311 0/imm32/no-r32 +14312 0/imm32/no-imm32 +14313 0/imm32/no-disp32 +14314 0/imm32/output-is-write-only +14315 0x11/imm32/alloc-id:fake +14316 _Primitive-decrement-ebx/imm32/next +14317 _Primitive-decrement-ebx: # (payload primitive) +14318 0x11/imm32/alloc-id:fake:payload +14319 # var/ebx <- decrement => 4b/decrement-ebx 14320 0x11/imm32/alloc-id:fake -14321 _Primitive-break-if-addr<-named/imm32/next -14322 # - branches to named blocks -14323 _Primitive-break-if-addr<-named: # (payload primitive) -14324 0x11/imm32/alloc-id:fake:payload -14325 0x11/imm32/alloc-id:fake -14326 _string-break-if-addr</imm32/name -14327 0x11/imm32/alloc-id:fake -14328 Single-lit-var/imm32/inouts -14329 0/imm32/no-outputs -14330 0/imm32/no-outputs -14331 0x11/imm32/alloc-id:fake -14332 _string_0f_82_jump_label/imm32/subx-name -14333 0/imm32/no-rm32 -14334 0/imm32/no-r32 -14335 0/imm32/no-imm32 -14336 1/imm32/disp32-is-first-inout -14337 0/imm32/no-output +14321 _string-decrement/imm32/name +14322 0/imm32/no-inouts +14323 0/imm32/no-inouts +14324 0x11/imm32/alloc-id:fake +14325 Single-int-var-in-ebx/imm32/outputs +14326 0x11/imm32/alloc-id:fake +14327 _string_4b_decrement_ebx/imm32/subx-name +14328 0/imm32/no-rm32 +14329 0/imm32/no-r32 +14330 0/imm32/no-imm32 +14331 0/imm32/no-disp32 +14332 0/imm32/output-is-write-only +14333 0x11/imm32/alloc-id:fake +14334 _Primitive-decrement-esi/imm32/next +14335 _Primitive-decrement-esi: # (payload primitive) +14336 0x11/imm32/alloc-id:fake:payload +14337 # var/esi <- decrement => 4e/decrement-esi 14338 0x11/imm32/alloc-id:fake -14339 _Primitive-break-if-addr>=-named/imm32/next -14340 _Primitive-break-if-addr>=-named: # (payload primitive) -14341 0x11/imm32/alloc-id:fake:payload +14339 _string-decrement/imm32/name +14340 0/imm32/no-inouts +14341 0/imm32/no-inouts 14342 0x11/imm32/alloc-id:fake -14343 _string-break-if-addr>=/imm32/name +14343 Single-int-var-in-esi/imm32/outputs 14344 0x11/imm32/alloc-id:fake -14345 Single-lit-var/imm32/inouts -14346 0/imm32/no-outputs -14347 0/imm32/no-outputs -14348 0x11/imm32/alloc-id:fake -14349 _string_0f_83_jump_label/imm32/subx-name -14350 0/imm32/no-rm32 -14351 0/imm32/no-r32 -14352 0/imm32/no-imm32 -14353 1/imm32/disp32-is-first-inout -14354 0/imm32/no-output -14355 0x11/imm32/alloc-id:fake -14356 _Primitive-break-if-=-named/imm32/next -14357 _Primitive-break-if-=-named: # (payload primitive) -14358 0x11/imm32/alloc-id:fake:payload -14359 0x11/imm32/alloc-id:fake -14360 _string-break-if-=/imm32/name -14361 0x11/imm32/alloc-id:fake -14362 Single-lit-var/imm32/inouts -14363 0/imm32/no-outputs -14364 0/imm32/no-outputs -14365 0x11/imm32/alloc-id:fake -14366 _string_0f_84_jump_label/imm32/subx-name -14367 0/imm32/no-rm32 -14368 0/imm32/no-r32 -14369 0/imm32/no-imm32 -14370 1/imm32/disp32-is-first-inout -14371 0/imm32/no-output -14372 0x11/imm32/alloc-id:fake -14373 _Primitive-break-if-!=-named/imm32/next -14374 _Primitive-break-if-!=-named: # (payload primitive) -14375 0x11/imm32/alloc-id:fake:payload +14345 _string_4e_decrement_esi/imm32/subx-name +14346 0/imm32/no-rm32 +14347 0/imm32/no-r32 +14348 0/imm32/no-imm32 +14349 0/imm32/no-disp32 +14350 0/imm32/output-is-write-only +14351 0x11/imm32/alloc-id:fake +14352 _Primitive-decrement-edi/imm32/next +14353 _Primitive-decrement-edi: # (payload primitive) +14354 0x11/imm32/alloc-id:fake:payload +14355 # var/edi <- decrement => 4f/decrement-edi +14356 0x11/imm32/alloc-id:fake +14357 _string-decrement/imm32/name +14358 0/imm32/no-inouts +14359 0/imm32/no-inouts +14360 0x11/imm32/alloc-id:fake +14361 Single-int-var-in-edi/imm32/outputs +14362 0x11/imm32/alloc-id:fake +14363 _string_4f_decrement_edi/imm32/subx-name +14364 0/imm32/no-rm32 +14365 0/imm32/no-r32 +14366 0/imm32/no-imm32 +14367 0/imm32/no-disp32 +14368 0/imm32/output-is-write-only +14369 0x11/imm32/alloc-id:fake +14370 _Primitive-increment-mem/imm32/next +14371 _Primitive-increment-mem: # (payload primitive) +14372 0x11/imm32/alloc-id:fake:payload +14373 # increment var => ff 0/subop/increment *(ebp+__) +14374 0x11/imm32/alloc-id:fake +14375 _string-increment/imm32/name 14376 0x11/imm32/alloc-id:fake -14377 _string-break-if-!=/imm32/name -14378 0x11/imm32/alloc-id:fake -14379 Single-lit-var/imm32/inouts -14380 0/imm32/no-outputs -14381 0/imm32/no-outputs -14382 0x11/imm32/alloc-id:fake -14383 _string_0f_85_jump_label/imm32/subx-name -14384 0/imm32/no-rm32 -14385 0/imm32/no-r32 -14386 0/imm32/no-imm32 -14387 1/imm32/disp32-is-first-inout -14388 0/imm32/no-output -14389 0x11/imm32/alloc-id:fake -14390 _Primitive-break-if-addr<=-named/imm32/next -14391 _Primitive-break-if-addr<=-named: # (payload primitive) -14392 0x11/imm32/alloc-id:fake:payload -14393 0x11/imm32/alloc-id:fake -14394 _string-break-if-addr<=/imm32/name -14395 0x11/imm32/alloc-id:fake -14396 Single-lit-var/imm32/inouts -14397 0/imm32/no-outputs -14398 0/imm32/no-outputs -14399 0x11/imm32/alloc-id:fake -14400 _string_0f_86_jump_label/imm32/subx-name -14401 0/imm32/no-rm32 -14402 0/imm32/no-r32 -14403 0/imm32/no-imm32 -14404 1/imm32/disp32-is-first-inout -14405 0/imm32/no-output -14406 0x11/imm32/alloc-id:fake -14407 _Primitive-break-if-addr>-named/imm32/next -14408 _Primitive-break-if-addr>-named: # (payload primitive) -14409 0x11/imm32/alloc-id:fake:payload +14377 Single-int-var-in-mem/imm32/inouts +14378 0/imm32/no-outputs +14379 0/imm32/no-outputs +14380 0x11/imm32/alloc-id:fake +14381 _string_ff_subop_increment/imm32/subx-name +14382 1/imm32/rm32-is-first-inout +14383 0/imm32/no-r32 +14384 0/imm32/no-imm32 +14385 0/imm32/no-disp32 +14386 0/imm32/output-is-write-only +14387 0x11/imm32/alloc-id:fake +14388 _Primitive-increment-reg/imm32/next +14389 _Primitive-increment-reg: # (payload primitive) +14390 0x11/imm32/alloc-id:fake:payload +14391 # var/reg <- increment => ff 0/subop/increment %__ +14392 0x11/imm32/alloc-id:fake +14393 _string-increment/imm32/name +14394 0/imm32/no-inouts +14395 0/imm32/no-inouts +14396 0x11/imm32/alloc-id:fake +14397 Single-int-var-in-some-register/imm32/outputs +14398 0x11/imm32/alloc-id:fake +14399 _string_ff_subop_increment/imm32/subx-name +14400 3/imm32/rm32-is-first-output +14401 0/imm32/no-r32 +14402 0/imm32/no-imm32 +14403 0/imm32/no-disp32 +14404 0/imm32/output-is-write-only +14405 0x11/imm32/alloc-id:fake +14406 _Primitive-decrement-mem/imm32/next +14407 _Primitive-decrement-mem: # (payload primitive) +14408 0x11/imm32/alloc-id:fake:payload +14409 # decrement var => ff 1/subop/decrement *(ebp+__) 14410 0x11/imm32/alloc-id:fake -14411 _string-break-if-addr>/imm32/name +14411 _string-decrement/imm32/name 14412 0x11/imm32/alloc-id:fake -14413 Single-lit-var/imm32/inouts +14413 Single-int-var-in-mem/imm32/inouts 14414 0/imm32/no-outputs 14415 0/imm32/no-outputs 14416 0x11/imm32/alloc-id:fake -14417 _string_0f_87_jump_label/imm32/subx-name -14418 0/imm32/no-rm32 +14417 _string_ff_subop_decrement/imm32/subx-name +14418 1/imm32/rm32-is-first-inout 14419 0/imm32/no-r32 14420 0/imm32/no-imm32 -14421 1/imm32/disp32-is-first-inout -14422 0/imm32/no-output +14421 0/imm32/no-disp32 +14422 0/imm32/output-is-write-only 14423 0x11/imm32/alloc-id:fake -14424 _Primitive-break-if-<-named/imm32/next -14425 _Primitive-break-if-<-named: # (payload primitive) +14424 _Primitive-decrement-reg/imm32/next +14425 _Primitive-decrement-reg: # (payload primitive) 14426 0x11/imm32/alloc-id:fake:payload -14427 0x11/imm32/alloc-id:fake -14428 _string-break-if-</imm32/name -14429 0x11/imm32/alloc-id:fake -14430 Single-lit-var/imm32/inouts -14431 0/imm32/no-outputs -14432 0/imm32/no-outputs -14433 0x11/imm32/alloc-id:fake -14434 _string_0f_8c_jump_label/imm32/subx-name -14435 0/imm32/no-rm32 -14436 0/imm32/no-r32 -14437 0/imm32/no-imm32 -14438 1/imm32/disp32-is-first-inout -14439 0/imm32/no-output -14440 0x11/imm32/alloc-id:fake -14441 _Primitive-break-if->=-named/imm32/next -14442 _Primitive-break-if->=-named: # (payload primitive) -14443 0x11/imm32/alloc-id:fake:payload -14444 0x11/imm32/alloc-id:fake -14445 _string-break-if->=/imm32/name -14446 0x11/imm32/alloc-id:fake -14447 Single-lit-var/imm32/inouts -14448 0/imm32/no-outputs -14449 0/imm32/no-outputs -14450 0x11/imm32/alloc-id:fake -14451 _string_0f_8d_jump_label/imm32/subx-name -14452 0/imm32/no-rm32 -14453 0/imm32/no-r32 -14454 0/imm32/no-imm32 -14455 1/imm32/disp32-is-first-inout -14456 0/imm32/no-output -14457 0x11/imm32/alloc-id:fake -14458 _Primitive-break-if-<=-named/imm32/next -14459 _Primitive-break-if-<=-named: # (payload primitive) -14460 0x11/imm32/alloc-id:fake:payload -14461 0x11/imm32/alloc-id:fake -14462 _string-break-if-<=/imm32/name -14463 0x11/imm32/alloc-id:fake -14464 Single-lit-var/imm32/inouts -14465 0/imm32/no-outputs -14466 0/imm32/no-outputs +14427 # var/reg <- decrement => ff 1/subop/decrement %__ +14428 0x11/imm32/alloc-id:fake +14429 _string-decrement/imm32/name +14430 0/imm32/no-inouts +14431 0/imm32/no-inouts +14432 0x11/imm32/alloc-id:fake +14433 Single-int-var-in-some-register/imm32/outputs +14434 0x11/imm32/alloc-id:fake +14435 _string_ff_subop_decrement/imm32/subx-name +14436 3/imm32/rm32-is-first-output +14437 0/imm32/no-r32 +14438 0/imm32/no-imm32 +14439 0/imm32/no-disp32 +14440 0/imm32/output-is-write-only +14441 0x11/imm32/alloc-id:fake +14442 _Primitive-add-to-eax/imm32/next +14443 # - add +14444 _Primitive-add-to-eax: # (payload primitive) +14445 0x11/imm32/alloc-id:fake:payload +14446 # var/eax <- add lit => 05/add-to-eax lit/imm32 +14447 0x11/imm32/alloc-id:fake +14448 _string-add/imm32/name +14449 0x11/imm32/alloc-id:fake +14450 Single-lit-var/imm32/inouts +14451 0x11/imm32/alloc-id:fake +14452 Single-int-var-in-eax/imm32/outputs +14453 0x11/imm32/alloc-id:fake +14454 _string_05_add_to_eax/imm32/subx-name +14455 0/imm32/no-rm32 +14456 0/imm32/no-r32 +14457 1/imm32/imm32-is-first-inout +14458 0/imm32/no-disp32 +14459 0/imm32/output-is-write-only +14460 0x11/imm32/alloc-id:fake +14461 _Primitive-add-reg-to-reg/imm32/next +14462 _Primitive-add-reg-to-reg: # (payload primitive) +14463 0x11/imm32/alloc-id:fake:payload +14464 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 +14465 0x11/imm32/alloc-id:fake +14466 _string-add/imm32/name 14467 0x11/imm32/alloc-id:fake -14468 _string_0f_8e_jump_label/imm32/subx-name -14469 0/imm32/no-rm32 -14470 0/imm32/no-r32 -14471 0/imm32/no-imm32 -14472 1/imm32/disp32-is-first-inout -14473 0/imm32/no-output -14474 0x11/imm32/alloc-id:fake -14475 _Primitive-break-if->-named/imm32/next -14476 _Primitive-break-if->-named: # (payload primitive) -14477 0x11/imm32/alloc-id:fake:payload +14468 Single-int-var-in-some-register/imm32/inouts +14469 0x11/imm32/alloc-id:fake +14470 Single-int-var-in-some-register/imm32/outputs +14471 0x11/imm32/alloc-id:fake +14472 _string_01_add_to/imm32/subx-name +14473 3/imm32/rm32-is-first-output +14474 1/imm32/r32-is-first-inout +14475 0/imm32/no-imm32 +14476 0/imm32/no-disp32 +14477 0/imm32/output-is-write-only 14478 0x11/imm32/alloc-id:fake -14479 _string-break-if->/imm32/name -14480 0x11/imm32/alloc-id:fake -14481 Single-lit-var/imm32/inouts -14482 0/imm32/no-outputs -14483 0/imm32/no-outputs -14484 0x11/imm32/alloc-id:fake -14485 _string_0f_8f_jump_label/imm32/subx-name -14486 0/imm32/no-rm32 -14487 0/imm32/no-r32 -14488 0/imm32/no-imm32 -14489 1/imm32/disp32-is-first-inout -14490 0/imm32/no-output -14491 0x11/imm32/alloc-id:fake -14492 _Primitive-break-named/imm32/next -14493 _Primitive-break-named: # (payload primitive) -14494 0x11/imm32/alloc-id:fake:payload -14495 0x11/imm32/alloc-id:fake -14496 _string-break/imm32/name -14497 0x11/imm32/alloc-id:fake -14498 Single-lit-var/imm32/inouts -14499 0/imm32/no-outputs -14500 0/imm32/no-outputs +14479 _Primitive-add-reg-to-mem/imm32/next +14480 _Primitive-add-reg-to-mem: # (payload primitive) +14481 0x11/imm32/alloc-id:fake:payload +14482 # add-to var1 var2/reg => 01/add-to var1 var2/r32 +14483 0x11/imm32/alloc-id:fake +14484 _string-add-to/imm32/name +14485 0x11/imm32/alloc-id:fake +14486 Two-args-int-stack-int-reg/imm32/inouts +14487 0/imm32/no-outputs +14488 0/imm32/no-outputs +14489 0x11/imm32/alloc-id:fake +14490 _string_01_add_to/imm32/subx-name +14491 1/imm32/rm32-is-first-inout +14492 2/imm32/r32-is-second-inout +14493 0/imm32/no-imm32 +14494 0/imm32/no-disp32 +14495 0/imm32/output-is-write-only +14496 0x11/imm32/alloc-id:fake +14497 _Primitive-add-mem-to-reg/imm32/next +14498 _Primitive-add-mem-to-reg: # (payload primitive) +14499 0x11/imm32/alloc-id:fake:payload +14500 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 14501 0x11/imm32/alloc-id:fake -14502 _string_e9_jump_label/imm32/subx-name -14503 0/imm32/no-rm32 -14504 0/imm32/no-r32 -14505 0/imm32/no-imm32 -14506 1/imm32/disp32-is-first-inout -14507 0/imm32/no-output -14508 0x11/imm32/alloc-id:fake -14509 _Primitive-loop-if-addr<-named/imm32/next -14510 _Primitive-loop-if-addr<-named: # (payload primitive) -14511 0x11/imm32/alloc-id:fake:payload -14512 0x11/imm32/alloc-id:fake -14513 _string-loop-if-addr</imm32/name +14502 _string-add/imm32/name +14503 0x11/imm32/alloc-id:fake +14504 Single-int-var-in-mem/imm32/inouts +14505 0x11/imm32/alloc-id:fake +14506 Single-int-var-in-some-register/imm32/outputs +14507 0x11/imm32/alloc-id:fake +14508 _string_03_add/imm32/subx-name +14509 1/imm32/rm32-is-first-inout +14510 3/imm32/r32-is-first-output +14511 0/imm32/no-imm32 +14512 0/imm32/no-disp32 +14513 0/imm32/output-is-write-only 14514 0x11/imm32/alloc-id:fake -14515 Single-lit-var/imm32/inouts -14516 0/imm32/no-outputs -14517 0/imm32/no-outputs -14518 0x11/imm32/alloc-id:fake -14519 _string_0f_82_jump_label/imm32/subx-name -14520 0/imm32/no-rm32 -14521 0/imm32/no-r32 -14522 0/imm32/no-imm32 -14523 1/imm32/disp32-is-first-inout -14524 0/imm32/no-output +14515 _Primitive-add-lit-to-reg/imm32/next +14516 _Primitive-add-lit-to-reg: # (payload primitive) +14517 0x11/imm32/alloc-id:fake:payload +14518 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 +14519 0x11/imm32/alloc-id:fake +14520 _string-add/imm32/name +14521 0x11/imm32/alloc-id:fake +14522 Single-lit-var/imm32/inouts +14523 0x11/imm32/alloc-id:fake +14524 Single-int-var-in-some-register/imm32/outputs 14525 0x11/imm32/alloc-id:fake -14526 _Primitive-loop-if-addr>=-named/imm32/next -14527 _Primitive-loop-if-addr>=-named: # (payload primitive) -14528 0x11/imm32/alloc-id:fake:payload -14529 0x11/imm32/alloc-id:fake -14530 _string-loop-if-addr>=/imm32/name -14531 0x11/imm32/alloc-id:fake -14532 Single-lit-var/imm32/inouts -14533 0/imm32/no-outputs -14534 0/imm32/no-outputs -14535 0x11/imm32/alloc-id:fake -14536 _string_0f_83_jump_label/imm32/subx-name -14537 0/imm32/no-rm32 -14538 0/imm32/no-r32 -14539 0/imm32/no-imm32 -14540 1/imm32/disp32-is-first-inout -14541 0/imm32/no-output -14542 0x11/imm32/alloc-id:fake -14543 _Primitive-loop-if-=-named/imm32/next -14544 _Primitive-loop-if-=-named: # (payload primitive) -14545 0x11/imm32/alloc-id:fake:payload -14546 0x11/imm32/alloc-id:fake -14547 _string-loop-if-=/imm32/name -14548 0x11/imm32/alloc-id:fake -14549 Single-lit-var/imm32/inouts -14550 0/imm32/no-outputs -14551 0/imm32/no-outputs -14552 0x11/imm32/alloc-id:fake -14553 _string_0f_84_jump_label/imm32/subx-name -14554 0/imm32/no-rm32 -14555 0/imm32/no-r32 -14556 0/imm32/no-imm32 -14557 1/imm32/disp32-is-first-inout -14558 0/imm32/no-output -14559 0x11/imm32/alloc-id:fake -14560 _Primitive-loop-if-!=-named/imm32/next -14561 _Primitive-loop-if-!=-named: # (payload primitive) -14562 0x11/imm32/alloc-id:fake:payload -14563 0x11/imm32/alloc-id:fake -14564 _string-loop-if-!=/imm32/name -14565 0x11/imm32/alloc-id:fake -14566 Single-lit-var/imm32/inouts -14567 0/imm32/no-outputs -14568 0/imm32/no-outputs +14526 _string_81_subop_add/imm32/subx-name +14527 3/imm32/rm32-is-first-output +14528 0/imm32/no-r32 +14529 1/imm32/imm32-is-first-inout +14530 0/imm32/no-disp32 +14531 0/imm32/output-is-write-only +14532 0x11/imm32/alloc-id:fake +14533 _Primitive-add-lit-to-mem/imm32/next +14534 _Primitive-add-lit-to-mem: # (payload primitive) +14535 0x11/imm32/alloc-id:fake:payload +14536 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 +14537 0x11/imm32/alloc-id:fake +14538 _string-add-to/imm32/name +14539 0x11/imm32/alloc-id:fake +14540 Int-var-and-literal/imm32/inouts +14541 0/imm32/no-outputs +14542 0/imm32/no-outputs +14543 0x11/imm32/alloc-id:fake +14544 _string_81_subop_add/imm32/subx-name +14545 1/imm32/rm32-is-first-inout +14546 0/imm32/no-r32 +14547 2/imm32/imm32-is-second-inout +14548 0/imm32/no-disp32 +14549 0/imm32/output-is-write-only +14550 0x11/imm32/alloc-id:fake +14551 _Primitive-subtract-from-eax/imm32/next +14552 # - subtract +14553 _Primitive-subtract-from-eax: # (payload primitive) +14554 0x11/imm32/alloc-id:fake:payload +14555 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 +14556 0x11/imm32/alloc-id:fake +14557 _string-subtract/imm32/name +14558 0x11/imm32/alloc-id:fake +14559 Single-lit-var/imm32/inouts +14560 0x11/imm32/alloc-id:fake +14561 Single-int-var-in-eax/imm32/outputs +14562 0x11/imm32/alloc-id:fake +14563 _string_2d_subtract_from_eax/imm32/subx-name +14564 0/imm32/no-rm32 +14565 0/imm32/no-r32 +14566 1/imm32/imm32-is-first-inout +14567 0/imm32/no-disp32 +14568 0/imm32/output-is-write-only 14569 0x11/imm32/alloc-id:fake -14570 _string_0f_85_jump_label/imm32/subx-name -14571 0/imm32/no-rm32 -14572 0/imm32/no-r32 -14573 0/imm32/no-imm32 -14574 1/imm32/disp32-is-first-inout -14575 0/imm32/no-output +14570 _Primitive-subtract-reg-from-reg/imm32/next +14571 _Primitive-subtract-reg-from-reg: # (payload primitive) +14572 0x11/imm32/alloc-id:fake:payload +14573 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 +14574 0x11/imm32/alloc-id:fake +14575 _string-subtract/imm32/name 14576 0x11/imm32/alloc-id:fake -14577 _Primitive-loop-if-addr<=-named/imm32/next -14578 _Primitive-loop-if-addr<=-named: # (payload primitive) -14579 0x11/imm32/alloc-id:fake:payload +14577 Single-int-var-in-some-register/imm32/inouts +14578 0x11/imm32/alloc-id:fake +14579 Single-int-var-in-some-register/imm32/outputs 14580 0x11/imm32/alloc-id:fake -14581 _string-loop-if-addr<=/imm32/name -14582 0x11/imm32/alloc-id:fake -14583 Single-lit-var/imm32/inouts -14584 0/imm32/no-outputs -14585 0/imm32/no-outputs -14586 0x11/imm32/alloc-id:fake -14587 _string_0f_86_jump_label/imm32/subx-name -14588 0/imm32/no-rm32 -14589 0/imm32/no-r32 -14590 0/imm32/no-imm32 -14591 1/imm32/disp32-is-first-inout -14592 0/imm32/no-output -14593 0x11/imm32/alloc-id:fake -14594 _Primitive-loop-if-addr>-named/imm32/next -14595 _Primitive-loop-if-addr>-named: # (payload primitive) -14596 0x11/imm32/alloc-id:fake:payload -14597 0x11/imm32/alloc-id:fake -14598 _string-loop-if-addr>/imm32/name -14599 0x11/imm32/alloc-id:fake -14600 Single-lit-var/imm32/inouts -14601 0/imm32/no-outputs -14602 0/imm32/no-outputs -14603 0x11/imm32/alloc-id:fake -14604 _string_0f_87_jump_label/imm32/subx-name -14605 0/imm32/no-rm32 -14606 0/imm32/no-r32 -14607 0/imm32/no-imm32 -14608 1/imm32/disp32-is-first-inout -14609 0/imm32/no-output +14581 _string_29_subtract_from/imm32/subx-name +14582 3/imm32/rm32-is-first-output +14583 1/imm32/r32-is-first-inout +14584 0/imm32/no-imm32 +14585 0/imm32/no-disp32 +14586 0/imm32/output-is-write-only +14587 0x11/imm32/alloc-id:fake +14588 _Primitive-subtract-reg-from-mem/imm32/next +14589 _Primitive-subtract-reg-from-mem: # (payload primitive) +14590 0x11/imm32/alloc-id:fake:payload +14591 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 +14592 0x11/imm32/alloc-id:fake +14593 _string-subtract-from/imm32/name +14594 0x11/imm32/alloc-id:fake +14595 Two-args-int-stack-int-reg/imm32/inouts +14596 0/imm32/no-outputs +14597 0/imm32/no-outputs +14598 0x11/imm32/alloc-id:fake +14599 _string_29_subtract_from/imm32/subx-name +14600 1/imm32/rm32-is-first-inout +14601 2/imm32/r32-is-second-inout +14602 0/imm32/no-imm32 +14603 0/imm32/no-disp32 +14604 0/imm32/output-is-write-only +14605 0x11/imm32/alloc-id:fake +14606 _Primitive-subtract-mem-from-reg/imm32/next +14607 _Primitive-subtract-mem-from-reg: # (payload primitive) +14608 0x11/imm32/alloc-id:fake:payload +14609 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 14610 0x11/imm32/alloc-id:fake -14611 _Primitive-loop-if-<-named/imm32/next -14612 _Primitive-loop-if-<-named: # (payload primitive) -14613 0x11/imm32/alloc-id:fake:payload +14611 _string-subtract/imm32/name +14612 0x11/imm32/alloc-id:fake +14613 Single-int-var-in-mem/imm32/inouts 14614 0x11/imm32/alloc-id:fake -14615 _string-loop-if-</imm32/name +14615 Single-int-var-in-some-register/imm32/outputs 14616 0x11/imm32/alloc-id:fake -14617 Single-lit-var/imm32/inouts -14618 0/imm32/no-outputs -14619 0/imm32/no-outputs -14620 0x11/imm32/alloc-id:fake -14621 _string_0f_8c_jump_label/imm32/subx-name -14622 0/imm32/no-rm32 -14623 0/imm32/no-r32 -14624 0/imm32/no-imm32 -14625 1/imm32/disp32-is-first-inout -14626 0/imm32/no-output -14627 0x11/imm32/alloc-id:fake -14628 _Primitive-loop-if->=-named/imm32/next -14629 _Primitive-loop-if->=-named: # (payload primitive) -14630 0x11/imm32/alloc-id:fake:payload -14631 0x11/imm32/alloc-id:fake -14632 _string-loop-if->=/imm32/name -14633 0x11/imm32/alloc-id:fake -14634 Single-lit-var/imm32/inouts -14635 0/imm32/no-outputs -14636 0/imm32/no-outputs -14637 0x11/imm32/alloc-id:fake -14638 _string_0f_8d_jump_label/imm32/subx-name -14639 0/imm32/no-rm32 -14640 0/imm32/no-r32 -14641 0/imm32/no-imm32 -14642 1/imm32/disp32-is-first-inout -14643 0/imm32/no-output -14644 0x11/imm32/alloc-id:fake -14645 _Primitive-loop-if-<=-named/imm32/next -14646 _Primitive-loop-if-<=-named: # (payload primitive) -14647 0x11/imm32/alloc-id:fake:payload +14617 _string_2b_subtract/imm32/subx-name +14618 1/imm32/rm32-is-first-inout +14619 3/imm32/r32-is-first-output +14620 0/imm32/no-imm32 +14621 0/imm32/no-disp32 +14622 0/imm32/output-is-write-only +14623 0x11/imm32/alloc-id:fake +14624 _Primitive-subtract-lit-from-reg/imm32/next +14625 _Primitive-subtract-lit-from-reg: # (payload primitive) +14626 0x11/imm32/alloc-id:fake:payload +14627 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 +14628 0x11/imm32/alloc-id:fake +14629 _string-subtract/imm32/name +14630 0x11/imm32/alloc-id:fake +14631 Single-lit-var/imm32/inouts +14632 0x11/imm32/alloc-id:fake +14633 Single-int-var-in-some-register/imm32/outputs +14634 0x11/imm32/alloc-id:fake +14635 _string_81_subop_subtract/imm32/subx-name +14636 3/imm32/rm32-is-first-output +14637 0/imm32/no-r32 +14638 1/imm32/imm32-is-first-inout +14639 0/imm32/no-disp32 +14640 0/imm32/output-is-write-only +14641 0x11/imm32/alloc-id:fake +14642 _Primitive-subtract-lit-from-mem/imm32/next +14643 _Primitive-subtract-lit-from-mem: # (payload primitive) +14644 0x11/imm32/alloc-id:fake:payload +14645 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 +14646 0x11/imm32/alloc-id:fake +14647 _string-subtract-from/imm32/name 14648 0x11/imm32/alloc-id:fake -14649 _string-loop-if-<=/imm32/name -14650 0x11/imm32/alloc-id:fake -14651 Single-lit-var/imm32/inouts -14652 0/imm32/no-outputs -14653 0/imm32/no-outputs -14654 0x11/imm32/alloc-id:fake -14655 _string_0f_8e_jump_label/imm32/subx-name -14656 0/imm32/no-rm32 -14657 0/imm32/no-r32 -14658 0/imm32/no-imm32 -14659 1/imm32/disp32-is-first-inout -14660 0/imm32/no-output -14661 0x11/imm32/alloc-id:fake -14662 _Primitive-loop-if->-named/imm32/next -14663 _Primitive-loop-if->-named: # (payload primitive) -14664 0x11/imm32/alloc-id:fake:payload +14649 Int-var-and-literal/imm32/inouts +14650 0/imm32/no-outputs +14651 0/imm32/no-outputs +14652 0x11/imm32/alloc-id:fake +14653 _string_81_subop_subtract/imm32/subx-name +14654 1/imm32/rm32-is-first-inout +14655 0/imm32/no-r32 +14656 2/imm32/imm32-is-first-inout +14657 0/imm32/no-disp32 +14658 0/imm32/output-is-write-only +14659 0x11/imm32/alloc-id:fake +14660 _Primitive-and-with-eax/imm32/next +14661 # - and +14662 _Primitive-and-with-eax: # (payload primitive) +14663 0x11/imm32/alloc-id:fake:payload +14664 # var/eax <- and lit => 25/and-with-eax lit/imm32 14665 0x11/imm32/alloc-id:fake -14666 _string-loop-if->/imm32/name +14666 _string-and/imm32/name 14667 0x11/imm32/alloc-id:fake -14668 Single-lit-var/imm32/inouts -14669 0/imm32/no-outputs -14670 0/imm32/no-outputs +14668 Single-lit-var/imm32/inouts +14669 0x11/imm32/alloc-id:fake +14670 Single-int-var-in-eax/imm32/outputs 14671 0x11/imm32/alloc-id:fake -14672 _string_0f_8f_jump_label/imm32/subx-name +14672 _string_25_and_with_eax/imm32/subx-name 14673 0/imm32/no-rm32 14674 0/imm32/no-r32 -14675 0/imm32/no-imm32 -14676 1/imm32/disp32-is-first-inout -14677 0/imm32/no-output +14675 1/imm32/imm32-is-first-inout +14676 0/imm32/no-disp32 +14677 0/imm32/output-is-write-only 14678 0x11/imm32/alloc-id:fake -14679 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break -14680 _Primitive-loop-named: # (payload primitive) +14679 _Primitive-and-reg-with-reg/imm32/next +14680 _Primitive-and-reg-with-reg: # (payload primitive) 14681 0x11/imm32/alloc-id:fake:payload -14682 0x11/imm32/alloc-id:fake -14683 _string-loop/imm32/name -14684 0x11/imm32/alloc-id:fake -14685 Single-lit-var/imm32/inouts -14686 0/imm32/no-outputs -14687 0/imm32/no-outputs -14688 0x11/imm32/alloc-id:fake -14689 _string_e9_jump_label/imm32/subx-name -14690 0/imm32/no-rm32 -14691 0/imm32/no-r32 -14692 0/imm32/no-imm32 -14693 1/imm32/disp32-is-first-inout -14694 0/imm32/no-output -14695 0/imm32/next -14696 0/imm32/next -14697 -14698 # string literals for Mu instructions -14699 _string-add: # (payload array byte) -14700 0x11/imm32/alloc-id:fake:payload -14701 # "add" -14702 0x3/imm32/size -14703 0x61/a 0x64/d 0x64/d -14704 _string-address: # (payload array byte) -14705 0x11/imm32/alloc-id:fake:payload -14706 # "address" -14707 0x7/imm32/size -14708 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s -14709 _string-add-to: # (payload array byte) -14710 0x11/imm32/alloc-id:fake:payload -14711 # "add-to" -14712 0x6/imm32/size -14713 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o -14714 _string-and: # (payload array byte) -14715 0x11/imm32/alloc-id:fake:payload -14716 # "and" -14717 0x3/imm32/size -14718 0x61/a 0x6e/n 0x64/d -14719 _string-and-with: # (payload array byte) -14720 0x11/imm32/alloc-id:fake:payload -14721 # "and-with" -14722 0x8/imm32/size -14723 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -14724 _string-break: # (payload array byte) -14725 0x11/imm32/alloc-id:fake:payload -14726 # "break" -14727 0x5/imm32/size -14728 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k -14729 _string-break-if-<: # (payload array byte) -14730 0x11/imm32/alloc-id:fake:payload -14731 # "break-if-<" -14732 0xa/imm32/size -14733 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -14734 _string-break-if-<=: # (payload array byte) +14682 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 +14683 0x11/imm32/alloc-id:fake +14684 _string-and/imm32/name +14685 0x11/imm32/alloc-id:fake +14686 Single-int-var-in-some-register/imm32/inouts +14687 0x11/imm32/alloc-id:fake +14688 Single-int-var-in-some-register/imm32/outputs +14689 0x11/imm32/alloc-id:fake +14690 _string_21_and_with/imm32/subx-name +14691 3/imm32/rm32-is-first-output +14692 1/imm32/r32-is-first-inout +14693 0/imm32/no-imm32 +14694 0/imm32/no-disp32 +14695 0/imm32/output-is-write-only +14696 0x11/imm32/alloc-id:fake +14697 _Primitive-and-reg-with-mem/imm32/next +14698 _Primitive-and-reg-with-mem: # (payload primitive) +14699 0x11/imm32/alloc-id:fake:payload +14700 # and-with var1 var2/reg => 21/and-with var1 var2/r32 +14701 0x11/imm32/alloc-id:fake +14702 _string-and-with/imm32/name +14703 0x11/imm32/alloc-id:fake +14704 Two-args-int-stack-int-reg/imm32/inouts +14705 0/imm32/no-outputs +14706 0/imm32/no-outputs +14707 0x11/imm32/alloc-id:fake +14708 _string_21_and_with/imm32/subx-name +14709 1/imm32/rm32-is-first-inout +14710 2/imm32/r32-is-second-inout +14711 0/imm32/no-imm32 +14712 0/imm32/no-disp32 +14713 0/imm32/output-is-write-only +14714 0x11/imm32/alloc-id:fake +14715 _Primitive-and-mem-with-reg/imm32/next +14716 _Primitive-and-mem-with-reg: # (payload primitive) +14717 0x11/imm32/alloc-id:fake:payload +14718 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 +14719 0x11/imm32/alloc-id:fake +14720 _string-and/imm32/name +14721 0x11/imm32/alloc-id:fake +14722 Single-int-var-in-mem/imm32/inouts +14723 0x11/imm32/alloc-id:fake +14724 Single-int-var-in-some-register/imm32/outputs +14725 0x11/imm32/alloc-id:fake +14726 _string_23_and/imm32/subx-name +14727 1/imm32/rm32-is-first-inout +14728 3/imm32/r32-is-first-output +14729 0/imm32/no-imm32 +14730 0/imm32/no-disp32 +14731 0/imm32/output-is-write-only +14732 0x11/imm32/alloc-id:fake +14733 _Primitive-and-lit-with-reg/imm32/next +14734 _Primitive-and-lit-with-reg: # (payload primitive) 14735 0x11/imm32/alloc-id:fake:payload -14736 # "break-if-<=" -14737 0xb/imm32/size -14738 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -14739 _string-break-if-=: # (payload array byte) -14740 0x11/imm32/alloc-id:fake:payload -14741 # "break-if-=" -14742 0xa/imm32/size -14743 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -14744 _string-break-if->: # (payload array byte) -14745 0x11/imm32/alloc-id:fake:payload -14746 # "break-if->" -14747 0xa/imm32/size -14748 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -14749 _string-break-if->=: # (payload array byte) -14750 0x11/imm32/alloc-id:fake:payload -14751 # "break-if->=" -14752 0xb/imm32/size -14753 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -14754 _string-break-if-!=: # (payload array byte) -14755 0x11/imm32/alloc-id:fake:payload -14756 # "break-if-!=" -14757 0xb/imm32/size -14758 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -14759 _string-break-if-addr<: # (payload array byte) -14760 0x11/imm32/alloc-id:fake:payload -14761 # "break-if-addr<" -14762 0xe/imm32/size -14763 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/< -14764 _string-break-if-addr<=: # (payload array byte) -14765 0x11/imm32/alloc-id:fake:payload -14766 # "break-if-addr<=" -14767 0xf/imm32/size -14768 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/= -14769 _string-break-if-addr>: # (payload array byte) -14770 0x11/imm32/alloc-id:fake:payload -14771 # "break-if-addr>" -14772 0xe/imm32/size -14773 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/> -14774 _string-break-if-addr>=: # (payload array byte) -14775 0x11/imm32/alloc-id:fake:payload -14776 # "break-if-addr>=" -14777 0xf/imm32/size -14778 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/= -14779 _string-compare: # (payload array byte) -14780 0x11/imm32/alloc-id:fake:payload -14781 # "compare" -14782 0x7/imm32/size -14783 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e -14784 _string-copy: # (payload array byte) -14785 0x11/imm32/alloc-id:fake:payload -14786 # "copy" -14787 0x4/imm32/size -14788 0x63/c 0x6f/o 0x70/p 0x79/y -14789 _string-copy-to: # (payload array byte) +14736 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 +14737 0x11/imm32/alloc-id:fake +14738 _string-and/imm32/name +14739 0x11/imm32/alloc-id:fake +14740 Single-lit-var/imm32/inouts +14741 0x11/imm32/alloc-id:fake +14742 Single-int-var-in-some-register/imm32/outputs +14743 0x11/imm32/alloc-id:fake +14744 _string_81_subop_and/imm32/subx-name +14745 3/imm32/rm32-is-first-output +14746 0/imm32/no-r32 +14747 1/imm32/imm32-is-first-inout +14748 0/imm32/no-disp32 +14749 0/imm32/output-is-write-only +14750 0x11/imm32/alloc-id:fake +14751 _Primitive-and-lit-with-mem/imm32/next +14752 _Primitive-and-lit-with-mem: # (payload primitive) +14753 0x11/imm32/alloc-id:fake:payload +14754 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 +14755 0x11/imm32/alloc-id:fake +14756 _string-and-with/imm32/name +14757 0x11/imm32/alloc-id:fake +14758 Int-var-and-literal/imm32/inouts +14759 0/imm32/no-outputs +14760 0/imm32/no-outputs +14761 0x11/imm32/alloc-id:fake +14762 _string_81_subop_and/imm32/subx-name +14763 1/imm32/rm32-is-first-inout +14764 0/imm32/no-r32 +14765 2/imm32/imm32-is-first-inout +14766 0/imm32/no-disp32 +14767 0/imm32/output-is-write-only +14768 0x11/imm32/alloc-id:fake +14769 _Primitive-or-with-eax/imm32/next +14770 # - or +14771 _Primitive-or-with-eax: # (payload primitive) +14772 0x11/imm32/alloc-id:fake:payload +14773 # var/eax <- or lit => 0d/or-with-eax lit/imm32 +14774 0x11/imm32/alloc-id:fake +14775 _string-or/imm32/name +14776 0x11/imm32/alloc-id:fake +14777 Single-lit-var/imm32/inouts +14778 0x11/imm32/alloc-id:fake +14779 Single-int-var-in-eax/imm32/outputs +14780 0x11/imm32/alloc-id:fake +14781 _string_0d_or_with_eax/imm32/subx-name +14782 0/imm32/no-rm32 +14783 0/imm32/no-r32 +14784 1/imm32/imm32-is-first-inout +14785 0/imm32/no-disp32 +14786 0/imm32/output-is-write-only +14787 0x11/imm32/alloc-id:fake +14788 _Primitive-or-reg-with-reg/imm32/next +14789 _Primitive-or-reg-with-reg: # (payload primitive) 14790 0x11/imm32/alloc-id:fake:payload -14791 # "copy-to" -14792 0x7/imm32/size -14793 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o -14794 _string-copy-byte: -14795 0x11/imm32/alloc-id:fake:payload -14796 # "copy-byte" -14797 0x9/imm32/size -14798 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e -14799 _string-copy-byte-to: -14800 0x11/imm32/alloc-id:fake:payload -14801 # "copy-byte-to" -14802 0xc/imm32/size -14803 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x74/t 0x6f/o -14804 _string-decrement: # (payload array byte) -14805 0x11/imm32/alloc-id:fake:payload -14806 # "decrement" -14807 0x9/imm32/size -14808 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -14809 _string-increment: # (payload array byte) -14810 0x11/imm32/alloc-id:fake:payload -14811 # "increment" -14812 0x9/imm32/size -14813 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t -14814 _string-loop: # (payload array byte) -14815 0x11/imm32/alloc-id:fake:payload -14816 # "loop" -14817 0x4/imm32/size -14818 0x6c/l 0x6f/o 0x6f/o 0x70/p -14819 _string-loop-if-<: # (payload array byte) -14820 0x11/imm32/alloc-id:fake:payload -14821 # "loop-if-<" -14822 0x9/imm32/size -14823 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< -14824 _string-loop-if-<=: # (payload array byte) -14825 0x11/imm32/alloc-id:fake:payload -14826 # "loop-if-<=" -14827 0xa/imm32/size -14828 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= -14829 _string-loop-if-=: # (payload array byte) -14830 0x11/imm32/alloc-id:fake:payload -14831 # "loop-if-=" -14832 0x9/imm32/size -14833 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= -14834 _string-loop-if->: # (payload array byte) -14835 0x11/imm32/alloc-id:fake:payload -14836 # "loop-if->" -14837 0x9/imm32/size -14838 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> -14839 _string-loop-if->=: # (payload array byte) -14840 0x11/imm32/alloc-id:fake:payload -14841 # "loop-if->=" -14842 0xa/imm32/size -14843 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= -14844 _string-loop-if-!=: # (payload array byte) -14845 0x11/imm32/alloc-id:fake:payload -14846 # "loop-if-!=" -14847 0xa/imm32/size -14848 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= -14849 _string-loop-if-addr<: # (payload array byte) -14850 0x11/imm32/alloc-id:fake:payload -14851 # "loop-if-addr<" -14852 0xd/imm32/size -14853 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/< -14854 _string-loop-if-addr<=: # (payload array byte) -14855 0x11/imm32/alloc-id:fake:payload -14856 # "loop-if-addr<=" -14857 0xe/imm32/size -14858 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/= -14859 _string-loop-if-addr>: # (payload array byte) -14860 0x11/imm32/alloc-id:fake:payload -14861 # "loop-if-addr>" -14862 0xd/imm32/size -14863 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/> -14864 _string-loop-if-addr>=: # (payload array byte) -14865 0x11/imm32/alloc-id:fake:payload -14866 # "loop-if-addr>=" -14867 0xe/imm32/size -14868 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/= -14869 _string-multiply: # (payload array byte) -14870 0x11/imm32/alloc-id:fake:payload -14871 # "multiply" -14872 0x8/imm32/size -14873 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y -14874 _string-or: # (payload array byte) -14875 0x11/imm32/alloc-id:fake:payload -14876 # "or" -14877 0x2/imm32/size -14878 0x6f/o 0x72/r -14879 _string-or-with: # (payload array byte) -14880 0x11/imm32/alloc-id:fake:payload -14881 # "or-with" -14882 0x7/imm32/size -14883 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -14884 _string-subtract: # (payload array byte) -14885 0x11/imm32/alloc-id:fake:payload -14886 # "subtract" -14887 0x8/imm32/size -14888 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -14889 _string-subtract-from: # (payload array byte) -14890 0x11/imm32/alloc-id:fake:payload -14891 # "subtract-from" -14892 0xd/imm32/size -14893 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 -14894 _string-xor: # (payload array byte) -14895 0x11/imm32/alloc-id:fake:payload -14896 # "xor" -14897 0x3/imm32/size -14898 0x78/x 0x6f/o 0x72/r -14899 _string-xor-with: # (payload array byte) -14900 0x11/imm32/alloc-id:fake:payload -14901 # "xor-with" -14902 0x8/imm32/size -14903 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -14904 -14905 # string literals for SubX instructions -14906 _string_01_add_to: # (payload array byte) -14907 0x11/imm32/alloc-id:fake:payload -14908 # "01/add-to" -14909 0x9/imm32/size -14910 0x30/0 0x31/1 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o -14911 _string_03_add: # (payload array byte) -14912 0x11/imm32/alloc-id:fake:payload -14913 # "03/add" -14914 0x6/imm32/size -14915 0x30/0 0x33/3 0x2f/slash 0x61/a 0x64/d 0x64/d -14916 _string_05_add_to_eax: # (payload array byte) +14791 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 +14792 0x11/imm32/alloc-id:fake +14793 _string-or/imm32/name +14794 0x11/imm32/alloc-id:fake +14795 Single-int-var-in-some-register/imm32/inouts +14796 0x11/imm32/alloc-id:fake +14797 Single-int-var-in-some-register/imm32/outputs +14798 0x11/imm32/alloc-id:fake +14799 _string_09_or_with/imm32/subx-name +14800 3/imm32/rm32-is-first-output +14801 1/imm32/r32-is-first-inout +14802 0/imm32/no-imm32 +14803 0/imm32/no-disp32 +14804 0/imm32/output-is-write-only +14805 0x11/imm32/alloc-id:fake +14806 _Primitive-or-reg-with-mem/imm32/next +14807 _Primitive-or-reg-with-mem: # (payload primitive) +14808 0x11/imm32/alloc-id:fake:payload +14809 # or-with var1 var2/reg => 09/or-with var1 var2/r32 +14810 0x11/imm32/alloc-id:fake +14811 _string-or-with/imm32/name +14812 0x11/imm32/alloc-id:fake +14813 Two-args-int-stack-int-reg/imm32/inouts +14814 0/imm32/no-outputs +14815 0/imm32/no-outputs +14816 0x11/imm32/alloc-id:fake +14817 _string_09_or_with/imm32/subx-name +14818 1/imm32/rm32-is-first-inout +14819 2/imm32/r32-is-second-inout +14820 0/imm32/no-imm32 +14821 0/imm32/no-disp32 +14822 0/imm32/output-is-write-only +14823 0x11/imm32/alloc-id:fake +14824 _Primitive-or-mem-with-reg/imm32/next +14825 _Primitive-or-mem-with-reg: # (payload primitive) +14826 0x11/imm32/alloc-id:fake:payload +14827 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 +14828 0x11/imm32/alloc-id:fake +14829 _string-or/imm32/name +14830 0x11/imm32/alloc-id:fake +14831 Single-int-var-in-mem/imm32/inouts +14832 0x11/imm32/alloc-id:fake +14833 Single-int-var-in-some-register/imm32/outputs +14834 0x11/imm32/alloc-id:fake +14835 _string_0b_or/imm32/subx-name +14836 1/imm32/rm32-is-first-inout +14837 3/imm32/r32-is-first-output +14838 0/imm32/no-imm32 +14839 0/imm32/no-disp32 +14840 0/imm32/output-is-write-only +14841 0x11/imm32/alloc-id:fake +14842 _Primitive-or-lit-with-reg/imm32/next +14843 _Primitive-or-lit-with-reg: # (payload primitive) +14844 0x11/imm32/alloc-id:fake:payload +14845 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 +14846 0x11/imm32/alloc-id:fake +14847 _string-or/imm32/name +14848 0x11/imm32/alloc-id:fake +14849 Single-lit-var/imm32/inouts +14850 0x11/imm32/alloc-id:fake +14851 Single-int-var-in-some-register/imm32/outputs +14852 0x11/imm32/alloc-id:fake +14853 _string_81_subop_or/imm32/subx-name +14854 3/imm32/rm32-is-first-output +14855 0/imm32/no-r32 +14856 1/imm32/imm32-is-first-inout +14857 0/imm32/no-disp32 +14858 0/imm32/output-is-write-only +14859 0x11/imm32/alloc-id:fake +14860 _Primitive-or-lit-with-mem/imm32/next +14861 _Primitive-or-lit-with-mem: # (payload primitive) +14862 0x11/imm32/alloc-id:fake:payload +14863 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 +14864 0x11/imm32/alloc-id:fake +14865 _string-or-with/imm32/name +14866 0x11/imm32/alloc-id:fake +14867 Int-var-and-literal/imm32/inouts +14868 0/imm32/no-outputs +14869 0/imm32/no-outputs +14870 0x11/imm32/alloc-id:fake +14871 _string_81_subop_or/imm32/subx-name +14872 1/imm32/rm32-is-first-inout +14873 0/imm32/no-r32 +14874 2/imm32/imm32-is-second-inout +14875 0/imm32/no-disp32 +14876 0/imm32/output-is-write-only +14877 0x11/imm32/alloc-id:fake +14878 _Primitive-xor-with-eax/imm32/next +14879 # - xor +14880 _Primitive-xor-with-eax: # (payload primitive) +14881 0x11/imm32/alloc-id:fake:payload +14882 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 +14883 0x11/imm32/alloc-id:fake +14884 _string-xor/imm32/name +14885 0x11/imm32/alloc-id:fake +14886 Single-lit-var/imm32/inouts +14887 0x11/imm32/alloc-id:fake +14888 Single-int-var-in-eax/imm32/outputs +14889 0x11/imm32/alloc-id:fake +14890 _string_35_xor_with_eax/imm32/subx-name +14891 0/imm32/no-rm32 +14892 0/imm32/no-r32 +14893 1/imm32/imm32-is-first-inout +14894 0/imm32/no-disp32 +14895 0/imm32/output-is-write-only +14896 0x11/imm32/alloc-id:fake +14897 _Primitive-xor-reg-with-reg/imm32/next +14898 _Primitive-xor-reg-with-reg: # (payload primitive) +14899 0x11/imm32/alloc-id:fake:payload +14900 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 +14901 0x11/imm32/alloc-id:fake +14902 _string-xor/imm32/name +14903 0x11/imm32/alloc-id:fake +14904 Single-int-var-in-some-register/imm32/inouts +14905 0x11/imm32/alloc-id:fake +14906 Single-int-var-in-some-register/imm32/outputs +14907 0x11/imm32/alloc-id:fake +14908 _string_31_xor_with/imm32/subx-name +14909 3/imm32/rm32-is-first-output +14910 1/imm32/r32-is-first-inout +14911 0/imm32/no-imm32 +14912 0/imm32/no-disp32 +14913 0/imm32/output-is-write-only +14914 0x11/imm32/alloc-id:fake +14915 _Primitive-xor-reg-with-mem/imm32/next +14916 _Primitive-xor-reg-with-mem: # (payload primitive) 14917 0x11/imm32/alloc-id:fake:payload -14918 # "05/add-to-eax" -14919 0xd/imm32/size -14920 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 -14921 _string_09_or_with: # (payload array byte) -14922 0x11/imm32/alloc-id:fake:payload -14923 # "09/or-with" -14924 0xa/imm32/size -14925 0x30/0 0x39/9 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -14926 _string_0b_or: # (payload array byte) -14927 0x11/imm32/alloc-id:fake:payload -14928 # "0b/or" -14929 0x5/imm32/size -14930 0x30/0 0x62/b 0x2f/slash 0x6f/o 0x72/r -14931 _string_0d_or_with_eax: # (payload array byte) -14932 0x11/imm32/alloc-id:fake:payload -14933 # "0d/or-with-eax" -14934 0xe/imm32/size -14935 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 -14936 _string_0f_82_jump_label: # (payload array byte) -14937 0x11/imm32/alloc-id:fake:payload -14938 # "0f 82/jump-if-addr<" -14939 0x13/imm32/size -14940 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/< -14941 _string_0f_82_jump_break: # (payload array byte) -14942 0x11/imm32/alloc-id:fake:payload -14943 # "0f 82/jump-if-addr< break/disp32" -14944 0x20/imm32/size -14945 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 -14946 _string_0f_82_jump_loop: # (payload array byte) -14947 0x11/imm32/alloc-id:fake:payload -14948 # "0f 82/jump-if-addr< loop/disp32" -14949 0x1f/imm32/size -14950 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 -14951 _string_0f_83_jump_label: # (payload array byte) -14952 0x11/imm32/alloc-id:fake:payload -14953 # "0f 83/jump-if-addr>=" -14954 0x14/imm32/size -14955 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/= -14956 _string_0f_83_jump_break: # (payload array byte) -14957 0x11/imm32/alloc-id:fake:payload -14958 # "0f 83/jump-if-addr>= break/disp32" -14959 0x21/imm32/size -14960 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 -14961 _string_0f_83_jump_loop: # (payload array byte) -14962 0x11/imm32/alloc-id:fake:payload -14963 # "0f 83/jump-if-addr>= loop/disp32" -14964 0x20/imm32/size -14965 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 -14966 _string_0f_84_jump_label: # (payload array byte) -14967 0x11/imm32/alloc-id:fake:payload -14968 # "0f 84/jump-if-=" -14969 0xf/imm32/size -14970 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/= -14971 _string_0f_84_jump_break: # (payload array byte) -14972 0x11/imm32/alloc-id:fake:payload -14973 # "0f 84/jump-if-= break/disp32" -14974 0x1c/imm32/size -14975 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 -14976 _string_0f_84_jump_loop: # (payload array byte) -14977 0x11/imm32/alloc-id:fake:payload -14978 # "0f 84/jump-if-= loop/disp32" -14979 0x1b/imm32/size -14980 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 -14981 _string_0f_85_jump_label: # (payload array byte) -14982 0x11/imm32/alloc-id:fake:payload -14983 # "0f 85/jump-if-!=" -14984 0x10/imm32/size -14985 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/= -14986 _string_0f_85_jump_break: # (payload array byte) -14987 0x11/imm32/alloc-id:fake:payload -14988 # "0f 85/jump-if-!= break/disp32" -14989 0x1d/imm32/size -14990 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 -14991 _string_0f_85_jump_loop: # (payload array byte) -14992 0x11/imm32/alloc-id:fake:payload -14993 # "0f 85/jump-if-!= loop/disp32" -14994 0x1c/imm32/size -14995 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 -14996 _string_0f_86_jump_label: # (payload array byte) -14997 0x11/imm32/alloc-id:fake:payload -14998 # "0f 86/jump-if-addr<=" -14999 0x14/imm32/size -15000 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/= -15001 _string_0f_86_jump_break: # (payload array byte) -15002 0x11/imm32/alloc-id:fake:payload -15003 # "0f 86/jump-if-addr<= break/disp32" -15004 0x21/imm32/size -15005 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 -15006 _string_0f_86_jump_loop: # (payload array byte) -15007 0x11/imm32/alloc-id:fake:payload -15008 # "0f 86/jump-if-addr<= loop/disp32" -15009 0x20/imm32/size -15010 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 -15011 _string_0f_87_jump_label: # (payload array byte) -15012 0x11/imm32/alloc-id:fake:payload -15013 # "0f 87/jump-if-addr>" -15014 0x13/imm32/size -15015 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/> -15016 _string_0f_87_jump_break: # (payload array byte) -15017 0x11/imm32/alloc-id:fake:payload -15018 # "0f 87/jump-if-addr> break/disp32" -15019 0x20/imm32/size -15020 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 -15021 _string_0f_87_jump_loop: # (payload array byte) -15022 0x11/imm32/alloc-id:fake:payload -15023 # "0f 87/jump-if-addr> loop/disp32" -15024 0x1f/imm32/size -15025 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 -15026 _string_0f_8c_jump_label: # (payload array byte) -15027 0x11/imm32/alloc-id:fake:payload -15028 # "0f 8c/jump-if-<" -15029 0xf/imm32/size -15030 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/< -15031 _string_0f_8c_jump_break: # (payload array byte) -15032 0x11/imm32/alloc-id:fake:payload -15033 # "0f 8c/jump-if-< break/disp32" -15034 0x1c/imm32/size -15035 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 -15036 _string_0f_8c_jump_loop: # (payload array byte) -15037 0x11/imm32/alloc-id:fake:payload -15038 # "0f 8c/jump-if-< loop/disp32" -15039 0x1b/imm32/size -15040 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 -15041 _string_0f_8d_jump_label: # (payload array byte) -15042 0x11/imm32/alloc-id:fake:payload -15043 # "0f 8d/jump-if->=" -15044 0x10/imm32/size -15045 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/= -15046 _string_0f_8d_jump_break: # (payload array byte) -15047 0x11/imm32/alloc-id:fake:payload -15048 # "0f 8d/jump-if->= break/disp32" -15049 0x1d/imm32/size -15050 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 -15051 _string_0f_8d_jump_loop: # (payload array byte) -15052 0x11/imm32/alloc-id:fake:payload -15053 # "0f 8d/jump-if->= loop/disp32" -15054 0x1c/imm32/size -15055 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 -15056 _string_0f_8e_jump_label: # (payload array byte) -15057 0x11/imm32/alloc-id:fake:payload -15058 # "0f 8e/jump-if-<=" -15059 0x10/imm32/size -15060 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/= -15061 _string_0f_8e_jump_break: # (payload array byte) +14918 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 +14919 0x11/imm32/alloc-id:fake +14920 _string-xor-with/imm32/name +14921 0x11/imm32/alloc-id:fake +14922 Two-args-int-stack-int-reg/imm32/inouts +14923 0/imm32/no-outputs +14924 0/imm32/no-outputs +14925 0x11/imm32/alloc-id:fake +14926 _string_31_xor_with/imm32/subx-name +14927 1/imm32/rm32-is-first-inout +14928 2/imm32/r32-is-second-inout +14929 0/imm32/no-imm32 +14930 0/imm32/no-disp32 +14931 0/imm32/output-is-write-only +14932 0x11/imm32/alloc-id:fake +14933 _Primitive-xor-mem-with-reg/imm32/next +14934 _Primitive-xor-mem-with-reg: # (payload primitive) +14935 0x11/imm32/alloc-id:fake:payload +14936 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 +14937 0x11/imm32/alloc-id:fake +14938 _string-xor/imm32/name +14939 0x11/imm32/alloc-id:fake +14940 Single-int-var-in-mem/imm32/inouts +14941 0x11/imm32/alloc-id:fake +14942 Single-int-var-in-some-register/imm32/outputs +14943 0x11/imm32/alloc-id:fake +14944 _string_33_xor/imm32/subx-name +14945 1/imm32/rm32-is-first-inout +14946 3/imm32/r32-is-first-output +14947 0/imm32/no-imm32 +14948 0/imm32/no-disp32 +14949 0/imm32/output-is-write-only +14950 0x11/imm32/alloc-id:fake +14951 _Primitive-xor-lit-with-reg/imm32/next +14952 _Primitive-xor-lit-with-reg: # (payload primitive) +14953 0x11/imm32/alloc-id:fake:payload +14954 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 +14955 0x11/imm32/alloc-id:fake +14956 _string-xor/imm32/name +14957 0x11/imm32/alloc-id:fake +14958 Single-lit-var/imm32/inouts +14959 0x11/imm32/alloc-id:fake +14960 Single-int-var-in-some-register/imm32/outputs +14961 0x11/imm32/alloc-id:fake +14962 _string_81_subop_xor/imm32/subx-name +14963 3/imm32/rm32-is-first-output +14964 0/imm32/no-r32 +14965 1/imm32/imm32-is-first-inout +14966 0/imm32/no-disp32 +14967 0/imm32/output-is-write-only +14968 0x11/imm32/alloc-id:fake +14969 _Primitive-xor-lit-with-mem/imm32/next +14970 _Primitive-xor-lit-with-mem: # (payload primitive) +14971 0x11/imm32/alloc-id:fake:payload +14972 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 +14973 0x11/imm32/alloc-id:fake +14974 _string-xor-with/imm32/name +14975 0x11/imm32/alloc-id:fake +14976 Int-var-and-literal/imm32/inouts +14977 0/imm32/no-outputs +14978 0/imm32/no-outputs +14979 0x11/imm32/alloc-id:fake +14980 _string_81_subop_xor/imm32/subx-name +14981 1/imm32/rm32-is-first-inout +14982 0/imm32/no-r32 +14983 2/imm32/imm32-is-first-inout +14984 0/imm32/no-disp32 +14985 0/imm32/output-is-write-only +14986 0x11/imm32/alloc-id:fake +14987 _Primitive-copy-to-eax/imm32/next +14988 # - copy +14989 _Primitive-copy-to-eax: # (payload primitive) +14990 0x11/imm32/alloc-id:fake:payload +14991 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 +14992 0x11/imm32/alloc-id:fake +14993 _string-copy/imm32/name +14994 0x11/imm32/alloc-id:fake +14995 Single-lit-var/imm32/inouts +14996 0x11/imm32/alloc-id:fake +14997 Single-int-var-in-eax/imm32/outputs +14998 0x11/imm32/alloc-id:fake +14999 _string_b8_copy_to_eax/imm32/subx-name +15000 0/imm32/no-rm32 +15001 0/imm32/no-r32 +15002 1/imm32/imm32-is-first-inout +15003 0/imm32/no-disp32 +15004 1/imm32/output-is-write-only +15005 0x11/imm32/alloc-id:fake +15006 _Primitive-copy-to-ecx/imm32/next +15007 _Primitive-copy-to-ecx: # (payload primitive) +15008 0x11/imm32/alloc-id:fake:payload +15009 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 +15010 0x11/imm32/alloc-id:fake +15011 _string-copy/imm32/name +15012 0x11/imm32/alloc-id:fake +15013 Single-lit-var/imm32/inouts +15014 0x11/imm32/alloc-id:fake +15015 Single-int-var-in-ecx/imm32/outputs +15016 0x11/imm32/alloc-id:fake +15017 _string_b9_copy_to_ecx/imm32/subx-name +15018 0/imm32/no-rm32 +15019 0/imm32/no-r32 +15020 1/imm32/imm32-is-first-inout +15021 0/imm32/no-disp32 +15022 1/imm32/output-is-write-only +15023 0x11/imm32/alloc-id:fake +15024 _Primitive-copy-to-edx/imm32/next +15025 _Primitive-copy-to-edx: # (payload primitive) +15026 0x11/imm32/alloc-id:fake:payload +15027 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 +15028 0x11/imm32/alloc-id:fake +15029 _string-copy/imm32/name +15030 0x11/imm32/alloc-id:fake +15031 Single-lit-var/imm32/inouts +15032 0x11/imm32/alloc-id:fake +15033 Single-int-var-in-edx/imm32/outputs +15034 0x11/imm32/alloc-id:fake +15035 _string_ba_copy_to_edx/imm32/subx-name +15036 0/imm32/no-rm32 +15037 0/imm32/no-r32 +15038 1/imm32/imm32-is-first-inout +15039 0/imm32/no-disp32 +15040 1/imm32/output-is-write-only +15041 0x11/imm32/alloc-id:fake +15042 _Primitive-copy-to-ebx/imm32/next +15043 _Primitive-copy-to-ebx: # (payload primitive) +15044 0x11/imm32/alloc-id:fake:payload +15045 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 +15046 0x11/imm32/alloc-id:fake +15047 _string-copy/imm32/name +15048 0x11/imm32/alloc-id:fake +15049 Single-lit-var/imm32/inouts +15050 0x11/imm32/alloc-id:fake +15051 Single-int-var-in-ebx/imm32/outputs +15052 0x11/imm32/alloc-id:fake +15053 _string_bb_copy_to_ebx/imm32/subx-name +15054 0/imm32/no-rm32 +15055 0/imm32/no-r32 +15056 1/imm32/imm32-is-first-inout +15057 0/imm32/no-disp32 +15058 1/imm32/output-is-write-only +15059 0x11/imm32/alloc-id:fake +15060 _Primitive-copy-to-esi/imm32/next +15061 _Primitive-copy-to-esi: # (payload primitive) 15062 0x11/imm32/alloc-id:fake:payload -15063 # "0f 8e/jump-if-<= break/disp32" -15064 0x1d/imm32/size -15065 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 -15066 _string_0f_8e_jump_loop: # (payload array byte) -15067 0x11/imm32/alloc-id:fake:payload -15068 # "0f 8e/jump-if-<= loop/disp32" -15069 0x1c/imm32/size -15070 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 -15071 _string_0f_8f_jump_label: # (payload array byte) -15072 0x11/imm32/alloc-id:fake:payload -15073 # "0f 8f/jump-if->" -15074 0xf/imm32/size -15075 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/> -15076 _string_0f_8f_jump_break: # (payload array byte) -15077 0x11/imm32/alloc-id:fake:payload -15078 # "0f 8f/jump-if-> break/disp32" -15079 0x1c/imm32/size -15080 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 -15081 _string_0f_8f_jump_loop: # (payload array byte) -15082 0x11/imm32/alloc-id:fake:payload -15083 # "0f 8f/jump-if-> loop/disp32" -15084 0x1b/imm32/size -15085 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 -15086 _string_0f_af_multiply: # (payload array byte) -15087 0x11/imm32/alloc-id:fake:payload -15088 # "0f af/multiply" -15089 0xe/imm32/size -15090 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 -15091 _string_21_and_with: # (payload array byte) -15092 0x11/imm32/alloc-id:fake:payload -15093 # "21/and-with" -15094 0xb/imm32/size -15095 0x32/2 0x31/1 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -15096 _string_23_and: # (payload array byte) -15097 0x11/imm32/alloc-id:fake:payload -15098 # "23/and" -15099 0x6/imm32/size -15100 0x32/2 0x33/3 0x2f/slash 0x61/a 0x6e/n 0x64/d -15101 _string_25_and_with_eax: # (payload array byte) -15102 0x11/imm32/alloc-id:fake:payload -15103 # "25/and-with-eax" -15104 0xf/imm32/size -15105 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 -15106 _string_29_subtract_from: # (payload array byte) -15107 0x11/imm32/alloc-id:fake:payload -15108 # "29/subtract-from" -15109 0x10/imm32/size -15110 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 -15111 _string_2b_subtract: # (payload array byte) -15112 0x11/imm32/alloc-id:fake:payload -15113 # "2b/subtract" -15114 0xb/imm32/size -15115 0x32/2 0x62/b 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t -15116 _string_2d_subtract_from_eax: # (payload array byte) -15117 0x11/imm32/alloc-id:fake:payload -15118 # "2d/subtract-from-eax" -15119 0x14/imm32/size -15120 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 -15121 _string_31_xor_with: # (payload array byte) -15122 0x11/imm32/alloc-id:fake:payload -15123 # "31/xor-with" -15124 0xb/imm32/size -15125 0x33/3 0x31/1 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h -15126 _string_33_xor: # (payload array byte) -15127 0x11/imm32/alloc-id:fake:payload -15128 # "33/xor" -15129 0x6/imm32/size -15130 0x33/3 0x33/3 0x2f/slash 0x78/x 0x6f/o 0x72/r -15131 _string_35_xor_with_eax: # (payload array byte) -15132 0x11/imm32/alloc-id:fake:payload -15133 # "35/xor-with-eax" -15134 0xf/imm32/size -15135 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 -15136 _string_39_compare->: # (payload array byte) -15137 0x11/imm32/alloc-id:fake:payload -15138 # "39/compare->" -15139 0xc/imm32/size -15140 0x33/3 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x3e/> -15141 _string_3b_compare<-: # (payload array byte) -15142 0x11/imm32/alloc-id:fake:payload -15143 # "3b/compare<-" -15144 0xc/imm32/size -15145 0x33/3 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x3c/< 0x2d/dash -15146 _string_3d_compare_eax_with: # (payload array byte) -15147 0x11/imm32/alloc-id:fake:payload -15148 # "3d/compare-eax-with" -15149 0x13/imm32/size -15150 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 -15151 _string_40_increment_eax: # (payload array byte) +15063 # var/esi <- copy lit => be/copy-to-esi lit/imm32 +15064 0x11/imm32/alloc-id:fake +15065 _string-copy/imm32/name +15066 0x11/imm32/alloc-id:fake +15067 Single-lit-var/imm32/inouts +15068 0x11/imm32/alloc-id:fake +15069 Single-int-var-in-esi/imm32/outputs +15070 0x11/imm32/alloc-id:fake +15071 _string_be_copy_to_esi/imm32/subx-name +15072 0/imm32/no-rm32 +15073 0/imm32/no-r32 +15074 1/imm32/imm32-is-first-inout +15075 0/imm32/no-disp32 +15076 1/imm32/output-is-write-only +15077 0x11/imm32/alloc-id:fake +15078 _Primitive-copy-to-edi/imm32/next +15079 _Primitive-copy-to-edi: # (payload primitive) +15080 0x11/imm32/alloc-id:fake:payload +15081 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 +15082 0x11/imm32/alloc-id:fake +15083 _string-copy/imm32/name +15084 0x11/imm32/alloc-id:fake +15085 Single-lit-var/imm32/inouts +15086 0x11/imm32/alloc-id:fake +15087 Single-int-var-in-edi/imm32/outputs +15088 0x11/imm32/alloc-id:fake +15089 _string_bf_copy_to_edi/imm32/subx-name +15090 0/imm32/no-rm32 +15091 0/imm32/no-r32 +15092 1/imm32/imm32-is-first-inout +15093 0/imm32/no-disp32 +15094 1/imm32/output-is-write-only +15095 0x11/imm32/alloc-id:fake +15096 _Primitive-copy-reg-to-reg/imm32/next +15097 _Primitive-copy-reg-to-reg: # (payload primitive) +15098 0x11/imm32/alloc-id:fake:payload +15099 # var1/reg <- copy var2/reg => 89/<- var1/rm32 var2/r32 +15100 0x11/imm32/alloc-id:fake +15101 _string-copy/imm32/name +15102 0x11/imm32/alloc-id:fake +15103 Single-int-var-in-some-register/imm32/inouts +15104 0x11/imm32/alloc-id:fake +15105 Single-int-var-in-some-register/imm32/outputs +15106 0x11/imm32/alloc-id:fake +15107 _string_89_<-/imm32/subx-name +15108 3/imm32/rm32-is-first-output +15109 1/imm32/r32-is-first-inout +15110 0/imm32/no-imm32 +15111 0/imm32/no-disp32 +15112 1/imm32/output-is-write-only +15113 0x11/imm32/alloc-id:fake +15114 _Primitive-copy-reg-to-mem/imm32/next +15115 _Primitive-copy-reg-to-mem: # (payload primitive) +15116 0x11/imm32/alloc-id:fake:payload +15117 # copy-to var1 var2/reg => 89/<- var1 var2/r32 +15118 0x11/imm32/alloc-id:fake +15119 _string-copy-to/imm32/name +15120 0x11/imm32/alloc-id:fake +15121 Two-args-int-stack-int-reg/imm32/inouts +15122 0/imm32/no-outputs +15123 0/imm32/no-outputs +15124 0x11/imm32/alloc-id:fake +15125 _string_89_<-/imm32/subx-name +15126 1/imm32/rm32-is-first-inout +15127 2/imm32/r32-is-second-inout +15128 0/imm32/no-imm32 +15129 0/imm32/no-disp32 +15130 1/imm32/output-is-write-only +15131 0x11/imm32/alloc-id:fake +15132 _Primitive-copy-mem-to-reg/imm32/next +15133 _Primitive-copy-mem-to-reg: # (payload primitive) +15134 0x11/imm32/alloc-id:fake:payload +15135 # var1/reg <- copy var2 => 8b/-> var2/rm32 var1/r32 +15136 0x11/imm32/alloc-id:fake +15137 _string-copy/imm32/name +15138 0x11/imm32/alloc-id:fake +15139 Single-int-var-in-mem/imm32/inouts +15140 0x11/imm32/alloc-id:fake +15141 Single-int-var-in-some-register/imm32/outputs +15142 0x11/imm32/alloc-id:fake +15143 _string_8b_->/imm32/subx-name +15144 1/imm32/rm32-is-first-inout +15145 3/imm32/r32-is-first-output +15146 0/imm32/no-imm32 +15147 0/imm32/no-disp32 +15148 1/imm32/output-is-write-only +15149 0x11/imm32/alloc-id:fake +15150 _Primitive-copy-lit-to-reg/imm32/next +15151 _Primitive-copy-lit-to-reg: # (payload primitive) 15152 0x11/imm32/alloc-id:fake:payload -15153 # "40/increment-eax" -15154 0x10/imm32/size -15155 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 -15156 _string_41_increment_ecx: # (payload array byte) -15157 0x11/imm32/alloc-id:fake:payload -15158 # "41/increment-ecx" -15159 0x10/imm32/size -15160 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 -15161 _string_42_increment_edx: # (payload array byte) -15162 0x11/imm32/alloc-id:fake:payload -15163 # "42/increment-edx" -15164 0x10/imm32/size -15165 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 -15166 _string_43_increment_ebx: # (payload array byte) -15167 0x11/imm32/alloc-id:fake:payload -15168 # "43/increment-ebx" -15169 0x10/imm32/size -15170 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 -15171 _string_46_increment_esi: # (payload array byte) -15172 0x11/imm32/alloc-id:fake:payload -15173 # "46/increment-esi" -15174 0x10/imm32/size -15175 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 -15176 _string_47_increment_edi: # (payload array byte) -15177 0x11/imm32/alloc-id:fake:payload -15178 # "47/increment-edi" -15179 0x10/imm32/size -15180 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 -15181 _string_48_decrement_eax: # (payload array byte) -15182 0x11/imm32/alloc-id:fake:payload -15183 # "48/decrement-eax" -15184 0x10/imm32/size -15185 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 -15186 _string_49_decrement_ecx: # (payload array byte) -15187 0x11/imm32/alloc-id:fake:payload -15188 # "49/decrement-ecx" -15189 0x10/imm32/size -15190 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 -15191 _string_4a_decrement_edx: # (payload array byte) -15192 0x11/imm32/alloc-id:fake:payload -15193 # "4a/decrement-edx" -15194 0x10/imm32/size -15195 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 -15196 _string_4b_decrement_ebx: # (payload array byte) -15197 0x11/imm32/alloc-id:fake:payload -15198 # "4b/decrement-ebx" -15199 0x10/imm32/size -15200 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 -15201 _string_4e_decrement_esi: # (payload array byte) -15202 0x11/imm32/alloc-id:fake:payload -15203 # "4e/decrement-esi" -15204 0x10/imm32/size -15205 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 -15206 _string_4f_decrement_edi: # (payload array byte) +15153 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 +15154 0x11/imm32/alloc-id:fake +15155 _string-copy/imm32/name +15156 0x11/imm32/alloc-id:fake +15157 Single-lit-var/imm32/inouts +15158 0x11/imm32/alloc-id:fake +15159 Single-int-var-in-some-register/imm32/outputs +15160 0x11/imm32/alloc-id:fake +15161 _string_c7_subop_copy/imm32/subx-name +15162 3/imm32/rm32-is-first-output +15163 0/imm32/no-r32 +15164 1/imm32/imm32-is-first-inout +15165 0/imm32/no-disp32 +15166 1/imm32/output-is-write-only +15167 0x11/imm32/alloc-id:fake +15168 _Primitive-copy-lit-to-mem/imm32/next +15169 _Primitive-copy-lit-to-mem: # (payload primitive) +15170 0x11/imm32/alloc-id:fake:payload +15171 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 +15172 0x11/imm32/alloc-id:fake +15173 _string-copy-to/imm32/name +15174 0x11/imm32/alloc-id:fake +15175 Int-var-and-literal/imm32/inouts +15176 0/imm32/no-outputs +15177 0/imm32/no-outputs +15178 0x11/imm32/alloc-id:fake +15179 _string_c7_subop_copy/imm32/subx-name +15180 1/imm32/rm32-is-first-inout +15181 0/imm32/no-r32 +15182 2/imm32/imm32-is-first-inout +15183 0/imm32/no-disp32 +15184 1/imm32/output-is-write-only +15185 0x11/imm32/alloc-id:fake +15186 _Primitive-copy-byte-from-reg/imm32/next +15187 # - copy byte +15188 _Primitive-copy-byte-from-reg: +15189 0x11/imm32/alloc-id:fake:payload +15190 # var/reg <- copy-byte var2/reg2 => 8a/byte-> %var2 var/r32 +15191 0x11/imm32/alloc-id:fake +15192 _string-copy-byte/imm32/name +15193 0x11/imm32/alloc-id:fake +15194 Single-byte-var-in-some-register/imm32/inouts +15195 0x11/imm32/alloc-id:fake +15196 Single-byte-var-in-some-register/imm32/outputs +15197 0x11/imm32/alloc-id:fake +15198 _string_8a_copy_byte/imm32/subx-name +15199 1/imm32/rm32-is-first-inout +15200 3/imm32/r32-is-first-output +15201 0/imm32/no-imm32 +15202 0/imm32/no-disp32 +15203 1/imm32/output-is-write-only +15204 0x11/imm32/alloc-id:fake +15205 _Primitive-copy-byte-from-mem/imm32/next +15206 _Primitive-copy-byte-from-mem: 15207 0x11/imm32/alloc-id:fake:payload -15208 # "4f/decrement-edi" -15209 0x10/imm32/size -15210 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 -15211 _string_81_subop_add: # (payload array byte) -15212 0x11/imm32/alloc-id:fake:payload -15213 # "81 0/subop/add" -15214 0xe/imm32/size -15215 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 -15216 _string_81_subop_or: # (payload array byte) -15217 0x11/imm32/alloc-id:fake:payload -15218 # "81 1/subop/or" -15219 0xd/imm32/size -15220 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 -15221 _string_81_subop_and: # (payload array byte) -15222 0x11/imm32/alloc-id:fake:payload -15223 # "81 4/subop/and" -15224 0xe/imm32/size -15225 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 -15226 _string_81_subop_subtract: # (payload array byte) -15227 0x11/imm32/alloc-id:fake:payload -15228 # "81 5/subop/subtract" -15229 0x13/imm32/size -15230 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 -15231 _string_81_subop_xor: # (payload array byte) -15232 0x11/imm32/alloc-id:fake:payload -15233 # "81 6/subop/xor" -15234 0xe/imm32/size -15235 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 -15236 _string_81_subop_compare: # (payload array byte) -15237 0x11/imm32/alloc-id:fake:payload -15238 # "81 7/subop/compare" -15239 0x12/imm32/size -15240 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 -15241 _string_89_<-: # (payload array byte) -15242 0x11/imm32/alloc-id:fake:payload -15243 # "89/<-" -15244 0x5/imm32/size -15245 0x38/8 0x39/9 0x2f/slash 0x3c/< 0x2d/dash -15246 _string_8b_->: # (payload array byte) -15247 0x11/imm32/alloc-id:fake:payload -15248 # "8b/->" -15249 0x5/imm32/size -15250 0x38/8 0x62/b 0x2f/slash 0x2d/dash 0x3e/> -15251 _string_8a_copy_byte: -15252 0x11/imm32/alloc-id:fake:payload -15253 # "8a/byte->" -15254 0x9/imm32/size -15255 0x38/8 0x61/a 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x3e/> -15256 _string_88_copy_byte: -15257 0x11/imm32/alloc-id:fake:payload -15258 # "88/byte<-" -15259 0x9/imm32/size -15260 0x38/8 0x38/8 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/- -15261 _string_8d_copy_address: # (payload array byte) -15262 0x11/imm32/alloc-id:fake:payload -15263 # "8d/copy-address" -15264 0xf/imm32/size -15265 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 -15266 _string_b8_copy_to_eax: # (payload array byte) -15267 0x11/imm32/alloc-id:fake:payload -15268 # "b8/copy-to-eax" -15269 0xe/imm32/size -15270 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 -15271 _string_b9_copy_to_ecx: # (payload array byte) -15272 0x11/imm32/alloc-id:fake:payload -15273 # "b9/copy-to-ecx" -15274 0xe/imm32/size -15275 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 -15276 _string_ba_copy_to_edx: # (payload array byte) -15277 0x11/imm32/alloc-id:fake:payload -15278 # "ba/copy-to-edx" -15279 0xe/imm32/size -15280 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 -15281 _string_bb_copy_to_ebx: # (payload array byte) -15282 0x11/imm32/alloc-id:fake:payload -15283 # "bb/copy-to-ebx" -15284 0xe/imm32/size -15285 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 -15286 _string_be_copy_to_esi: # (payload array byte) -15287 0x11/imm32/alloc-id:fake:payload -15288 # "be/copy-to-esi" -15289 0xe/imm32/size -15290 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 -15291 _string_bf_copy_to_edi: # (payload array byte) -15292 0x11/imm32/alloc-id:fake:payload -15293 # "bf/copy-to-edi" -15294 0xe/imm32/size -15295 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 -15296 _string_c7_subop_copy: # (payload array byte) -15297 0x11/imm32/alloc-id:fake:payload -15298 # "c7 0/subop/copy" -15299 0xf/imm32/size -15300 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 -15301 _string_e9_jump_label: # (payload array byte) -15302 0x11/imm32/alloc-id:fake:payload -15303 # "e9/jump" -15304 0x7/imm32/size -15305 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p -15306 _string_e9_jump_break: # (payload array byte) -15307 0x11/imm32/alloc-id:fake:payload -15308 # "e9/jump break/disp32" -15309 0x14/imm32/size -15310 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 -15311 _string_e9_jump_loop: # (payload array byte) -15312 0x11/imm32/alloc-id:fake:payload -15313 # "e9/jump loop/disp32" -15314 0x13/imm32/size -15315 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 -15316 _string_ff_subop_increment: # (payload array byte) +15208 # var/reg <- copy-byte *var2/reg2 => 8a/byte-> *var2 var/r32 +15209 0x11/imm32/alloc-id:fake +15210 _string-copy-byte/imm32/name +15211 0x11/imm32/alloc-id:fake +15212 Single-byte-var-in-mem/imm32/inouts +15213 0x11/imm32/alloc-id:fake +15214 Single-byte-var-in-some-register/imm32/outputs +15215 0x11/imm32/alloc-id:fake +15216 _string_8a_copy_byte/imm32/subx-name +15217 1/imm32/rm32-is-first-inout +15218 3/imm32/r32-is-first-output +15219 0/imm32/no-imm32 +15220 0/imm32/no-disp32 +15221 1/imm32/output-is-write-only +15222 0x11/imm32/alloc-id:fake +15223 _Primitive-copy-byte-to-mem/imm32/next +15224 _Primitive-copy-byte-to-mem: +15225 0x11/imm32/alloc-id:fake:payload +15226 # copy-byte-to *var1/reg1, var2/reg2 => 88/byte<- *reg1 reg2/r32 +15227 0x11/imm32/alloc-id:fake +15228 _string-copy-byte-to/imm32/name +15229 0x11/imm32/alloc-id:fake +15230 Two-args-byte-stack-byte-reg/imm32/inouts +15231 0/imm32/no-outputs +15232 0/imm32/no-outputs +15233 0x11/imm32/alloc-id:fake +15234 _string_88_copy_byte/imm32/subx-name +15235 1/imm32/rm32-is-first-inout +15236 2/imm32/r32-is-second-inout +15237 0/imm32/no-imm32 +15238 0/imm32/no-disp32 +15239 0/imm32/output-is-write-only +15240 0x11/imm32/alloc-id:fake +15241 _Primitive-address/imm32/next +15242 # - address +15243 _Primitive-address: # (payload primitive) +15244 0x11/imm32/alloc-id:fake:payload +15245 # var1/reg <- address var2 => 8d/copy-address var2/rm32 var1/r32 +15246 0x11/imm32/alloc-id:fake +15247 _string-address/imm32/name +15248 0x11/imm32/alloc-id:fake +15249 Single-int-var-in-mem/imm32/inouts +15250 0x11/imm32/alloc-id:fake +15251 Single-addr-var-in-some-register/imm32/outputs +15252 0x11/imm32/alloc-id:fake +15253 _string_8d_copy_address/imm32/subx-name +15254 1/imm32/rm32-is-first-inout +15255 3/imm32/r32-is-first-output +15256 0/imm32/no-imm32 +15257 0/imm32/no-disp32 +15258 1/imm32/output-is-write-only +15259 0x11/imm32/alloc-id:fake +15260 _Primitive-compare-reg-with-reg/imm32/next +15261 # - compare +15262 _Primitive-compare-reg-with-reg: # (payload primitive) +15263 0x11/imm32/alloc-id:fake:payload +15264 # compare var1/reg1 var2/reg2 => 39/compare var1/rm32 var2/r32 +15265 0x11/imm32/alloc-id:fake +15266 _string-compare/imm32/name +15267 0x11/imm32/alloc-id:fake +15268 Two-int-args-in-regs/imm32/inouts +15269 0/imm32/no-outputs +15270 0/imm32/no-outputs +15271 0x11/imm32/alloc-id:fake +15272 _string_39_compare->/imm32/subx-name +15273 1/imm32/rm32-is-first-inout +15274 2/imm32/r32-is-second-inout +15275 0/imm32/no-imm32 +15276 0/imm32/no-disp32 +15277 0/imm32/output-is-write-only +15278 0x11/imm32/alloc-id:fake +15279 _Primitive-compare-mem-with-reg/imm32/next +15280 _Primitive-compare-mem-with-reg: # (payload primitive) +15281 0x11/imm32/alloc-id:fake:payload +15282 # compare var1 var2/reg => 39/compare var1/rm32 var2/r32 +15283 0x11/imm32/alloc-id:fake +15284 _string-compare/imm32/name +15285 0x11/imm32/alloc-id:fake +15286 Two-args-int-stack-int-reg/imm32/inouts +15287 0/imm32/no-outputs +15288 0/imm32/no-outputs +15289 0x11/imm32/alloc-id:fake +15290 _string_39_compare->/imm32/subx-name +15291 1/imm32/rm32-is-first-inout +15292 2/imm32/r32-is-second-inout +15293 0/imm32/no-imm32 +15294 0/imm32/no-disp32 +15295 0/imm32/output-is-write-only +15296 0x11/imm32/alloc-id:fake +15297 _Primitive-compare-reg-with-mem/imm32/next +15298 _Primitive-compare-reg-with-mem: # (payload primitive) +15299 0x11/imm32/alloc-id:fake:payload +15300 # compare var1/reg var2 => 3b/compare<- var2/rm32 var1/r32 +15301 0x11/imm32/alloc-id:fake +15302 _string-compare/imm32/name +15303 0x11/imm32/alloc-id:fake +15304 Two-args-int-reg-int-stack/imm32/inouts +15305 0/imm32/no-outputs +15306 0/imm32/no-outputs +15307 0x11/imm32/alloc-id:fake +15308 _string_3b_compare<-/imm32/subx-name +15309 2/imm32/rm32-is-second-inout +15310 1/imm32/r32-is-first-inout +15311 0/imm32/no-imm32 +15312 0/imm32/no-disp32 +15313 0/imm32/output-is-write-only +15314 0x11/imm32/alloc-id:fake +15315 _Primitive-compare-eax-with-literal/imm32/next +15316 _Primitive-compare-eax-with-literal: # (payload primitive) 15317 0x11/imm32/alloc-id:fake:payload -15318 # "ff 0/subop/increment" -15319 0x14/imm32/size -15320 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 -15321 _string_ff_subop_decrement: # (payload array byte) -15322 0x11/imm32/alloc-id:fake:payload -15323 # "ff 1/subop/decrement" -15324 0x14/imm32/size -15325 0x66/f 0x66/f 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 -15326 -15327 Single-int-var-in-mem: # (payload list var) -15328 0x11/imm32/alloc-id:fake:payload -15329 0x11/imm32/alloc-id:fake -15330 Int-var-in-mem/imm32 -15331 0/imm32/next -15332 0/imm32/next -15333 -15334 Int-var-in-mem: # (payload var) +15318 # compare var1/eax n => 3d/compare-eax-with n/imm32 +15319 0x11/imm32/alloc-id:fake +15320 _string-compare/imm32/name +15321 0x11/imm32/alloc-id:fake +15322 Two-args-int-eax-int-literal/imm32/inouts +15323 0/imm32/no-outputs +15324 0/imm32/no-outputs +15325 0x11/imm32/alloc-id:fake +15326 _string_3d_compare_eax_with/imm32/subx-name +15327 0/imm32/no-rm32 +15328 0/imm32/no-r32 +15329 2/imm32/imm32-is-second-inout +15330 0/imm32/no-disp32 +15331 0/imm32/output-is-write-only +15332 0x11/imm32/alloc-id:fake +15333 _Primitive-compare-reg-with-literal/imm32/next +15334 _Primitive-compare-reg-with-literal: # (payload primitive) 15335 0x11/imm32/alloc-id:fake:payload -15336 0/imm32/name -15337 0/imm32/name -15338 0x11/imm32/alloc-id:fake -15339 Type-int/imm32 -15340 1/imm32/some-block-depth -15341 1/imm32/some-stack-offset -15342 0/imm32/no-register -15343 0/imm32/no-register -15344 -15345 # Not really legal, but closest we can currently represent a dereference of an (addr byte) -15346 Single-byte-var-in-mem: # (payload list var) -15347 0x11/imm32/alloc-id:fake:payload -15348 0x11/imm32/alloc-id:fake -15349 Byte-var-in-mem/imm32 -15350 0/imm32/next -15351 0/imm32/next -15352 -15353 # Not really legal, but closest we can currently represent a dereference of an (addr byte) -15354 Byte-var-in-mem: # (payload var) -15355 0x11/imm32/alloc-id:fake:payload -15356 0/imm32/name -15357 0/imm32/name -15358 0x11/imm32/alloc-id:fake -15359 Type-byte/imm32 -15360 1/imm32/some-block-depth -15361 1/imm32/some-stack-offset -15362 0/imm32/no-register -15363 0/imm32/no-register -15364 -15365 Two-args-int-stack-int-reg: # (payload list var) -15366 0x11/imm32/alloc-id:fake:payload -15367 0x11/imm32/alloc-id:fake -15368 Int-var-in-mem/imm32 -15369 0x11/imm32/alloc-id:fake -15370 Single-int-var-in-some-register/imm32/next -15371 -15372 Two-int-args-in-regs: # (payload list var) -15373 0x11/imm32/alloc-id:fake:payload +15336 # compare var1/reg n => 81 7/subop/compare %reg n/imm32 +15337 0x11/imm32/alloc-id:fake +15338 _string-compare/imm32/name +15339 0x11/imm32/alloc-id:fake +15340 Int-var-in-register-and-literal/imm32/inouts +15341 0/imm32/no-outputs +15342 0/imm32/no-outputs +15343 0x11/imm32/alloc-id:fake +15344 _string_81_subop_compare/imm32/subx-name +15345 1/imm32/rm32-is-first-inout +15346 0/imm32/no-r32 +15347 2/imm32/imm32-is-second-inout +15348 0/imm32/no-disp32 +15349 0/imm32/output-is-write-only +15350 0x11/imm32/alloc-id:fake +15351 _Primitive-compare-mem-with-literal/imm32/next +15352 _Primitive-compare-mem-with-literal: # (payload primitive) +15353 0x11/imm32/alloc-id:fake:payload +15354 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32 +15355 0x11/imm32/alloc-id:fake +15356 _string-compare/imm32/name +15357 0x11/imm32/alloc-id:fake +15358 Int-var-and-literal/imm32/inouts +15359 0/imm32/no-outputs +15360 0/imm32/no-outputs +15361 0x11/imm32/alloc-id:fake +15362 _string_81_subop_compare/imm32/subx-name +15363 1/imm32/rm32-is-first-inout +15364 0/imm32/no-r32 +15365 2/imm32/imm32-is-second-inout +15366 0/imm32/no-disp32 +15367 0/imm32/output-is-write-only +15368 0x11/imm32/alloc-id:fake +15369 _Primitive-multiply-reg-by-reg/imm32/next +15370 # - multiply +15371 _Primitive-multiply-reg-by-reg: # (payload primitive) +15372 0x11/imm32/alloc-id:fake:payload +15373 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 15374 0x11/imm32/alloc-id:fake -15375 Int-var-in-some-register/imm32 +15375 _string-multiply/imm32/name 15376 0x11/imm32/alloc-id:fake -15377 Single-int-var-in-some-register/imm32/next -15378 -15379 # Not really legal, but closest we can currently represent a dereference of an (addr byte) -15380 Two-args-byte-stack-byte-reg: # (payload list var) -15381 0x11/imm32/alloc-id:fake:payload -15382 0x11/imm32/alloc-id:fake -15383 Byte-var-in-mem/imm32 -15384 0x11/imm32/alloc-id:fake -15385 Single-byte-var-in-some-register/imm32/next -15386 -15387 Two-args-int-reg-int-stack: # (payload list var) -15388 0x11/imm32/alloc-id:fake:payload -15389 0x11/imm32/alloc-id:fake -15390 Int-var-in-some-register/imm32 -15391 0x11/imm32/alloc-id:fake -15392 Single-int-var-in-mem/imm32/next -15393 -15394 Two-args-int-eax-int-literal: # (payload list var) -15395 0x11/imm32/alloc-id:fake:payload +15377 Single-int-var-in-some-register/imm32/inouts +15378 0x11/imm32/alloc-id:fake +15379 Single-int-var-in-some-register/imm32/outputs +15380 0x11/imm32/alloc-id:fake +15381 _string_0f_af_multiply/imm32/subx-name +15382 1/imm32/rm32-is-first-inout +15383 3/imm32/r32-is-first-output +15384 0/imm32/no-imm32 +15385 0/imm32/no-disp32 +15386 0/imm32/output-is-write-only +15387 0x11/imm32/alloc-id:fake +15388 _Primitive-multiply-reg-by-mem/imm32/next +15389 _Primitive-multiply-reg-by-mem: # (payload primitive) +15390 0x11/imm32/alloc-id:fake:payload +15391 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 +15392 0x11/imm32/alloc-id:fake +15393 _string-multiply/imm32/name +15394 0x11/imm32/alloc-id:fake +15395 Single-int-var-in-mem/imm32/inouts 15396 0x11/imm32/alloc-id:fake -15397 Int-var-in-eax/imm32 +15397 Single-int-var-in-some-register/imm32/outputs 15398 0x11/imm32/alloc-id:fake -15399 Single-lit-var/imm32/next -15400 -15401 Int-var-and-literal: # (payload list var) -15402 0x11/imm32/alloc-id:fake:payload -15403 0x11/imm32/alloc-id:fake -15404 Int-var-in-mem/imm32 +15399 _string_0f_af_multiply/imm32/subx-name +15400 1/imm32/rm32-is-first-inout +15401 3/imm32/r32-is-first-output +15402 0/imm32/no-imm32 +15403 0/imm32/no-disp32 +15404 0/imm32/output-is-write-only 15405 0x11/imm32/alloc-id:fake -15406 Single-lit-var/imm32/next -15407 -15408 Int-var-in-register-and-literal: # (payload list var) +15406 _Primitive-break-if-addr</imm32/next +15407 # - branches +15408 _Primitive-break-if-addr<: # (payload primitive) 15409 0x11/imm32/alloc-id:fake:payload 15410 0x11/imm32/alloc-id:fake -15411 Int-var-in-some-register/imm32 -15412 0x11/imm32/alloc-id:fake -15413 Single-lit-var/imm32/next -15414 -15415 Single-int-var-in-some-register: # (payload list var) -15416 0x11/imm32/alloc-id:fake:payload -15417 0x11/imm32/alloc-id:fake -15418 Int-var-in-some-register/imm32 -15419 0/imm32/next -15420 0/imm32/next -15421 -15422 Single-addr-var-in-some-register: # (payload list var) -15423 0x11/imm32/alloc-id:fake:payload -15424 0x11/imm32/alloc-id:fake -15425 Addr-var-in-some-register/imm32 -15426 0/imm32/next -15427 0/imm32/next -15428 -15429 Single-byte-var-in-some-register: # (payload list var) -15430 0x11/imm32/alloc-id:fake:payload -15431 0x11/imm32/alloc-id:fake -15432 Byte-var-in-some-register/imm32 -15433 0/imm32/next -15434 0/imm32/next -15435 -15436 Int-var-in-some-register: # (payload var) -15437 0x11/imm32/alloc-id:fake:payload -15438 0/imm32/name -15439 0/imm32/name +15411 _string-break-if-addr</imm32/name +15412 0/imm32/no-inouts +15413 0/imm32/no-inouts +15414 0/imm32/no-outputs +15415 0/imm32/no-outputs +15416 0x11/imm32/alloc-id:fake +15417 _string_0f_82_jump_break/imm32/subx-name +15418 0/imm32/no-rm32 +15419 0/imm32/no-r32 +15420 0/imm32/no-imm32 +15421 0/imm32/no-disp32 +15422 0/imm32/no-output +15423 0x11/imm32/alloc-id:fake +15424 _Primitive-break-if-addr>=/imm32/next +15425 _Primitive-break-if-addr>=: # (payload primitive) +15426 0x11/imm32/alloc-id:fake:payload +15427 0x11/imm32/alloc-id:fake +15428 _string-break-if-addr>=/imm32/name +15429 0/imm32/no-inouts +15430 0/imm32/no-inouts +15431 0/imm32/no-outputs +15432 0/imm32/no-outputs +15433 0x11/imm32/alloc-id:fake +15434 _string_0f_83_jump_break/imm32/subx-name +15435 0/imm32/no-rm32 +15436 0/imm32/no-r32 +15437 0/imm32/no-imm32 +15438 0/imm32/no-disp32 +15439 0/imm32/no-output 15440 0x11/imm32/alloc-id:fake -15441 Type-int/imm32 -15442 1/imm32/some-block-depth -15443 0/imm32/no-stack-offset +15441 _Primitive-break-if-=/imm32/next +15442 _Primitive-break-if-=: # (payload primitive) +15443 0x11/imm32/alloc-id:fake:payload 15444 0x11/imm32/alloc-id:fake -15445 Any-register/imm32 -15446 -15447 Any-register: # (payload array byte) -15448 0x11/imm32/alloc-id:fake:payload -15449 1/imm32/size -15450 # data -15451 2a/asterisk -15452 -15453 Addr-var-in-some-register: # (payload var) -15454 0x11/imm32/alloc-id:fake:payload -15455 0/imm32/name -15456 0/imm32/name +15445 _string-break-if-=/imm32/name +15446 0/imm32/no-inouts +15447 0/imm32/no-inouts +15448 0/imm32/no-outputs +15449 0/imm32/no-outputs +15450 0x11/imm32/alloc-id:fake +15451 _string_0f_84_jump_break/imm32/subx-name +15452 0/imm32/no-rm32 +15453 0/imm32/no-r32 +15454 0/imm32/no-imm32 +15455 0/imm32/no-disp32 +15456 0/imm32/no-output 15457 0x11/imm32/alloc-id:fake -15458 Type-addr/imm32 -15459 1/imm32/some-block-depth -15460 0/imm32/no-stack-offset +15458 _Primitive-break-if-!=/imm32/next +15459 _Primitive-break-if-!=: # (payload primitive) +15460 0x11/imm32/alloc-id:fake:payload 15461 0x11/imm32/alloc-id:fake -15462 Any-register/imm32 -15463 -15464 Byte-var-in-some-register: # (payload var) -15465 0x11/imm32/alloc-id:fake:payload -15466 0/imm32/name -15467 0/imm32/name -15468 0x11/imm32/alloc-id:fake -15469 Type-byte/imm32 -15470 1/imm32/some-block-depth -15471 0/imm32/no-stack-offset -15472 0x11/imm32/alloc-id:fake -15473 Any-register/imm32 -15474 -15475 Single-int-var-in-eax: # (payload list var) -15476 0x11/imm32/alloc-id:fake:payload -15477 0x11/imm32/alloc-id:fake -15478 Int-var-in-eax/imm32 -15479 0/imm32/next -15480 0/imm32/next -15481 -15482 Int-var-in-eax: -15483 0x11/imm32/alloc-id:fake:payload -15484 0/imm32/name -15485 0/imm32/name -15486 0x11/imm32/alloc-id:fake -15487 Type-int/imm32 -15488 1/imm32/some-block-depth -15489 0/imm32/no-stack-offset -15490 0x11/imm32/alloc-id:fake -15491 $Register-eax/imm32 -15492 -15493 Single-int-var-in-ecx: # (payload list var) +15462 _string-break-if-!=/imm32/name +15463 0/imm32/no-inouts +15464 0/imm32/no-inouts +15465 0/imm32/no-outputs +15466 0/imm32/no-outputs +15467 0x11/imm32/alloc-id:fake +15468 _string_0f_85_jump_break/imm32/subx-name +15469 0/imm32/no-rm32 +15470 0/imm32/no-r32 +15471 0/imm32/no-imm32 +15472 0/imm32/no-disp32 +15473 0/imm32/no-output +15474 0x11/imm32/alloc-id:fake +15475 _Primitive-break-if-addr<=/imm32/next +15476 _Primitive-break-if-addr<=: # (payload primitive) +15477 0x11/imm32/alloc-id:fake:payload +15478 0x11/imm32/alloc-id:fake +15479 _string-break-if-addr<=/imm32/name +15480 0/imm32/no-inouts +15481 0/imm32/no-inouts +15482 0/imm32/no-outputs +15483 0/imm32/no-outputs +15484 0x11/imm32/alloc-id:fake +15485 _string_0f_86_jump_break/imm32/subx-name +15486 0/imm32/no-rm32 +15487 0/imm32/no-r32 +15488 0/imm32/no-imm32 +15489 0/imm32/no-disp32 +15490 0/imm32/no-output +15491 0x11/imm32/alloc-id:fake +15492 _Primitive-break-if-addr>/imm32/next +15493 _Primitive-break-if-addr>: # (payload primitive) 15494 0x11/imm32/alloc-id:fake:payload 15495 0x11/imm32/alloc-id:fake -15496 Int-var-in-ecx/imm32 -15497 0/imm32/next -15498 0/imm32/next -15499 -15500 Int-var-in-ecx: -15501 0x11/imm32/alloc-id:fake:payload -15502 0/imm32/name -15503 0/imm32/name -15504 0x11/imm32/alloc-id:fake -15505 Type-int/imm32 -15506 1/imm32/some-block-depth -15507 0/imm32/no-stack-offset +15496 _string-break-if-addr>/imm32/name +15497 0/imm32/no-inouts +15498 0/imm32/no-inouts +15499 0/imm32/no-outputs +15500 0/imm32/no-outputs +15501 0x11/imm32/alloc-id:fake +15502 _string_0f_87_jump_break/imm32/subx-name +15503 0/imm32/no-rm32 +15504 0/imm32/no-r32 +15505 0/imm32/no-imm32 +15506 0/imm32/no-disp32 +15507 0/imm32/no-output 15508 0x11/imm32/alloc-id:fake -15509 $Register-ecx/imm32/register -15510 -15511 Single-int-var-in-edx: # (payload list var) -15512 0x11/imm32/alloc-id:fake:payload -15513 0x11/imm32/alloc-id:fake -15514 Int-var-in-edx/imm32 -15515 0/imm32/next -15516 0/imm32/next -15517 -15518 Int-var-in-edx: # (payload list var) -15519 0x11/imm32/alloc-id:fake:payload -15520 0/imm32/name -15521 0/imm32/name -15522 0x11/imm32/alloc-id:fake -15523 Type-int/imm32 -15524 1/imm32/some-block-depth -15525 0/imm32/no-stack-offset -15526 0x11/imm32/alloc-id:fake -15527 $Register-edx/imm32/register -15528 -15529 Single-int-var-in-ebx: # (payload list var) -15530 0x11/imm32/alloc-id:fake:payload -15531 0x11/imm32/alloc-id:fake -15532 Int-var-in-ebx/imm32 -15533 0/imm32/next -15534 0/imm32/next -15535 -15536 Int-var-in-ebx: # (payload list var) -15537 0x11/imm32/alloc-id:fake:payload -15538 0/imm32/name -15539 0/imm32/name -15540 0x11/imm32/alloc-id:fake -15541 Type-int/imm32 -15542 1/imm32/some-block-depth -15543 0/imm32/no-stack-offset -15544 0x11/imm32/alloc-id:fake -15545 $Register-ebx/imm32/register -15546 -15547 Single-int-var-in-esi: # (payload list var) -15548 0x11/imm32/alloc-id:fake:payload -15549 0x11/imm32/alloc-id:fake -15550 Int-var-in-esi/imm32 -15551 0/imm32/next -15552 0/imm32/next -15553 -15554 Int-var-in-esi: # (payload list var) -15555 0x11/imm32/alloc-id:fake:payload -15556 0/imm32/name -15557 0/imm32/name -15558 0x11/imm32/alloc-id:fake -15559 Type-int/imm32 -15560 1/imm32/some-block-depth -15561 0/imm32/no-stack-offset -15562 0x11/imm32/alloc-id:fake -15563 $Register-esi/imm32/register -15564 -15565 Single-int-var-in-edi: # (payload list var) -15566 0x11/imm32/alloc-id:fake:payload -15567 0x11/imm32/alloc-id:fake -15568 Int-var-in-edi/imm32 -15569 0/imm32/next -15570 0/imm32/next -15571 -15572 Int-var-in-edi: # (payload list var) -15573 0x11/imm32/alloc-id:fake:payload -15574 0/imm32/name -15575 0/imm32/name +15509 _Primitive-break-if-</imm32/next +15510 _Primitive-break-if-<: # (payload primitive) +15511 0x11/imm32/alloc-id:fake:payload +15512 0x11/imm32/alloc-id:fake +15513 _string-break-if-</imm32/name +15514 0/imm32/no-inouts +15515 0/imm32/no-inouts +15516 0/imm32/no-outputs +15517 0/imm32/no-outputs +15518 0x11/imm32/alloc-id:fake +15519 _string_0f_8c_jump_break/imm32/subx-name +15520 0/imm32/no-rm32 +15521 0/imm32/no-r32 +15522 0/imm32/no-imm32 +15523 0/imm32/no-disp32 +15524 0/imm32/no-output +15525 0x11/imm32/alloc-id:fake +15526 _Primitive-break-if->=/imm32/next +15527 _Primitive-break-if->=: # (payload primitive) +15528 0x11/imm32/alloc-id:fake:payload +15529 0x11/imm32/alloc-id:fake +15530 _string-break-if->=/imm32/name +15531 0/imm32/no-inouts +15532 0/imm32/no-inouts +15533 0/imm32/no-outputs +15534 0/imm32/no-outputs +15535 0x11/imm32/alloc-id:fake +15536 _string_0f_8d_jump_break/imm32/subx-name +15537 0/imm32/no-rm32 +15538 0/imm32/no-r32 +15539 0/imm32/no-imm32 +15540 0/imm32/no-disp32 +15541 0/imm32/no-output +15542 0x11/imm32/alloc-id:fake +15543 _Primitive-break-if-<=/imm32/next +15544 _Primitive-break-if-<=: # (payload primitive) +15545 0x11/imm32/alloc-id:fake:payload +15546 0x11/imm32/alloc-id:fake +15547 _string-break-if-<=/imm32/name +15548 0/imm32/no-inouts +15549 0/imm32/no-inouts +15550 0/imm32/no-outputs +15551 0/imm32/no-outputs +15552 0x11/imm32/alloc-id:fake +15553 _string_0f_8e_jump_break/imm32/subx-name +15554 0/imm32/no-rm32 +15555 0/imm32/no-r32 +15556 0/imm32/no-imm32 +15557 0/imm32/no-disp32 +15558 0/imm32/no-output +15559 0x11/imm32/alloc-id:fake +15560 _Primitive-break-if->/imm32/next +15561 _Primitive-break-if->: # (payload primitive) +15562 0x11/imm32/alloc-id:fake:payload +15563 0x11/imm32/alloc-id:fake +15564 _string-break-if->/imm32/name +15565 0/imm32/no-inouts +15566 0/imm32/no-inouts +15567 0/imm32/no-outputs +15568 0/imm32/no-outputs +15569 0x11/imm32/alloc-id:fake +15570 _string_0f_8f_jump_break/imm32/subx-name +15571 0/imm32/no-rm32 +15572 0/imm32/no-r32 +15573 0/imm32/no-imm32 +15574 0/imm32/no-disp32 +15575 0/imm32/no-output 15576 0x11/imm32/alloc-id:fake -15577 Type-int/imm32 -15578 1/imm32/some-block-depth -15579 0/imm32/no-stack-offset +15577 _Primitive-break/imm32/next +15578 _Primitive-break: # (payload primitive) +15579 0x11/imm32/alloc-id:fake:payload 15580 0x11/imm32/alloc-id:fake -15581 $Register-edi/imm32/register -15582 -15583 Single-lit-var: # (payload list var) -15584 0x11/imm32/alloc-id:fake:payload -15585 0x11/imm32/alloc-id:fake -15586 Lit-var/imm32 -15587 0/imm32/next -15588 0/imm32/next -15589 -15590 Lit-var: # (payload var) -15591 0x11/imm32/alloc-id:fake:payload -15592 0/imm32/name -15593 0/imm32/name -15594 0x11/imm32/alloc-id:fake -15595 Type-literal/imm32 -15596 1/imm32/some-block-depth -15597 0/imm32/no-stack-offset -15598 0/imm32/no-register -15599 0/imm32/no-register -15600 -15601 Type-int: # (payload tree type-id) -15602 0x11/imm32/alloc-id:fake:payload -15603 1/imm32/left-is-atom -15604 1/imm32/value:int -15605 0/imm32/left:unused -15606 0/imm32/right:null -15607 0/imm32/right:null -15608 -15609 Type-literal: # (payload tree type-id) -15610 0x11/imm32/alloc-id:fake:payload -15611 1/imm32/is-atom -15612 0/imm32/value:literal -15613 0/imm32/left:unused -15614 0/imm32/right:null -15615 0/imm32/right:null -15616 -15617 Type-addr: # (payload tree type-id) -15618 0x11/imm32/alloc-id:fake:payload -15619 1/imm32/is-atom -15620 2/imm32/value:addr -15621 0/imm32/left:unused -15622 0/imm32/right:null -15623 0/imm32/right:null -15624 -15625 Type-byte: # (payload tree type-id) -15626 0x11/imm32/alloc-id:fake:payload -15627 1/imm32/is-atom -15628 8/imm32/value:byte -15629 0/imm32/left:unused -15630 0/imm32/right:null -15631 0/imm32/right:null -15632 -15633 == code -15634 emit-subx-primitive: # out: (addr buffered-file), stmt: (addr stmt), primitive: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) -15635 # . prologue -15636 55/push-ebp -15637 89/<- %ebp 4/r32/esp -15638 # . save registers -15639 50/push-eax -15640 51/push-ecx -15641 # ecx = primitive -15642 8b/-> *(ebp+0x10) 1/r32/ecx -15643 # emit primitive name -15644 (emit-indent *(ebp+8) *Curr-block-depth) -15645 (lookup *(ecx+0x18) *(ecx+0x1c)) # Primitive-subx-name Primitive-subx-name => eax -15646 (write-buffered *(ebp+8) %eax) -15647 # emit rm32 if necessary -15648 (emit-subx-rm32 *(ebp+8) *(ecx+0x20) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-rm32 -15649 # emit r32 if necessary -15650 (emit-subx-r32 *(ebp+8) *(ecx+0x24) *(ebp+0xc)) # Primitive-subx-r32 -15651 # emit imm32 if necessary -15652 (emit-subx-imm32 *(ebp+8) *(ecx+0x28) *(ebp+0xc)) # Primitive-subx-imm32 -15653 # emit disp32 if necessary -15654 (emit-subx-disp32 *(ebp+8) *(ecx+0x2c) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-disp32 -15655 (write-buffered *(ebp+8) Newline) -15656 $emit-subx-primitive:end: -15657 # . restore registers -15658 59/pop-to-ecx -15659 58/pop-to-eax -15660 # . epilogue -15661 89/<- %esp 5/r32/ebp -15662 5d/pop-to-ebp -15663 c3/return -15664 -15665 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -15666 # . prologue -15667 55/push-ebp -15668 89/<- %ebp 4/r32/esp -15669 # . save registers -15670 50/push-eax -15671 # if (l == 0) return -15672 81 7/subop/compare *(ebp+0xc) 0/imm32 -15673 74/jump-if-= $emit-subx-rm32:end/disp8 -15674 # var v/eax: (addr stmt-var) -15675 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax -15676 (emit-subx-var-as-rm32 *(ebp+8) %eax) -15677 $emit-subx-rm32:end: -15678 # . restore registers -15679 58/pop-to-eax -15680 # . epilogue -15681 89/<- %esp 5/r32/ebp -15682 5d/pop-to-ebp -15683 c3/return -15684 -15685 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) -15686 # . prologue -15687 55/push-ebp -15688 89/<- %ebp 4/r32/esp -15689 # . save registers -15690 51/push-ecx -15691 # eax = l -15692 8b/-> *(ebp+0xc) 0/r32/eax -15693 # ecx = stmt -15694 8b/-> *(ebp+8) 1/r32/ecx -15695 # if (l == 1) return stmt->inouts -15696 { -15697 3d/compare-eax-and 1/imm32 -15698 75/jump-if-!= break/disp8 -15699 $get-stmt-operand-from-arg-location:1: -15700 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15701 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -15702 } -15703 # if (l == 2) return stmt->inouts->next -15704 { -15705 3d/compare-eax-and 2/imm32 -15706 75/jump-if-!= break/disp8 -15707 $get-stmt-operand-from-arg-location:2: -15708 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15709 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -15710 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -15711 } -15712 # if (l == 3) return stmt->outputs -15713 { -15714 3d/compare-eax-and 3/imm32 -15715 75/jump-if-!= break/disp8 -15716 $get-stmt-operand-from-arg-location:3: -15717 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -15718 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -15719 } -15720 # abort -15721 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 -15722 $get-stmt-operand-from-arg-location:end: -15723 # . restore registers -15724 59/pop-to-ecx -15725 # . epilogue -15726 89/<- %esp 5/r32/ebp -15727 5d/pop-to-ebp -15728 c3/return -15729 -15730 $get-stmt-operand-from-arg-location:abort: -15731 # error("invalid arg-location " eax) -15732 (write-buffered *(ebp+0x10) "invalid arg-location ") -15733 (print-int32-buffered *(ebp+0x10) %eax) -15734 (write-buffered *(ebp+0x10) Newline) -15735 (flush *(ebp+0x10)) -15736 (stop *(ebp+0x14) 1) -15737 # never gets here -15738 -15739 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -15740 # . prologue -15741 55/push-ebp -15742 89/<- %ebp 4/r32/esp -15743 # . save registers -15744 50/push-eax -15745 51/push-ecx -15746 # if (l == 0) return -15747 81 7/subop/compare *(ebp+0xc) 0/imm32 -15748 0f 84/jump-if-= $emit-subx-r32:end/disp32 -15749 # var v/eax: (addr stmt-var) -15750 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -15751 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15752 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax -15753 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index) -15754 (write-buffered *(ebp+8) Space) -15755 (print-int32-buffered *(ebp+8) *eax) -15756 (write-buffered *(ebp+8) "/r32") -15757 $emit-subx-r32:end: -15758 # . restore registers -15759 59/pop-to-ecx -15760 58/pop-to-eax -15761 # . epilogue -15762 89/<- %esp 5/r32/ebp -15763 5d/pop-to-ebp -15764 c3/return -15765 -15766 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) -15767 # . prologue -15768 55/push-ebp -15769 89/<- %ebp 4/r32/esp -15770 # . save registers -15771 50/push-eax -15772 51/push-ecx -15773 # if (l == 0) return -15774 81 7/subop/compare *(ebp+0xc) 0/imm32 -15775 0f 84/jump-if-= $emit-subx-imm32:end/disp32 -15776 # var v/eax: (handle var) -15777 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax -15778 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15779 (lookup *eax *(eax+4)) # Var-name Var-name => eax -15780 (write-buffered *(ebp+8) Space) -15781 (write-buffered *(ebp+8) %eax) -15782 (write-buffered *(ebp+8) "/imm32") -15783 $emit-subx-imm32:end: -15784 # . restore registers -15785 59/pop-to-ecx -15786 58/pop-to-eax -15787 # . epilogue -15788 89/<- %esp 5/r32/ebp -15789 5d/pop-to-ebp -15790 c3/return -15791 -15792 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) -15793 # . prologue -15794 55/push-ebp -15795 89/<- %ebp 4/r32/esp -15796 # . save registers -15797 50/push-eax -15798 51/push-ecx -15799 # if (location == 0) return -15800 81 7/subop/compare *(ebp+0xc) 0/imm32 -15801 0f 84/jump-if-= $emit-subx-disp32:end/disp32 -15802 # var v/eax: (addr stmt-var) -15803 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax -15804 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax -15805 (lookup *eax *(eax+4)) # Var-name Var-name => eax -15806 (write-buffered *(ebp+8) Space) -15807 (write-buffered *(ebp+8) %eax) -15808 # hack: if instruction operation starts with "break", emit ":break" -15809 # var name/ecx: (addr array byte) = lookup(stmt->operation) -15810 8b/-> *(ebp+0x10) 0/r32/eax -15811 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -15812 89/<- %ecx 0/r32/eax -15813 { -15814 (string-starts-with? %ecx "break") # => eax -15815 3d/compare-eax-and 0/imm32/false -15816 74/jump-if-= break/disp8 -15817 (write-buffered *(ebp+8) ":break") -15818 } -15819 # hack: if instruction operation starts with "loop", emit ":loop" -15820 { -15821 (string-starts-with? %ecx "loop") # => eax -15822 3d/compare-eax-and 0/imm32/false -15823 74/jump-if-= break/disp8 -15824 (write-buffered *(ebp+8) ":loop") -15825 } -15826 (write-buffered *(ebp+8) "/disp32") -15827 $emit-subx-disp32:end: -15828 # . restore registers -15829 59/pop-to-ecx -15830 58/pop-to-eax -15831 # . epilogue -15832 89/<- %esp 5/r32/ebp -15833 5d/pop-to-ebp -15834 c3/return -15835 -15836 emit-call: # out: (addr buffered-file), stmt: (addr stmt) -15837 # . prologue -15838 55/push-ebp -15839 89/<- %ebp 4/r32/esp -15840 # . save registers -15841 50/push-eax -15842 51/push-ecx -15843 # -15844 (emit-indent *(ebp+8) *Curr-block-depth) -15845 (write-buffered *(ebp+8) "(") -15846 # ecx = stmt -15847 8b/-> *(ebp+0xc) 1/r32/ecx -15848 # - emit function name -15849 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -15850 (write-buffered *(ebp+8) %eax) -15851 # - emit arguments -15852 # var curr/eax: (addr stmt-var) = lookup(stmt->inouts) -15853 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -15854 { -15855 # if (curr == null) break -15856 3d/compare-eax-and 0/imm32 -15857 74/jump-if-= break/disp8 -15858 # -15859 (emit-subx-call-operand *(ebp+8) %eax) -15860 # curr = lookup(curr->next) -15861 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax -15862 eb/jump loop/disp8 -15863 } -15864 # -15865 (write-buffered *(ebp+8) ")\n") -15866 $emit-call:end: -15867 # . restore registers -15868 59/pop-to-ecx -15869 58/pop-to-eax -15870 # . epilogue -15871 89/<- %esp 5/r32/ebp -15872 5d/pop-to-ebp -15873 c3/return -15874 -15875 emit-subx-call-operand: # out: (addr buffered-file), s: (addr stmt-var) -15876 # shares code with emit-subx-var-as-rm32 -15877 # . prologue -15878 55/push-ebp -15879 89/<- %ebp 4/r32/esp -15880 # . save registers -15881 50/push-eax -15882 51/push-ecx -15883 56/push-esi -15884 # ecx = s -15885 8b/-> *(ebp+0xc) 1/r32/ecx -15886 # var operand/esi: (addr var) = lookup(s->value) -15887 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -15888 89/<- %esi 0/r32/eax -15889 # if (operand->register && !s->is-deref?) emit "%__" -15890 { -15891 $emit-subx-call-operand:check-for-register-direct: -15892 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -15893 74/jump-if-= break/disp8 -15894 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -15895 75/jump-if-!= break/disp8 -15896 $emit-subx-call-operand:register-direct: -15897 (write-buffered *(ebp+8) " %") -15898 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -15899 (write-buffered *(ebp+8) %eax) -15900 e9/jump $emit-subx-call-operand:end/disp32 -15901 } -15902 # else if (operand->register && s->is-deref?) emit "*__" -15903 { -15904 $emit-subx-call-operand:check-for-register-indirect: -15905 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -15906 74/jump-if-= break/disp8 -15907 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -15908 74/jump-if-= break/disp8 -15909 $emit-subx-call-operand:register-indirect: -15910 (emit-subx-call-operand-register-indirect *(ebp+8) %esi) -15911 e9/jump $emit-subx-call-operand:end/disp32 -15912 } -15913 # else if (operand->stack-offset) emit "*(ebp+__)" -15914 { -15915 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset -15916 74/jump-if-= break/disp8 -15917 $emit-subx-call-operand:stack: -15918 (emit-subx-call-operand-stack *(ebp+8) %esi) -15919 e9/jump $emit-subx-call-operand:end/disp32 -15920 } -15921 # else if (operand->type == literal) emit "__" -15922 { -15923 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -15924 81 7/subop/compare *(eax+4) 0/imm32 # Tree-left -15925 75/jump-if-!= break/disp8 -15926 $emit-subx-call-operand:literal: -15927 (write-buffered *(ebp+8) Space) -15928 (lookup *esi *(esi+4)) # Var-name Var-name => eax -15929 (write-buffered *(ebp+8) %eax) -15930 } -15931 $emit-subx-call-operand:end: -15932 # . restore registers -15933 5e/pop-to-esi -15934 59/pop-to-ecx -15935 58/pop-to-eax -15936 # . epilogue -15937 89/<- %esp 5/r32/ebp -15938 5d/pop-to-ebp -15939 c3/return -15940 -15941 emit-subx-call-operand-register-indirect: # out: (addr buffered-file), v: (addr var) -15942 # . prologue -15943 55/push-ebp -15944 89/<- %ebp 4/r32/esp -15945 # . save registers -15946 50/push-eax -15947 51/push-ecx -15948 56/push-esi -15949 # esi = v -15950 8b/-> *(ebp+0xc) 6/r32/esi -15951 # var size/ecx: int = size-of-deref(v) -15952 (size-of-deref %esi) # => eax -15953 89/<- %ecx 0/r32/eax -15954 # var reg-name/esi: (addr array byte) = lookup(v->register) -15955 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -15956 89/<- %esi 0/r32/eax -15957 # TODO: assert size is a multiple of 4 -15958 # var i/eax: int = 0 -15959 b8/copy-to-eax 0/imm32 -15960 { -15961 $emit-subx-call-operand-register-indirect:loop: -15962 # if (i >= size) break -15963 39/compare %eax 1/r32/ecx -15964 7d/jump-if->= break/disp8 -15965 # emit " *(" v->register "+" i ")" -15966 (write-buffered *(ebp+8) " *(") -15967 (write-buffered *(ebp+8) %esi) -15968 (write-buffered *(ebp+8) "+") -15969 (print-int32-buffered *(ebp+8) %eax) -15970 (write-buffered *(ebp+8) ")") -15971 # i += 4 -15972 05/add-to-eax 4/imm32 -15973 # -15974 eb/jump loop/disp8 -15975 } -15976 $emit-subx-call-operand-register-indirect:end: -15977 # . restore registers -15978 5e/pop-to-esi -15979 59/pop-to-ecx -15980 58/pop-to-eax -15981 # . epilogue -15982 89/<- %esp 5/r32/ebp -15983 5d/pop-to-ebp -15984 c3/return -15985 -15986 emit-subx-call-operand-stack: # out: (addr buffered-file), v: (addr var) -15987 # . prologue -15988 55/push-ebp -15989 89/<- %ebp 4/r32/esp -15990 # . save registers -15991 50/push-eax -15992 51/push-ecx -15993 56/push-esi -15994 # esi = v -15995 8b/-> *(ebp+0xc) 6/r32/esi -15996 # var curr/ecx: int = v->offset -15997 8b/-> *(esi+0x14) 1/r32/ecx # Var-offset -15998 # var max/eax: int = v->offset + size-of(v) -15999 (size-of %esi) # => eax -16000 # TODO: assert size is a multiple of 4 -16001 01/add-to %eax 1/r32/ecx -16002 { -16003 $emit-subx-call-operand-stack:loop: -16004 # if (curr >= max) break -16005 39/compare %ecx 0/r32/eax -16006 7d/jump-if->= break/disp8 -16007 # emit " *(ebp+" curr ")" -16008 (write-buffered *(ebp+8) " *(ebp+") -16009 (print-int32-buffered *(ebp+8) %ecx) -16010 (write-buffered *(ebp+8) ")") -16011 # i += 4 -16012 81 0/subop/add %ecx 4/imm32 -16013 # -16014 eb/jump loop/disp8 -16015 } -16016 $emit-subx-call-operand-stack:end: -16017 # . restore registers -16018 5e/pop-to-esi -16019 59/pop-to-ecx -16020 58/pop-to-eax -16021 # . epilogue -16022 89/<- %esp 5/r32/ebp -16023 5d/pop-to-ebp -16024 c3/return -16025 -16026 emit-subx-var-as-rm32: # out: (addr buffered-file), s: (addr stmt-var) -16027 # . prologue -16028 55/push-ebp -16029 89/<- %ebp 4/r32/esp -16030 # . save registers -16031 50/push-eax -16032 51/push-ecx -16033 56/push-esi -16034 # ecx = s -16035 8b/-> *(ebp+0xc) 1/r32/ecx -16036 # var operand/esi: (addr var) = lookup(s->value) -16037 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -16038 89/<- %esi 0/r32/eax -16039 # if (operand->register && s->is-deref?) emit "*__" -16040 { -16041 $emit-subx-var-as-rm32:check-for-register-indirect: -16042 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -16043 74/jump-if-= break/disp8 -16044 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -16045 74/jump-if-= break/disp8 -16046 $emit-subx-var-as-rm32:register-indirect: -16047 (write-buffered *(ebp+8) " *") -16048 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -16049 (write-buffered *(ebp+8) %eax) -16050 e9/jump $emit-subx-var-as-rm32:end/disp32 -16051 } -16052 # if (operand->register && !s->is-deref?) emit "%__" -16053 { -16054 $emit-subx-var-as-rm32:check-for-register-direct: -16055 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -16056 74/jump-if-= break/disp8 -16057 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -16058 75/jump-if-!= break/disp8 -16059 $emit-subx-var-as-rm32:register-direct: -16060 (write-buffered *(ebp+8) " %") -16061 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -16062 (write-buffered *(ebp+8) %eax) -16063 e9/jump $emit-subx-var-as-rm32:end/disp32 -16064 } -16065 # else if (operand->stack-offset) emit "*(ebp+__)" -16066 { -16067 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset -16068 74/jump-if-= break/disp8 -16069 $emit-subx-var-as-rm32:stack: -16070 (write-buffered *(ebp+8) Space) -16071 (write-buffered *(ebp+8) "*(ebp+") -16072 (print-int32-buffered *(ebp+8) *(esi+0x14)) # Var-offset -16073 (write-buffered *(ebp+8) ")") -16074 } -16075 $emit-subx-var-as-rm32:end: -16076 # . restore registers -16077 5e/pop-to-esi -16078 59/pop-to-ecx -16079 58/pop-to-eax -16080 # . epilogue -16081 89/<- %esp 5/r32/ebp -16082 5d/pop-to-ebp -16083 c3/return -16084 -16085 find-matching-primitive: # primitives: (addr primitive), stmt: (addr stmt) -> result/eax: (addr primitive) -16086 # . prologue -16087 55/push-ebp -16088 89/<- %ebp 4/r32/esp -16089 # . save registers -16090 51/push-ecx -16091 # var curr/ecx: (addr primitive) = primitives -16092 8b/-> *(ebp+8) 1/r32/ecx -16093 { -16094 $find-matching-primitive:loop: -16095 # if (curr == null) break -16096 81 7/subop/compare %ecx 0/imm32 -16097 74/jump-if-= break/disp8 -16098 # if match(curr, stmt) return curr -16099 { -16100 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax -16101 3d/compare-eax-and 0/imm32/false -16102 74/jump-if-= break/disp8 -16103 89/<- %eax 1/r32/ecx -16104 eb/jump $find-matching-primitive:end/disp8 -16105 } -16106 $find-matching-primitive:next-primitive: -16107 # curr = curr->next -16108 (lookup *(ecx+0x34) *(ecx+0x38)) # Primitive-next Primitive-next => eax -16109 89/<- %ecx 0/r32/eax -16110 # -16111 e9/jump loop/disp32 -16112 } -16113 # return null -16114 b8/copy-to-eax 0/imm32 -16115 $find-matching-primitive:end: -16116 # . restore registers -16117 59/pop-to-ecx -16118 # . epilogue -16119 89/<- %esp 5/r32/ebp -16120 5d/pop-to-ebp -16121 c3/return -16122 -16123 mu-stmt-matches-primitive?: # stmt: (addr stmt), primitive: (addr primitive) -> result/eax: boolean -16124 # A mu stmt matches a primitive if the name matches, all the inout vars -16125 # match, and all the output vars match. -16126 # Vars match if types match and registers match. -16127 # In addition, a stmt output matches a primitive's output if types match -16128 # and the primitive has a wildcard register. -16129 # . prologue -16130 55/push-ebp -16131 89/<- %ebp 4/r32/esp -16132 # . save registers -16133 51/push-ecx -16134 52/push-edx -16135 53/push-ebx -16136 56/push-esi -16137 57/push-edi -16138 # ecx = stmt -16139 8b/-> *(ebp+8) 1/r32/ecx -16140 # edx = primitive -16141 8b/-> *(ebp+0xc) 2/r32/edx -16142 { -16143 $mu-stmt-matches-primitive?:check-name: -16144 # if (primitive->name != stmt->operation) return false -16145 # . var esi: (addr array byte) = lookup(stmt->operation) -16146 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax -16147 89/<- %esi 0/r32/eax -16148 # . var edi: (addr array byte) = lookup(primitive->name) -16149 (lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax -16150 89/<- %edi 0/r32/eax -16151 (string-equal? %esi %edi) # => eax -16152 3d/compare-eax-and 0/imm32/false -16153 75/jump-if-!= break/disp8 -16154 b8/copy-to-eax 0/imm32 -16155 e9/jump $mu-stmt-matches-primitive?:end/disp32 -16156 } -16157 # var curr/esi: (addr stmt-var) = lookup(stmt->inouts) -16158 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax -16159 89/<- %esi 0/r32/eax -16160 # var curr2/edi: (addr list var) = lookup(primitive->inouts) -16161 (lookup *(edx+8) *(edx+0xc)) # Primitive-inouts Primitive-inouts => eax -16162 89/<- %edi 0/r32/eax -16163 { -16164 $mu-stmt-matches-primitive?:inouts-loop: -16165 # if (curr == 0 && curr2 == 0) move on to check outputs -16166 { -16167 $mu-stmt-matches-primitive?:check-both-inouts-null: -16168 81 7/subop/compare %esi 0/imm32 -16169 75/jump-if-!= break/disp8 -16170 $mu-stmt-matches-primitive?:stmt-inout-null: -16171 81 7/subop/compare %edi 0/imm32 -16172 0f 84/jump-if-= $mu-stmt-matches-primitive?:check-outputs/disp32 -16173 $mu-stmt-matches-primitive?:stmt-inout-null-and-prim-inout-not-null: -16174 # return false -16175 b8/copy-to-eax 0/imm32/false -16176 e9/jump $mu-stmt-matches-primitive?:end/disp32 -16177 } -16178 # if (curr2 == 0) return false -16179 { -16180 $mu-stmt-matches-primitive?:check-prim-inout-null: -16181 81 7/subop/compare %edi 0/imm32 -16182 75/jump-if-!= break/disp8 -16183 $mu-stmt-matches-primitive?:prim-inout-null: -16184 b8/copy-to-eax 0/imm32/false -16185 e9/jump $mu-stmt-matches-primitive?:end/disp32 -16186 } -16187 # if (curr != curr2) return false -16188 { -16189 $mu-stmt-matches-primitive?:check-inouts-match: -16190 (lookup *edi *(edi+4)) # List-value List-value => eax -16191 (operand-matches-primitive? %esi %eax) # => eax -16192 3d/compare-eax-and 0/imm32/false -16193 75/jump-if-!= break/disp8 -16194 $mu-stmt-matches-primitive?:inouts-match: -16195 b8/copy-to-eax 0/imm32/false -16196 e9/jump $mu-stmt-matches-primitive?:end/disp32 -16197 } -16198 $mu-stmt-matches-primitive?:next-inout: -16199 # curr = lookup(curr->next) -16200 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -16201 89/<- %esi 0/r32/eax -16202 # curr2 = lookup(curr2->next) -16203 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax -16204 89/<- %edi 0/r32/eax -16205 # -16206 e9/jump loop/disp32 -16207 } -16208 $mu-stmt-matches-primitive?:check-outputs: -16209 # var curr/esi: (addr stmt-var) = lookup(stmt->outputs) -16210 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax -16211 89/<- %esi 0/r32/eax -16212 # var curr2/edi: (addr list var) = lookup(primitive->outputs) -16213 (lookup *(edx+0x10) *(edx+0x14)) # Primitive-outputs Primitive-outputs => eax -16214 89/<- %edi 0/r32/eax -16215 { -16216 $mu-stmt-matches-primitive?:outputs-loop: -16217 # if (curr == 0) return (curr2 == 0) -16218 { -16219 $mu-stmt-matches-primitive?:check-both-outputs-null: -16220 81 7/subop/compare %esi 0/imm32 -16221 75/jump-if-!= break/disp8 -16222 { -16223 $mu-stmt-matches-primitive?:stmt-output-null: -16224 81 7/subop/compare %edi 0/imm32 -16225 75/jump-if-!= break/disp8 -16226 $mu-stmt-matches-primitive?:both-outputs-null: -16227 # return true -16228 b8/copy-to-eax 1/imm32 -16229 e9/jump $mu-stmt-matches-primitive?:end/disp32 -16230 } -16231 $mu-stmt-matches-primitive?:stmt-output-null-and-prim-output-not-null: -16232 # return false -16233 b8/copy-to-eax 0/imm32 -16234 e9/jump $mu-stmt-matches-primitive?:end/disp32 -16235 } -16236 # if (curr2 == 0) return false -16237 { -16238 $mu-stmt-matches-primitive?:check-prim-output-null: -16239 81 7/subop/compare %edi 0/imm32 -16240 75/jump-if-!= break/disp8 -16241 $mu-stmt-matches-primitive?:prim-output-is-null: -16242 b8/copy-to-eax 0/imm32 -16243 e9/jump $mu-stmt-matches-primitive?:end/disp32 -16244 } -16245 # if (curr != curr2) return false -16246 { -16247 $mu-stmt-matches-primitive?:check-outputs-match: -16248 (lookup *edi *(edi+4)) # List-value List-value => eax -16249 (operand-matches-primitive? %esi %eax) # => eax -16250 3d/compare-eax-and 0/imm32/false -16251 75/jump-if-!= break/disp8 -16252 $mu-stmt-matches-primitive?:outputs-match: -16253 b8/copy-to-eax 0/imm32 -16254 e9/jump $mu-stmt-matches-primitive?:end/disp32 -16255 } -16256 $mu-stmt-matches-primitive?:next-output: -16257 # curr = lookup(curr->next) -16258 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax -16259 89/<- %esi 0/r32/eax -16260 # curr2 = lookup(curr2->next) -16261 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax -16262 89/<- %edi 0/r32/eax -16263 # -16264 e9/jump loop/disp32 -16265 } -16266 $mu-stmt-matches-primitive?:return-true: -16267 b8/copy-to-eax 1/imm32 -16268 $mu-stmt-matches-primitive?:end: -16269 # . restore registers -16270 5f/pop-to-edi -16271 5e/pop-to-esi -16272 5b/pop-to-ebx -16273 5a/pop-to-edx -16274 59/pop-to-ecx -16275 # . epilogue -16276 89/<- %esp 5/r32/ebp -16277 5d/pop-to-ebp -16278 c3/return -16279 -16280 operand-matches-primitive?: # s: (addr stmt-var), prim-var: (addr var) -> result/eax: boolean -16281 # . prologue -16282 55/push-ebp -16283 89/<- %ebp 4/r32/esp -16284 # . save registers -16285 51/push-ecx -16286 52/push-edx -16287 53/push-ebx -16288 56/push-esi -16289 57/push-edi -16290 # ecx = s -16291 8b/-> *(ebp+8) 1/r32/ecx -16292 # var var/esi: (addr var) = lookup(s->value) -16293 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax -16294 89/<- %esi 0/r32/eax -16295 # edi = prim-var -16296 8b/-> *(ebp+0xc) 7/r32/edi -16297 $operand-matches-primitive?:check-type: -16298 # if (var->type != prim-var->type) return false -16299 # . var vtype/ebx: (addr tree type-id) = lookup(var->type) -16300 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax -16301 89/<- %ebx 0/r32/eax -16302 # . var ptype/eax: (addr tree type-id) = lookup(prim-var->type) -16303 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax -16304 (subx-type-equal? %ebx %eax) # => eax -16305 3d/compare-eax-and 0/imm32/false -16306 0f 84/jump-if-= $operand-matches-primitive?:return-false/disp32 -16307 { -16308 $operand-matches-primitive?:check-register: -16309 # if prim-var is in memory and var is in register but dereference, match -16310 { -16311 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register -16312 0f 85/jump-if-!= break/disp32 -16313 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -16314 74/jump-if-= break/disp8 -16315 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -16316 74/jump-if-= break/disp8 -16317 $operand-matches-primitive?:var-deref-match: -16318 e9/jump $operand-matches-primitive?:return-true/disp32 -16319 } -16320 # if prim-var is in register and var is in register but dereference, no match -16321 { -16322 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register -16323 0f 84/jump-if-= break/disp32 -16324 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register -16325 0f 84/jump-if-= break/disp32 -16326 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref -16327 74/jump-if-= break/disp8 -16328 $operand-matches-primitive?:var-deref-no-match: -16329 e9/jump $operand-matches-primitive?:return-false/disp32 -16330 } -16331 # return false if var->register doesn't match prim-var->register -16332 { -16333 # if register addresses are equal, it's a match -16334 # var vreg/ebx: (addr array byte) = lookup(var->register) -16335 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax -16336 89/<- %ebx 0/r32/eax -16337 # var preg/ecx: (addr array byte) = lookup(prim-var->register) -16338 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax -16339 89/<- %ecx 0/r32/eax -16340 # if (vreg == preg) break -16341 39/compare %ecx 3/r32/ebx -16342 74/jump-if-= break/disp8 -16343 $operand-matches-primitive?:var-register-no-match: -16344 # if either address is 0, return false -16345 81 7/subop/compare %ebx 0/imm32 -16346 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -16347 81 7/subop/compare %ecx 0/imm32 -16348 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -16349 # if prim-var->register is wildcard, it's a match -16350 (string-equal? %ecx "*") # Any-register => eax -16351 3d/compare-eax-and 0/imm32/false -16352 75/jump-if-!= break/disp8 -16353 $operand-matches-primitive?:wildcard-no-match: -16354 # if string contents aren't equal, return false -16355 (string-equal? %ecx %ebx) # => eax -16356 3d/compare-eax-and 0/imm32/false -16357 74/jump-if-= $operand-matches-primitive?:return-false/disp8 -16358 } -16359 } -16360 $operand-matches-primitive?:return-true: -16361 b8/copy-to-eax 1/imm32/true -16362 eb/jump $operand-matches-primitive?:end/disp8 -16363 $operand-matches-primitive?:return-false: -16364 b8/copy-to-eax 0/imm32/false -16365 $operand-matches-primitive?:end: -16366 # . restore registers -16367 5f/pop-to-edi -16368 5e/pop-to-esi -16369 5b/pop-to-ebx -16370 5a/pop-to-edx -16371 59/pop-to-ecx -16372 # . epilogue -16373 89/<- %esp 5/r32/ebp -16374 5d/pop-to-ebp -16375 c3/return -16376 -16377 find-matching-function: # functions: (addr function), stmt: (addr stmt) -> result/eax: (addr function) -16378 # . prologue -16379 55/push-ebp -16380 89/<- %ebp 4/r32/esp -16381 # . save registers -16382 51/push-ecx -16383 # var curr/ecx: (handle function) = functions -16384 8b/-> *(ebp+8) 1/r32/ecx -16385 { -16386 # if (curr == null) break -16387 81 7/subop/compare %ecx 0/imm32 -16388 74/jump-if-= break/disp8 -16389 #? (write-buffered Stderr "iter\n") -16390 #? (flush Stderr) -16391 # if match(stmt, curr) return curr -16392 { -16393 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax -16394 3d/compare-eax-and 0/imm32/false -16395 74/jump-if-= break/disp8 -16396 89/<- %eax 1/r32/ecx -16397 eb/jump $find-matching-function:end/disp8 -16398 } -16399 # curr = curr->next -16400 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax -16401 89/<- %ecx 0/r32/eax -16402 # -16403 eb/jump loop/disp8 -16404 } -16405 # return null -16406 b8/copy-to-eax 0/imm32 -16407 $find-matching-function:end: -16408 # . restore registers -16409 59/pop-to-ecx -16410 # . epilogue -16411 89/<- %esp 5/r32/ebp -16412 5d/pop-to-ebp -16413 c3/return -16414 -16415 # Just compare names; user-defined functions don't support overloading yet. -16416 mu-stmt-matches-function?: # stmt: (addr stmt1), function: (addr function) -> result/eax: boolean -16417 # . prologue -16418 55/push-ebp -16419 89/<- %ebp 4/r32/esp -16420 # . save registers -16421 51/push-ecx -16422 # return function->name == stmt->operation -16423 # ecx = lookup(stmt->operation) -16424 8b/-> *(ebp+8) 0/r32/eax -16425 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax -16426 89/<- %ecx 0/r32/eax -16427 # eax = lookup(function->name) -16428 8b/-> *(ebp+0xc) 0/r32/eax -16429 (lookup *eax *(eax+4)) # Function-name Function-name => eax -16430 (string-equal? %eax %ecx) # => eax -16431 $mu-stmt-matches-function?:end: -16432 # . restore registers -16433 59/pop-to-ecx -16434 # . epilogue -16435 89/<- %esp 5/r32/ebp -16436 5d/pop-to-ebp -16437 c3/return -16438 -16439 subx-type-equal?: # a: (addr tree type-id), b: (addr tree type-id) -> result/eax: boolean -16440 # . prologue -16441 55/push-ebp -16442 89/<- %ebp 4/r32/esp -16443 # . save registers -16444 51/push-ecx -16445 # var alit/ecx: boolean = is-literal-type?(a) -16446 (is-simple-mu-type? *(ebp+8) 0) # => eax -16447 89/<- %ecx 0/r32/eax -16448 # var blit/eax: boolean = is-literal-type?(b) -16449 (is-simple-mu-type? *(ebp+0xc) 0) # => eax -16450 # return alit == blit -16451 39/compare %eax 1/r32/ecx -16452 0f 94/set-byte-if-= %al -16453 81 4/subop/and %eax 0xff/imm32 -16454 $subx-type-equal?:end: -16455 # . restore registers -16456 59/pop-to-ecx -16457 # . epilogue -16458 89/<- %esp 5/r32/ebp -16459 5d/pop-to-ebp -16460 c3/return -16461 -16462 is-simple-mu-type?: # a: (addr tree type-id), n: type-id -> result/eax: boolean -16463 # . prologue -16464 55/push-ebp -16465 89/<- %ebp 4/r32/esp -16466 # . save registers -16467 51/push-ecx -16468 # ecx = n -16469 8b/-> *(ebp+0xc) 1/r32/ecx -16470 # return (a->value == n) -16471 8b/-> *(ebp+8) 0/r32/eax -16472 39/compare *(eax+4) 1/r32/ecx # Tree-value -16473 0f 94/set-byte-if-= %al -16474 81 4/subop/and %eax 0xff/imm32 -16475 $is-simple-mu-type?:end: -16476 # . restore registers -16477 59/pop-to-ecx -16478 # . epilogue -16479 89/<- %esp 5/r32/ebp -16480 5d/pop-to-ebp -16481 c3/return -16482 -16483 test-emit-subx-stmt-primitive: -16484 # Primitive operation on a variable on the stack. -16485 # increment foo -16486 # => -16487 # ff 0/subop/increment *(ebp-8) -16488 # -16489 # There's a variable on the var stack as follows: -16490 # name: 'foo' -16491 # type: int -16492 # stack-offset: -8 -16493 # -16494 # There's a primitive with this info: -16495 # name: 'increment' -16496 # inouts: int/mem -16497 # value: 'ff 0/subop/increment' -16498 # -16499 # . prologue -16500 55/push-ebp -16501 89/<- %ebp 4/r32/esp -16502 # setup -16503 (clear-stream _test-output-stream) -16504 (clear-stream $_test-output-buffered-file->buffer) -16505 # simulate allocated payloads starting with an initial fake alloc-id (0x11) -16506 $test-emit-subx-stmt-primitive:initialize-type: -16507 # var type/ecx: (payload tree type-id) = int -16508 68/push 0/imm32/right:null -16509 68/push 0/imm32/right:null -16510 68/push 0/imm32/left:unused -16511 68/push 1/imm32/value:int -16512 68/push 1/imm32/is-atom?:true -16513 68/push 0x11/imm32/alloc-id:fake:payload -16514 89/<- %ecx 4/r32/esp -16515 $test-emit-subx-stmt-primitive:initialize-var: -16516 # var var-foo/ecx: (payload var) = var(type) -16517 68/push 0/imm32/no-register -16518 68/push 0/imm32/no-register -16519 68/push -8/imm32/stack-offset -16520 68/push 1/imm32/block-depth -16521 51/push-ecx/type -16522 68/push 0x11/imm32/alloc-id:fake -16523 68/push 0/imm32/name -16524 68/push 0/imm32/name -16525 68/push 0x11/imm32/alloc-id:fake:payload -16526 89/<- %ecx 4/r32/esp -16527 $test-emit-subx-stmt-primitive:initialize-var-name: -16528 # var-foo->name = "foo" -16529 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -16530 (copy-array Heap "foo" %eax) -16531 $test-emit-subx-stmt-primitive:initialize-stmt-var: -16532 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -16533 68/push 0/imm32/is-deref:false -16534 68/push 0/imm32/next -16535 68/push 0/imm32/next -16536 51/push-ecx/var-foo -16537 68/push 0x11/imm32/alloc-id:fake -16538 68/push 0x11/imm32/alloc-id:fake:payload -16539 89/<- %ebx 4/r32/esp -16540 $test-emit-subx-stmt-primitive:initialize-stmt: -16541 # var stmt/esi: (addr statement) -16542 68/push 0/imm32/no-outputs -16543 68/push 0/imm32/no-outputs -16544 53/push-ebx/inouts -16545 68/push 0x11/imm32/alloc-id:fake -16546 68/push 0/imm32/operation -16547 68/push 0/imm32/operation -16548 68/push 1/imm32/tag -16549 89/<- %esi 4/r32/esp -16550 $test-emit-subx-stmt-primitive:initialize-stmt-operation: -16551 # stmt->operation = "increment" -16552 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -16553 (copy-array Heap "increment" %eax) -16554 $test-emit-subx-stmt-primitive:initialize-primitive: -16555 # var primitives/ebx: (addr primitive) -16556 68/push 0/imm32/next -16557 68/push 0/imm32/next -16558 68/push 0/imm32/output-is-write-only -16559 68/push 0/imm32/no-disp32 -16560 68/push 0/imm32/no-imm32 -16561 68/push 0/imm32/no-r32 -16562 68/push 1/imm32/rm32-is-first-inout -16563 68/push 0/imm32/subx-name -16564 68/push 0/imm32/subx-name -16565 68/push 0/imm32/no-outputs -16566 68/push 0/imm32/no-outputs -16567 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration -16568 68/push 0x11/imm32/alloc-id:fake -16569 68/push 0/imm32/name -16570 68/push 0/imm32/name -16571 89/<- %ebx 4/r32/esp -16572 $test-emit-subx-stmt-primitive:initialize-primitive-name: -16573 # primitives->name = "increment" -16574 (copy-array Heap "increment" %ebx) # Primitive-name -16575 $test-emit-subx-stmt-primitive:initialize-primitive-subx-name: -16576 # primitives->subx-name = "ff 0/subop/increment" -16577 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -16578 (copy-array Heap "ff 0/subop/increment" %eax) -16579 # convert -16580 c7 0/subop/copy *Curr-block-depth 0/imm32 -16581 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) -16582 (flush _test-output-buffered-file) -16583 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -16589 # check output -16590 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-stmt-primitive") -16591 # . epilogue -16592 89/<- %esp 5/r32/ebp -16593 5d/pop-to-ebp -16594 c3/return -16595 -16596 test-emit-subx-stmt-primitive-register: -16597 # Primitive operation on a variable in a register. -16598 # foo <- increment -16599 # => -16600 # ff 0/subop/increment %eax # sub-optimal, but should suffice -16601 # -16602 # There's a variable on the var stack as follows: -16603 # name: 'foo' -16604 # type: int -16605 # register: 'eax' -16606 # -16607 # There's a primitive with this info: -16608 # name: 'increment' -16609 # out: int/reg -16610 # value: 'ff 0/subop/increment' -16611 # -16612 # . prologue -16613 55/push-ebp -16614 89/<- %ebp 4/r32/esp -16615 # setup -16616 (clear-stream _test-output-stream) -16617 (clear-stream $_test-output-buffered-file->buffer) -16618 $test-emit-subx-stmt-primitive-register:initialize-type: -16619 # var type/ecx: (payload tree type-id) = int -16620 68/push 0/imm32/right:null -16621 68/push 0/imm32/right:null -16622 68/push 0/imm32/left:unused -16623 68/push 1/imm32/value:int -16624 68/push 1/imm32/is-atom?:true -16625 68/push 0x11/imm32/alloc-id:fake:payload -16626 89/<- %ecx 4/r32/esp -16627 $test-emit-subx-stmt-primitive-register:initialize-var: -16628 # var var-foo/ecx: (payload var) -16629 68/push 0/imm32/register -16630 68/push 0/imm32/register -16631 68/push 0/imm32/no-stack-offset -16632 68/push 1/imm32/block-depth -16633 51/push-ecx -16634 68/push 0x11/imm32/alloc-id:fake -16635 68/push 0/imm32/name -16636 68/push 0/imm32/name -16637 68/push 0x11/imm32/alloc-id:fake:payload -16638 89/<- %ecx 4/r32/esp -16639 $test-emit-subx-stmt-primitive-register:initialize-var-name: -16640 # var-foo->name = "foo" -16641 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -16642 (copy-array Heap "foo" %eax) -16643 $test-emit-subx-stmt-primitive-register:initialize-var-register: -16644 # var-foo->register = "eax" -16645 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -16646 (copy-array Heap "eax" %eax) -16647 $test-emit-subx-stmt-primitive-register:initialize-stmt-var: -16648 # var operand/ebx: (payload stmt-var) -16649 68/push 0/imm32/is-deref:false -16650 68/push 0/imm32/next -16651 68/push 0/imm32/next -16652 51/push-ecx/var-foo -16653 68/push 0x11/imm32/alloc-id:fake -16654 68/push 0x11/imm32/alloc-id:fake:payload -16655 89/<- %ebx 4/r32/esp -16656 $test-emit-subx-stmt-primitive-register:initialize-stmt: -16657 # var stmt/esi: (addr statement) -16658 53/push-ebx/outputs -16659 68/push 0x11/imm32/alloc-id:fake -16660 68/push 0/imm32/no-inouts -16661 68/push 0/imm32/no-inouts -16662 68/push 0/imm32/operation -16663 68/push 0/imm32/operation -16664 68/push 1/imm32 -16665 89/<- %esi 4/r32/esp -16666 $test-emit-subx-stmt-primitive-register:initialize-stmt-operation: -16667 # stmt->operation = "increment" -16668 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -16669 (copy-array Heap "increment" %eax) -16670 $test-emit-subx-stmt-primitive-register:initialize-formal-var: -16671 # var formal-var/ebx: (payload var) -16672 68/push 0/imm32/register -16673 68/push 0/imm32/register -16674 68/push 0/imm32/no-stack-offset -16675 68/push 1/imm32/block-depth -16676 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -16677 68/push 0x11/imm32/alloc-id:fake -16678 68/push 0/imm32/name -16679 68/push 0/imm32/name -16680 68/push 0x11/imm32/alloc-id:fake:payload -16681 89/<- %ebx 4/r32/esp -16682 $test-emit-subx-stmt-primitive-register:initialize-formal-var-name: -16683 # formal-var->name = "dummy" -16684 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -16685 (copy-array Heap "dummy" %eax) -16686 $test-emit-subx-stmt-primitive-register:initialize-formal-register: -16687 # formal-var->register = "*" -16688 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -16689 (copy-array Heap "*" %eax) # Any-register -16690 $test-emit-subx-stmt-primitive-register:initialize-var-list: -16691 # var formal-outputs/ebx: (payload list var) -16692 68/push 0/imm32/next -16693 68/push 0/imm32/next -16694 53/push-ebx/formal-var -16695 68/push 0x11/imm32/alloc-id:fake -16696 68/push 0x11/imm32/alloc-id:fake:payload -16697 89/<- %ebx 4/r32/esp -16698 $test-emit-subx-stmt-primitive-register:initialize-primitive: -16699 # var primitives/ebx: (addr primitive) -16700 68/push 0/imm32/next -16701 68/push 0/imm32/next -16702 68/push 0/imm32/output-is-write-only -16703 68/push 0/imm32/no-disp32 -16704 68/push 0/imm32/no-imm32 -16705 68/push 0/imm32/no-r32 -16706 68/push 3/imm32/rm32-is-first-output -16707 68/push 0/imm32/subx-name -16708 68/push 0/imm32/subx-name -16709 53/push-ebx/outputs -16710 68/push 0x11/imm32/alloc-id:fake -16711 68/push 0/imm32/no-inouts -16712 68/push 0/imm32/no-inouts -16713 68/push 0/imm32/name -16714 68/push 0/imm32/name -16715 89/<- %ebx 4/r32/esp -16716 $test-emit-subx-stmt-primitive-register:initialize-primitive-name: -16717 # primitives->name = "increment" -16718 (copy-array Heap "increment" %ebx) # Primitive-name -16719 $test-emit-subx-stmt-primitive-register:initialize-primitive-subx-name: -16720 # primitives->subx-name = "ff 0/subop/increment" -16721 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -16722 (copy-array Heap "ff 0/subop/increment" %eax) -16723 # convert -16724 c7 0/subop/copy *Curr-block-depth 0/imm32 -16725 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) -16726 (flush _test-output-buffered-file) -16727 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -16733 # check output -16734 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-primitive-register") -16735 # . epilogue -16736 89/<- %esp 5/r32/ebp -16737 5d/pop-to-ebp -16738 c3/return -16739 -16740 test-emit-subx-stmt-select-primitive: -16741 # Select the right primitive between overloads. -16742 # foo <- increment -16743 # => -16744 # ff 0/subop/increment %eax # sub-optimal, but should suffice -16745 # -16746 # There's a variable on the var stack as follows: -16747 # name: 'foo' -16748 # type: int -16749 # register: 'eax' -16750 # -16751 # There's two primitives, as follows: -16752 # - name: 'increment' -16753 # out: int/reg -16754 # value: 'ff 0/subop/increment' -16755 # - name: 'increment' -16756 # inout: int/mem -16757 # value: 'ff 0/subop/increment' -16758 # -16759 # . prologue -16760 55/push-ebp -16761 89/<- %ebp 4/r32/esp -16762 # setup -16763 (clear-stream _test-output-stream) -16764 (clear-stream $_test-output-buffered-file->buffer) -16765 $test-emit-subx-stmt-select-primitive:initialize-type: -16766 # var type/ecx: (payload tree type-id) = int -16767 68/push 0/imm32/right:null -16768 68/push 0/imm32/right:null -16769 68/push 0/imm32/left:unused -16770 68/push 1/imm32/value:int -16771 68/push 1/imm32/is-atom?:true -16772 68/push 0x11/imm32/alloc-id:fake:payload -16773 89/<- %ecx 4/r32/esp -16774 $test-emit-subx-stmt-select-primitive:initialize-var: -16775 # var var-foo/ecx: (payload var) -16776 68/push 0/imm32/register -16777 68/push 0/imm32/register -16778 68/push 0/imm32/no-stack-offset -16779 68/push 1/imm32/block-depth -16780 51/push-ecx -16781 68/push 0x11/imm32/alloc-id:fake -16782 68/push 0/imm32/name -16783 68/push 0/imm32/name -16784 68/push 0x11/imm32/alloc-id:fake:payload -16785 89/<- %ecx 4/r32/esp -16786 $test-emit-subx-stmt-select-primitive:initialize-var-name: -16787 # var-foo->name = "foo" -16788 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -16789 (copy-array Heap "foo" %eax) -16790 $test-emit-subx-stmt-select-primitive:initialize-var-register: -16791 # var-foo->register = "eax" -16792 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -16793 (copy-array Heap "eax" %eax) -16794 $test-emit-subx-stmt-select-primitive:initialize-stmt-var: -16795 # var operand/ebx: (payload stmt-var) -16796 68/push 0/imm32/is-deref:false -16797 68/push 0/imm32/next -16798 68/push 0/imm32/next -16799 51/push-ecx/var-foo -16800 68/push 0x11/imm32/alloc-id:fake -16801 68/push 0x11/imm32/alloc-id:fake:payload -16802 89/<- %ebx 4/r32/esp -16803 $test-emit-subx-stmt-select-primitive:initialize-stmt: -16804 # var stmt/esi: (addr statement) -16805 53/push-ebx/outputs -16806 68/push 0x11/imm32/alloc-id:fake -16807 68/push 0/imm32/no-inouts -16808 68/push 0/imm32/no-inouts -16809 68/push 0/imm32/operation -16810 68/push 0/imm32/operation -16811 68/push 1/imm32 -16812 89/<- %esi 4/r32/esp -16813 $test-emit-subx-stmt-select-primitive:initialize-stmt-operation: -16814 # stmt->operation = "increment" -16815 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -16816 (copy-array Heap "increment" %eax) -16817 $test-emit-subx-stmt-select-primitive:initialize-formal-var: -16818 # var formal-var/ebx: (payload var) -16819 68/push 0/imm32/register -16820 68/push 0/imm32/register -16821 68/push 0/imm32/no-stack-offset -16822 68/push 1/imm32/block-depth -16823 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -16824 68/push 0x11/imm32/alloc-id:fake -16825 68/push 0/imm32/name -16826 68/push 0/imm32/name -16827 68/push 0x11/imm32/alloc-id:fake:payload -16828 89/<- %ebx 4/r32/esp -16829 $test-emit-subx-stmt-select-primitive:initialize-formal-var-name: -16830 # formal-var->name = "dummy" -16831 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -16832 (copy-array Heap "dummy" %eax) -16833 $test-emit-subx-stmt-select-primitive:initialize-formal-register: -16834 # formal-var->register = "*" -16835 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -16836 (copy-array Heap "*" %eax) # Any-register -16837 $test-emit-subx-stmt-select-primitive:initialize-var-list: -16838 # var formal-outputs/ebx: (payload list var) -16839 68/push 0/imm32/next -16840 68/push 0/imm32/next -16841 53/push-ebx/formal-var -16842 68/push 0x11/imm32/alloc-id:fake -16843 68/push 0x11/imm32/alloc-id:fake:payload -16844 89/<- %ebx 4/r32/esp -16845 $test-emit-subx-stmt-select-primitive:initialize-primitive2: -16846 # var primitive2/edi: (payload primitive) -16847 68/push 0/imm32/next -16848 68/push 0/imm32/next -16849 68/push 0/imm32/output-is-write-only -16850 68/push 0/imm32/no-disp32 -16851 68/push 0/imm32/no-imm32 -16852 68/push 0/imm32/no-r32 -16853 68/push 3/imm32/rm32-is-first-output -16854 68/push 0/imm32/subx-name -16855 68/push 0/imm32/subx-name -16856 53/push-ebx/outputs -16857 68/push 0x11/imm32/alloc-id:fake -16858 68/push 0/imm32/no-inouts -16859 68/push 0/imm32/no-inouts -16860 68/push 0/imm32/name -16861 68/push 0/imm32/name -16862 68/push 0x11/imm32/alloc-id:fake:payload -16863 89/<- %edi 4/r32/esp -16864 $test-emit-subx-stmt-select-primitive:initialize-primitive2-name: -16865 # primitives->name = "increment" -16866 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 -16867 (copy-array Heap "increment" %eax) -16868 $test-emit-subx-stmt-select-primitive:initialize-primitive2-subx-name: -16869 # primitives->subx-name = "ff 0/subop/increment" -16870 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 -16871 (copy-array Heap "ff 0/subop/increment" %eax) -16872 $test-emit-subx-stmt-select-primitive:initialize-primitive: -16873 # var primitives/ebx: (addr primitive) -16874 57/push-edi -16875 68/push 0x11/imm32/alloc-id:fake -16876 68/push 0/imm32/output-is-write-only -16877 68/push 0/imm32/no-disp32 -16878 68/push 0/imm32/no-imm32 -16879 68/push 0/imm32/no-r32 -16880 68/push 1/imm32/rm32-is-first-inout -16881 68/push 0/imm32/subx-name -16882 68/push 0/imm32/subx-name -16883 68/push 0/imm32/no-outputs -16884 68/push 0/imm32/no-outputs -16885 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration -16886 68/push 0x11/imm32/alloc-id:fake -16887 68/push 0/imm32/name -16888 68/push 0/imm32/name -16889 89/<- %ebx 4/r32/esp -16890 $test-emit-subx-stmt-select-primitive:initialize-primitive-name: -16891 # primitives->name = "increment" -16892 (copy-array Heap "increment" %ebx) # Primitive-name -16893 $test-emit-subx-stmt-select-primitive:initialize-primitive-subx-name: -16894 # primitives->subx-name = "ff 0/subop/increment" -16895 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -16896 (copy-array Heap "ff 0/subop/increment" %eax) -16897 # convert -16898 c7 0/subop/copy *Curr-block-depth 0/imm32 -16899 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) -16900 (flush _test-output-buffered-file) -16901 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -16907 # check output -16908 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive") -16909 # . epilogue -16910 89/<- %esp 5/r32/ebp -16911 5d/pop-to-ebp -16912 c3/return -16913 -16914 test-emit-subx-stmt-select-primitive-2: -16915 # Select the right primitive between overloads. -16916 # increment foo -16917 # => -16918 # ff 0/subop/increment %eax # sub-optimal, but should suffice -16919 # -16920 # There's a variable on the var stack as follows: -16921 # name: 'foo' -16922 # type: int -16923 # register: 'eax' -16924 # -16925 # There's two primitives, as follows: -16926 # - name: 'increment' -16927 # out: int/reg -16928 # value: 'ff 0/subop/increment' -16929 # - name: 'increment' -16930 # inout: int/mem -16931 # value: 'ff 0/subop/increment' -16932 # -16933 # . prologue -16934 55/push-ebp -16935 89/<- %ebp 4/r32/esp -16936 # setup -16937 (clear-stream _test-output-stream) -16938 (clear-stream $_test-output-buffered-file->buffer) -16939 $test-emit-subx-stmt-select-primitive-2:initialize-type: -16940 # var type/ecx: (payload tree type-id) = int -16941 68/push 0/imm32/right:null -16942 68/push 0/imm32/right:null -16943 68/push 0/imm32/left:unused -16944 68/push 1/imm32/value:int -16945 68/push 1/imm32/is-atom?:true -16946 68/push 0x11/imm32/alloc-id:fake:payload -16947 89/<- %ecx 4/r32/esp -16948 $test-emit-subx-stmt-select-primitive-2:initialize-var: -16949 # var var-foo/ecx: (payload var) -16950 68/push 0/imm32/register -16951 68/push 0/imm32/register -16952 68/push 0/imm32/no-stack-offset -16953 68/push 1/imm32/block-depth -16954 51/push-ecx -16955 68/push 0x11/imm32/alloc-id:fake -16956 68/push 0/imm32/name -16957 68/push 0/imm32/name -16958 68/push 0x11/imm32/alloc-id:fake:payload -16959 89/<- %ecx 4/r32/esp -16960 $test-emit-subx-stmt-select-primitive-2:initialize-var-name: -16961 # var-foo->name = "foo" -16962 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -16963 (copy-array Heap "foo" %eax) -16964 $test-emit-subx-stmt-select-primitive-2:initialize-var-register: -16965 # var-foo->register = "eax" -16966 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -16967 (copy-array Heap "eax" %eax) -16968 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-var: -16969 # var operand/ebx: (payload stmt-var) -16970 68/push 0/imm32/is-deref:false -16971 68/push 0/imm32/next -16972 68/push 0/imm32/next -16973 51/push-ecx/var-foo -16974 68/push 0x11/imm32/alloc-id:fake -16975 68/push 0x11/imm32/alloc-id:fake:payload -16976 89/<- %ebx 4/r32/esp -16977 $test-emit-subx-stmt-select-primitive-2:initialize-stmt: -16978 # var stmt/esi: (addr statement) -16979 68/push 0/imm32/no-outputs -16980 68/push 0/imm32/no-outputs -16981 53/push-ebx/inouts -16982 68/push 0x11/imm32/alloc-id:fake -16983 68/push 0/imm32/operation -16984 68/push 0/imm32/operation -16985 68/push 1/imm32 -16986 89/<- %esi 4/r32/esp -16987 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-operation: -16988 # stmt->operation = "increment" -16989 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -16990 (copy-array Heap "increment" %eax) -16991 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var: -16992 # var formal-var/ebx: (payload var) -16993 68/push 0/imm32/register -16994 68/push 0/imm32/register -16995 68/push 0/imm32/no-stack-offset -16996 68/push 1/imm32/block-depth -16997 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id -16998 68/push 0x11/imm32/alloc-id:fake -16999 68/push 0/imm32/name -17000 68/push 0/imm32/name -17001 68/push 0x11/imm32/alloc-id:fake:payload -17002 89/<- %ebx 4/r32/esp -17003 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var-name: -17004 # formal-var->name = "dummy" -17005 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 -17006 (copy-array Heap "dummy" %eax) -17007 $test-emit-subx-stmt-select-primitive-2:initialize-formal-register: -17008 # formal-var->register = "*" -17009 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 -17010 (copy-array Heap "*" %eax) # Any-register -17011 $test-emit-subx-stmt-select-primitive-2:initialize-var-list: -17012 # var formal-outputs/ebx: (payload list stmt-var) -17013 68/push 0/imm32/next -17014 68/push 0/imm32/next -17015 53/push-ebx/formal-var -17016 68/push 0x11/imm32/alloc-id:fake -17017 68/push 0x11/imm32/alloc-id:fake:payload -17018 89/<- %ebx 4/r32/esp -17019 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2: -17020 # var primitive2/edi: (payload primitive) -17021 68/push 0/imm32/next -17022 68/push 0/imm32/next -17023 68/push 0/imm32/output-is-write-only -17024 68/push 0/imm32/no-disp32 -17025 68/push 0/imm32/no-imm32 -17026 68/push 0/imm32/no-r32 -17027 68/push 3/imm32/rm32-is-first-output -17028 68/push 0/imm32/subx-name -17029 68/push 0/imm32/subx-name -17030 53/push-ebx/outputs -17031 68/push 0x11/imm32/alloc-id:fake -17032 68/push 0/imm32/no-inouts -17033 68/push 0/imm32/no-inouts -17034 68/push 0/imm32/name -17035 68/push 0/imm32/name -17036 68/push 0x11/imm32/alloc-id:fake:payload -17037 89/<- %edi 4/r32/esp -17038 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-name: -17039 # primitives->name = "increment" -17040 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 -17041 (copy-array Heap "increment" %eax) -17042 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-subx-name: -17043 # primitives->subx-name = "ff 0/subop/increment" -17044 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 -17045 (copy-array Heap "ff 0/subop/increment" %eax) -17046 $test-emit-subx-stmt-select-primitive-2:initialize-primitive: -17047 # var primitives/ebx: (addr primitive) -17048 57/push-edi -17049 68/push 0x11/imm32/alloc-id:fake -17050 68/push 0/imm32/output-is-write-only -17051 68/push 0/imm32/no-disp32 -17052 68/push 0/imm32/no-imm32 -17053 68/push 0/imm32/no-r32 -17054 68/push 1/imm32/rm32-is-first-inout -17055 68/push 0/imm32/subx-name -17056 68/push 0/imm32/subx-name -17057 68/push 0/imm32/no-outputs -17058 68/push 0/imm32/no-outputs -17059 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration -17060 68/push 0x11/imm32/alloc-id:fake -17061 68/push 0/imm32/name -17062 68/push 0/imm32/name -17063 89/<- %ebx 4/r32/esp -17064 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-name: -17065 # primitives->name = "increment" -17066 (copy-array Heap "increment" %ebx) # Primitive-name -17067 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-subx-name: -17068 # primitives->subx-name = "ff 0/subop/increment" -17069 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name -17070 (copy-array Heap "ff 0/subop/increment" %eax) -17071 # convert -17072 c7 0/subop/copy *Curr-block-depth 0/imm32 -17073 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) -17074 (flush _test-output-buffered-file) -17075 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -17081 # check output -17082 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive-2") -17083 # . epilogue -17084 89/<- %esp 5/r32/ebp -17085 5d/pop-to-ebp -17086 c3/return -17087 -17088 test-increment-register: -17089 # Select the right register between overloads. -17090 # foo <- increment -17091 # => -17092 # 50/increment-eax -17093 # -17094 # There's a variable on the var stack as follows: -17095 # name: 'foo' -17096 # type: int -17097 # register: 'eax' -17098 # -17099 # Primitives are the global definitions. -17100 # -17101 # . prologue -17102 55/push-ebp -17103 89/<- %ebp 4/r32/esp -17104 # setup -17105 (clear-stream _test-output-stream) -17106 (clear-stream $_test-output-buffered-file->buffer) -17107 $test-increment-register:initialize-type: -17108 # var type/ecx: (payload tree type-id) = int -17109 68/push 0/imm32/right:null -17110 68/push 0/imm32/right:null -17111 68/push 0/imm32/left:unused -17112 68/push 1/imm32/value:int -17113 68/push 1/imm32/is-atom?:true -17114 68/push 0x11/imm32/alloc-id:fake:payload -17115 89/<- %ecx 4/r32/esp -17116 $test-increment-register:initialize-var: -17117 # var var-foo/ecx: (payload var) -17118 68/push 0/imm32/register -17119 68/push 0/imm32/register -17120 68/push 0/imm32/no-stack-offset -17121 68/push 1/imm32/block-depth -17122 51/push-ecx -17123 68/push 0x11/imm32/alloc-id:fake -17124 68/push 0/imm32/name -17125 68/push 0/imm32/name -17126 68/push 0x11/imm32/alloc-id:fake:payload -17127 89/<- %ecx 4/r32/esp -17128 $test-increment-register:initialize-var-name: -17129 # var-foo->name = "foo" -17130 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -17131 (copy-array Heap "foo" %eax) -17132 $test-increment-register:initialize-var-register: -17133 # var-foo->register = "eax" -17134 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -17135 (copy-array Heap "eax" %eax) -17136 $test-increment-register:initialize-stmt-var: -17137 # var operand/ebx: (payload stmt-var) -17138 68/push 0/imm32/is-deref:false -17139 68/push 0/imm32/next -17140 68/push 0/imm32/next -17141 51/push-ecx/var-foo -17142 68/push 0x11/imm32/alloc-id:fake -17143 68/push 0x11/imm32/alloc-id:fake:payload -17144 89/<- %ebx 4/r32/esp -17145 $test-increment-register:initialize-stmt: -17146 # var stmt/esi: (addr statement) -17147 53/push-ebx/outputs -17148 68/push 0x11/imm32/alloc-id:fake -17149 68/push 0/imm32/no-inouts -17150 68/push 0/imm32/no-inouts -17151 68/push 0/imm32/operation -17152 68/push 0/imm32/operation -17153 68/push 1/imm32 -17154 89/<- %esi 4/r32/esp -17155 $test-increment-register:initialize-stmt-operation: -17156 # stmt->operation = "increment" -17157 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -17158 (copy-array Heap "increment" %eax) -17159 # convert -17160 c7 0/subop/copy *Curr-block-depth 0/imm32 -17161 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -17162 (flush _test-output-buffered-file) -17163 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -17169 # check output -17170 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") -17171 # . epilogue -17172 89/<- %esp 5/r32/ebp -17173 5d/pop-to-ebp -17174 c3/return -17175 -17176 test-add-reg-to-reg: -17177 # var1/reg <- add var2/reg -17178 # => -17179 # 01/add-to %var1 var2 -17180 # -17181 # . prologue -17182 55/push-ebp -17183 89/<- %ebp 4/r32/esp -17184 # setup -17185 (clear-stream _test-output-stream) -17186 (clear-stream $_test-output-buffered-file->buffer) -17187 $test-add-reg-to-reg:initialize-type: -17188 # var type/ecx: (payload tree type-id) = int -17189 68/push 0/imm32/right:null -17190 68/push 0/imm32/right:null -17191 68/push 0/imm32/left:unused -17192 68/push 1/imm32/value:int -17193 68/push 1/imm32/is-atom?:true -17194 68/push 0x11/imm32/alloc-id:fake:payload -17195 89/<- %ecx 4/r32/esp -17196 $test-add-reg-to-reg:initialize-var1: -17197 # var var1/ecx: (payload var) -17198 68/push 0/imm32/register -17199 68/push 0/imm32/register -17200 68/push 0/imm32/no-stack-offset -17201 68/push 1/imm32/block-depth -17202 51/push-ecx -17203 68/push 0x11/imm32/alloc-id:fake -17204 68/push 0/imm32/name -17205 68/push 0/imm32/name -17206 68/push 0x11/imm32/alloc-id:fake:payload -17207 89/<- %ecx 4/r32/esp -17208 $test-add-reg-to-reg:initialize-var1-name: -17209 # var1->name = "var1" -17210 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -17211 (copy-array Heap "var1" %eax) -17212 $test-add-reg-to-reg:initialize-var1-register: -17213 # var1->register = "eax" -17214 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -17215 (copy-array Heap "eax" %eax) -17216 $test-add-reg-to-reg:initialize-var2: -17217 # var var2/edx: (payload var) -17218 68/push 0/imm32/register -17219 68/push 0/imm32/register -17220 68/push 0/imm32/no-stack-offset -17221 68/push 1/imm32/block-depth -17222 ff 6/subop/push *(ecx+0x10) -17223 68/push 0x11/imm32/alloc-id:fake -17224 68/push 0/imm32/name -17225 68/push 0/imm32/name -17226 68/push 0x11/imm32/alloc-id:fake:payload -17227 89/<- %edx 4/r32/esp -17228 $test-add-reg-to-reg:initialize-var2-name: -17229 # var2->name = "var2" -17230 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -17231 (copy-array Heap "var2" %eax) -17232 $test-add-reg-to-reg:initialize-var2-register: -17233 # var2->register = "ecx" -17234 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -17235 (copy-array Heap "ecx" %eax) -17236 $test-add-reg-to-reg:initialize-inouts: -17237 # var inouts/esi: (payload stmt-var) = [var2] -17238 68/push 0/imm32/is-deref:false -17239 68/push 0/imm32/next -17240 68/push 0/imm32/next -17241 52/push-edx/var2 -17242 68/push 0x11/imm32/alloc-id:fake -17243 68/push 0x11/imm32/alloc-id:fake:payload -17244 89/<- %esi 4/r32/esp -17245 $test-add-reg-to-reg:initialize-outputs: -17246 # var outputs/edi: (payload stmt-var) = [var1] -17247 68/push 0/imm32/is-deref:false -17248 68/push 0/imm32/next -17249 68/push 0/imm32/next -17250 51/push-ecx/var1 -17251 68/push 0x11/imm32/alloc-id:fake -17252 68/push 0x11/imm32/alloc-id:fake:payload -17253 89/<- %edi 4/r32/esp -17254 $test-add-reg-to-reg:initialize-stmt: -17255 # var stmt/esi: (addr statement) -17256 68/push 0/imm32/next -17257 68/push 0/imm32/next -17258 57/push-edi/outputs -17259 68/push 0x11/imm32/alloc-id:fake -17260 56/push-esi/inouts -17261 68/push 0x11/imm32/alloc-id:fake -17262 68/push 0/imm32/operation -17263 68/push 0/imm32/operation -17264 68/push 1/imm32/tag:stmt1 -17265 89/<- %esi 4/r32/esp -17266 $test-add-reg-to-reg:initialize-stmt-operation: -17267 # stmt->operation = "add" -17268 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -17269 (copy-array Heap "add" %eax) -17270 # convert -17271 c7 0/subop/copy *Curr-block-depth 0/imm32 -17272 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -17273 (flush _test-output-buffered-file) -17274 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -17280 # check output -17281 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") -17282 # . epilogue -17283 89/<- %esp 5/r32/ebp -17284 5d/pop-to-ebp -17285 c3/return -17286 -17287 test-add-reg-to-mem: -17288 # add-to var1 var2/reg -17289 # => -17290 # 01/add-to *(ebp+__) var2 -17291 # -17292 # . prologue -17293 55/push-ebp -17294 89/<- %ebp 4/r32/esp -17295 # setup -17296 (clear-stream _test-output-stream) -17297 (clear-stream $_test-output-buffered-file->buffer) -17298 $test-add-reg-to-mem:initialize-type: -17299 # var type/ecx: (payload tree type-id) = int -17300 68/push 0/imm32/right:null -17301 68/push 0/imm32/right:null -17302 68/push 0/imm32/left:unused -17303 68/push 1/imm32/value:int -17304 68/push 1/imm32/is-atom?:true -17305 68/push 0x11/imm32/alloc-id:fake:payload -17306 89/<- %ecx 4/r32/esp -17307 $test-add-reg-to-mem:initialize-var1: -17308 # var var1/ecx: (payload var) -17309 68/push 0/imm32/register -17310 68/push 0/imm32/register -17311 68/push 8/imm32/stack-offset -17312 68/push 1/imm32/block-depth -17313 51/push-ecx -17314 68/push 0x11/imm32/alloc-id:fake -17315 68/push 0/imm32/name -17316 68/push 0/imm32/name -17317 68/push 0x11/imm32/alloc-id:fake:payload -17318 89/<- %ecx 4/r32/esp -17319 $test-add-reg-to-mem:initialize-var1-name: -17320 # var1->name = "var1" -17321 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -17322 (copy-array Heap "var1" %eax) -17323 $test-add-reg-to-mem:initialize-var2: -17324 # var var2/edx: (payload var) -17325 68/push 0/imm32/register -17326 68/push 0/imm32/register -17327 68/push 0/imm32/no-stack-offset -17328 68/push 1/imm32/block-depth -17329 ff 6/subop/push *(ecx+0x10) -17330 68/push 0x11/imm32/alloc-id:fake -17331 68/push 0/imm32/name -17332 68/push 0/imm32/name -17333 68/push 0x11/imm32/alloc-id:fake:payload -17334 89/<- %edx 4/r32/esp -17335 $test-add-reg-to-mem:initialize-var2-name: -17336 # var2->name = "var2" -17337 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -17338 (copy-array Heap "var2" %eax) -17339 $test-add-reg-to-mem:initialize-var2-register: -17340 # var2->register = "ecx" -17341 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -17342 (copy-array Heap "ecx" %eax) -17343 $test-add-reg-to-mem:initialize-inouts: -17344 # var inouts/esi: (payload stmt-var) = [var2] -17345 68/push 0/imm32/is-deref:false -17346 68/push 0/imm32/next -17347 68/push 0/imm32/next -17348 52/push-edx/var2 -17349 68/push 0x11/imm32/alloc-id:fake -17350 68/push 0x11/imm32/alloc-id:fake:payload -17351 89/<- %esi 4/r32/esp -17352 # inouts = [var1, var2] -17353 68/push 0/imm32/is-deref:false -17354 56/push-esi/next -17355 68/push 0x11/imm32/alloc-id:fake -17356 51/push-ecx/var1 -17357 68/push 0x11/imm32/alloc-id:fake -17358 68/push 0x11/imm32/alloc-id:fake:payload -17359 89/<- %esi 4/r32/esp -17360 $test-add-reg-to-mem:initialize-stmt: -17361 # var stmt/esi: (addr statement) -17362 68/push 0/imm32/next -17363 68/push 0/imm32/next -17364 68/push 0/imm32/outputs -17365 68/push 0/imm32/outputs -17366 56/push-esi/inouts -17367 68/push 0x11/imm32/alloc-id:fake -17368 68/push 0/imm32/operation -17369 68/push 0/imm32/operation -17370 68/push 1/imm32/tag:stmt1 -17371 89/<- %esi 4/r32/esp -17372 $test-add-reg-to-mem:initialize-stmt-operation: -17373 # stmt->operation = "add-to" -17374 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -17375 (copy-array Heap "add-to" %eax) -17376 # convert -17377 c7 0/subop/copy *Curr-block-depth 0/imm32 -17378 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -17379 (flush _test-output-buffered-file) -17380 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -17386 # check output -17387 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") -17388 # . epilogue -17389 89/<- %esp 5/r32/ebp -17390 5d/pop-to-ebp -17391 c3/return -17392 -17393 test-add-mem-to-reg: -17394 # var1/reg <- add var2 -17395 # => -17396 # 03/add *(ebp+__) var1 -17397 # -17398 # . prologue -17399 55/push-ebp -17400 89/<- %ebp 4/r32/esp -17401 # setup -17402 (clear-stream _test-output-stream) -17403 (clear-stream $_test-output-buffered-file->buffer) -17404 $test-add-mem-to-reg:initialize-type: -17405 # var type/ecx: (payload tree type-id) = int -17406 68/push 0/imm32/right:null -17407 68/push 0/imm32/right:null -17408 68/push 0/imm32/left:unused -17409 68/push 1/imm32/value:int -17410 68/push 1/imm32/is-atom?:true -17411 68/push 0x11/imm32/alloc-id:fake:payload -17412 89/<- %ecx 4/r32/esp -17413 $test-add-mem-to-reg:initialize-var: -17414 # var var1/ecx: (payload var) -17415 68/push 0/imm32/register -17416 68/push 0/imm32/register -17417 68/push 0/imm32/no-stack-offset -17418 68/push 1/imm32/block-depth -17419 51/push-ecx -17420 68/push 0x11/imm32/alloc-id:fake -17421 68/push 0/imm32/name -17422 68/push 0/imm32/name -17423 68/push 0x11/imm32/alloc-id:fake:payload -17424 89/<- %ecx 4/r32/esp -17425 $test-add-mem-to-reg:initialize-var-name: -17426 # var1->name = "foo" -17427 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -17428 (copy-array Heap "var1" %eax) -17429 $test-add-mem-to-reg:initialize-var-register: -17430 # var1->register = "eax" -17431 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -17432 (copy-array Heap "eax" %eax) -17433 $test-add-mem-to-reg:initialize-var2: -17434 # var var2/edx: (payload var) -17435 68/push 0/imm32/register -17436 68/push 0/imm32/register -17437 68/push 8/imm32/stack-offset -17438 68/push 1/imm32/block-depth -17439 ff 6/subop/push *(ecx+0x10) -17440 68/push 0x11/imm32/alloc-id:fake -17441 68/push 0/imm32/name -17442 68/push 0/imm32/name -17443 68/push 0x11/imm32/alloc-id:fake:payload -17444 89/<- %edx 4/r32/esp -17445 $test-add-mem-to-reg:initialize-var2-name: -17446 # var2->name = "var2" -17447 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -17448 (copy-array Heap "var2" %eax) -17449 $test-add-mem-to-reg:initialize-inouts: -17450 # var inouts/esi: (payload stmt-var) = [var2] -17451 68/push 0/imm32/is-deref:false -17452 68/push 0/imm32/next -17453 68/push 0/imm32/next -17454 52/push-edx/var2 -17455 68/push 0x11/imm32/alloc-id:fake -17456 68/push 0x11/imm32/alloc-id:fake:payload -17457 89/<- %esi 4/r32/esp -17458 $test-add-mem-to-reg:initialize-outputs: -17459 # var outputs/edi: (payload stmt-var) = [var1] -17460 68/push 0/imm32/is-deref:false -17461 68/push 0/imm32/next -17462 68/push 0/imm32/next -17463 51/push-ecx/var1 -17464 68/push 0x11/imm32/alloc-id:fake -17465 68/push 0x11/imm32/alloc-id:fake:payload -17466 89/<- %edi 4/r32/esp -17467 $test-add-mem-to-reg:initialize-stmt: -17468 # var stmt/esi: (addr statement) -17469 68/push 0/imm32/next -17470 68/push 0/imm32/next -17471 57/push-edi/outputs -17472 68/push 0x11/imm32/alloc-id:fake -17473 56/push-esi/inouts -17474 68/push 0x11/imm32/alloc-id:fake -17475 68/push 0/imm32/operation -17476 68/push 0/imm32/operation -17477 68/push 1/imm32/tag:stmt1 -17478 89/<- %esi 4/r32/esp -17479 $test-add-mem-to-reg:initialize-stmt-operation: -17480 # stmt->operation = "add" -17481 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -17482 (copy-array Heap "add" %eax) -17483 # convert -17484 c7 0/subop/copy *Curr-block-depth 0/imm32 -17485 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -17486 (flush _test-output-buffered-file) -17487 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -17493 # check output -17494 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") -17495 # . epilogue -17496 89/<- %esp 5/r32/ebp -17497 5d/pop-to-ebp -17498 c3/return -17499 -17500 test-add-literal-to-eax: -17501 # var1/eax <- add 0x34 -17502 # => -17503 # 05/add-to-eax 0x34/imm32 -17504 # -17505 # . prologue -17506 55/push-ebp -17507 89/<- %ebp 4/r32/esp -17508 # setup -17509 (clear-stream _test-output-stream) -17510 (clear-stream $_test-output-buffered-file->buffer) -17511 $test-add-literal-to-eax:initialize-var-type: -17512 # var type/ecx: (payload tree type-id) = int -17513 68/push 0/imm32/right:null -17514 68/push 0/imm32/right:null -17515 68/push 0/imm32/left:unused -17516 68/push 1/imm32/value:int -17517 68/push 1/imm32/is-atom?:true -17518 68/push 0x11/imm32/alloc-id:fake:payload -17519 89/<- %ecx 4/r32/esp -17520 $test-add-literal-to-eax:initialize-var: -17521 # var v/ecx: (payload var) -17522 68/push 0/imm32/register -17523 68/push 0/imm32/register -17524 68/push 0/imm32/no-stack-offset -17525 68/push 1/imm32/block-depth -17526 51/push-ecx -17527 68/push 0x11/imm32/alloc-id:fake -17528 68/push 0/imm32/name -17529 68/push 0/imm32/name -17530 68/push 0x11/imm32/alloc-id:fake:payload -17531 89/<- %ecx 4/r32/esp -17532 $test-add-literal-to-eax:initialize-var-name: -17533 # v->name = "v" -17534 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -17535 (copy-array Heap "v" %eax) -17536 $test-add-literal-to-eax:initialize-var-register: -17537 # v->register = "eax" -17538 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -17539 (copy-array Heap "eax" %eax) -17540 $test-add-literal-to-eax:initialize-literal-type: -17541 # var type/edx: (payload tree type-id) = literal -17542 68/push 0/imm32/right:null -17543 68/push 0/imm32/right:null -17544 68/push 0/imm32/left:unused -17545 68/push 0/imm32/value:literal -17546 68/push 1/imm32/is-atom?:true -17547 68/push 0x11/imm32/alloc-id:fake:payload -17548 89/<- %edx 4/r32/esp -17549 $test-add-literal-to-eax:initialize-literal: -17550 # var l/edx: (payload var) -17551 68/push 0/imm32/register -17552 68/push 0/imm32/register -17553 68/push 0/imm32/no-stack-offset -17554 68/push 1/imm32/block-depth -17555 52/push-edx -17556 68/push 0x11/imm32/alloc-id:fake -17557 68/push 0/imm32/name -17558 68/push 0/imm32/name -17559 68/push 0x11/imm32/alloc-id:fake:payload -17560 89/<- %edx 4/r32/esp -17561 $test-add-literal-to-eax:initialize-literal-value: -17562 # l->name = "0x34" -17563 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -17564 (copy-array Heap "0x34" %eax) -17565 $test-add-literal-to-eax:initialize-inouts: -17566 # var inouts/esi: (payload stmt-var) = [l] -17567 68/push 0/imm32/is-deref:false -17568 68/push 0/imm32/next -17569 68/push 0/imm32/next -17570 52/push-edx/l -17571 68/push 0x11/imm32/alloc-id:fake -17572 68/push 0x11/imm32/alloc-id:fake:payload -17573 89/<- %esi 4/r32/esp -17574 $test-add-literal-to-eax:initialize-outputs: -17575 # var outputs/edi: (payload stmt-var) = [v] -17576 68/push 0/imm32/is-deref:false -17577 68/push 0/imm32/next -17578 68/push 0/imm32/next -17579 51/push-ecx/v -17580 68/push 0x11/imm32/alloc-id:fake -17581 68/push 0x11/imm32/alloc-id:fake:payload -17582 89/<- %edi 4/r32/esp -17583 $test-add-literal-to-eax:initialize-stmt: -17584 # var stmt/esi: (addr statement) -17585 68/push 0/imm32/next -17586 68/push 0/imm32/next -17587 57/push-edi/outputs -17588 68/push 0x11/imm32/alloc-id:fake -17589 56/push-esi/inouts -17590 68/push 0x11/imm32/alloc-id:fake -17591 68/push 0/imm32/operation -17592 68/push 0/imm32/operation -17593 68/push 1/imm32/tag:stmt1 -17594 89/<- %esi 4/r32/esp -17595 $test-add-literal-to-eax:initialize-stmt-operation: -17596 # stmt->operation = "add" -17597 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -17598 (copy-array Heap "add" %eax) -17599 # convert -17600 c7 0/subop/copy *Curr-block-depth 0/imm32 -17601 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -17602 (flush _test-output-buffered-file) -17603 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -17609 # check output -17610 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") -17611 # . epilogue -17612 89/<- %esp 5/r32/ebp -17613 5d/pop-to-ebp -17614 c3/return -17615 -17616 test-add-literal-to-reg: -17617 # var1/ecx <- add 0x34 -17618 # => -17619 # 81 0/subop/add %ecx 0x34/imm32 -17620 # -17621 # . prologue -17622 55/push-ebp -17623 89/<- %ebp 4/r32/esp -17624 # setup -17625 (clear-stream _test-output-stream) -17626 (clear-stream $_test-output-buffered-file->buffer) -17627 $test-add-literal-to-reg:initialize-var-type: -17628 # var type/ecx: (payload tree type-id) = int -17629 68/push 0/imm32/right:null -17630 68/push 0/imm32/right:null -17631 68/push 0/imm32/left:unused -17632 68/push 1/imm32/value:int -17633 68/push 1/imm32/is-atom?:true -17634 68/push 0x11/imm32/alloc-id:fake:payload -17635 89/<- %ecx 4/r32/esp -17636 $test-add-literal-to-reg:initialize-var: -17637 # var v/ecx: (payload var) -17638 68/push 0/imm32/register -17639 68/push 0/imm32/register -17640 68/push 0/imm32/no-stack-offset -17641 68/push 1/imm32/block-depth -17642 51/push-ecx -17643 68/push 0x11/imm32/alloc-id:fake -17644 68/push 0/imm32/name -17645 68/push 0/imm32/name -17646 68/push 0x11/imm32/alloc-id:fake:payload -17647 89/<- %ecx 4/r32/esp -17648 $test-add-literal-to-reg:initialize-var-name: -17649 # v->name = "v" -17650 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -17651 (copy-array Heap "v" %eax) -17652 $test-add-literal-to-reg:initialize-var-register: -17653 # v->register = "ecx" -17654 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -17655 (copy-array Heap "ecx" %eax) -17656 $test-add-literal-to-reg:initialize-literal-type: -17657 # var type/edx: (payload tree type-id) = literal -17658 68/push 0/imm32/right:null -17659 68/push 0/imm32/right:null -17660 68/push 0/imm32/left:unused -17661 68/push 0/imm32/value:literal -17662 68/push 1/imm32/is-atom?:true -17663 68/push 0x11/imm32/alloc-id:fake:payload -17664 89/<- %edx 4/r32/esp -17665 $test-add-literal-to-reg:initialize-literal: -17666 # var l/edx: (payload var) -17667 68/push 0/imm32/register -17668 68/push 0/imm32/register -17669 68/push 0/imm32/no-stack-offset -17670 68/push 1/imm32/block-depth -17671 52/push-edx -17672 68/push 0x11/imm32/alloc-id:fake -17673 68/push 0/imm32/name -17674 68/push 0/imm32/name -17675 68/push 0x11/imm32/alloc-id:fake:payload -17676 89/<- %edx 4/r32/esp -17677 $test-add-literal-to-reg:initialize-literal-value: -17678 # l->name = "0x34" -17679 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -17680 (copy-array Heap "0x34" %eax) -17681 $test-add-literal-to-reg:initialize-inouts: -17682 # var inouts/esi: (payload stmt-var) = [l] -17683 68/push 0/imm32/is-deref:false -17684 68/push 0/imm32/next -17685 68/push 0/imm32/next -17686 52/push-edx/l -17687 68/push 0x11/imm32/alloc-id:fake -17688 68/push 0x11/imm32/alloc-id:fake:payload -17689 89/<- %esi 4/r32/esp -17690 $test-add-literal-to-reg:initialize-outputs: -17691 # var outputs/edi: (payload stmt-var) = [v] -17692 68/push 0/imm32/is-deref:false -17693 68/push 0/imm32/next -17694 68/push 0/imm32/next -17695 51/push-ecx/v -17696 68/push 0x11/imm32/alloc-id:fake -17697 68/push 0x11/imm32/alloc-id:fake:payload -17698 89/<- %edi 4/r32/esp -17699 $test-add-literal-to-reg:initialize-stmt: -17700 # var stmt/esi: (addr statement) -17701 68/push 0/imm32/next -17702 68/push 0/imm32/next -17703 57/push-edi/outputs -17704 68/push 0x11/imm32/alloc-id:fake -17705 56/push-esi/inouts -17706 68/push 0x11/imm32/alloc-id:fake -17707 68/push 0/imm32/operation -17708 68/push 0/imm32/operation -17709 68/push 1/imm32/tag:stmt1 -17710 89/<- %esi 4/r32/esp -17711 $test-add-literal-to-reg:initialize-stmt-operation: -17712 # stmt->operation = "add" -17713 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -17714 (copy-array Heap "add" %eax) -17715 # convert -17716 c7 0/subop/copy *Curr-block-depth 0/imm32 -17717 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -17718 (flush _test-output-buffered-file) -17719 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -17725 # check output -17726 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") -17727 # . epilogue -17728 89/<- %esp 5/r32/ebp -17729 5d/pop-to-ebp -17730 c3/return -17731 -17732 test-add-literal-to-mem: -17733 # add-to var1, 0x34 -17734 # => -17735 # 81 0/subop/add %eax 0x34/imm32 -17736 # -17737 # . prologue -17738 55/push-ebp -17739 89/<- %ebp 4/r32/esp -17740 # setup -17741 (clear-stream _test-output-stream) -17742 (clear-stream $_test-output-buffered-file->buffer) -17743 $test-add-literal-to-mem:initialize-type: -17744 # var type/ecx: (payload tree type-id) = int -17745 68/push 0/imm32/right:null -17746 68/push 0/imm32/right:null -17747 68/push 0/imm32/left:unused -17748 68/push 1/imm32/value:int -17749 68/push 1/imm32/is-atom?:true -17750 68/push 0x11/imm32/alloc-id:fake:payload -17751 89/<- %ecx 4/r32/esp -17752 $test-add-literal-to-mem:initialize-var1: -17753 # var var1/ecx: (payload var) -17754 68/push 0/imm32/register -17755 68/push 0/imm32/register -17756 68/push 8/imm32/stack-offset -17757 68/push 1/imm32/block-depth -17758 51/push-ecx -17759 68/push 0x11/imm32/alloc-id:fake -17760 68/push 0/imm32/name -17761 68/push 0/imm32/name -17762 68/push 0x11/imm32/alloc-id:fake:payload -17763 89/<- %ecx 4/r32/esp -17764 $test-add-literal-to-mem:initialize-var1-name: -17765 # var1->name = "var1" -17766 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -17767 (copy-array Heap "var1" %eax) -17768 $test-add-literal-to-mem:initialize-literal-type: -17769 # var type/edx: (payload tree type-id) = literal -17770 68/push 0/imm32/right:null -17771 68/push 0/imm32/right:null -17772 68/push 0/imm32/left:unused -17773 68/push 0/imm32/value:literal -17774 68/push 1/imm32/is-atom?:true -17775 68/push 0x11/imm32/alloc-id:fake:payload -17776 89/<- %edx 4/r32/esp -17777 $test-add-literal-to-mem:initialize-literal: -17778 # var l/edx: (payload var) -17779 68/push 0/imm32/register -17780 68/push 0/imm32/register -17781 68/push 0/imm32/no-stack-offset -17782 68/push 1/imm32/block-depth -17783 52/push-edx -17784 68/push 0x11/imm32/alloc-id:fake -17785 68/push 0/imm32/name -17786 68/push 0/imm32/name -17787 68/push 0x11/imm32/alloc-id:fake:payload -17788 89/<- %edx 4/r32/esp -17789 $test-add-literal-to-mem:initialize-literal-value: -17790 # l->name = "0x34" -17791 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -17792 (copy-array Heap "0x34" %eax) -17793 $test-add-literal-to-mem:initialize-inouts: -17794 # var inouts/esi: (payload stmt-var) = [l] -17795 68/push 0/imm32/is-deref:false -17796 68/push 0/imm32/next -17797 68/push 0/imm32/next -17798 52/push-edx/l -17799 68/push 0x11/imm32/alloc-id:fake -17800 68/push 0x11/imm32/alloc-id:fake:payload -17801 89/<- %esi 4/r32/esp -17802 # var inouts = (handle stmt-var) = [var1, var2] -17803 68/push 0/imm32/is-deref:false -17804 56/push-esi/next -17805 68/push 0x11/imm32/alloc-id:fake -17806 51/push-ecx/var1 -17807 68/push 0x11/imm32/alloc-id:fake -17808 68/push 0x11/imm32/alloc-id:fake:payload -17809 89/<- %esi 4/r32/esp -17810 $test-add-literal-to-mem:initialize-stmt: -17811 # var stmt/esi: (addr statement) -17812 68/push 0/imm32/next -17813 68/push 0/imm32/next -17814 68/push 0/imm32/outputs -17815 68/push 0/imm32/outputs -17816 56/push-esi/inouts -17817 68/push 0x11/imm32/alloc-id:fake -17818 68/push 0/imm32/operation -17819 68/push 0/imm32/operation -17820 68/push 1/imm32/tag:stmt1 -17821 89/<- %esi 4/r32/esp -17822 $test-add-literal-to-mem:initialize-stmt-operation: -17823 # stmt->operation = "add-to" -17824 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -17825 (copy-array Heap "add-to" %eax) -17826 # convert -17827 c7 0/subop/copy *Curr-block-depth 0/imm32 -17828 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -17829 (flush _test-output-buffered-file) -17830 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -17836 # check output -17837 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") -17838 # . epilogue -17839 89/<- %esp 5/r32/ebp -17840 5d/pop-to-ebp -17841 c3/return -17842 -17843 test-compare-reg-with-reg: -17844 # compare var1/ecx, var2/eax -17845 # => -17846 # 39/compare %ecx 0/r32/eax -17847 # -17848 # . prologue -17849 55/push-ebp -17850 89/<- %ebp 4/r32/esp -17851 # setup -17852 (clear-stream _test-output-stream) -17853 (clear-stream $_test-output-buffered-file->buffer) -17854 $test-compare-reg-with-reg:initialize-type: -17855 # var type/ecx: (payload tree type-id) = int -17856 68/push 0/imm32/right:null -17857 68/push 0/imm32/right:null -17858 68/push 0/imm32/left:unused -17859 68/push 1/imm32/value:int -17860 68/push 1/imm32/is-atom?:true -17861 68/push 0x11/imm32/alloc-id:fake:payload -17862 89/<- %ecx 4/r32/esp -17863 $test-compare-reg-with-reg:initialize-var1: -17864 # var var1/ecx: (payload var) -17865 68/push 0/imm32/register -17866 68/push 0/imm32/register -17867 68/push 0/imm32/no-stack-offset -17868 68/push 1/imm32/block-depth -17869 51/push-ecx -17870 68/push 0x11/imm32/alloc-id:fake -17871 68/push 0/imm32/name -17872 68/push 0/imm32/name -17873 68/push 0x11/imm32/alloc-id:fake:payload -17874 89/<- %ecx 4/r32/esp -17875 $test-compare-reg-with-reg:initialize-var1-name: -17876 # var1->name = "var1" -17877 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -17878 (copy-array Heap "var1" %eax) -17879 $test-compare-reg-with-reg:initialize-var1-register: -17880 # var1->register = "ecx" -17881 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -17882 (copy-array Heap "ecx" %eax) -17883 $test-compare-reg-with-reg:initialize-var2: -17884 # var var2/edx: (payload var) -17885 68/push 0/imm32/register -17886 68/push 0/imm32/register -17887 68/push 0/imm32/no-stack-offset -17888 68/push 1/imm32/block-depth -17889 ff 6/subop/push *(ecx+0x10) -17890 68/push 0x11/imm32/alloc-id:fake -17891 68/push 0/imm32/name -17892 68/push 0/imm32/name -17893 68/push 0x11/imm32/alloc-id:fake:payload -17894 89/<- %edx 4/r32/esp -17895 $test-compare-reg-with-reg:initialize-var2-name: -17896 # var2->name = "var2" -17897 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -17898 (copy-array Heap "var2" %eax) -17899 $test-compare-reg-with-reg:initialize-var2-register: -17900 # var2->register = "eax" -17901 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -17902 (copy-array Heap "eax" %eax) -17903 $test-compare-reg-with-reg:initialize-inouts: -17904 # var inouts/esi: (payload stmt-var) = [var2] -17905 68/push 0/imm32/is-deref:false -17906 68/push 0/imm32/next -17907 68/push 0/imm32/next -17908 52/push-edx/var2 -17909 68/push 0x11/imm32/alloc-id:fake -17910 68/push 0x11/imm32/alloc-id:fake:payload -17911 89/<- %esi 4/r32/esp -17912 # inouts = [var1, var2] -17913 68/push 0/imm32/is-deref:false -17914 56/push-esi/next -17915 68/push 0x11/imm32/alloc-id:fake -17916 51/push-ecx/var1 -17917 68/push 0x11/imm32/alloc-id:fake -17918 68/push 0x11/imm32/alloc-id:fake:payload -17919 89/<- %esi 4/r32/esp -17920 $test-compare-reg-with-reg:initialize-stmt: -17921 # var stmt/esi: (addr statement) -17922 68/push 0/imm32/next -17923 68/push 0/imm32/next -17924 68/push 0/imm32/outputs -17925 68/push 0/imm32/outputs -17926 56/push-esi/inouts -17927 68/push 0x11/imm32/alloc-id:fake -17928 68/push 0/imm32/operation -17929 68/push 0/imm32/operation -17930 68/push 1/imm32/tag:stmt1 -17931 89/<- %esi 4/r32/esp -17932 $test-compare-reg-with-reg:initialize-stmt-operation: -17933 # stmt->operation = "compare" -17934 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -17935 (copy-array Heap "compare" %eax) -17936 # convert -17937 c7 0/subop/copy *Curr-block-depth 0/imm32 -17938 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -17939 (flush _test-output-buffered-file) -17940 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -17946 # check output -17947 (check-next-stream-line-equal _test-output-stream "39/compare-> %ecx 0x00000000/r32" "F - test-compare-reg-with-reg") -17948 # . epilogue -17949 89/<- %esp 5/r32/ebp -17950 5d/pop-to-ebp -17951 c3/return -17952 -17953 test-compare-mem-with-reg: -17954 # compare var1, var2/eax -17955 # => -17956 # 39/compare *(ebp+___) 0/r32/eax -17957 # -17958 # . prologue -17959 55/push-ebp -17960 89/<- %ebp 4/r32/esp -17961 # setup -17962 (clear-stream _test-output-stream) -17963 (clear-stream $_test-output-buffered-file->buffer) -17964 $test-compare-mem-with-reg:initialize-type: -17965 # var type/ecx: (payload tree type-id) = int -17966 68/push 0/imm32/right:null -17967 68/push 0/imm32/right:null -17968 68/push 0/imm32/left:unused -17969 68/push 1/imm32/value:int -17970 68/push 1/imm32/is-atom?:true -17971 68/push 0x11/imm32/alloc-id:fake:payload -17972 89/<- %ecx 4/r32/esp -17973 $test-compare-mem-with-reg:initialize-var1: -17974 # var var1/ecx: (payload var) -17975 68/push 0/imm32/register -17976 68/push 0/imm32/register -17977 68/push 8/imm32/stack-offset -17978 68/push 1/imm32/block-depth -17979 51/push-ecx -17980 68/push 0x11/imm32/alloc-id:fake -17981 68/push 0/imm32/name -17982 68/push 0/imm32/name -17983 68/push 0x11/imm32/alloc-id:fake:payload -17984 89/<- %ecx 4/r32/esp -17985 $test-compare-mem-with-reg:initialize-var1-name: -17986 # var1->name = "var1" -17987 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -17988 (copy-array Heap "var1" %eax) -17989 $test-compare-mem-with-reg:initialize-var2: -17990 # var var2/edx: (payload var) -17991 68/push 0/imm32/register -17992 68/push 0/imm32/register -17993 68/push 0/imm32/no-stack-offset -17994 68/push 1/imm32/block-depth -17995 ff 6/subop/push *(ecx+0x10) -17996 68/push 0x11/imm32/alloc-id:fake -17997 68/push 0/imm32/name -17998 68/push 0/imm32/name -17999 68/push 0x11/imm32/alloc-id:fake:payload -18000 89/<- %edx 4/r32/esp -18001 $test-compare-mem-with-reg:initialize-var2-name: -18002 # var2->name = "var2" -18003 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -18004 (copy-array Heap "var2" %eax) -18005 $test-compare-mem-with-reg:initialize-var2-register: -18006 # var2->register = "eax" -18007 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 -18008 (copy-array Heap "eax" %eax) -18009 $test-compare-mem-with-reg:initialize-inouts: -18010 # var inouts/esi: (payload stmt-var) = [var2] -18011 68/push 0/imm32/is-deref:false -18012 68/push 0/imm32/next -18013 68/push 0/imm32/next -18014 52/push-edx/var2 -18015 68/push 0x11/imm32/alloc-id:fake -18016 68/push 0x11/imm32/alloc-id:fake:payload -18017 89/<- %esi 4/r32/esp -18018 # inouts = [var1, var2] -18019 68/push 0/imm32/is-deref:false -18020 56/push-esi/next +15581 _string-break/imm32/name +15582 0/imm32/no-inouts +15583 0/imm32/no-inouts +15584 0/imm32/no-outputs +15585 0/imm32/no-outputs +15586 0x11/imm32/alloc-id:fake +15587 _string_e9_jump_break/imm32/subx-name +15588 0/imm32/no-rm32 +15589 0/imm32/no-r32 +15590 0/imm32/no-imm32 +15591 0/imm32/no-disp32 +15592 0/imm32/no-output +15593 0x11/imm32/alloc-id:fake +15594 _Primitive-loop-if-addr</imm32/next +15595 _Primitive-loop-if-addr<: # (payload primitive) +15596 0x11/imm32/alloc-id:fake:payload +15597 0x11/imm32/alloc-id:fake +15598 _string-loop-if-addr</imm32/name +15599 0/imm32/no-inouts +15600 0/imm32/no-inouts +15601 0/imm32/no-outputs +15602 0/imm32/no-outputs +15603 0x11/imm32/alloc-id:fake +15604 _string_0f_82_jump_loop/imm32/subx-name +15605 0/imm32/no-rm32 +15606 0/imm32/no-r32 +15607 0/imm32/no-imm32 +15608 0/imm32/no-disp32 +15609 0/imm32/no-output +15610 0x11/imm32/alloc-id:fake +15611 _Primitive-loop-if-addr>=/imm32/next +15612 _Primitive-loop-if-addr>=: # (payload primitive) +15613 0x11/imm32/alloc-id:fake:payload +15614 0x11/imm32/alloc-id:fake +15615 _string-loop-if-addr>=/imm32/name +15616 0/imm32/no-inouts +15617 0/imm32/no-inouts +15618 0/imm32/no-outputs +15619 0/imm32/no-outputs +15620 0x11/imm32/alloc-id:fake +15621 _string_0f_83_jump_loop/imm32/subx-name +15622 0/imm32/no-rm32 +15623 0/imm32/no-r32 +15624 0/imm32/no-imm32 +15625 0/imm32/no-disp32 +15626 0/imm32/no-output +15627 0x11/imm32/alloc-id:fake +15628 _Primitive-loop-if-=/imm32/next +15629 _Primitive-loop-if-=: # (payload primitive) +15630 0x11/imm32/alloc-id:fake:payload +15631 0x11/imm32/alloc-id:fake +15632 _string-loop-if-=/imm32/name +15633 0/imm32/no-inouts +15634 0/imm32/no-inouts +15635 0/imm32/no-outputs +15636 0/imm32/no-outputs +15637 0x11/imm32/alloc-id:fake +15638 _string_0f_84_jump_loop/imm32/subx-name +15639 0/imm32/no-rm32 +15640 0/imm32/no-r32 +15641 0/imm32/no-imm32 +15642 0/imm32/no-disp32 +15643 0/imm32/no-output +15644 0x11/imm32/alloc-id:fake +15645 _Primitive-loop-if-!=/imm32/next +15646 _Primitive-loop-if-!=: # (payload primitive) +15647 0x11/imm32/alloc-id:fake:payload +15648 0x11/imm32/alloc-id:fake +15649 _string-loop-if-!=/imm32/name +15650 0/imm32/no-inouts +15651 0/imm32/no-inouts +15652 0/imm32/no-outputs +15653 0/imm32/no-outputs +15654 0x11/imm32/alloc-id:fake +15655 _string_0f_85_jump_loop/imm32/subx-name +15656 0/imm32/no-rm32 +15657 0/imm32/no-r32 +15658 0/imm32/no-imm32 +15659 0/imm32/no-disp32 +15660 0/imm32/no-output +15661 0x11/imm32/alloc-id:fake +15662 _Primitive-loop-if-addr<=/imm32/next +15663 _Primitive-loop-if-addr<=: # (payload primitive) +15664 0x11/imm32/alloc-id:fake:payload +15665 0x11/imm32/alloc-id:fake +15666 _string-loop-if-addr<=/imm32/name +15667 0/imm32/no-inouts +15668 0/imm32/no-inouts +15669 0/imm32/no-outputs +15670 0/imm32/no-outputs +15671 0x11/imm32/alloc-id:fake +15672 _string_0f_86_jump_loop/imm32/subx-name +15673 0/imm32/no-rm32 +15674 0/imm32/no-r32 +15675 0/imm32/no-imm32 +15676 0/imm32/no-disp32 +15677 0/imm32/no-output +15678 0x11/imm32/alloc-id:fake +15679 _Primitive-loop-if-addr>/imm32/next +15680 _Primitive-loop-if-addr>: # (payload primitive) +15681 0x11/imm32/alloc-id:fake:payload +15682 0x11/imm32/alloc-id:fake +15683 _string-loop-if-addr>/imm32/name +15684 0/imm32/no-inouts +15685 0/imm32/no-inouts +15686 0/imm32/no-outputs +15687 0/imm32/no-outputs +15688 0x11/imm32/alloc-id:fake +15689 _string_0f_87_jump_loop/imm32/subx-name +15690 0/imm32/no-rm32 +15691 0/imm32/no-r32 +15692 0/imm32/no-imm32 +15693 0/imm32/no-disp32 +15694 0/imm32/no-output +15695 0x11/imm32/alloc-id:fake +15696 _Primitive-loop-if-</imm32/next +15697 _Primitive-loop-if-<: # (payload primitive) +15698 0x11/imm32/alloc-id:fake:payload +15699 0x11/imm32/alloc-id:fake +15700 _string-loop-if-</imm32/name +15701 0/imm32/no-inouts +15702 0/imm32/no-inouts +15703 0/imm32/no-outputs +15704 0/imm32/no-outputs +15705 0x11/imm32/alloc-id:fake +15706 _string_0f_8c_jump_loop/imm32/subx-name +15707 0/imm32/no-rm32 +15708 0/imm32/no-r32 +15709 0/imm32/no-imm32 +15710 0/imm32/no-disp32 +15711 0/imm32/no-output +15712 0x11/imm32/alloc-id:fake +15713 _Primitive-loop-if->=/imm32/next +15714 _Primitive-loop-if->=: # (payload primitive) +15715 0x11/imm32/alloc-id:fake:payload +15716 0x11/imm32/alloc-id:fake +15717 _string-loop-if->=/imm32/name +15718 0/imm32/no-inouts +15719 0/imm32/no-inouts +15720 0/imm32/no-outputs +15721 0/imm32/no-outputs +15722 0x11/imm32/alloc-id:fake +15723 _string_0f_8d_jump_loop/imm32/subx-name +15724 0/imm32/no-rm32 +15725 0/imm32/no-r32 +15726 0/imm32/no-imm32 +15727 0/imm32/no-disp32 +15728 0/imm32/no-output +15729 0x11/imm32/alloc-id:fake +15730 _Primitive-loop-if-<=/imm32/next +15731 _Primitive-loop-if-<=: # (payload primitive) +15732 0x11/imm32/alloc-id:fake:payload +15733 0x11/imm32/alloc-id:fake +15734 _string-loop-if-<=/imm32/name +15735 0/imm32/no-inouts +15736 0/imm32/no-inouts +15737 0/imm32/no-outputs +15738 0/imm32/no-outputs +15739 0x11/imm32/alloc-id:fake +15740 _string_0f_8e_jump_loop/imm32/subx-name +15741 0/imm32/no-rm32 +15742 0/imm32/no-r32 +15743 0/imm32/no-imm32 +15744 0/imm32/no-disp32 +15745 0/imm32/no-output +15746 0x11/imm32/alloc-id:fake +15747 _Primitive-loop-if->/imm32/next +15748 _Primitive-loop-if->: # (payload primitive) +15749 0x11/imm32/alloc-id:fake:payload +15750 0x11/imm32/alloc-id:fake +15751 _string-loop-if->/imm32/name +15752 0/imm32/no-inouts +15753 0/imm32/no-inouts +15754 0/imm32/no-outputs +15755 0/imm32/no-outputs +15756 0x11/imm32/alloc-id:fake +15757 _string_0f_8f_jump_loop/imm32/subx-name +15758 0/imm32/no-rm32 +15759 0/imm32/no-r32 +15760 0/imm32/no-imm32 +15761 0/imm32/no-disp32 +15762 0/imm32/no-output +15763 0x11/imm32/alloc-id:fake +15764 _Primitive-loop/imm32/next # we probably don't need an unconditional break +15765 _Primitive-loop: # (payload primitive) +15766 0x11/imm32/alloc-id:fake:payload +15767 0x11/imm32/alloc-id:fake +15768 _string-loop/imm32/name +15769 0/imm32/no-inouts +15770 0/imm32/no-inouts +15771 0/imm32/no-outputs +15772 0/imm32/no-outputs +15773 0x11/imm32/alloc-id:fake +15774 _string_e9_jump_loop/imm32/subx-name +15775 0/imm32/no-rm32 +15776 0/imm32/no-r32 +15777 0/imm32/no-imm32 +15778 0/imm32/no-disp32 +15779 0/imm32/no-output +15780 0x11/imm32/alloc-id:fake +15781 _Primitive-break-if-addr<-named/imm32/next +15782 # - branches to named blocks +15783 _Primitive-break-if-addr<-named: # (payload primitive) +15784 0x11/imm32/alloc-id:fake:payload +15785 0x11/imm32/alloc-id:fake +15786 _string-break-if-addr</imm32/name +15787 0x11/imm32/alloc-id:fake +15788 Single-lit-var/imm32/inouts +15789 0/imm32/no-outputs +15790 0/imm32/no-outputs +15791 0x11/imm32/alloc-id:fake +15792 _string_0f_82_jump_label/imm32/subx-name +15793 0/imm32/no-rm32 +15794 0/imm32/no-r32 +15795 0/imm32/no-imm32 +15796 1/imm32/disp32-is-first-inout +15797 0/imm32/no-output +15798 0x11/imm32/alloc-id:fake +15799 _Primitive-break-if-addr>=-named/imm32/next +15800 _Primitive-break-if-addr>=-named: # (payload primitive) +15801 0x11/imm32/alloc-id:fake:payload +15802 0x11/imm32/alloc-id:fake +15803 _string-break-if-addr>=/imm32/name +15804 0x11/imm32/alloc-id:fake +15805 Single-lit-var/imm32/inouts +15806 0/imm32/no-outputs +15807 0/imm32/no-outputs +15808 0x11/imm32/alloc-id:fake +15809 _string_0f_83_jump_label/imm32/subx-name +15810 0/imm32/no-rm32 +15811 0/imm32/no-r32 +15812 0/imm32/no-imm32 +15813 1/imm32/disp32-is-first-inout +15814 0/imm32/no-output +15815 0x11/imm32/alloc-id:fake +15816 _Primitive-break-if-=-named/imm32/next +15817 _Primitive-break-if-=-named: # (payload primitive) +15818 0x11/imm32/alloc-id:fake:payload +15819 0x11/imm32/alloc-id:fake +15820 _string-break-if-=/imm32/name +15821 0x11/imm32/alloc-id:fake +15822 Single-lit-var/imm32/inouts +15823 0/imm32/no-outputs +15824 0/imm32/no-outputs +15825 0x11/imm32/alloc-id:fake +15826 _string_0f_84_jump_label/imm32/subx-name +15827 0/imm32/no-rm32 +15828 0/imm32/no-r32 +15829 0/imm32/no-imm32 +15830 1/imm32/disp32-is-first-inout +15831 0/imm32/no-output +15832 0x11/imm32/alloc-id:fake +15833 _Primitive-break-if-!=-named/imm32/next +15834 _Primitive-break-if-!=-named: # (payload primitive) +15835 0x11/imm32/alloc-id:fake:payload +15836 0x11/imm32/alloc-id:fake +15837 _string-break-if-!=/imm32/name +15838 0x11/imm32/alloc-id:fake +15839 Single-lit-var/imm32/inouts +15840 0/imm32/no-outputs +15841 0/imm32/no-outputs +15842 0x11/imm32/alloc-id:fake +15843 _string_0f_85_jump_label/imm32/subx-name +15844 0/imm32/no-rm32 +15845 0/imm32/no-r32 +15846 0/imm32/no-imm32 +15847 1/imm32/disp32-is-first-inout +15848 0/imm32/no-output +15849 0x11/imm32/alloc-id:fake +15850 _Primitive-break-if-addr<=-named/imm32/next +15851 _Primitive-break-if-addr<=-named: # (payload primitive) +15852 0x11/imm32/alloc-id:fake:payload +15853 0x11/imm32/alloc-id:fake +15854 _string-break-if-addr<=/imm32/name +15855 0x11/imm32/alloc-id:fake +15856 Single-lit-var/imm32/inouts +15857 0/imm32/no-outputs +15858 0/imm32/no-outputs +15859 0x11/imm32/alloc-id:fake +15860 _string_0f_86_jump_label/imm32/subx-name +15861 0/imm32/no-rm32 +15862 0/imm32/no-r32 +15863 0/imm32/no-imm32 +15864 1/imm32/disp32-is-first-inout +15865 0/imm32/no-output +15866 0x11/imm32/alloc-id:fake +15867 _Primitive-break-if-addr>-named/imm32/next +15868 _Primitive-break-if-addr>-named: # (payload primitive) +15869 0x11/imm32/alloc-id:fake:payload +15870 0x11/imm32/alloc-id:fake +15871 _string-break-if-addr>/imm32/name +15872 0x11/imm32/alloc-id:fake +15873 Single-lit-var/imm32/inouts +15874 0/imm32/no-outputs +15875 0/imm32/no-outputs +15876 0x11/imm32/alloc-id:fake +15877 _string_0f_87_jump_label/imm32/subx-name +15878 0/imm32/no-rm32 +15879 0/imm32/no-r32 +15880 0/imm32/no-imm32 +15881 1/imm32/disp32-is-first-inout +15882 0/imm32/no-output +15883 0x11/imm32/alloc-id:fake +15884 _Primitive-break-if-<-named/imm32/next +15885 _Primitive-break-if-<-named: # (payload primitive) +15886 0x11/imm32/alloc-id:fake:payload +15887 0x11/imm32/alloc-id:fake +15888 _string-break-if-</imm32/name +15889 0x11/imm32/alloc-id:fake +15890 Single-lit-var/imm32/inouts +15891 0/imm32/no-outputs +15892 0/imm32/no-outputs +15893 0x11/imm32/alloc-id:fake +15894 _string_0f_8c_jump_label/imm32/subx-name +15895 0/imm32/no-rm32 +15896 0/imm32/no-r32 +15897 0/imm32/no-imm32 +15898 1/imm32/disp32-is-first-inout +15899 0/imm32/no-output +15900 0x11/imm32/alloc-id:fake +15901 _Primitive-break-if->=-named/imm32/next +15902 _Primitive-break-if->=-named: # (payload primitive) +15903 0x11/imm32/alloc-id:fake:payload +15904 0x11/imm32/alloc-id:fake +15905 _string-break-if->=/imm32/name +15906 0x11/imm32/alloc-id:fake +15907 Single-lit-var/imm32/inouts +15908 0/imm32/no-outputs +15909 0/imm32/no-outputs +15910 0x11/imm32/alloc-id:fake +15911 _string_0f_8d_jump_label/imm32/subx-name +15912 0/imm32/no-rm32 +15913 0/imm32/no-r32 +15914 0/imm32/no-imm32 +15915 1/imm32/disp32-is-first-inout +15916 0/imm32/no-output +15917 0x11/imm32/alloc-id:fake +15918 _Primitive-break-if-<=-named/imm32/next +15919 _Primitive-break-if-<=-named: # (payload primitive) +15920 0x11/imm32/alloc-id:fake:payload +15921 0x11/imm32/alloc-id:fake +15922 _string-break-if-<=/imm32/name +15923 0x11/imm32/alloc-id:fake +15924 Single-lit-var/imm32/inouts +15925 0/imm32/no-outputs +15926 0/imm32/no-outputs +15927 0x11/imm32/alloc-id:fake +15928 _string_0f_8e_jump_label/imm32/subx-name +15929 0/imm32/no-rm32 +15930 0/imm32/no-r32 +15931 0/imm32/no-imm32 +15932 1/imm32/disp32-is-first-inout +15933 0/imm32/no-output +15934 0x11/imm32/alloc-id:fake +15935 _Primitive-break-if->-named/imm32/next +15936 _Primitive-break-if->-named: # (payload primitive) +15937 0x11/imm32/alloc-id:fake:payload +15938 0x11/imm32/alloc-id:fake +15939 _string-break-if->/imm32/name +15940 0x11/imm32/alloc-id:fake +15941 Single-lit-var/imm32/inouts +15942 0/imm32/no-outputs +15943 0/imm32/no-outputs +15944 0x11/imm32/alloc-id:fake +15945 _string_0f_8f_jump_label/imm32/subx-name +15946 0/imm32/no-rm32 +15947 0/imm32/no-r32 +15948 0/imm32/no-imm32 +15949 1/imm32/disp32-is-first-inout +15950 0/imm32/no-output +15951 0x11/imm32/alloc-id:fake +15952 _Primitive-break-named/imm32/next +15953 _Primitive-break-named: # (payload primitive) +15954 0x11/imm32/alloc-id:fake:payload +15955 0x11/imm32/alloc-id:fake +15956 _string-break/imm32/name +15957 0x11/imm32/alloc-id:fake +15958 Single-lit-var/imm32/inouts +15959 0/imm32/no-outputs +15960 0/imm32/no-outputs +15961 0x11/imm32/alloc-id:fake +15962 _string_e9_jump_label/imm32/subx-name +15963 0/imm32/no-rm32 +15964 0/imm32/no-r32 +15965 0/imm32/no-imm32 +15966 1/imm32/disp32-is-first-inout +15967 0/imm32/no-output +15968 0x11/imm32/alloc-id:fake +15969 _Primitive-loop-if-addr<-named/imm32/next +15970 _Primitive-loop-if-addr<-named: # (payload primitive) +15971 0x11/imm32/alloc-id:fake:payload +15972 0x11/imm32/alloc-id:fake +15973 _string-loop-if-addr</imm32/name +15974 0x11/imm32/alloc-id:fake +15975 Single-lit-var/imm32/inouts +15976 0/imm32/no-outputs +15977 0/imm32/no-outputs +15978 0x11/imm32/alloc-id:fake +15979 _string_0f_82_jump_label/imm32/subx-name +15980 0/imm32/no-rm32 +15981 0/imm32/no-r32 +15982 0/imm32/no-imm32 +15983 1/imm32/disp32-is-first-inout +15984 0/imm32/no-output +15985 0x11/imm32/alloc-id:fake +15986 _Primitive-loop-if-addr>=-named/imm32/next +15987 _Primitive-loop-if-addr>=-named: # (payload primitive) +15988 0x11/imm32/alloc-id:fake:payload +15989 0x11/imm32/alloc-id:fake +15990 _string-loop-if-addr>=/imm32/name +15991 0x11/imm32/alloc-id:fake +15992 Single-lit-var/imm32/inouts +15993 0/imm32/no-outputs +15994 0/imm32/no-outputs +15995 0x11/imm32/alloc-id:fake +15996 _string_0f_83_jump_label/imm32/subx-name +15997 0/imm32/no-rm32 +15998 0/imm32/no-r32 +15999 0/imm32/no-imm32 +16000 1/imm32/disp32-is-first-inout +16001 0/imm32/no-output +16002 0x11/imm32/alloc-id:fake +16003 _Primitive-loop-if-=-named/imm32/next +16004 _Primitive-loop-if-=-named: # (payload primitive) +16005 0x11/imm32/alloc-id:fake:payload +16006 0x11/imm32/alloc-id:fake +16007 _string-loop-if-=/imm32/name +16008 0x11/imm32/alloc-id:fake +16009 Single-lit-var/imm32/inouts +16010 0/imm32/no-outputs +16011 0/imm32/no-outputs +16012 0x11/imm32/alloc-id:fake +16013 _string_0f_84_jump_label/imm32/subx-name +16014 0/imm32/no-rm32 +16015 0/imm32/no-r32 +16016 0/imm32/no-imm32 +16017 1/imm32/disp32-is-first-inout +16018 0/imm32/no-output +16019 0x11/imm32/alloc-id:fake +16020 _Primitive-loop-if-!=-named/imm32/next +16021 _Primitive-loop-if-!=-named: # (payload primitive) +16022 0x11/imm32/alloc-id:fake:payload +16023 0x11/imm32/alloc-id:fake +16024 _string-loop-if-!=/imm32/name +16025 0x11/imm32/alloc-id:fake +16026 Single-lit-var/imm32/inouts +16027 0/imm32/no-outputs +16028 0/imm32/no-outputs +16029 0x11/imm32/alloc-id:fake +16030 _string_0f_85_jump_label/imm32/subx-name +16031 0/imm32/no-rm32 +16032 0/imm32/no-r32 +16033 0/imm32/no-imm32 +16034 1/imm32/disp32-is-first-inout +16035 0/imm32/no-output +16036 0x11/imm32/alloc-id:fake +16037 _Primitive-loop-if-addr<=-named/imm32/next +16038 _Primitive-loop-if-addr<=-named: # (payload primitive) +16039 0x11/imm32/alloc-id:fake:payload +16040 0x11/imm32/alloc-id:fake +16041 _string-loop-if-addr<=/imm32/name +16042 0x11/imm32/alloc-id:fake +16043 Single-lit-var/imm32/inouts +16044 0/imm32/no-outputs +16045 0/imm32/no-outputs +16046 0x11/imm32/alloc-id:fake +16047 _string_0f_86_jump_label/imm32/subx-name +16048 0/imm32/no-rm32 +16049 0/imm32/no-r32 +16050 0/imm32/no-imm32 +16051 1/imm32/disp32-is-first-inout +16052 0/imm32/no-output +16053 0x11/imm32/alloc-id:fake +16054 _Primitive-loop-if-addr>-named/imm32/next +16055 _Primitive-loop-if-addr>-named: # (payload primitive) +16056 0x11/imm32/alloc-id:fake:payload +16057 0x11/imm32/alloc-id:fake +16058 _string-loop-if-addr>/imm32/name +16059 0x11/imm32/alloc-id:fake +16060 Single-lit-var/imm32/inouts +16061 0/imm32/no-outputs +16062 0/imm32/no-outputs +16063 0x11/imm32/alloc-id:fake +16064 _string_0f_87_jump_label/imm32/subx-name +16065 0/imm32/no-rm32 +16066 0/imm32/no-r32 +16067 0/imm32/no-imm32 +16068 1/imm32/disp32-is-first-inout +16069 0/imm32/no-output +16070 0x11/imm32/alloc-id:fake +16071 _Primitive-loop-if-<-named/imm32/next +16072 _Primitive-loop-if-<-named: # (payload primitive) +16073 0x11/imm32/alloc-id:fake:payload +16074 0x11/imm32/alloc-id:fake +16075 _string-loop-if-</imm32/name +16076 0x11/imm32/alloc-id:fake +16077 Single-lit-var/imm32/inouts +16078 0/imm32/no-outputs +16079 0/imm32/no-outputs +16080 0x11/imm32/alloc-id:fake +16081 _string_0f_8c_jump_label/imm32/subx-name +16082 0/imm32/no-rm32 +16083 0/imm32/no-r32 +16084 0/imm32/no-imm32 +16085 1/imm32/disp32-is-first-inout +16086 0/imm32/no-output +16087 0x11/imm32/alloc-id:fake +16088 _Primitive-loop-if->=-named/imm32/next +16089 _Primitive-loop-if->=-named: # (payload primitive) +16090 0x11/imm32/alloc-id:fake:payload +16091 0x11/imm32/alloc-id:fake +16092 _string-loop-if->=/imm32/name +16093 0x11/imm32/alloc-id:fake +16094 Single-lit-var/imm32/inouts +16095 0/imm32/no-outputs +16096 0/imm32/no-outputs +16097 0x11/imm32/alloc-id:fake +16098 _string_0f_8d_jump_label/imm32/subx-name +16099 0/imm32/no-rm32 +16100 0/imm32/no-r32 +16101 0/imm32/no-imm32 +16102 1/imm32/disp32-is-first-inout +16103 0/imm32/no-output +16104 0x11/imm32/alloc-id:fake +16105 _Primitive-loop-if-<=-named/imm32/next +16106 _Primitive-loop-if-<=-named: # (payload primitive) +16107 0x11/imm32/alloc-id:fake:payload +16108 0x11/imm32/alloc-id:fake +16109 _string-loop-if-<=/imm32/name +16110 0x11/imm32/alloc-id:fake +16111 Single-lit-var/imm32/inouts +16112 0/imm32/no-outputs +16113 0/imm32/no-outputs +16114 0x11/imm32/alloc-id:fake +16115 _string_0f_8e_jump_label/imm32/subx-name +16116 0/imm32/no-rm32 +16117 0/imm32/no-r32 +16118 0/imm32/no-imm32 +16119 1/imm32/disp32-is-first-inout +16120 0/imm32/no-output +16121 0x11/imm32/alloc-id:fake +16122 _Primitive-loop-if->-named/imm32/next +16123 _Primitive-loop-if->-named: # (payload primitive) +16124 0x11/imm32/alloc-id:fake:payload +16125 0x11/imm32/alloc-id:fake +16126 _string-loop-if->/imm32/name +16127 0x11/imm32/alloc-id:fake +16128 Single-lit-var/imm32/inouts +16129 0/imm32/no-outputs +16130 0/imm32/no-outputs +16131 0x11/imm32/alloc-id:fake +16132 _string_0f_8f_jump_label/imm32/subx-name +16133 0/imm32/no-rm32 +16134 0/imm32/no-r32 +16135 0/imm32/no-imm32 +16136 1/imm32/disp32-is-first-inout +16137 0/imm32/no-output +16138 0x11/imm32/alloc-id:fake +16139 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break +16140 _Primitive-loop-named: # (payload primitive) +16141 0x11/imm32/alloc-id:fake:payload +16142 0x11/imm32/alloc-id:fake +16143 _string-loop/imm32/name +16144 0x11/imm32/alloc-id:fake +16145 Single-lit-var/imm32/inouts +16146 0/imm32/no-outputs +16147 0/imm32/no-outputs +16148 0x11/imm32/alloc-id:fake +16149 _string_e9_jump_label/imm32/subx-name +16150 0/imm32/no-rm32 +16151 0/imm32/no-r32 +16152 0/imm32/no-imm32 +16153 1/imm32/disp32-is-first-inout +16154 0/imm32/no-output +16155 0/imm32/next +16156 0/imm32/next +16157 +16158 # string literals for Mu instructions +16159 _string-add: # (payload array byte) +16160 0x11/imm32/alloc-id:fake:payload +16161 # "add" +16162 0x3/imm32/size +16163 0x61/a 0x64/d 0x64/d +16164 _string-address: # (payload array byte) +16165 0x11/imm32/alloc-id:fake:payload +16166 # "address" +16167 0x7/imm32/size +16168 0x61/a 0x64/d 0x64/d 0x72/r 0x65/e 0x73/s 0x73/s +16169 _string-add-to: # (payload array byte) +16170 0x11/imm32/alloc-id:fake:payload +16171 # "add-to" +16172 0x6/imm32/size +16173 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o +16174 _string-and: # (payload array byte) +16175 0x11/imm32/alloc-id:fake:payload +16176 # "and" +16177 0x3/imm32/size +16178 0x61/a 0x6e/n 0x64/d +16179 _string-and-with: # (payload array byte) +16180 0x11/imm32/alloc-id:fake:payload +16181 # "and-with" +16182 0x8/imm32/size +16183 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +16184 _string-break: # (payload array byte) +16185 0x11/imm32/alloc-id:fake:payload +16186 # "break" +16187 0x5/imm32/size +16188 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k +16189 _string-break-if-<: # (payload array byte) +16190 0x11/imm32/alloc-id:fake:payload +16191 # "break-if-<" +16192 0xa/imm32/size +16193 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +16194 _string-break-if-<=: # (payload array byte) +16195 0x11/imm32/alloc-id:fake:payload +16196 # "break-if-<=" +16197 0xb/imm32/size +16198 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +16199 _string-break-if-=: # (payload array byte) +16200 0x11/imm32/alloc-id:fake:payload +16201 # "break-if-=" +16202 0xa/imm32/size +16203 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +16204 _string-break-if->: # (payload array byte) +16205 0x11/imm32/alloc-id:fake:payload +16206 # "break-if->" +16207 0xa/imm32/size +16208 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +16209 _string-break-if->=: # (payload array byte) +16210 0x11/imm32/alloc-id:fake:payload +16211 # "break-if->=" +16212 0xb/imm32/size +16213 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +16214 _string-break-if-!=: # (payload array byte) +16215 0x11/imm32/alloc-id:fake:payload +16216 # "break-if-!=" +16217 0xb/imm32/size +16218 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +16219 _string-break-if-addr<: # (payload array byte) +16220 0x11/imm32/alloc-id:fake:payload +16221 # "break-if-addr<" +16222 0xe/imm32/size +16223 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/< +16224 _string-break-if-addr<=: # (payload array byte) +16225 0x11/imm32/alloc-id:fake:payload +16226 # "break-if-addr<=" +16227 0xf/imm32/size +16228 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/= +16229 _string-break-if-addr>: # (payload array byte) +16230 0x11/imm32/alloc-id:fake:payload +16231 # "break-if-addr>" +16232 0xe/imm32/size +16233 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/> +16234 _string-break-if-addr>=: # (payload array byte) +16235 0x11/imm32/alloc-id:fake:payload +16236 # "break-if-addr>=" +16237 0xf/imm32/size +16238 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/= +16239 _string-compare: # (payload array byte) +16240 0x11/imm32/alloc-id:fake:payload +16241 # "compare" +16242 0x7/imm32/size +16243 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e +16244 _string-copy: # (payload array byte) +16245 0x11/imm32/alloc-id:fake:payload +16246 # "copy" +16247 0x4/imm32/size +16248 0x63/c 0x6f/o 0x70/p 0x79/y +16249 _string-copy-to: # (payload array byte) +16250 0x11/imm32/alloc-id:fake:payload +16251 # "copy-to" +16252 0x7/imm32/size +16253 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x74/t 0x6f/o +16254 _string-copy-byte: +16255 0x11/imm32/alloc-id:fake:payload +16256 # "copy-byte" +16257 0x9/imm32/size +16258 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e +16259 _string-copy-byte-to: +16260 0x11/imm32/alloc-id:fake:payload +16261 # "copy-byte-to" +16262 0xc/imm32/size +16263 0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x74/t 0x6f/o +16264 _string-decrement: # (payload array byte) +16265 0x11/imm32/alloc-id:fake:payload +16266 # "decrement" +16267 0x9/imm32/size +16268 0x64/d 0x65/e 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +16269 _string-increment: # (payload array byte) +16270 0x11/imm32/alloc-id:fake:payload +16271 # "increment" +16272 0x9/imm32/size +16273 0x69/i 0x6e/n 0x63/c 0x72/r 0x65/e 0x6d/m 0x65/e 0x6e/n 0x74/t +16274 _string-loop: # (payload array byte) +16275 0x11/imm32/alloc-id:fake:payload +16276 # "loop" +16277 0x4/imm32/size +16278 0x6c/l 0x6f/o 0x6f/o 0x70/p +16279 _string-loop-if-<: # (payload array byte) +16280 0x11/imm32/alloc-id:fake:payload +16281 # "loop-if-<" +16282 0x9/imm32/size +16283 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< +16284 _string-loop-if-<=: # (payload array byte) +16285 0x11/imm32/alloc-id:fake:payload +16286 # "loop-if-<=" +16287 0xa/imm32/size +16288 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3c/< 0x3d/= +16289 _string-loop-if-=: # (payload array byte) +16290 0x11/imm32/alloc-id:fake:payload +16291 # "loop-if-=" +16292 0x9/imm32/size +16293 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= +16294 _string-loop-if->: # (payload array byte) +16295 0x11/imm32/alloc-id:fake:payload +16296 # "loop-if->" +16297 0x9/imm32/size +16298 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> +16299 _string-loop-if->=: # (payload array byte) +16300 0x11/imm32/alloc-id:fake:payload +16301 # "loop-if->=" +16302 0xa/imm32/size +16303 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3e/> 0x3d/= +16304 _string-loop-if-!=: # (payload array byte) +16305 0x11/imm32/alloc-id:fake:payload +16306 # "loop-if-!=" +16307 0xa/imm32/size +16308 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x21/! 0x3d/= +16309 _string-loop-if-addr<: # (payload array byte) +16310 0x11/imm32/alloc-id:fake:payload +16311 # "loop-if-addr<" +16312 0xd/imm32/size +16313 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/< +16314 _string-loop-if-addr<=: # (payload array byte) +16315 0x11/imm32/alloc-id:fake:payload +16316 # "loop-if-addr<=" +16317 0xe/imm32/size +16318 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/= +16319 _string-loop-if-addr>: # (payload array byte) +16320 0x11/imm32/alloc-id:fake:payload +16321 # "loop-if-addr>" +16322 0xd/imm32/size +16323 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/> +16324 _string-loop-if-addr>=: # (payload array byte) +16325 0x11/imm32/alloc-id:fake:payload +16326 # "loop-if-addr>=" +16327 0xe/imm32/size +16328 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/= +16329 _string-multiply: # (payload array byte) +16330 0x11/imm32/alloc-id:fake:payload +16331 # "multiply" +16332 0x8/imm32/size +16333 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y +16334 _string-or: # (payload array byte) +16335 0x11/imm32/alloc-id:fake:payload +16336 # "or" +16337 0x2/imm32/size +16338 0x6f/o 0x72/r +16339 _string-or-with: # (payload array byte) +16340 0x11/imm32/alloc-id:fake:payload +16341 # "or-with" +16342 0x7/imm32/size +16343 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +16344 _string-subtract: # (payload array byte) +16345 0x11/imm32/alloc-id:fake:payload +16346 # "subtract" +16347 0x8/imm32/size +16348 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +16349 _string-subtract-from: # (payload array byte) +16350 0x11/imm32/alloc-id:fake:payload +16351 # "subtract-from" +16352 0xd/imm32/size +16353 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 +16354 _string-xor: # (payload array byte) +16355 0x11/imm32/alloc-id:fake:payload +16356 # "xor" +16357 0x3/imm32/size +16358 0x78/x 0x6f/o 0x72/r +16359 _string-xor-with: # (payload array byte) +16360 0x11/imm32/alloc-id:fake:payload +16361 # "xor-with" +16362 0x8/imm32/size +16363 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +16364 +16365 # string literals for SubX instructions +16366 _string_01_add_to: # (payload array byte) +16367 0x11/imm32/alloc-id:fake:payload +16368 # "01/add-to" +16369 0x9/imm32/size +16370 0x30/0 0x31/1 0x2f/slash 0x61/a 0x64/d 0x64/d 0x2d/dash 0x74/t 0x6f/o +16371 _string_03_add: # (payload array byte) +16372 0x11/imm32/alloc-id:fake:payload +16373 # "03/add" +16374 0x6/imm32/size +16375 0x30/0 0x33/3 0x2f/slash 0x61/a 0x64/d 0x64/d +16376 _string_05_add_to_eax: # (payload array byte) +16377 0x11/imm32/alloc-id:fake:payload +16378 # "05/add-to-eax" +16379 0xd/imm32/size +16380 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 +16381 _string_09_or_with: # (payload array byte) +16382 0x11/imm32/alloc-id:fake:payload +16383 # "09/or-with" +16384 0xa/imm32/size +16385 0x30/0 0x39/9 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +16386 _string_0b_or: # (payload array byte) +16387 0x11/imm32/alloc-id:fake:payload +16388 # "0b/or" +16389 0x5/imm32/size +16390 0x30/0 0x62/b 0x2f/slash 0x6f/o 0x72/r +16391 _string_0d_or_with_eax: # (payload array byte) +16392 0x11/imm32/alloc-id:fake:payload +16393 # "0d/or-with-eax" +16394 0xe/imm32/size +16395 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 +16396 _string_0f_82_jump_label: # (payload array byte) +16397 0x11/imm32/alloc-id:fake:payload +16398 # "0f 82/jump-if-addr<" +16399 0x13/imm32/size +16400 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/< +16401 _string_0f_82_jump_break: # (payload array byte) +16402 0x11/imm32/alloc-id:fake:payload +16403 # "0f 82/jump-if-addr< break/disp32" +16404 0x20/imm32/size +16405 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 +16406 _string_0f_82_jump_loop: # (payload array byte) +16407 0x11/imm32/alloc-id:fake:payload +16408 # "0f 82/jump-if-addr< loop/disp32" +16409 0x1f/imm32/size +16410 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 +16411 _string_0f_83_jump_label: # (payload array byte) +16412 0x11/imm32/alloc-id:fake:payload +16413 # "0f 83/jump-if-addr>=" +16414 0x14/imm32/size +16415 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/= +16416 _string_0f_83_jump_break: # (payload array byte) +16417 0x11/imm32/alloc-id:fake:payload +16418 # "0f 83/jump-if-addr>= break/disp32" +16419 0x21/imm32/size +16420 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 +16421 _string_0f_83_jump_loop: # (payload array byte) +16422 0x11/imm32/alloc-id:fake:payload +16423 # "0f 83/jump-if-addr>= loop/disp32" +16424 0x20/imm32/size +16425 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 +16426 _string_0f_84_jump_label: # (payload array byte) +16427 0x11/imm32/alloc-id:fake:payload +16428 # "0f 84/jump-if-=" +16429 0xf/imm32/size +16430 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/= +16431 _string_0f_84_jump_break: # (payload array byte) +16432 0x11/imm32/alloc-id:fake:payload +16433 # "0f 84/jump-if-= break/disp32" +16434 0x1c/imm32/size +16435 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 +16436 _string_0f_84_jump_loop: # (payload array byte) +16437 0x11/imm32/alloc-id:fake:payload +16438 # "0f 84/jump-if-= loop/disp32" +16439 0x1b/imm32/size +16440 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 +16441 _string_0f_85_jump_label: # (payload array byte) +16442 0x11/imm32/alloc-id:fake:payload +16443 # "0f 85/jump-if-!=" +16444 0x10/imm32/size +16445 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/= +16446 _string_0f_85_jump_break: # (payload array byte) +16447 0x11/imm32/alloc-id:fake:payload +16448 # "0f 85/jump-if-!= break/disp32" +16449 0x1d/imm32/size +16450 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 +16451 _string_0f_85_jump_loop: # (payload array byte) +16452 0x11/imm32/alloc-id:fake:payload +16453 # "0f 85/jump-if-!= loop/disp32" +16454 0x1c/imm32/size +16455 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 +16456 _string_0f_86_jump_label: # (payload array byte) +16457 0x11/imm32/alloc-id:fake:payload +16458 # "0f 86/jump-if-addr<=" +16459 0x14/imm32/size +16460 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/= +16461 _string_0f_86_jump_break: # (payload array byte) +16462 0x11/imm32/alloc-id:fake:payload +16463 # "0f 86/jump-if-addr<= break/disp32" +16464 0x21/imm32/size +16465 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 +16466 _string_0f_86_jump_loop: # (payload array byte) +16467 0x11/imm32/alloc-id:fake:payload +16468 # "0f 86/jump-if-addr<= loop/disp32" +16469 0x20/imm32/size +16470 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 +16471 _string_0f_87_jump_label: # (payload array byte) +16472 0x11/imm32/alloc-id:fake:payload +16473 # "0f 87/jump-if-addr>" +16474 0x13/imm32/size +16475 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/> +16476 _string_0f_87_jump_break: # (payload array byte) +16477 0x11/imm32/alloc-id:fake:payload +16478 # "0f 87/jump-if-addr> break/disp32" +16479 0x20/imm32/size +16480 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 +16481 _string_0f_87_jump_loop: # (payload array byte) +16482 0x11/imm32/alloc-id:fake:payload +16483 # "0f 87/jump-if-addr> loop/disp32" +16484 0x1f/imm32/size +16485 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 +16486 _string_0f_8c_jump_label: # (payload array byte) +16487 0x11/imm32/alloc-id:fake:payload +16488 # "0f 8c/jump-if-<" +16489 0xf/imm32/size +16490 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/< +16491 _string_0f_8c_jump_break: # (payload array byte) +16492 0x11/imm32/alloc-id:fake:payload +16493 # "0f 8c/jump-if-< break/disp32" +16494 0x1c/imm32/size +16495 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 +16496 _string_0f_8c_jump_loop: # (payload array byte) +16497 0x11/imm32/alloc-id:fake:payload +16498 # "0f 8c/jump-if-< loop/disp32" +16499 0x1b/imm32/size +16500 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 +16501 _string_0f_8d_jump_label: # (payload array byte) +16502 0x11/imm32/alloc-id:fake:payload +16503 # "0f 8d/jump-if->=" +16504 0x10/imm32/size +16505 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/= +16506 _string_0f_8d_jump_break: # (payload array byte) +16507 0x11/imm32/alloc-id:fake:payload +16508 # "0f 8d/jump-if->= break/disp32" +16509 0x1d/imm32/size +16510 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 +16511 _string_0f_8d_jump_loop: # (payload array byte) +16512 0x11/imm32/alloc-id:fake:payload +16513 # "0f 8d/jump-if->= loop/disp32" +16514 0x1c/imm32/size +16515 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 +16516 _string_0f_8e_jump_label: # (payload array byte) +16517 0x11/imm32/alloc-id:fake:payload +16518 # "0f 8e/jump-if-<=" +16519 0x10/imm32/size +16520 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/= +16521 _string_0f_8e_jump_break: # (payload array byte) +16522 0x11/imm32/alloc-id:fake:payload +16523 # "0f 8e/jump-if-<= break/disp32" +16524 0x1d/imm32/size +16525 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 +16526 _string_0f_8e_jump_loop: # (payload array byte) +16527 0x11/imm32/alloc-id:fake:payload +16528 # "0f 8e/jump-if-<= loop/disp32" +16529 0x1c/imm32/size +16530 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 +16531 _string_0f_8f_jump_label: # (payload array byte) +16532 0x11/imm32/alloc-id:fake:payload +16533 # "0f 8f/jump-if->" +16534 0xf/imm32/size +16535 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/> +16536 _string_0f_8f_jump_break: # (payload array byte) +16537 0x11/imm32/alloc-id:fake:payload +16538 # "0f 8f/jump-if-> break/disp32" +16539 0x1c/imm32/size +16540 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 +16541 _string_0f_8f_jump_loop: # (payload array byte) +16542 0x11/imm32/alloc-id:fake:payload +16543 # "0f 8f/jump-if-> loop/disp32" +16544 0x1b/imm32/size +16545 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 +16546 _string_0f_af_multiply: # (payload array byte) +16547 0x11/imm32/alloc-id:fake:payload +16548 # "0f af/multiply" +16549 0xe/imm32/size +16550 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 +16551 _string_21_and_with: # (payload array byte) +16552 0x11/imm32/alloc-id:fake:payload +16553 # "21/and-with" +16554 0xb/imm32/size +16555 0x32/2 0x31/1 0x2f/slash 0x61/a 0x6e/n 0x64/d 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +16556 _string_23_and: # (payload array byte) +16557 0x11/imm32/alloc-id:fake:payload +16558 # "23/and" +16559 0x6/imm32/size +16560 0x32/2 0x33/3 0x2f/slash 0x61/a 0x6e/n 0x64/d +16561 _string_25_and_with_eax: # (payload array byte) +16562 0x11/imm32/alloc-id:fake:payload +16563 # "25/and-with-eax" +16564 0xf/imm32/size +16565 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 +16566 _string_29_subtract_from: # (payload array byte) +16567 0x11/imm32/alloc-id:fake:payload +16568 # "29/subtract-from" +16569 0x10/imm32/size +16570 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 +16571 _string_2b_subtract: # (payload array byte) +16572 0x11/imm32/alloc-id:fake:payload +16573 # "2b/subtract" +16574 0xb/imm32/size +16575 0x32/2 0x62/b 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t +16576 _string_2d_subtract_from_eax: # (payload array byte) +16577 0x11/imm32/alloc-id:fake:payload +16578 # "2d/subtract-from-eax" +16579 0x14/imm32/size +16580 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 +16581 _string_31_xor_with: # (payload array byte) +16582 0x11/imm32/alloc-id:fake:payload +16583 # "31/xor-with" +16584 0xb/imm32/size +16585 0x33/3 0x31/1 0x2f/slash 0x78/x 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h +16586 _string_33_xor: # (payload array byte) +16587 0x11/imm32/alloc-id:fake:payload +16588 # "33/xor" +16589 0x6/imm32/size +16590 0x33/3 0x33/3 0x2f/slash 0x78/x 0x6f/o 0x72/r +16591 _string_35_xor_with_eax: # (payload array byte) +16592 0x11/imm32/alloc-id:fake:payload +16593 # "35/xor-with-eax" +16594 0xf/imm32/size +16595 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 +16596 _string_39_compare->: # (payload array byte) +16597 0x11/imm32/alloc-id:fake:payload +16598 # "39/compare->" +16599 0xc/imm32/size +16600 0x33/3 0x39/9 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x2d/dash 0x3e/> +16601 _string_3b_compare<-: # (payload array byte) +16602 0x11/imm32/alloc-id:fake:payload +16603 # "3b/compare<-" +16604 0xc/imm32/size +16605 0x33/3 0x62/b 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e 0x3c/< 0x2d/dash +16606 _string_3d_compare_eax_with: # (payload array byte) +16607 0x11/imm32/alloc-id:fake:payload +16608 # "3d/compare-eax-with" +16609 0x13/imm32/size +16610 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 +16611 _string_40_increment_eax: # (payload array byte) +16612 0x11/imm32/alloc-id:fake:payload +16613 # "40/increment-eax" +16614 0x10/imm32/size +16615 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 +16616 _string_41_increment_ecx: # (payload array byte) +16617 0x11/imm32/alloc-id:fake:payload +16618 # "41/increment-ecx" +16619 0x10/imm32/size +16620 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 +16621 _string_42_increment_edx: # (payload array byte) +16622 0x11/imm32/alloc-id:fake:payload +16623 # "42/increment-edx" +16624 0x10/imm32/size +16625 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 +16626 _string_43_increment_ebx: # (payload array byte) +16627 0x11/imm32/alloc-id:fake:payload +16628 # "43/increment-ebx" +16629 0x10/imm32/size +16630 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 +16631 _string_46_increment_esi: # (payload array byte) +16632 0x11/imm32/alloc-id:fake:payload +16633 # "46/increment-esi" +16634 0x10/imm32/size +16635 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 +16636 _string_47_increment_edi: # (payload array byte) +16637 0x11/imm32/alloc-id:fake:payload +16638 # "47/increment-edi" +16639 0x10/imm32/size +16640 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 +16641 _string_48_decrement_eax: # (payload array byte) +16642 0x11/imm32/alloc-id:fake:payload +16643 # "48/decrement-eax" +16644 0x10/imm32/size +16645 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 +16646 _string_49_decrement_ecx: # (payload array byte) +16647 0x11/imm32/alloc-id:fake:payload +16648 # "49/decrement-ecx" +16649 0x10/imm32/size +16650 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 +16651 _string_4a_decrement_edx: # (payload array byte) +16652 0x11/imm32/alloc-id:fake:payload +16653 # "4a/decrement-edx" +16654 0x10/imm32/size +16655 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 +16656 _string_4b_decrement_ebx: # (payload array byte) +16657 0x11/imm32/alloc-id:fake:payload +16658 # "4b/decrement-ebx" +16659 0x10/imm32/size +16660 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 +16661 _string_4e_decrement_esi: # (payload array byte) +16662 0x11/imm32/alloc-id:fake:payload +16663 # "4e/decrement-esi" +16664 0x10/imm32/size +16665 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 +16666 _string_4f_decrement_edi: # (payload array byte) +16667 0x11/imm32/alloc-id:fake:payload +16668 # "4f/decrement-edi" +16669 0x10/imm32/size +16670 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 +16671 _string_81_subop_add: # (payload array byte) +16672 0x11/imm32/alloc-id:fake:payload +16673 # "81 0/subop/add" +16674 0xe/imm32/size +16675 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 +16676 _string_81_subop_or: # (payload array byte) +16677 0x11/imm32/alloc-id:fake:payload +16678 # "81 1/subop/or" +16679 0xd/imm32/size +16680 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 +16681 _string_81_subop_and: # (payload array byte) +16682 0x11/imm32/alloc-id:fake:payload +16683 # "81 4/subop/and" +16684 0xe/imm32/size +16685 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 +16686 _string_81_subop_subtract: # (payload array byte) +16687 0x11/imm32/alloc-id:fake:payload +16688 # "81 5/subop/subtract" +16689 0x13/imm32/size +16690 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 +16691 _string_81_subop_xor: # (payload array byte) +16692 0x11/imm32/alloc-id:fake:payload +16693 # "81 6/subop/xor" +16694 0xe/imm32/size +16695 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 +16696 _string_81_subop_compare: # (payload array byte) +16697 0x11/imm32/alloc-id:fake:payload +16698 # "81 7/subop/compare" +16699 0x12/imm32/size +16700 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 +16701 _string_89_<-: # (payload array byte) +16702 0x11/imm32/alloc-id:fake:payload +16703 # "89/<-" +16704 0x5/imm32/size +16705 0x38/8 0x39/9 0x2f/slash 0x3c/< 0x2d/dash +16706 _string_8b_->: # (payload array byte) +16707 0x11/imm32/alloc-id:fake:payload +16708 # "8b/->" +16709 0x5/imm32/size +16710 0x38/8 0x62/b 0x2f/slash 0x2d/dash 0x3e/> +16711 _string_8a_copy_byte: +16712 0x11/imm32/alloc-id:fake:payload +16713 # "8a/byte->" +16714 0x9/imm32/size +16715 0x38/8 0x61/a 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x3e/> +16716 _string_88_copy_byte: +16717 0x11/imm32/alloc-id:fake:payload +16718 # "88/byte<-" +16719 0x9/imm32/size +16720 0x38/8 0x38/8 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/- +16721 _string_8d_copy_address: # (payload array byte) +16722 0x11/imm32/alloc-id:fake:payload +16723 # "8d/copy-address" +16724 0xf/imm32/size +16725 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 +16726 _string_b8_copy_to_eax: # (payload array byte) +16727 0x11/imm32/alloc-id:fake:payload +16728 # "b8/copy-to-eax" +16729 0xe/imm32/size +16730 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 +16731 _string_b9_copy_to_ecx: # (payload array byte) +16732 0x11/imm32/alloc-id:fake:payload +16733 # "b9/copy-to-ecx" +16734 0xe/imm32/size +16735 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 +16736 _string_ba_copy_to_edx: # (payload array byte) +16737 0x11/imm32/alloc-id:fake:payload +16738 # "ba/copy-to-edx" +16739 0xe/imm32/size +16740 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 +16741 _string_bb_copy_to_ebx: # (payload array byte) +16742 0x11/imm32/alloc-id:fake:payload +16743 # "bb/copy-to-ebx" +16744 0xe/imm32/size +16745 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 +16746 _string_be_copy_to_esi: # (payload array byte) +16747 0x11/imm32/alloc-id:fake:payload +16748 # "be/copy-to-esi" +16749 0xe/imm32/size +16750 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 +16751 _string_bf_copy_to_edi: # (payload array byte) +16752 0x11/imm32/alloc-id:fake:payload +16753 # "bf/copy-to-edi" +16754 0xe/imm32/size +16755 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 +16756 _string_c7_subop_copy: # (payload array byte) +16757 0x11/imm32/alloc-id:fake:payload +16758 # "c7 0/subop/copy" +16759 0xf/imm32/size +16760 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 +16761 _string_e9_jump_label: # (payload array byte) +16762 0x11/imm32/alloc-id:fake:payload +16763 # "e9/jump" +16764 0x7/imm32/size +16765 0x65/e 0x39/9 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p +16766 _string_e9_jump_break: # (payload array byte) +16767 0x11/imm32/alloc-id:fake:payload +16768 # "e9/jump break/disp32" +16769 0x14/imm32/size +16770 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 +16771 _string_e9_jump_loop: # (payload array byte) +16772 0x11/imm32/alloc-id:fake:payload +16773 # "e9/jump loop/disp32" +16774 0x13/imm32/size +16775 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 +16776 _string_ff_subop_increment: # (payload array byte) +16777 0x11/imm32/alloc-id:fake:payload +16778 # "ff 0/subop/increment" +16779 0x14/imm32/size +16780 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 +16781 _string_ff_subop_decrement: # (payload array byte) +16782 0x11/imm32/alloc-id:fake:payload +16783 # "ff 1/subop/decrement" +16784 0x14/imm32/size +16785 0x66/f 0x66/f 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 +16786 +16787 Single-int-var-in-mem: # (payload list var) +16788 0x11/imm32/alloc-id:fake:payload +16789 0x11/imm32/alloc-id:fake +16790 Int-var-in-mem/imm32 +16791 0/imm32/next +16792 0/imm32/next +16793 +16794 Int-var-in-mem: # (payload var) +16795 0x11/imm32/alloc-id:fake:payload +16796 0/imm32/name +16797 0/imm32/name +16798 0x11/imm32/alloc-id:fake +16799 Type-int/imm32 +16800 1/imm32/some-block-depth +16801 1/imm32/some-stack-offset +16802 0/imm32/no-register +16803 0/imm32/no-register +16804 +16805 # Not really legal, but closest we can currently represent a dereference of an (addr byte) +16806 Single-byte-var-in-mem: # (payload list var) +16807 0x11/imm32/alloc-id:fake:payload +16808 0x11/imm32/alloc-id:fake +16809 Byte-var-in-mem/imm32 +16810 0/imm32/next +16811 0/imm32/next +16812 +16813 # Not really legal, but closest we can currently represent a dereference of an (addr byte) +16814 Byte-var-in-mem: # (payload var) +16815 0x11/imm32/alloc-id:fake:payload +16816 0/imm32/name +16817 0/imm32/name +16818 0x11/imm32/alloc-id:fake +16819 Type-byte/imm32 +16820 1/imm32/some-block-depth +16821 1/imm32/some-stack-offset +16822 0/imm32/no-register +16823 0/imm32/no-register +16824 +16825 Two-args-int-stack-int-reg: # (payload list var) +16826 0x11/imm32/alloc-id:fake:payload +16827 0x11/imm32/alloc-id:fake +16828 Int-var-in-mem/imm32 +16829 0x11/imm32/alloc-id:fake +16830 Single-int-var-in-some-register/imm32/next +16831 +16832 Two-int-args-in-regs: # (payload list var) +16833 0x11/imm32/alloc-id:fake:payload +16834 0x11/imm32/alloc-id:fake +16835 Int-var-in-some-register/imm32 +16836 0x11/imm32/alloc-id:fake +16837 Single-int-var-in-some-register/imm32/next +16838 +16839 # Not really legal, but closest we can currently represent a dereference of an (addr byte) +16840 Two-args-byte-stack-byte-reg: # (payload list var) +16841 0x11/imm32/alloc-id:fake:payload +16842 0x11/imm32/alloc-id:fake +16843 Byte-var-in-mem/imm32 +16844 0x11/imm32/alloc-id:fake +16845 Single-byte-var-in-some-register/imm32/next +16846 +16847 Two-args-int-reg-int-stack: # (payload list var) +16848 0x11/imm32/alloc-id:fake:payload +16849 0x11/imm32/alloc-id:fake +16850 Int-var-in-some-register/imm32 +16851 0x11/imm32/alloc-id:fake +16852 Single-int-var-in-mem/imm32/next +16853 +16854 Two-args-int-eax-int-literal: # (payload list var) +16855 0x11/imm32/alloc-id:fake:payload +16856 0x11/imm32/alloc-id:fake +16857 Int-var-in-eax/imm32 +16858 0x11/imm32/alloc-id:fake +16859 Single-lit-var/imm32/next +16860 +16861 Int-var-and-literal: # (payload list var) +16862 0x11/imm32/alloc-id:fake:payload +16863 0x11/imm32/alloc-id:fake +16864 Int-var-in-mem/imm32 +16865 0x11/imm32/alloc-id:fake +16866 Single-lit-var/imm32/next +16867 +16868 Int-var-in-register-and-literal: # (payload list var) +16869 0x11/imm32/alloc-id:fake:payload +16870 0x11/imm32/alloc-id:fake +16871 Int-var-in-some-register/imm32 +16872 0x11/imm32/alloc-id:fake +16873 Single-lit-var/imm32/next +16874 +16875 Single-int-var-in-some-register: # (payload list var) +16876 0x11/imm32/alloc-id:fake:payload +16877 0x11/imm32/alloc-id:fake +16878 Int-var-in-some-register/imm32 +16879 0/imm32/next +16880 0/imm32/next +16881 +16882 Single-addr-var-in-some-register: # (payload list var) +16883 0x11/imm32/alloc-id:fake:payload +16884 0x11/imm32/alloc-id:fake +16885 Addr-var-in-some-register/imm32 +16886 0/imm32/next +16887 0/imm32/next +16888 +16889 Single-byte-var-in-some-register: # (payload list var) +16890 0x11/imm32/alloc-id:fake:payload +16891 0x11/imm32/alloc-id:fake +16892 Byte-var-in-some-register/imm32 +16893 0/imm32/next +16894 0/imm32/next +16895 +16896 Int-var-in-some-register: # (payload var) +16897 0x11/imm32/alloc-id:fake:payload +16898 0/imm32/name +16899 0/imm32/name +16900 0x11/imm32/alloc-id:fake +16901 Type-int/imm32 +16902 1/imm32/some-block-depth +16903 0/imm32/no-stack-offset +16904 0x11/imm32/alloc-id:fake +16905 Any-register/imm32 +16906 +16907 Any-register: # (payload array byte) +16908 0x11/imm32/alloc-id:fake:payload +16909 1/imm32/size +16910 # data +16911 2a/asterisk +16912 +16913 Addr-var-in-some-register: # (payload var) +16914 0x11/imm32/alloc-id:fake:payload +16915 0/imm32/name +16916 0/imm32/name +16917 0x11/imm32/alloc-id:fake +16918 Type-addr/imm32 +16919 1/imm32/some-block-depth +16920 0/imm32/no-stack-offset +16921 0x11/imm32/alloc-id:fake +16922 Any-register/imm32 +16923 +16924 Byte-var-in-some-register: # (payload var) +16925 0x11/imm32/alloc-id:fake:payload +16926 0/imm32/name +16927 0/imm32/name +16928 0x11/imm32/alloc-id:fake +16929 Type-byte/imm32 +16930 1/imm32/some-block-depth +16931 0/imm32/no-stack-offset +16932 0x11/imm32/alloc-id:fake +16933 Any-register/imm32 +16934 +16935 Single-int-var-in-eax: # (payload list var) +16936 0x11/imm32/alloc-id:fake:payload +16937 0x11/imm32/alloc-id:fake +16938 Int-var-in-eax/imm32 +16939 0/imm32/next +16940 0/imm32/next +16941 +16942 Int-var-in-eax: +16943 0x11/imm32/alloc-id:fake:payload +16944 0/imm32/name +16945 0/imm32/name +16946 0x11/imm32/alloc-id:fake +16947 Type-int/imm32 +16948 1/imm32/some-block-depth +16949 0/imm32/no-stack-offset +16950 0x11/imm32/alloc-id:fake +16951 $Register-eax/imm32 +16952 +16953 Single-int-var-in-ecx: # (payload list var) +16954 0x11/imm32/alloc-id:fake:payload +16955 0x11/imm32/alloc-id:fake +16956 Int-var-in-ecx/imm32 +16957 0/imm32/next +16958 0/imm32/next +16959 +16960 Int-var-in-ecx: +16961 0x11/imm32/alloc-id:fake:payload +16962 0/imm32/name +16963 0/imm32/name +16964 0x11/imm32/alloc-id:fake +16965 Type-int/imm32 +16966 1/imm32/some-block-depth +16967 0/imm32/no-stack-offset +16968 0x11/imm32/alloc-id:fake +16969 $Register-ecx/imm32/register +16970 +16971 Single-int-var-in-edx: # (payload list var) +16972 0x11/imm32/alloc-id:fake:payload +16973 0x11/imm32/alloc-id:fake +16974 Int-var-in-edx/imm32 +16975 0/imm32/next +16976 0/imm32/next +16977 +16978 Int-var-in-edx: # (payload list var) +16979 0x11/imm32/alloc-id:fake:payload +16980 0/imm32/name +16981 0/imm32/name +16982 0x11/imm32/alloc-id:fake +16983 Type-int/imm32 +16984 1/imm32/some-block-depth +16985 0/imm32/no-stack-offset +16986 0x11/imm32/alloc-id:fake +16987 $Register-edx/imm32/register +16988 +16989 Single-int-var-in-ebx: # (payload list var) +16990 0x11/imm32/alloc-id:fake:payload +16991 0x11/imm32/alloc-id:fake +16992 Int-var-in-ebx/imm32 +16993 0/imm32/next +16994 0/imm32/next +16995 +16996 Int-var-in-ebx: # (payload list var) +16997 0x11/imm32/alloc-id:fake:payload +16998 0/imm32/name +16999 0/imm32/name +17000 0x11/imm32/alloc-id:fake +17001 Type-int/imm32 +17002 1/imm32/some-block-depth +17003 0/imm32/no-stack-offset +17004 0x11/imm32/alloc-id:fake +17005 $Register-ebx/imm32/register +17006 +17007 Single-int-var-in-esi: # (payload list var) +17008 0x11/imm32/alloc-id:fake:payload +17009 0x11/imm32/alloc-id:fake +17010 Int-var-in-esi/imm32 +17011 0/imm32/next +17012 0/imm32/next +17013 +17014 Int-var-in-esi: # (payload list var) +17015 0x11/imm32/alloc-id:fake:payload +17016 0/imm32/name +17017 0/imm32/name +17018 0x11/imm32/alloc-id:fake +17019 Type-int/imm32 +17020 1/imm32/some-block-depth +17021 0/imm32/no-stack-offset +17022 0x11/imm32/alloc-id:fake +17023 $Register-esi/imm32/register +17024 +17025 Single-int-var-in-edi: # (payload list var) +17026 0x11/imm32/alloc-id:fake:payload +17027 0x11/imm32/alloc-id:fake +17028 Int-var-in-edi/imm32 +17029 0/imm32/next +17030 0/imm32/next +17031 +17032 Int-var-in-edi: # (payload list var) +17033 0x11/imm32/alloc-id:fake:payload +17034 0/imm32/name +17035 0/imm32/name +17036 0x11/imm32/alloc-id:fake +17037 Type-int/imm32 +17038 1/imm32/some-block-depth +17039 0/imm32/no-stack-offset +17040 0x11/imm32/alloc-id:fake +17041 $Register-edi/imm32/register +17042 +17043 Single-lit-var: # (payload list var) +17044 0x11/imm32/alloc-id:fake:payload +17045 0x11/imm32/alloc-id:fake +17046 Lit-var/imm32 +17047 0/imm32/next +17048 0/imm32/next +17049 +17050 Lit-var: # (payload var) +17051 0x11/imm32/alloc-id:fake:payload +17052 0/imm32/name +17053 0/imm32/name +17054 0x11/imm32/alloc-id:fake +17055 Type-literal/imm32 +17056 1/imm32/some-block-depth +17057 0/imm32/no-stack-offset +17058 0/imm32/no-register +17059 0/imm32/no-register +17060 +17061 Type-int: # (payload tree type-id) +17062 0x11/imm32/alloc-id:fake:payload +17063 1/imm32/left-is-atom +17064 1/imm32/value:int +17065 0/imm32/left:unused +17066 0/imm32/right:null +17067 0/imm32/right:null +17068 +17069 Type-literal: # (payload tree type-id) +17070 0x11/imm32/alloc-id:fake:payload +17071 1/imm32/is-atom +17072 0/imm32/value:literal +17073 0/imm32/left:unused +17074 0/imm32/right:null +17075 0/imm32/right:null +17076 +17077 Type-addr: # (payload tree type-id) +17078 0x11/imm32/alloc-id:fake:payload +17079 1/imm32/is-atom +17080 2/imm32/value:addr +17081 0/imm32/left:unused +17082 0/imm32/right:null +17083 0/imm32/right:null +17084 +17085 Type-byte: # (payload tree type-id) +17086 0x11/imm32/alloc-id:fake:payload +17087 1/imm32/is-atom +17088 8/imm32/value:byte +17089 0/imm32/left:unused +17090 0/imm32/right:null +17091 0/imm32/right:null +17092 +17093 == code +17094 emit-subx-primitive: # out: (addr buffered-file), stmt: (addr stmt), primitive: (addr primitive), err: (addr buffered-file), ed: (addr exit-descriptor) +17095 # . prologue +17096 55/push-ebp +17097 89/<- %ebp 4/r32/esp +17098 # . save registers +17099 50/push-eax +17100 51/push-ecx +17101 # ecx = primitive +17102 8b/-> *(ebp+0x10) 1/r32/ecx +17103 # emit primitive name +17104 (emit-indent *(ebp+8) *Curr-block-depth) +17105 (lookup *(ecx+0x18) *(ecx+0x1c)) # Primitive-subx-name Primitive-subx-name => eax +17106 (write-buffered *(ebp+8) %eax) +17107 # emit rm32 if necessary +17108 (emit-subx-rm32 *(ebp+8) *(ecx+0x20) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-rm32 +17109 # emit r32 if necessary +17110 (emit-subx-r32 *(ebp+8) *(ecx+0x24) *(ebp+0xc)) # Primitive-subx-r32 +17111 # emit imm32 if necessary +17112 (emit-subx-imm32 *(ebp+8) *(ecx+0x28) *(ebp+0xc)) # Primitive-subx-imm32 +17113 # emit disp32 if necessary +17114 (emit-subx-disp32 *(ebp+8) *(ecx+0x2c) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # Primitive-subx-disp32 +17115 (write-buffered *(ebp+8) Newline) +17116 $emit-subx-primitive:end: +17117 # . restore registers +17118 59/pop-to-ecx +17119 58/pop-to-eax +17120 # . epilogue +17121 89/<- %esp 5/r32/ebp +17122 5d/pop-to-ebp +17123 c3/return +17124 +17125 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +17126 # . prologue +17127 55/push-ebp +17128 89/<- %ebp 4/r32/esp +17129 # . save registers +17130 50/push-eax +17131 # if (l == 0) return +17132 81 7/subop/compare *(ebp+0xc) 0/imm32 +17133 74/jump-if-= $emit-subx-rm32:end/disp8 +17134 # var v/eax: (addr stmt-var) +17135 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax +17136 (emit-subx-var-as-rm32 *(ebp+8) %eax) +17137 $emit-subx-rm32:end: +17138 # . restore registers +17139 58/pop-to-eax +17140 # . epilogue +17141 89/<- %esp 5/r32/ebp +17142 5d/pop-to-ebp +17143 c3/return +17144 +17145 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) +17146 # . prologue +17147 55/push-ebp +17148 89/<- %ebp 4/r32/esp +17149 # . save registers +17150 51/push-ecx +17151 # eax = l +17152 8b/-> *(ebp+0xc) 0/r32/eax +17153 # ecx = stmt +17154 8b/-> *(ebp+8) 1/r32/ecx +17155 # if (l == 1) return stmt->inouts +17156 { +17157 3d/compare-eax-and 1/imm32 +17158 75/jump-if-!= break/disp8 +17159 $get-stmt-operand-from-arg-location:1: +17160 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +17161 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +17162 } +17163 # if (l == 2) return stmt->inouts->next +17164 { +17165 3d/compare-eax-and 2/imm32 +17166 75/jump-if-!= break/disp8 +17167 $get-stmt-operand-from-arg-location:2: +17168 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +17169 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +17170 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +17171 } +17172 # if (l == 3) return stmt->outputs +17173 { +17174 3d/compare-eax-and 3/imm32 +17175 75/jump-if-!= break/disp8 +17176 $get-stmt-operand-from-arg-location:3: +17177 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +17178 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +17179 } +17180 # abort +17181 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 +17182 $get-stmt-operand-from-arg-location:end: +17183 # . restore registers +17184 59/pop-to-ecx +17185 # . epilogue +17186 89/<- %esp 5/r32/ebp +17187 5d/pop-to-ebp +17188 c3/return +17189 +17190 $get-stmt-operand-from-arg-location:abort: +17191 # error("invalid arg-location " eax) +17192 (write-buffered *(ebp+0x10) "invalid arg-location ") +17193 (print-int32-buffered *(ebp+0x10) %eax) +17194 (write-buffered *(ebp+0x10) Newline) +17195 (flush *(ebp+0x10)) +17196 (stop *(ebp+0x14) 1) +17197 # never gets here +17198 +17199 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +17200 # . prologue +17201 55/push-ebp +17202 89/<- %ebp 4/r32/esp +17203 # . save registers +17204 50/push-eax +17205 51/push-ecx +17206 # if (l == 0) return +17207 81 7/subop/compare *(ebp+0xc) 0/imm32 +17208 0f 84/jump-if-= $emit-subx-r32:end/disp32 +17209 # var v/eax: (addr stmt-var) +17210 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +17211 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +17212 (lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax +17213 (maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index) +17214 (write-buffered *(ebp+8) Space) +17215 (print-int32-buffered *(ebp+8) *eax) +17216 (write-buffered *(ebp+8) "/r32") +17217 $emit-subx-r32:end: +17218 # . restore registers +17219 59/pop-to-ecx +17220 58/pop-to-eax +17221 # . epilogue +17222 89/<- %esp 5/r32/ebp +17223 5d/pop-to-ebp +17224 c3/return +17225 +17226 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt) +17227 # . prologue +17228 55/push-ebp +17229 89/<- %ebp 4/r32/esp +17230 # . save registers +17231 50/push-eax +17232 51/push-ecx +17233 # if (l == 0) return +17234 81 7/subop/compare *(ebp+0xc) 0/imm32 +17235 0f 84/jump-if-= $emit-subx-imm32:end/disp32 +17236 # var v/eax: (handle var) +17237 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # => eax +17238 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +17239 (lookup *eax *(eax+4)) # Var-name Var-name => eax +17240 (write-buffered *(ebp+8) Space) +17241 (write-buffered *(ebp+8) %eax) +17242 (write-buffered *(ebp+8) "/imm32") +17243 $emit-subx-imm32:end: +17244 # . restore registers +17245 59/pop-to-ecx +17246 58/pop-to-eax +17247 # . epilogue +17248 89/<- %esp 5/r32/ebp +17249 5d/pop-to-ebp +17250 c3/return +17251 +17252 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor) +17253 # . prologue +17254 55/push-ebp +17255 89/<- %ebp 4/r32/esp +17256 # . save registers +17257 50/push-eax +17258 51/push-ecx +17259 # if (location == 0) return +17260 81 7/subop/compare *(ebp+0xc) 0/imm32 +17261 0f 84/jump-if-= $emit-subx-disp32:end/disp32 +17262 # var v/eax: (addr stmt-var) +17263 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc) *(ebp+0x14) *(ebp+0x18)) # => eax +17264 (lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax +17265 (lookup *eax *(eax+4)) # Var-name Var-name => eax +17266 (write-buffered *(ebp+8) Space) +17267 (write-buffered *(ebp+8) %eax) +17268 # hack: if instruction operation starts with "break", emit ":break" +17269 # var name/ecx: (addr array byte) = lookup(stmt->operation) +17270 8b/-> *(ebp+0x10) 0/r32/eax +17271 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +17272 89/<- %ecx 0/r32/eax +17273 { +17274 (string-starts-with? %ecx "break") # => eax +17275 3d/compare-eax-and 0/imm32/false +17276 74/jump-if-= break/disp8 +17277 (write-buffered *(ebp+8) ":break") +17278 } +17279 # hack: if instruction operation starts with "loop", emit ":loop" +17280 { +17281 (string-starts-with? %ecx "loop") # => eax +17282 3d/compare-eax-and 0/imm32/false +17283 74/jump-if-= break/disp8 +17284 (write-buffered *(ebp+8) ":loop") +17285 } +17286 (write-buffered *(ebp+8) "/disp32") +17287 $emit-subx-disp32:end: +17288 # . restore registers +17289 59/pop-to-ecx +17290 58/pop-to-eax +17291 # . epilogue +17292 89/<- %esp 5/r32/ebp +17293 5d/pop-to-ebp +17294 c3/return +17295 +17296 emit-call: # out: (addr buffered-file), stmt: (addr stmt) +17297 # . prologue +17298 55/push-ebp +17299 89/<- %ebp 4/r32/esp +17300 # . save registers +17301 50/push-eax +17302 51/push-ecx +17303 # +17304 (emit-indent *(ebp+8) *Curr-block-depth) +17305 (write-buffered *(ebp+8) "(") +17306 # ecx = stmt +17307 8b/-> *(ebp+0xc) 1/r32/ecx +17308 # - emit function name +17309 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +17310 (write-buffered *(ebp+8) %eax) +17311 # - emit arguments +17312 # var curr/eax: (addr stmt-var) = lookup(stmt->inouts) +17313 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +17314 { +17315 # if (curr == null) break +17316 3d/compare-eax-and 0/imm32 +17317 74/jump-if-= break/disp8 +17318 # +17319 (emit-subx-call-operand *(ebp+8) %eax) +17320 # curr = lookup(curr->next) +17321 (lookup *(eax+8) *(eax+0xc)) # Stmt-var-next Stmt-var-next => eax +17322 eb/jump loop/disp8 +17323 } +17324 # +17325 (write-buffered *(ebp+8) ")\n") +17326 $emit-call:end: +17327 # . restore registers +17328 59/pop-to-ecx +17329 58/pop-to-eax +17330 # . epilogue +17331 89/<- %esp 5/r32/ebp +17332 5d/pop-to-ebp +17333 c3/return +17334 +17335 emit-subx-call-operand: # out: (addr buffered-file), s: (addr stmt-var) +17336 # shares code with emit-subx-var-as-rm32 +17337 # . prologue +17338 55/push-ebp +17339 89/<- %ebp 4/r32/esp +17340 # . save registers +17341 50/push-eax +17342 51/push-ecx +17343 56/push-esi +17344 # ecx = s +17345 8b/-> *(ebp+0xc) 1/r32/ecx +17346 # var operand/esi: (addr var) = lookup(s->value) +17347 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +17348 89/<- %esi 0/r32/eax +17349 # if (operand->register && !s->is-deref?) emit "%__" +17350 { +17351 $emit-subx-call-operand:check-for-register-direct: +17352 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +17353 74/jump-if-= break/disp8 +17354 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +17355 75/jump-if-!= break/disp8 +17356 $emit-subx-call-operand:register-direct: +17357 (write-buffered *(ebp+8) " %") +17358 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +17359 (write-buffered *(ebp+8) %eax) +17360 e9/jump $emit-subx-call-operand:end/disp32 +17361 } +17362 # else if (operand->register && s->is-deref?) emit "*__" +17363 { +17364 $emit-subx-call-operand:check-for-register-indirect: +17365 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +17366 74/jump-if-= break/disp8 +17367 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +17368 74/jump-if-= break/disp8 +17369 $emit-subx-call-operand:register-indirect: +17370 (emit-subx-call-operand-register-indirect *(ebp+8) %esi) +17371 e9/jump $emit-subx-call-operand:end/disp32 +17372 } +17373 # else if (operand->stack-offset) emit "*(ebp+__)" +17374 { +17375 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset +17376 74/jump-if-= break/disp8 +17377 $emit-subx-call-operand:stack: +17378 (emit-subx-call-operand-stack *(ebp+8) %esi) +17379 e9/jump $emit-subx-call-operand:end/disp32 +17380 } +17381 # else if (operand->type == literal) emit "__" +17382 { +17383 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +17384 81 7/subop/compare *(eax+4) 0/imm32 # Tree-left +17385 75/jump-if-!= break/disp8 +17386 $emit-subx-call-operand:literal: +17387 (write-buffered *(ebp+8) Space) +17388 (lookup *esi *(esi+4)) # Var-name Var-name => eax +17389 (write-buffered *(ebp+8) %eax) +17390 } +17391 $emit-subx-call-operand:end: +17392 # . restore registers +17393 5e/pop-to-esi +17394 59/pop-to-ecx +17395 58/pop-to-eax +17396 # . epilogue +17397 89/<- %esp 5/r32/ebp +17398 5d/pop-to-ebp +17399 c3/return +17400 +17401 emit-subx-call-operand-register-indirect: # out: (addr buffered-file), v: (addr var) +17402 # . prologue +17403 55/push-ebp +17404 89/<- %ebp 4/r32/esp +17405 # . save registers +17406 50/push-eax +17407 51/push-ecx +17408 56/push-esi +17409 # esi = v +17410 8b/-> *(ebp+0xc) 6/r32/esi +17411 # var size/ecx: int = size-of-deref(v) +17412 (size-of-deref %esi) # => eax +17413 89/<- %ecx 0/r32/eax +17414 # var reg-name/esi: (addr array byte) = lookup(v->register) +17415 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +17416 89/<- %esi 0/r32/eax +17417 # TODO: assert size is a multiple of 4 +17418 # var i/eax: int = 0 +17419 b8/copy-to-eax 0/imm32 +17420 { +17421 $emit-subx-call-operand-register-indirect:loop: +17422 # if (i >= size) break +17423 39/compare %eax 1/r32/ecx +17424 7d/jump-if->= break/disp8 +17425 # emit " *(" v->register "+" i ")" +17426 (write-buffered *(ebp+8) " *(") +17427 (write-buffered *(ebp+8) %esi) +17428 (write-buffered *(ebp+8) "+") +17429 (print-int32-buffered *(ebp+8) %eax) +17430 (write-buffered *(ebp+8) ")") +17431 # i += 4 +17432 05/add-to-eax 4/imm32 +17433 # +17434 eb/jump loop/disp8 +17435 } +17436 $emit-subx-call-operand-register-indirect:end: +17437 # . restore registers +17438 5e/pop-to-esi +17439 59/pop-to-ecx +17440 58/pop-to-eax +17441 # . epilogue +17442 89/<- %esp 5/r32/ebp +17443 5d/pop-to-ebp +17444 c3/return +17445 +17446 emit-subx-call-operand-stack: # out: (addr buffered-file), v: (addr var) +17447 # . prologue +17448 55/push-ebp +17449 89/<- %ebp 4/r32/esp +17450 # . save registers +17451 50/push-eax +17452 51/push-ecx +17453 56/push-esi +17454 # esi = v +17455 8b/-> *(ebp+0xc) 6/r32/esi +17456 # var curr/ecx: int = v->offset +17457 8b/-> *(esi+0x14) 1/r32/ecx # Var-offset +17458 # var max/eax: int = v->offset + size-of(v) +17459 (size-of %esi) # => eax +17460 # TODO: assert size is a multiple of 4 +17461 01/add-to %eax 1/r32/ecx +17462 { +17463 $emit-subx-call-operand-stack:loop: +17464 # if (curr >= max) break +17465 39/compare %ecx 0/r32/eax +17466 7d/jump-if->= break/disp8 +17467 # emit " *(ebp+" curr ")" +17468 (write-buffered *(ebp+8) " *(ebp+") +17469 (print-int32-buffered *(ebp+8) %ecx) +17470 (write-buffered *(ebp+8) ")") +17471 # i += 4 +17472 81 0/subop/add %ecx 4/imm32 +17473 # +17474 eb/jump loop/disp8 +17475 } +17476 $emit-subx-call-operand-stack:end: +17477 # . restore registers +17478 5e/pop-to-esi +17479 59/pop-to-ecx +17480 58/pop-to-eax +17481 # . epilogue +17482 89/<- %esp 5/r32/ebp +17483 5d/pop-to-ebp +17484 c3/return +17485 +17486 emit-subx-var-as-rm32: # out: (addr buffered-file), s: (addr stmt-var) +17487 # . prologue +17488 55/push-ebp +17489 89/<- %ebp 4/r32/esp +17490 # . save registers +17491 50/push-eax +17492 51/push-ecx +17493 56/push-esi +17494 # ecx = s +17495 8b/-> *(ebp+0xc) 1/r32/ecx +17496 # var operand/esi: (addr var) = lookup(s->value) +17497 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +17498 89/<- %esi 0/r32/eax +17499 # if (operand->register && s->is-deref?) emit "*__" +17500 { +17501 $emit-subx-var-as-rm32:check-for-register-indirect: +17502 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +17503 74/jump-if-= break/disp8 +17504 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +17505 74/jump-if-= break/disp8 +17506 $emit-subx-var-as-rm32:register-indirect: +17507 (write-buffered *(ebp+8) " *") +17508 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +17509 (write-buffered *(ebp+8) %eax) +17510 e9/jump $emit-subx-var-as-rm32:end/disp32 +17511 } +17512 # if (operand->register && !s->is-deref?) emit "%__" +17513 { +17514 $emit-subx-var-as-rm32:check-for-register-direct: +17515 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +17516 74/jump-if-= break/disp8 +17517 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +17518 75/jump-if-!= break/disp8 +17519 $emit-subx-var-as-rm32:register-direct: +17520 (write-buffered *(ebp+8) " %") +17521 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +17522 (write-buffered *(ebp+8) %eax) +17523 e9/jump $emit-subx-var-as-rm32:end/disp32 +17524 } +17525 # else if (operand->stack-offset) emit "*(ebp+__)" +17526 { +17527 81 7/subop/compare *(esi+0x14) 0/imm32 # Var-offset +17528 74/jump-if-= break/disp8 +17529 $emit-subx-var-as-rm32:stack: +17530 (write-buffered *(ebp+8) Space) +17531 (write-buffered *(ebp+8) "*(ebp+") +17532 (print-int32-buffered *(ebp+8) *(esi+0x14)) # Var-offset +17533 (write-buffered *(ebp+8) ")") +17534 } +17535 $emit-subx-var-as-rm32:end: +17536 # . restore registers +17537 5e/pop-to-esi +17538 59/pop-to-ecx +17539 58/pop-to-eax +17540 # . epilogue +17541 89/<- %esp 5/r32/ebp +17542 5d/pop-to-ebp +17543 c3/return +17544 +17545 find-matching-primitive: # primitives: (addr primitive), stmt: (addr stmt) -> result/eax: (addr primitive) +17546 # . prologue +17547 55/push-ebp +17548 89/<- %ebp 4/r32/esp +17549 # . save registers +17550 51/push-ecx +17551 # var curr/ecx: (addr primitive) = primitives +17552 8b/-> *(ebp+8) 1/r32/ecx +17553 { +17554 $find-matching-primitive:loop: +17555 # if (curr == null) break +17556 81 7/subop/compare %ecx 0/imm32 +17557 74/jump-if-= break/disp8 +17558 # if match(curr, stmt) return curr +17559 { +17560 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax +17561 3d/compare-eax-and 0/imm32/false +17562 74/jump-if-= break/disp8 +17563 89/<- %eax 1/r32/ecx +17564 eb/jump $find-matching-primitive:end/disp8 +17565 } +17566 $find-matching-primitive:next-primitive: +17567 # curr = curr->next +17568 (lookup *(ecx+0x34) *(ecx+0x38)) # Primitive-next Primitive-next => eax +17569 89/<- %ecx 0/r32/eax +17570 # +17571 e9/jump loop/disp32 +17572 } +17573 # return null +17574 b8/copy-to-eax 0/imm32 +17575 $find-matching-primitive:end: +17576 # . restore registers +17577 59/pop-to-ecx +17578 # . epilogue +17579 89/<- %esp 5/r32/ebp +17580 5d/pop-to-ebp +17581 c3/return +17582 +17583 mu-stmt-matches-primitive?: # stmt: (addr stmt), primitive: (addr primitive) -> result/eax: boolean +17584 # A mu stmt matches a primitive if the name matches, all the inout vars +17585 # match, and all the output vars match. +17586 # Vars match if types match and registers match. +17587 # In addition, a stmt output matches a primitive's output if types match +17588 # and the primitive has a wildcard register. +17589 # . prologue +17590 55/push-ebp +17591 89/<- %ebp 4/r32/esp +17592 # . save registers +17593 51/push-ecx +17594 52/push-edx +17595 53/push-ebx +17596 56/push-esi +17597 57/push-edi +17598 # ecx = stmt +17599 8b/-> *(ebp+8) 1/r32/ecx +17600 # edx = primitive +17601 8b/-> *(ebp+0xc) 2/r32/edx +17602 { +17603 $mu-stmt-matches-primitive?:check-name: +17604 # if (primitive->name != stmt->operation) return false +17605 # . var esi: (addr array byte) = lookup(stmt->operation) +17606 (lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax +17607 89/<- %esi 0/r32/eax +17608 # . var edi: (addr array byte) = lookup(primitive->name) +17609 (lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax +17610 89/<- %edi 0/r32/eax +17611 (string-equal? %esi %edi) # => eax +17612 3d/compare-eax-and 0/imm32/false +17613 75/jump-if-!= break/disp8 +17614 b8/copy-to-eax 0/imm32 +17615 e9/jump $mu-stmt-matches-primitive?:end/disp32 +17616 } +17617 # var curr/esi: (addr stmt-var) = lookup(stmt->inouts) +17618 (lookup *(ecx+0xc) *(ecx+0x10)) # Stmt1-inouts Stmt1-inouts => eax +17619 89/<- %esi 0/r32/eax +17620 # var curr2/edi: (addr list var) = lookup(primitive->inouts) +17621 (lookup *(edx+8) *(edx+0xc)) # Primitive-inouts Primitive-inouts => eax +17622 89/<- %edi 0/r32/eax +17623 { +17624 $mu-stmt-matches-primitive?:inouts-loop: +17625 # if (curr == 0 && curr2 == 0) move on to check outputs +17626 { +17627 $mu-stmt-matches-primitive?:check-both-inouts-null: +17628 81 7/subop/compare %esi 0/imm32 +17629 75/jump-if-!= break/disp8 +17630 $mu-stmt-matches-primitive?:stmt-inout-null: +17631 81 7/subop/compare %edi 0/imm32 +17632 0f 84/jump-if-= $mu-stmt-matches-primitive?:check-outputs/disp32 +17633 $mu-stmt-matches-primitive?:stmt-inout-null-and-prim-inout-not-null: +17634 # return false +17635 b8/copy-to-eax 0/imm32/false +17636 e9/jump $mu-stmt-matches-primitive?:end/disp32 +17637 } +17638 # if (curr2 == 0) return false +17639 { +17640 $mu-stmt-matches-primitive?:check-prim-inout-null: +17641 81 7/subop/compare %edi 0/imm32 +17642 75/jump-if-!= break/disp8 +17643 $mu-stmt-matches-primitive?:prim-inout-null: +17644 b8/copy-to-eax 0/imm32/false +17645 e9/jump $mu-stmt-matches-primitive?:end/disp32 +17646 } +17647 # if (curr != curr2) return false +17648 { +17649 $mu-stmt-matches-primitive?:check-inouts-match: +17650 (lookup *edi *(edi+4)) # List-value List-value => eax +17651 (operand-matches-primitive? %esi %eax) # => eax +17652 3d/compare-eax-and 0/imm32/false +17653 75/jump-if-!= break/disp8 +17654 $mu-stmt-matches-primitive?:inouts-match: +17655 b8/copy-to-eax 0/imm32/false +17656 e9/jump $mu-stmt-matches-primitive?:end/disp32 +17657 } +17658 $mu-stmt-matches-primitive?:next-inout: +17659 # curr = lookup(curr->next) +17660 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +17661 89/<- %esi 0/r32/eax +17662 # curr2 = lookup(curr2->next) +17663 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax +17664 89/<- %edi 0/r32/eax +17665 # +17666 e9/jump loop/disp32 +17667 } +17668 $mu-stmt-matches-primitive?:check-outputs: +17669 # var curr/esi: (addr stmt-var) = lookup(stmt->outputs) +17670 (lookup *(ecx+0x14) *(ecx+0x18)) # Stmt1-outputs Stmt1-outputs => eax +17671 89/<- %esi 0/r32/eax +17672 # var curr2/edi: (addr list var) = lookup(primitive->outputs) +17673 (lookup *(edx+0x10) *(edx+0x14)) # Primitive-outputs Primitive-outputs => eax +17674 89/<- %edi 0/r32/eax +17675 { +17676 $mu-stmt-matches-primitive?:outputs-loop: +17677 # if (curr == 0) return (curr2 == 0) +17678 { +17679 $mu-stmt-matches-primitive?:check-both-outputs-null: +17680 81 7/subop/compare %esi 0/imm32 +17681 75/jump-if-!= break/disp8 +17682 { +17683 $mu-stmt-matches-primitive?:stmt-output-null: +17684 81 7/subop/compare %edi 0/imm32 +17685 75/jump-if-!= break/disp8 +17686 $mu-stmt-matches-primitive?:both-outputs-null: +17687 # return true +17688 b8/copy-to-eax 1/imm32 +17689 e9/jump $mu-stmt-matches-primitive?:end/disp32 +17690 } +17691 $mu-stmt-matches-primitive?:stmt-output-null-and-prim-output-not-null: +17692 # return false +17693 b8/copy-to-eax 0/imm32 +17694 e9/jump $mu-stmt-matches-primitive?:end/disp32 +17695 } +17696 # if (curr2 == 0) return false +17697 { +17698 $mu-stmt-matches-primitive?:check-prim-output-null: +17699 81 7/subop/compare %edi 0/imm32 +17700 75/jump-if-!= break/disp8 +17701 $mu-stmt-matches-primitive?:prim-output-is-null: +17702 b8/copy-to-eax 0/imm32 +17703 e9/jump $mu-stmt-matches-primitive?:end/disp32 +17704 } +17705 # if (curr != curr2) return false +17706 { +17707 $mu-stmt-matches-primitive?:check-outputs-match: +17708 (lookup *edi *(edi+4)) # List-value List-value => eax +17709 (operand-matches-primitive? %esi %eax) # => eax +17710 3d/compare-eax-and 0/imm32/false +17711 75/jump-if-!= break/disp8 +17712 $mu-stmt-matches-primitive?:outputs-match: +17713 b8/copy-to-eax 0/imm32 +17714 e9/jump $mu-stmt-matches-primitive?:end/disp32 +17715 } +17716 $mu-stmt-matches-primitive?:next-output: +17717 # curr = lookup(curr->next) +17718 (lookup *(esi+8) *(esi+0xc)) # Stmt-var-next Stmt-var-next => eax +17719 89/<- %esi 0/r32/eax +17720 # curr2 = lookup(curr2->next) +17721 (lookup *(edi+8) *(edi+0xc)) # List-next List-next => eax +17722 89/<- %edi 0/r32/eax +17723 # +17724 e9/jump loop/disp32 +17725 } +17726 $mu-stmt-matches-primitive?:return-true: +17727 b8/copy-to-eax 1/imm32 +17728 $mu-stmt-matches-primitive?:end: +17729 # . restore registers +17730 5f/pop-to-edi +17731 5e/pop-to-esi +17732 5b/pop-to-ebx +17733 5a/pop-to-edx +17734 59/pop-to-ecx +17735 # . epilogue +17736 89/<- %esp 5/r32/ebp +17737 5d/pop-to-ebp +17738 c3/return +17739 +17740 operand-matches-primitive?: # s: (addr stmt-var), prim-var: (addr var) -> result/eax: boolean +17741 # . prologue +17742 55/push-ebp +17743 89/<- %ebp 4/r32/esp +17744 # . save registers +17745 51/push-ecx +17746 52/push-edx +17747 53/push-ebx +17748 56/push-esi +17749 57/push-edi +17750 # ecx = s +17751 8b/-> *(ebp+8) 1/r32/ecx +17752 # var var/esi: (addr var) = lookup(s->value) +17753 (lookup *ecx *(ecx+4)) # Stmt-var-value Stmt-var-value => eax +17754 89/<- %esi 0/r32/eax +17755 # edi = prim-var +17756 8b/-> *(ebp+0xc) 7/r32/edi +17757 $operand-matches-primitive?:check-type: +17758 # if !category-match?(var->type, prim-var->type) return false +17759 # . var vtype/ebx: (addr tree type-id) = lookup(var->type) +17760 (lookup *(esi+8) *(esi+0xc)) # Var-type Var-type => eax +17761 89/<- %ebx 0/r32/eax +17762 # . var ptype/eax: (addr tree type-id) = lookup(prim-var->type) +17763 (lookup *(edi+8) *(edi+0xc)) # Var-type Var-type => eax +17764 (subx-type-category-match? %ebx %eax) # => eax +17765 3d/compare-eax-and 0/imm32/false +17766 0f 84/jump-if-= $operand-matches-primitive?:return-false/disp32 +17767 { +17768 $operand-matches-primitive?:check-register: +17769 # if prim-var is in memory and var is in register but dereference, match +17770 { +17771 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register +17772 0f 85/jump-if-!= break/disp32 +17773 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +17774 74/jump-if-= break/disp8 +17775 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +17776 74/jump-if-= break/disp8 +17777 $operand-matches-primitive?:var-deref-match: +17778 e9/jump $operand-matches-primitive?:return-true/disp32 +17779 } +17780 # if prim-var is in register and var is in register but dereference, no match +17781 { +17782 81 7/subop/compare *(edi+0x18) 0/imm32 # Var-register +17783 0f 84/jump-if-= break/disp32 +17784 81 7/subop/compare *(esi+0x18) 0/imm32 # Var-register +17785 0f 84/jump-if-= break/disp32 +17786 81 7/subop/compare *(ecx+0x10) 0/imm32/false # Stmt-var-is-deref +17787 74/jump-if-= break/disp8 +17788 $operand-matches-primitive?:var-deref-no-match: +17789 e9/jump $operand-matches-primitive?:return-false/disp32 +17790 } +17791 # return false if var->register doesn't match prim-var->register +17792 { +17793 # if register addresses are equal, it's a match +17794 # var vreg/ebx: (addr array byte) = lookup(var->register) +17795 (lookup *(esi+0x18) *(esi+0x1c)) # Var-register Var-register => eax +17796 89/<- %ebx 0/r32/eax +17797 # var preg/ecx: (addr array byte) = lookup(prim-var->register) +17798 (lookup *(edi+0x18) *(edi+0x1c)) # Var-register Var-register => eax +17799 89/<- %ecx 0/r32/eax +17800 # if (vreg == preg) break +17801 39/compare %ecx 3/r32/ebx +17802 74/jump-if-= break/disp8 +17803 $operand-matches-primitive?:var-register-no-match: +17804 # if either address is 0, return false +17805 81 7/subop/compare %ebx 0/imm32 +17806 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +17807 81 7/subop/compare %ecx 0/imm32 +17808 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +17809 # if prim-var->register is wildcard, it's a match +17810 (string-equal? %ecx "*") # Any-register => eax +17811 3d/compare-eax-and 0/imm32/false +17812 75/jump-if-!= break/disp8 +17813 $operand-matches-primitive?:wildcard-no-match: +17814 # if string contents aren't equal, return false +17815 (string-equal? %ecx %ebx) # => eax +17816 3d/compare-eax-and 0/imm32/false +17817 74/jump-if-= $operand-matches-primitive?:return-false/disp8 +17818 } +17819 } +17820 $operand-matches-primitive?:return-true: +17821 b8/copy-to-eax 1/imm32/true +17822 eb/jump $operand-matches-primitive?:end/disp8 +17823 $operand-matches-primitive?:return-false: +17824 b8/copy-to-eax 0/imm32/false +17825 $operand-matches-primitive?:end: +17826 # . restore registers +17827 5f/pop-to-edi +17828 5e/pop-to-esi +17829 5b/pop-to-ebx +17830 5a/pop-to-edx +17831 59/pop-to-ecx +17832 # . epilogue +17833 89/<- %esp 5/r32/ebp +17834 5d/pop-to-ebp +17835 c3/return +17836 +17837 find-matching-function: # functions: (addr function), stmt: (addr stmt) -> result/eax: (addr function) +17838 # . prologue +17839 55/push-ebp +17840 89/<- %ebp 4/r32/esp +17841 # . save registers +17842 51/push-ecx +17843 # var curr/ecx: (handle function) = functions +17844 8b/-> *(ebp+8) 1/r32/ecx +17845 { +17846 # if (curr == null) break +17847 81 7/subop/compare %ecx 0/imm32 +17848 74/jump-if-= break/disp8 +17849 #? (write-buffered Stderr "iter\n") +17850 #? (flush Stderr) +17851 # if match(stmt, curr) return curr +17852 { +17853 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax +17854 3d/compare-eax-and 0/imm32/false +17855 74/jump-if-= break/disp8 +17856 89/<- %eax 1/r32/ecx +17857 eb/jump $find-matching-function:end/disp8 +17858 } +17859 # curr = curr->next +17860 (lookup *(ecx+0x20) *(ecx+0x24)) # Function-next Function-next => eax +17861 89/<- %ecx 0/r32/eax +17862 # +17863 eb/jump loop/disp8 +17864 } +17865 # return null +17866 b8/copy-to-eax 0/imm32 +17867 $find-matching-function:end: +17868 # . restore registers +17869 59/pop-to-ecx +17870 # . epilogue +17871 89/<- %esp 5/r32/ebp +17872 5d/pop-to-ebp +17873 c3/return +17874 +17875 # Just compare names; user-defined functions don't support overloading yet. +17876 mu-stmt-matches-function?: # stmt: (addr stmt1), function: (addr function) -> result/eax: boolean +17877 # . prologue +17878 55/push-ebp +17879 89/<- %ebp 4/r32/esp +17880 # . save registers +17881 51/push-ecx +17882 # return function->name == stmt->operation +17883 # ecx = lookup(stmt->operation) +17884 8b/-> *(ebp+8) 0/r32/eax +17885 (lookup *(eax+4) *(eax+8)) # Stmt1-operation Stmt1-operation => eax +17886 89/<- %ecx 0/r32/eax +17887 # eax = lookup(function->name) +17888 8b/-> *(ebp+0xc) 0/r32/eax +17889 (lookup *eax *(eax+4)) # Function-name Function-name => eax +17890 (string-equal? %eax %ecx) # => eax +17891 $mu-stmt-matches-function?:end: +17892 # . restore registers +17893 59/pop-to-ecx +17894 # . epilogue +17895 89/<- %esp 5/r32/ebp +17896 5d/pop-to-ebp +17897 c3/return +17898 +17899 # Type-checking happens elsewhere. This method is for selecting between +17900 # primitives. +17901 subx-type-category-match?: # a: (addr tree type-id), b: (addr tree type-id) -> result/eax: boolean +17902 # . prologue +17903 55/push-ebp +17904 89/<- %ebp 4/r32/esp +17905 # . save registers +17906 51/push-ecx +17907 # var alit/ecx: boolean = is-literal-type?(a) +17908 (is-simple-mu-type? *(ebp+8) 0) # => eax +17909 89/<- %ecx 0/r32/eax +17910 # var blit/eax: boolean = is-literal-type?(b) +17911 (is-simple-mu-type? *(ebp+0xc) 0) # => eax +17912 # return alit == blit +17913 39/compare %eax 1/r32/ecx +17914 0f 94/set-byte-if-= %al +17915 81 4/subop/and %eax 0xff/imm32 +17916 $subx-type-category-match?:end: +17917 # . restore registers +17918 59/pop-to-ecx +17919 # . epilogue +17920 89/<- %esp 5/r32/ebp +17921 5d/pop-to-ebp +17922 c3/return +17923 +17924 is-simple-mu-type?: # a: (addr tree type-id), n: type-id -> result/eax: boolean +17925 # . prologue +17926 55/push-ebp +17927 89/<- %ebp 4/r32/esp +17928 # . save registers +17929 51/push-ecx +17930 # ecx = n +17931 8b/-> *(ebp+0xc) 1/r32/ecx +17932 # return (a->value == n) +17933 8b/-> *(ebp+8) 0/r32/eax +17934 39/compare *(eax+4) 1/r32/ecx # Tree-value +17935 0f 94/set-byte-if-= %al +17936 81 4/subop/and %eax 0xff/imm32 +17937 $is-simple-mu-type?:end: +17938 # . restore registers +17939 59/pop-to-ecx +17940 # . epilogue +17941 89/<- %esp 5/r32/ebp +17942 5d/pop-to-ebp +17943 c3/return +17944 +17945 is-mu-addr-type?: # a: (addr tree type-id) -> result/eax: boolean +17946 # . prologue +17947 55/push-ebp +17948 89/<- %ebp 4/r32/esp +17949 # eax = a +17950 8b/-> *(ebp+8) 0/r32/eax +17951 # if (!a->is-atom?) a = a->left +17952 81 7/subop/compare *eax 0/imm32/false # Tree-is-atom +17953 { +17954 75/jump-if-!= break/disp8 +17955 (lookup *(eax+4) *(eax+8)) # Tree-left Tree-left => eax +17956 } +17957 # return (a->value == addr) +17958 81 7/subop/compare *(eax+4) 2/imm32/addr # Tree-value +17959 0f 94/set-byte-if-= %al +17960 81 4/subop/and %eax 0xff/imm32 +17961 $is-mu-addr-type?:end: +17962 # . epilogue +17963 89/<- %esp 5/r32/ebp +17964 5d/pop-to-ebp +17965 c3/return +17966 +17967 test-emit-subx-stmt-primitive: +17968 # Primitive operation on a variable on the stack. +17969 # increment foo +17970 # => +17971 # ff 0/subop/increment *(ebp-8) +17972 # +17973 # There's a variable on the var stack as follows: +17974 # name: 'foo' +17975 # type: int +17976 # stack-offset: -8 +17977 # +17978 # There's a primitive with this info: +17979 # name: 'increment' +17980 # inouts: int/mem +17981 # value: 'ff 0/subop/increment' +17982 # +17983 # . prologue +17984 55/push-ebp +17985 89/<- %ebp 4/r32/esp +17986 # setup +17987 (clear-stream _test-output-stream) +17988 (clear-stream $_test-output-buffered-file->buffer) +17989 # simulate allocated payloads starting with an initial fake alloc-id (0x11) +17990 $test-emit-subx-stmt-primitive:initialize-type: +17991 # var type/ecx: (payload tree type-id) = int +17992 68/push 0/imm32/right:null +17993 68/push 0/imm32/right:null +17994 68/push 0/imm32/left:unused +17995 68/push 1/imm32/value:int +17996 68/push 1/imm32/is-atom?:true +17997 68/push 0x11/imm32/alloc-id:fake:payload +17998 89/<- %ecx 4/r32/esp +17999 $test-emit-subx-stmt-primitive:initialize-var: +18000 # var var-foo/ecx: (payload var) = var(type) +18001 68/push 0/imm32/no-register +18002 68/push 0/imm32/no-register +18003 68/push -8/imm32/stack-offset +18004 68/push 1/imm32/block-depth +18005 51/push-ecx/type +18006 68/push 0x11/imm32/alloc-id:fake +18007 68/push 0/imm32/name +18008 68/push 0/imm32/name +18009 68/push 0x11/imm32/alloc-id:fake:payload +18010 89/<- %ecx 4/r32/esp +18011 $test-emit-subx-stmt-primitive:initialize-var-name: +18012 # var-foo->name = "foo" +18013 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +18014 (copy-array Heap "foo" %eax) +18015 $test-emit-subx-stmt-primitive:initialize-stmt-var: +18016 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +18017 68/push 0/imm32/is-deref:false +18018 68/push 0/imm32/next +18019 68/push 0/imm32/next +18020 51/push-ecx/var-foo 18021 68/push 0x11/imm32/alloc-id:fake -18022 51/push-ecx/var1 -18023 68/push 0x11/imm32/alloc-id:fake -18024 68/push 0x11/imm32/alloc-id:fake:payload -18025 89/<- %esi 4/r32/esp -18026 $test-compare-mem-with-reg:initialize-stmt: -18027 # var stmt/esi: (addr statement) -18028 68/push 0/imm32/next -18029 68/push 0/imm32/next -18030 68/push 0/imm32/outputs -18031 68/push 0/imm32/outputs -18032 56/push-esi/inouts -18033 68/push 0x11/imm32/alloc-id:fake -18034 68/push 0/imm32/operation -18035 68/push 0/imm32/operation -18036 68/push 1/imm32/tag:stmt1 -18037 89/<- %esi 4/r32/esp -18038 $test-compare-mem-with-reg:initialize-stmt-operation: -18039 # stmt->operation = "compare" -18040 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -18041 (copy-array Heap "compare" %eax) -18042 # convert -18043 c7 0/subop/copy *Curr-block-depth 0/imm32 -18044 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -18045 (flush _test-output-buffered-file) -18046 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -18052 # check output -18053 (check-next-stream-line-equal _test-output-stream "39/compare-> *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg") -18054 # . epilogue -18055 89/<- %esp 5/r32/ebp -18056 5d/pop-to-ebp -18057 c3/return -18058 -18059 test-compare-reg-with-mem: -18060 # compare var1/eax, var2 -18061 # => -18062 # 3b/compare<- *(ebp+___) 0/r32/eax -18063 # -18064 # . prologue -18065 55/push-ebp -18066 89/<- %ebp 4/r32/esp -18067 # setup -18068 (clear-stream _test-output-stream) -18069 (clear-stream $_test-output-buffered-file->buffer) -18070 $test-compare-reg-with-mem:initialize-type: -18071 # var type/ecx: (payload tree type-id) = int -18072 68/push 0/imm32/right:null -18073 68/push 0/imm32/right:null -18074 68/push 0/imm32/left:unused -18075 68/push 1/imm32/value:int -18076 68/push 1/imm32/is-atom?:true -18077 68/push 0x11/imm32/alloc-id:fake:payload -18078 89/<- %ecx 4/r32/esp -18079 $test-compare-reg-with-mem:initialize-var1: -18080 # var var1/ecx: (payload var) -18081 68/push 0/imm32/register -18082 68/push 0/imm32/register -18083 68/push 0/imm32/no-stack-offset -18084 68/push 1/imm32/block-depth -18085 51/push-ecx -18086 68/push 0x11/imm32/alloc-id:fake -18087 68/push 0/imm32/name -18088 68/push 0/imm32/name -18089 68/push 0x11/imm32/alloc-id:fake:payload -18090 89/<- %ecx 4/r32/esp -18091 $test-compare-reg-with-mem:initialize-var1-name: -18092 # var1->name = "var1" -18093 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -18094 (copy-array Heap "var1" %eax) -18095 $test-compare-reg-with-mem:initialize-var1-register: -18096 # var1->register = "eax" -18097 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -18098 (copy-array Heap "eax" %eax) -18099 $test-compare-reg-with-mem:initialize-var2: -18100 # var var2/edx: (payload var) -18101 68/push 0/imm32/register -18102 68/push 0/imm32/register -18103 68/push 8/imm32/stack-offset -18104 68/push 1/imm32/block-depth -18105 ff 6/subop/push *(ecx+0x10) -18106 68/push 0x11/imm32/alloc-id:fake -18107 68/push 0/imm32/name -18108 68/push 0/imm32/name +18022 68/push 0x11/imm32/alloc-id:fake:payload +18023 89/<- %ebx 4/r32/esp +18024 $test-emit-subx-stmt-primitive:initialize-stmt: +18025 # var stmt/esi: (addr statement) +18026 68/push 0/imm32/no-outputs +18027 68/push 0/imm32/no-outputs +18028 53/push-ebx/inouts +18029 68/push 0x11/imm32/alloc-id:fake +18030 68/push 0/imm32/operation +18031 68/push 0/imm32/operation +18032 68/push 1/imm32/tag +18033 89/<- %esi 4/r32/esp +18034 $test-emit-subx-stmt-primitive:initialize-stmt-operation: +18035 # stmt->operation = "increment" +18036 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +18037 (copy-array Heap "increment" %eax) +18038 $test-emit-subx-stmt-primitive:initialize-primitive: +18039 # var primitives/ebx: (addr primitive) +18040 68/push 0/imm32/next +18041 68/push 0/imm32/next +18042 68/push 0/imm32/output-is-write-only +18043 68/push 0/imm32/no-disp32 +18044 68/push 0/imm32/no-imm32 +18045 68/push 0/imm32/no-r32 +18046 68/push 1/imm32/rm32-is-first-inout +18047 68/push 0/imm32/subx-name +18048 68/push 0/imm32/subx-name +18049 68/push 0/imm32/no-outputs +18050 68/push 0/imm32/no-outputs +18051 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +18052 68/push 0x11/imm32/alloc-id:fake +18053 68/push 0/imm32/name +18054 68/push 0/imm32/name +18055 89/<- %ebx 4/r32/esp +18056 $test-emit-subx-stmt-primitive:initialize-primitive-name: +18057 # primitives->name = "increment" +18058 (copy-array Heap "increment" %ebx) # Primitive-name +18059 $test-emit-subx-stmt-primitive:initialize-primitive-subx-name: +18060 # primitives->subx-name = "ff 0/subop/increment" +18061 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +18062 (copy-array Heap "ff 0/subop/increment" %eax) +18063 # convert +18064 c7 0/subop/copy *Curr-block-depth 0/imm32 +18065 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) +18066 (flush _test-output-buffered-file) +18067 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +18073 # check output +18074 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-stmt-primitive") +18075 # . epilogue +18076 89/<- %esp 5/r32/ebp +18077 5d/pop-to-ebp +18078 c3/return +18079 +18080 test-emit-subx-stmt-primitive-register: +18081 # Primitive operation on a variable in a register. +18082 # foo <- increment +18083 # => +18084 # ff 0/subop/increment %eax # sub-optimal, but should suffice +18085 # +18086 # There's a variable on the var stack as follows: +18087 # name: 'foo' +18088 # type: int +18089 # register: 'eax' +18090 # +18091 # There's a primitive with this info: +18092 # name: 'increment' +18093 # out: int/reg +18094 # value: 'ff 0/subop/increment' +18095 # +18096 # . prologue +18097 55/push-ebp +18098 89/<- %ebp 4/r32/esp +18099 # setup +18100 (clear-stream _test-output-stream) +18101 (clear-stream $_test-output-buffered-file->buffer) +18102 $test-emit-subx-stmt-primitive-register:initialize-type: +18103 # var type/ecx: (payload tree type-id) = int +18104 68/push 0/imm32/right:null +18105 68/push 0/imm32/right:null +18106 68/push 0/imm32/left:unused +18107 68/push 1/imm32/value:int +18108 68/push 1/imm32/is-atom?:true 18109 68/push 0x11/imm32/alloc-id:fake:payload -18110 89/<- %edx 4/r32/esp -18111 $test-compare-reg-with-mem:initialize-var2-name: -18112 # var2->name = "var2" -18113 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -18114 (copy-array Heap "var2" %eax) -18115 $test-compare-reg-with-mem:initialize-inouts: -18116 # var inouts/esi: (payload stmt-var) = [var2] -18117 68/push 0/imm32/is-deref:false -18118 68/push 0/imm32/next -18119 68/push 0/imm32/next -18120 52/push-edx/var2 -18121 68/push 0x11/imm32/alloc-id:fake -18122 68/push 0x11/imm32/alloc-id:fake:payload -18123 89/<- %esi 4/r32/esp -18124 # inouts = [var1, var2] -18125 68/push 0/imm32/is-deref:false -18126 56/push-esi/next -18127 68/push 0x11/imm32/alloc-id:fake -18128 51/push-ecx/var1 -18129 68/push 0x11/imm32/alloc-id:fake -18130 68/push 0x11/imm32/alloc-id:fake:payload -18131 89/<- %esi 4/r32/esp -18132 $test-compare-reg-with-mem:initialize-stmt: -18133 # var stmt/esi: (addr statement) +18110 89/<- %ecx 4/r32/esp +18111 $test-emit-subx-stmt-primitive-register:initialize-var: +18112 # var var-foo/ecx: (payload var) +18113 68/push 0/imm32/register +18114 68/push 0/imm32/register +18115 68/push 0/imm32/no-stack-offset +18116 68/push 1/imm32/block-depth +18117 51/push-ecx +18118 68/push 0x11/imm32/alloc-id:fake +18119 68/push 0/imm32/name +18120 68/push 0/imm32/name +18121 68/push 0x11/imm32/alloc-id:fake:payload +18122 89/<- %ecx 4/r32/esp +18123 $test-emit-subx-stmt-primitive-register:initialize-var-name: +18124 # var-foo->name = "foo" +18125 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +18126 (copy-array Heap "foo" %eax) +18127 $test-emit-subx-stmt-primitive-register:initialize-var-register: +18128 # var-foo->register = "eax" +18129 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +18130 (copy-array Heap "eax" %eax) +18131 $test-emit-subx-stmt-primitive-register:initialize-stmt-var: +18132 # var operand/ebx: (payload stmt-var) +18133 68/push 0/imm32/is-deref:false 18134 68/push 0/imm32/next 18135 68/push 0/imm32/next -18136 68/push 0/imm32/outputs -18137 68/push 0/imm32/outputs -18138 56/push-esi/inouts -18139 68/push 0x11/imm32/alloc-id:fake -18140 68/push 0/imm32/operation -18141 68/push 0/imm32/operation -18142 68/push 1/imm32/tag:stmt1 -18143 89/<- %esi 4/r32/esp -18144 $test-compare-reg-with-mem:initialize-stmt-operation: -18145 # stmt->operation = "compare" -18146 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -18147 (copy-array Heap "compare" %eax) -18148 # convert -18149 c7 0/subop/copy *Curr-block-depth 0/imm32 -18150 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -18151 (flush _test-output-buffered-file) -18152 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -18158 # check output -18159 (check-next-stream-line-equal _test-output-stream "3b/compare<- *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem") -18160 # . epilogue -18161 89/<- %esp 5/r32/ebp -18162 5d/pop-to-ebp -18163 c3/return -18164 -18165 test-compare-mem-with-literal: -18166 # compare var1, 0x34 -18167 # => -18168 # 81 7/subop/compare *(ebp+___) 0x34/imm32 -18169 # -18170 # . prologue -18171 55/push-ebp -18172 89/<- %ebp 4/r32/esp -18173 # setup -18174 (clear-stream _test-output-stream) -18175 (clear-stream $_test-output-buffered-file->buffer) -18176 $test-compare-mem-with-literal:initialize-type: -18177 # var type/ecx: (payload tree type-id) = int -18178 68/push 0/imm32/right:null -18179 68/push 0/imm32/right:null -18180 68/push 0/imm32/left:unused -18181 68/push 1/imm32/value:int -18182 68/push 1/imm32/is-atom?:true -18183 68/push 0x11/imm32/alloc-id:fake:payload -18184 89/<- %ecx 4/r32/esp -18185 $test-compare-mem-with-literal:initialize-var1: -18186 # var var1/ecx: (payload var) -18187 68/push 0/imm32/register -18188 68/push 0/imm32/register -18189 68/push 8/imm32/stack-offset -18190 68/push 1/imm32/block-depth -18191 51/push-ecx -18192 68/push 0x11/imm32/alloc-id:fake -18193 68/push 0/imm32/name -18194 68/push 0/imm32/name -18195 68/push 0x11/imm32/alloc-id:fake:payload -18196 89/<- %ecx 4/r32/esp -18197 $test-compare-mem-with-literal:initialize-var1-name: -18198 # var1->name = "var1" -18199 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -18200 (copy-array Heap "var1" %eax) -18201 $test-compare-mem-with-literal:initialize-literal-type: -18202 # var type/edx: (payload tree type-id) = literal -18203 68/push 0/imm32/right:null -18204 68/push 0/imm32/right:null -18205 68/push 0/imm32/left:unused -18206 68/push 0/imm32/value:literal -18207 68/push 1/imm32/is-atom?:true -18208 68/push 0x11/imm32/alloc-id:fake:payload -18209 89/<- %edx 4/r32/esp -18210 $test-compare-mem-with-literal:initialize-literal: -18211 # var l/edx: (payload var) -18212 68/push 0/imm32/register -18213 68/push 0/imm32/register -18214 68/push 0/imm32/no-stack-offset -18215 68/push 1/imm32/block-depth -18216 52/push-edx -18217 68/push 0x11/imm32/alloc-id:fake -18218 68/push 0/imm32/name -18219 68/push 0/imm32/name -18220 68/push 0x11/imm32/alloc-id:fake:payload -18221 89/<- %edx 4/r32/esp -18222 $test-compare-mem-with-literal:initialize-literal-value: -18223 # l->name = "0x34" -18224 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -18225 (copy-array Heap "0x34" %eax) -18226 $test-compare-mem-with-literal:initialize-inouts: -18227 # var inouts/esi: (payload stmt-var) = [l] -18228 68/push 0/imm32/is-deref:false -18229 68/push 0/imm32/next -18230 68/push 0/imm32/next -18231 52/push-edx/l -18232 68/push 0x11/imm32/alloc-id:fake -18233 68/push 0x11/imm32/alloc-id:fake:payload -18234 89/<- %esi 4/r32/esp -18235 # var inouts = (handle stmt-var) = [var1, var2] -18236 68/push 0/imm32/is-deref:false -18237 56/push-esi/next -18238 68/push 0x11/imm32/alloc-id:fake -18239 51/push-ecx/var1 -18240 68/push 0x11/imm32/alloc-id:fake -18241 68/push 0x11/imm32/alloc-id:fake:payload -18242 89/<- %esi 4/r32/esp -18243 $test-compare-mem-with-literal:initialize-stmt: -18244 # var stmt/esi: (addr statement) -18245 68/push 0/imm32/next -18246 68/push 0/imm32/next -18247 68/push 0/imm32/outputs -18248 68/push 0/imm32/outputs -18249 56/push-esi/inouts -18250 68/push 0x11/imm32/alloc-id:fake -18251 68/push 0/imm32/operation -18252 68/push 0/imm32/operation -18253 68/push 1/imm32/tag:stmt1 -18254 89/<- %esi 4/r32/esp -18255 $test-compare-mem-with-literal:initialize-stmt-operation: -18256 # stmt->operation = "compare" -18257 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -18258 (copy-array Heap "compare" %eax) -18259 # convert -18260 c7 0/subop/copy *Curr-block-depth 0/imm32 -18261 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -18262 (flush _test-output-buffered-file) -18263 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -18269 # check output -18270 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal") -18271 # . epilogue -18272 89/<- %esp 5/r32/ebp -18273 5d/pop-to-ebp -18274 c3/return -18275 -18276 test-compare-eax-with-literal: -18277 # compare var1/eax 0x34 -18278 # => -18279 # 3d/compare-eax-with 0x34/imm32 -18280 # -18281 # . prologue -18282 55/push-ebp -18283 89/<- %ebp 4/r32/esp -18284 # setup -18285 (clear-stream _test-output-stream) -18286 (clear-stream $_test-output-buffered-file->buffer) -18287 $test-compare-eax-with-literal:initialize-type: -18288 # var type/ecx: (payload tree type-id) = int -18289 68/push 0/imm32/right:null -18290 68/push 0/imm32/right:null -18291 68/push 0/imm32/left:unused -18292 68/push 1/imm32/value:int -18293 68/push 1/imm32/is-atom?:true -18294 68/push 0x11/imm32/alloc-id:fake:payload -18295 89/<- %ecx 4/r32/esp -18296 $test-compare-eax-with-literal:initialize-var1: -18297 # var var1/ecx: (payload var) -18298 68/push 0/imm32/register -18299 68/push 0/imm32/register -18300 68/push 0/imm32/no-stack-offset -18301 68/push 1/imm32/block-depth -18302 51/push-ecx -18303 68/push 0x11/imm32/alloc-id:fake -18304 68/push 0/imm32/name -18305 68/push 0/imm32/name -18306 68/push 0x11/imm32/alloc-id:fake:payload -18307 89/<- %ecx 4/r32/esp -18308 $test-compare-eax-with-literal:initialize-var1-name: -18309 # var1->name = "var1" -18310 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -18311 (copy-array Heap "var1" %eax) -18312 $test-compare-eax-with-literal:initialize-var1-register: -18313 # v->register = "eax" -18314 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -18315 (copy-array Heap "eax" %eax) -18316 $test-compare-eax-with-literal:initialize-literal-type: -18317 # var type/edx: (payload tree type-id) = literal -18318 68/push 0/imm32/right:null -18319 68/push 0/imm32/right:null -18320 68/push 0/imm32/left:unused -18321 68/push 0/imm32/value:literal -18322 68/push 1/imm32/is-atom?:true -18323 68/push 0x11/imm32/alloc-id:fake:payload -18324 89/<- %edx 4/r32/esp -18325 $test-compare-eax-with-literal:initialize-literal: -18326 # var l/edx: (payload var) -18327 68/push 0/imm32/register -18328 68/push 0/imm32/register -18329 68/push 0/imm32/no-stack-offset -18330 68/push 1/imm32/block-depth -18331 52/push-edx -18332 68/push 0x11/imm32/alloc-id:fake -18333 68/push 0/imm32/name -18334 68/push 0/imm32/name -18335 68/push 0x11/imm32/alloc-id:fake:payload -18336 89/<- %edx 4/r32/esp -18337 $test-compare-eax-with-literal:initialize-literal-value: -18338 # l->name = "0x34" -18339 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -18340 (copy-array Heap "0x34" %eax) -18341 $test-compare-eax-with-literal:initialize-inouts: -18342 # var inouts/esi: (payload stmt-var) = [l] -18343 68/push 0/imm32/is-deref:false -18344 68/push 0/imm32/next -18345 68/push 0/imm32/next -18346 52/push-edx/l -18347 68/push 0x11/imm32/alloc-id:fake -18348 68/push 0x11/imm32/alloc-id:fake:payload -18349 89/<- %esi 4/r32/esp -18350 # var inouts = (handle stmt-var) = [var1, var2] -18351 68/push 0/imm32/is-deref:false -18352 56/push-esi/next -18353 68/push 0x11/imm32/alloc-id:fake -18354 51/push-ecx/var1 -18355 68/push 0x11/imm32/alloc-id:fake -18356 68/push 0x11/imm32/alloc-id:fake:payload -18357 89/<- %esi 4/r32/esp -18358 $test-compare-eax-with-literal:initialize-stmt: -18359 # var stmt/esi: (addr statement) -18360 68/push 0/imm32/next -18361 68/push 0/imm32/next -18362 68/push 0/imm32/outputs -18363 68/push 0/imm32/outputs -18364 56/push-esi/inouts -18365 68/push 0x11/imm32/alloc-id:fake -18366 68/push 0/imm32/operation -18367 68/push 0/imm32/operation -18368 68/push 1/imm32/tag:stmt1 -18369 89/<- %esi 4/r32/esp -18370 $test-compare-eax-with-literal:initialize-stmt-operation: -18371 # stmt->operation = "compare" -18372 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -18373 (copy-array Heap "compare" %eax) -18374 # convert -18375 c7 0/subop/copy *Curr-block-depth 0/imm32 -18376 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -18377 (flush _test-output-buffered-file) -18378 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -18384 # check output -18385 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal") -18386 # . epilogue -18387 89/<- %esp 5/r32/ebp -18388 5d/pop-to-ebp -18389 c3/return -18390 -18391 test-compare-reg-with-literal: -18392 # compare var1/ecx 0x34 -18393 # => -18394 # 81 7/subop/compare %ecx 0x34/imm32 -18395 # -18396 # . prologue -18397 55/push-ebp -18398 89/<- %ebp 4/r32/esp -18399 # setup -18400 (clear-stream _test-output-stream) -18401 (clear-stream $_test-output-buffered-file->buffer) -18402 $test-compare-reg-with-literal:initialize-type: -18403 # var type/ecx: (payload tree type-id) = int -18404 68/push 0/imm32/right:null -18405 68/push 0/imm32/right:null -18406 68/push 0/imm32/left:unused -18407 68/push 1/imm32/value:int -18408 68/push 1/imm32/is-atom?:true -18409 68/push 0x11/imm32/alloc-id:fake:payload -18410 89/<- %ecx 4/r32/esp -18411 $test-compare-reg-with-literal:initialize-var1: -18412 # var var1/ecx: (payload var) -18413 68/push 0/imm32/register -18414 68/push 0/imm32/register -18415 68/push 0/imm32/no-stack-offset -18416 68/push 1/imm32/block-depth -18417 51/push-ecx -18418 68/push 0x11/imm32/alloc-id:fake -18419 68/push 0/imm32/name -18420 68/push 0/imm32/name -18421 68/push 0x11/imm32/alloc-id:fake:payload -18422 89/<- %ecx 4/r32/esp -18423 $test-compare-reg-with-literal:initialize-var1-name: -18424 # var1->name = "var1" -18425 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -18426 (copy-array Heap "var1" %eax) -18427 $test-compare-reg-with-literal:initialize-var1-register: -18428 # v->register = "ecx" -18429 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 -18430 (copy-array Heap "ecx" %eax) -18431 $test-compare-reg-with-literal:initialize-literal-type: -18432 # var type/edx: (payload tree type-id) = literal -18433 68/push 0/imm32/right:null -18434 68/push 0/imm32/right:null -18435 68/push 0/imm32/left:unused -18436 68/push 0/imm32/value:literal -18437 68/push 1/imm32/is-atom?:true -18438 68/push 0x11/imm32/alloc-id:fake:payload -18439 89/<- %edx 4/r32/esp -18440 $test-compare-reg-with-literal:initialize-literal: -18441 # var l/edx: (payload var) -18442 68/push 0/imm32/register -18443 68/push 0/imm32/register -18444 68/push 0/imm32/no-stack-offset -18445 68/push 1/imm32/block-depth -18446 52/push-edx -18447 68/push 0x11/imm32/alloc-id:fake -18448 68/push 0/imm32/name -18449 68/push 0/imm32/name -18450 68/push 0x11/imm32/alloc-id:fake:payload -18451 89/<- %edx 4/r32/esp -18452 $test-compare-reg-with-literal:initialize-literal-value: -18453 # l->name = "0x34" -18454 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 -18455 (copy-array Heap "0x34" %eax) -18456 $test-compare-reg-with-literal:initialize-inouts: -18457 # var inouts/esi: (payload stmt-var) = [l] -18458 68/push 0/imm32/is-deref:false -18459 68/push 0/imm32/next -18460 68/push 0/imm32/next -18461 52/push-edx/l -18462 68/push 0x11/imm32/alloc-id:fake -18463 68/push 0x11/imm32/alloc-id:fake:payload -18464 89/<- %esi 4/r32/esp -18465 # var inouts = (handle stmt-var) = [var1, var2] -18466 68/push 0/imm32/is-deref:false -18467 56/push-esi/next -18468 68/push 0x11/imm32/alloc-id:fake -18469 51/push-ecx/var1 -18470 68/push 0x11/imm32/alloc-id:fake -18471 68/push 0x11/imm32/alloc-id:fake:payload -18472 89/<- %esi 4/r32/esp -18473 $test-compare-reg-with-literal:initialize-stmt: -18474 # var stmt/esi: (addr statement) -18475 68/push 0/imm32/next -18476 68/push 0/imm32/next -18477 68/push 0/imm32/outputs -18478 68/push 0/imm32/outputs -18479 56/push-esi/inouts -18480 68/push 0x11/imm32/alloc-id:fake -18481 68/push 0/imm32/operation -18482 68/push 0/imm32/operation -18483 68/push 1/imm32/tag:stmt1 -18484 89/<- %esi 4/r32/esp -18485 $test-compare-reg-with-literal:initialize-stmt-operation: -18486 # stmt->operation = "compare" -18487 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -18488 (copy-array Heap "compare" %eax) -18489 # convert -18490 c7 0/subop/copy *Curr-block-depth 0/imm32 -18491 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) -18492 (flush _test-output-buffered-file) -18493 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -18499 # check output -18500 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal") -18501 # . epilogue -18502 89/<- %esp 5/r32/ebp -18503 5d/pop-to-ebp -18504 c3/return -18505 -18506 test-emit-subx-stmt-function-call: -18507 # Call a function on a variable on the stack. -18508 # f foo -18509 # => -18510 # (f *(ebp-8)) -18511 # (Changing the function name supports overloading in general, but here it -18512 # just serves to help disambiguate things.) -18513 # -18514 # There's a variable on the var stack as follows: -18515 # name: 'foo' -18516 # type: int -18517 # stack-offset: -8 -18518 # -18519 # There's nothing in primitives. -18520 # -18521 # We don't perform any checking here on the type of 'f'. -18522 # -18523 # . prologue -18524 55/push-ebp -18525 89/<- %ebp 4/r32/esp -18526 # setup -18527 (clear-stream _test-output-stream) -18528 (clear-stream $_test-output-buffered-file->buffer) -18529 $test-emit-subx-function-call:initialize-type: -18530 # var type/ecx: (payload tree type-id) = int -18531 68/push 0/imm32/right:null -18532 68/push 0/imm32/right:null -18533 68/push 0/imm32/left:unused -18534 68/push 1/imm32/value:int -18535 68/push 1/imm32/is-atom?:true -18536 68/push 0x11/imm32/alloc-id:fake:payload -18537 89/<- %ecx 4/r32/esp -18538 $test-emit-subx-function-call:initialize-var: -18539 # var var-foo/ecx: (payload var) = var(type) -18540 68/push 0/imm32/no-register -18541 68/push 0/imm32/no-register -18542 68/push -8/imm32/stack-offset -18543 68/push 1/imm32/block-depth -18544 51/push-ecx/type -18545 68/push 0x11/imm32/alloc-id:fake +18136 51/push-ecx/var-foo +18137 68/push 0x11/imm32/alloc-id:fake +18138 68/push 0x11/imm32/alloc-id:fake:payload +18139 89/<- %ebx 4/r32/esp +18140 $test-emit-subx-stmt-primitive-register:initialize-stmt: +18141 # var stmt/esi: (addr statement) +18142 53/push-ebx/outputs +18143 68/push 0x11/imm32/alloc-id:fake +18144 68/push 0/imm32/no-inouts +18145 68/push 0/imm32/no-inouts +18146 68/push 0/imm32/operation +18147 68/push 0/imm32/operation +18148 68/push 1/imm32 +18149 89/<- %esi 4/r32/esp +18150 $test-emit-subx-stmt-primitive-register:initialize-stmt-operation: +18151 # stmt->operation = "increment" +18152 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +18153 (copy-array Heap "increment" %eax) +18154 $test-emit-subx-stmt-primitive-register:initialize-formal-var: +18155 # var formal-var/ebx: (payload var) +18156 68/push 0/imm32/register +18157 68/push 0/imm32/register +18158 68/push 0/imm32/no-stack-offset +18159 68/push 1/imm32/block-depth +18160 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +18161 68/push 0x11/imm32/alloc-id:fake +18162 68/push 0/imm32/name +18163 68/push 0/imm32/name +18164 68/push 0x11/imm32/alloc-id:fake:payload +18165 89/<- %ebx 4/r32/esp +18166 $test-emit-subx-stmt-primitive-register:initialize-formal-var-name: +18167 # formal-var->name = "dummy" +18168 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +18169 (copy-array Heap "dummy" %eax) +18170 $test-emit-subx-stmt-primitive-register:initialize-formal-register: +18171 # formal-var->register = "*" +18172 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +18173 (copy-array Heap "*" %eax) # Any-register +18174 $test-emit-subx-stmt-primitive-register:initialize-var-list: +18175 # var formal-outputs/ebx: (payload list var) +18176 68/push 0/imm32/next +18177 68/push 0/imm32/next +18178 53/push-ebx/formal-var +18179 68/push 0x11/imm32/alloc-id:fake +18180 68/push 0x11/imm32/alloc-id:fake:payload +18181 89/<- %ebx 4/r32/esp +18182 $test-emit-subx-stmt-primitive-register:initialize-primitive: +18183 # var primitives/ebx: (addr primitive) +18184 68/push 0/imm32/next +18185 68/push 0/imm32/next +18186 68/push 0/imm32/output-is-write-only +18187 68/push 0/imm32/no-disp32 +18188 68/push 0/imm32/no-imm32 +18189 68/push 0/imm32/no-r32 +18190 68/push 3/imm32/rm32-is-first-output +18191 68/push 0/imm32/subx-name +18192 68/push 0/imm32/subx-name +18193 53/push-ebx/outputs +18194 68/push 0x11/imm32/alloc-id:fake +18195 68/push 0/imm32/no-inouts +18196 68/push 0/imm32/no-inouts +18197 68/push 0/imm32/name +18198 68/push 0/imm32/name +18199 89/<- %ebx 4/r32/esp +18200 $test-emit-subx-stmt-primitive-register:initialize-primitive-name: +18201 # primitives->name = "increment" +18202 (copy-array Heap "increment" %ebx) # Primitive-name +18203 $test-emit-subx-stmt-primitive-register:initialize-primitive-subx-name: +18204 # primitives->subx-name = "ff 0/subop/increment" +18205 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +18206 (copy-array Heap "ff 0/subop/increment" %eax) +18207 # convert +18208 c7 0/subop/copy *Curr-block-depth 0/imm32 +18209 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) +18210 (flush _test-output-buffered-file) +18211 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +18217 # check output +18218 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-primitive-register") +18219 # . epilogue +18220 89/<- %esp 5/r32/ebp +18221 5d/pop-to-ebp +18222 c3/return +18223 +18224 test-emit-subx-stmt-select-primitive: +18225 # Select the right primitive between overloads. +18226 # foo <- increment +18227 # => +18228 # ff 0/subop/increment %eax # sub-optimal, but should suffice +18229 # +18230 # There's a variable on the var stack as follows: +18231 # name: 'foo' +18232 # type: int +18233 # register: 'eax' +18234 # +18235 # There's two primitives, as follows: +18236 # - name: 'increment' +18237 # out: int/reg +18238 # value: 'ff 0/subop/increment' +18239 # - name: 'increment' +18240 # inout: int/mem +18241 # value: 'ff 0/subop/increment' +18242 # +18243 # . prologue +18244 55/push-ebp +18245 89/<- %ebp 4/r32/esp +18246 # setup +18247 (clear-stream _test-output-stream) +18248 (clear-stream $_test-output-buffered-file->buffer) +18249 $test-emit-subx-stmt-select-primitive:initialize-type: +18250 # var type/ecx: (payload tree type-id) = int +18251 68/push 0/imm32/right:null +18252 68/push 0/imm32/right:null +18253 68/push 0/imm32/left:unused +18254 68/push 1/imm32/value:int +18255 68/push 1/imm32/is-atom?:true +18256 68/push 0x11/imm32/alloc-id:fake:payload +18257 89/<- %ecx 4/r32/esp +18258 $test-emit-subx-stmt-select-primitive:initialize-var: +18259 # var var-foo/ecx: (payload var) +18260 68/push 0/imm32/register +18261 68/push 0/imm32/register +18262 68/push 0/imm32/no-stack-offset +18263 68/push 1/imm32/block-depth +18264 51/push-ecx +18265 68/push 0x11/imm32/alloc-id:fake +18266 68/push 0/imm32/name +18267 68/push 0/imm32/name +18268 68/push 0x11/imm32/alloc-id:fake:payload +18269 89/<- %ecx 4/r32/esp +18270 $test-emit-subx-stmt-select-primitive:initialize-var-name: +18271 # var-foo->name = "foo" +18272 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +18273 (copy-array Heap "foo" %eax) +18274 $test-emit-subx-stmt-select-primitive:initialize-var-register: +18275 # var-foo->register = "eax" +18276 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +18277 (copy-array Heap "eax" %eax) +18278 $test-emit-subx-stmt-select-primitive:initialize-stmt-var: +18279 # var operand/ebx: (payload stmt-var) +18280 68/push 0/imm32/is-deref:false +18281 68/push 0/imm32/next +18282 68/push 0/imm32/next +18283 51/push-ecx/var-foo +18284 68/push 0x11/imm32/alloc-id:fake +18285 68/push 0x11/imm32/alloc-id:fake:payload +18286 89/<- %ebx 4/r32/esp +18287 $test-emit-subx-stmt-select-primitive:initialize-stmt: +18288 # var stmt/esi: (addr statement) +18289 53/push-ebx/outputs +18290 68/push 0x11/imm32/alloc-id:fake +18291 68/push 0/imm32/no-inouts +18292 68/push 0/imm32/no-inouts +18293 68/push 0/imm32/operation +18294 68/push 0/imm32/operation +18295 68/push 1/imm32 +18296 89/<- %esi 4/r32/esp +18297 $test-emit-subx-stmt-select-primitive:initialize-stmt-operation: +18298 # stmt->operation = "increment" +18299 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +18300 (copy-array Heap "increment" %eax) +18301 $test-emit-subx-stmt-select-primitive:initialize-formal-var: +18302 # var formal-var/ebx: (payload var) +18303 68/push 0/imm32/register +18304 68/push 0/imm32/register +18305 68/push 0/imm32/no-stack-offset +18306 68/push 1/imm32/block-depth +18307 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +18308 68/push 0x11/imm32/alloc-id:fake +18309 68/push 0/imm32/name +18310 68/push 0/imm32/name +18311 68/push 0x11/imm32/alloc-id:fake:payload +18312 89/<- %ebx 4/r32/esp +18313 $test-emit-subx-stmt-select-primitive:initialize-formal-var-name: +18314 # formal-var->name = "dummy" +18315 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +18316 (copy-array Heap "dummy" %eax) +18317 $test-emit-subx-stmt-select-primitive:initialize-formal-register: +18318 # formal-var->register = "*" +18319 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +18320 (copy-array Heap "*" %eax) # Any-register +18321 $test-emit-subx-stmt-select-primitive:initialize-var-list: +18322 # var formal-outputs/ebx: (payload list var) +18323 68/push 0/imm32/next +18324 68/push 0/imm32/next +18325 53/push-ebx/formal-var +18326 68/push 0x11/imm32/alloc-id:fake +18327 68/push 0x11/imm32/alloc-id:fake:payload +18328 89/<- %ebx 4/r32/esp +18329 $test-emit-subx-stmt-select-primitive:initialize-primitive2: +18330 # var primitive2/edi: (payload primitive) +18331 68/push 0/imm32/next +18332 68/push 0/imm32/next +18333 68/push 0/imm32/output-is-write-only +18334 68/push 0/imm32/no-disp32 +18335 68/push 0/imm32/no-imm32 +18336 68/push 0/imm32/no-r32 +18337 68/push 3/imm32/rm32-is-first-output +18338 68/push 0/imm32/subx-name +18339 68/push 0/imm32/subx-name +18340 53/push-ebx/outputs +18341 68/push 0x11/imm32/alloc-id:fake +18342 68/push 0/imm32/no-inouts +18343 68/push 0/imm32/no-inouts +18344 68/push 0/imm32/name +18345 68/push 0/imm32/name +18346 68/push 0x11/imm32/alloc-id:fake:payload +18347 89/<- %edi 4/r32/esp +18348 $test-emit-subx-stmt-select-primitive:initialize-primitive2-name: +18349 # primitives->name = "increment" +18350 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 +18351 (copy-array Heap "increment" %eax) +18352 $test-emit-subx-stmt-select-primitive:initialize-primitive2-subx-name: +18353 # primitives->subx-name = "ff 0/subop/increment" +18354 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 +18355 (copy-array Heap "ff 0/subop/increment" %eax) +18356 $test-emit-subx-stmt-select-primitive:initialize-primitive: +18357 # var primitives/ebx: (addr primitive) +18358 57/push-edi +18359 68/push 0x11/imm32/alloc-id:fake +18360 68/push 0/imm32/output-is-write-only +18361 68/push 0/imm32/no-disp32 +18362 68/push 0/imm32/no-imm32 +18363 68/push 0/imm32/no-r32 +18364 68/push 1/imm32/rm32-is-first-inout +18365 68/push 0/imm32/subx-name +18366 68/push 0/imm32/subx-name +18367 68/push 0/imm32/no-outputs +18368 68/push 0/imm32/no-outputs +18369 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +18370 68/push 0x11/imm32/alloc-id:fake +18371 68/push 0/imm32/name +18372 68/push 0/imm32/name +18373 89/<- %ebx 4/r32/esp +18374 $test-emit-subx-stmt-select-primitive:initialize-primitive-name: +18375 # primitives->name = "increment" +18376 (copy-array Heap "increment" %ebx) # Primitive-name +18377 $test-emit-subx-stmt-select-primitive:initialize-primitive-subx-name: +18378 # primitives->subx-name = "ff 0/subop/increment" +18379 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +18380 (copy-array Heap "ff 0/subop/increment" %eax) +18381 # convert +18382 c7 0/subop/copy *Curr-block-depth 0/imm32 +18383 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) +18384 (flush _test-output-buffered-file) +18385 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +18391 # check output +18392 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive") +18393 # . epilogue +18394 89/<- %esp 5/r32/ebp +18395 5d/pop-to-ebp +18396 c3/return +18397 +18398 test-emit-subx-stmt-select-primitive-2: +18399 # Select the right primitive between overloads. +18400 # increment foo +18401 # => +18402 # ff 0/subop/increment %eax # sub-optimal, but should suffice +18403 # +18404 # There's a variable on the var stack as follows: +18405 # name: 'foo' +18406 # type: int +18407 # register: 'eax' +18408 # +18409 # There's two primitives, as follows: +18410 # - name: 'increment' +18411 # out: int/reg +18412 # value: 'ff 0/subop/increment' +18413 # - name: 'increment' +18414 # inout: int/mem +18415 # value: 'ff 0/subop/increment' +18416 # +18417 # . prologue +18418 55/push-ebp +18419 89/<- %ebp 4/r32/esp +18420 # setup +18421 (clear-stream _test-output-stream) +18422 (clear-stream $_test-output-buffered-file->buffer) +18423 $test-emit-subx-stmt-select-primitive-2:initialize-type: +18424 # var type/ecx: (payload tree type-id) = int +18425 68/push 0/imm32/right:null +18426 68/push 0/imm32/right:null +18427 68/push 0/imm32/left:unused +18428 68/push 1/imm32/value:int +18429 68/push 1/imm32/is-atom?:true +18430 68/push 0x11/imm32/alloc-id:fake:payload +18431 89/<- %ecx 4/r32/esp +18432 $test-emit-subx-stmt-select-primitive-2:initialize-var: +18433 # var var-foo/ecx: (payload var) +18434 68/push 0/imm32/register +18435 68/push 0/imm32/register +18436 68/push 0/imm32/no-stack-offset +18437 68/push 1/imm32/block-depth +18438 51/push-ecx +18439 68/push 0x11/imm32/alloc-id:fake +18440 68/push 0/imm32/name +18441 68/push 0/imm32/name +18442 68/push 0x11/imm32/alloc-id:fake:payload +18443 89/<- %ecx 4/r32/esp +18444 $test-emit-subx-stmt-select-primitive-2:initialize-var-name: +18445 # var-foo->name = "foo" +18446 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +18447 (copy-array Heap "foo" %eax) +18448 $test-emit-subx-stmt-select-primitive-2:initialize-var-register: +18449 # var-foo->register = "eax" +18450 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +18451 (copy-array Heap "eax" %eax) +18452 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-var: +18453 # var operand/ebx: (payload stmt-var) +18454 68/push 0/imm32/is-deref:false +18455 68/push 0/imm32/next +18456 68/push 0/imm32/next +18457 51/push-ecx/var-foo +18458 68/push 0x11/imm32/alloc-id:fake +18459 68/push 0x11/imm32/alloc-id:fake:payload +18460 89/<- %ebx 4/r32/esp +18461 $test-emit-subx-stmt-select-primitive-2:initialize-stmt: +18462 # var stmt/esi: (addr statement) +18463 68/push 0/imm32/no-outputs +18464 68/push 0/imm32/no-outputs +18465 53/push-ebx/inouts +18466 68/push 0x11/imm32/alloc-id:fake +18467 68/push 0/imm32/operation +18468 68/push 0/imm32/operation +18469 68/push 1/imm32 +18470 89/<- %esi 4/r32/esp +18471 $test-emit-subx-stmt-select-primitive-2:initialize-stmt-operation: +18472 # stmt->operation = "increment" +18473 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +18474 (copy-array Heap "increment" %eax) +18475 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var: +18476 # var formal-var/ebx: (payload var) +18477 68/push 0/imm32/register +18478 68/push 0/imm32/register +18479 68/push 0/imm32/no-stack-offset +18480 68/push 1/imm32/block-depth +18481 ff 6/subop/push *(ecx+0x10) # Var-type + payload alloc id + handle alloc id +18482 68/push 0x11/imm32/alloc-id:fake +18483 68/push 0/imm32/name +18484 68/push 0/imm32/name +18485 68/push 0x11/imm32/alloc-id:fake:payload +18486 89/<- %ebx 4/r32/esp +18487 $test-emit-subx-stmt-select-primitive-2:initialize-formal-var-name: +18488 # formal-var->name = "dummy" +18489 8d/copy-address *(ebx+4) 0/r32/eax # Var-name + 4 +18490 (copy-array Heap "dummy" %eax) +18491 $test-emit-subx-stmt-select-primitive-2:initialize-formal-register: +18492 # formal-var->register = "*" +18493 8d/copy-address *(ebx+0x1c) 0/r32/eax # Var-register + 4 +18494 (copy-array Heap "*" %eax) # Any-register +18495 $test-emit-subx-stmt-select-primitive-2:initialize-var-list: +18496 # var formal-outputs/ebx: (payload list stmt-var) +18497 68/push 0/imm32/next +18498 68/push 0/imm32/next +18499 53/push-ebx/formal-var +18500 68/push 0x11/imm32/alloc-id:fake +18501 68/push 0x11/imm32/alloc-id:fake:payload +18502 89/<- %ebx 4/r32/esp +18503 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2: +18504 # var primitive2/edi: (payload primitive) +18505 68/push 0/imm32/next +18506 68/push 0/imm32/next +18507 68/push 0/imm32/output-is-write-only +18508 68/push 0/imm32/no-disp32 +18509 68/push 0/imm32/no-imm32 +18510 68/push 0/imm32/no-r32 +18511 68/push 3/imm32/rm32-is-first-output +18512 68/push 0/imm32/subx-name +18513 68/push 0/imm32/subx-name +18514 53/push-ebx/outputs +18515 68/push 0x11/imm32/alloc-id:fake +18516 68/push 0/imm32/no-inouts +18517 68/push 0/imm32/no-inouts +18518 68/push 0/imm32/name +18519 68/push 0/imm32/name +18520 68/push 0x11/imm32/alloc-id:fake:payload +18521 89/<- %edi 4/r32/esp +18522 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-name: +18523 # primitives->name = "increment" +18524 8d/copy-address *(edi+4) 0/r32/eax # Primitive-name + 4 +18525 (copy-array Heap "increment" %eax) +18526 $test-emit-subx-stmt-select-primitive-2:initialize-primitive2-subx-name: +18527 # primitives->subx-name = "ff 0/subop/increment" +18528 8d/copy-address *(edi+0x1c) 0/r32/eax # Primitive-subx-name + 4 +18529 (copy-array Heap "ff 0/subop/increment" %eax) +18530 $test-emit-subx-stmt-select-primitive-2:initialize-primitive: +18531 # var primitives/ebx: (addr primitive) +18532 57/push-edi +18533 68/push 0x11/imm32/alloc-id:fake +18534 68/push 0/imm32/output-is-write-only +18535 68/push 0/imm32/no-disp32 +18536 68/push 0/imm32/no-imm32 +18537 68/push 0/imm32/no-r32 +18538 68/push 1/imm32/rm32-is-first-inout +18539 68/push 0/imm32/subx-name +18540 68/push 0/imm32/subx-name +18541 68/push 0/imm32/no-outputs +18542 68/push 0/imm32/no-outputs +18543 53/push-ebx/inouts # hack: reuse stmt-var from call stmt as (list var) in function declaration +18544 68/push 0x11/imm32/alloc-id:fake +18545 68/push 0/imm32/name 18546 68/push 0/imm32/name -18547 68/push 0/imm32/name -18548 68/push 0x11/imm32/alloc-id:fake:payload -18549 89/<- %ecx 4/r32/esp -18550 $test-emit-subx-function-call:initialize-var-name: -18551 # var-foo->name = "foo" -18552 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -18553 (copy-array Heap "foo" %eax) -18554 $test-emit-subx-function-call:initialize-stmt-var: -18555 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -18556 68/push 0/imm32/is-deref:false -18557 68/push 0/imm32/next -18558 68/push 0/imm32/next -18559 51/push-ecx/var-foo -18560 68/push 0x11/imm32/alloc-id:fake -18561 68/push 0x11/imm32/alloc-id:fake:payload -18562 89/<- %ebx 4/r32/esp -18563 $test-emit-subx-function-call:initialize-stmt: -18564 # var stmt/esi: (addr statement) -18565 68/push 0/imm32/no-outputs -18566 68/push 0/imm32/no-outputs -18567 53/push-ebx/inouts -18568 68/push 0x11/imm32/alloc-id:fake -18569 68/push 0/imm32/operation -18570 68/push 0/imm32/operation -18571 68/push 1/imm32/tag -18572 89/<- %esi 4/r32/esp -18573 $test-emit-subx-function-call:initialize-stmt-operation: -18574 # stmt->operation = "f" -18575 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -18576 (copy-array Heap "f" %eax) -18577 # convert -18578 c7 0/subop/copy *Curr-block-depth 0/imm32 -18579 (emit-subx-stmt _test-output-buffered-file %esi 0 Stderr 0) -18580 (flush _test-output-buffered-file) -18581 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -18587 # check output -18588 (check-next-stream-line-equal _test-output-stream "(f *(ebp+0xfffffff8))" "F - test-emit-subx-stmt-function-call") -18589 # . epilogue -18590 89/<- %esp 5/r32/ebp -18591 5d/pop-to-ebp -18592 c3/return -18593 -18594 test-emit-subx-stmt-function-call-with-literal-arg: -18595 # Call a function on a literal. -18596 # f 0x34 -18597 # => -18598 # (f2 0x34) -18599 # -18600 # . prologue -18601 55/push-ebp -18602 89/<- %ebp 4/r32/esp -18603 # setup -18604 (clear-stream _test-output-stream) -18605 (clear-stream $_test-output-buffered-file->buffer) -18606 $test-emit-subx-function-call-with-literal-arg:initialize-type: -18607 # var type/ecx: (payload tree type-id) = int -18608 68/push 0/imm32/right:null -18609 68/push 0/imm32/right:null -18610 68/push 0/imm32/left:unused -18611 68/push 0/imm32/value:literal -18612 68/push 1/imm32/is-atom?:true -18613 68/push 0x11/imm32/alloc-id:fake:payload -18614 89/<- %ecx 4/r32/esp -18615 $test-emit-subx-function-call-with-literal-arg:initialize-var: -18616 # var var-foo/ecx: (payload var) = var(lit) -18617 68/push 0/imm32/no-register -18618 68/push 0/imm32/no-register -18619 68/push 0/imm32/no-stack-offset -18620 68/push 1/imm32/block-depth -18621 51/push-ecx/type -18622 68/push 0x11/imm32/alloc-id:fake -18623 68/push 0/imm32/name -18624 68/push 0/imm32/name -18625 68/push 0x11/imm32/alloc-id:fake:payload -18626 89/<- %ecx 4/r32/esp -18627 $test-emit-subx-function-call-with-literal-arg:initialize-var-name: -18628 # var-foo->name = "0x34" -18629 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 -18630 (copy-array Heap "0x34" %eax) -18631 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-var: -18632 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) -18633 68/push 0/imm32/is-deref:false -18634 68/push 0/imm32/next -18635 68/push 0/imm32/next -18636 51/push-ecx/var-foo -18637 68/push 0x11/imm32/alloc-id:fake -18638 68/push 0x11/imm32/alloc-id:fake:payload -18639 89/<- %ebx 4/r32/esp -18640 $test-emit-subx-function-call-with-literal-arg:initialize-stmt: -18641 # var stmt/esi: (addr statement) -18642 68/push 0/imm32/no-outputs -18643 68/push 0/imm32/no-outputs -18644 53/push-ebx/inouts -18645 68/push 0x11/imm32/alloc-id:fake -18646 68/push 0/imm32/operation -18647 68/push 0/imm32/operation -18648 68/push 1/imm32/tag -18649 89/<- %esi 4/r32/esp -18650 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-operation: -18651 # stmt->operation = "f" -18652 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation -18653 (copy-array Heap "f" %eax) -18654 # convert -18655 c7 0/subop/copy *Curr-block-depth 0/imm32 -18656 (emit-subx-stmt _test-output-buffered-file %esi 0 %ebx Stderr 0) -18657 (flush _test-output-buffered-file) -18658 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- -18664 # check output -18665 (check-next-stream-line-equal _test-output-stream "(f 0x34)" "F - test-emit-subx-stmt-function-call-with-literal-arg") -18666 # . epilogue -18667 89/<- %esp 5/r32/ebp -18668 5d/pop-to-ebp -18669 c3/return -18670 -18671 emit-indent: # out: (addr buffered-file), n: int -18672 # . prologue -18673 55/push-ebp -18674 89/<- %ebp 4/r32/esp -18675 # . save registers -18676 50/push-eax -18677 # var i/eax: int = n -18678 8b/-> *(ebp+0xc) 0/r32/eax -18679 { -18680 # if (i <= 0) break -18681 3d/compare-eax-with 0/imm32 -18682 7e/jump-if-<= break/disp8 -18683 (write-buffered *(ebp+8) " ") -18684 48/decrement-eax -18685 eb/jump loop/disp8 -18686 } -18687 $emit-indent:end: -18688 # . restore registers -18689 58/pop-to-eax -18690 # . epilogue -18691 89/<- %esp 5/r32/ebp -18692 5d/pop-to-ebp -18693 c3/return -18694 -18695 emit-subx-prologue: # out: (addr buffered-file) -18696 # . prologue -18697 55/push-ebp -18698 89/<- %ebp 4/r32/esp -18699 # -18700 (write-buffered *(ebp+8) " # . prologue\n") -18701 (write-buffered *(ebp+8) " 55/push-ebp\n") -18702 (write-buffered *(ebp+8) " 89/<- %ebp 4/r32/esp\n") -18703 $emit-subx-prologue:end: -18704 # . epilogue -18705 89/<- %esp 5/r32/ebp -18706 5d/pop-to-ebp -18707 c3/return -18708 -18709 emit-subx-epilogue: # out: (addr buffered-file) -18710 # . prologue -18711 55/push-ebp -18712 89/<- %ebp 4/r32/esp -18713 # -18714 (write-buffered *(ebp+8) " # . epilogue\n") -18715 (write-buffered *(ebp+8) " 89/<- %esp 5/r32/ebp\n") -18716 (write-buffered *(ebp+8) " 5d/pop-to-ebp\n") -18717 (write-buffered *(ebp+8) " c3/return\n") -18718 $emit-subx-epilogue:end: -18719 # . epilogue -18720 89/<- %esp 5/r32/ebp -18721 5d/pop-to-ebp -18722 c3/return +18547 89/<- %ebx 4/r32/esp +18548 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-name: +18549 # primitives->name = "increment" +18550 (copy-array Heap "increment" %ebx) # Primitive-name +18551 $test-emit-subx-stmt-select-primitive-2:initialize-primitive-subx-name: +18552 # primitives->subx-name = "ff 0/subop/increment" +18553 8d/copy-address *(ebx+0x18) 0/r32/eax # Primitive-subx-name +18554 (copy-array Heap "ff 0/subop/increment" %eax) +18555 # convert +18556 c7 0/subop/copy *Curr-block-depth 0/imm32 +18557 (emit-subx-stmt _test-output-buffered-file %esi %ebx Stderr 0) +18558 (flush _test-output-buffered-file) +18559 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +18565 # check output +18566 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-stmt-select-primitive-2") +18567 # . epilogue +18568 89/<- %esp 5/r32/ebp +18569 5d/pop-to-ebp +18570 c3/return +18571 +18572 test-increment-register: +18573 # Select the right register between overloads. +18574 # foo <- increment +18575 # => +18576 # 50/increment-eax +18577 # +18578 # There's a variable on the var stack as follows: +18579 # name: 'foo' +18580 # type: int +18581 # register: 'eax' +18582 # +18583 # Primitives are the global definitions. +18584 # +18585 # . prologue +18586 55/push-ebp +18587 89/<- %ebp 4/r32/esp +18588 # setup +18589 (clear-stream _test-output-stream) +18590 (clear-stream $_test-output-buffered-file->buffer) +18591 $test-increment-register:initialize-type: +18592 # var type/ecx: (payload tree type-id) = int +18593 68/push 0/imm32/right:null +18594 68/push 0/imm32/right:null +18595 68/push 0/imm32/left:unused +18596 68/push 1/imm32/value:int +18597 68/push 1/imm32/is-atom?:true +18598 68/push 0x11/imm32/alloc-id:fake:payload +18599 89/<- %ecx 4/r32/esp +18600 $test-increment-register:initialize-var: +18601 # var var-foo/ecx: (payload var) +18602 68/push 0/imm32/register +18603 68/push 0/imm32/register +18604 68/push 0/imm32/no-stack-offset +18605 68/push 1/imm32/block-depth +18606 51/push-ecx +18607 68/push 0x11/imm32/alloc-id:fake +18608 68/push 0/imm32/name +18609 68/push 0/imm32/name +18610 68/push 0x11/imm32/alloc-id:fake:payload +18611 89/<- %ecx 4/r32/esp +18612 $test-increment-register:initialize-var-name: +18613 # var-foo->name = "foo" +18614 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +18615 (copy-array Heap "foo" %eax) +18616 $test-increment-register:initialize-var-register: +18617 # var-foo->register = "eax" +18618 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +18619 (copy-array Heap "eax" %eax) +18620 $test-increment-register:initialize-stmt-var: +18621 # var operand/ebx: (payload stmt-var) +18622 68/push 0/imm32/is-deref:false +18623 68/push 0/imm32/next +18624 68/push 0/imm32/next +18625 51/push-ecx/var-foo +18626 68/push 0x11/imm32/alloc-id:fake +18627 68/push 0x11/imm32/alloc-id:fake:payload +18628 89/<- %ebx 4/r32/esp +18629 $test-increment-register:initialize-stmt: +18630 # var stmt/esi: (addr statement) +18631 53/push-ebx/outputs +18632 68/push 0x11/imm32/alloc-id:fake +18633 68/push 0/imm32/no-inouts +18634 68/push 0/imm32/no-inouts +18635 68/push 0/imm32/operation +18636 68/push 0/imm32/operation +18637 68/push 1/imm32 +18638 89/<- %esi 4/r32/esp +18639 $test-increment-register:initialize-stmt-operation: +18640 # stmt->operation = "increment" +18641 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +18642 (copy-array Heap "increment" %eax) +18643 # convert +18644 c7 0/subop/copy *Curr-block-depth 0/imm32 +18645 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +18646 (flush _test-output-buffered-file) +18647 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +18653 # check output +18654 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") +18655 # . epilogue +18656 89/<- %esp 5/r32/ebp +18657 5d/pop-to-ebp +18658 c3/return +18659 +18660 test-add-reg-to-reg: +18661 # var1/reg <- add var2/reg +18662 # => +18663 # 01/add-to %var1 var2 +18664 # +18665 # . prologue +18666 55/push-ebp +18667 89/<- %ebp 4/r32/esp +18668 # setup +18669 (clear-stream _test-output-stream) +18670 (clear-stream $_test-output-buffered-file->buffer) +18671 $test-add-reg-to-reg:initialize-type: +18672 # var type/ecx: (payload tree type-id) = int +18673 68/push 0/imm32/right:null +18674 68/push 0/imm32/right:null +18675 68/push 0/imm32/left:unused +18676 68/push 1/imm32/value:int +18677 68/push 1/imm32/is-atom?:true +18678 68/push 0x11/imm32/alloc-id:fake:payload +18679 89/<- %ecx 4/r32/esp +18680 $test-add-reg-to-reg:initialize-var1: +18681 # var var1/ecx: (payload var) +18682 68/push 0/imm32/register +18683 68/push 0/imm32/register +18684 68/push 0/imm32/no-stack-offset +18685 68/push 1/imm32/block-depth +18686 51/push-ecx +18687 68/push 0x11/imm32/alloc-id:fake +18688 68/push 0/imm32/name +18689 68/push 0/imm32/name +18690 68/push 0x11/imm32/alloc-id:fake:payload +18691 89/<- %ecx 4/r32/esp +18692 $test-add-reg-to-reg:initialize-var1-name: +18693 # var1->name = "var1" +18694 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +18695 (copy-array Heap "var1" %eax) +18696 $test-add-reg-to-reg:initialize-var1-register: +18697 # var1->register = "eax" +18698 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +18699 (copy-array Heap "eax" %eax) +18700 $test-add-reg-to-reg:initialize-var2: +18701 # var var2/edx: (payload var) +18702 68/push 0/imm32/register +18703 68/push 0/imm32/register +18704 68/push 0/imm32/no-stack-offset +18705 68/push 1/imm32/block-depth +18706 ff 6/subop/push *(ecx+0x10) +18707 68/push 0x11/imm32/alloc-id:fake +18708 68/push 0/imm32/name +18709 68/push 0/imm32/name +18710 68/push 0x11/imm32/alloc-id:fake:payload +18711 89/<- %edx 4/r32/esp +18712 $test-add-reg-to-reg:initialize-var2-name: +18713 # var2->name = "var2" +18714 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +18715 (copy-array Heap "var2" %eax) +18716 $test-add-reg-to-reg:initialize-var2-register: +18717 # var2->register = "ecx" +18718 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +18719 (copy-array Heap "ecx" %eax) +18720 $test-add-reg-to-reg:initialize-inouts: +18721 # var inouts/esi: (payload stmt-var) = [var2] +18722 68/push 0/imm32/is-deref:false +18723 68/push 0/imm32/next +18724 68/push 0/imm32/next +18725 52/push-edx/var2 +18726 68/push 0x11/imm32/alloc-id:fake +18727 68/push 0x11/imm32/alloc-id:fake:payload +18728 89/<- %esi 4/r32/esp +18729 $test-add-reg-to-reg:initialize-outputs: +18730 # var outputs/edi: (payload stmt-var) = [var1] +18731 68/push 0/imm32/is-deref:false +18732 68/push 0/imm32/next +18733 68/push 0/imm32/next +18734 51/push-ecx/var1 +18735 68/push 0x11/imm32/alloc-id:fake +18736 68/push 0x11/imm32/alloc-id:fake:payload +18737 89/<- %edi 4/r32/esp +18738 $test-add-reg-to-reg:initialize-stmt: +18739 # var stmt/esi: (addr statement) +18740 68/push 0/imm32/next +18741 68/push 0/imm32/next +18742 57/push-edi/outputs +18743 68/push 0x11/imm32/alloc-id:fake +18744 56/push-esi/inouts +18745 68/push 0x11/imm32/alloc-id:fake +18746 68/push 0/imm32/operation +18747 68/push 0/imm32/operation +18748 68/push 1/imm32/tag:stmt1 +18749 89/<- %esi 4/r32/esp +18750 $test-add-reg-to-reg:initialize-stmt-operation: +18751 # stmt->operation = "add" +18752 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +18753 (copy-array Heap "add" %eax) +18754 # convert +18755 c7 0/subop/copy *Curr-block-depth 0/imm32 +18756 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +18757 (flush _test-output-buffered-file) +18758 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +18764 # check output +18765 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") +18766 # . epilogue +18767 89/<- %esp 5/r32/ebp +18768 5d/pop-to-ebp +18769 c3/return +18770 +18771 test-add-reg-to-mem: +18772 # add-to var1 var2/reg +18773 # => +18774 # 01/add-to *(ebp+__) var2 +18775 # +18776 # . prologue +18777 55/push-ebp +18778 89/<- %ebp 4/r32/esp +18779 # setup +18780 (clear-stream _test-output-stream) +18781 (clear-stream $_test-output-buffered-file->buffer) +18782 $test-add-reg-to-mem:initialize-type: +18783 # var type/ecx: (payload tree type-id) = int +18784 68/push 0/imm32/right:null +18785 68/push 0/imm32/right:null +18786 68/push 0/imm32/left:unused +18787 68/push 1/imm32/value:int +18788 68/push 1/imm32/is-atom?:true +18789 68/push 0x11/imm32/alloc-id:fake:payload +18790 89/<- %ecx 4/r32/esp +18791 $test-add-reg-to-mem:initialize-var1: +18792 # var var1/ecx: (payload var) +18793 68/push 0/imm32/register +18794 68/push 0/imm32/register +18795 68/push 8/imm32/stack-offset +18796 68/push 1/imm32/block-depth +18797 51/push-ecx +18798 68/push 0x11/imm32/alloc-id:fake +18799 68/push 0/imm32/name +18800 68/push 0/imm32/name +18801 68/push 0x11/imm32/alloc-id:fake:payload +18802 89/<- %ecx 4/r32/esp +18803 $test-add-reg-to-mem:initialize-var1-name: +18804 # var1->name = "var1" +18805 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +18806 (copy-array Heap "var1" %eax) +18807 $test-add-reg-to-mem:initialize-var2: +18808 # var var2/edx: (payload var) +18809 68/push 0/imm32/register +18810 68/push 0/imm32/register +18811 68/push 0/imm32/no-stack-offset +18812 68/push 1/imm32/block-depth +18813 ff 6/subop/push *(ecx+0x10) +18814 68/push 0x11/imm32/alloc-id:fake +18815 68/push 0/imm32/name +18816 68/push 0/imm32/name +18817 68/push 0x11/imm32/alloc-id:fake:payload +18818 89/<- %edx 4/r32/esp +18819 $test-add-reg-to-mem:initialize-var2-name: +18820 # var2->name = "var2" +18821 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +18822 (copy-array Heap "var2" %eax) +18823 $test-add-reg-to-mem:initialize-var2-register: +18824 # var2->register = "ecx" +18825 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +18826 (copy-array Heap "ecx" %eax) +18827 $test-add-reg-to-mem:initialize-inouts: +18828 # var inouts/esi: (payload stmt-var) = [var2] +18829 68/push 0/imm32/is-deref:false +18830 68/push 0/imm32/next +18831 68/push 0/imm32/next +18832 52/push-edx/var2 +18833 68/push 0x11/imm32/alloc-id:fake +18834 68/push 0x11/imm32/alloc-id:fake:payload +18835 89/<- %esi 4/r32/esp +18836 # inouts = [var1, var2] +18837 68/push 0/imm32/is-deref:false +18838 56/push-esi/next +18839 68/push 0x11/imm32/alloc-id:fake +18840 51/push-ecx/var1 +18841 68/push 0x11/imm32/alloc-id:fake +18842 68/push 0x11/imm32/alloc-id:fake:payload +18843 89/<- %esi 4/r32/esp +18844 $test-add-reg-to-mem:initialize-stmt: +18845 # var stmt/esi: (addr statement) +18846 68/push 0/imm32/next +18847 68/push 0/imm32/next +18848 68/push 0/imm32/outputs +18849 68/push 0/imm32/outputs +18850 56/push-esi/inouts +18851 68/push 0x11/imm32/alloc-id:fake +18852 68/push 0/imm32/operation +18853 68/push 0/imm32/operation +18854 68/push 1/imm32/tag:stmt1 +18855 89/<- %esi 4/r32/esp +18856 $test-add-reg-to-mem:initialize-stmt-operation: +18857 # stmt->operation = "add-to" +18858 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +18859 (copy-array Heap "add-to" %eax) +18860 # convert +18861 c7 0/subop/copy *Curr-block-depth 0/imm32 +18862 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +18863 (flush _test-output-buffered-file) +18864 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +18870 # check output +18871 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") +18872 # . epilogue +18873 89/<- %esp 5/r32/ebp +18874 5d/pop-to-ebp +18875 c3/return +18876 +18877 test-add-mem-to-reg: +18878 # var1/reg <- add var2 +18879 # => +18880 # 03/add *(ebp+__) var1 +18881 # +18882 # . prologue +18883 55/push-ebp +18884 89/<- %ebp 4/r32/esp +18885 # setup +18886 (clear-stream _test-output-stream) +18887 (clear-stream $_test-output-buffered-file->buffer) +18888 $test-add-mem-to-reg:initialize-type: +18889 # var type/ecx: (payload tree type-id) = int +18890 68/push 0/imm32/right:null +18891 68/push 0/imm32/right:null +18892 68/push 0/imm32/left:unused +18893 68/push 1/imm32/value:int +18894 68/push 1/imm32/is-atom?:true +18895 68/push 0x11/imm32/alloc-id:fake:payload +18896 89/<- %ecx 4/r32/esp +18897 $test-add-mem-to-reg:initialize-var: +18898 # var var1/ecx: (payload var) +18899 68/push 0/imm32/register +18900 68/push 0/imm32/register +18901 68/push 0/imm32/no-stack-offset +18902 68/push 1/imm32/block-depth +18903 51/push-ecx +18904 68/push 0x11/imm32/alloc-id:fake +18905 68/push 0/imm32/name +18906 68/push 0/imm32/name +18907 68/push 0x11/imm32/alloc-id:fake:payload +18908 89/<- %ecx 4/r32/esp +18909 $test-add-mem-to-reg:initialize-var-name: +18910 # var1->name = "foo" +18911 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +18912 (copy-array Heap "var1" %eax) +18913 $test-add-mem-to-reg:initialize-var-register: +18914 # var1->register = "eax" +18915 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +18916 (copy-array Heap "eax" %eax) +18917 $test-add-mem-to-reg:initialize-var2: +18918 # var var2/edx: (payload var) +18919 68/push 0/imm32/register +18920 68/push 0/imm32/register +18921 68/push 8/imm32/stack-offset +18922 68/push 1/imm32/block-depth +18923 ff 6/subop/push *(ecx+0x10) +18924 68/push 0x11/imm32/alloc-id:fake +18925 68/push 0/imm32/name +18926 68/push 0/imm32/name +18927 68/push 0x11/imm32/alloc-id:fake:payload +18928 89/<- %edx 4/r32/esp +18929 $test-add-mem-to-reg:initialize-var2-name: +18930 # var2->name = "var2" +18931 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +18932 (copy-array Heap "var2" %eax) +18933 $test-add-mem-to-reg:initialize-inouts: +18934 # var inouts/esi: (payload stmt-var) = [var2] +18935 68/push 0/imm32/is-deref:false +18936 68/push 0/imm32/next +18937 68/push 0/imm32/next +18938 52/push-edx/var2 +18939 68/push 0x11/imm32/alloc-id:fake +18940 68/push 0x11/imm32/alloc-id:fake:payload +18941 89/<- %esi 4/r32/esp +18942 $test-add-mem-to-reg:initialize-outputs: +18943 # var outputs/edi: (payload stmt-var) = [var1] +18944 68/push 0/imm32/is-deref:false +18945 68/push 0/imm32/next +18946 68/push 0/imm32/next +18947 51/push-ecx/var1 +18948 68/push 0x11/imm32/alloc-id:fake +18949 68/push 0x11/imm32/alloc-id:fake:payload +18950 89/<- %edi 4/r32/esp +18951 $test-add-mem-to-reg:initialize-stmt: +18952 # var stmt/esi: (addr statement) +18953 68/push 0/imm32/next +18954 68/push 0/imm32/next +18955 57/push-edi/outputs +18956 68/push 0x11/imm32/alloc-id:fake +18957 56/push-esi/inouts +18958 68/push 0x11/imm32/alloc-id:fake +18959 68/push 0/imm32/operation +18960 68/push 0/imm32/operation +18961 68/push 1/imm32/tag:stmt1 +18962 89/<- %esi 4/r32/esp +18963 $test-add-mem-to-reg:initialize-stmt-operation: +18964 # stmt->operation = "add" +18965 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +18966 (copy-array Heap "add" %eax) +18967 # convert +18968 c7 0/subop/copy *Curr-block-depth 0/imm32 +18969 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +18970 (flush _test-output-buffered-file) +18971 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +18977 # check output +18978 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") +18979 # . epilogue +18980 89/<- %esp 5/r32/ebp +18981 5d/pop-to-ebp +18982 c3/return +18983 +18984 test-add-literal-to-eax: +18985 # var1/eax <- add 0x34 +18986 # => +18987 # 05/add-to-eax 0x34/imm32 +18988 # +18989 # . prologue +18990 55/push-ebp +18991 89/<- %ebp 4/r32/esp +18992 # setup +18993 (clear-stream _test-output-stream) +18994 (clear-stream $_test-output-buffered-file->buffer) +18995 $test-add-literal-to-eax:initialize-var-type: +18996 # var type/ecx: (payload tree type-id) = int +18997 68/push 0/imm32/right:null +18998 68/push 0/imm32/right:null +18999 68/push 0/imm32/left:unused +19000 68/push 1/imm32/value:int +19001 68/push 1/imm32/is-atom?:true +19002 68/push 0x11/imm32/alloc-id:fake:payload +19003 89/<- %ecx 4/r32/esp +19004 $test-add-literal-to-eax:initialize-var: +19005 # var v/ecx: (payload var) +19006 68/push 0/imm32/register +19007 68/push 0/imm32/register +19008 68/push 0/imm32/no-stack-offset +19009 68/push 1/imm32/block-depth +19010 51/push-ecx +19011 68/push 0x11/imm32/alloc-id:fake +19012 68/push 0/imm32/name +19013 68/push 0/imm32/name +19014 68/push 0x11/imm32/alloc-id:fake:payload +19015 89/<- %ecx 4/r32/esp +19016 $test-add-literal-to-eax:initialize-var-name: +19017 # v->name = "v" +19018 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +19019 (copy-array Heap "v" %eax) +19020 $test-add-literal-to-eax:initialize-var-register: +19021 # v->register = "eax" +19022 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +19023 (copy-array Heap "eax" %eax) +19024 $test-add-literal-to-eax:initialize-literal-type: +19025 # var type/edx: (payload tree type-id) = literal +19026 68/push 0/imm32/right:null +19027 68/push 0/imm32/right:null +19028 68/push 0/imm32/left:unused +19029 68/push 0/imm32/value:literal +19030 68/push 1/imm32/is-atom?:true +19031 68/push 0x11/imm32/alloc-id:fake:payload +19032 89/<- %edx 4/r32/esp +19033 $test-add-literal-to-eax:initialize-literal: +19034 # var l/edx: (payload var) +19035 68/push 0/imm32/register +19036 68/push 0/imm32/register +19037 68/push 0/imm32/no-stack-offset +19038 68/push 1/imm32/block-depth +19039 52/push-edx +19040 68/push 0x11/imm32/alloc-id:fake +19041 68/push 0/imm32/name +19042 68/push 0/imm32/name +19043 68/push 0x11/imm32/alloc-id:fake:payload +19044 89/<- %edx 4/r32/esp +19045 $test-add-literal-to-eax:initialize-literal-value: +19046 # l->name = "0x34" +19047 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +19048 (copy-array Heap "0x34" %eax) +19049 $test-add-literal-to-eax:initialize-inouts: +19050 # var inouts/esi: (payload stmt-var) = [l] +19051 68/push 0/imm32/is-deref:false +19052 68/push 0/imm32/next +19053 68/push 0/imm32/next +19054 52/push-edx/l +19055 68/push 0x11/imm32/alloc-id:fake +19056 68/push 0x11/imm32/alloc-id:fake:payload +19057 89/<- %esi 4/r32/esp +19058 $test-add-literal-to-eax:initialize-outputs: +19059 # var outputs/edi: (payload stmt-var) = [v] +19060 68/push 0/imm32/is-deref:false +19061 68/push 0/imm32/next +19062 68/push 0/imm32/next +19063 51/push-ecx/v +19064 68/push 0x11/imm32/alloc-id:fake +19065 68/push 0x11/imm32/alloc-id:fake:payload +19066 89/<- %edi 4/r32/esp +19067 $test-add-literal-to-eax:initialize-stmt: +19068 # var stmt/esi: (addr statement) +19069 68/push 0/imm32/next +19070 68/push 0/imm32/next +19071 57/push-edi/outputs +19072 68/push 0x11/imm32/alloc-id:fake +19073 56/push-esi/inouts +19074 68/push 0x11/imm32/alloc-id:fake +19075 68/push 0/imm32/operation +19076 68/push 0/imm32/operation +19077 68/push 1/imm32/tag:stmt1 +19078 89/<- %esi 4/r32/esp +19079 $test-add-literal-to-eax:initialize-stmt-operation: +19080 # stmt->operation = "add" +19081 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +19082 (copy-array Heap "add" %eax) +19083 # convert +19084 c7 0/subop/copy *Curr-block-depth 0/imm32 +19085 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +19086 (flush _test-output-buffered-file) +19087 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +19093 # check output +19094 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") +19095 # . epilogue +19096 89/<- %esp 5/r32/ebp +19097 5d/pop-to-ebp +19098 c3/return +19099 +19100 test-add-literal-to-reg: +19101 # var1/ecx <- add 0x34 +19102 # => +19103 # 81 0/subop/add %ecx 0x34/imm32 +19104 # +19105 # . prologue +19106 55/push-ebp +19107 89/<- %ebp 4/r32/esp +19108 # setup +19109 (clear-stream _test-output-stream) +19110 (clear-stream $_test-output-buffered-file->buffer) +19111 $test-add-literal-to-reg:initialize-var-type: +19112 # var type/ecx: (payload tree type-id) = int +19113 68/push 0/imm32/right:null +19114 68/push 0/imm32/right:null +19115 68/push 0/imm32/left:unused +19116 68/push 1/imm32/value:int +19117 68/push 1/imm32/is-atom?:true +19118 68/push 0x11/imm32/alloc-id:fake:payload +19119 89/<- %ecx 4/r32/esp +19120 $test-add-literal-to-reg:initialize-var: +19121 # var v/ecx: (payload var) +19122 68/push 0/imm32/register +19123 68/push 0/imm32/register +19124 68/push 0/imm32/no-stack-offset +19125 68/push 1/imm32/block-depth +19126 51/push-ecx +19127 68/push 0x11/imm32/alloc-id:fake +19128 68/push 0/imm32/name +19129 68/push 0/imm32/name +19130 68/push 0x11/imm32/alloc-id:fake:payload +19131 89/<- %ecx 4/r32/esp +19132 $test-add-literal-to-reg:initialize-var-name: +19133 # v->name = "v" +19134 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +19135 (copy-array Heap "v" %eax) +19136 $test-add-literal-to-reg:initialize-var-register: +19137 # v->register = "ecx" +19138 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +19139 (copy-array Heap "ecx" %eax) +19140 $test-add-literal-to-reg:initialize-literal-type: +19141 # var type/edx: (payload tree type-id) = literal +19142 68/push 0/imm32/right:null +19143 68/push 0/imm32/right:null +19144 68/push 0/imm32/left:unused +19145 68/push 0/imm32/value:literal +19146 68/push 1/imm32/is-atom?:true +19147 68/push 0x11/imm32/alloc-id:fake:payload +19148 89/<- %edx 4/r32/esp +19149 $test-add-literal-to-reg:initialize-literal: +19150 # var l/edx: (payload var) +19151 68/push 0/imm32/register +19152 68/push 0/imm32/register +19153 68/push 0/imm32/no-stack-offset +19154 68/push 1/imm32/block-depth +19155 52/push-edx +19156 68/push 0x11/imm32/alloc-id:fake +19157 68/push 0/imm32/name +19158 68/push 0/imm32/name +19159 68/push 0x11/imm32/alloc-id:fake:payload +19160 89/<- %edx 4/r32/esp +19161 $test-add-literal-to-reg:initialize-literal-value: +19162 # l->name = "0x34" +19163 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +19164 (copy-array Heap "0x34" %eax) +19165 $test-add-literal-to-reg:initialize-inouts: +19166 # var inouts/esi: (payload stmt-var) = [l] +19167 68/push 0/imm32/is-deref:false +19168 68/push 0/imm32/next +19169 68/push 0/imm32/next +19170 52/push-edx/l +19171 68/push 0x11/imm32/alloc-id:fake +19172 68/push 0x11/imm32/alloc-id:fake:payload +19173 89/<- %esi 4/r32/esp +19174 $test-add-literal-to-reg:initialize-outputs: +19175 # var outputs/edi: (payload stmt-var) = [v] +19176 68/push 0/imm32/is-deref:false +19177 68/push 0/imm32/next +19178 68/push 0/imm32/next +19179 51/push-ecx/v +19180 68/push 0x11/imm32/alloc-id:fake +19181 68/push 0x11/imm32/alloc-id:fake:payload +19182 89/<- %edi 4/r32/esp +19183 $test-add-literal-to-reg:initialize-stmt: +19184 # var stmt/esi: (addr statement) +19185 68/push 0/imm32/next +19186 68/push 0/imm32/next +19187 57/push-edi/outputs +19188 68/push 0x11/imm32/alloc-id:fake +19189 56/push-esi/inouts +19190 68/push 0x11/imm32/alloc-id:fake +19191 68/push 0/imm32/operation +19192 68/push 0/imm32/operation +19193 68/push 1/imm32/tag:stmt1 +19194 89/<- %esi 4/r32/esp +19195 $test-add-literal-to-reg:initialize-stmt-operation: +19196 # stmt->operation = "add" +19197 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +19198 (copy-array Heap "add" %eax) +19199 # convert +19200 c7 0/subop/copy *Curr-block-depth 0/imm32 +19201 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +19202 (flush _test-output-buffered-file) +19203 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +19209 # check output +19210 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") +19211 # . epilogue +19212 89/<- %esp 5/r32/ebp +19213 5d/pop-to-ebp +19214 c3/return +19215 +19216 test-add-literal-to-mem: +19217 # add-to var1, 0x34 +19218 # => +19219 # 81 0/subop/add %eax 0x34/imm32 +19220 # +19221 # . prologue +19222 55/push-ebp +19223 89/<- %ebp 4/r32/esp +19224 # setup +19225 (clear-stream _test-output-stream) +19226 (clear-stream $_test-output-buffered-file->buffer) +19227 $test-add-literal-to-mem:initialize-type: +19228 # var type/ecx: (payload tree type-id) = int +19229 68/push 0/imm32/right:null +19230 68/push 0/imm32/right:null +19231 68/push 0/imm32/left:unused +19232 68/push 1/imm32/value:int +19233 68/push 1/imm32/is-atom?:true +19234 68/push 0x11/imm32/alloc-id:fake:payload +19235 89/<- %ecx 4/r32/esp +19236 $test-add-literal-to-mem:initialize-var1: +19237 # var var1/ecx: (payload var) +19238 68/push 0/imm32/register +19239 68/push 0/imm32/register +19240 68/push 8/imm32/stack-offset +19241 68/push 1/imm32/block-depth +19242 51/push-ecx +19243 68/push 0x11/imm32/alloc-id:fake +19244 68/push 0/imm32/name +19245 68/push 0/imm32/name +19246 68/push 0x11/imm32/alloc-id:fake:payload +19247 89/<- %ecx 4/r32/esp +19248 $test-add-literal-to-mem:initialize-var1-name: +19249 # var1->name = "var1" +19250 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +19251 (copy-array Heap "var1" %eax) +19252 $test-add-literal-to-mem:initialize-literal-type: +19253 # var type/edx: (payload tree type-id) = literal +19254 68/push 0/imm32/right:null +19255 68/push 0/imm32/right:null +19256 68/push 0/imm32/left:unused +19257 68/push 0/imm32/value:literal +19258 68/push 1/imm32/is-atom?:true +19259 68/push 0x11/imm32/alloc-id:fake:payload +19260 89/<- %edx 4/r32/esp +19261 $test-add-literal-to-mem:initialize-literal: +19262 # var l/edx: (payload var) +19263 68/push 0/imm32/register +19264 68/push 0/imm32/register +19265 68/push 0/imm32/no-stack-offset +19266 68/push 1/imm32/block-depth +19267 52/push-edx +19268 68/push 0x11/imm32/alloc-id:fake +19269 68/push 0/imm32/name +19270 68/push 0/imm32/name +19271 68/push 0x11/imm32/alloc-id:fake:payload +19272 89/<- %edx 4/r32/esp +19273 $test-add-literal-to-mem:initialize-literal-value: +19274 # l->name = "0x34" +19275 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +19276 (copy-array Heap "0x34" %eax) +19277 $test-add-literal-to-mem:initialize-inouts: +19278 # var inouts/esi: (payload stmt-var) = [l] +19279 68/push 0/imm32/is-deref:false +19280 68/push 0/imm32/next +19281 68/push 0/imm32/next +19282 52/push-edx/l +19283 68/push 0x11/imm32/alloc-id:fake +19284 68/push 0x11/imm32/alloc-id:fake:payload +19285 89/<- %esi 4/r32/esp +19286 # var inouts = (handle stmt-var) = [var1, var2] +19287 68/push 0/imm32/is-deref:false +19288 56/push-esi/next +19289 68/push 0x11/imm32/alloc-id:fake +19290 51/push-ecx/var1 +19291 68/push 0x11/imm32/alloc-id:fake +19292 68/push 0x11/imm32/alloc-id:fake:payload +19293 89/<- %esi 4/r32/esp +19294 $test-add-literal-to-mem:initialize-stmt: +19295 # var stmt/esi: (addr statement) +19296 68/push 0/imm32/next +19297 68/push 0/imm32/next +19298 68/push 0/imm32/outputs +19299 68/push 0/imm32/outputs +19300 56/push-esi/inouts +19301 68/push 0x11/imm32/alloc-id:fake +19302 68/push 0/imm32/operation +19303 68/push 0/imm32/operation +19304 68/push 1/imm32/tag:stmt1 +19305 89/<- %esi 4/r32/esp +19306 $test-add-literal-to-mem:initialize-stmt-operation: +19307 # stmt->operation = "add-to" +19308 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +19309 (copy-array Heap "add-to" %eax) +19310 # convert +19311 c7 0/subop/copy *Curr-block-depth 0/imm32 +19312 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +19313 (flush _test-output-buffered-file) +19314 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +19320 # check output +19321 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") +19322 # . epilogue +19323 89/<- %esp 5/r32/ebp +19324 5d/pop-to-ebp +19325 c3/return +19326 +19327 test-compare-reg-with-reg: +19328 # compare var1/ecx, var2/eax +19329 # => +19330 # 39/compare %ecx 0/r32/eax +19331 # +19332 # . prologue +19333 55/push-ebp +19334 89/<- %ebp 4/r32/esp +19335 # setup +19336 (clear-stream _test-output-stream) +19337 (clear-stream $_test-output-buffered-file->buffer) +19338 $test-compare-reg-with-reg:initialize-type: +19339 # var type/ecx: (payload tree type-id) = int +19340 68/push 0/imm32/right:null +19341 68/push 0/imm32/right:null +19342 68/push 0/imm32/left:unused +19343 68/push 1/imm32/value:int +19344 68/push 1/imm32/is-atom?:true +19345 68/push 0x11/imm32/alloc-id:fake:payload +19346 89/<- %ecx 4/r32/esp +19347 $test-compare-reg-with-reg:initialize-var1: +19348 # var var1/ecx: (payload var) +19349 68/push 0/imm32/register +19350 68/push 0/imm32/register +19351 68/push 0/imm32/no-stack-offset +19352 68/push 1/imm32/block-depth +19353 51/push-ecx +19354 68/push 0x11/imm32/alloc-id:fake +19355 68/push 0/imm32/name +19356 68/push 0/imm32/name +19357 68/push 0x11/imm32/alloc-id:fake:payload +19358 89/<- %ecx 4/r32/esp +19359 $test-compare-reg-with-reg:initialize-var1-name: +19360 # var1->name = "var1" +19361 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +19362 (copy-array Heap "var1" %eax) +19363 $test-compare-reg-with-reg:initialize-var1-register: +19364 # var1->register = "ecx" +19365 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +19366 (copy-array Heap "ecx" %eax) +19367 $test-compare-reg-with-reg:initialize-var2: +19368 # var var2/edx: (payload var) +19369 68/push 0/imm32/register +19370 68/push 0/imm32/register +19371 68/push 0/imm32/no-stack-offset +19372 68/push 1/imm32/block-depth +19373 ff 6/subop/push *(ecx+0x10) +19374 68/push 0x11/imm32/alloc-id:fake +19375 68/push 0/imm32/name +19376 68/push 0/imm32/name +19377 68/push 0x11/imm32/alloc-id:fake:payload +19378 89/<- %edx 4/r32/esp +19379 $test-compare-reg-with-reg:initialize-var2-name: +19380 # var2->name = "var2" +19381 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +19382 (copy-array Heap "var2" %eax) +19383 $test-compare-reg-with-reg:initialize-var2-register: +19384 # var2->register = "eax" +19385 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +19386 (copy-array Heap "eax" %eax) +19387 $test-compare-reg-with-reg:initialize-inouts: +19388 # var inouts/esi: (payload stmt-var) = [var2] +19389 68/push 0/imm32/is-deref:false +19390 68/push 0/imm32/next +19391 68/push 0/imm32/next +19392 52/push-edx/var2 +19393 68/push 0x11/imm32/alloc-id:fake +19394 68/push 0x11/imm32/alloc-id:fake:payload +19395 89/<- %esi 4/r32/esp +19396 # inouts = [var1, var2] +19397 68/push 0/imm32/is-deref:false +19398 56/push-esi/next +19399 68/push 0x11/imm32/alloc-id:fake +19400 51/push-ecx/var1 +19401 68/push 0x11/imm32/alloc-id:fake +19402 68/push 0x11/imm32/alloc-id:fake:payload +19403 89/<- %esi 4/r32/esp +19404 $test-compare-reg-with-reg:initialize-stmt: +19405 # var stmt/esi: (addr statement) +19406 68/push 0/imm32/next +19407 68/push 0/imm32/next +19408 68/push 0/imm32/outputs +19409 68/push 0/imm32/outputs +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-compare-reg-with-reg:initialize-stmt-operation: +19417 # stmt->operation = "compare" +19418 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +19419 (copy-array Heap "compare" %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 "39/compare-> %ecx 0x00000000/r32" "F - test-compare-reg-with-reg") +19432 # . epilogue +19433 89/<- %esp 5/r32/ebp +19434 5d/pop-to-ebp +19435 c3/return +19436 +19437 test-compare-mem-with-reg: +19438 # compare var1, var2/eax +19439 # => +19440 # 39/compare *(ebp+___) 0/r32/eax +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-compare-mem-with-reg:initialize-type: +19449 # var type/ecx: (payload tree type-id) = 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-compare-mem-with-reg:initialize-var1: +19458 # var var1/ecx: (payload var) +19459 68/push 0/imm32/register +19460 68/push 0/imm32/register +19461 68/push 8/imm32/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-compare-mem-with-reg:initialize-var1-name: +19470 # var1->name = "var1" +19471 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +19472 (copy-array Heap "var1" %eax) +19473 $test-compare-mem-with-reg:initialize-var2: +19474 # var var2/edx: (payload var) +19475 68/push 0/imm32/register +19476 68/push 0/imm32/register +19477 68/push 0/imm32/no-stack-offset +19478 68/push 1/imm32/block-depth +19479 ff 6/subop/push *(ecx+0x10) +19480 68/push 0x11/imm32/alloc-id:fake +19481 68/push 0/imm32/name +19482 68/push 0/imm32/name +19483 68/push 0x11/imm32/alloc-id:fake:payload +19484 89/<- %edx 4/r32/esp +19485 $test-compare-mem-with-reg:initialize-var2-name: +19486 # var2->name = "var2" +19487 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +19488 (copy-array Heap "var2" %eax) +19489 $test-compare-mem-with-reg:initialize-var2-register: +19490 # var2->register = "eax" +19491 8d/copy-address *(edx+0x1c) 0/r32/eax # Var-register + 4 +19492 (copy-array Heap "eax" %eax) +19493 $test-compare-mem-with-reg:initialize-inouts: +19494 # var inouts/esi: (payload stmt-var) = [var2] +19495 68/push 0/imm32/is-deref:false +19496 68/push 0/imm32/next +19497 68/push 0/imm32/next +19498 52/push-edx/var2 +19499 68/push 0x11/imm32/alloc-id:fake +19500 68/push 0x11/imm32/alloc-id:fake:payload +19501 89/<- %esi 4/r32/esp +19502 # inouts = [var1, var2] +19503 68/push 0/imm32/is-deref:false +19504 56/push-esi/next +19505 68/push 0x11/imm32/alloc-id:fake +19506 51/push-ecx/var1 +19507 68/push 0x11/imm32/alloc-id:fake +19508 68/push 0x11/imm32/alloc-id:fake:payload +19509 89/<- %esi 4/r32/esp +19510 $test-compare-mem-with-reg:initialize-stmt: +19511 # var stmt/esi: (addr statement) +19512 68/push 0/imm32/next +19513 68/push 0/imm32/next +19514 68/push 0/imm32/outputs +19515 68/push 0/imm32/outputs +19516 56/push-esi/inouts +19517 68/push 0x11/imm32/alloc-id:fake +19518 68/push 0/imm32/operation +19519 68/push 0/imm32/operation +19520 68/push 1/imm32/tag:stmt1 +19521 89/<- %esi 4/r32/esp +19522 $test-compare-mem-with-reg:initialize-stmt-operation: +19523 # stmt->operation = "compare" +19524 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +19525 (copy-array Heap "compare" %eax) +19526 # convert +19527 c7 0/subop/copy *Curr-block-depth 0/imm32 +19528 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +19529 (flush _test-output-buffered-file) +19530 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +19536 # check output +19537 (check-next-stream-line-equal _test-output-stream "39/compare-> *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg") +19538 # . epilogue +19539 89/<- %esp 5/r32/ebp +19540 5d/pop-to-ebp +19541 c3/return +19542 +19543 test-compare-reg-with-mem: +19544 # compare var1/eax, var2 +19545 # => +19546 # 3b/compare<- *(ebp+___) 0/r32/eax +19547 # +19548 # . prologue +19549 55/push-ebp +19550 89/<- %ebp 4/r32/esp +19551 # setup +19552 (clear-stream _test-output-stream) +19553 (clear-stream $_test-output-buffered-file->buffer) +19554 $test-compare-reg-with-mem:initialize-type: +19555 # var type/ecx: (payload tree type-id) = int +19556 68/push 0/imm32/right:null +19557 68/push 0/imm32/right:null +19558 68/push 0/imm32/left:unused +19559 68/push 1/imm32/value:int +19560 68/push 1/imm32/is-atom?:true +19561 68/push 0x11/imm32/alloc-id:fake:payload +19562 89/<- %ecx 4/r32/esp +19563 $test-compare-reg-with-mem:initialize-var1: +19564 # var var1/ecx: (payload var) +19565 68/push 0/imm32/register +19566 68/push 0/imm32/register +19567 68/push 0/imm32/no-stack-offset +19568 68/push 1/imm32/block-depth +19569 51/push-ecx +19570 68/push 0x11/imm32/alloc-id:fake +19571 68/push 0/imm32/name +19572 68/push 0/imm32/name +19573 68/push 0x11/imm32/alloc-id:fake:payload +19574 89/<- %ecx 4/r32/esp +19575 $test-compare-reg-with-mem:initialize-var1-name: +19576 # var1->name = "var1" +19577 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +19578 (copy-array Heap "var1" %eax) +19579 $test-compare-reg-with-mem:initialize-var1-register: +19580 # var1->register = "eax" +19581 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +19582 (copy-array Heap "eax" %eax) +19583 $test-compare-reg-with-mem:initialize-var2: +19584 # var var2/edx: (payload var) +19585 68/push 0/imm32/register +19586 68/push 0/imm32/register +19587 68/push 8/imm32/stack-offset +19588 68/push 1/imm32/block-depth +19589 ff 6/subop/push *(ecx+0x10) +19590 68/push 0x11/imm32/alloc-id:fake +19591 68/push 0/imm32/name +19592 68/push 0/imm32/name +19593 68/push 0x11/imm32/alloc-id:fake:payload +19594 89/<- %edx 4/r32/esp +19595 $test-compare-reg-with-mem:initialize-var2-name: +19596 # var2->name = "var2" +19597 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +19598 (copy-array Heap "var2" %eax) +19599 $test-compare-reg-with-mem:initialize-inouts: +19600 # var inouts/esi: (payload stmt-var) = [var2] +19601 68/push 0/imm32/is-deref:false +19602 68/push 0/imm32/next +19603 68/push 0/imm32/next +19604 52/push-edx/var2 +19605 68/push 0x11/imm32/alloc-id:fake +19606 68/push 0x11/imm32/alloc-id:fake:payload +19607 89/<- %esi 4/r32/esp +19608 # inouts = [var1, var2] +19609 68/push 0/imm32/is-deref:false +19610 56/push-esi/next +19611 68/push 0x11/imm32/alloc-id:fake +19612 51/push-ecx/var1 +19613 68/push 0x11/imm32/alloc-id:fake +19614 68/push 0x11/imm32/alloc-id:fake:payload +19615 89/<- %esi 4/r32/esp +19616 $test-compare-reg-with-mem:initialize-stmt: +19617 # var stmt/esi: (addr statement) +19618 68/push 0/imm32/next +19619 68/push 0/imm32/next +19620 68/push 0/imm32/outputs +19621 68/push 0/imm32/outputs +19622 56/push-esi/inouts +19623 68/push 0x11/imm32/alloc-id:fake +19624 68/push 0/imm32/operation +19625 68/push 0/imm32/operation +19626 68/push 1/imm32/tag:stmt1 +19627 89/<- %esi 4/r32/esp +19628 $test-compare-reg-with-mem:initialize-stmt-operation: +19629 # stmt->operation = "compare" +19630 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +19631 (copy-array Heap "compare" %eax) +19632 # convert +19633 c7 0/subop/copy *Curr-block-depth 0/imm32 +19634 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +19635 (flush _test-output-buffered-file) +19636 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +19642 # check output +19643 (check-next-stream-line-equal _test-output-stream "3b/compare<- *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem") +19644 # . epilogue +19645 89/<- %esp 5/r32/ebp +19646 5d/pop-to-ebp +19647 c3/return +19648 +19649 test-compare-mem-with-literal: +19650 # compare var1, 0x34 +19651 # => +19652 # 81 7/subop/compare *(ebp+___) 0x34/imm32 +19653 # +19654 # . prologue +19655 55/push-ebp +19656 89/<- %ebp 4/r32/esp +19657 # setup +19658 (clear-stream _test-output-stream) +19659 (clear-stream $_test-output-buffered-file->buffer) +19660 $test-compare-mem-with-literal:initialize-type: +19661 # var type/ecx: (payload tree type-id) = int +19662 68/push 0/imm32/right:null +19663 68/push 0/imm32/right:null +19664 68/push 0/imm32/left:unused +19665 68/push 1/imm32/value:int +19666 68/push 1/imm32/is-atom?:true +19667 68/push 0x11/imm32/alloc-id:fake:payload +19668 89/<- %ecx 4/r32/esp +19669 $test-compare-mem-with-literal:initialize-var1: +19670 # var var1/ecx: (payload var) +19671 68/push 0/imm32/register +19672 68/push 0/imm32/register +19673 68/push 8/imm32/stack-offset +19674 68/push 1/imm32/block-depth +19675 51/push-ecx +19676 68/push 0x11/imm32/alloc-id:fake +19677 68/push 0/imm32/name +19678 68/push 0/imm32/name +19679 68/push 0x11/imm32/alloc-id:fake:payload +19680 89/<- %ecx 4/r32/esp +19681 $test-compare-mem-with-literal:initialize-var1-name: +19682 # var1->name = "var1" +19683 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +19684 (copy-array Heap "var1" %eax) +19685 $test-compare-mem-with-literal:initialize-literal-type: +19686 # var type/edx: (payload tree type-id) = literal +19687 68/push 0/imm32/right:null +19688 68/push 0/imm32/right:null +19689 68/push 0/imm32/left:unused +19690 68/push 0/imm32/value:literal +19691 68/push 1/imm32/is-atom?:true +19692 68/push 0x11/imm32/alloc-id:fake:payload +19693 89/<- %edx 4/r32/esp +19694 $test-compare-mem-with-literal:initialize-literal: +19695 # var l/edx: (payload var) +19696 68/push 0/imm32/register +19697 68/push 0/imm32/register +19698 68/push 0/imm32/no-stack-offset +19699 68/push 1/imm32/block-depth +19700 52/push-edx +19701 68/push 0x11/imm32/alloc-id:fake +19702 68/push 0/imm32/name +19703 68/push 0/imm32/name +19704 68/push 0x11/imm32/alloc-id:fake:payload +19705 89/<- %edx 4/r32/esp +19706 $test-compare-mem-with-literal:initialize-literal-value: +19707 # l->name = "0x34" +19708 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +19709 (copy-array Heap "0x34" %eax) +19710 $test-compare-mem-with-literal:initialize-inouts: +19711 # var inouts/esi: (payload stmt-var) = [l] +19712 68/push 0/imm32/is-deref:false +19713 68/push 0/imm32/next +19714 68/push 0/imm32/next +19715 52/push-edx/l +19716 68/push 0x11/imm32/alloc-id:fake +19717 68/push 0x11/imm32/alloc-id:fake:payload +19718 89/<- %esi 4/r32/esp +19719 # var inouts = (handle stmt-var) = [var1, var2] +19720 68/push 0/imm32/is-deref:false +19721 56/push-esi/next +19722 68/push 0x11/imm32/alloc-id:fake +19723 51/push-ecx/var1 +19724 68/push 0x11/imm32/alloc-id:fake +19725 68/push 0x11/imm32/alloc-id:fake:payload +19726 89/<- %esi 4/r32/esp +19727 $test-compare-mem-with-literal:initialize-stmt: +19728 # var stmt/esi: (addr statement) +19729 68/push 0/imm32/next +19730 68/push 0/imm32/next +19731 68/push 0/imm32/outputs +19732 68/push 0/imm32/outputs +19733 56/push-esi/inouts +19734 68/push 0x11/imm32/alloc-id:fake +19735 68/push 0/imm32/operation +19736 68/push 0/imm32/operation +19737 68/push 1/imm32/tag:stmt1 +19738 89/<- %esi 4/r32/esp +19739 $test-compare-mem-with-literal:initialize-stmt-operation: +19740 # stmt->operation = "compare" +19741 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +19742 (copy-array Heap "compare" %eax) +19743 # convert +19744 c7 0/subop/copy *Curr-block-depth 0/imm32 +19745 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +19746 (flush _test-output-buffered-file) +19747 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +19753 # check output +19754 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal") +19755 # . epilogue +19756 89/<- %esp 5/r32/ebp +19757 5d/pop-to-ebp +19758 c3/return +19759 +19760 test-compare-eax-with-literal: +19761 # compare var1/eax 0x34 +19762 # => +19763 # 3d/compare-eax-with 0x34/imm32 +19764 # +19765 # . prologue +19766 55/push-ebp +19767 89/<- %ebp 4/r32/esp +19768 # setup +19769 (clear-stream _test-output-stream) +19770 (clear-stream $_test-output-buffered-file->buffer) +19771 $test-compare-eax-with-literal:initialize-type: +19772 # var type/ecx: (payload tree type-id) = int +19773 68/push 0/imm32/right:null +19774 68/push 0/imm32/right:null +19775 68/push 0/imm32/left:unused +19776 68/push 1/imm32/value:int +19777 68/push 1/imm32/is-atom?:true +19778 68/push 0x11/imm32/alloc-id:fake:payload +19779 89/<- %ecx 4/r32/esp +19780 $test-compare-eax-with-literal:initialize-var1: +19781 # var var1/ecx: (payload var) +19782 68/push 0/imm32/register +19783 68/push 0/imm32/register +19784 68/push 0/imm32/no-stack-offset +19785 68/push 1/imm32/block-depth +19786 51/push-ecx +19787 68/push 0x11/imm32/alloc-id:fake +19788 68/push 0/imm32/name +19789 68/push 0/imm32/name +19790 68/push 0x11/imm32/alloc-id:fake:payload +19791 89/<- %ecx 4/r32/esp +19792 $test-compare-eax-with-literal:initialize-var1-name: +19793 # var1->name = "var1" +19794 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +19795 (copy-array Heap "var1" %eax) +19796 $test-compare-eax-with-literal:initialize-var1-register: +19797 # v->register = "eax" +19798 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +19799 (copy-array Heap "eax" %eax) +19800 $test-compare-eax-with-literal:initialize-literal-type: +19801 # var type/edx: (payload tree type-id) = literal +19802 68/push 0/imm32/right:null +19803 68/push 0/imm32/right:null +19804 68/push 0/imm32/left:unused +19805 68/push 0/imm32/value:literal +19806 68/push 1/imm32/is-atom?:true +19807 68/push 0x11/imm32/alloc-id:fake:payload +19808 89/<- %edx 4/r32/esp +19809 $test-compare-eax-with-literal:initialize-literal: +19810 # var l/edx: (payload var) +19811 68/push 0/imm32/register +19812 68/push 0/imm32/register +19813 68/push 0/imm32/no-stack-offset +19814 68/push 1/imm32/block-depth +19815 52/push-edx +19816 68/push 0x11/imm32/alloc-id:fake +19817 68/push 0/imm32/name +19818 68/push 0/imm32/name +19819 68/push 0x11/imm32/alloc-id:fake:payload +19820 89/<- %edx 4/r32/esp +19821 $test-compare-eax-with-literal:initialize-literal-value: +19822 # l->name = "0x34" +19823 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +19824 (copy-array Heap "0x34" %eax) +19825 $test-compare-eax-with-literal:initialize-inouts: +19826 # var inouts/esi: (payload stmt-var) = [l] +19827 68/push 0/imm32/is-deref:false +19828 68/push 0/imm32/next +19829 68/push 0/imm32/next +19830 52/push-edx/l +19831 68/push 0x11/imm32/alloc-id:fake +19832 68/push 0x11/imm32/alloc-id:fake:payload +19833 89/<- %esi 4/r32/esp +19834 # var inouts = (handle stmt-var) = [var1, var2] +19835 68/push 0/imm32/is-deref:false +19836 56/push-esi/next +19837 68/push 0x11/imm32/alloc-id:fake +19838 51/push-ecx/var1 +19839 68/push 0x11/imm32/alloc-id:fake +19840 68/push 0x11/imm32/alloc-id:fake:payload +19841 89/<- %esi 4/r32/esp +19842 $test-compare-eax-with-literal:initialize-stmt: +19843 # var stmt/esi: (addr statement) +19844 68/push 0/imm32/next +19845 68/push 0/imm32/next +19846 68/push 0/imm32/outputs +19847 68/push 0/imm32/outputs +19848 56/push-esi/inouts +19849 68/push 0x11/imm32/alloc-id:fake +19850 68/push 0/imm32/operation +19851 68/push 0/imm32/operation +19852 68/push 1/imm32/tag:stmt1 +19853 89/<- %esi 4/r32/esp +19854 $test-compare-eax-with-literal:initialize-stmt-operation: +19855 # stmt->operation = "compare" +19856 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +19857 (copy-array Heap "compare" %eax) +19858 # convert +19859 c7 0/subop/copy *Curr-block-depth 0/imm32 +19860 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +19861 (flush _test-output-buffered-file) +19862 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +19868 # check output +19869 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal") +19870 # . epilogue +19871 89/<- %esp 5/r32/ebp +19872 5d/pop-to-ebp +19873 c3/return +19874 +19875 test-compare-reg-with-literal: +19876 # compare var1/ecx 0x34 +19877 # => +19878 # 81 7/subop/compare %ecx 0x34/imm32 +19879 # +19880 # . prologue +19881 55/push-ebp +19882 89/<- %ebp 4/r32/esp +19883 # setup +19884 (clear-stream _test-output-stream) +19885 (clear-stream $_test-output-buffered-file->buffer) +19886 $test-compare-reg-with-literal:initialize-type: +19887 # var type/ecx: (payload tree type-id) = int +19888 68/push 0/imm32/right:null +19889 68/push 0/imm32/right:null +19890 68/push 0/imm32/left:unused +19891 68/push 1/imm32/value:int +19892 68/push 1/imm32/is-atom?:true +19893 68/push 0x11/imm32/alloc-id:fake:payload +19894 89/<- %ecx 4/r32/esp +19895 $test-compare-reg-with-literal:initialize-var1: +19896 # var var1/ecx: (payload var) +19897 68/push 0/imm32/register +19898 68/push 0/imm32/register +19899 68/push 0/imm32/no-stack-offset +19900 68/push 1/imm32/block-depth +19901 51/push-ecx +19902 68/push 0x11/imm32/alloc-id:fake +19903 68/push 0/imm32/name +19904 68/push 0/imm32/name +19905 68/push 0x11/imm32/alloc-id:fake:payload +19906 89/<- %ecx 4/r32/esp +19907 $test-compare-reg-with-literal:initialize-var1-name: +19908 # var1->name = "var1" +19909 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +19910 (copy-array Heap "var1" %eax) +19911 $test-compare-reg-with-literal:initialize-var1-register: +19912 # v->register = "ecx" +19913 8d/copy-address *(ecx+0x1c) 0/r32/eax # Var-register + 4 +19914 (copy-array Heap "ecx" %eax) +19915 $test-compare-reg-with-literal:initialize-literal-type: +19916 # var type/edx: (payload tree type-id) = literal +19917 68/push 0/imm32/right:null +19918 68/push 0/imm32/right:null +19919 68/push 0/imm32/left:unused +19920 68/push 0/imm32/value:literal +19921 68/push 1/imm32/is-atom?:true +19922 68/push 0x11/imm32/alloc-id:fake:payload +19923 89/<- %edx 4/r32/esp +19924 $test-compare-reg-with-literal:initialize-literal: +19925 # var l/edx: (payload var) +19926 68/push 0/imm32/register +19927 68/push 0/imm32/register +19928 68/push 0/imm32/no-stack-offset +19929 68/push 1/imm32/block-depth +19930 52/push-edx +19931 68/push 0x11/imm32/alloc-id:fake +19932 68/push 0/imm32/name +19933 68/push 0/imm32/name +19934 68/push 0x11/imm32/alloc-id:fake:payload +19935 89/<- %edx 4/r32/esp +19936 $test-compare-reg-with-literal:initialize-literal-value: +19937 # l->name = "0x34" +19938 8d/copy-address *(edx+4) 0/r32/eax # Var-name + 4 +19939 (copy-array Heap "0x34" %eax) +19940 $test-compare-reg-with-literal:initialize-inouts: +19941 # var inouts/esi: (payload stmt-var) = [l] +19942 68/push 0/imm32/is-deref:false +19943 68/push 0/imm32/next +19944 68/push 0/imm32/next +19945 52/push-edx/l +19946 68/push 0x11/imm32/alloc-id:fake +19947 68/push 0x11/imm32/alloc-id:fake:payload +19948 89/<- %esi 4/r32/esp +19949 # var inouts = (handle stmt-var) = [var1, var2] +19950 68/push 0/imm32/is-deref:false +19951 56/push-esi/next +19952 68/push 0x11/imm32/alloc-id:fake +19953 51/push-ecx/var1 +19954 68/push 0x11/imm32/alloc-id:fake +19955 68/push 0x11/imm32/alloc-id:fake:payload +19956 89/<- %esi 4/r32/esp +19957 $test-compare-reg-with-literal:initialize-stmt: +19958 # var stmt/esi: (addr statement) +19959 68/push 0/imm32/next +19960 68/push 0/imm32/next +19961 68/push 0/imm32/outputs +19962 68/push 0/imm32/outputs +19963 56/push-esi/inouts +19964 68/push 0x11/imm32/alloc-id:fake +19965 68/push 0/imm32/operation +19966 68/push 0/imm32/operation +19967 68/push 1/imm32/tag:stmt1 +19968 89/<- %esi 4/r32/esp +19969 $test-compare-reg-with-literal:initialize-stmt-operation: +19970 # stmt->operation = "compare" +19971 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +19972 (copy-array Heap "compare" %eax) +19973 # convert +19974 c7 0/subop/copy *Curr-block-depth 0/imm32 +19975 (emit-subx-stmt _test-output-buffered-file %esi Primitives Stderr 0) +19976 (flush _test-output-buffered-file) +19977 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +19983 # check output +19984 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal") +19985 # . epilogue +19986 89/<- %esp 5/r32/ebp +19987 5d/pop-to-ebp +19988 c3/return +19989 +19990 test-emit-subx-stmt-function-call: +19991 # Call a function on a variable on the stack. +19992 # f foo +19993 # => +19994 # (f *(ebp-8)) +19995 # (Changing the function name supports overloading in general, but here it +19996 # just serves to help disambiguate things.) +19997 # +19998 # There's a variable on the var stack as follows: +19999 # name: 'foo' +20000 # type: int +20001 # stack-offset: -8 +20002 # +20003 # There's nothing in primitives. +20004 # +20005 # We don't perform any checking here on the type of 'f'. +20006 # +20007 # . prologue +20008 55/push-ebp +20009 89/<- %ebp 4/r32/esp +20010 # setup +20011 (clear-stream _test-output-stream) +20012 (clear-stream $_test-output-buffered-file->buffer) +20013 $test-emit-subx-function-call:initialize-type: +20014 # var type/ecx: (payload tree type-id) = int +20015 68/push 0/imm32/right:null +20016 68/push 0/imm32/right:null +20017 68/push 0/imm32/left:unused +20018 68/push 1/imm32/value:int +20019 68/push 1/imm32/is-atom?:true +20020 68/push 0x11/imm32/alloc-id:fake:payload +20021 89/<- %ecx 4/r32/esp +20022 $test-emit-subx-function-call:initialize-var: +20023 # var var-foo/ecx: (payload var) = var(type) +20024 68/push 0/imm32/no-register +20025 68/push 0/imm32/no-register +20026 68/push -8/imm32/stack-offset +20027 68/push 1/imm32/block-depth +20028 51/push-ecx/type +20029 68/push 0x11/imm32/alloc-id:fake +20030 68/push 0/imm32/name +20031 68/push 0/imm32/name +20032 68/push 0x11/imm32/alloc-id:fake:payload +20033 89/<- %ecx 4/r32/esp +20034 $test-emit-subx-function-call:initialize-var-name: +20035 # var-foo->name = "foo" +20036 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +20037 (copy-array Heap "foo" %eax) +20038 $test-emit-subx-function-call:initialize-stmt-var: +20039 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +20040 68/push 0/imm32/is-deref:false +20041 68/push 0/imm32/next +20042 68/push 0/imm32/next +20043 51/push-ecx/var-foo +20044 68/push 0x11/imm32/alloc-id:fake +20045 68/push 0x11/imm32/alloc-id:fake:payload +20046 89/<- %ebx 4/r32/esp +20047 $test-emit-subx-function-call:initialize-stmt: +20048 # var stmt/esi: (addr statement) +20049 68/push 0/imm32/no-outputs +20050 68/push 0/imm32/no-outputs +20051 53/push-ebx/inouts +20052 68/push 0x11/imm32/alloc-id:fake +20053 68/push 0/imm32/operation +20054 68/push 0/imm32/operation +20055 68/push 1/imm32/tag +20056 89/<- %esi 4/r32/esp +20057 $test-emit-subx-function-call:initialize-stmt-operation: +20058 # stmt->operation = "f" +20059 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +20060 (copy-array Heap "f" %eax) +20061 # convert +20062 c7 0/subop/copy *Curr-block-depth 0/imm32 +20063 (emit-subx-stmt _test-output-buffered-file %esi 0 Stderr 0) +20064 (flush _test-output-buffered-file) +20065 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +20071 # check output +20072 (check-next-stream-line-equal _test-output-stream "(f *(ebp+0xfffffff8))" "F - test-emit-subx-stmt-function-call") +20073 # . epilogue +20074 89/<- %esp 5/r32/ebp +20075 5d/pop-to-ebp +20076 c3/return +20077 +20078 test-emit-subx-stmt-function-call-with-literal-arg: +20079 # Call a function on a literal. +20080 # f 0x34 +20081 # => +20082 # (f2 0x34) +20083 # +20084 # . prologue +20085 55/push-ebp +20086 89/<- %ebp 4/r32/esp +20087 # setup +20088 (clear-stream _test-output-stream) +20089 (clear-stream $_test-output-buffered-file->buffer) +20090 $test-emit-subx-function-call-with-literal-arg:initialize-type: +20091 # var type/ecx: (payload tree type-id) = int +20092 68/push 0/imm32/right:null +20093 68/push 0/imm32/right:null +20094 68/push 0/imm32/left:unused +20095 68/push 0/imm32/value:literal +20096 68/push 1/imm32/is-atom?:true +20097 68/push 0x11/imm32/alloc-id:fake:payload +20098 89/<- %ecx 4/r32/esp +20099 $test-emit-subx-function-call-with-literal-arg:initialize-var: +20100 # var var-foo/ecx: (payload var) = var(lit) +20101 68/push 0/imm32/no-register +20102 68/push 0/imm32/no-register +20103 68/push 0/imm32/no-stack-offset +20104 68/push 1/imm32/block-depth +20105 51/push-ecx/type +20106 68/push 0x11/imm32/alloc-id:fake +20107 68/push 0/imm32/name +20108 68/push 0/imm32/name +20109 68/push 0x11/imm32/alloc-id:fake:payload +20110 89/<- %ecx 4/r32/esp +20111 $test-emit-subx-function-call-with-literal-arg:initialize-var-name: +20112 # var-foo->name = "0x34" +20113 8d/copy-address *(ecx+4) 0/r32/eax # Var-name + 4 +20114 (copy-array Heap "0x34" %eax) +20115 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-var: +20116 # var operand/ebx: (payload stmt-var) = stmt-var(var-foo) +20117 68/push 0/imm32/is-deref:false +20118 68/push 0/imm32/next +20119 68/push 0/imm32/next +20120 51/push-ecx/var-foo +20121 68/push 0x11/imm32/alloc-id:fake +20122 68/push 0x11/imm32/alloc-id:fake:payload +20123 89/<- %ebx 4/r32/esp +20124 $test-emit-subx-function-call-with-literal-arg:initialize-stmt: +20125 # var stmt/esi: (addr statement) +20126 68/push 0/imm32/no-outputs +20127 68/push 0/imm32/no-outputs +20128 53/push-ebx/inouts +20129 68/push 0x11/imm32/alloc-id:fake +20130 68/push 0/imm32/operation +20131 68/push 0/imm32/operation +20132 68/push 1/imm32/tag +20133 89/<- %esi 4/r32/esp +20134 $test-emit-subx-function-call-with-literal-arg:initialize-stmt-operation: +20135 # stmt->operation = "f" +20136 8d/copy-address *(esi+4) 0/r32/eax # Stmt1-operation +20137 (copy-array Heap "f" %eax) +20138 # convert +20139 c7 0/subop/copy *Curr-block-depth 0/imm32 +20140 (emit-subx-stmt _test-output-buffered-file %esi 0 %ebx Stderr 0) +20141 (flush _test-output-buffered-file) +20142 +-- 6 lines: #? # dump _test-output-stream ----------------------------------------------------------------------------------------------------------------------------------------- +20148 # check output +20149 (check-next-stream-line-equal _test-output-stream "(f 0x34)" "F - test-emit-subx-stmt-function-call-with-literal-arg") +20150 # . epilogue +20151 89/<- %esp 5/r32/ebp +20152 5d/pop-to-ebp +20153 c3/return +20154 +20155 emit-indent: # out: (addr buffered-file), n: int +20156 # . prologue +20157 55/push-ebp +20158 89/<- %ebp 4/r32/esp +20159 # . save registers +20160 50/push-eax +20161 # var i/eax: int = n +20162 8b/-> *(ebp+0xc) 0/r32/eax +20163 { +20164 # if (i <= 0) break +20165 3d/compare-eax-with 0/imm32 +20166 7e/jump-if-<= break/disp8 +20167 (write-buffered *(ebp+8) " ") +20168 48/decrement-eax +20169 eb/jump loop/disp8 +20170 } +20171 $emit-indent:end: +20172 # . restore registers +20173 58/pop-to-eax +20174 # . epilogue +20175 89/<- %esp 5/r32/ebp +20176 5d/pop-to-ebp +20177 c3/return +20178 +20179 emit-subx-prologue: # out: (addr buffered-file) +20180 # . prologue +20181 55/push-ebp +20182 89/<- %ebp 4/r32/esp +20183 # +20184 (write-buffered *(ebp+8) " # . prologue\n") +20185 (write-buffered *(ebp+8) " 55/push-ebp\n") +20186 (write-buffered *(ebp+8) " 89/<- %ebp 4/r32/esp\n") +20187 $emit-subx-prologue:end: +20188 # . epilogue +20189 89/<- %esp 5/r32/ebp +20190 5d/pop-to-ebp +20191 c3/return +20192 +20193 emit-subx-epilogue: # out: (addr buffered-file) +20194 # . prologue +20195 55/push-ebp +20196 89/<- %ebp 4/r32/esp +20197 # +20198 (write-buffered *(ebp+8) " # . epilogue\n") +20199 (write-buffered *(ebp+8) " 89/<- %esp 5/r32/ebp\n") +20200 (write-buffered *(ebp+8) " 5d/pop-to-ebp\n") +20201 (write-buffered *(ebp+8) " c3/return\n") +20202 $emit-subx-epilogue:end: +20203 # . epilogue +20204 89/<- %esp 5/r32/ebp +20205 5d/pop-to-ebp +20206 c3/return -- cgit 1.4.1-2-gfad0