From 21627e9d02cdbb2ccae81c9f7c0f476f1df62e2e Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Thu, 30 Jan 2020 01:21:36 -0800 Subject: 5963 --- html/apps/mu.subx.html | 7948 ++++++++++++++++++++++++------------------------ 1 file changed, 3992 insertions(+), 3956 deletions(-) (limited to 'html/apps') diff --git a/html/apps/mu.subx.html b/html/apps/mu.subx.html index 8348bbd4..4c1682e2 100644 --- a/html/apps/mu.subx.html +++ b/html/apps/mu.subx.html @@ -459,8 +459,8 @@ if ('onhashchange' in window) { 397 89/<- %ebp 4/r32/esp 398 # 399 (parse-mu *(ebp+8)) - 400 (check-mu-types) - 401 (emit-subx *(ebp+0xc)) + 400 (check-mu-types) + 401 (emit-subx *(ebp+0xc)) 402 $convert-mu:end: 403 # . epilogue 404 89/<- %esp 5/r32/ebp @@ -1607,10 +1607,10 @@ if ('onhashchange' in window) { 1625 # v->stack-offset = next-offset 1626 89/<- *(ebx+0xc) 2/r32/edx # Var-stack-offset 1627 # next-offset += size-of(v) -1628 (size-of %ebx) # => eax +1628 (size-of %ebx) # => eax 1629 01/add %edx 0/r32/eax 1630 # -1631 (append-list Heap %ebx *(edi+8)) # Function-inouts => eax +1631 (append-list Heap %ebx *(edi+8)) # Function-inouts => eax 1632 89/<- *(edi+8) 0/r32/eax # Function-inouts 1633 (push *(ebp+0x10) %ebx) 1634 # @@ -1638,7 +1638,7 @@ if ('onhashchange' in window) { 1656 # assert(var->register != null) 1657 81 7/subop/compare *(ebx+0x10) 0/imm32 # Var-register 1658 0f 84/jump-if-= $populate-mu-function-header:error3/disp32 -1659 (append-list Heap %ebx *(edi+0xc)) # Function-outputs => eax +1659 (append-list Heap %ebx *(edi+0xc)) # Function-outputs => eax 1660 89/<- *(edi+0xc) 0/r32/eax # Function-outputs 1661 e9/jump loop/disp32 1662 } @@ -3062,7 +3062,7 @@ if ('onhashchange' in window) { 3080 (check-no-tokens-left %ecx) 3081 # parse new block and append 3082 (parse-mu-block *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax -3083 (append-to-block Heap %edi %eax) +3083 (append-to-block Heap %edi %eax) 3084 e9/jump $parse-mu-block:line-loop/disp32 3085 } 3086 # if slice-equal?(word-slice, "}") break @@ -3084,7 +3084,7 @@ if ('onhashchange' in window) { 3102 # 3103 # TODO: error-check the rest of 'line' 3104 (parse-mu-named-block %edx *(ebp+8) *(ebp+0xc) *(ebp+0x10)) # => eax -3105 (append-to-block Heap %edi %eax) +3105 (append-to-block Heap %edi %eax) 3106 e9/jump $parse-mu-block:line-loop/disp32 3107 } 3108 # if slice-equal?(word-slice, "var") @@ -3095,13 +3095,13 @@ if ('onhashchange' in window) { 3113 74/jump-if-= break/disp8 3114 # 3115 (parse-mu-var-def %ecx *(ebp+0xc)) # => eax -3116 (append-to-block Heap %edi %eax) +3116 (append-to-block Heap %edi %eax) 3117 e9/jump $parse-mu-block:line-loop/disp32 3118 } 3119 $parse-mu-block:regular-stmt: 3120 # otherwise 3121 (parse-mu-stmt %ecx *(ebp+0xc) *(ebp+0x10)) # => eax -3122 (append-to-block Heap %edi %eax) +3122 (append-to-block Heap %edi %eax) 3123 e9/jump loop/disp32 3124 } # end line loop 3125 # return result @@ -3227,7 +3227,7 @@ if ('onhashchange' in window) { 3245 8b/-> *Next-local-stack-offset 0/r32/eax 3246 89/<- *(edx+0xc) 0/r32/eax # Var-stack-offset 3247 # *Next-local-stack-offset -= size-of(v) -3248 (size-of %edx) +3248 (size-of %edx) 3249 29/subtract-from *Next-local-stack-offset 0/r32/eax 3250 # 3251 (push *(ebp+0xc) %edx) @@ -3237,7 +3237,7 @@ if ('onhashchange' in window) { 3255 { 3256 75/jump-if-!= break/disp8 3257 # TODO: ensure that there's nothing else on this line -3258 (new-vardef Heap %edx) # => eax +3258 (new-vardef Heap %edx) # => eax 3259 eb/jump $parse-mu-var-def:end/disp8 3260 } 3261 # or v has a register and there's more to this line @@ -3249,7 +3249,7 @@ if ('onhashchange' in window) { 3267 3d/compare-eax-and 0/imm32 3268 74/jump-if-= $parse-mu-var-def:abort/disp8 3269 # -3270 (new-regvardef Heap %edx) # => eax +3270 (new-regvardef Heap %edx) # => eax 3271 (add-operation-and-inputs-to-stmt %eax *(ebp+8) *(ebp+0xc)) 3272 } 3273 $parse-mu-var-def:end: @@ -3393,8 +3393,8 @@ if ('onhashchange' in window) { 3411 3d/compare-eax-and 0/imm32 3412 0f 84/jump-if-= $parse-mu-stmt:abort/disp32 3413 # -3414 (lookup-or-define-var %ecx *(ebp+0xc) *(ebp+0x10)) # => eax -3415 (append-list Heap %eax *(edi+0xc)) # Stmt1-outputs => eax +3414 (lookup-or-define-var %ecx *(ebp+0xc) *(ebp+0x10)) # => eax +3415 (append-list Heap %eax *(edi+0xc)) # Stmt1-outputs => eax 3416 89/<- *(edi+0xc) 0/r32/eax # Stmt1-outputs 3417 e9/jump loop/disp32 3418 } @@ -3472,9 +3472,9 @@ if ('onhashchange' in window) { 3490 3d/compare-eax-and 0x24/imm32/dollar 3491 75/jump-if-!= break/disp8 3492 # var eax: (handle var) -3493 (new-label Heap %ecx) # => eax +3493 (new-label Heap %ecx) # => eax 3494 # stmt->inouts = append(eax, stmt->inouts) -3495 (append-list Heap %eax *(edi+8)) # Stmt1-inouts => eax +3495 (append-list Heap %eax *(edi+8)) # Stmt1-inouts => eax 3496 89/<- *(edi+8) 0/r32/eax # Stmt1-inouts 3497 # continue 3498 e9/jump $add-operation-and-inputs-to-stmt:read-inouts/disp32 @@ -3482,7 +3482,7 @@ if ('onhashchange' in window) { 3500 $add-operation-and-inputs-to-stmt:regular-inout: 3501 # otherwise 3502 (lookup-var-or-literal %ecx *(ebp+0x10)) # => eax -3503 (append-list Heap %eax *(edi+8)) # Stmt1-inouts or Regvardef-inouts => eax +3503 (append-list Heap %eax *(edi+8)) # Stmt1-inouts or Regvardef-inouts => eax 3504 89/<- *(edi+8) 0/r32/eax # Stmt1-inouts or Regvardef-inouts 3505 e9/jump loop/disp32 3506 } @@ -3573,539 +3573,539 @@ if ('onhashchange' in window) { 3591 (slice-empty? %esi) # => eax 3592 3d/compare-eax-and 0/imm32 3593 0f 85/jump-if-!= $lookup-var-or-literal:abort/disp32 -3594 # var ecx: byte = *name->start +3594 # var c/ecx: byte = *name->start 3595 8b/-> *esi 1/r32/ecx 3596 8a/copy-byte *ecx 1/r32/CL 3597 81 4/subop/and %ecx 0xff/imm32 -3598 # if is-decimal-digit?(*name->start) return new var(name) -3599 (is-decimal-digit? %ecx) # => eax -3600 81 7/subop/compare %eax 0/imm32 -3601 { +3598 # if is-decimal-digit?(c) return new var(name) +3599 { +3600 (is-decimal-digit? %ecx) # => eax +3601 81 7/subop/compare %eax 0/imm32 3602 74/jump-if-= break/disp8 -3603 (new-literal-integer Heap %esi) # => eax -3604 } -3605 # otherwise return lookup-var(name, vars) -3606 { -3607 75/jump-if-!= break/disp8 -3608 (lookup-var %esi *(ebp+0xc)) # => eax -3609 } -3610 $lookup-var-or-literal:end: -3611 # . restore registers -3612 5e/pop-to-esi -3613 59/pop-to-ecx -3614 # . epilogue -3615 89/<- %esp 5/r32/ebp -3616 5d/pop-to-ebp -3617 c3/return -3618 -3619 $lookup-var-or-literal:abort: -3620 (write-buffered Stderr "empty variable!") -3621 (flush Stderr) -3622 # . syscall(exit, 1) -3623 bb/copy-to-ebx 1/imm32 -3624 b8/copy-to-eax 1/imm32/exit -3625 cd/syscall 0x80/imm8 -3626 # never gets here -3627 -3628 # return first 'name' from the top (back) of 'vars' and abort if not found -3629 lookup-var: # name: (addr slice), vars: (addr stack (handle var)) -> result/eax: (handle var) -3630 # . prologue -3631 55/push-ebp -3632 89/<- %ebp 4/r32/esp -3633 # var target/eax: (handle array byte) = slice-to-string(name) -3634 (slice-to-string Heap *(ebp+8)) # => eax -3635 # -3636 (lookup-var-helper %eax *(ebp+0xc)) # => eax -3637 # if (result == 0) abort -3638 3d/compare-eax-and 0/imm32 -3639 74/jump-if-= $lookup-var:abort/disp8 -3640 $lookup-var:end: -3641 # . epilogue -3642 89/<- %esp 5/r32/ebp -3643 5d/pop-to-ebp -3644 c3/return -3645 -3646 $lookup-var:abort: -3647 (write-buffered Stderr "unknown variable '") -3648 (write-slice-buffered Stderr *(ebp+8)) -3649 (write-buffered Stderr "'\n") -3650 (flush Stderr) -3651 # . syscall(exit, 1) -3652 bb/copy-to-ebx 1/imm32 -3653 b8/copy-to-eax 1/imm32/exit -3654 cd/syscall 0x80/imm8 -3655 # never gets here -3656 -3657 # return first 'name' from the top (back) of 'vars', and 0/null if not found -3658 lookup-var-helper: # name: (addr array byte), vars: (addr stack (handle var)) -> result/eax: (handle var) -3659 # pseudocode: -3660 # var curr: (addr handle var) = &vars->data[vars->top - 4] -3661 # var min = vars->data -3662 # while curr >= min -3663 # var v: (handle var) = *curr -3664 # if v->name == name -3665 # return v -3666 # return 0 -3667 # -3668 # . prologue -3669 55/push-ebp -3670 89/<- %ebp 4/r32/esp -3671 # . save registers -3672 52/push-edx -3673 53/push-ebx -3674 56/push-esi -3675 # esi = vars -3676 8b/-> *(ebp+0xc) 6/r32/esi -3677 # ebx = vars->top -3678 8b/-> *esi 3/r32/ebx -3679 # if (vars->top > vars->length) abort -3680 3b/compare 0/r32/eax *(esi+4) -3681 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 -3682 # var min/edx: (addr handle var) = vars->data -3683 8d/copy-address *(esi+8) 2/r32/edx -3684 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 4] -3685 81 5/subop/subtract %ebx 4/imm32 -3686 8d/copy-address *(esi+ebx+8) 3/r32/ebx -3687 { -3688 # if (curr < min) return 0 -3689 39/compare %ebx 2/r32/edx -3690 b8/copy-to-eax 0/imm32 -3691 0f 82/jump-if-addr< break/disp32 -3692 # var v/eax: (handle var) = *curr -3693 8b/-> *ebx 0/r32/eax -3694 # if (v->name == name) return v -3695 (string-equal? *eax *(ebp+8)) # Var-name -3696 3d/compare-eax-and 0/imm32 -3697 8b/-> *ebx 0/r32/eax -3698 75/jump-if-!= break/disp8 -3699 # curr -= 4 -3700 81 5/subop/subtract %ebx 4/imm32 -3701 e9/jump loop/disp32 -3702 } -3703 $lookup-var-helper:end: -3704 # . restore registers -3705 5e/pop-to-esi -3706 5b/pop-to-ebx -3707 5a/pop-to-edx -3708 # . epilogue -3709 89/<- %esp 5/r32/ebp -3710 5d/pop-to-ebp -3711 c3/return -3712 -3713 $lookup-var-helper:error1: -3714 (write-buffered Stderr "malformed stack when looking up '") -3715 (write-slice-buffered Stderr *(ebp+8)) -3716 (write-buffered Stderr "'\n") -3717 (flush Stderr) -3718 # . syscall(exit, 1) -3719 bb/copy-to-ebx 1/imm32 -3720 b8/copy-to-eax 1/imm32/exit -3721 cd/syscall 0x80/imm8 -3722 # never gets here -3723 -3724 # return first 'name' from the top (back) of 'vars' and create a new var for a fn output if not found -3725 lookup-or-define-var: # name: (addr slice), vars: (addr stack (handle var)), fn: (handle function) -> result/eax: (handle var) -3726 # . prologue -3727 55/push-ebp -3728 89/<- %ebp 4/r32/esp -3729 # . save registers -3730 51/push-ecx -3731 # var target/ecx: (handle array byte) = slice-to-string(name) -3732 (slice-to-string Heap *(ebp+8)) # => eax -3733 89/<- %ecx 0/r32/eax -3734 # -3735 (lookup-var-helper %ecx *(ebp+0xc)) # => eax -3736 { -3737 # if (result != 0) return -3738 3d/compare-eax-and 0/imm32 -3739 75/jump-if-!= break/disp8 -3740 # if name is one of fn's outputs, return it -3741 { -3742 (find-in-function-outputs *(ebp+0x10) %ecx) # => eax -3743 3d/compare-eax-and 0/imm32 -3744 # otherwise abort -3745 0f 84/jump-if-!= $lookup-var:abort/disp32 -3746 } -3747 } -3748 $lookup-or-define-var:end: -3749 # . restore registers -3750 59/pop-to-ecx -3751 # . epilogue -3752 89/<- %esp 5/r32/ebp -3753 5d/pop-to-ebp -3754 c3/return -3755 -3756 find-in-function-outputs: # fn: (handle function), name: (handle array byte) => result/eax: (handle var) -3757 # . prologue -3758 55/push-ebp -3759 89/<- %ebp 4/r32/esp -3760 # . save registers -3761 51/push-ecx -3762 # var curr/ecx: (handle list var) = fn->outputs -3763 8b/-> *(ebp+8) 1/r32/ecx -3764 8b/-> *(ecx+0xc) 1/r32/ecx -3765 # while curr != null -3766 { -3767 81 7/subop/compare %ecx 0/imm32 -3768 74/jump-if-= break/disp8 -3769 # var v: (handle var) = *curr -3770 8b/-> *ecx 0/r32/eax # List-value -3771 # if (curr->name == name) return curr -3772 50/push-eax -3773 (string-equal? *eax *(ebp+0xc)) -3774 3d/compare-eax-and 0/imm32 -3775 58/pop-to-eax -3776 75/jump-if-!= $find-in-function-outputs:end/disp8 -3777 # curr = curr->next -3778 8b/-> *(ecx+4) 1/r32/ecx # List-next -3779 eb/jump loop/disp8 -3780 } -3781 b8/copy-to-eax 0/imm32 -3782 $find-in-function-outputs:end: -3783 # . restore registers -3784 59/pop-to-ecx -3785 # . epilogue -3786 89/<- %esp 5/r32/ebp -3787 5d/pop-to-ebp -3788 c3/return -3789 -3790 test-parse-mu-stmt: -3791 # 'increment n' -3792 # . prologue -3793 55/push-ebp -3794 89/<- %ebp 4/r32/esp -3795 # setup -3796 (clear-stream _test-input-stream) -3797 (write _test-input-stream "increment n\n") -3798 # var vars/ecx: (stack (addr var) 4) -3799 81 5/subop/subtract %esp 0x10/imm32 -3800 68/push 0x10/imm32/length -3801 68/push 0/imm32/top -3802 89/<- %ecx 4/r32/esp -3803 (clear-stack %ecx) -3804 # var v/edx: var -3805 81 5/subop/subtract %esp 0x14/imm32 # Var-size -3806 89/<- %edx 4/r32/esp -3807 (zero-out %edx 0x14) -3808 # v->name = "n" -3809 c7 0/subop/copy *edx "n"/imm32 # Var-name -3810 # -3811 (push %ecx %edx) -3812 # convert -3813 (parse-mu-stmt _test-input-stream %ecx) # => eax -3814 # check result -3815 (check-ints-equal *eax 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 -3816 (check-strings-equal *(eax+4) "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation -3817 # edx: (handle list var) = result->inouts -3818 8b/-> *(eax+8) 2/r32/edx # Stmt1-inouts -3819 # ebx: (handle var) = result->inouts->value -3820 8b/-> *edx 3/r32/ebx # List-value -3821 (check-strings-equal *ebx "n" "F - test-parse-mu-stmt/inout:0") # Var-name -3822 # . epilogue -3823 89/<- %esp 5/r32/ebp -3824 5d/pop-to-ebp -3825 c3/return -3826 -3827 test-parse-mu-stmt-with-comma: -3828 # 'increment n' -3829 # . prologue -3830 55/push-ebp -3831 89/<- %ebp 4/r32/esp -3832 # setup -3833 (clear-stream _test-input-stream) -3834 (write _test-input-stream "copy-to n, 3\n") -3835 # var vars/ecx: (stack (addr var) 4) -3836 81 5/subop/subtract %esp 0x10/imm32 -3837 68/push 0x10/imm32/length -3838 68/push 0/imm32/top -3839 89/<- %ecx 4/r32/esp -3840 (clear-stack %ecx) -3841 # var v/edx: var -3842 81 5/subop/subtract %esp 0x14/imm32 # Var-size -3843 89/<- %edx 4/r32/esp -3844 (zero-out %edx 0x14) -3845 # v->name = "n" -3846 c7 0/subop/copy *edx "n"/imm32 # Var-name -3847 # -3848 (push %ecx %edx) -3849 # convert -3850 (parse-mu-stmt _test-input-stream %ecx) # => eax -3851 # check result -3852 (check-ints-equal *eax 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1 -3853 (check-strings-equal *(eax+4) "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation -3854 # edx: (handle list var) = result->inouts -3855 8b/-> *(eax+8) 2/r32/edx # Stmt1-inouts -3856 # ebx: (handle var) = result->inouts->value -3857 8b/-> *edx 3/r32/ebx # List-value -3858 (check-strings-equal *ebx "n" "F - test-parse-mu-stmt-with-comma/inout:0") # Var-name -3859 # . epilogue -3860 89/<- %esp 5/r32/ebp -3861 5d/pop-to-ebp -3862 c3/return -3863 -3864 new-function: # ad: (addr allocation-descriptor), name: (addr array byte), subx-name: (addr array byte), inouts: (handle list var), outputs: (handle list var), body: (handle block), next: (handle function) -> result/eax: (handle function) -3865 # . prologue -3866 55/push-ebp -3867 89/<- %ebp 4/r32/esp -3868 # . save registers -3869 51/push-ecx -3870 # -3871 (allocate *(ebp+8) *Function-size) # => eax -3872 8b/-> *(ebp+0xc) 1/r32/ecx -3873 89/<- *eax 1/r32/ecx # Function-name -3874 8b/-> *(ebp+0x10) 1/r32/ecx -3875 89/<- *(eax+4) 1/r32/ecx # Function-subx-name -3876 8b/-> *(ebp+0x14) 1/r32/ecx -3877 89/<- *(eax+8) 1/r32/ecx # Function-inouts -3878 8b/-> *(ebp+0x18) 1/r32/ecx -3879 89/<- *(eax+0xc) 1/r32/ecx # Function-outputs -3880 8b/-> *(ebp+0x1c) 1/r32/ecx -3881 89/<- *(eax+0x10) 1/r32/ecx # Function-body -3882 8b/-> *(ebp+0x20) 1/r32/ecx -3883 89/<- *(eax+0x14) 1/r32/ecx # Function-next -3884 $new-function:end: -3885 # . restore registers -3886 59/pop-to-ecx -3887 # . epilogue -3888 89/<- %esp 5/r32/ebp -3889 5d/pop-to-ebp -3890 c3/return -3891 -3892 new-var: # ad: (addr allocation-descriptor), name: (addr array byte), type: int, block: int, stack-offset: int, register: (addr array byte) -> result/eax: (handle var) -3893 # . prologue -3894 55/push-ebp -3895 89/<- %ebp 4/r32/esp -3896 # . save registers -3897 51/push-ecx -3898 # -3899 (allocate *(ebp+8) *Var-size) # => eax -3900 8b/-> *(ebp+0xc) 1/r32/ecx -3901 89/<- *eax 1/r32/ecx # Var-name -3902 8b/-> *(ebp+0x10) 1/r32/ecx -3903 89/<- *(eax+4) 1/r32/ecx # Var-type -3904 8b/-> *(ebp+0x14) 1/r32/ecx -3905 89/<- *(eax+8) 1/r32/ecx # Var-block -3906 8b/-> *(ebp+0x18) 1/r32/ecx -3907 89/<- *(eax+0xc) 1/r32/ecx # Var-stack-offset -3908 8b/-> *(ebp+0x1c) 1/r32/ecx -3909 89/<- *(eax+0x10) 1/r32/ecx # Var-register -3910 $new-var:end: -3911 # . restore registers -3912 59/pop-to-ecx -3913 # . epilogue -3914 89/<- %esp 5/r32/ebp -3915 5d/pop-to-ebp -3916 c3/return -3917 -3918 new-literal-integer: # ad: (addr allocation-descriptor), name: (addr slice) -> result/eax: (handle var) -3919 # . prologue -3920 55/push-ebp -3921 89/<- %ebp 4/r32/esp -3922 # . save registers -3923 51/push-ecx -3924 # if (!is-hex-int?(name)) abort -3925 (is-hex-int? *(ebp+0xc)) # => eax -3926 3d/compare-eax-and 0/imm32 -3927 0f 84/jump-if-= $new-literal-integer:abort/disp32 -3928 # var s/ecx: (addr array byte) -3929 (slice-to-string Heap *(ebp+0xc)) # => eax -3930 89/<- %ecx 0/r32/eax -3931 # -3932 (allocate *(ebp+8) *Var-size) # => eax -3933 89/<- *eax 1/r32/ecx # Var-name -3934 89/<- %ecx 0/r32/eax -3935 (allocate *(ebp+8) *Tree-size) # => eax -3936 89/<- *(ecx+4) 0/r32/eax # Var-type -3937 89/<- %eax 1/r32/ecx -3938 c7 0/subop/copy *(eax+8) 0/imm32 # Var-block -3939 c7 0/subop/copy *(eax+0xc) 0/imm32 # Var-stack-offset -3940 c7 0/subop/copy *(eax+0x10) 0/imm32 # Var-register -3941 $new-literal-integer:end: -3942 # . restore registers -3943 59/pop-to-ecx -3944 # . epilogue -3945 89/<- %esp 5/r32/ebp -3946 5d/pop-to-ebp -3947 c3/return -3948 -3949 $new-literal-integer:abort: -3950 (write-buffered Stderr "variable cannot begin with a digit '") -3951 (write-slice-buffered Stderr *(ebp+0xc)) -3952 (write-buffered Stderr "'\n") -3953 (flush Stderr) -3954 # . syscall(exit, 1) -3955 bb/copy-to-ebx 1/imm32 -3956 b8/copy-to-eax 1/imm32/exit -3957 cd/syscall 0x80/imm8 -3958 # never gets here -3959 -3960 new-label: # ad: (addr allocation-descriptor), name: (addr slice) -> result/eax: (handle var) -3961 # . prologue -3962 55/push-ebp -3963 89/<- %ebp 4/r32/esp -3964 # . save registers -3965 51/push-ecx -3966 # var s/ecx: (addr array byte) -3967 (slice-to-string Heap *(ebp+0xc)) # => eax -3968 89/<- %ecx 0/r32/eax -3969 # -3970 (allocate *(ebp+8) *Var-size) # => eax -3971 89/<- *eax 1/r32/ecx # Var-name -3972 89/<- %ecx 0/r32/eax -3973 (allocate *(ebp+8) *Tree-size) # => eax -3974 89/<- *(ecx+4) 0/r32/eax # Var-type -3975 89/<- %eax 1/r32/ecx -3976 c7 0/subop/copy *(eax+8) 0/imm32 # Var-block -3977 c7 0/subop/copy *(eax+0xc) 0/imm32 # Var-stack-offset -3978 c7 0/subop/copy *(eax+0x10) 0/imm32 # Var-register -3979 $new-label:end: -3980 # . restore registers -3981 59/pop-to-ecx -3982 # . epilogue -3983 89/<- %esp 5/r32/ebp -3984 5d/pop-to-ebp -3985 c3/return -3986 -3987 new-block: # ad: (addr allocation-descriptor), data: (handle list statement) -> result/eax: (handle statement) -3988 # . prologue -3989 55/push-ebp -3990 89/<- %ebp 4/r32/esp -3991 # . save registers -3992 51/push-ecx -3993 # -3994 (allocate *(ebp+8) *Stmt-size) # => eax -3995 (zero-out %eax *Stmt-size) -3996 c7 0/subop/copy *eax 0/imm32/tag/block # Stmt-tag -3997 8b/-> *(ebp+0xc) 1/r32/ecx -3998 89/<- *(eax+4) 1/r32/ecx # Block-statements -3999 $new-block:end: -4000 # . restore registers -4001 59/pop-to-ecx -4002 # . epilogue -4003 89/<- %esp 5/r32/ebp -4004 5d/pop-to-ebp -4005 c3/return -4006 -4007 new-vardef: # ad: (addr allocation-descriptor), var: (handle var) -> result/eax: (handle statement) -4008 # . prologue -4009 55/push-ebp -4010 89/<- %ebp 4/r32/esp -4011 # . save registers -4012 51/push-ecx -4013 # -4014 (allocate *(ebp+8) *Stmt-size) # => eax -4015 (zero-out %eax *Stmt-size) -4016 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag -4017 # result->var = var -4018 8b/-> *(ebp+0xc) 1/r32/ecx -4019 89/<- *(eax+4) 1/r32/ecx # Vardef-var -4020 $new-vardef:end: -4021 # . restore registers -4022 59/pop-to-ecx -4023 # . epilogue -4024 89/<- %esp 5/r32/ebp -4025 5d/pop-to-ebp -4026 c3/return -4027 -4028 new-regvardef: # ad: (addr allocation-descriptor), var: (handle var) -> result/eax: (handle statement) -4029 # . prologue -4030 55/push-ebp -4031 89/<- %ebp 4/r32/esp -4032 # . save registers -4033 51/push-ecx -4034 57/push-edi -4035 # ecx = var -4036 8b/-> *(ebp+0xc) 1/r32/ecx -4037 # edi = result -4038 (allocate *(ebp+8) *Stmt-size) # => eax -4039 89/<- %edi 0/r32/eax -4040 (zero-out %edi *Stmt-size) -4041 # set tag -4042 c7 0/subop/copy *edi 3/imm32/tag/var-in-register # Stmt-tag -4043 # set output -4044 (append-list Heap %ecx *(edi+0xc)) # Regvardef-outputs => eax -4045 89/<- *(edi+0xc) 0/r32/eax # Regvardef-outputs -4046 $new-regvardef:end: -4047 89/<- %eax 7/r32/edi -4048 # . restore registers -4049 5f/pop-to-edi -4050 59/pop-to-ecx -4051 # . epilogue -4052 89/<- %esp 5/r32/ebp -4053 5d/pop-to-ebp -4054 c3/return -4055 -4056 new-named-block: # ad: (addr allocation-descriptor), name: (addr array byte), data: (handle list statement) -> result/eax: (handle statement) -4057 # . prologue -4058 55/push-ebp -4059 89/<- %ebp 4/r32/esp -4060 # . save registers -4061 51/push-ecx -4062 # -4063 (allocate *(ebp+8) *Stmt-size) # => eax -4064 (zero-out %eax *Stmt-size) -4065 c7 0/subop/copy *eax 4/imm32/tag/named-block -4066 8b/-> *(ebp+0xc) 1/r32/ecx -4067 89/<- *(eax+8) 1/r32/ecx # Named-block-name -4068 8b/-> *(ebp+0x10) 1/r32/ecx -4069 89/<- *(eax+4) 1/r32/ecx # Named-block-statements -4070 $new-named-block:end: -4071 # . restore registers -4072 59/pop-to-ecx -4073 # . epilogue -4074 89/<- %esp 5/r32/ebp -4075 5d/pop-to-ebp -4076 c3/return -4077 -4078 new-list: # ad: (addr allocation-descriptor), value: _type, next: (handle list _type) -> result/eax: (handle list _type) -4079 # . prologue -4080 55/push-ebp -4081 89/<- %ebp 4/r32/esp -4082 # . save registers -4083 51/push-ecx -4084 # -4085 (allocate *(ebp+8) *List-size) # => eax -4086 8b/-> *(ebp+0xc) 1/r32/ecx -4087 89/<- *eax 1/r32/ecx # List-value -4088 8b/-> *(ebp+0x10) 1/r32/ecx -4089 89/<- *(eax+4) 1/r32/ecx # List-next -4090 $new-list:end: -4091 # . restore registers -4092 59/pop-to-ecx -4093 # . epilogue -4094 89/<- %esp 5/r32/ebp -4095 5d/pop-to-ebp -4096 c3/return -4097 -4098 append-list: # ad: (addr allocation-descriptor), value: _type, list: (handle list _type) -> result/eax: (handle list _type) -4099 # . prologue -4100 55/push-ebp -4101 89/<- %ebp 4/r32/esp -4102 # . save registers -4103 51/push-ecx -4104 # -4105 (allocate *(ebp+8) *List-size) # => eax -4106 8b/-> *(ebp+0xc) 1/r32/ecx -4107 89/<- *eax 1/r32/ecx # List-value -4108 # if (list == null) return result -4109 81 7/subop/compare *(ebp+0x10) 0/imm32 -4110 74/jump-if-= $new-list:end/disp8 -4111 # otherwise append -4112 # var curr/ecx = list -4113 8b/-> *(ebp+0x10) 1/r32/ecx -4114 # while (curr->next != null) curr = curr->next -4115 { -4116 81 7/subop/compare *(ecx+4) 0/imm32 # List-next -4117 74/jump-if-= break/disp8 -4118 # curr = curr->next -4119 8b/-> *(ecx+4) 1/r32/ecx -4120 eb/jump loop/disp8 -4121 } -4122 # curr->next = result -4123 89/<- *(ecx+4) 0/r32/eax -4124 # return list -4125 8b/-> *(ebp+0x10) 0/r32/eax -4126 $append-list:end: +3603 (new-literal-integer Heap %esi) # => eax +3604 eb/jump $lookup-var-or-literal:end/disp8 +3605 } +3606 # else if (c == '"') return new var(name) +3607 { +3608 81 7/subop/compare %ecx 0x22/imm32/dquote +3609 75/jump-if-!= break/disp8 +3610 (new-literal-string Heap %esi) # => eax +3611 eb/jump $lookup-var-or-literal:end/disp8 +3612 } +3613 # otherwise return lookup-var(name, vars) +3614 { +3615 (lookup-var %esi *(ebp+0xc)) # => eax +3616 } +3617 $lookup-var-or-literal:end: +3618 # . restore registers +3619 5e/pop-to-esi +3620 59/pop-to-ecx +3621 # . epilogue +3622 89/<- %esp 5/r32/ebp +3623 5d/pop-to-ebp +3624 c3/return +3625 +3626 $lookup-var-or-literal:abort: +3627 (write-buffered Stderr "empty variable!") +3628 (flush Stderr) +3629 # . syscall(exit, 1) +3630 bb/copy-to-ebx 1/imm32 +3631 b8/copy-to-eax 1/imm32/exit +3632 cd/syscall 0x80/imm8 +3633 # never gets here +3634 +3635 # return first 'name' from the top (back) of 'vars' and abort if not found +3636 lookup-var: # name: (addr slice), vars: (addr stack (handle var)) -> result/eax: (handle var) +3637 # . prologue +3638 55/push-ebp +3639 89/<- %ebp 4/r32/esp +3640 # var target/eax: (handle array byte) = slice-to-string(name) +3641 (slice-to-string Heap *(ebp+8)) # => eax +3642 # +3643 (lookup-var-helper %eax *(ebp+0xc)) # => eax +3644 # if (result == 0) abort +3645 3d/compare-eax-and 0/imm32 +3646 74/jump-if-= $lookup-var:abort/disp8 +3647 $lookup-var:end: +3648 # . epilogue +3649 89/<- %esp 5/r32/ebp +3650 5d/pop-to-ebp +3651 c3/return +3652 +3653 $lookup-var:abort: +3654 (write-buffered Stderr "unknown variable '") +3655 (write-slice-buffered Stderr *(ebp+8)) +3656 (write-buffered Stderr "'\n") +3657 (flush Stderr) +3658 # . syscall(exit, 1) +3659 bb/copy-to-ebx 1/imm32 +3660 b8/copy-to-eax 1/imm32/exit +3661 cd/syscall 0x80/imm8 +3662 # never gets here +3663 +3664 # return first 'name' from the top (back) of 'vars', and 0/null if not found +3665 lookup-var-helper: # name: (addr array byte), vars: (addr stack (handle var)) -> result/eax: (handle var) +3666 # pseudocode: +3667 # var curr: (addr handle var) = &vars->data[vars->top - 4] +3668 # var min = vars->data +3669 # while curr >= min +3670 # var v: (handle var) = *curr +3671 # if v->name == name +3672 # return v +3673 # return 0 +3674 # +3675 # . prologue +3676 55/push-ebp +3677 89/<- %ebp 4/r32/esp +3678 # . save registers +3679 52/push-edx +3680 53/push-ebx +3681 56/push-esi +3682 # esi = vars +3683 8b/-> *(ebp+0xc) 6/r32/esi +3684 # ebx = vars->top +3685 8b/-> *esi 3/r32/ebx +3686 # if (vars->top > vars->length) abort +3687 3b/compare 0/r32/eax *(esi+4) +3688 0f 8f/jump-if-> $lookup-var-helper:error1/disp32 +3689 # var min/edx: (addr handle var) = vars->data +3690 8d/copy-address *(esi+8) 2/r32/edx +3691 # var curr/ebx: (addr handle var) = &vars->data[vars->top - 4] +3692 81 5/subop/subtract %ebx 4/imm32 +3693 8d/copy-address *(esi+ebx+8) 3/r32/ebx +3694 { +3695 # if (curr < min) return 0 +3696 39/compare %ebx 2/r32/edx +3697 b8/copy-to-eax 0/imm32 +3698 0f 82/jump-if-addr< break/disp32 +3699 # var v/eax: (handle var) = *curr +3700 8b/-> *ebx 0/r32/eax +3701 # if (v->name == name) return v +3702 (string-equal? *eax *(ebp+8)) # Var-name +3703 3d/compare-eax-and 0/imm32 +3704 8b/-> *ebx 0/r32/eax +3705 75/jump-if-!= break/disp8 +3706 # curr -= 4 +3707 81 5/subop/subtract %ebx 4/imm32 +3708 e9/jump loop/disp32 +3709 } +3710 $lookup-var-helper:end: +3711 # . restore registers +3712 5e/pop-to-esi +3713 5b/pop-to-ebx +3714 5a/pop-to-edx +3715 # . epilogue +3716 89/<- %esp 5/r32/ebp +3717 5d/pop-to-ebp +3718 c3/return +3719 +3720 $lookup-var-helper:error1: +3721 (write-buffered Stderr "malformed stack when looking up '") +3722 (write-slice-buffered Stderr *(ebp+8)) +3723 (write-buffered Stderr "'\n") +3724 (flush Stderr) +3725 # . syscall(exit, 1) +3726 bb/copy-to-ebx 1/imm32 +3727 b8/copy-to-eax 1/imm32/exit +3728 cd/syscall 0x80/imm8 +3729 # never gets here +3730 +3731 # return first 'name' from the top (back) of 'vars' and create a new var for a fn output if not found +3732 lookup-or-define-var: # name: (addr slice), vars: (addr stack (handle var)), fn: (handle function) -> result/eax: (handle var) +3733 # . prologue +3734 55/push-ebp +3735 89/<- %ebp 4/r32/esp +3736 # . save registers +3737 51/push-ecx +3738 # var target/ecx: (handle array byte) = slice-to-string(name) +3739 (slice-to-string Heap *(ebp+8)) # => eax +3740 89/<- %ecx 0/r32/eax +3741 # +3742 (lookup-var-helper %ecx *(ebp+0xc)) # => eax +3743 { +3744 # if (result != 0) return +3745 3d/compare-eax-and 0/imm32 +3746 75/jump-if-!= break/disp8 +3747 # if name is one of fn's outputs, return it +3748 { +3749 (find-in-function-outputs *(ebp+0x10) %ecx) # => eax +3750 3d/compare-eax-and 0/imm32 +3751 # otherwise abort +3752 0f 84/jump-if-!= $lookup-var:abort/disp32 +3753 } +3754 } +3755 $lookup-or-define-var:end: +3756 # . restore registers +3757 59/pop-to-ecx +3758 # . epilogue +3759 89/<- %esp 5/r32/ebp +3760 5d/pop-to-ebp +3761 c3/return +3762 +3763 find-in-function-outputs: # fn: (handle function), name: (handle array byte) => result/eax: (handle var) +3764 # . prologue +3765 55/push-ebp +3766 89/<- %ebp 4/r32/esp +3767 # . save registers +3768 51/push-ecx +3769 # var curr/ecx: (handle list var) = fn->outputs +3770 8b/-> *(ebp+8) 1/r32/ecx +3771 8b/-> *(ecx+0xc) 1/r32/ecx +3772 # while curr != null +3773 { +3774 81 7/subop/compare %ecx 0/imm32 +3775 74/jump-if-= break/disp8 +3776 # var v: (handle var) = *curr +3777 8b/-> *ecx 0/r32/eax # List-value +3778 # if (curr->name == name) return curr +3779 50/push-eax +3780 (string-equal? *eax *(ebp+0xc)) +3781 3d/compare-eax-and 0/imm32 +3782 58/pop-to-eax +3783 75/jump-if-!= $find-in-function-outputs:end/disp8 +3784 # curr = curr->next +3785 8b/-> *(ecx+4) 1/r32/ecx # List-next +3786 eb/jump loop/disp8 +3787 } +3788 b8/copy-to-eax 0/imm32 +3789 $find-in-function-outputs:end: +3790 # . restore registers +3791 59/pop-to-ecx +3792 # . epilogue +3793 89/<- %esp 5/r32/ebp +3794 5d/pop-to-ebp +3795 c3/return +3796 +3797 test-parse-mu-stmt: +3798 # 'increment n' +3799 # . prologue +3800 55/push-ebp +3801 89/<- %ebp 4/r32/esp +3802 # setup +3803 (clear-stream _test-input-stream) +3804 (write _test-input-stream "increment n\n") +3805 # var vars/ecx: (stack (addr var) 4) +3806 81 5/subop/subtract %esp 0x10/imm32 +3807 68/push 0x10/imm32/length +3808 68/push 0/imm32/top +3809 89/<- %ecx 4/r32/esp +3810 (clear-stack %ecx) +3811 # var v/edx: var +3812 81 5/subop/subtract %esp 0x14/imm32 # Var-size +3813 89/<- %edx 4/r32/esp +3814 (zero-out %edx 0x14) +3815 # v->name = "n" +3816 c7 0/subop/copy *edx "n"/imm32 # Var-name +3817 # +3818 (push %ecx %edx) +3819 # convert +3820 (parse-mu-stmt _test-input-stream %ecx) # => eax +3821 # check result +3822 (check-ints-equal *eax 1 "F - test-parse-mu-stmt/tag") # Stmt-tag is Stmt1 +3823 (check-strings-equal *(eax+4) "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation +3824 # edx: (handle list var) = result->inouts +3825 8b/-> *(eax+8) 2/r32/edx # Stmt1-inouts +3826 # ebx: (handle var) = result->inouts->value +3827 8b/-> *edx 3/r32/ebx # List-value +3828 (check-strings-equal *ebx "n" "F - test-parse-mu-stmt/inout:0") # Var-name +3829 # . epilogue +3830 89/<- %esp 5/r32/ebp +3831 5d/pop-to-ebp +3832 c3/return +3833 +3834 test-parse-mu-stmt-with-comma: +3835 # 'increment n' +3836 # . prologue +3837 55/push-ebp +3838 89/<- %ebp 4/r32/esp +3839 # setup +3840 (clear-stream _test-input-stream) +3841 (write _test-input-stream "copy-to n, 3\n") +3842 # var vars/ecx: (stack (addr var) 4) +3843 81 5/subop/subtract %esp 0x10/imm32 +3844 68/push 0x10/imm32/length +3845 68/push 0/imm32/top +3846 89/<- %ecx 4/r32/esp +3847 (clear-stack %ecx) +3848 # var v/edx: var +3849 81 5/subop/subtract %esp 0x14/imm32 # Var-size +3850 89/<- %edx 4/r32/esp +3851 (zero-out %edx 0x14) +3852 # v->name = "n" +3853 c7 0/subop/copy *edx "n"/imm32 # Var-name +3854 # +3855 (push %ecx %edx) +3856 # convert +3857 (parse-mu-stmt _test-input-stream %ecx) # => eax +3858 # check result +3859 (check-ints-equal *eax 1 "F - test-parse-mu-stmt-with-comma/tag") # Stmt-tag is Stmt1 +3860 (check-strings-equal *(eax+4) "copy-to" "F - test-parse-mu-stmt-with-comma/name") # Stmt1-operation +3861 # edx: (handle list var) = result->inouts +3862 8b/-> *(eax+8) 2/r32/edx # Stmt1-inouts +3863 # ebx: (handle var) = result->inouts->value +3864 8b/-> *edx 3/r32/ebx # List-value +3865 (check-strings-equal *ebx "n" "F - test-parse-mu-stmt-with-comma/inout:0") # Var-name +3866 # . epilogue +3867 89/<- %esp 5/r32/ebp +3868 5d/pop-to-ebp +3869 c3/return +3870 +3871 new-function: # ad: (addr allocation-descriptor), name: (addr array byte), subx-name: (addr array byte), inouts: (handle list var), outputs: (handle list var), body: (handle block), next: (handle function) -> result/eax: (handle function) +3872 # . prologue +3873 55/push-ebp +3874 89/<- %ebp 4/r32/esp +3875 # . save registers +3876 51/push-ecx +3877 # +3878 (allocate *(ebp+8) *Function-size) # => eax +3879 8b/-> *(ebp+0xc) 1/r32/ecx +3880 89/<- *eax 1/r32/ecx # Function-name +3881 8b/-> *(ebp+0x10) 1/r32/ecx +3882 89/<- *(eax+4) 1/r32/ecx # Function-subx-name +3883 8b/-> *(ebp+0x14) 1/r32/ecx +3884 89/<- *(eax+8) 1/r32/ecx # Function-inouts +3885 8b/-> *(ebp+0x18) 1/r32/ecx +3886 89/<- *(eax+0xc) 1/r32/ecx # Function-outputs +3887 8b/-> *(ebp+0x1c) 1/r32/ecx +3888 89/<- *(eax+0x10) 1/r32/ecx # Function-body +3889 8b/-> *(ebp+0x20) 1/r32/ecx +3890 89/<- *(eax+0x14) 1/r32/ecx # Function-next +3891 $new-function:end: +3892 # . restore registers +3893 59/pop-to-ecx +3894 # . epilogue +3895 89/<- %esp 5/r32/ebp +3896 5d/pop-to-ebp +3897 c3/return +3898 +3899 new-var: # ad: (addr allocation-descriptor), name: (addr array byte), type: int, block: int, stack-offset: int, register: (addr array byte) -> result/eax: (handle var) +3900 # . prologue +3901 55/push-ebp +3902 89/<- %ebp 4/r32/esp +3903 # . save registers +3904 51/push-ecx +3905 # +3906 (allocate *(ebp+8) *Var-size) # => eax +3907 8b/-> *(ebp+0xc) 1/r32/ecx +3908 89/<- *eax 1/r32/ecx # Var-name +3909 8b/-> *(ebp+0x10) 1/r32/ecx +3910 89/<- *(eax+4) 1/r32/ecx # Var-type +3911 8b/-> *(ebp+0x14) 1/r32/ecx +3912 89/<- *(eax+8) 1/r32/ecx # Var-block +3913 8b/-> *(ebp+0x18) 1/r32/ecx +3914 89/<- *(eax+0xc) 1/r32/ecx # Var-stack-offset +3915 8b/-> *(ebp+0x1c) 1/r32/ecx +3916 89/<- *(eax+0x10) 1/r32/ecx # Var-register +3917 $new-var:end: +3918 # . restore registers +3919 59/pop-to-ecx +3920 # . epilogue +3921 89/<- %esp 5/r32/ebp +3922 5d/pop-to-ebp +3923 c3/return +3924 +3925 new-literal-integer: # ad: (addr allocation-descriptor), name: (addr slice) -> result/eax: (handle var) +3926 # . prologue +3927 55/push-ebp +3928 89/<- %ebp 4/r32/esp +3929 # . save registers +3930 51/push-ecx +3931 # if (!is-hex-int?(name)) abort +3932 (is-hex-int? *(ebp+0xc)) # => eax +3933 3d/compare-eax-and 0/imm32 +3934 0f 84/jump-if-= $new-literal-integer:abort/disp32 +3935 # var s/ecx: (addr array byte) +3936 (slice-to-string Heap *(ebp+0xc)) # => eax +3937 89/<- %ecx 0/r32/eax +3938 # result/ecx = new var(s) +3939 (allocate *(ebp+8) *Var-size) # => eax +3940 (zero-out %eax *Var-size) +3941 89/<- *eax 1/r32/ecx # Var-name +3942 89/<- %ecx 0/r32/eax +3943 # result->type = new type() +3944 (allocate *(ebp+8) *Tree-size) # => eax +3945 (zero-out %eax *Tree-size) # default type is 'literal' +3946 89/<- *(ecx+4) 0/r32/eax # Var-type +3947 # move result to eax +3948 89/<- %eax 1/r32/ecx +3949 $new-literal-integer:end: +3950 # . restore registers +3951 59/pop-to-ecx +3952 # . epilogue +3953 89/<- %esp 5/r32/ebp +3954 5d/pop-to-ebp +3955 c3/return +3956 +3957 $new-literal-integer:abort: +3958 (write-buffered Stderr "variable cannot begin with a digit '") +3959 (write-slice-buffered Stderr *(ebp+0xc)) +3960 (write-buffered Stderr "'\n") +3961 (flush Stderr) +3962 # . syscall(exit, 1) +3963 bb/copy-to-ebx 1/imm32 +3964 b8/copy-to-eax 1/imm32/exit +3965 cd/syscall 0x80/imm8 +3966 # never gets here +3967 +3968 new-literal-string: # ad: (addr allocation-descriptor), name: (addr slice) -> result/eax: (handle var) +3969 # . prologue +3970 55/push-ebp +3971 89/<- %ebp 4/r32/esp +3972 # . save registers +3973 51/push-ecx +3974 # var s/ecx: (addr array byte) +3975 (slice-to-string Heap *(ebp+0xc)) # => eax +3976 89/<- %ecx 0/r32/eax +3977 # result/ecx = new var(s) +3978 (allocate *(ebp+8) *Var-size) # => eax +3979 (zero-out %eax) +3980 89/<- *eax 1/r32/ecx # Var-name +3981 89/<- %ecx 0/r32/eax +3982 # result->type = new type() +3983 (allocate *(ebp+8) *Tree-size) # => eax +3984 (zero-out %eax) # default type is 'literal' +3985 89/<- *(ecx+4) 0/r32/eax # Var-type +3986 # move result to eax +3987 89/<- %eax 1/r32/ecx +3988 $new-literal-string:end: +3989 # . restore registers +3990 59/pop-to-ecx +3991 # . epilogue +3992 89/<- %esp 5/r32/ebp +3993 5d/pop-to-ebp +3994 c3/return +3995 +3996 new-label: # ad: (addr allocation-descriptor), name: (addr slice) -> result/eax: (handle var) +3997 # . prologue +3998 55/push-ebp +3999 89/<- %ebp 4/r32/esp +4000 # . save registers +4001 51/push-ecx +4002 # var s/ecx: (addr array byte) +4003 (slice-to-string Heap *(ebp+0xc)) # => eax +4004 89/<- %ecx 0/r32/eax +4005 # +4006 (allocate *(ebp+8) *Var-size) # => eax +4007 89/<- *eax 1/r32/ecx # Var-name +4008 89/<- %ecx 0/r32/eax +4009 (allocate *(ebp+8) *Tree-size) # => eax +4010 89/<- *(ecx+4) 0/r32/eax # Var-type +4011 89/<- %eax 1/r32/ecx +4012 c7 0/subop/copy *(eax+8) 0/imm32 # Var-block +4013 c7 0/subop/copy *(eax+0xc) 0/imm32 # Var-stack-offset +4014 c7 0/subop/copy *(eax+0x10) 0/imm32 # Var-register +4015 $new-label:end: +4016 # . restore registers +4017 59/pop-to-ecx +4018 # . epilogue +4019 89/<- %esp 5/r32/ebp +4020 5d/pop-to-ebp +4021 c3/return +4022 +4023 new-block: # ad: (addr allocation-descriptor), data: (handle list statement) -> result/eax: (handle statement) +4024 # . prologue +4025 55/push-ebp +4026 89/<- %ebp 4/r32/esp +4027 # . save registers +4028 51/push-ecx +4029 # +4030 (allocate *(ebp+8) *Stmt-size) # => eax +4031 (zero-out %eax *Stmt-size) +4032 c7 0/subop/copy *eax 0/imm32/tag/block # Stmt-tag +4033 8b/-> *(ebp+0xc) 1/r32/ecx +4034 89/<- *(eax+4) 1/r32/ecx # Block-statements +4035 $new-block:end: +4036 # . restore registers +4037 59/pop-to-ecx +4038 # . epilogue +4039 89/<- %esp 5/r32/ebp +4040 5d/pop-to-ebp +4041 c3/return +4042 +4043 new-vardef: # ad: (addr allocation-descriptor), var: (handle var) -> result/eax: (handle statement) +4044 # . prologue +4045 55/push-ebp +4046 89/<- %ebp 4/r32/esp +4047 # . save registers +4048 51/push-ecx +4049 # +4050 (allocate *(ebp+8) *Stmt-size) # => eax +4051 (zero-out %eax *Stmt-size) +4052 c7 0/subop/copy *eax 2/imm32/tag/var-on-stack # Stmt-tag +4053 # result->var = var +4054 8b/-> *(ebp+0xc) 1/r32/ecx +4055 89/<- *(eax+4) 1/r32/ecx # Vardef-var +4056 $new-vardef:end: +4057 # . restore registers +4058 59/pop-to-ecx +4059 # . epilogue +4060 89/<- %esp 5/r32/ebp +4061 5d/pop-to-ebp +4062 c3/return +4063 +4064 new-regvardef: # ad: (addr allocation-descriptor), var: (handle var) -> result/eax: (handle statement) +4065 # . prologue +4066 55/push-ebp +4067 89/<- %ebp 4/r32/esp +4068 # . save registers +4069 51/push-ecx +4070 57/push-edi +4071 # ecx = var +4072 8b/-> *(ebp+0xc) 1/r32/ecx +4073 # edi = result +4074 (allocate *(ebp+8) *Stmt-size) # => eax +4075 89/<- %edi 0/r32/eax +4076 (zero-out %edi *Stmt-size) +4077 # set tag +4078 c7 0/subop/copy *edi 3/imm32/tag/var-in-register # Stmt-tag +4079 # set output +4080 (append-list Heap %ecx *(edi+0xc)) # Regvardef-outputs => eax +4081 89/<- *(edi+0xc) 0/r32/eax # Regvardef-outputs +4082 $new-regvardef:end: +4083 89/<- %eax 7/r32/edi +4084 # . restore registers +4085 5f/pop-to-edi +4086 59/pop-to-ecx +4087 # . epilogue +4088 89/<- %esp 5/r32/ebp +4089 5d/pop-to-ebp +4090 c3/return +4091 +4092 new-named-block: # ad: (addr allocation-descriptor), name: (addr array byte), data: (handle list statement) -> result/eax: (handle statement) +4093 # . prologue +4094 55/push-ebp +4095 89/<- %ebp 4/r32/esp +4096 # . save registers +4097 51/push-ecx +4098 # +4099 (allocate *(ebp+8) *Stmt-size) # => eax +4100 (zero-out %eax *Stmt-size) +4101 c7 0/subop/copy *eax 4/imm32/tag/named-block +4102 8b/-> *(ebp+0xc) 1/r32/ecx +4103 89/<- *(eax+8) 1/r32/ecx # Named-block-name +4104 8b/-> *(ebp+0x10) 1/r32/ecx +4105 89/<- *(eax+4) 1/r32/ecx # Named-block-statements +4106 $new-named-block:end: +4107 # . restore registers +4108 59/pop-to-ecx +4109 # . epilogue +4110 89/<- %esp 5/r32/ebp +4111 5d/pop-to-ebp +4112 c3/return +4113 +4114 new-list: # ad: (addr allocation-descriptor), value: _type, next: (handle list _type) -> result/eax: (handle list _type) +4115 # . prologue +4116 55/push-ebp +4117 89/<- %ebp 4/r32/esp +4118 # . save registers +4119 51/push-ecx +4120 # +4121 (allocate *(ebp+8) *List-size) # => eax +4122 8b/-> *(ebp+0xc) 1/r32/ecx +4123 89/<- *eax 1/r32/ecx # List-value +4124 8b/-> *(ebp+0x10) 1/r32/ecx +4125 89/<- *(eax+4) 1/r32/ecx # List-next +4126 $new-list:end: 4127 # . restore registers 4128 59/pop-to-ecx 4129 # . epilogue @@ -4113,3613 +4113,3649 @@ if ('onhashchange' in window) { 4131 5d/pop-to-ebp 4132 c3/return 4133 -4134 append-to-block: # ad: (addr allocation-descriptor), block: (handle block), x: (handle stmt) +4134 append-list: # ad: (addr allocation-descriptor), value: _type, list: (handle list _type) -> result/eax: (handle list _type) 4135 # . prologue 4136 55/push-ebp 4137 89/<- %ebp 4/r32/esp 4138 # . save registers -4139 56/push-esi -4140 # esi = block -4141 8b/-> *(ebp+0xc) 6/r32/esi -4142 (append-list *(ebp+8) *(ebp+0x10) *(esi+4)) # ad, x, Block-statements -4143 89/<- *(esi+4) 0/r32/eax # Block-statements -4144 $append-to-block:end: -4145 # . restore registers -4146 5e/pop-to-esi -4147 # . epilogue -4148 89/<- %esp 5/r32/ebp -4149 5d/pop-to-ebp -4150 c3/return -4151 -4152 ####################################################### -4153 # Type-checking -4154 ####################################################### -4155 -4156 check-mu-types: -4157 # . prologue -4158 55/push-ebp -4159 89/<- %ebp 4/r32/esp -4160 # -4161 $check-mu-types:end: -4162 # . epilogue -4163 89/<- %esp 5/r32/ebp -4164 5d/pop-to-ebp -4165 c3/return -4166 -4167 size-of: # n: (addr var) -> result/eax: int -4168 # . prologue -4169 55/push-ebp -4170 89/<- %ebp 4/r32/esp -4171 # hard-coded since we only support 'int' types for now -4172 b8/copy-to-eax 4/imm32 -4173 $size-of:end: -4174 # . epilogue -4175 89/<- %esp 5/r32/ebp -4176 5d/pop-to-ebp -4177 c3/return -4178 -4179 == data -4180 -4181 # not yet used, but it will be -4182 Type-size: # (stream int) -4183 0x18/imm32/write -4184 0/imm32/read -4185 0x100/imm32/length -4186 # data -4187 4/imm32 # literal -4188 4/imm32 # int -4189 4/imm32 # addr -4190 0/imm32 # array (logic elsewhere) -4191 8/imm32 # handle (fat pointer) -4192 4/imm32 # bool -4193 0/imm32 -4194 0/imm32 -4195 # 0x20 -4196 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 -4197 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 -4198 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 -4199 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 -4200 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 -4201 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 -4202 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 -4203 -4204 == code -4205 -4206 ####################################################### -4207 # Code-generation -4208 ####################################################### -4209 -4210 emit-subx: # out: (addr buffered-file) -4211 # . prologue -4212 55/push-ebp -4213 89/<- %ebp 4/r32/esp -4214 # . save registers -4215 50/push-eax -4216 51/push-ecx -4217 57/push-edi -4218 # edi = out -4219 8b/-> *(ebp+8) 7/r32/edi -4220 # var curr/ecx: (handle function) = *Program -4221 8b/-> *Program 1/r32/ecx -4222 { -4223 # if (curr == null) break -4224 81 7/subop/compare %ecx 0/imm32 -4225 0f 84/jump-if-= break/disp32 -4226 (emit-subx-function %edi %ecx) -4227 # curr = curr->next -4228 8b/-> *(ecx+0x14) 1/r32/ecx # Function-next -4229 e9/jump loop/disp32 -4230 } -4231 $emit-subx:end: -4232 # . restore registers -4233 5f/pop-to-edi -4234 59/pop-to-ecx -4235 58/pop-to-eax -4236 # . epilogue -4237 89/<- %esp 5/r32/ebp -4238 5d/pop-to-ebp -4239 c3/return -4240 -4241 emit-subx-function: # out: (addr buffered-file), f: (handle function) -4242 # . prologue -4243 55/push-ebp -4244 89/<- %ebp 4/r32/esp -4245 # . save registers -4246 50/push-eax -4247 51/push-ecx -4248 52/push-edx -4249 57/push-edi -4250 # edi = out -4251 8b/-> *(ebp+8) 7/r32/edi -4252 # ecx = f -4253 8b/-> *(ebp+0xc) 1/r32/ecx -4254 # var vars/edx: (stack (addr var) 256) -4255 81 5/subop/subtract %esp 0x400/imm32 -4256 68/push 0x400/imm32/length -4257 68/push 0/imm32/top -4258 89/<- %edx 4/r32/esp -4259 # -4260 (write-buffered %edi *ecx) -4261 (write-buffered %edi ":\n") -4262 (emit-subx-prologue %edi) -4263 (emit-subx-block %edi *(ecx+0x10) %edx) # Function-body -4264 (emit-subx-epilogue %edi) -4265 $emit-subx-function:end: -4266 # . reclaim locals -4267 81 0/subop/add %esp 408/imm32 +4139 51/push-ecx +4140 # +4141 (allocate *(ebp+8) *List-size) # => eax +4142 8b/-> *(ebp+0xc) 1/r32/ecx +4143 89/<- *eax 1/r32/ecx # List-value +4144 # if (list == null) return result +4145 81 7/subop/compare *(ebp+0x10) 0/imm32 +4146 74/jump-if-= $new-list:end/disp8 +4147 # otherwise append +4148 # var curr/ecx = list +4149 8b/-> *(ebp+0x10) 1/r32/ecx +4150 # while (curr->next != null) curr = curr->next +4151 { +4152 81 7/subop/compare *(ecx+4) 0/imm32 # List-next +4153 74/jump-if-= break/disp8 +4154 # curr = curr->next +4155 8b/-> *(ecx+4) 1/r32/ecx +4156 eb/jump loop/disp8 +4157 } +4158 # curr->next = result +4159 89/<- *(ecx+4) 0/r32/eax +4160 # return list +4161 8b/-> *(ebp+0x10) 0/r32/eax +4162 $append-list:end: +4163 # . restore registers +4164 59/pop-to-ecx +4165 # . epilogue +4166 89/<- %esp 5/r32/ebp +4167 5d/pop-to-ebp +4168 c3/return +4169 +4170 append-to-block: # ad: (addr allocation-descriptor), block: (handle block), x: (handle stmt) +4171 # . prologue +4172 55/push-ebp +4173 89/<- %ebp 4/r32/esp +4174 # . save registers +4175 56/push-esi +4176 # esi = block +4177 8b/-> *(ebp+0xc) 6/r32/esi +4178 (append-list *(ebp+8) *(ebp+0x10) *(esi+4)) # ad, x, Block-statements +4179 89/<- *(esi+4) 0/r32/eax # Block-statements +4180 $append-to-block:end: +4181 # . restore registers +4182 5e/pop-to-esi +4183 # . epilogue +4184 89/<- %esp 5/r32/ebp +4185 5d/pop-to-ebp +4186 c3/return +4187 +4188 ####################################################### +4189 # Type-checking +4190 ####################################################### +4191 +4192 check-mu-types: +4193 # . prologue +4194 55/push-ebp +4195 89/<- %ebp 4/r32/esp +4196 # +4197 $check-mu-types:end: +4198 # . epilogue +4199 89/<- %esp 5/r32/ebp +4200 5d/pop-to-ebp +4201 c3/return +4202 +4203 size-of: # n: (addr var) -> result/eax: int +4204 # . prologue +4205 55/push-ebp +4206 89/<- %ebp 4/r32/esp +4207 # hard-coded since we only support 'int' types for now +4208 b8/copy-to-eax 4/imm32 +4209 $size-of:end: +4210 # . epilogue +4211 89/<- %esp 5/r32/ebp +4212 5d/pop-to-ebp +4213 c3/return +4214 +4215 == data +4216 +4217 # not yet used, but it will be +4218 Type-size: # (stream int) +4219 0x18/imm32/write +4220 0/imm32/read +4221 0x100/imm32/length +4222 # data +4223 4/imm32 # literal +4224 4/imm32 # int +4225 4/imm32 # addr +4226 0/imm32 # array (logic elsewhere) +4227 8/imm32 # handle (fat pointer) +4228 4/imm32 # bool +4229 0/imm32 +4230 0/imm32 +4231 # 0x20 +4232 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 +4233 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 +4234 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 +4235 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 +4236 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 +4237 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 +4238 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 +4239 +4240 == code +4241 +4242 ####################################################### +4243 # Code-generation +4244 ####################################################### +4245 +4246 emit-subx: # out: (addr buffered-file) +4247 # . prologue +4248 55/push-ebp +4249 89/<- %ebp 4/r32/esp +4250 # . save registers +4251 50/push-eax +4252 51/push-ecx +4253 57/push-edi +4254 # edi = out +4255 8b/-> *(ebp+8) 7/r32/edi +4256 # var curr/ecx: (handle function) = *Program +4257 8b/-> *Program 1/r32/ecx +4258 { +4259 # if (curr == null) break +4260 81 7/subop/compare %ecx 0/imm32 +4261 0f 84/jump-if-= break/disp32 +4262 (emit-subx-function %edi %ecx) +4263 # curr = curr->next +4264 8b/-> *(ecx+0x14) 1/r32/ecx # Function-next +4265 e9/jump loop/disp32 +4266 } +4267 $emit-subx:end: 4268 # . restore registers 4269 5f/pop-to-edi -4270 5a/pop-to-edx -4271 59/pop-to-ecx -4272 58/pop-to-eax -4273 # . epilogue -4274 89/<- %esp 5/r32/ebp -4275 5d/pop-to-ebp -4276 c3/return -4277 -4278 emit-subx-block: # out: (addr buffered-file), block: (handle block), vars: (addr stack (handle var)) -4279 # . prologue -4280 55/push-ebp -4281 89/<- %ebp 4/r32/esp -4282 # . save registers -4283 56/push-esi -4284 # var stmts/esi: (handle list statement) = block->statements -4285 8b/-> *(ebp+0xc) 6/r32/esi -4286 8b/-> *(esi+4) 6/r32/esi # Block-statements -4287 # -4288 { -4289 $emit-subx-block:check-empty: -4290 81 7/subop/compare %esi 0/imm32 -4291 0f 84/jump-if-= break/disp32 -4292 (write-buffered *(ebp+8) "{\n") -4293 (emit-subx-stmt-list *(ebp+8) %esi *(ebp+0x10)) -4294 (write-buffered *(ebp+8) "}\n") -4295 } -4296 $emit-subx-block:end: -4297 # . restore registers -4298 5e/pop-to-esi -4299 # . epilogue -4300 89/<- %esp 5/r32/ebp -4301 5d/pop-to-ebp -4302 c3/return -4303 -4304 emit-subx-stmt-list: # out: (addr buffered-file), stmts: (handle list stmt), vars: (addr stack (handle var)) -4305 # . prologue -4306 55/push-ebp -4307 89/<- %ebp 4/r32/esp -4308 # . save registers -4309 50/push-eax -4310 51/push-ecx -4311 56/push-esi -4312 # esi = stmts -4313 8b/-> *(ebp+0xc) 6/r32/esi -4314 # -4315 { -4316 $emit-subx-stmt-list:loop: -4317 81 7/subop/compare %esi 0/imm32 -4318 0f 84/jump-if-= break/disp32 -4319 # var curr-stmt/ecx = stmts->value -4320 8b/-> *esi 1/r32/ecx # List-value -4321 { -4322 $emit-subx-stmt-list:check-for-block: -4323 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag -4324 75/jump-if-!= break/disp8 -4325 $emit-subx-stmt-list:block: -4326 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10)) -4327 } -4328 { -4329 $emit-subx-stmt-list:check-for-stmt: -4330 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag -4331 75/jump-if-!= break/disp8 -4332 $emit-subx-stmt-list:stmt: -4333 (emit-subx-statement *(ebp+8) %ecx Primitives *Program) -4334 } -4335 { -4336 $emit-subx-stmt-list:check-for-vardef: -4337 81 7/subop/compare *ecx 2/imm32/vardef # Stmt-tag -4338 75/jump-if-!= break/disp8 -4339 $emit-subx-stmt-list:vardef: -4340 (emit-subx-var-def *(ebp+8) %ecx) -4341 (push *(ebp+0x10) *(ecx+4)) # Vardef-var -4342 } -4343 { -4344 $emit-subx-stmt-list:check-for-regvardef: -4345 81 7/subop/compare *ecx 3/imm32/regvardef # Stmt-tag -4346 0f 85/jump-if-!= break/disp32 -4347 $emit-subx-stmt-list:regvardef: -4348 # TODO: ensure that there's exactly one output -4349 # var output/eax: (handle var) = curr-stmt->outputs->value -4350 8b/-> *(ecx+0xc) 0/r32/eax -4351 8b/-> *eax 0/r32/eax -4352 # ensure that output is in a register -4353 81 7/subop/compare *(eax+0x10) 0/imm32 # Var-register -4354 0f 84/jump-if-= $emit-subx-stmt-list:abort-regvardef-without-register/disp32 -4355 # emit spill -4356 (write-buffered *(ebp+8) "ff 6/subop/push %") -4357 (write-buffered *(ebp+8) *(eax+0x10)) -4358 (write-buffered *(ebp+8) Newline) -4359 # register variable definition -4360 (push *(ebp+0x10) %eax) -4361 # emit the instruction as usual -4362 (emit-subx-statement *(ebp+8) %ecx Primitives *Program) +4270 59/pop-to-ecx +4271 58/pop-to-eax +4272 # . epilogue +4273 89/<- %esp 5/r32/ebp +4274 5d/pop-to-ebp +4275 c3/return +4276 +4277 emit-subx-function: # out: (addr buffered-file), f: (handle function) +4278 # . prologue +4279 55/push-ebp +4280 89/<- %ebp 4/r32/esp +4281 # . save registers +4282 50/push-eax +4283 51/push-ecx +4284 52/push-edx +4285 57/push-edi +4286 # edi = out +4287 8b/-> *(ebp+8) 7/r32/edi +4288 # ecx = f +4289 8b/-> *(ebp+0xc) 1/r32/ecx +4290 # var vars/edx: (stack (addr var) 256) +4291 81 5/subop/subtract %esp 0x400/imm32 +4292 68/push 0x400/imm32/length +4293 68/push 0/imm32/top +4294 89/<- %edx 4/r32/esp +4295 # +4296 (write-buffered %edi *ecx) +4297 (write-buffered %edi ":\n") +4298 (emit-subx-prologue %edi) +4299 (emit-subx-block %edi *(ecx+0x10) %edx) # Function-body +4300 (emit-subx-epilogue %edi) +4301 $emit-subx-function:end: +4302 # . reclaim locals +4303 81 0/subop/add %esp 408/imm32 +4304 # . restore registers +4305 5f/pop-to-edi +4306 5a/pop-to-edx +4307 59/pop-to-ecx +4308 58/pop-to-eax +4309 # . epilogue +4310 89/<- %esp 5/r32/ebp +4311 5d/pop-to-ebp +4312 c3/return +4313 +4314 emit-subx-block: # out: (addr buffered-file), block: (handle block), vars: (addr stack (handle var)) +4315 # . prologue +4316 55/push-ebp +4317 89/<- %ebp 4/r32/esp +4318 # . save registers +4319 56/push-esi +4320 # var stmts/esi: (handle list statement) = block->statements +4321 8b/-> *(ebp+0xc) 6/r32/esi +4322 8b/-> *(esi+4) 6/r32/esi # Block-statements +4323 # +4324 { +4325 $emit-subx-block:check-empty: +4326 81 7/subop/compare %esi 0/imm32 +4327 0f 84/jump-if-= break/disp32 +4328 (write-buffered *(ebp+8) "{\n") +4329 (emit-subx-stmt-list *(ebp+8) %esi *(ebp+0x10)) +4330 (write-buffered *(ebp+8) "}\n") +4331 } +4332 $emit-subx-block:end: +4333 # . restore registers +4334 5e/pop-to-esi +4335 # . epilogue +4336 89/<- %esp 5/r32/ebp +4337 5d/pop-to-ebp +4338 c3/return +4339 +4340 emit-subx-stmt-list: # out: (addr buffered-file), stmts: (handle list stmt), vars: (addr stack (handle var)) +4341 # . prologue +4342 55/push-ebp +4343 89/<- %ebp 4/r32/esp +4344 # . save registers +4345 50/push-eax +4346 51/push-ecx +4347 56/push-esi +4348 # esi = stmts +4349 8b/-> *(ebp+0xc) 6/r32/esi +4350 # +4351 { +4352 $emit-subx-stmt-list:loop: +4353 81 7/subop/compare %esi 0/imm32 +4354 0f 84/jump-if-= break/disp32 +4355 # var curr-stmt/ecx = stmts->value +4356 8b/-> *esi 1/r32/ecx # List-value +4357 { +4358 $emit-subx-stmt-list:check-for-block: +4359 81 7/subop/compare *ecx 0/imm32/block # Stmt-tag +4360 75/jump-if-!= break/disp8 +4361 $emit-subx-stmt-list:block: +4362 (emit-subx-block *(ebp+8) %ecx *(ebp+0x10)) 4363 } 4364 { -4365 $emit-subx-stmt-list:check-for-named-block: -4366 81 7/subop/compare *ecx 4/imm32/named-block # Stmt-tag +4365 $emit-subx-stmt-list:check-for-stmt: +4366 81 7/subop/compare *ecx 1/imm32/stmt1 # Stmt-tag 4367 75/jump-if-!= break/disp8 -4368 $emit-subx-stmt-list:named-block: -4369 (emit-subx-named-block *(ebp+8) %ecx *(ebp+0x10)) +4368 $emit-subx-stmt-list:stmt: +4369 (emit-subx-statement *(ebp+8) %ecx Primitives *Program) 4370 } -4371 8b/-> *(esi+4) 6/r32/esi # List-next -4372 e9/jump loop/disp32 -4373 } -4374 # reclaim locals -4375 # TODO: support nested blocks; take block-ids into account -4376 { -4377 $emit-subx-stmt-list:reclaim-loop: -4378 8b/-> *(ebp+0x10) 0/r32/eax -4379 81 7/subop/compare *eax 0/imm32 # Stack-top -4380 0f 84/jump-if-= break/disp32 -4381 # var v/ecx : (handle var) = top(vars) -4382 (top %eax) # => eax -4383 89/<- %ecx 0/r32/eax -4384 # if v is in a register -4385 81 7/subop/compare *(ecx+0x10) 0/imm32 # Var-register -4386 { -4387 74/jump-if-= break/disp8 -4388 $emit-subx-stmt-list:reclaim-var-in-register: -4389 (write-buffered *(ebp+8) "8f 0/subop/pop %") -4390 (write-buffered *(ebp+8) *(ecx+0x10)) -4391 (write-buffered *(ebp+8) Newline) -4392 } -4393 # if v is on the stack -4394 { -4395 75/jump-if-!= break/disp8 -4396 $emit-subx-stmt-list:reclaim-var-on-stack: -4397 (size-of %ecx) # => eax -4398 01/add *Next-local-stack-offset 0/r32/eax -4399 (write-buffered *(ebp+8) "81 0/subop/add %esp ") -4400 (print-int32-buffered *(ebp+8) %eax) -4401 (write-buffered *(ebp+8) "/imm32\n") -4402 } -4403 # -4404 (pop *(ebp+0x10)) -4405 e9/jump loop/disp32 -4406 } -4407 $emit-subx-stmt-list:end: -4408 # . restore registers -4409 5e/pop-to-esi -4410 59/pop-to-ecx -4411 58/pop-to-eax -4412 # . epilogue -4413 89/<- %esp 5/r32/ebp -4414 5d/pop-to-ebp -4415 c3/return -4416 -4417 $emit-subx-stmt-list:abort-regvardef-without-register: -4418 # error("var '" var->name "' initialized from an instruction must live in a register\n") -4419 (write-buffered Stderr "var '") -4420 (write-buffered Stderr *eax) # Var-name -4421 (write-buffered Stderr "' initialized from an instruction must live in a register\n") -4422 (flush Stderr) -4423 # . syscall(exit, 1) -4424 bb/copy-to-ebx 1/imm32 -4425 b8/copy-to-eax 1/imm32/exit -4426 cd/syscall 0x80/imm8 -4427 # never gets here -4428 -4429 emit-subx-var-def: # out: (addr buffered-file), stmt: (handle statement) -4430 # . prologue -4431 55/push-ebp -4432 89/<- %ebp 4/r32/esp -4433 # . save registers -4434 50/push-eax -4435 51/push-ecx -4436 # eax = stmt -4437 8b/-> *(ebp+0xc) 0/r32/eax -4438 # var n/eax: int = size-of(stmt->var) -4439 (size-of *(eax+4)) # Vardef-var => eax -4440 # while n > 0 -4441 { -4442 3d/compare-eax-with 0/imm32 -4443 7e/jump-if-<= break/disp8 -4444 (write-buffered *(ebp+8) "68/push 0/imm32\n") -4445 # n -= 4 -4446 2d/subtract-from-eax 4/imm32 -4447 # -4448 eb/jump loop/disp8 -4449 } -4450 $emit-subx-var-def:end: -4451 # . restore registers -4452 59/pop-to-ecx -4453 58/pop-to-eax -4454 # . epilogue -4455 89/<- %esp 5/r32/ebp -4456 5d/pop-to-ebp -4457 c3/return -4458 -4459 emit-subx-statement: # out: (addr buffered-file), stmt: (handle statement), primitives: (handle primitive), functions: (handle function) -4460 # . prologue -4461 55/push-ebp -4462 89/<- %ebp 4/r32/esp -4463 # . save registers -4464 50/push-eax -4465 51/push-ecx -4466 # if stmt matches a primitive, emit it -4467 { -4468 $emit-subx-statement:check-for-primitive: -4469 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => curr/eax -4470 3d/compare-eax-and 0/imm32 -4471 74/jump-if-= break/disp8 -4472 $emit-subx-statement:primitive: -4473 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr -4474 e9/jump $emit-subx-statement:end/disp32 -4475 } -4476 # else if stmt matches a function, emit a call to it +4371 { +4372 $emit-subx-stmt-list:check-for-vardef: +4373 81 7/subop/compare *ecx 2/imm32/vardef # Stmt-tag +4374 75/jump-if-!= break/disp8 +4375 $emit-subx-stmt-list:vardef: +4376 (emit-subx-var-def *(ebp+8) %ecx) +4377 (push *(ebp+0x10) *(ecx+4)) # Vardef-var +4378 } +4379 { +4380 $emit-subx-stmt-list:check-for-regvardef: +4381 81 7/subop/compare *ecx 3/imm32/regvardef # Stmt-tag +4382 0f 85/jump-if-!= break/disp32 +4383 $emit-subx-stmt-list:regvardef: +4384 # TODO: ensure that there's exactly one output +4385 # var output/eax: (handle var) = curr-stmt->outputs->value +4386 8b/-> *(ecx+0xc) 0/r32/eax +4387 8b/-> *eax 0/r32/eax +4388 # ensure that output is in a register +4389 81 7/subop/compare *(eax+0x10) 0/imm32 # Var-register +4390 0f 84/jump-if-= $emit-subx-stmt-list:abort-regvardef-without-register/disp32 +4391 # emit spill +4392 (write-buffered *(ebp+8) "ff 6/subop/push %") +4393 (write-buffered *(ebp+8) *(eax+0x10)) +4394 (write-buffered *(ebp+8) Newline) +4395 # register variable definition +4396 (push *(ebp+0x10) %eax) +4397 # emit the instruction as usual +4398 (emit-subx-statement *(ebp+8) %ecx Primitives *Program) +4399 } +4400 { +4401 $emit-subx-stmt-list:check-for-named-block: +4402 81 7/subop/compare *ecx 4/imm32/named-block # Stmt-tag +4403 75/jump-if-!= break/disp8 +4404 $emit-subx-stmt-list:named-block: +4405 (emit-subx-named-block *(ebp+8) %ecx *(ebp+0x10)) +4406 } +4407 8b/-> *(esi+4) 6/r32/esi # List-next +4408 e9/jump loop/disp32 +4409 } +4410 # reclaim locals +4411 # TODO: support nested blocks; take block-ids into account +4412 { +4413 $emit-subx-stmt-list:reclaim-loop: +4414 8b/-> *(ebp+0x10) 0/r32/eax +4415 81 7/subop/compare *eax 0/imm32 # Stack-top +4416 0f 84/jump-if-= break/disp32 +4417 # var v/ecx : (handle var) = top(vars) +4418 (top %eax) # => eax +4419 89/<- %ecx 0/r32/eax +4420 # if v is in a register +4421 81 7/subop/compare *(ecx+0x10) 0/imm32 # Var-register +4422 { +4423 74/jump-if-= break/disp8 +4424 $emit-subx-stmt-list:reclaim-var-in-register: +4425 (write-buffered *(ebp+8) "8f 0/subop/pop %") +4426 (write-buffered *(ebp+8) *(ecx+0x10)) +4427 (write-buffered *(ebp+8) Newline) +4428 } +4429 # if v is on the stack +4430 { +4431 75/jump-if-!= break/disp8 +4432 $emit-subx-stmt-list:reclaim-var-on-stack: +4433 (size-of %ecx) # => eax +4434 01/add *Next-local-stack-offset 0/r32/eax +4435 (write-buffered *(ebp+8) "81 0/subop/add %esp ") +4436 (print-int32-buffered *(ebp+8) %eax) +4437 (write-buffered *(ebp+8) "/imm32\n") +4438 } +4439 # +4440 (pop *(ebp+0x10)) +4441 e9/jump loop/disp32 +4442 } +4443 $emit-subx-stmt-list:end: +4444 # . restore registers +4445 5e/pop-to-esi +4446 59/pop-to-ecx +4447 58/pop-to-eax +4448 # . epilogue +4449 89/<- %esp 5/r32/ebp +4450 5d/pop-to-ebp +4451 c3/return +4452 +4453 $emit-subx-stmt-list:abort-regvardef-without-register: +4454 # error("var '" var->name "' initialized from an instruction must live in a register\n") +4455 (write-buffered Stderr "var '") +4456 (write-buffered Stderr *eax) # Var-name +4457 (write-buffered Stderr "' initialized from an instruction must live in a register\n") +4458 (flush Stderr) +4459 # . syscall(exit, 1) +4460 bb/copy-to-ebx 1/imm32 +4461 b8/copy-to-eax 1/imm32/exit +4462 cd/syscall 0x80/imm8 +4463 # never gets here +4464 +4465 emit-subx-var-def: # out: (addr buffered-file), stmt: (handle statement) +4466 # . prologue +4467 55/push-ebp +4468 89/<- %ebp 4/r32/esp +4469 # . save registers +4470 50/push-eax +4471 51/push-ecx +4472 # eax = stmt +4473 8b/-> *(ebp+0xc) 0/r32/eax +4474 # var n/eax: int = size-of(stmt->var) +4475 (size-of *(eax+4)) # Vardef-var => eax +4476 # while n > 0 4477 { -4478 $emit-subx-statement:check-for-call: -4479 (find-matching-function *(ebp+0x14) *(ebp+0xc)) # functions, stmt => curr/eax -4480 3d/compare-eax-and 0/imm32 -4481 74/jump-if-= break/disp8 -4482 $emit-subx-statement:call: -4483 (emit-subx-call *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr -4484 e9/jump $emit-subx-statement:end/disp32 +4478 3d/compare-eax-with 0/imm32 +4479 7e/jump-if-<= break/disp8 +4480 (write-buffered *(ebp+8) "68/push 0/imm32\n") +4481 # n -= 4 +4482 2d/subtract-from-eax 4/imm32 +4483 # +4484 eb/jump loop/disp8 4485 } -4486 # else abort -4487 e9/jump $emit-subx-statement:abort/disp32 -4488 $emit-subx-statement:end: -4489 # . restore registers -4490 59/pop-to-ecx -4491 58/pop-to-eax -4492 # . epilogue -4493 89/<- %esp 5/r32/ebp -4494 5d/pop-to-ebp -4495 c3/return -4496 -4497 $emit-subx-statement:abort: -4498 # error("couldn't translate '" stmt "'\n") -4499 (write-buffered Stderr "couldn't translate an instruction with operation '") -4500 8b/-> *(ebp+0xc) 0/r32/eax -4501 (write-buffered Stderr *(eax+4)) # Stmt1-operation -4502 (write-buffered Stderr "'\n") -4503 (flush Stderr) -4504 # . syscall(exit, 1) -4505 bb/copy-to-ebx 1/imm32 -4506 b8/copy-to-eax 1/imm32/exit -4507 cd/syscall 0x80/imm8 -4508 # never gets here -4509 -4510 emit-subx-named-block: # out: (addr buffered-file), named-block: (handle named-block), vars: (addr stack (handle var)) -4511 # . prologue -4512 55/push-ebp -4513 89/<- %ebp 4/r32/esp -4514 # . save registers -4515 50/push-eax -4516 51/push-ecx -4517 56/push-esi -4518 # esi = block -4519 8b/-> *(ebp+0xc) 6/r32/esi -4520 # var stmts/ecx: (handle list statement) = block->statements -4521 8b/-> *(esi+4) 0/r32/eax # Block-statements -4522 # -4523 { -4524 $emit-subx-named-block:check-empty: -4525 81 7/subop/compare %eax 0/imm32 -4526 0f 84/jump-if-= break/disp32 -4527 (write-buffered *(ebp+8) "{\n") -4528 (write-buffered *(ebp+8) *(esi+8)) # Named-block-name -4529 (write-buffered *(ebp+8) "loop:\n") -4530 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10)) -4531 (write-buffered *(ebp+8) "}\n") -4532 (write-buffered *(ebp+8) *(esi+8)) # Named-block-name -4533 (write-buffered *(ebp+8) "break:\n") -4534 } -4535 $emit-subx-named-block:end: -4536 # . restore registers -4537 5e/pop-to-esi -4538 59/pop-to-ecx -4539 58/pop-to-eax -4540 # . epilogue -4541 89/<- %esp 5/r32/ebp -4542 5d/pop-to-ebp -4543 c3/return -4544 -4545 # Primitives supported -4546 # For each operation, put variants with hard-coded registers before flexible ones. -4547 == data -4548 Primitives: -4549 # - increment/decrement -4550 _Primitive-inc-eax: -4551 # var/eax <- increment => 40/increment-eax -4552 "increment"/imm32/name -4553 0/imm32/no-inouts -4554 Single-int-var-in-eax/imm32/outputs -4555 "40/increment-eax"/imm32/subx-name -4556 0/imm32/no-rm32 -4557 0/imm32/no-r32 -4558 0/imm32/no-imm32 -4559 0/imm32/no-disp32 -4560 0/imm32/output-is-write-only -4561 _Primitive-inc-ecx/imm32/next -4562 _Primitive-inc-ecx: -4563 # var/ecx <- increment => 41/increment-ecx -4564 "increment"/imm32/name -4565 0/imm32/no-inouts -4566 Single-int-var-in-ecx/imm32/outputs -4567 "41/increment-ecx"/imm32/subx-name -4568 0/imm32/no-rm32 -4569 0/imm32/no-r32 -4570 0/imm32/no-imm32 -4571 0/imm32/no-disp32 -4572 0/imm32/output-is-write-only -4573 _Primitive-inc-edx/imm32/next -4574 _Primitive-inc-edx: -4575 # var/edx <- increment => 42/increment-edx -4576 "increment"/imm32/name -4577 0/imm32/no-inouts -4578 Single-int-var-in-edx/imm32/outputs -4579 "42/increment-edx"/imm32/subx-name -4580 0/imm32/no-rm32 -4581 0/imm32/no-r32 -4582 0/imm32/no-imm32 -4583 0/imm32/no-disp32 -4584 0/imm32/output-is-write-only -4585 _Primitive-inc-ebx/imm32/next -4586 _Primitive-inc-ebx: -4587 # var/ebx <- increment => 43/increment-ebx +4486 $emit-subx-var-def:end: +4487 # . restore registers +4488 59/pop-to-ecx +4489 58/pop-to-eax +4490 # . epilogue +4491 89/<- %esp 5/r32/ebp +4492 5d/pop-to-ebp +4493 c3/return +4494 +4495 emit-subx-statement: # out: (addr buffered-file), stmt: (handle statement), primitives: (handle primitive), functions: (handle function) +4496 # . prologue +4497 55/push-ebp +4498 89/<- %ebp 4/r32/esp +4499 # . save registers +4500 50/push-eax +4501 51/push-ecx +4502 # if stmt matches a primitive, emit it +4503 { +4504 $emit-subx-statement:check-for-primitive: +4505 (find-matching-primitive *(ebp+0x10) *(ebp+0xc)) # primitives, stmt => curr/eax +4506 3d/compare-eax-and 0/imm32 +4507 74/jump-if-= break/disp8 +4508 $emit-subx-statement:primitive: +4509 (emit-subx-primitive *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr +4510 e9/jump $emit-subx-statement:end/disp32 +4511 } +4512 # else if stmt matches a function, emit a call to it +4513 { +4514 $emit-subx-statement:check-for-call: +4515 (find-matching-function *(ebp+0x14) *(ebp+0xc)) # functions, stmt => curr/eax +4516 3d/compare-eax-and 0/imm32 +4517 74/jump-if-= break/disp8 +4518 $emit-subx-statement:call: +4519 (emit-subx-call *(ebp+8) *(ebp+0xc) %eax) # out, stmt, curr +4520 e9/jump $emit-subx-statement:end/disp32 +4521 } +4522 # else abort +4523 e9/jump $emit-subx-statement:abort/disp32 +4524 $emit-subx-statement:end: +4525 # . restore registers +4526 59/pop-to-ecx +4527 58/pop-to-eax +4528 # . epilogue +4529 89/<- %esp 5/r32/ebp +4530 5d/pop-to-ebp +4531 c3/return +4532 +4533 $emit-subx-statement:abort: +4534 # error("couldn't translate '" stmt "'\n") +4535 (write-buffered Stderr "couldn't translate an instruction with operation '") +4536 8b/-> *(ebp+0xc) 0/r32/eax +4537 (write-buffered Stderr *(eax+4)) # Stmt1-operation +4538 (write-buffered Stderr "'\n") +4539 (flush Stderr) +4540 # . syscall(exit, 1) +4541 bb/copy-to-ebx 1/imm32 +4542 b8/copy-to-eax 1/imm32/exit +4543 cd/syscall 0x80/imm8 +4544 # never gets here +4545 +4546 emit-subx-named-block: # out: (addr buffered-file), named-block: (handle named-block), vars: (addr stack (handle var)) +4547 # . prologue +4548 55/push-ebp +4549 89/<- %ebp 4/r32/esp +4550 # . save registers +4551 50/push-eax +4552 51/push-ecx +4553 56/push-esi +4554 # esi = block +4555 8b/-> *(ebp+0xc) 6/r32/esi +4556 # var stmts/ecx: (handle list statement) = block->statements +4557 8b/-> *(esi+4) 0/r32/eax # Block-statements +4558 # +4559 { +4560 $emit-subx-named-block:check-empty: +4561 81 7/subop/compare %eax 0/imm32 +4562 0f 84/jump-if-= break/disp32 +4563 (write-buffered *(ebp+8) "{\n") +4564 (write-buffered *(ebp+8) *(esi+8)) # Named-block-name +4565 (write-buffered *(ebp+8) "loop:\n") +4566 (emit-subx-stmt-list *(ebp+8) %eax *(ebp+0x10)) +4567 (write-buffered *(ebp+8) "}\n") +4568 (write-buffered *(ebp+8) *(esi+8)) # Named-block-name +4569 (write-buffered *(ebp+8) "break:\n") +4570 } +4571 $emit-subx-named-block:end: +4572 # . restore registers +4573 5e/pop-to-esi +4574 59/pop-to-ecx +4575 58/pop-to-eax +4576 # . epilogue +4577 89/<- %esp 5/r32/ebp +4578 5d/pop-to-ebp +4579 c3/return +4580 +4581 # Primitives supported +4582 # For each operation, put variants with hard-coded registers before flexible ones. +4583 == data +4584 Primitives: +4585 # - increment/decrement +4586 _Primitive-inc-eax: +4587 # var/eax <- increment => 40/increment-eax 4588 "increment"/imm32/name 4589 0/imm32/no-inouts -4590 Single-int-var-in-ebx/imm32/outputs -4591 "43/increment-ebx"/imm32/subx-name +4590 Single-int-var-in-eax/imm32/outputs +4591 "40/increment-eax"/imm32/subx-name 4592 0/imm32/no-rm32 4593 0/imm32/no-r32 4594 0/imm32/no-imm32 4595 0/imm32/no-disp32 4596 0/imm32/output-is-write-only -4597 _Primitive-inc-esi/imm32/next -4598 _Primitive-inc-esi: -4599 # var/esi <- increment => 46/increment-esi +4597 _Primitive-inc-ecx/imm32/next +4598 _Primitive-inc-ecx: +4599 # var/ecx <- increment => 41/increment-ecx 4600 "increment"/imm32/name 4601 0/imm32/no-inouts -4602 Single-int-var-in-esi/imm32/outputs -4603 "46/increment-esi"/imm32/subx-name +4602 Single-int-var-in-ecx/imm32/outputs +4603 "41/increment-ecx"/imm32/subx-name 4604 0/imm32/no-rm32 4605 0/imm32/no-r32 4606 0/imm32/no-imm32 4607 0/imm32/no-disp32 4608 0/imm32/output-is-write-only -4609 _Primitive-inc-edi/imm32/next -4610 _Primitive-inc-edi: -4611 # var/edi <- increment => 47/increment-edi +4609 _Primitive-inc-edx/imm32/next +4610 _Primitive-inc-edx: +4611 # var/edx <- increment => 42/increment-edx 4612 "increment"/imm32/name 4613 0/imm32/no-inouts -4614 Single-int-var-in-edi/imm32/outputs -4615 "47/increment-edi"/imm32/subx-name +4614 Single-int-var-in-edx/imm32/outputs +4615 "42/increment-edx"/imm32/subx-name 4616 0/imm32/no-rm32 4617 0/imm32/no-r32 4618 0/imm32/no-imm32 4619 0/imm32/no-disp32 4620 0/imm32/output-is-write-only -4621 _Primitive-dec-eax/imm32/next -4622 _Primitive-dec-eax: -4623 # var/eax <- decrement => 48/decrement-eax -4624 "decrement"/imm32/name +4621 _Primitive-inc-ebx/imm32/next +4622 _Primitive-inc-ebx: +4623 # var/ebx <- increment => 43/increment-ebx +4624 "increment"/imm32/name 4625 0/imm32/no-inouts -4626 Single-int-var-in-eax/imm32/outputs -4627 "48/decrement-eax"/imm32/subx-name +4626 Single-int-var-in-ebx/imm32/outputs +4627 "43/increment-ebx"/imm32/subx-name 4628 0/imm32/no-rm32 4629 0/imm32/no-r32 4630 0/imm32/no-imm32 4631 0/imm32/no-disp32 4632 0/imm32/output-is-write-only -4633 _Primitive-dec-ecx/imm32/next -4634 _Primitive-dec-ecx: -4635 # var/ecx <- decrement => 49/decrement-ecx -4636 "decrement"/imm32/name +4633 _Primitive-inc-esi/imm32/next +4634 _Primitive-inc-esi: +4635 # var/esi <- increment => 46/increment-esi +4636 "increment"/imm32/name 4637 0/imm32/no-inouts -4638 Single-int-var-in-ecx/imm32/outputs -4639 "49/decrement-ecx"/imm32/subx-name +4638 Single-int-var-in-esi/imm32/outputs +4639 "46/increment-esi"/imm32/subx-name 4640 0/imm32/no-rm32 4641 0/imm32/no-r32 4642 0/imm32/no-imm32 4643 0/imm32/no-disp32 4644 0/imm32/output-is-write-only -4645 _Primitive-dec-edx/imm32/next -4646 _Primitive-dec-edx: -4647 # var/edx <- decrement => 4a/decrement-edx -4648 "decrement"/imm32/name +4645 _Primitive-inc-edi/imm32/next +4646 _Primitive-inc-edi: +4647 # var/edi <- increment => 47/increment-edi +4648 "increment"/imm32/name 4649 0/imm32/no-inouts -4650 Single-int-var-in-edx/imm32/outputs -4651 "4a/decrement-edx"/imm32/subx-name +4650 Single-int-var-in-edi/imm32/outputs +4651 "47/increment-edi"/imm32/subx-name 4652 0/imm32/no-rm32 4653 0/imm32/no-r32 4654 0/imm32/no-imm32 4655 0/imm32/no-disp32 4656 0/imm32/output-is-write-only -4657 _Primitive-dec-ebx/imm32/next -4658 _Primitive-dec-ebx: -4659 # var/ebx <- decrement => 4b/decrement-ebx +4657 _Primitive-dec-eax/imm32/next +4658 _Primitive-dec-eax: +4659 # var/eax <- decrement => 48/decrement-eax 4660 "decrement"/imm32/name 4661 0/imm32/no-inouts -4662 Single-int-var-in-ebx/imm32/outputs -4663 "4b/decrement-ebx"/imm32/subx-name +4662 Single-int-var-in-eax/imm32/outputs +4663 "48/decrement-eax"/imm32/subx-name 4664 0/imm32/no-rm32 4665 0/imm32/no-r32 4666 0/imm32/no-imm32 4667 0/imm32/no-disp32 4668 0/imm32/output-is-write-only -4669 _Primitive-dec-esi/imm32/next -4670 _Primitive-dec-esi: -4671 # var/esi <- decrement => 4e/decrement-esi +4669 _Primitive-dec-ecx/imm32/next +4670 _Primitive-dec-ecx: +4671 # var/ecx <- decrement => 49/decrement-ecx 4672 "decrement"/imm32/name 4673 0/imm32/no-inouts -4674 Single-int-var-in-esi/imm32/outputs -4675 "4e/decrement-esi"/imm32/subx-name +4674 Single-int-var-in-ecx/imm32/outputs +4675 "49/decrement-ecx"/imm32/subx-name 4676 0/imm32/no-rm32 4677 0/imm32/no-r32 4678 0/imm32/no-imm32 4679 0/imm32/no-disp32 4680 0/imm32/output-is-write-only -4681 _Primitive-dec-edi/imm32/next -4682 _Primitive-dec-edi: -4683 # var/edi <- decrement => 4f/decrement-edi +4681 _Primitive-dec-edx/imm32/next +4682 _Primitive-dec-edx: +4683 # var/edx <- decrement => 4a/decrement-edx 4684 "decrement"/imm32/name 4685 0/imm32/no-inouts -4686 Single-int-var-in-edi/imm32/outputs -4687 "4f/decrement-edi"/imm32/subx-name +4686 Single-int-var-in-edx/imm32/outputs +4687 "4a/decrement-edx"/imm32/subx-name 4688 0/imm32/no-rm32 4689 0/imm32/no-r32 4690 0/imm32/no-imm32 4691 0/imm32/no-disp32 4692 0/imm32/output-is-write-only -4693 _Primitive-inc-mem/imm32/next -4694 _Primitive-inc-mem: -4695 # increment var => ff 0/subop/increment *(ebp+__) -4696 "increment"/imm32/name -4697 Single-int-var-on-stack/imm32/inouts -4698 0/imm32/no-outputs -4699 "ff 0/subop/increment"/imm32/subx-name -4700 1/imm32/rm32-is-first-inout +4693 _Primitive-dec-ebx/imm32/next +4694 _Primitive-dec-ebx: +4695 # var/ebx <- decrement => 4b/decrement-ebx +4696 "decrement"/imm32/name +4697 0/imm32/no-inouts +4698 Single-int-var-in-ebx/imm32/outputs +4699 "4b/decrement-ebx"/imm32/subx-name +4700 0/imm32/no-rm32 4701 0/imm32/no-r32 4702 0/imm32/no-imm32 4703 0/imm32/no-disp32 4704 0/imm32/output-is-write-only -4705 _Primitive-inc-reg/imm32/next -4706 _Primitive-inc-reg: -4707 # var/reg <- increment => ff 0/subop/increment %__ -4708 "increment"/imm32/name +4705 _Primitive-dec-esi/imm32/next +4706 _Primitive-dec-esi: +4707 # var/esi <- decrement => 4e/decrement-esi +4708 "decrement"/imm32/name 4709 0/imm32/no-inouts -4710 Single-int-var-in-some-register/imm32/outputs -4711 "ff 0/subop/increment"/imm32/subx-name -4712 3/imm32/rm32-is-first-output +4710 Single-int-var-in-esi/imm32/outputs +4711 "4e/decrement-esi"/imm32/subx-name +4712 0/imm32/no-rm32 4713 0/imm32/no-r32 4714 0/imm32/no-imm32 4715 0/imm32/no-disp32 4716 0/imm32/output-is-write-only -4717 _Primitive-dec-mem/imm32/next -4718 _Primitive-dec-mem: -4719 # decrement var => ff 1/subop/decrement *(ebp+__) +4717 _Primitive-dec-edi/imm32/next +4718 _Primitive-dec-edi: +4719 # var/edi <- decrement => 4f/decrement-edi 4720 "decrement"/imm32/name -4721 Single-int-var-on-stack/imm32/inouts -4722 0/imm32/no-outputs -4723 "ff 1/subop/decrement"/imm32/subx-name -4724 1/imm32/rm32-is-first-inout +4721 0/imm32/no-inouts +4722 Single-int-var-in-edi/imm32/outputs +4723 "4f/decrement-edi"/imm32/subx-name +4724 0/imm32/no-rm32 4725 0/imm32/no-r32 4726 0/imm32/no-imm32 4727 0/imm32/no-disp32 4728 0/imm32/output-is-write-only -4729 _Primitive-dec-reg/imm32/next -4730 _Primitive-dec-reg: -4731 # var/reg <- decrement => ff 1/subop/decrement %__ -4732 "decrement"/imm32/name -4733 0/imm32/no-inouts -4734 Single-int-var-in-some-register/imm32/outputs -4735 "ff 1/subop/decrement"/imm32/subx-name -4736 3/imm32/rm32-is-first-output +4729 _Primitive-inc-mem/imm32/next +4730 _Primitive-inc-mem: +4731 # increment var => ff 0/subop/increment *(ebp+__) +4732 "increment"/imm32/name +4733 Single-int-var-on-stack/imm32/inouts +4734 0/imm32/no-outputs +4735 "ff 0/subop/increment"/imm32/subx-name +4736 1/imm32/rm32-is-first-inout 4737 0/imm32/no-r32 4738 0/imm32/no-imm32 4739 0/imm32/no-disp32 4740 0/imm32/output-is-write-only -4741 _Primitive-add-to-eax/imm32/next -4742 # - add -4743 _Primitive-add-to-eax: -4744 # var/eax <- add lit => 05/add-to-eax lit/imm32 -4745 "add"/imm32/name -4746 Single-lit-var/imm32/inouts -4747 Single-int-var-in-eax/imm32/outputs -4748 "05/add-to-eax"/imm32/subx-name -4749 0/imm32/no-rm32 -4750 0/imm32/no-r32 -4751 1/imm32/imm32-is-first-inout -4752 0/imm32/no-disp32 -4753 0/imm32/output-is-write-only -4754 _Primitive-add-reg-to-reg/imm32/next -4755 _Primitive-add-reg-to-reg: -4756 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 -4757 "add"/imm32/name -4758 Single-int-var-in-some-register/imm32/inouts -4759 Single-int-var-in-some-register/imm32/outputs -4760 "01/add-to"/imm32/subx-name -4761 3/imm32/rm32-is-first-output -4762 1/imm32/r32-is-first-inout -4763 0/imm32/no-imm32 -4764 0/imm32/no-disp32 -4765 0/imm32/output-is-write-only -4766 _Primitive-add-reg-to-mem/imm32/next -4767 _Primitive-add-reg-to-mem: -4768 # add-to var1 var2/reg => 01/add-to var1 var2/r32 -4769 "add-to"/imm32/name -4770 Two-args-int-stack-int-reg/imm32/inouts -4771 0/imm32/outputs -4772 "01/add-to"/imm32/subx-name -4773 1/imm32/rm32-is-first-inout -4774 2/imm32/r32-is-second-inout -4775 0/imm32/no-imm32 -4776 0/imm32/no-disp32 -4777 0/imm32/output-is-write-only -4778 _Primitive-add-mem-to-reg/imm32/next -4779 _Primitive-add-mem-to-reg: -4780 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 +4741 _Primitive-inc-reg/imm32/next +4742 _Primitive-inc-reg: +4743 # var/reg <- increment => ff 0/subop/increment %__ +4744 "increment"/imm32/name +4745 0/imm32/no-inouts +4746 Single-int-var-in-some-register/imm32/outputs +4747 "ff 0/subop/increment"/imm32/subx-name +4748 3/imm32/rm32-is-first-output +4749 0/imm32/no-r32 +4750 0/imm32/no-imm32 +4751 0/imm32/no-disp32 +4752 0/imm32/output-is-write-only +4753 _Primitive-dec-mem/imm32/next +4754 _Primitive-dec-mem: +4755 # decrement var => ff 1/subop/decrement *(ebp+__) +4756 "decrement"/imm32/name +4757 Single-int-var-on-stack/imm32/inouts +4758 0/imm32/no-outputs +4759 "ff 1/subop/decrement"/imm32/subx-name +4760 1/imm32/rm32-is-first-inout +4761 0/imm32/no-r32 +4762 0/imm32/no-imm32 +4763 0/imm32/no-disp32 +4764 0/imm32/output-is-write-only +4765 _Primitive-dec-reg/imm32/next +4766 _Primitive-dec-reg: +4767 # var/reg <- decrement => ff 1/subop/decrement %__ +4768 "decrement"/imm32/name +4769 0/imm32/no-inouts +4770 Single-int-var-in-some-register/imm32/outputs +4771 "ff 1/subop/decrement"/imm32/subx-name +4772 3/imm32/rm32-is-first-output +4773 0/imm32/no-r32 +4774 0/imm32/no-imm32 +4775 0/imm32/no-disp32 +4776 0/imm32/output-is-write-only +4777 _Primitive-add-to-eax/imm32/next +4778 # - add +4779 _Primitive-add-to-eax: +4780 # var/eax <- add lit => 05/add-to-eax lit/imm32 4781 "add"/imm32/name -4782 Single-int-var-on-stack/imm32/inouts -4783 Single-int-var-in-some-register/imm32/outputs -4784 "03/add"/imm32/subx-name -4785 1/imm32/rm32-is-first-inout -4786 3/imm32/r32-is-first-output -4787 0/imm32/no-imm32 +4782 Single-lit-var/imm32/inouts +4783 Single-int-var-in-eax/imm32/outputs +4784 "05/add-to-eax"/imm32/subx-name +4785 0/imm32/no-rm32 +4786 0/imm32/no-r32 +4787 1/imm32/imm32-is-first-inout 4788 0/imm32/no-disp32 4789 0/imm32/output-is-write-only -4790 _Primitive-add-lit-to-reg/imm32/next -4791 _Primitive-add-lit-to-reg: -4792 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 +4790 _Primitive-add-reg-to-reg/imm32/next +4791 _Primitive-add-reg-to-reg: +4792 # var1/reg <- add var2/reg => 01/add-to var1/rm32 var2/r32 4793 "add"/imm32/name -4794 Single-lit-var/imm32/inouts -4795 Single-int-var-in-some-register/imm32/outputs -4796 "81 0/subop/add"/imm32/subx-name +4794 Single-int-var-in-some-register/imm32/inouts +4795 Single-int-var-in-some-register/imm32/outputs +4796 "01/add-to"/imm32/subx-name 4797 3/imm32/rm32-is-first-output -4798 0/imm32/no-r32 -4799 1/imm32/imm32-is-first-inout +4798 1/imm32/r32-is-first-inout +4799 0/imm32/no-imm32 4800 0/imm32/no-disp32 4801 0/imm32/output-is-write-only -4802 _Primitive-add-lit-to-mem/imm32/next -4803 _Primitive-add-lit-to-mem: -4804 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 +4802 _Primitive-add-reg-to-mem/imm32/next +4803 _Primitive-add-reg-to-mem: +4804 # add-to var1 var2/reg => 01/add-to var1 var2/r32 4805 "add-to"/imm32/name -4806 Int-var-and-literal/imm32/inouts +4806 Two-args-int-stack-int-reg/imm32/inouts 4807 0/imm32/outputs -4808 "81 0/subop/add"/imm32/subx-name +4808 "01/add-to"/imm32/subx-name 4809 1/imm32/rm32-is-first-inout -4810 0/imm32/no-r32 -4811 2/imm32/imm32-is-second-inout +4810 2/imm32/r32-is-second-inout +4811 0/imm32/no-imm32 4812 0/imm32/no-disp32 4813 0/imm32/output-is-write-only -4814 _Primitive-subtract-from-eax/imm32/next -4815 # - subtract -4816 _Primitive-subtract-from-eax: -4817 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 -4818 "subtract"/imm32/name -4819 Single-lit-var/imm32/inouts -4820 Single-int-var-in-eax/imm32/outputs -4821 "2d/subtract-from-eax"/imm32/subx-name -4822 0/imm32/no-rm32 -4823 0/imm32/no-r32 -4824 1/imm32/imm32-is-first-inout -4825 0/imm32/no-disp32 -4826 0/imm32/output-is-write-only -4827 _Primitive-subtract-reg-from-reg/imm32/next -4828 _Primitive-subtract-reg-from-reg: -4829 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 -4830 "subtract"/imm32/name -4831 Single-int-var-in-some-register/imm32/inouts -4832 Single-int-var-in-some-register/imm32/outputs -4833 "29/subtract-from"/imm32/subx-name -4834 3/imm32/rm32-is-first-output -4835 1/imm32/r32-is-first-inout -4836 0/imm32/no-imm32 -4837 0/imm32/no-disp32 -4838 0/imm32/output-is-write-only -4839 _Primitive-subtract-reg-from-mem/imm32/next -4840 _Primitive-subtract-reg-from-mem: -4841 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 -4842 "subtract-from"/imm32/name -4843 Two-args-int-stack-int-reg/imm32/inouts -4844 0/imm32/outputs -4845 "29/subtract-from"/imm32/subx-name -4846 1/imm32/rm32-is-first-inout -4847 2/imm32/r32-is-second-inout -4848 0/imm32/no-imm32 -4849 0/imm32/no-disp32 -4850 0/imm32/output-is-write-only -4851 _Primitive-subtract-mem-from-reg/imm32/next -4852 _Primitive-subtract-mem-from-reg: -4853 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 +4814 _Primitive-add-mem-to-reg/imm32/next +4815 _Primitive-add-mem-to-reg: +4816 # var1/reg <- add var2 => 03/add var2/rm32 var1/r32 +4817 "add"/imm32/name +4818 Single-int-var-on-stack/imm32/inouts +4819 Single-int-var-in-some-register/imm32/outputs +4820 "03/add"/imm32/subx-name +4821 1/imm32/rm32-is-first-inout +4822 3/imm32/r32-is-first-output +4823 0/imm32/no-imm32 +4824 0/imm32/no-disp32 +4825 0/imm32/output-is-write-only +4826 _Primitive-add-lit-to-reg/imm32/next +4827 _Primitive-add-lit-to-reg: +4828 # var1/reg <- add lit => 81 0/subop/add var1/rm32 lit/imm32 +4829 "add"/imm32/name +4830 Single-lit-var/imm32/inouts +4831 Single-int-var-in-some-register/imm32/outputs +4832 "81 0/subop/add"/imm32/subx-name +4833 3/imm32/rm32-is-first-output +4834 0/imm32/no-r32 +4835 1/imm32/imm32-is-first-inout +4836 0/imm32/no-disp32 +4837 0/imm32/output-is-write-only +4838 _Primitive-add-lit-to-mem/imm32/next +4839 _Primitive-add-lit-to-mem: +4840 # add-to var1, lit => 81 0/subop/add var1/rm32 lit/imm32 +4841 "add-to"/imm32/name +4842 Int-var-and-literal/imm32/inouts +4843 0/imm32/outputs +4844 "81 0/subop/add"/imm32/subx-name +4845 1/imm32/rm32-is-first-inout +4846 0/imm32/no-r32 +4847 2/imm32/imm32-is-second-inout +4848 0/imm32/no-disp32 +4849 0/imm32/output-is-write-only +4850 _Primitive-subtract-from-eax/imm32/next +4851 # - subtract +4852 _Primitive-subtract-from-eax: +4853 # var/eax <- subtract lit => 2d/subtract-from-eax lit/imm32 4854 "subtract"/imm32/name -4855 Single-int-var-on-stack/imm32/inouts -4856 Single-int-var-in-some-register/imm32/outputs -4857 "2b/subtract"/imm32/subx-name -4858 1/imm32/rm32-is-first-inout -4859 3/imm32/r32-is-first-output -4860 0/imm32/no-imm32 +4855 Single-lit-var/imm32/inouts +4856 Single-int-var-in-eax/imm32/outputs +4857 "2d/subtract-from-eax"/imm32/subx-name +4858 0/imm32/no-rm32 +4859 0/imm32/no-r32 +4860 1/imm32/imm32-is-first-inout 4861 0/imm32/no-disp32 4862 0/imm32/output-is-write-only -4863 _Primitive-subtract-lit-from-reg/imm32/next -4864 _Primitive-subtract-lit-from-reg: -4865 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 +4863 _Primitive-subtract-reg-from-reg/imm32/next +4864 _Primitive-subtract-reg-from-reg: +4865 # var1/reg <- subtract var2/reg => 29/subtract-from var1/rm32 var2/r32 4866 "subtract"/imm32/name -4867 Single-lit-var/imm32/inouts -4868 Single-int-var-in-some-register/imm32/outputs -4869 "81 5/subop/subtract"/imm32/subx-name +4867 Single-int-var-in-some-register/imm32/inouts +4868 Single-int-var-in-some-register/imm32/outputs +4869 "29/subtract-from"/imm32/subx-name 4870 3/imm32/rm32-is-first-output -4871 0/imm32/no-r32 -4872 1/imm32/imm32-is-first-inout +4871 1/imm32/r32-is-first-inout +4872 0/imm32/no-imm32 4873 0/imm32/no-disp32 4874 0/imm32/output-is-write-only -4875 _Primitive-subtract-lit-from-mem/imm32/next -4876 _Primitive-subtract-lit-from-mem: -4877 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 +4875 _Primitive-subtract-reg-from-mem/imm32/next +4876 _Primitive-subtract-reg-from-mem: +4877 # subtract-from var1 var2/reg => 29/subtract-from var1 var2/r32 4878 "subtract-from"/imm32/name -4879 Int-var-and-literal/imm32/inouts +4879 Two-args-int-stack-int-reg/imm32/inouts 4880 0/imm32/outputs -4881 "81 5/subop/subtract"/imm32/subx-name +4881 "29/subtract-from"/imm32/subx-name 4882 1/imm32/rm32-is-first-inout -4883 0/imm32/no-r32 -4884 2/imm32/imm32-is-first-inout +4883 2/imm32/r32-is-second-inout +4884 0/imm32/no-imm32 4885 0/imm32/no-disp32 4886 0/imm32/output-is-write-only -4887 _Primitive-and-with-eax/imm32/next -4888 # - and -4889 _Primitive-and-with-eax: -4890 # var/eax <- and lit => 25/and-with-eax lit/imm32 -4891 "and"/imm32/name -4892 Single-lit-var/imm32/inouts -4893 Single-int-var-in-eax/imm32/outputs -4894 "25/and-with-eax"/imm32/subx-name -4895 0/imm32/no-rm32 -4896 0/imm32/no-r32 -4897 1/imm32/imm32-is-first-inout -4898 0/imm32/no-disp32 -4899 0/imm32/output-is-write-only -4900 _Primitive-and-reg-with-reg/imm32/next -4901 _Primitive-and-reg-with-reg: -4902 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 -4903 "and"/imm32/name -4904 Single-int-var-in-some-register/imm32/inouts -4905 Single-int-var-in-some-register/imm32/outputs -4906 "21/and-with"/imm32/subx-name -4907 3/imm32/rm32-is-first-output -4908 1/imm32/r32-is-first-inout -4909 0/imm32/no-imm32 -4910 0/imm32/no-disp32 -4911 0/imm32/output-is-write-only -4912 _Primitive-and-reg-with-mem/imm32/next -4913 _Primitive-and-reg-with-mem: -4914 # and-with var1 var2/reg => 21/and-with var1 var2/r32 -4915 "and-with"/imm32/name -4916 Two-args-int-stack-int-reg/imm32/inouts -4917 0/imm32/outputs -4918 "21/and-with"/imm32/subx-name -4919 1/imm32/rm32-is-first-inout -4920 2/imm32/r32-is-second-inout -4921 0/imm32/no-imm32 -4922 0/imm32/no-disp32 -4923 0/imm32/output-is-write-only -4924 _Primitive-and-mem-with-reg/imm32/next -4925 _Primitive-and-mem-with-reg: -4926 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 +4887 _Primitive-subtract-mem-from-reg/imm32/next +4888 _Primitive-subtract-mem-from-reg: +4889 # var1/reg <- subtract var2 => 2b/subtract var2/rm32 var1/r32 +4890 "subtract"/imm32/name +4891 Single-int-var-on-stack/imm32/inouts +4892 Single-int-var-in-some-register/imm32/outputs +4893 "2b/subtract"/imm32/subx-name +4894 1/imm32/rm32-is-first-inout +4895 3/imm32/r32-is-first-output +4896 0/imm32/no-imm32 +4897 0/imm32/no-disp32 +4898 0/imm32/output-is-write-only +4899 _Primitive-subtract-lit-from-reg/imm32/next +4900 _Primitive-subtract-lit-from-reg: +4901 # var1/reg <- subtract lit => 81 5/subop/subtract var1/rm32 lit/imm32 +4902 "subtract"/imm32/name +4903 Single-lit-var/imm32/inouts +4904 Single-int-var-in-some-register/imm32/outputs +4905 "81 5/subop/subtract"/imm32/subx-name +4906 3/imm32/rm32-is-first-output +4907 0/imm32/no-r32 +4908 1/imm32/imm32-is-first-inout +4909 0/imm32/no-disp32 +4910 0/imm32/output-is-write-only +4911 _Primitive-subtract-lit-from-mem/imm32/next +4912 _Primitive-subtract-lit-from-mem: +4913 # subtract-from var1, lit => 81 5/subop/subtract var1/rm32 lit/imm32 +4914 "subtract-from"/imm32/name +4915 Int-var-and-literal/imm32/inouts +4916 0/imm32/outputs +4917 "81 5/subop/subtract"/imm32/subx-name +4918 1/imm32/rm32-is-first-inout +4919 0/imm32/no-r32 +4920 2/imm32/imm32-is-first-inout +4921 0/imm32/no-disp32 +4922 0/imm32/output-is-write-only +4923 _Primitive-and-with-eax/imm32/next +4924 # - and +4925 _Primitive-and-with-eax: +4926 # var/eax <- and lit => 25/and-with-eax lit/imm32 4927 "and"/imm32/name -4928 Single-int-var-on-stack/imm32/inouts -4929 Single-int-var-in-some-register/imm32/outputs -4930 "23/and"/imm32/subx-name -4931 1/imm32/rm32-is-first-inout -4932 3/imm32/r32-is-first-output -4933 0/imm32/no-imm32 +4928 Single-lit-var/imm32/inouts +4929 Single-int-var-in-eax/imm32/outputs +4930 "25/and-with-eax"/imm32/subx-name +4931 0/imm32/no-rm32 +4932 0/imm32/no-r32 +4933 1/imm32/imm32-is-first-inout 4934 0/imm32/no-disp32 4935 0/imm32/output-is-write-only -4936 _Primitive-and-lit-with-reg/imm32/next -4937 _Primitive-and-lit-with-reg: -4938 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 +4936 _Primitive-and-reg-with-reg/imm32/next +4937 _Primitive-and-reg-with-reg: +4938 # var1/reg <- and var2/reg => 21/and-with var1/rm32 var2/r32 4939 "and"/imm32/name -4940 Single-lit-var/imm32/inouts -4941 Single-int-var-in-some-register/imm32/outputs -4942 "81 4/subop/and"/imm32/subx-name +4940 Single-int-var-in-some-register/imm32/inouts +4941 Single-int-var-in-some-register/imm32/outputs +4942 "21/and-with"/imm32/subx-name 4943 3/imm32/rm32-is-first-output -4944 0/imm32/no-r32 -4945 1/imm32/imm32-is-first-inout +4944 1/imm32/r32-is-first-inout +4945 0/imm32/no-imm32 4946 0/imm32/no-disp32 4947 0/imm32/output-is-write-only -4948 _Primitive-and-lit-with-mem/imm32/next -4949 _Primitive-and-lit-with-mem: -4950 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 +4948 _Primitive-and-reg-with-mem/imm32/next +4949 _Primitive-and-reg-with-mem: +4950 # and-with var1 var2/reg => 21/and-with var1 var2/r32 4951 "and-with"/imm32/name -4952 Int-var-and-literal/imm32/inouts +4952 Two-args-int-stack-int-reg/imm32/inouts 4953 0/imm32/outputs -4954 "81 4/subop/and"/imm32/subx-name +4954 "21/and-with"/imm32/subx-name 4955 1/imm32/rm32-is-first-inout -4956 0/imm32/no-r32 -4957 2/imm32/imm32-is-first-inout +4956 2/imm32/r32-is-second-inout +4957 0/imm32/no-imm32 4958 0/imm32/no-disp32 4959 0/imm32/output-is-write-only -4960 _Primitive-or-with-eax/imm32/next -4961 # - or -4962 _Primitive-or-with-eax: -4963 # var/eax <- or lit => 0d/or-with-eax lit/imm32 -4964 "or"/imm32/name -4965 Single-lit-var/imm32/inouts -4966 Single-int-var-in-eax/imm32/outputs -4967 "0d/or-with-eax"/imm32/subx-name -4968 0/imm32/no-rm32 -4969 0/imm32/no-r32 -4970 1/imm32/imm32-is-first-inout -4971 0/imm32/no-disp32 -4972 0/imm32/output-is-write-only -4973 _Primitive-or-reg-with-reg/imm32/next -4974 _Primitive-or-reg-with-reg: -4975 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 -4976 "or"/imm32/name -4977 Single-int-var-in-some-register/imm32/inouts -4978 Single-int-var-in-some-register/imm32/outputs -4979 "09/or-with"/imm32/subx-name -4980 3/imm32/rm32-is-first-output -4981 1/imm32/r32-is-first-inout -4982 0/imm32/no-imm32 -4983 0/imm32/no-disp32 -4984 0/imm32/output-is-write-only -4985 _Primitive-or-reg-with-mem/imm32/next -4986 _Primitive-or-reg-with-mem: -4987 # or-with var1 var2/reg => 09/or-with var1 var2/r32 -4988 "or-with"/imm32/name -4989 Two-args-int-stack-int-reg/imm32/inouts -4990 0/imm32/outputs -4991 "09/or-with"/imm32/subx-name -4992 1/imm32/rm32-is-first-inout -4993 2/imm32/r32-is-second-inout -4994 0/imm32/no-imm32 -4995 0/imm32/no-disp32 -4996 0/imm32/output-is-write-only -4997 _Primitive-or-mem-with-reg/imm32/next -4998 _Primitive-or-mem-with-reg: -4999 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 +4960 _Primitive-and-mem-with-reg/imm32/next +4961 _Primitive-and-mem-with-reg: +4962 # var1/reg <- and var2 => 23/and var2/rm32 var1/r32 +4963 "and"/imm32/name +4964 Single-int-var-on-stack/imm32/inouts +4965 Single-int-var-in-some-register/imm32/outputs +4966 "23/and"/imm32/subx-name +4967 1/imm32/rm32-is-first-inout +4968 3/imm32/r32-is-first-output +4969 0/imm32/no-imm32 +4970 0/imm32/no-disp32 +4971 0/imm32/output-is-write-only +4972 _Primitive-and-lit-with-reg/imm32/next +4973 _Primitive-and-lit-with-reg: +4974 # var1/reg <- and lit => 81 4/subop/and var1/rm32 lit/imm32 +4975 "and"/imm32/name +4976 Single-lit-var/imm32/inouts +4977 Single-int-var-in-some-register/imm32/outputs +4978 "81 4/subop/and"/imm32/subx-name +4979 3/imm32/rm32-is-first-output +4980 0/imm32/no-r32 +4981 1/imm32/imm32-is-first-inout +4982 0/imm32/no-disp32 +4983 0/imm32/output-is-write-only +4984 _Primitive-and-lit-with-mem/imm32/next +4985 _Primitive-and-lit-with-mem: +4986 # and-with var1, lit => 81 4/subop/and var1/rm32 lit/imm32 +4987 "and-with"/imm32/name +4988 Int-var-and-literal/imm32/inouts +4989 0/imm32/outputs +4990 "81 4/subop/and"/imm32/subx-name +4991 1/imm32/rm32-is-first-inout +4992 0/imm32/no-r32 +4993 2/imm32/imm32-is-first-inout +4994 0/imm32/no-disp32 +4995 0/imm32/output-is-write-only +4996 _Primitive-or-with-eax/imm32/next +4997 # - or +4998 _Primitive-or-with-eax: +4999 # var/eax <- or lit => 0d/or-with-eax lit/imm32 5000 "or"/imm32/name -5001 Single-int-var-on-stack/imm32/inouts -5002 Single-int-var-in-some-register/imm32/outputs -5003 "0b/or"/imm32/subx-name -5004 1/imm32/rm32-is-first-inout -5005 3/imm32/r32-is-first-output -5006 0/imm32/no-imm32 +5001 Single-lit-var/imm32/inouts +5002 Single-int-var-in-eax/imm32/outputs +5003 "0d/or-with-eax"/imm32/subx-name +5004 0/imm32/no-rm32 +5005 0/imm32/no-r32 +5006 1/imm32/imm32-is-first-inout 5007 0/imm32/no-disp32 5008 0/imm32/output-is-write-only -5009 _Primitive-or-lit-with-reg/imm32/next -5010 _Primitive-or-lit-with-reg: -5011 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 +5009 _Primitive-or-reg-with-reg/imm32/next +5010 _Primitive-or-reg-with-reg: +5011 # var1/reg <- or var2/reg => 09/or-with var1/rm32 var2/r32 5012 "or"/imm32/name -5013 Single-lit-var/imm32/inouts -5014 Single-int-var-in-some-register/imm32/outputs -5015 "81 4/subop/or"/imm32/subx-name +5013 Single-int-var-in-some-register/imm32/inouts +5014 Single-int-var-in-some-register/imm32/outputs +5015 "09/or-with"/imm32/subx-name 5016 3/imm32/rm32-is-first-output -5017 0/imm32/no-r32 -5018 1/imm32/imm32-is-first-inout +5017 1/imm32/r32-is-first-inout +5018 0/imm32/no-imm32 5019 0/imm32/no-disp32 5020 0/imm32/output-is-write-only -5021 _Primitive-or-lit-with-mem/imm32/next -5022 _Primitive-or-lit-with-mem: -5023 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 +5021 _Primitive-or-reg-with-mem/imm32/next +5022 _Primitive-or-reg-with-mem: +5023 # or-with var1 var2/reg => 09/or-with var1 var2/r32 5024 "or-with"/imm32/name -5025 Int-var-and-literal/imm32/inouts +5025 Two-args-int-stack-int-reg/imm32/inouts 5026 0/imm32/outputs -5027 "81 4/subop/or"/imm32/subx-name +5027 "09/or-with"/imm32/subx-name 5028 1/imm32/rm32-is-first-inout -5029 0/imm32/no-r32 -5030 2/imm32/imm32-is-second-inout +5029 2/imm32/r32-is-second-inout +5030 0/imm32/no-imm32 5031 0/imm32/no-disp32 5032 0/imm32/output-is-write-only -5033 _Primitive-xor-with-eax/imm32/next -5034 # - xor -5035 _Primitive-xor-with-eax: -5036 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 -5037 "xor"/imm32/name -5038 Single-lit-var/imm32/inouts -5039 Single-int-var-in-eax/imm32/outputs -5040 "35/xor-with-eax"/imm32/subx-name -5041 0/imm32/no-rm32 -5042 0/imm32/no-r32 -5043 1/imm32/imm32-is-first-inout -5044 0/imm32/no-disp32 -5045 0/imm32/output-is-write-only -5046 _Primitive-xor-reg-with-reg/imm32/next -5047 _Primitive-xor-reg-with-reg: -5048 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 -5049 "xor"/imm32/name -5050 Single-int-var-in-some-register/imm32/inouts -5051 Single-int-var-in-some-register/imm32/outputs -5052 "31/xor-with"/imm32/subx-name -5053 3/imm32/rm32-is-first-output -5054 1/imm32/r32-is-first-inout -5055 0/imm32/no-imm32 -5056 0/imm32/no-disp32 -5057 0/imm32/output-is-write-only -5058 _Primitive-xor-reg-with-mem/imm32/next -5059 _Primitive-xor-reg-with-mem: -5060 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 -5061 "xor-with"/imm32/name -5062 Two-args-int-stack-int-reg/imm32/inouts -5063 0/imm32/outputs -5064 "31/xor-with"/imm32/subx-name -5065 1/imm32/rm32-is-first-inout -5066 2/imm32/r32-is-second-inout -5067 0/imm32/no-imm32 -5068 0/imm32/no-disp32 -5069 0/imm32/output-is-write-only -5070 _Primitive-xor-mem-with-reg/imm32/next -5071 _Primitive-xor-mem-with-reg: -5072 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 +5033 _Primitive-or-mem-with-reg/imm32/next +5034 _Primitive-or-mem-with-reg: +5035 # var1/reg <- or var2 => 0b/or var2/rm32 var1/r32 +5036 "or"/imm32/name +5037 Single-int-var-on-stack/imm32/inouts +5038 Single-int-var-in-some-register/imm32/outputs +5039 "0b/or"/imm32/subx-name +5040 1/imm32/rm32-is-first-inout +5041 3/imm32/r32-is-first-output +5042 0/imm32/no-imm32 +5043 0/imm32/no-disp32 +5044 0/imm32/output-is-write-only +5045 _Primitive-or-lit-with-reg/imm32/next +5046 _Primitive-or-lit-with-reg: +5047 # var1/reg <- or lit => 81 1/subop/or var1/rm32 lit/imm32 +5048 "or"/imm32/name +5049 Single-lit-var/imm32/inouts +5050 Single-int-var-in-some-register/imm32/outputs +5051 "81 4/subop/or"/imm32/subx-name +5052 3/imm32/rm32-is-first-output +5053 0/imm32/no-r32 +5054 1/imm32/imm32-is-first-inout +5055 0/imm32/no-disp32 +5056 0/imm32/output-is-write-only +5057 _Primitive-or-lit-with-mem/imm32/next +5058 _Primitive-or-lit-with-mem: +5059 # or-with var1, lit => 81 1/subop/or var1/rm32 lit/imm32 +5060 "or-with"/imm32/name +5061 Int-var-and-literal/imm32/inouts +5062 0/imm32/outputs +5063 "81 4/subop/or"/imm32/subx-name +5064 1/imm32/rm32-is-first-inout +5065 0/imm32/no-r32 +5066 2/imm32/imm32-is-second-inout +5067 0/imm32/no-disp32 +5068 0/imm32/output-is-write-only +5069 _Primitive-xor-with-eax/imm32/next +5070 # - xor +5071 _Primitive-xor-with-eax: +5072 # var/eax <- xor lit => 35/xor-with-eax lit/imm32 5073 "xor"/imm32/name -5074 Single-int-var-on-stack/imm32/inouts -5075 Single-int-var-in-some-register/imm32/outputs -5076 "33/xor"/imm32/subx-name -5077 1/imm32/rm32-is-first-inout -5078 3/imm32/r32-is-first-output -5079 0/imm32/no-imm32 +5074 Single-lit-var/imm32/inouts +5075 Single-int-var-in-eax/imm32/outputs +5076 "35/xor-with-eax"/imm32/subx-name +5077 0/imm32/no-rm32 +5078 0/imm32/no-r32 +5079 1/imm32/imm32-is-first-inout 5080 0/imm32/no-disp32 5081 0/imm32/output-is-write-only -5082 _Primitive-xor-lit-with-reg/imm32/next -5083 _Primitive-xor-lit-with-reg: -5084 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 +5082 _Primitive-xor-reg-with-reg/imm32/next +5083 _Primitive-xor-reg-with-reg: +5084 # var1/reg <- xor var2/reg => 31/xor-with var1/rm32 var2/r32 5085 "xor"/imm32/name -5086 Single-lit-var/imm32/inouts -5087 Single-int-var-in-some-register/imm32/outputs -5088 "81 4/subop/xor"/imm32/subx-name +5086 Single-int-var-in-some-register/imm32/inouts +5087 Single-int-var-in-some-register/imm32/outputs +5088 "31/xor-with"/imm32/subx-name 5089 3/imm32/rm32-is-first-output -5090 0/imm32/no-r32 -5091 1/imm32/imm32-is-first-inout +5090 1/imm32/r32-is-first-inout +5091 0/imm32/no-imm32 5092 0/imm32/no-disp32 5093 0/imm32/output-is-write-only -5094 _Primitive-xor-lit-with-mem/imm32/next -5095 _Primitive-xor-lit-with-mem: -5096 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 +5094 _Primitive-xor-reg-with-mem/imm32/next +5095 _Primitive-xor-reg-with-mem: +5096 # xor-with var1 var2/reg => 31/xor-with var1 var2/r32 5097 "xor-with"/imm32/name -5098 Int-var-and-literal/imm32/inouts +5098 Two-args-int-stack-int-reg/imm32/inouts 5099 0/imm32/outputs -5100 "81 4/subop/xor"/imm32/subx-name +5100 "31/xor-with"/imm32/subx-name 5101 1/imm32/rm32-is-first-inout -5102 0/imm32/no-r32 -5103 2/imm32/imm32-is-first-inout +5102 2/imm32/r32-is-second-inout +5103 0/imm32/no-imm32 5104 0/imm32/no-disp32 5105 0/imm32/output-is-write-only -5106 _Primitive-copy-to-eax/imm32/next -5107 # - copy -5108 _Primitive-copy-to-eax: -5109 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 -5110 "copy"/imm32/name -5111 Single-lit-var/imm32/inouts -5112 Single-int-var-in-eax/imm32/outputs -5113 "b8/copy-to-eax"/imm32/subx-name -5114 0/imm32/no-rm32 -5115 0/imm32/no-r32 -5116 1/imm32/imm32-is-first-inout -5117 0/imm32/no-disp32 -5118 1/imm32/output-is-write-only -5119 _Primitive-copy-to-ecx/imm32/next -5120 _Primitive-copy-to-ecx: -5121 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 -5122 "copy"/imm32/name -5123 Single-lit-var/imm32/inouts -5124 Single-int-var-in-ecx/imm32/outputs -5125 "b9/copy-to-ecx"/imm32/subx-name -5126 0/imm32/no-rm32 -5127 0/imm32/no-r32 -5128 1/imm32/imm32-is-first-inout -5129 0/imm32/no-disp32 -5130 1/imm32/output-is-write-only -5131 _Primitive-copy-to-edx/imm32/next -5132 _Primitive-copy-to-edx: -5133 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 -5134 "copy"/imm32/name -5135 Single-lit-var/imm32/inouts -5136 Single-int-var-in-edx/imm32/outputs -5137 "ba/copy-to-edx"/imm32/subx-name -5138 0/imm32/no-rm32 -5139 0/imm32/no-r32 -5140 1/imm32/imm32-is-first-inout -5141 0/imm32/no-disp32 -5142 1/imm32/output-is-write-only -5143 _Primitive-copy-to-ebx/imm32/next -5144 _Primitive-copy-to-ebx: -5145 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 +5106 _Primitive-xor-mem-with-reg/imm32/next +5107 _Primitive-xor-mem-with-reg: +5108 # var1/reg <- xor var2 => 33/xor var2/rm32 var1/r32 +5109 "xor"/imm32/name +5110 Single-int-var-on-stack/imm32/inouts +5111 Single-int-var-in-some-register/imm32/outputs +5112 "33/xor"/imm32/subx-name +5113 1/imm32/rm32-is-first-inout +5114 3/imm32/r32-is-first-output +5115 0/imm32/no-imm32 +5116 0/imm32/no-disp32 +5117 0/imm32/output-is-write-only +5118 _Primitive-xor-lit-with-reg/imm32/next +5119 _Primitive-xor-lit-with-reg: +5120 # var1/reg <- xor lit => 81 6/subop/xor var1/rm32 lit/imm32 +5121 "xor"/imm32/name +5122 Single-lit-var/imm32/inouts +5123 Single-int-var-in-some-register/imm32/outputs +5124 "81 4/subop/xor"/imm32/subx-name +5125 3/imm32/rm32-is-first-output +5126 0/imm32/no-r32 +5127 1/imm32/imm32-is-first-inout +5128 0/imm32/no-disp32 +5129 0/imm32/output-is-write-only +5130 _Primitive-xor-lit-with-mem/imm32/next +5131 _Primitive-xor-lit-with-mem: +5132 # xor-with var1, lit => 81 6/subop/xor var1/rm32 lit/imm32 +5133 "xor-with"/imm32/name +5134 Int-var-and-literal/imm32/inouts +5135 0/imm32/outputs +5136 "81 4/subop/xor"/imm32/subx-name +5137 1/imm32/rm32-is-first-inout +5138 0/imm32/no-r32 +5139 2/imm32/imm32-is-first-inout +5140 0/imm32/no-disp32 +5141 0/imm32/output-is-write-only +5142 _Primitive-copy-to-eax/imm32/next +5143 # - copy +5144 _Primitive-copy-to-eax: +5145 # var/eax <- copy lit => b8/copy-to-eax lit/imm32 5146 "copy"/imm32/name -5147 Single-lit-var/imm32/inouts -5148 Single-int-var-in-ebx/imm32/outputs -5149 "bb/copy-to-ebx"/imm32/subx-name +5147 Single-lit-var/imm32/inouts +5148 Single-int-var-in-eax/imm32/outputs +5149 "b8/copy-to-eax"/imm32/subx-name 5150 0/imm32/no-rm32 5151 0/imm32/no-r32 5152 1/imm32/imm32-is-first-inout 5153 0/imm32/no-disp32 5154 1/imm32/output-is-write-only -5155 _Primitive-copy-to-esi/imm32/next -5156 _Primitive-copy-to-esi: -5157 # var/esi <- copy lit => be/copy-to-esi lit/imm32 +5155 _Primitive-copy-to-ecx/imm32/next +5156 _Primitive-copy-to-ecx: +5157 # var/ecx <- copy lit => b9/copy-to-ecx lit/imm32 5158 "copy"/imm32/name -5159 Single-lit-var/imm32/inouts -5160 Single-int-var-in-esi/imm32/outputs -5161 "be/copy-to-esi"/imm32/subx-name +5159 Single-lit-var/imm32/inouts +5160 Single-int-var-in-ecx/imm32/outputs +5161 "b9/copy-to-ecx"/imm32/subx-name 5162 0/imm32/no-rm32 5163 0/imm32/no-r32 5164 1/imm32/imm32-is-first-inout 5165 0/imm32/no-disp32 5166 1/imm32/output-is-write-only -5167 _Primitive-copy-to-edi/imm32/next -5168 _Primitive-copy-to-edi: -5169 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 +5167 _Primitive-copy-to-edx/imm32/next +5168 _Primitive-copy-to-edx: +5169 # var/edx <- copy lit => ba/copy-to-edx lit/imm32 5170 "copy"/imm32/name -5171 Single-lit-var/imm32/inouts -5172 Single-int-var-in-edi/imm32/outputs -5173 "bf/copy-to-edi"/imm32/subx-name +5171 Single-lit-var/imm32/inouts +5172 Single-int-var-in-edx/imm32/outputs +5173 "ba/copy-to-edx"/imm32/subx-name 5174 0/imm32/no-rm32 5175 0/imm32/no-r32 5176 1/imm32/imm32-is-first-inout 5177 0/imm32/no-disp32 5178 1/imm32/output-is-write-only -5179 _Primitive-copy-reg-to-reg/imm32/next -5180 _Primitive-copy-reg-to-reg: -5181 # var1/reg <- copy var2/reg => 89/copy-to var1/rm32 var2/r32 +5179 _Primitive-copy-to-ebx/imm32/next +5180 _Primitive-copy-to-ebx: +5181 # var/ebx <- copy lit => bb/copy-to-ebx lit/imm32 5182 "copy"/imm32/name -5183 Single-int-var-in-some-register/imm32/inouts -5184 Single-int-var-in-some-register/imm32/outputs -5185 "89/copy-to"/imm32/subx-name -5186 3/imm32/rm32-is-first-output -5187 1/imm32/r32-is-first-inout -5188 0/imm32/no-imm32 +5183 Single-lit-var/imm32/inouts +5184 Single-int-var-in-ebx/imm32/outputs +5185 "bb/copy-to-ebx"/imm32/subx-name +5186 0/imm32/no-rm32 +5187 0/imm32/no-r32 +5188 1/imm32/imm32-is-first-inout 5189 0/imm32/no-disp32 5190 1/imm32/output-is-write-only -5191 _Primitive-copy-reg-to-mem/imm32/next -5192 _Primitive-copy-reg-to-mem: -5193 # copy-to var1 var2/reg => 89/copy-to var1 var2/r32 -5194 "copy-to"/imm32/name -5195 Two-args-int-stack-int-reg/imm32/inouts -5196 0/imm32/outputs -5197 "89/copy-to"/imm32/subx-name -5198 1/imm32/rm32-is-first-inout -5199 2/imm32/r32-is-second-inout -5200 0/imm32/no-imm32 +5191 _Primitive-copy-to-esi/imm32/next +5192 _Primitive-copy-to-esi: +5193 # var/esi <- copy lit => be/copy-to-esi lit/imm32 +5194 "copy"/imm32/name +5195 Single-lit-var/imm32/inouts +5196 Single-int-var-in-esi/imm32/outputs +5197 "be/copy-to-esi"/imm32/subx-name +5198 0/imm32/no-rm32 +5199 0/imm32/no-r32 +5200 1/imm32/imm32-is-first-inout 5201 0/imm32/no-disp32 5202 1/imm32/output-is-write-only -5203 _Primitive-copy-mem-to-reg/imm32/next -5204 _Primitive-copy-mem-to-reg: -5205 # var1/reg <- copy var2 => 8b/copy-from var2/rm32 var1/r32 +5203 _Primitive-copy-to-edi/imm32/next +5204 _Primitive-copy-to-edi: +5205 # var/edi <- copy lit => bf/copy-to-edi lit/imm32 5206 "copy"/imm32/name -5207 Single-int-var-on-stack/imm32/inouts -5208 Single-int-var-in-some-register/imm32/outputs -5209 "8b/copy-from"/imm32/subx-name -5210 1/imm32/rm32-is-first-inout -5211 3/imm32/r32-is-first-output -5212 0/imm32/no-imm32 +5207 Single-lit-var/imm32/inouts +5208 Single-int-var-in-edi/imm32/outputs +5209 "bf/copy-to-edi"/imm32/subx-name +5210 0/imm32/no-rm32 +5211 0/imm32/no-r32 +5212 1/imm32/imm32-is-first-inout 5213 0/imm32/no-disp32 5214 1/imm32/output-is-write-only -5215 _Primitive-copy-lit-to-reg/imm32/next -5216 _Primitive-copy-lit-to-reg: -5217 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 +5215 _Primitive-copy-reg-to-reg/imm32/next +5216 _Primitive-copy-reg-to-reg: +5217 # var1/reg <- copy var2/reg => 89/copy-to var1/rm32 var2/r32 5218 "copy"/imm32/name -5219 Single-lit-var/imm32/inouts -5220 Single-int-var-in-some-register/imm32/outputs -5221 "c7 0/subop/copy"/imm32/subx-name +5219 Single-int-var-in-some-register/imm32/inouts +5220 Single-int-var-in-some-register/imm32/outputs +5221 "89/copy-to"/imm32/subx-name 5222 3/imm32/rm32-is-first-output -5223 0/imm32/no-r32 -5224 1/imm32/imm32-is-first-inout +5223 1/imm32/r32-is-first-inout +5224 0/imm32/no-imm32 5225 0/imm32/no-disp32 5226 1/imm32/output-is-write-only -5227 _Primitive-copy-lit-to-mem/imm32/next -5228 _Primitive-copy-lit-to-mem: -5229 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 +5227 _Primitive-copy-reg-to-mem/imm32/next +5228 _Primitive-copy-reg-to-mem: +5229 # copy-to var1 var2/reg => 89/copy-to var1 var2/r32 5230 "copy-to"/imm32/name -5231 Int-var-and-literal/imm32/inouts +5231 Two-args-int-stack-int-reg/imm32/inouts 5232 0/imm32/outputs -5233 "c7 0/subop/copy"/imm32/subx-name +5233 "89/copy-to"/imm32/subx-name 5234 1/imm32/rm32-is-first-inout -5235 0/imm32/no-r32 -5236 2/imm32/imm32-is-first-inout +5235 2/imm32/r32-is-second-inout +5236 0/imm32/no-imm32 5237 0/imm32/no-disp32 5238 1/imm32/output-is-write-only -5239 _Primitive-compare-mem-with-reg/imm32/next -5240 # - compare -5241 _Primitive-compare-mem-with-reg: -5242 # compare var1 var2/reg => 39/compare-> var1/rm32 var2/r32 -5243 "compare"/imm32/name -5244 Two-args-int-stack-int-reg/imm32/inouts -5245 0/imm32/outputs -5246 "39/compare"/imm32/subx-name -5247 1/imm32/rm32-is-first-inout -5248 2/imm32/r32-is-second-inout -5249 0/imm32/no-imm32 -5250 0/imm32/no-disp32 -5251 0/imm32/output-is-write-only -5252 _Primitive-compare-reg-with-mem/imm32/next -5253 _Primitive-compare-reg-with-mem: -5254 # compare var1/reg var2 => 3b/compare-> var2/rm32 var1/r32 -5255 "compare"/imm32/name -5256 Two-args-int-reg-int-stack/imm32/inouts -5257 0/imm32/outputs -5258 "3b/compare"/imm32/subx-name -5259 2/imm32/rm32-is-second-inout -5260 1/imm32/r32-is-first-inout -5261 0/imm32/no-imm32 -5262 0/imm32/no-disp32 -5263 0/imm32/output-is-write-only -5264 _Primitive-compare-eax-with-literal/imm32/next -5265 _Primitive-compare-eax-with-literal: -5266 # compare var1/eax n => 3d/compare-eax-with n/imm32 -5267 "compare"/imm32/name -5268 Two-args-int-eax-int-literal/imm32/inouts -5269 0/imm32/outputs -5270 "3d/compare-eax-with"/imm32/subx-name -5271 0/imm32/no-rm32 -5272 0/imm32/no-r32 -5273 2/imm32/imm32-is-second-inout -5274 0/imm32/no-disp32 -5275 0/imm32/output-is-write-only -5276 _Primitive-compare-regmem-with-literal/imm32/next -5277 _Primitive-compare-regmem-with-literal: -5278 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32 +5239 _Primitive-copy-mem-to-reg/imm32/next +5240 _Primitive-copy-mem-to-reg: +5241 # var1/reg <- copy var2 => 8b/copy-from var2/rm32 var1/r32 +5242 "copy"/imm32/name +5243 Single-int-var-on-stack/imm32/inouts +5244 Single-int-var-in-some-register/imm32/outputs +5245 "8b/copy-from"/imm32/subx-name +5246 1/imm32/rm32-is-first-inout +5247 3/imm32/r32-is-first-output +5248 0/imm32/no-imm32 +5249 0/imm32/no-disp32 +5250 1/imm32/output-is-write-only +5251 _Primitive-copy-lit-to-reg/imm32/next +5252 _Primitive-copy-lit-to-reg: +5253 # var1/reg <- copy lit => c7 0/subop/copy var1/rm32 lit/imm32 +5254 "copy"/imm32/name +5255 Single-lit-var/imm32/inouts +5256 Single-int-var-in-some-register/imm32/outputs +5257 "c7 0/subop/copy"/imm32/subx-name +5258 3/imm32/rm32-is-first-output +5259 0/imm32/no-r32 +5260 1/imm32/imm32-is-first-inout +5261 0/imm32/no-disp32 +5262 1/imm32/output-is-write-only +5263 _Primitive-copy-lit-to-mem/imm32/next +5264 _Primitive-copy-lit-to-mem: +5265 # copy-to var1, lit => c7 0/subop/copy var1/rm32 lit/imm32 +5266 "copy-to"/imm32/name +5267 Int-var-and-literal/imm32/inouts +5268 0/imm32/outputs +5269 "c7 0/subop/copy"/imm32/subx-name +5270 1/imm32/rm32-is-first-inout +5271 0/imm32/no-r32 +5272 2/imm32/imm32-is-first-inout +5273 0/imm32/no-disp32 +5274 1/imm32/output-is-write-only +5275 _Primitive-compare-mem-with-reg/imm32/next +5276 # - compare +5277 _Primitive-compare-mem-with-reg: +5278 # compare var1 var2/reg => 39/compare-> var1/rm32 var2/r32 5279 "compare"/imm32/name -5280 Int-var-and-literal/imm32/inouts +5280 Two-args-int-stack-int-reg/imm32/inouts 5281 0/imm32/outputs -5282 "81 7/subop/compare"/imm32/subx-name +5282 "39/compare"/imm32/subx-name 5283 1/imm32/rm32-is-first-inout -5284 0/imm32/no-r32 -5285 2/imm32/imm32-is-second-inout +5284 2/imm32/r32-is-second-inout +5285 0/imm32/no-imm32 5286 0/imm32/no-disp32 5287 0/imm32/output-is-write-only -5288 _Primitive-multiply-reg-by-mem/imm32/next -5289 # - multiply -5290 _Primitive-multiply-reg-by-mem: -5291 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 -5292 "multiply"/imm32/name -5293 Single-int-var-on-stack/imm32/inouts -5294 Single-int-var-in-some-register/imm32/outputs -5295 "0f af/multiply"/imm32/subx-name -5296 1/imm32/rm32-is-first-inout -5297 3/imm32/r32-is-first-output -5298 0/imm32/no-imm32 -5299 0/imm32/no-disp32 -5300 0/imm32/output-is-write-only -5301 _Primitive-break-if-addr</imm32/next -5302 # - branches -5303 _Primitive-break-if-addr<: -5304 "break-if-addr<"/imm32/name -5305 0/imm32/inouts -5306 0/imm32/outputs -5307 "0f 82/jump-if-addr< break/disp32"/imm32/subx-name -5308 0/imm32/no-rm32 -5309 0/imm32/no-r32 -5310 0/imm32/no-imm32 -5311 0/imm32/no-disp32 -5312 0/imm32/no-output -5313 _Primitive-break-if-addr>=/imm32/next -5314 _Primitive-break-if-addr>=: -5315 "break-if-addr>="/imm32/name -5316 0/imm32/inouts +5288 _Primitive-compare-reg-with-mem/imm32/next +5289 _Primitive-compare-reg-with-mem: +5290 # compare var1/reg var2 => 3b/compare-> var2/rm32 var1/r32 +5291 "compare"/imm32/name +5292 Two-args-int-reg-int-stack/imm32/inouts +5293 0/imm32/outputs +5294 "3b/compare"/imm32/subx-name +5295 2/imm32/rm32-is-second-inout +5296 1/imm32/r32-is-first-inout +5297 0/imm32/no-imm32 +5298 0/imm32/no-disp32 +5299 0/imm32/output-is-write-only +5300 _Primitive-compare-eax-with-literal/imm32/next +5301 _Primitive-compare-eax-with-literal: +5302 # compare var1/eax n => 3d/compare-eax-with n/imm32 +5303 "compare"/imm32/name +5304 Two-args-int-eax-int-literal/imm32/inouts +5305 0/imm32/outputs +5306 "3d/compare-eax-with"/imm32/subx-name +5307 0/imm32/no-rm32 +5308 0/imm32/no-r32 +5309 2/imm32/imm32-is-second-inout +5310 0/imm32/no-disp32 +5311 0/imm32/output-is-write-only +5312 _Primitive-compare-regmem-with-literal/imm32/next +5313 _Primitive-compare-regmem-with-literal: +5314 # compare var1 n => 81 7/subop/compare *(ebp+___) n/imm32 +5315 "compare"/imm32/name +5316 Int-var-and-literal/imm32/inouts 5317 0/imm32/outputs -5318 "0f 83/jump-if-addr>= break/disp32"/imm32/subx-name -5319 0/imm32/no-rm32 +5318 "81 7/subop/compare"/imm32/subx-name +5319 1/imm32/rm32-is-first-inout 5320 0/imm32/no-r32 -5321 0/imm32/no-imm32 +5321 2/imm32/imm32-is-second-inout 5322 0/imm32/no-disp32 -5323 0/imm32/no-output -5324 _Primitive-break-if-=/imm32/next -5325 _Primitive-break-if-=: -5326 "break-if-="/imm32/name -5327 0/imm32/inouts -5328 0/imm32/outputs -5329 "0f 84/jump-if-= break/disp32"/imm32/subx-name -5330 0/imm32/no-rm32 -5331 0/imm32/no-r32 -5332 0/imm32/no-imm32 -5333 0/imm32/no-disp32 -5334 0/imm32/no-output -5335 _Primitive-break-if-!=/imm32/next -5336 _Primitive-break-if-!=: -5337 "break-if-!="/imm32/name -5338 0/imm32/inouts -5339 0/imm32/outputs -5340 "0f 85/jump-if-!= break/disp32"/imm32/subx-name -5341 0/imm32/no-rm32 -5342 0/imm32/no-r32 -5343 0/imm32/no-imm32 -5344 0/imm32/no-disp32 -5345 0/imm32/no-output -5346 _Primitive-break-if-addr<=/imm32/next -5347 _Primitive-break-if-addr<=: -5348 "break-if-addr<="/imm32/name -5349 0/imm32/inouts -5350 0/imm32/outputs -5351 "0f 86/jump-if-addr<= break/disp32"/imm32/subx-name -5352 0/imm32/no-rm32 -5353 0/imm32/no-r32 -5354 0/imm32/no-imm32 -5355 0/imm32/no-disp32 -5356 0/imm32/no-output -5357 _Primitive-break-if-addr>/imm32/next -5358 _Primitive-break-if-addr>: -5359 "break-if-addr>"/imm32/name -5360 0/imm32/inouts -5361 0/imm32/outputs -5362 "0f 87/jump-if-addr> break/disp32"/imm32/subx-name -5363 0/imm32/no-rm32 -5364 0/imm32/no-r32 -5365 0/imm32/no-imm32 -5366 0/imm32/no-disp32 -5367 0/imm32/no-output -5368 _Primitive-break-if-</imm32/next -5369 _Primitive-break-if-<: -5370 "break-if-<"/imm32/name -5371 0/imm32/inouts -5372 0/imm32/outputs -5373 "0f 8c/jump-if-< break/disp32"/imm32/subx-name -5374 0/imm32/no-rm32 -5375 0/imm32/no-r32 -5376 0/imm32/no-imm32 -5377 0/imm32/no-disp32 -5378 0/imm32/no-output -5379 _Primitive-break-if->=/imm32/next -5380 _Primitive-break-if->=: -5381 "break-if->="/imm32/name -5382 0/imm32/inouts -5383 0/imm32/outputs -5384 "0f 8d/jump-if->= break/disp32"/imm32/subx-name -5385 0/imm32/no-rm32 -5386 0/imm32/no-r32 -5387 0/imm32/no-imm32 -5388 0/imm32/no-disp32 -5389 0/imm32/no-output -5390 _Primitive-break-if-<=/imm32/next -5391 _Primitive-break-if-<=: -5392 "break-if-<="/imm32/name -5393 0/imm32/inouts -5394 0/imm32/outputs -5395 "0f 8e/jump-if-<= break/disp32"/imm32/subx-name -5396 0/imm32/no-rm32 -5397 0/imm32/no-r32 -5398 0/imm32/no-imm32 -5399 0/imm32/no-disp32 -5400 0/imm32/no-output -5401 _Primitive-break-if->/imm32/next -5402 _Primitive-break-if->: -5403 "break-if->"/imm32/name -5404 0/imm32/inouts -5405 0/imm32/outputs -5406 "0f 8f/jump-if-> break/disp32"/imm32/subx-name -5407 0/imm32/no-rm32 -5408 0/imm32/no-r32 -5409 0/imm32/no-imm32 -5410 0/imm32/no-disp32 -5411 0/imm32/no-output -5412 _Primitive-loop-if-addr</imm32/next -5413 _Primitive-loop-if-addr<: -5414 "loop-if-addr<"/imm32/name -5415 0/imm32/inouts -5416 0/imm32/outputs -5417 "0f 82/jump-if-addr< loop/disp32"/imm32/subx-name -5418 0/imm32/no-rm32 -5419 0/imm32/no-r32 -5420 0/imm32/no-imm32 -5421 0/imm32/no-disp32 -5422 0/imm32/no-output -5423 _Primitive-loop-if-addr>=/imm32/next -5424 _Primitive-loop-if-addr>=: -5425 "loop-if-addr>="/imm32/name -5426 0/imm32/inouts -5427 0/imm32/outputs -5428 "0f 83/jump-if-addr>= loop/disp32"/imm32/subx-name -5429 0/imm32/no-rm32 -5430 0/imm32/no-r32 -5431 0/imm32/no-imm32 -5432 0/imm32/no-disp32 -5433 0/imm32/no-output -5434 _Primitive-loop-if-=/imm32/next -5435 _Primitive-loop-if-=: -5436 "loop-if-="/imm32/name -5437 0/imm32/inouts -5438 0/imm32/outputs -5439 "0f 84/jump-if-= loop/disp32"/imm32/subx-name -5440 0/imm32/no-rm32 -5441 0/imm32/no-r32 -5442 0/imm32/no-imm32 -5443 0/imm32/no-disp32 -5444 0/imm32/no-output -5445 _Primitive-loop-if-!=/imm32/next -5446 _Primitive-loop-if-!=: -5447 "loop-if-!="/imm32/name -5448 0/imm32/inouts -5449 0/imm32/outputs -5450 "0f 85/jump-if-!= loop/disp32"/imm32/subx-name -5451 0/imm32/no-rm32 -5452 0/imm32/no-r32 -5453 0/imm32/no-imm32 -5454 0/imm32/no-disp32 -5455 0/imm32/no-output -5456 _Primitive-loop-if-addr<=/imm32/next -5457 _Primitive-loop-if-addr<=: -5458 "loop-if-addr<="/imm32/name -5459 0/imm32/inouts -5460 0/imm32/outputs -5461 "0f 86/jump-if-addr<= loop/disp32"/imm32/subx-name -5462 0/imm32/no-rm32 -5463 0/imm32/no-r32 -5464 0/imm32/no-imm32 -5465 0/imm32/no-disp32 -5466 0/imm32/no-output -5467 _Primitive-loop-if-addr>/imm32/next -5468 _Primitive-loop-if-addr>: -5469 "loop-if-addr>"/imm32/name -5470 0/imm32/inouts -5471 0/imm32/outputs -5472 "0f 87/jump-if-addr> loop/disp32"/imm32/subx-name -5473 0/imm32/no-rm32 -5474 0/imm32/no-r32 -5475 0/imm32/no-imm32 -5476 0/imm32/no-disp32 -5477 0/imm32/no-output -5478 _Primitive-loop-if-</imm32/next -5479 _Primitive-loop-if-<: -5480 "loop-if-<"/imm32/name -5481 0/imm32/inouts -5482 0/imm32/outputs -5483 "0f 8c/jump-if-< loop/disp32"/imm32/subx-name -5484 0/imm32/no-rm32 -5485 0/imm32/no-r32 -5486 0/imm32/no-imm32 -5487 0/imm32/no-disp32 -5488 0/imm32/no-output -5489 _Primitive-loop-if->=/imm32/next -5490 _Primitive-loop-if->=: -5491 "loop-if->="/imm32/name -5492 0/imm32/inouts -5493 0/imm32/outputs -5494 "0f 8d/jump-if->= loop/disp32"/imm32/subx-name -5495 0/imm32/no-rm32 -5496 0/imm32/no-r32 -5497 0/imm32/no-imm32 -5498 0/imm32/no-disp32 -5499 0/imm32/no-output -5500 _Primitive-loop-if-<=/imm32/next -5501 _Primitive-loop-if-<=: -5502 "loop-if-<="/imm32/name -5503 0/imm32/inouts -5504 0/imm32/outputs -5505 "0f 8e/jump-if-<= loop/disp32"/imm32/subx-name -5506 0/imm32/no-rm32 -5507 0/imm32/no-r32 -5508 0/imm32/no-imm32 -5509 0/imm32/no-disp32 -5510 0/imm32/no-output -5511 _Primitive-loop-if->/imm32/next -5512 _Primitive-loop-if->: -5513 "loop-if->"/imm32/name -5514 0/imm32/inouts -5515 0/imm32/outputs -5516 "0f 8f/jump-if-> loop/disp32"/imm32/subx-name -5517 0/imm32/no-rm32 -5518 0/imm32/no-r32 -5519 0/imm32/no-imm32 -5520 0/imm32/no-disp32 -5521 0/imm32/no-output -5522 _Primitive-loop/imm32/next # we probably don't need an unconditional break -5523 _Primitive-loop: -5524 "loop"/imm32/name -5525 0/imm32/inouts -5526 0/imm32/outputs -5527 "e9/jump loop/disp32"/imm32/subx-name -5528 0/imm32/no-rm32 -5529 0/imm32/no-r32 -5530 0/imm32/no-imm32 -5531 0/imm32/no-disp32 -5532 0/imm32/no-output -5533 _Primitive-break-if-addr<-named/imm32/next -5534 # - branches to named blocks -5535 _Primitive-break-if-addr<-named: -5536 "break-if-addr<"/imm32/name -5537 Single-lit-var/imm32/inouts -5538 0/imm32/outputs -5539 "0f 82/jump-if-addr<"/imm32/subx-name -5540 0/imm32/no-rm32 -5541 0/imm32/no-r32 -5542 0/imm32/no-imm32 -5543 1/imm32/disp32-is-first-inout -5544 0/imm32/no-output -5545 _Primitive-break-if-addr>=-named/imm32/next -5546 _Primitive-break-if-addr>=-named: -5547 "break-if-addr>="/imm32/name -5548 Single-lit-var/imm32/inouts -5549 0/imm32/outputs -5550 "0f 83/jump-if-addr>="/imm32/subx-name -5551 0/imm32/no-rm32 -5552 0/imm32/no-r32 -5553 0/imm32/no-imm32 -5554 1/imm32/disp32-is-first-inout -5555 0/imm32/no-output -5556 _Primitive-break-if-=-named/imm32/next -5557 _Primitive-break-if-=-named: -5558 "break-if-="/imm32/name -5559 Single-lit-var/imm32/inouts -5560 0/imm32/outputs -5561 "0f 84/jump-if-="/imm32/subx-name -5562 0/imm32/no-rm32 -5563 0/imm32/no-r32 -5564 0/imm32/no-imm32 -5565 1/imm32/disp32-is-first-inout -5566 0/imm32/no-output -5567 _Primitive-break-if-!=-named/imm32/next -5568 _Primitive-break-if-!=-named: -5569 "break-if-!="/imm32/name -5570 Single-lit-var/imm32/inouts -5571 0/imm32/outputs -5572 "0f 85/jump-if-!="/imm32/subx-name -5573 0/imm32/no-rm32 -5574 0/imm32/no-r32 -5575 0/imm32/no-imm32 -5576 1/imm32/disp32-is-first-inout -5577 0/imm32/no-output -5578 _Primitive-break-if-addr<=-named/imm32/next -5579 _Primitive-break-if-addr<=-named: -5580 "break-if-addr<="/imm32/name -5581 Single-lit-var/imm32/inouts -5582 0/imm32/outputs -5583 "0f 86/jump-if-addr<="/imm32/subx-name -5584 0/imm32/no-rm32 -5585 0/imm32/no-r32 -5586 0/imm32/no-imm32 -5587 1/imm32/disp32-is-first-inout -5588 0/imm32/no-output -5589 _Primitive-break-if-addr>-named/imm32/next -5590 _Primitive-break-if-addr>-named: -5591 "break-if-addr>"/imm32/name -5592 Single-lit-var/imm32/inouts -5593 0/imm32/outputs -5594 "0f 87/jump-if-addr>"/imm32/subx-name -5595 0/imm32/no-rm32 -5596 0/imm32/no-r32 -5597 0/imm32/no-imm32 -5598 1/imm32/disp32-is-first-inout -5599 0/imm32/no-output -5600 _Primitive-break-if-<-named/imm32/next -5601 _Primitive-break-if-<-named: -5602 "break-if-<"/imm32/name -5603 Single-lit-var/imm32/inouts -5604 0/imm32/outputs -5605 "0f 8c/jump-if-<"/imm32/subx-name -5606 0/imm32/no-rm32 -5607 0/imm32/no-r32 -5608 0/imm32/no-imm32 -5609 1/imm32/disp32-is-first-inout -5610 0/imm32/no-output -5611 _Primitive-break-if->=-named/imm32/next -5612 _Primitive-break-if->=-named: -5613 "break-if->="/imm32/name -5614 Single-lit-var/imm32/inouts -5615 0/imm32/outputs -5616 "0f 8d/jump-if->="/imm32/subx-name -5617 0/imm32/no-rm32 -5618 0/imm32/no-r32 -5619 0/imm32/no-imm32 -5620 1/imm32/disp32-is-first-inout -5621 0/imm32/no-output -5622 _Primitive-break-if-<=-named/imm32/next -5623 _Primitive-break-if-<=-named: -5624 "break-if-<="/imm32/name -5625 Single-lit-var/imm32/inouts -5626 0/imm32/outputs -5627 "0f 8e/jump-if-<="/imm32/subx-name -5628 0/imm32/no-rm32 -5629 0/imm32/no-r32 -5630 0/imm32/no-imm32 -5631 1/imm32/disp32-is-first-inout -5632 0/imm32/no-output -5633 _Primitive-break-if->-named/imm32/next -5634 _Primitive-break-if->-named: -5635 "break-if->"/imm32/name -5636 Single-lit-var/imm32/inouts -5637 0/imm32/outputs -5638 "0f 8f/jump-if->"/imm32/subx-name -5639 0/imm32/no-rm32 -5640 0/imm32/no-r32 -5641 0/imm32/no-imm32 -5642 1/imm32/disp32-is-first-inout -5643 0/imm32/no-output -5644 _Primitive-loop-if-addr<-named/imm32/next -5645 _Primitive-loop-if-addr<-named: -5646 "loop-if-addr<"/imm32/name -5647 Single-lit-var/imm32/inouts -5648 0/imm32/outputs -5649 "0f 82/jump-if-addr<"/imm32/subx-name -5650 0/imm32/no-rm32 -5651 0/imm32/no-r32 -5652 0/imm32/no-imm32 -5653 1/imm32/disp32-is-first-inout -5654 0/imm32/no-output -5655 _Primitive-loop-if-addr>=-named/imm32/next -5656 _Primitive-loop-if-addr>=-named: -5657 "loop-if-addr>="/imm32/name -5658 Single-lit-var/imm32/inouts -5659 0/imm32/outputs -5660 "0f 83/jump-if-addr>="/imm32/subx-name -5661 0/imm32/no-rm32 -5662 0/imm32/no-r32 -5663 0/imm32/no-imm32 -5664 1/imm32/disp32-is-first-inout -5665 0/imm32/no-output -5666 _Primitive-loop-if-=-named/imm32/next -5667 _Primitive-loop-if-=-named: -5668 "loop-if-="/imm32/name -5669 Single-lit-var/imm32/inouts -5670 0/imm32/outputs -5671 "0f 84/jump-if-="/imm32/subx-name -5672 0/imm32/no-rm32 -5673 0/imm32/no-r32 -5674 0/imm32/no-imm32 -5675 1/imm32/disp32-is-first-inout -5676 0/imm32/no-output -5677 _Primitive-loop-if-!=-named/imm32/next -5678 _Primitive-loop-if-!=-named: -5679 "loop-if-!="/imm32/name -5680 Single-lit-var/imm32/inouts -5681 0/imm32/outputs -5682 "0f 85/jump-if-!="/imm32/subx-name -5683 0/imm32/no-rm32 -5684 0/imm32/no-r32 -5685 0/imm32/no-imm32 -5686 1/imm32/disp32-is-first-inout -5687 0/imm32/no-output -5688 _Primitive-loop-if-addr<=-named/imm32/next -5689 _Primitive-loop-if-addr<=-named: -5690 "loop-if-addr<="/imm32/name -5691 Single-lit-var/imm32/inouts -5692 0/imm32/outputs -5693 "0f 86/jump-if-addr<="/imm32/subx-name -5694 0/imm32/no-rm32 -5695 0/imm32/no-r32 -5696 0/imm32/no-imm32 -5697 1/imm32/disp32-is-first-inout -5698 0/imm32/no-output -5699 _Primitive-loop-if-addr>-named/imm32/next -5700 _Primitive-loop-if-addr>-named: -5701 "loop-if-addr>"/imm32/name -5702 Single-lit-var/imm32/inouts -5703 0/imm32/outputs -5704 "0f 87/jump-if-addr>"/imm32/subx-name -5705 0/imm32/no-rm32 -5706 0/imm32/no-r32 -5707 0/imm32/no-imm32 -5708 1/imm32/disp32-is-first-inout -5709 0/imm32/no-output -5710 _Primitive-loop-if-<-named/imm32/next -5711 _Primitive-loop-if-<-named: -5712 "loop-if-<"/imm32/name -5713 Single-lit-var/imm32/inouts -5714 0/imm32/outputs -5715 "0f 8c/jump-if-<"/imm32/subx-name -5716 0/imm32/no-rm32 -5717 0/imm32/no-r32 -5718 0/imm32/no-imm32 -5719 1/imm32/disp32-is-first-inout -5720 0/imm32/no-output -5721 _Primitive-loop-if->=-named/imm32/next -5722 _Primitive-loop-if->=-named: -5723 "loop-if->="/imm32/name -5724 Single-lit-var/imm32/inouts -5725 0/imm32/outputs -5726 "0f 8d/jump-if->="/imm32/subx-name -5727 0/imm32/no-rm32 -5728 0/imm32/no-r32 -5729 0/imm32/no-imm32 -5730 1/imm32/disp32-is-first-inout -5731 0/imm32/no-output -5732 _Primitive-loop-if-<=-named/imm32/next -5733 _Primitive-loop-if-<=-named: -5734 "loop-if-<="/imm32/name -5735 Single-lit-var/imm32/inouts -5736 0/imm32/outputs -5737 "0f 8e/jump-if-<="/imm32/subx-name -5738 0/imm32/no-rm32 -5739 0/imm32/no-r32 -5740 0/imm32/no-imm32 -5741 1/imm32/disp32-is-first-inout -5742 0/imm32/no-output -5743 _Primitive-loop-if->-named/imm32/next -5744 _Primitive-loop-if->-named: -5745 "loop-if->"/imm32/name -5746 Single-lit-var/imm32/inouts -5747 0/imm32/outputs -5748 "0f 8f/jump-if->"/imm32/subx-name -5749 0/imm32/no-rm32 -5750 0/imm32/no-r32 -5751 0/imm32/no-imm32 -5752 1/imm32/disp32-is-first-inout -5753 0/imm32/no-output -5754 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break -5755 _Primitive-loop-named: -5756 "loop"/imm32/name -5757 Single-lit-var/imm32/inouts -5758 0/imm32/outputs -5759 "e9/jump"/imm32/subx-name -5760 0/imm32/no-rm32 -5761 0/imm32/no-r32 -5762 0/imm32/no-imm32 -5763 1/imm32/disp32-is-first-inout -5764 0/imm32/no-output -5765 0/imm32/next -5766 -5767 Single-int-var-on-stack: -5768 Int-var-on-stack/imm32 -5769 0/imm32/next -5770 -5771 Int-var-on-stack: -5772 "arg1"/imm32/name -5773 Type-int/imm32 -5774 1/imm32/some-block-depth -5775 1/imm32/some-stack-offset -5776 0/imm32/no-register -5777 -5778 Two-args-int-stack-int-reg: -5779 Int-var-on-stack/imm32 -5780 Single-int-var-in-some-register/imm32/next -5781 -5782 Two-args-int-reg-int-stack: -5783 Int-var-in-some-register/imm32 -5784 Single-int-var-on-stack/imm32/next -5785 -5786 Two-args-int-eax-int-literal: -5787 Int-var-in-eax/imm32 -5788 Single-lit-var/imm32/next -5789 -5790 Int-var-and-literal: -5791 Int-var-on-stack/imm32 -5792 Single-lit-var/imm32/next -5793 -5794 Single-int-var-in-some-register: -5795 Int-var-in-some-register/imm32 -5796 0/imm32/next -5797 -5798 Int-var-in-some-register: -5799 "arg1"/imm32/name -5800 Type-int/imm32 -5801 1/imm32/some-block-depth -5802 0/imm32/no-stack-offset -5803 "*"/imm32/register -5804 -5805 Single-int-var-in-eax: -5806 Int-var-in-eax/imm32 -5807 0/imm32/next -5808 -5809 Int-var-in-eax: -5810 "arg1"/imm32/name -5811 Type-int/imm32 -5812 1/imm32/some-block-depth -5813 0/imm32/no-stack-offset -5814 "eax"/imm32/register -5815 -5816 Single-int-var-in-ecx: -5817 Int-var-in-ecx/imm32 -5818 0/imm32/next -5819 -5820 Int-var-in-ecx: -5821 "arg1"/imm32/name -5822 Type-int/imm32 -5823 1/imm32/some-block-depth -5824 0/imm32/no-stack-offset -5825 "ecx"/imm32/register -5826 -5827 Single-int-var-in-edx: -5828 Int-var-in-edx/imm32 -5829 0/imm32/next -5830 -5831 Int-var-in-edx: -5832 "arg1"/imm32/name -5833 Type-int/imm32 -5834 1/imm32/some-block-depth -5835 0/imm32/no-stack-offset -5836 "edx"/imm32/register -5837 -5838 Single-int-var-in-ebx: -5839 Int-var-in-ebx/imm32 -5840 0/imm32/next -5841 -5842 Int-var-in-ebx: -5843 "arg1"/imm32/name -5844 Type-int/imm32 -5845 1/imm32/some-block-depth -5846 0/imm32/no-stack-offset -5847 "ebx"/imm32/register -5848 -5849 Single-int-var-in-esi: -5850 Int-var-in-esi/imm32 -5851 0/imm32/next -5852 -5853 Int-var-in-esi: -5854 "arg1"/imm32/name -5855 Type-int/imm32 -5856 1/imm32/some-block-depth -5857 0/imm32/no-stack-offset -5858 "esi"/imm32/register -5859 -5860 Single-int-var-in-edi: -5861 Int-var-in-edi/imm32 -5862 0/imm32/next -5863 -5864 Int-var-in-edi: -5865 "arg1"/imm32/name -5866 Type-int/imm32 -5867 1/imm32/some-block-depth -5868 0/imm32/no-stack-offset -5869 "edi"/imm32/register -5870 -5871 Single-lit-var: -5872 Lit-var/imm32 -5873 0/imm32/next -5874 -5875 Lit-var: -5876 "literal"/imm32/name -5877 Type-literal/imm32 -5878 1/imm32/some-block-depth -5879 0/imm32/no-stack-offset -5880 0/imm32/no-register -5881 -5882 Type-int: -5883 1/imm32/left/int -5884 0/imm32/right/null -5885 -5886 Type-literal: -5887 0/imm32/left/literal -5888 0/imm32/right/null -5889 -5890 == code -5891 emit-subx-primitive: # out: (addr buffered-file), stmt: (handle statement), primitive: (handle function) -5892 # . prologue -5893 55/push-ebp -5894 89/<- %ebp 4/r32/esp -5895 # . save registers -5896 50/push-eax -5897 51/push-ecx -5898 # ecx = primitive -5899 8b/-> *(ebp+0x10) 1/r32/ecx -5900 # emit primitive name -5901 (write-buffered *(ebp+8) *(ecx+0xc)) # Primitive-subx-name -5902 # emit rm32 if necessary -5903 (emit-subx-rm32 *(ebp+8) *(ecx+0x10) *(ebp+0xc)) # out, Primitive-subx-rm32, stmt -5904 # emit r32 if necessary -5905 (emit-subx-r32 *(ebp+8) *(ecx+0x14) *(ebp+0xc)) # out, Primitive-subx-r32, stmt -5906 # emit imm32 if necessary -5907 (emit-subx-imm32 *(ebp+8) *(ecx+0x18) *(ebp+0xc)) # out, Primitive-subx-imm32, stmt -5908 # emit disp32 if necessary -5909 (emit-subx-disp32 *(ebp+8) *(ecx+0x1c) *(ebp+0xc)) # out, Primitive-subx-disp32, stmt -5910 (write-buffered *(ebp+8) Newline) -5911 $emit-subx-primitive:end: -5912 # . restore registers -5913 59/pop-to-ecx -5914 58/pop-to-eax -5915 # . epilogue -5916 89/<- %esp 5/r32/ebp -5917 5d/pop-to-ebp -5918 c3/return -5919 -5920 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (handle statement) -5921 # . prologue -5922 55/push-ebp -5923 89/<- %ebp 4/r32/esp -5924 # . save registers -5925 50/push-eax -5926 # if (l == 0) return -5927 81 7/subop/compare *(ebp+0xc) 0/imm32 -5928 74/jump-if-= $emit-subx-rm32:end/disp8 -5929 # -5930 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax -5931 (emit-subx-var-as-rm32 *(ebp+8) %eax) # out, var -5932 $emit-subx-rm32:end: -5933 # . restore registers -5934 58/pop-to-eax -5935 # . epilogue -5936 89/<- %esp 5/r32/ebp -5937 5d/pop-to-ebp -5938 c3/return -5939 -5940 get-stmt-operand-from-arg-location: # stmt: (handle statement), l: arg-location -> var/eax: (handle variable) -5941 # . prologue -5942 55/push-ebp -5943 89/<- %ebp 4/r32/esp -5944 # . save registers -5945 51/push-ecx -5946 # eax = l -5947 8b/-> *(ebp+0xc) 0/r32/eax -5948 # ecx = stmt -5949 8b/-> *(ebp+8) 1/r32/ecx -5950 # if (l == 1) return stmt->inouts->var -5951 { -5952 3d/compare-eax-and 1/imm32 -5953 75/jump-if-!= break/disp8 -5954 $get-stmt-operand-from-arg-location:1: -5955 8b/-> *(ecx+8) 0/r32/eax # Stmt1-inouts -5956 8b/-> *eax 0/r32/eax # Operand-var -5957 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -5958 } -5959 # if (l == 2) return stmt->inouts->next->var -5960 { -5961 3d/compare-eax-and 2/imm32 -5962 75/jump-if-!= break/disp8 -5963 $get-stmt-operand-from-arg-location:2: -5964 8b/-> *(ecx+8) 0/r32/eax # Stmt1-inouts -5965 8b/-> *(eax+4) 0/r32/eax # Operand-next -5966 8b/-> *eax 0/r32/eax # Operand-var -5967 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -5968 } -5969 # if (l == 3) return stmt->outputs -5970 { -5971 3d/compare-eax-and 3/imm32 -5972 75/jump-if-!= break/disp8 -5973 $get-stmt-operand-from-arg-location:3: -5974 8b/-> *(ecx+0xc) 0/r32/eax # Stmt1-outputs -5975 8b/-> *eax 0/r32/eax # Operand-var -5976 eb/jump $get-stmt-operand-from-arg-location:end/disp8 -5977 } -5978 # abort -5979 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 -5980 $get-stmt-operand-from-arg-location:end: -5981 # . restore registers -5982 59/pop-to-ecx -5983 # . epilogue -5984 89/<- %esp 5/r32/ebp -5985 5d/pop-to-ebp -5986 c3/return -5987 -5988 $get-stmt-operand-from-arg-location:abort: -5989 # error("invalid arg-location " eax) -5990 (write-buffered Stderr "invalid arg-location ") -5991 (print-int32-buffered Stderr %eax) -5992 (write-buffered Stderr Newline) -5993 (flush Stderr) -5994 # . syscall(exit, 1) -5995 bb/copy-to-ebx 1/imm32 -5996 b8/copy-to-eax 1/imm32/exit -5997 cd/syscall 0x80/imm8 -5998 # never gets here -5999 -6000 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (handle statement) -6001 # . prologue -6002 55/push-ebp -6003 89/<- %ebp 4/r32/esp -6004 # . save registers -6005 50/push-eax -6006 51/push-ecx -6007 # if (location == 0) return -6008 81 7/subop/compare *(ebp+0xc) 0/imm32 -6009 0f 84/jump-if-= $emit-subx-r32:end/disp32 -6010 # -6011 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax -6012 (maybe-get Registers *(eax+0x10) 8) # Var-register => eax: (addr register-index) -6013 (write-buffered *(ebp+8) Space) -6014 (print-int32-buffered *(ebp+8) *eax) -6015 (write-buffered *(ebp+8) "/r32") -6016 $emit-subx-r32:end: +5323 0/imm32/output-is-write-only +5324 _Primitive-multiply-reg-by-mem/imm32/next +5325 # - multiply +5326 _Primitive-multiply-reg-by-mem: +5327 # var1/reg <- multiply var2 => 0f af/multiply var2/rm32 var1/r32 +5328 "multiply"/imm32/name +5329 Single-int-var-on-stack/imm32/inouts +5330 Single-int-var-in-some-register/imm32/outputs +5331 "0f af/multiply"/imm32/subx-name +5332 1/imm32/rm32-is-first-inout +5333 3/imm32/r32-is-first-output +5334 0/imm32/no-imm32 +5335 0/imm32/no-disp32 +5336 0/imm32/output-is-write-only +5337 _Primitive-break-if-addr</imm32/next +5338 # - branches +5339 _Primitive-break-if-addr<: +5340 "break-if-addr<"/imm32/name +5341 0/imm32/inouts +5342 0/imm32/outputs +5343 "0f 82/jump-if-addr< break/disp32"/imm32/subx-name +5344 0/imm32/no-rm32 +5345 0/imm32/no-r32 +5346 0/imm32/no-imm32 +5347 0/imm32/no-disp32 +5348 0/imm32/no-output +5349 _Primitive-break-if-addr>=/imm32/next +5350 _Primitive-break-if-addr>=: +5351 "break-if-addr>="/imm32/name +5352 0/imm32/inouts +5353 0/imm32/outputs +5354 "0f 83/jump-if-addr>= break/disp32"/imm32/subx-name +5355 0/imm32/no-rm32 +5356 0/imm32/no-r32 +5357 0/imm32/no-imm32 +5358 0/imm32/no-disp32 +5359 0/imm32/no-output +5360 _Primitive-break-if-=/imm32/next +5361 _Primitive-break-if-=: +5362 "break-if-="/imm32/name +5363 0/imm32/inouts +5364 0/imm32/outputs +5365 "0f 84/jump-if-= break/disp32"/imm32/subx-name +5366 0/imm32/no-rm32 +5367 0/imm32/no-r32 +5368 0/imm32/no-imm32 +5369 0/imm32/no-disp32 +5370 0/imm32/no-output +5371 _Primitive-break-if-!=/imm32/next +5372 _Primitive-break-if-!=: +5373 "break-if-!="/imm32/name +5374 0/imm32/inouts +5375 0/imm32/outputs +5376 "0f 85/jump-if-!= break/disp32"/imm32/subx-name +5377 0/imm32/no-rm32 +5378 0/imm32/no-r32 +5379 0/imm32/no-imm32 +5380 0/imm32/no-disp32 +5381 0/imm32/no-output +5382 _Primitive-break-if-addr<=/imm32/next +5383 _Primitive-break-if-addr<=: +5384 "break-if-addr<="/imm32/name +5385 0/imm32/inouts +5386 0/imm32/outputs +5387 "0f 86/jump-if-addr<= break/disp32"/imm32/subx-name +5388 0/imm32/no-rm32 +5389 0/imm32/no-r32 +5390 0/imm32/no-imm32 +5391 0/imm32/no-disp32 +5392 0/imm32/no-output +5393 _Primitive-break-if-addr>/imm32/next +5394 _Primitive-break-if-addr>: +5395 "break-if-addr>"/imm32/name +5396 0/imm32/inouts +5397 0/imm32/outputs +5398 "0f 87/jump-if-addr> break/disp32"/imm32/subx-name +5399 0/imm32/no-rm32 +5400 0/imm32/no-r32 +5401 0/imm32/no-imm32 +5402 0/imm32/no-disp32 +5403 0/imm32/no-output +5404 _Primitive-break-if-</imm32/next +5405 _Primitive-break-if-<: +5406 "break-if-<"/imm32/name +5407 0/imm32/inouts +5408 0/imm32/outputs +5409 "0f 8c/jump-if-< break/disp32"/imm32/subx-name +5410 0/imm32/no-rm32 +5411 0/imm32/no-r32 +5412 0/imm32/no-imm32 +5413 0/imm32/no-disp32 +5414 0/imm32/no-output +5415 _Primitive-break-if->=/imm32/next +5416 _Primitive-break-if->=: +5417 "break-if->="/imm32/name +5418 0/imm32/inouts +5419 0/imm32/outputs +5420 "0f 8d/jump-if->= break/disp32"/imm32/subx-name +5421 0/imm32/no-rm32 +5422 0/imm32/no-r32 +5423 0/imm32/no-imm32 +5424 0/imm32/no-disp32 +5425 0/imm32/no-output +5426 _Primitive-break-if-<=/imm32/next +5427 _Primitive-break-if-<=: +5428 "break-if-<="/imm32/name +5429 0/imm32/inouts +5430 0/imm32/outputs +5431 "0f 8e/jump-if-<= break/disp32"/imm32/subx-name +5432 0/imm32/no-rm32 +5433 0/imm32/no-r32 +5434 0/imm32/no-imm32 +5435 0/imm32/no-disp32 +5436 0/imm32/no-output +5437 _Primitive-break-if->/imm32/next +5438 _Primitive-break-if->: +5439 "break-if->"/imm32/name +5440 0/imm32/inouts +5441 0/imm32/outputs +5442 "0f 8f/jump-if-> break/disp32"/imm32/subx-name +5443 0/imm32/no-rm32 +5444 0/imm32/no-r32 +5445 0/imm32/no-imm32 +5446 0/imm32/no-disp32 +5447 0/imm32/no-output +5448 _Primitive-loop-if-addr</imm32/next +5449 _Primitive-loop-if-addr<: +5450 "loop-if-addr<"/imm32/name +5451 0/imm32/inouts +5452 0/imm32/outputs +5453 "0f 82/jump-if-addr< loop/disp32"/imm32/subx-name +5454 0/imm32/no-rm32 +5455 0/imm32/no-r32 +5456 0/imm32/no-imm32 +5457 0/imm32/no-disp32 +5458 0/imm32/no-output +5459 _Primitive-loop-if-addr>=/imm32/next +5460 _Primitive-loop-if-addr>=: +5461 "loop-if-addr>="/imm32/name +5462 0/imm32/inouts +5463 0/imm32/outputs +5464 "0f 83/jump-if-addr>= loop/disp32"/imm32/subx-name +5465 0/imm32/no-rm32 +5466 0/imm32/no-r32 +5467 0/imm32/no-imm32 +5468 0/imm32/no-disp32 +5469 0/imm32/no-output +5470 _Primitive-loop-if-=/imm32/next +5471 _Primitive-loop-if-=: +5472 "loop-if-="/imm32/name +5473 0/imm32/inouts +5474 0/imm32/outputs +5475 "0f 84/jump-if-= loop/disp32"/imm32/subx-name +5476 0/imm32/no-rm32 +5477 0/imm32/no-r32 +5478 0/imm32/no-imm32 +5479 0/imm32/no-disp32 +5480 0/imm32/no-output +5481 _Primitive-loop-if-!=/imm32/next +5482 _Primitive-loop-if-!=: +5483 "loop-if-!="/imm32/name +5484 0/imm32/inouts +5485 0/imm32/outputs +5486 "0f 85/jump-if-!= loop/disp32"/imm32/subx-name +5487 0/imm32/no-rm32 +5488 0/imm32/no-r32 +5489 0/imm32/no-imm32 +5490 0/imm32/no-disp32 +5491 0/imm32/no-output +5492 _Primitive-loop-if-addr<=/imm32/next +5493 _Primitive-loop-if-addr<=: +5494 "loop-if-addr<="/imm32/name +5495 0/imm32/inouts +5496 0/imm32/outputs +5497 "0f 86/jump-if-addr<= loop/disp32"/imm32/subx-name +5498 0/imm32/no-rm32 +5499 0/imm32/no-r32 +5500 0/imm32/no-imm32 +5501 0/imm32/no-disp32 +5502 0/imm32/no-output +5503 _Primitive-loop-if-addr>/imm32/next +5504 _Primitive-loop-if-addr>: +5505 "loop-if-addr>"/imm32/name +5506 0/imm32/inouts +5507 0/imm32/outputs +5508 "0f 87/jump-if-addr> loop/disp32"/imm32/subx-name +5509 0/imm32/no-rm32 +5510 0/imm32/no-r32 +5511 0/imm32/no-imm32 +5512 0/imm32/no-disp32 +5513 0/imm32/no-output +5514 _Primitive-loop-if-</imm32/next +5515 _Primitive-loop-if-<: +5516 "loop-if-<"/imm32/name +5517 0/imm32/inouts +5518 0/imm32/outputs +5519 "0f 8c/jump-if-< loop/disp32"/imm32/subx-name +5520 0/imm32/no-rm32 +5521 0/imm32/no-r32 +5522 0/imm32/no-imm32 +5523 0/imm32/no-disp32 +5524 0/imm32/no-output +5525 _Primitive-loop-if->=/imm32/next +5526 _Primitive-loop-if->=: +5527 "loop-if->="/imm32/name +5528 0/imm32/inouts +5529 0/imm32/outputs +5530 "0f 8d/jump-if->= loop/disp32"/imm32/subx-name +5531 0/imm32/no-rm32 +5532 0/imm32/no-r32 +5533 0/imm32/no-imm32 +5534 0/imm32/no-disp32 +5535 0/imm32/no-output +5536 _Primitive-loop-if-<=/imm32/next +5537 _Primitive-loop-if-<=: +5538 "loop-if-<="/imm32/name +5539 0/imm32/inouts +5540 0/imm32/outputs +5541 "0f 8e/jump-if-<= loop/disp32"/imm32/subx-name +5542 0/imm32/no-rm32 +5543 0/imm32/no-r32 +5544 0/imm32/no-imm32 +5545 0/imm32/no-disp32 +5546 0/imm32/no-output +5547 _Primitive-loop-if->/imm32/next +5548 _Primitive-loop-if->: +5549 "loop-if->"/imm32/name +5550 0/imm32/inouts +5551 0/imm32/outputs +5552 "0f 8f/jump-if-> loop/disp32"/imm32/subx-name +5553 0/imm32/no-rm32 +5554 0/imm32/no-r32 +5555 0/imm32/no-imm32 +5556 0/imm32/no-disp32 +5557 0/imm32/no-output +5558 _Primitive-loop/imm32/next # we probably don't need an unconditional break +5559 _Primitive-loop: +5560 "loop"/imm32/name +5561 0/imm32/inouts +5562 0/imm32/outputs +5563 "e9/jump loop/disp32"/imm32/subx-name +5564 0/imm32/no-rm32 +5565 0/imm32/no-r32 +5566 0/imm32/no-imm32 +5567 0/imm32/no-disp32 +5568 0/imm32/no-output +5569 _Primitive-break-if-addr<-named/imm32/next +5570 # - branches to named blocks +5571 _Primitive-break-if-addr<-named: +5572 "break-if-addr<"/imm32/name +5573 Single-lit-var/imm32/inouts +5574 0/imm32/outputs +5575 "0f 82/jump-if-addr<"/imm32/subx-name +5576 0/imm32/no-rm32 +5577 0/imm32/no-r32 +5578 0/imm32/no-imm32 +5579 1/imm32/disp32-is-first-inout +5580 0/imm32/no-output +5581 _Primitive-break-if-addr>=-named/imm32/next +5582 _Primitive-break-if-addr>=-named: +5583 "break-if-addr>="/imm32/name +5584 Single-lit-var/imm32/inouts +5585 0/imm32/outputs +5586 "0f 83/jump-if-addr>="/imm32/subx-name +5587 0/imm32/no-rm32 +5588 0/imm32/no-r32 +5589 0/imm32/no-imm32 +5590 1/imm32/disp32-is-first-inout +5591 0/imm32/no-output +5592 _Primitive-break-if-=-named/imm32/next +5593 _Primitive-break-if-=-named: +5594 "break-if-="/imm32/name +5595 Single-lit-var/imm32/inouts +5596 0/imm32/outputs +5597 "0f 84/jump-if-="/imm32/subx-name +5598 0/imm32/no-rm32 +5599 0/imm32/no-r32 +5600 0/imm32/no-imm32 +5601 1/imm32/disp32-is-first-inout +5602 0/imm32/no-output +5603 _Primitive-break-if-!=-named/imm32/next +5604 _Primitive-break-if-!=-named: +5605 "break-if-!="/imm32/name +5606 Single-lit-var/imm32/inouts +5607 0/imm32/outputs +5608 "0f 85/jump-if-!="/imm32/subx-name +5609 0/imm32/no-rm32 +5610 0/imm32/no-r32 +5611 0/imm32/no-imm32 +5612 1/imm32/disp32-is-first-inout +5613 0/imm32/no-output +5614 _Primitive-break-if-addr<=-named/imm32/next +5615 _Primitive-break-if-addr<=-named: +5616 "break-if-addr<="/imm32/name +5617 Single-lit-var/imm32/inouts +5618 0/imm32/outputs +5619 "0f 86/jump-if-addr<="/imm32/subx-name +5620 0/imm32/no-rm32 +5621 0/imm32/no-r32 +5622 0/imm32/no-imm32 +5623 1/imm32/disp32-is-first-inout +5624 0/imm32/no-output +5625 _Primitive-break-if-addr>-named/imm32/next +5626 _Primitive-break-if-addr>-named: +5627 "break-if-addr>"/imm32/name +5628 Single-lit-var/imm32/inouts +5629 0/imm32/outputs +5630 "0f 87/jump-if-addr>"/imm32/subx-name +5631 0/imm32/no-rm32 +5632 0/imm32/no-r32 +5633 0/imm32/no-imm32 +5634 1/imm32/disp32-is-first-inout +5635 0/imm32/no-output +5636 _Primitive-break-if-<-named/imm32/next +5637 _Primitive-break-if-<-named: +5638 "break-if-<"/imm32/name +5639 Single-lit-var/imm32/inouts +5640 0/imm32/outputs +5641 "0f 8c/jump-if-<"/imm32/subx-name +5642 0/imm32/no-rm32 +5643 0/imm32/no-r32 +5644 0/imm32/no-imm32 +5645 1/imm32/disp32-is-first-inout +5646 0/imm32/no-output +5647 _Primitive-break-if->=-named/imm32/next +5648 _Primitive-break-if->=-named: +5649 "break-if->="/imm32/name +5650 Single-lit-var/imm32/inouts +5651 0/imm32/outputs +5652 "0f 8d/jump-if->="/imm32/subx-name +5653 0/imm32/no-rm32 +5654 0/imm32/no-r32 +5655 0/imm32/no-imm32 +5656 1/imm32/disp32-is-first-inout +5657 0/imm32/no-output +5658 _Primitive-break-if-<=-named/imm32/next +5659 _Primitive-break-if-<=-named: +5660 "break-if-<="/imm32/name +5661 Single-lit-var/imm32/inouts +5662 0/imm32/outputs +5663 "0f 8e/jump-if-<="/imm32/subx-name +5664 0/imm32/no-rm32 +5665 0/imm32/no-r32 +5666 0/imm32/no-imm32 +5667 1/imm32/disp32-is-first-inout +5668 0/imm32/no-output +5669 _Primitive-break-if->-named/imm32/next +5670 _Primitive-break-if->-named: +5671 "break-if->"/imm32/name +5672 Single-lit-var/imm32/inouts +5673 0/imm32/outputs +5674 "0f 8f/jump-if->"/imm32/subx-name +5675 0/imm32/no-rm32 +5676 0/imm32/no-r32 +5677 0/imm32/no-imm32 +5678 1/imm32/disp32-is-first-inout +5679 0/imm32/no-output +5680 _Primitive-loop-if-addr<-named/imm32/next +5681 _Primitive-loop-if-addr<-named: +5682 "loop-if-addr<"/imm32/name +5683 Single-lit-var/imm32/inouts +5684 0/imm32/outputs +5685 "0f 82/jump-if-addr<"/imm32/subx-name +5686 0/imm32/no-rm32 +5687 0/imm32/no-r32 +5688 0/imm32/no-imm32 +5689 1/imm32/disp32-is-first-inout +5690 0/imm32/no-output +5691 _Primitive-loop-if-addr>=-named/imm32/next +5692 _Primitive-loop-if-addr>=-named: +5693 "loop-if-addr>="/imm32/name +5694 Single-lit-var/imm32/inouts +5695 0/imm32/outputs +5696 "0f 83/jump-if-addr>="/imm32/subx-name +5697 0/imm32/no-rm32 +5698 0/imm32/no-r32 +5699 0/imm32/no-imm32 +5700 1/imm32/disp32-is-first-inout +5701 0/imm32/no-output +5702 _Primitive-loop-if-=-named/imm32/next +5703 _Primitive-loop-if-=-named: +5704 "loop-if-="/imm32/name +5705 Single-lit-var/imm32/inouts +5706 0/imm32/outputs +5707 "0f 84/jump-if-="/imm32/subx-name +5708 0/imm32/no-rm32 +5709 0/imm32/no-r32 +5710 0/imm32/no-imm32 +5711 1/imm32/disp32-is-first-inout +5712 0/imm32/no-output +5713 _Primitive-loop-if-!=-named/imm32/next +5714 _Primitive-loop-if-!=-named: +5715 "loop-if-!="/imm32/name +5716 Single-lit-var/imm32/inouts +5717 0/imm32/outputs +5718 "0f 85/jump-if-!="/imm32/subx-name +5719 0/imm32/no-rm32 +5720 0/imm32/no-r32 +5721 0/imm32/no-imm32 +5722 1/imm32/disp32-is-first-inout +5723 0/imm32/no-output +5724 _Primitive-loop-if-addr<=-named/imm32/next +5725 _Primitive-loop-if-addr<=-named: +5726 "loop-if-addr<="/imm32/name +5727 Single-lit-var/imm32/inouts +5728 0/imm32/outputs +5729 "0f 86/jump-if-addr<="/imm32/subx-name +5730 0/imm32/no-rm32 +5731 0/imm32/no-r32 +5732 0/imm32/no-imm32 +5733 1/imm32/disp32-is-first-inout +5734 0/imm32/no-output +5735 _Primitive-loop-if-addr>-named/imm32/next +5736 _Primitive-loop-if-addr>-named: +5737 "loop-if-addr>"/imm32/name +5738 Single-lit-var/imm32/inouts +5739 0/imm32/outputs +5740 "0f 87/jump-if-addr>"/imm32/subx-name +5741 0/imm32/no-rm32 +5742 0/imm32/no-r32 +5743 0/imm32/no-imm32 +5744 1/imm32/disp32-is-first-inout +5745 0/imm32/no-output +5746 _Primitive-loop-if-<-named/imm32/next +5747 _Primitive-loop-if-<-named: +5748 "loop-if-<"/imm32/name +5749 Single-lit-var/imm32/inouts +5750 0/imm32/outputs +5751 "0f 8c/jump-if-<"/imm32/subx-name +5752 0/imm32/no-rm32 +5753 0/imm32/no-r32 +5754 0/imm32/no-imm32 +5755 1/imm32/disp32-is-first-inout +5756 0/imm32/no-output +5757 _Primitive-loop-if->=-named/imm32/next +5758 _Primitive-loop-if->=-named: +5759 "loop-if->="/imm32/name +5760 Single-lit-var/imm32/inouts +5761 0/imm32/outputs +5762 "0f 8d/jump-if->="/imm32/subx-name +5763 0/imm32/no-rm32 +5764 0/imm32/no-r32 +5765 0/imm32/no-imm32 +5766 1/imm32/disp32-is-first-inout +5767 0/imm32/no-output +5768 _Primitive-loop-if-<=-named/imm32/next +5769 _Primitive-loop-if-<=-named: +5770 "loop-if-<="/imm32/name +5771 Single-lit-var/imm32/inouts +5772 0/imm32/outputs +5773 "0f 8e/jump-if-<="/imm32/subx-name +5774 0/imm32/no-rm32 +5775 0/imm32/no-r32 +5776 0/imm32/no-imm32 +5777 1/imm32/disp32-is-first-inout +5778 0/imm32/no-output +5779 _Primitive-loop-if->-named/imm32/next +5780 _Primitive-loop-if->-named: +5781 "loop-if->"/imm32/name +5782 Single-lit-var/imm32/inouts +5783 0/imm32/outputs +5784 "0f 8f/jump-if->"/imm32/subx-name +5785 0/imm32/no-rm32 +5786 0/imm32/no-r32 +5787 0/imm32/no-imm32 +5788 1/imm32/disp32-is-first-inout +5789 0/imm32/no-output +5790 _Primitive-loop-named/imm32/next # we probably don't need an unconditional break +5791 _Primitive-loop-named: +5792 "loop"/imm32/name +5793 Single-lit-var/imm32/inouts +5794 0/imm32/outputs +5795 "e9/jump"/imm32/subx-name +5796 0/imm32/no-rm32 +5797 0/imm32/no-r32 +5798 0/imm32/no-imm32 +5799 1/imm32/disp32-is-first-inout +5800 0/imm32/no-output +5801 0/imm32/next +5802 +5803 Single-int-var-on-stack: +5804 Int-var-on-stack/imm32 +5805 0/imm32/next +5806 +5807 Int-var-on-stack: +5808 "arg1"/imm32/name +5809 Type-int/imm32 +5810 1/imm32/some-block-depth +5811 1/imm32/some-stack-offset +5812 0/imm32/no-register +5813 +5814 Two-args-int-stack-int-reg: +5815 Int-var-on-stack/imm32 +5816 Single-int-var-in-some-register/imm32/next +5817 +5818 Two-args-int-reg-int-stack: +5819 Int-var-in-some-register/imm32 +5820 Single-int-var-on-stack/imm32/next +5821 +5822 Two-args-int-eax-int-literal: +5823 Int-var-in-eax/imm32 +5824 Single-lit-var/imm32/next +5825 +5826 Int-var-and-literal: +5827 Int-var-on-stack/imm32 +5828 Single-lit-var/imm32/next +5829 +5830 Single-int-var-in-some-register: +5831 Int-var-in-some-register/imm32 +5832 0/imm32/next +5833 +5834 Int-var-in-some-register: +5835 "arg1"/imm32/name +5836 Type-int/imm32 +5837 1/imm32/some-block-depth +5838 0/imm32/no-stack-offset +5839 "*"/imm32/register +5840 +5841 Single-int-var-in-eax: +5842 Int-var-in-eax/imm32 +5843 0/imm32/next +5844 +5845 Int-var-in-eax: +5846 "arg1"/imm32/name +5847 Type-int/imm32 +5848 1/imm32/some-block-depth +5849 0/imm32/no-stack-offset +5850 "eax"/imm32/register +5851 +5852 Single-int-var-in-ecx: +5853 Int-var-in-ecx/imm32 +5854 0/imm32/next +5855 +5856 Int-var-in-ecx: +5857 "arg1"/imm32/name +5858 Type-int/imm32 +5859 1/imm32/some-block-depth +5860 0/imm32/no-stack-offset +5861 "ecx"/imm32/register +5862 +5863 Single-int-var-in-edx: +5864 Int-var-in-edx/imm32 +5865 0/imm32/next +5866 +5867 Int-var-in-edx: +5868 "arg1"/imm32/name +5869 Type-int/imm32 +5870 1/imm32/some-block-depth +5871 0/imm32/no-stack-offset +5872 "edx"/imm32/register +5873 +5874 Single-int-var-in-ebx: +5875 Int-var-in-ebx/imm32 +5876 0/imm32/next +5877 +5878 Int-var-in-ebx: +5879 "arg1"/imm32/name +5880 Type-int/imm32 +5881 1/imm32/some-block-depth +5882 0/imm32/no-stack-offset +5883 "ebx"/imm32/register +5884 +5885 Single-int-var-in-esi: +5886 Int-var-in-esi/imm32 +5887 0/imm32/next +5888 +5889 Int-var-in-esi: +5890 "arg1"/imm32/name +5891 Type-int/imm32 +5892 1/imm32/some-block-depth +5893 0/imm32/no-stack-offset +5894 "esi"/imm32/register +5895 +5896 Single-int-var-in-edi: +5897 Int-var-in-edi/imm32 +5898 0/imm32/next +5899 +5900 Int-var-in-edi: +5901 "arg1"/imm32/name +5902 Type-int/imm32 +5903 1/imm32/some-block-depth +5904 0/imm32/no-stack-offset +5905 "edi"/imm32/register +5906 +5907 Single-lit-var: +5908 Lit-var/imm32 +5909 0/imm32/next +5910 +5911 Lit-var: +5912 "literal"/imm32/name +5913 Type-literal/imm32 +5914 1/imm32/some-block-depth +5915 0/imm32/no-stack-offset +5916 0/imm32/no-register +5917 +5918 Type-int: +5919 1/imm32/left/int +5920 0/imm32/right/null +5921 +5922 Type-literal: +5923 0/imm32/left/literal +5924 0/imm32/right/null +5925 +5926 == code +5927 emit-subx-primitive: # out: (addr buffered-file), stmt: (handle statement), primitive: (handle function) +5928 # . prologue +5929 55/push-ebp +5930 89/<- %ebp 4/r32/esp +5931 # . save registers +5932 50/push-eax +5933 51/push-ecx +5934 # ecx = primitive +5935 8b/-> *(ebp+0x10) 1/r32/ecx +5936 # emit primitive name +5937 (write-buffered *(ebp+8) *(ecx+0xc)) # Primitive-subx-name +5938 # emit rm32 if necessary +5939 (emit-subx-rm32 *(ebp+8) *(ecx+0x10) *(ebp+0xc)) # out, Primitive-subx-rm32, stmt +5940 # emit r32 if necessary +5941 (emit-subx-r32 *(ebp+8) *(ecx+0x14) *(ebp+0xc)) # out, Primitive-subx-r32, stmt +5942 # emit imm32 if necessary +5943 (emit-subx-imm32 *(ebp+8) *(ecx+0x18) *(ebp+0xc)) # out, Primitive-subx-imm32, stmt +5944 # emit disp32 if necessary +5945 (emit-subx-disp32 *(ebp+8) *(ecx+0x1c) *(ebp+0xc)) # out, Primitive-subx-disp32, stmt +5946 (write-buffered *(ebp+8) Newline) +5947 $emit-subx-primitive:end: +5948 # . restore registers +5949 59/pop-to-ecx +5950 58/pop-to-eax +5951 # . epilogue +5952 89/<- %esp 5/r32/ebp +5953 5d/pop-to-ebp +5954 c3/return +5955 +5956 emit-subx-rm32: # out: (addr buffered-file), l: arg-location, stmt: (handle statement) +5957 # . prologue +5958 55/push-ebp +5959 89/<- %ebp 4/r32/esp +5960 # . save registers +5961 50/push-eax +5962 # if (l == 0) return +5963 81 7/subop/compare *(ebp+0xc) 0/imm32 +5964 74/jump-if-= $emit-subx-rm32:end/disp8 +5965 # +5966 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax +5967 (emit-subx-var-as-rm32 *(ebp+8) %eax) # out, var +5968 $emit-subx-rm32:end: +5969 # . restore registers +5970 58/pop-to-eax +5971 # . epilogue +5972 89/<- %esp 5/r32/ebp +5973 5d/pop-to-ebp +5974 c3/return +5975 +5976 get-stmt-operand-from-arg-location: # stmt: (handle statement), l: arg-location -> var/eax: (handle variable) +5977 # . prologue +5978 55/push-ebp +5979 89/<- %ebp 4/r32/esp +5980 # . save registers +5981 51/push-ecx +5982 # eax = l +5983 8b/-> *(ebp+0xc) 0/r32/eax +5984 # ecx = stmt +5985 8b/-> *(ebp+8) 1/r32/ecx +5986 # if (l == 1) return stmt->inouts->var +5987 { +5988 3d/compare-eax-and 1/imm32 +5989 75/jump-if-!= break/disp8 +5990 $get-stmt-operand-from-arg-location:1: +5991 8b/-> *(ecx+8) 0/r32/eax # Stmt1-inouts +5992 8b/-> *eax 0/r32/eax # Operand-var +5993 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +5994 } +5995 # if (l == 2) return stmt->inouts->next->var +5996 { +5997 3d/compare-eax-and 2/imm32 +5998 75/jump-if-!= break/disp8 +5999 $get-stmt-operand-from-arg-location:2: +6000 8b/-> *(ecx+8) 0/r32/eax # Stmt1-inouts +6001 8b/-> *(eax+4) 0/r32/eax # Operand-next +6002 8b/-> *eax 0/r32/eax # Operand-var +6003 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +6004 } +6005 # if (l == 3) return stmt->outputs +6006 { +6007 3d/compare-eax-and 3/imm32 +6008 75/jump-if-!= break/disp8 +6009 $get-stmt-operand-from-arg-location:3: +6010 8b/-> *(ecx+0xc) 0/r32/eax # Stmt1-outputs +6011 8b/-> *eax 0/r32/eax # Operand-var +6012 eb/jump $get-stmt-operand-from-arg-location:end/disp8 +6013 } +6014 # abort +6015 e9/jump $get-stmt-operand-from-arg-location:abort/disp32 +6016 $get-stmt-operand-from-arg-location:end: 6017 # . restore registers 6018 59/pop-to-ecx -6019 58/pop-to-eax -6020 # . epilogue -6021 89/<- %esp 5/r32/ebp -6022 5d/pop-to-ebp -6023 c3/return -6024 -6025 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (handle statement) -6026 # . prologue -6027 55/push-ebp -6028 89/<- %ebp 4/r32/esp -6029 # . save registers -6030 50/push-eax -6031 51/push-ecx -6032 # if (location == 0) return -6033 81 7/subop/compare *(ebp+0xc) 0/imm32 -6034 74/jump-if-= $emit-subx-imm32:end/disp8 -6035 # -6036 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax -6037 (write-buffered *(ebp+8) Space) -6038 (write-buffered *(ebp+8) *eax) # Var-name -6039 (write-buffered *(ebp+8) "/imm32") -6040 $emit-subx-imm32:end: -6041 # . restore registers -6042 59/pop-to-ecx -6043 58/pop-to-eax -6044 # . epilogue -6045 89/<- %esp 5/r32/ebp -6046 5d/pop-to-ebp -6047 c3/return -6048 -6049 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (handle statement) -6050 # . prologue -6051 55/push-ebp -6052 89/<- %ebp 4/r32/esp -6053 # . save registers -6054 50/push-eax -6055 51/push-ecx -6056 # if (location == 0) return -6057 81 7/subop/compare *(ebp+0xc) 0/imm32 -6058 0f 84/jump-if-= $emit-subx-disp32:end/disp32 -6059 # -6060 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax -6061 (write-buffered *(ebp+8) Space) -6062 (write-buffered *(ebp+8) *eax) # Var-name -6063 # hack: if instruction operation starts with "break", emit ":break" -6064 # var name/ecx: (addr array byte) = stmt->operation -6065 8b/-> *(ebp+0x10) 0/r32/eax -6066 8b/-> *(eax+4) 1/r32/ecx -6067 { -6068 (string-starts-with? %ecx "break") # => eax -6069 3d/compare-eax-and 0/imm32 -6070 74/jump-if-= break/disp8 -6071 (write-buffered *(ebp+8) ":break") -6072 } -6073 # hack: if instruction operation starts with "loop", emit ":loop" -6074 { -6075 (string-starts-with? %ecx "loop") # => eax -6076 3d/compare-eax-and 0/imm32 -6077 74/jump-if-= break/disp8 -6078 (write-buffered *(ebp+8) ":loop") -6079 } -6080 (write-buffered *(ebp+8) "/disp32") -6081 $emit-subx-disp32:end: -6082 # . restore registers -6083 59/pop-to-ecx -6084 58/pop-to-eax -6085 # . epilogue -6086 89/<- %esp 5/r32/ebp -6087 5d/pop-to-ebp -6088 c3/return -6089 -6090 emit-subx-call: # out: (addr buffered-file), stmt: (handle statement), callee: (handle function) -6091 # . prologue -6092 55/push-ebp -6093 89/<- %ebp 4/r32/esp -6094 # . save registers -6095 50/push-eax -6096 51/push-ecx -6097 # -6098 (write-buffered *(ebp+8) "(") -6099 # - emit function name -6100 8b/-> *(ebp+0x10) 1/r32/ecx -6101 (write-buffered *(ebp+8) *(ecx+4)) # Function-subx-name -6102 # - emit arguments -6103 # var curr/ecx: (handle list var) = stmt->inouts -6104 8b/-> *(ebp+0xc) 1/r32/ecx -6105 8b/-> *(ecx+8) 1/r32/ecx # Stmt1-inouts -6106 { -6107 # if (curr == null) break -6108 81 7/subop/compare %ecx 0/imm32 -6109 74/jump-if-= break/disp8 -6110 # -6111 (emit-subx-call-operand *(ebp+8) *ecx) -6112 # curr = curr->next -6113 8b/-> *(ecx+4) 1/r32/ecx -6114 eb/jump loop/disp8 +6019 # . epilogue +6020 89/<- %esp 5/r32/ebp +6021 5d/pop-to-ebp +6022 c3/return +6023 +6024 $get-stmt-operand-from-arg-location:abort: +6025 # error("invalid arg-location " eax) +6026 (write-buffered Stderr "invalid arg-location ") +6027 (print-int32-buffered Stderr %eax) +6028 (write-buffered Stderr Newline) +6029 (flush Stderr) +6030 # . syscall(exit, 1) +6031 bb/copy-to-ebx 1/imm32 +6032 b8/copy-to-eax 1/imm32/exit +6033 cd/syscall 0x80/imm8 +6034 # never gets here +6035 +6036 emit-subx-r32: # out: (addr buffered-file), l: arg-location, stmt: (handle statement) +6037 # . prologue +6038 55/push-ebp +6039 89/<- %ebp 4/r32/esp +6040 # . save registers +6041 50/push-eax +6042 51/push-ecx +6043 # if (location == 0) return +6044 81 7/subop/compare *(ebp+0xc) 0/imm32 +6045 0f 84/jump-if-= $emit-subx-r32:end/disp32 +6046 # +6047 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax +6048 (maybe-get Registers *(eax+0x10) 8) # Var-register => eax: (addr register-index) +6049 (write-buffered *(ebp+8) Space) +6050 (print-int32-buffered *(ebp+8) *eax) +6051 (write-buffered *(ebp+8) "/r32") +6052 $emit-subx-r32:end: +6053 # . restore registers +6054 59/pop-to-ecx +6055 58/pop-to-eax +6056 # . epilogue +6057 89/<- %esp 5/r32/ebp +6058 5d/pop-to-ebp +6059 c3/return +6060 +6061 emit-subx-imm32: # out: (addr buffered-file), l: arg-location, stmt: (handle statement) +6062 # . prologue +6063 55/push-ebp +6064 89/<- %ebp 4/r32/esp +6065 # . save registers +6066 50/push-eax +6067 51/push-ecx +6068 # if (location == 0) return +6069 81 7/subop/compare *(ebp+0xc) 0/imm32 +6070 74/jump-if-= $emit-subx-imm32:end/disp8 +6071 # +6072 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax +6073 (write-buffered *(ebp+8) Space) +6074 (write-buffered *(ebp+8) *eax) # Var-name +6075 (write-buffered *(ebp+8) "/imm32") +6076 $emit-subx-imm32:end: +6077 # . restore registers +6078 59/pop-to-ecx +6079 58/pop-to-eax +6080 # . epilogue +6081 89/<- %esp 5/r32/ebp +6082 5d/pop-to-ebp +6083 c3/return +6084 +6085 emit-subx-disp32: # out: (addr buffered-file), l: arg-location, stmt: (handle statement) +6086 # . prologue +6087 55/push-ebp +6088 89/<- %ebp 4/r32/esp +6089 # . save registers +6090 50/push-eax +6091 51/push-ecx +6092 # if (location == 0) return +6093 81 7/subop/compare *(ebp+0xc) 0/imm32 +6094 0f 84/jump-if-= $emit-subx-disp32:end/disp32 +6095 # +6096 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc)) # stmt, l => var/eax +6097 (write-buffered *(ebp+8) Space) +6098 (write-buffered *(ebp+8) *eax) # Var-name +6099 # hack: if instruction operation starts with "break", emit ":break" +6100 # var name/ecx: (addr array byte) = stmt->operation +6101 8b/-> *(ebp+0x10) 0/r32/eax +6102 8b/-> *(eax+4) 1/r32/ecx +6103 { +6104 (string-starts-with? %ecx "break") # => eax +6105 3d/compare-eax-and 0/imm32 +6106 74/jump-if-= break/disp8 +6107 (write-buffered *(ebp+8) ":break") +6108 } +6109 # hack: if instruction operation starts with "loop", emit ":loop" +6110 { +6111 (string-starts-with? %ecx "loop") # => eax +6112 3d/compare-eax-and 0/imm32 +6113 74/jump-if-= break/disp8 +6114 (write-buffered *(ebp+8) ":loop") 6115 } -6116 # -6117 (write-buffered *(ebp+8) ")\n") -6118 $emit-subx-call:end: -6119 # . restore registers -6120 59/pop-to-ecx -6121 58/pop-to-eax -6122 # . epilogue -6123 89/<- %esp 5/r32/ebp -6124 5d/pop-to-ebp -6125 c3/return -6126 -6127 emit-subx-call-operand: # out: (addr buffered-file), operand: (handle variable) -6128 # shares code with emit-subx-var-as-rm32 -6129 # . prologue -6130 55/push-ebp -6131 89/<- %ebp 4/r32/esp -6132 # . save registers -6133 50/push-eax -6134 # eax = operand -6135 8b/-> *(ebp+0xc) 0/r32/eax -6136 # if (operand->register) emit "%__" -6137 { -6138 81 7/subop/compare *(eax+0x10) 0/imm32 # Var-register -6139 74/jump-if-= break/disp8 -6140 $emit-subx-call-operand:register: -6141 (write-buffered *(ebp+8) " %") -6142 (write-buffered *(ebp+8) *(eax+0x10)) # Var-register -6143 e9/jump $emit-subx-call-operand:end/disp32 -6144 } -6145 # else if (operand->stack-offset) emit "*(ebp+__)" -6146 { -6147 81 7/subop/compare *(eax+0xc) 0/imm32 # Var-stack-offset -6148 74/jump-if-= break/disp8 -6149 $emit-subx-call-operand:stack: -6150 (write-buffered *(ebp+8) Space) -6151 (write-buffered *(ebp+8) "*(ebp+") -6152 8b/-> *(ebp+0xc) 0/r32/eax -6153 (print-int32-buffered *(ebp+8) *(eax+0xc)) # Var-stack-offset -6154 (write-buffered *(ebp+8) ")") -6155 e9/jump $emit-subx-call-operand:end/disp32 -6156 } -6157 # else if (operand->type == literal) emit "__" -6158 { -6159 50/push-eax -6160 8b/-> *(eax+4) 0/r32/eax # Var-type -6161 81 7/subop/compare *eax 0/imm32 # Tree-left -6162 58/pop-to-eax -6163 75/jump-if-!= break/disp8 -6164 $emit-subx-call-operand:literal: -6165 (write-buffered *(ebp+8) Space) -6166 (write-buffered *(ebp+8) *eax) -6167 } -6168 $emit-subx-call-operand:end: -6169 # . restore registers -6170 58/pop-to-eax -6171 # . epilogue -6172 89/<- %esp 5/r32/ebp -6173 5d/pop-to-ebp -6174 c3/return -6175 -6176 emit-subx-var-as-rm32: # out: (addr buffered-file), operand: (handle variable) -6177 # . prologue -6178 55/push-ebp -6179 89/<- %ebp 4/r32/esp -6180 # . save registers -6181 50/push-eax -6182 # eax = operand -6183 8b/-> *(ebp+0xc) 0/r32/eax -6184 # if (operand->register) emit "%__" -6185 { -6186 81 7/subop/compare *(eax+0x10) 0/imm32 # Var-register -6187 74/jump-if-= break/disp8 -6188 $emit-subx-var-as-rm32:register: -6189 (write-buffered *(ebp+8) " %") -6190 (write-buffered *(ebp+8) *(eax+0x10)) # Var-register -6191 } -6192 # else if (operand->stack-offset) emit "*(ebp+__)" -6193 { -6194 81 7/subop/compare *(eax+0xc) 0/imm32 # Var-stack-offset -6195 74/jump-if-= break/disp8 -6196 $emit-subx-var-as-rm32:stack: -6197 (write-buffered *(ebp+8) Space) -6198 (write-buffered *(ebp+8) "*(ebp+") -6199 8b/-> *(ebp+0xc) 0/r32/eax -6200 (print-int32-buffered *(ebp+8) *(eax+0xc)) # Var-stack-offset -6201 (write-buffered *(ebp+8) ")") -6202 } -6203 $emit-subx-var-as-rm32:end: -6204 # . restore registers -6205 58/pop-to-eax -6206 # . epilogue -6207 89/<- %esp 5/r32/ebp -6208 5d/pop-to-ebp -6209 c3/return -6210 -6211 find-matching-function: # functions: (addr function), stmt: (handle statement) -> result/eax: (handle function) -6212 # . prologue -6213 55/push-ebp -6214 89/<- %ebp 4/r32/esp -6215 # . save registers -6216 51/push-ecx -6217 # var curr/ecx: (handle function) = functions -6218 8b/-> *(ebp+8) 1/r32/ecx -6219 { -6220 # if (curr == null) break -6221 81 7/subop/compare %ecx 0/imm32 -6222 74/jump-if-= break/disp8 -6223 # if match(stmt, curr) return curr -6224 { -6225 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax -6226 3d/compare-eax-and 0/imm32 -6227 74/jump-if-= break/disp8 -6228 89/<- %eax 1/r32/ecx -6229 eb/jump $find-matching-function:end/disp8 -6230 } -6231 # curr = curr->next -6232 8b/-> *(ecx+0x14) 1/r32/ecx # Function-next -6233 eb/jump loop/disp8 -6234 } -6235 # return null -6236 b8/copy-to-eax 0/imm32 -6237 $find-matching-function:end: -6238 # . restore registers -6239 59/pop-to-ecx -6240 # . epilogue -6241 89/<- %esp 5/r32/ebp -6242 5d/pop-to-ebp -6243 c3/return -6244 -6245 find-matching-primitive: # primitives: (handle primitive), stmt: (handle statement) -> result/eax: (handle primitive) -6246 # . prologue -6247 55/push-ebp -6248 89/<- %ebp 4/r32/esp -6249 # . save registers -6250 51/push-ecx -6251 # var curr/ecx: (handle primitive) = primitives -6252 8b/-> *(ebp+8) 1/r32/ecx -6253 { -6254 $find-matching-primitive:loop: -6255 # if (curr == null) break -6256 81 7/subop/compare %ecx 0/imm32 -6257 0f 84/jump-if-= break/disp32 -6258 #? (write-buffered Stderr "prim: ") -6259 #? (write-buffered Stderr *ecx) # Primitive-name -6260 #? (write-buffered Stderr " => ") -6261 #? (write-buffered Stderr *(ecx+0xc)) # Primitive-subx-name -6262 #? (write-buffered Stderr Newline) -6263 #? (flush Stderr) -6264 # if match(curr, stmt) return curr -6265 { -6266 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax -6267 3d/compare-eax-and 0/imm32 -6268 74/jump-if-= break/disp8 -6269 89/<- %eax 1/r32/ecx -6270 eb/jump $find-matching-primitive:end/disp8 -6271 } -6272 $find-matching-primitive:next-primitive: -6273 # curr = curr->next -6274 8b/-> *(ecx+0x24) 1/r32/ecx # Primitive-next -6275 e9/jump loop/disp32 -6276 } -6277 # return null -6278 b8/copy-to-eax 0/imm32 -6279 $find-matching-primitive:end: -6280 # . restore registers -6281 59/pop-to-ecx -6282 # . epilogue -6283 89/<- %esp 5/r32/ebp -6284 5d/pop-to-ebp -6285 c3/return -6286 -6287 mu-stmt-matches-function?: # stmt: (handle statement), function: (handle function) => result/eax: boolean -6288 # . prologue -6289 55/push-ebp -6290 89/<- %ebp 4/r32/esp -6291 # . save registers -6292 51/push-ecx -6293 # return function->name == stmt->operation -6294 8b/-> *(ebp+8) 1/r32/ecx -6295 8b/-> *(ebp+0xc) 0/r32/eax -6296 (string-equal? *(ecx+4) *eax) # Stmt1-operation, Function-name => eax -6297 $mu-stmt-matches-function?:end: -6298 # . restore registers -6299 59/pop-to-ecx -6300 # . epilogue -6301 89/<- %esp 5/r32/ebp -6302 5d/pop-to-ebp -6303 c3/return -6304 -6305 mu-stmt-matches-primitive?: # stmt: (handle statement), primitive: (handle primitive) => result/eax: boolean -6306 # A mu stmt matches a primitive if the name matches, all the inout vars -6307 # match, and all the output vars match. -6308 # Vars match if types match and registers match. -6309 # In addition, a stmt output matches a primitive's output if types match -6310 # and the primitive has a wildcard register. -6311 # . prologue -6312 55/push-ebp -6313 89/<- %ebp 4/r32/esp -6314 # . save registers -6315 51/push-ecx -6316 52/push-edx -6317 53/push-ebx -6318 56/push-esi -6319 57/push-edi -6320 # ecx = stmt -6321 8b/-> *(ebp+8) 1/r32/ecx -6322 # edx = primitive -6323 8b/-> *(ebp+0xc) 2/r32/edx -6324 { -6325 $mu-stmt-matches-primitive?:check-name: -6326 # if (primitive->name != stmt->operation) return false -6327 (string-equal? *(ecx+4) *edx) # Stmt1-operation, Primitive-name => eax -6328 3d/compare-eax-and 0/imm32 -6329 75/jump-if-!= break/disp8 -6330 b8/copy-to-eax 0/imm32 -6331 e9/jump $mu-stmt-matches-primitive?:end/disp32 -6332 } -6333 $mu-stmt-matches-primitive?:check-inouts: -6334 # for (curr/esi in stmt->inouts, curr2/edi in primitive->inouts) -6335 8b/-> *(ecx+8) 6/r32/esi # Stmt1-inouts -6336 8b/-> *(edx+4) 7/r32/edi # Primitive-inouts -6337 { -6338 # if (curr == 0 && curr2 == 0) move on to check outputs -6339 { -6340 81 7/subop/compare %esi 0/imm32 -6341 75/jump-if-!= break/disp8 -6342 $mu-stmt-matches-primitive?:stmt-inout-is-null: -6343 { -6344 81 7/subop/compare %edi 0/imm32 -6345 75/jump-if-!= break/disp8 -6346 # -6347 e9/jump $mu-stmt-matches-primitive?:check-outputs/disp32 -6348 } -6349 # return false -6350 b8/copy-to-eax 0/imm32/false -6351 e9/jump $mu-stmt-matches-primitive?:end/disp32 -6352 } -6353 # if (curr2 == 0) return false -6354 { -6355 81 7/subop/compare %edi 0/imm32 -6356 75/jump-if-!= break/disp8 -6357 $mu-stmt-matches-primitive?:prim-inout-is-null: -6358 b8/copy-to-eax 0/imm32/false -6359 e9/jump $mu-stmt-matches-primitive?:end/disp32 -6360 } -6361 # if (curr != curr2) return false -6362 { -6363 (operand-matches-primitive? *esi *edi) # => eax -6364 3d/compare-eax-and 0/imm32 -6365 75/jump-if-!= break/disp8 -6366 b8/copy-to-eax 0/imm32/false -6367 e9/jump $mu-stmt-matches-primitive?:end/disp32 -6368 } -6369 # curr=curr->next -6370 8b/-> *(esi+4) 6/r32/esi # Operand-next -6371 # curr2=curr2->next -6372 8b/-> *(edi+4) 7/r32/edi # Operand-next -6373 eb/jump loop/disp8 -6374 } -6375 $mu-stmt-matches-primitive?:check-outputs: -6376 # for (curr/esi in stmt->outputs, curr2/edi in primitive->outputs) -6377 8b/-> *(ecx+0xc) 6/r32/esi # Stmt1-outputs -6378 8b/-> *(edx+8) 7/r32/edi # Primitive-outputs -6379 { -6380 # if (curr == 0) return (curr2 == 0) -6381 { -6382 $mu-stmt-matches-primitive?:check-output: -6383 81 7/subop/compare %esi 0/imm32 -6384 75/jump-if-!= break/disp8 -6385 { -6386 81 7/subop/compare %edi 0/imm32 -6387 75/jump-if-!= break/disp8 -6388 # return true -6389 b8/copy-to-eax 1/imm32 -6390 e9/jump $mu-stmt-matches-primitive?:end/disp32 -6391 } -6392 # return false -6393 b8/copy-to-eax 0/imm32 -6394 e9/jump $mu-stmt-matches-primitive?:end/disp32 -6395 } -6396 # if (curr2 == 0) return false -6397 { -6398 81 7/subop/compare %edi 0/imm32 -6399 75/jump-if-!= break/disp8 -6400 b8/copy-to-eax 0/imm32 -6401 e9/jump $mu-stmt-matches-primitive?:end/disp32 -6402 } -6403 # if (curr != curr2) return false -6404 { -6405 (operand-matches-primitive? *esi *edi) # List-value List-value => eax -6406 3d/compare-eax-and 0/imm32 -6407 75/jump-if-!= break/disp8 -6408 b8/copy-to-eax 0/imm32 -6409 e9/jump $mu-stmt-matches-primitive?:end/disp32 -6410 } -6411 # curr=curr->next -6412 8b/-> *(esi+4) 6/r32/esi # Operand-next -6413 # curr2=curr2->next -6414 8b/-> *(edi+4) 7/r32/edi # Operand-next -6415 eb/jump loop/disp8 -6416 } -6417 $mu-stmt-matches-primitive?:return-true: -6418 b8/copy-to-eax 1/imm32 -6419 $mu-stmt-matches-primitive?:end: -6420 # . restore registers -6421 5f/pop-to-edi -6422 5e/pop-to-esi -6423 5b/pop-to-ebx -6424 5a/pop-to-edx -6425 59/pop-to-ecx -6426 # . epilogue -6427 89/<- %esp 5/r32/ebp -6428 5d/pop-to-ebp -6429 c3/return -6430 -6431 operand-matches-primitive?: # var: (handle var), prim-var: (handle var) => result/eax: boolean -6432 # . prologue -6433 55/push-ebp -6434 89/<- %ebp 4/r32/esp -6435 # . save registers -6436 56/push-esi -6437 57/push-edi -6438 # esi = var -6439 8b/-> *(ebp+8) 6/r32/esi -6440 # edi = prim-var -6441 8b/-> *(ebp+0xc) 7/r32/edi -6442 # if (var->type != prim-var->type) return false -6443 (type-equal? *(esi+4) *(edi+4)) # Var-type, Var-type => eax -6444 3d/compare-eax-and 0/imm32 -6445 b8/copy-to-eax 0/imm32/false -6446 74/jump-if-= $operand-matches-primitive?:end/disp8 -6447 # return false if var->register doesn't match prim-var->register -6448 { -6449 # if addresses are equal, don't return here -6450 8b/-> *(esi+0x10) 0/r32/eax -6451 39/compare *(edi+0x10) 0/r32/eax -6452 74/jump-if-= break/disp8 -6453 # if either address is 0, return false -6454 3d/compare-eax-and 0/imm32 -6455 74/jump-if-= $operand-matches-primitive?:end/disp8 # eax goes from meaning var->register to result -6456 81 7/subop/compare *(edi+0x10) 0/imm32 -6457 74/jump-if-= $operand-matches-primitive?:end/disp8 # eax goes from meaning var->register to result -6458 # if prim-var->register is "*", return true -6459 (string-equal? *(edi+0x10) "*") # Var-register -6460 3d/compare-eax-and 0/imm32 -6461 b8/copy-to-eax 1/imm32/true -6462 75/jump-if-!= $operand-matches-primitive?:end/disp8 -6463 # if string contents don't match, return false -6464 (string-equal? *(esi+0x10) *(edi+0x10)) # Var-register Var-register -6465 3d/compare-eax-and 0/imm32 -6466 b8/copy-to-eax 0/imm32/false -6467 74/jump-if-= $operand-matches-primitive?:end/disp8 -6468 } -6469 # return true -6470 b8/copy-to-eax 1/imm32/true -6471 $operand-matches-primitive?:end: -6472 # . restore registers -6473 5f/pop-to-edi -6474 5e/pop-to-esi -6475 # . epilogue -6476 89/<- %esp 5/r32/ebp -6477 5d/pop-to-ebp -6478 c3/return -6479 -6480 type-equal?: # a: (handle tree type-id), b: (handle tree type-id) => result/eax: boolean -6481 # . prologue -6482 55/push-ebp -6483 89/<- %ebp 4/r32/esp -6484 # . save registers -6485 51/push-ecx -6486 52/push-edx -6487 # ecx = a -6488 8b/-> *(ebp+8) 1/r32/ecx -6489 # edx = b -6490 8b/-> *(ebp+0xc) 2/r32/edx -6491 # if (a == b) return true -6492 8b/-> %ecx 0/r32/eax # Var-type -6493 39/compare %edx 0/r32/eax # Var-type -6494 b8/copy-to-eax 1/imm32/true -6495 74/jump-if-= $type-equal?:end/disp8 -6496 # if (a < MAX_TYPE_ID) return false -6497 81 7/subop/compare %ecx 0x10000/imm32 -6498 b8/copy-to-eax 0/imm32/false -6499 72/jump-if-addr< $type-equal?:end/disp8 -6500 # if (b < MAX_TYPE_ID) return false -6501 81 7/subop/compare %edx 0x10000/imm32 -6502 b8/copy-to-eax 0/imm32/false -6503 72/jump-if-addr< $type-equal?:end/disp8 -6504 # if (!type-equal?(a->left, b->left)) return false -6505 (type-equal? *ecx *edx) # Tree-left, Tree-left => eax -6506 3d/compare-eax-and 0/imm32 -6507 74/jump-if-= $type-equal?:end/disp8 -6508 # return type-equal?(a->right, b->right) -6509 (type-equal? *(ecx+4) *(edx+4)) # Tree-right, Tree-right => eax -6510 $type-equal?:end: -6511 # . restore registers -6512 5a/pop-to-edx -6513 59/pop-to-ecx -6514 # . epilogue -6515 89/<- %esp 5/r32/ebp -6516 5d/pop-to-ebp -6517 c3/return -6518 -6519 test-emit-subx-statement-primitive: -6520 # Primitive operation on a variable on the stack. -6521 # increment foo -6522 # => -6523 # ff 0/subop/increment *(ebp-8) -6524 # -6525 # There's a variable on the var stack as follows: -6526 # name: 'foo' -6527 # type: int -6528 # stack-offset: -8 -6529 # -6530 # There's a primitive with this info: -6531 # name: 'increment' -6532 # inouts: int/mem -6533 # value: 'ff 0/subop/increment' -6534 # -6535 # There's nothing in functions. -6536 # -6537 # . prologue -6538 55/push-ebp -6539 89/<- %ebp 4/r32/esp -6540 # setup -6541 (clear-stream _test-output-stream) -6542 (clear-stream $_test-output-buffered-file->buffer) -6543 # var type/ecx: (handle tree type-id) = int -6544 68/push 0/imm32/right/null -6545 68/push 1/imm32/left/int -6546 89/<- %ecx 4/r32/esp -6547 # var var-foo/ecx: var -6548 68/push 0/imm32/no-register -6549 68/push -8/imm32/stack-offset -6550 68/push 1/imm32/block-depth -6551 51/push-ecx -6552 68/push "foo"/imm32 -6553 89/<- %ecx 4/r32/esp -6554 # var operand/ebx: (list var) -6555 68/push 0/imm32/next -6556 51/push-ecx/var-foo -6557 89/<- %ebx 4/r32/esp -6558 # var stmt/esi: statement -6559 68/push 0/imm32/next -6560 68/push 0/imm32/outputs -6561 53/push-ebx/operands -6562 68/push "increment"/imm32/operation -6563 68/push 1/imm32 -6564 89/<- %esi 4/r32/esp -6565 # var primitives/ebx: primitive -6566 68/push 0/imm32/next -6567 68/push 0/imm32/output-is-write-only -6568 68/push 0/imm32/no-disp32 -6569 68/push 0/imm32/no-imm32 -6570 68/push 0/imm32/no-r32 -6571 68/push 1/imm32/rm32-is-first-inout -6572 68/push "ff 0/subop/increment"/imm32/subx-name -6573 68/push 0/imm32/outputs -6574 53/push-ebx/inouts # hack; in practice we won't have the same var in function definition and call -6575 68/push "increment"/imm32/name -6576 89/<- %ebx 4/r32/esp -6577 # convert -6578 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) -6579 (flush _test-output-buffered-file) -6580 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -6586 # check output -6587 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-statement-primitive") -6588 # . epilogue -6589 89/<- %esp 5/r32/ebp -6590 5d/pop-to-ebp -6591 c3/return -6592 -6593 test-emit-subx-statement-primitive-register: -6594 # Primitive operation on a variable in a register. -6595 # foo <- increment -6596 # => -6597 # ff 0/subop/increment %eax # sub-optimal, but should suffice -6598 # -6599 # There's a variable on the var stack as follows: -6600 # name: 'foo' -6601 # type: int -6602 # register: 'eax' -6603 # -6604 # There's a primitive with this info: -6605 # name: 'increment' -6606 # out: int/reg -6607 # value: 'ff 0/subop/increment' -6608 # -6609 # There's nothing in functions. -6610 # -6611 # . prologue -6612 55/push-ebp -6613 89/<- %ebp 4/r32/esp -6614 # setup -6615 (clear-stream _test-output-stream) -6616 (clear-stream $_test-output-buffered-file->buffer) -6617 # var type/ecx: (handle tree type-id) = int -6618 68/push 0/imm32/right/null -6619 68/push 1/imm32/left/int -6620 89/<- %ecx 4/r32/esp -6621 # var var-foo/ecx: var in eax -6622 68/push "eax"/imm32/register -6623 68/push 0/imm32/no-stack-offset -6624 68/push 1/imm32/block-depth -6625 51/push-ecx -6626 68/push "foo"/imm32 -6627 89/<- %ecx 4/r32/esp -6628 # var operand/ebx: (list var) -6629 68/push 0/imm32/next -6630 51/push-ecx/var-foo -6631 89/<- %ebx 4/r32/esp -6632 # var stmt/esi: statement -6633 68/push 0/imm32/next -6634 53/push-ebx/outputs -6635 68/push 0/imm32/inouts -6636 68/push "increment"/imm32/operation -6637 68/push 1/imm32 -6638 89/<- %esi 4/r32/esp -6639 # var formal-var/ebx: var in any register -6640 68/push Any-register/imm32 -6641 68/push 0/imm32/no-stack-offset -6642 68/push 1/imm32/block-depth -6643 ff 6/subop/push *(ecx+4) # Var-type -6644 68/push "dummy"/imm32 -6645 89/<- %ebx 4/r32/esp -6646 # var operand/ebx: (list var) -6647 68/push 0/imm32/next -6648 53/push-ebx/formal-var -6649 89/<- %ebx 4/r32/esp -6650 # var primitives/ebx: primitive -6651 68/push 0/imm32/next -6652 68/push 0/imm32/output-is-write-only -6653 68/push 0/imm32/no-disp32 -6654 68/push 0/imm32/no-imm32 -6655 68/push 0/imm32/no-r32 -6656 68/push 3/imm32/rm32-in-first-output -6657 68/push "ff 0/subop/increment"/imm32/subx-name -6658 53/push-ebx/outputs -6659 68/push 0/imm32/inouts -6660 68/push "increment"/imm32/name -6661 89/<- %ebx 4/r32/esp -6662 # convert -6663 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) -6664 (flush _test-output-buffered-file) -6665 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -6671 # check output -6672 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-primitive-register") -6673 # . epilogue -6674 89/<- %esp 5/r32/ebp -6675 5d/pop-to-ebp -6676 c3/return -6677 -6678 test-emit-subx-statement-select-primitive: -6679 # Select the right primitive between overloads. -6680 # foo <- increment -6681 # => -6682 # ff 0/subop/increment %eax # sub-optimal, but should suffice -6683 # -6684 # There's a variable on the var stack as follows: -6685 # name: 'foo' -6686 # type: int -6687 # register: 'eax' -6688 # -6689 # There's two primitives, as follows: -6690 # - name: 'increment' -6691 # out: int/reg -6692 # value: 'ff 0/subop/increment' -6693 # - name: 'increment' -6694 # inout: int/mem -6695 # value: 'ff 0/subop/increment' -6696 # -6697 # There's nothing in functions. -6698 # -6699 # . prologue -6700 55/push-ebp -6701 89/<- %ebp 4/r32/esp -6702 # setup -6703 (clear-stream _test-output-stream) -6704 (clear-stream $_test-output-buffered-file->buffer) -6705 # var type/ecx: (handle tree type-id) = int -6706 68/push 0/imm32/right/null -6707 68/push 1/imm32/left/int -6708 89/<- %ecx 4/r32/esp -6709 # var var-foo/ecx: var in eax -6710 68/push "eax"/imm32/register -6711 68/push 0/imm32/no-stack-offset -6712 68/push 1/imm32/block-depth -6713 51/push-ecx -6714 68/push "foo"/imm32 -6715 89/<- %ecx 4/r32/esp -6716 # var real-outputs/edi: (list var) -6717 68/push 0/imm32/next -6718 51/push-ecx/var-foo -6719 89/<- %edi 4/r32/esp -6720 # var stmt/esi: statement -6721 68/push 0/imm32/next -6722 57/push-edi/outputs -6723 68/push 0/imm32/inouts -6724 68/push "increment"/imm32/operation -6725 68/push 1/imm32 -6726 89/<- %esi 4/r32/esp -6727 # var formal-var/ebx: var in any register -6728 68/push Any-register/imm32 -6729 68/push 0/imm32/no-stack-offset -6730 68/push 1/imm32/block-depth -6731 ff 6/subop/push *(ecx+4) # Var-type -6732 68/push "dummy"/imm32 -6733 89/<- %ebx 4/r32/esp -6734 # var formal-outputs/ebx: (list var) = {formal-var, 0} -6735 68/push 0/imm32/next -6736 53/push-ebx/formal-var -6737 89/<- %ebx 4/r32/esp -6738 # var primitive1/ebx: primitive -6739 68/push 0/imm32/next -6740 68/push 0/imm32/output-is-write-only -6741 68/push 0/imm32/no-disp32 -6742 68/push 0/imm32/no-imm32 -6743 68/push 0/imm32/no-r32 -6744 68/push 3/imm32/rm32-in-first-output -6745 68/push "ff 0/subop/increment"/imm32/subx-name -6746 53/push-ebx/outputs/formal-outputs -6747 68/push 0/imm32/inouts -6748 68/push "increment"/imm32/name -6749 89/<- %ebx 4/r32/esp -6750 # var primitives/ebx: primitive -6751 53/push-ebx/next -6752 68/push 0/imm32/output-is-write-only -6753 68/push 0/imm32/no-disp32 -6754 68/push 0/imm32/no-imm32 -6755 68/push 0/imm32/no-r32 -6756 68/push 1/imm32/rm32-is-first-inout -6757 68/push "ff 0/subop/increment"/imm32/subx-name -6758 68/push 0/imm32/outputs -6759 57/push-edi/inouts/real-outputs # hack; in practice we won't have the same var in function definition and call -6760 68/push "increment"/imm32/name -6761 89/<- %ebx 4/r32/esp -6762 # convert -6763 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) -6764 (flush _test-output-buffered-file) -6765 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -6771 # check output -6772 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive") -6773 # . epilogue -6774 89/<- %esp 5/r32/ebp -6775 5d/pop-to-ebp -6776 c3/return -6777 -6778 test-emit-subx-statement-select-primitive-2: -6779 # Select the right primitive between overloads. -6780 # foo <- increment -6781 # => -6782 # ff 0/subop/increment %eax # sub-optimal, but should suffice -6783 # -6784 # There's a variable on the var stack as follows: -6785 # name: 'foo' -6786 # type: int -6787 # register: 'eax' -6788 # -6789 # There's two primitives, as follows: -6790 # - name: 'increment' -6791 # out: int/reg -6792 # value: 'ff 0/subop/increment' -6793 # - name: 'increment' -6794 # inout: int/mem -6795 # value: 'ff 0/subop/increment' -6796 # -6797 # There's nothing in functions. -6798 # -6799 # . prologue -6800 55/push-ebp -6801 89/<- %ebp 4/r32/esp -6802 # setup -6803 (clear-stream _test-output-stream) -6804 (clear-stream $_test-output-buffered-file->buffer) -6805 # var type/ecx: (handle tree type-id) = int -6806 68/push 0/imm32/right/null -6807 68/push 1/imm32/left/int -6808 89/<- %ecx 4/r32/esp -6809 # var var-foo/ecx: var in eax -6810 68/push "eax"/imm32/register -6811 68/push 0/imm32/no-stack-offset -6812 68/push 1/imm32/block-depth -6813 51/push-ecx -6814 68/push "foo"/imm32 -6815 89/<- %ecx 4/r32/esp -6816 # var inouts/edi: (list var) -6817 68/push 0/imm32/next -6818 51/push-ecx/var-foo -6819 89/<- %edi 4/r32/esp -6820 # var stmt/esi: statement -6821 68/push 0/imm32/next -6822 68/push 0/imm32/outputs -6823 57/push-edi/inouts -6824 68/push "increment"/imm32/operation -6825 68/push 1/imm32 -6826 89/<- %esi 4/r32/esp -6827 # var formal-var/ebx: var in any register -6828 68/push Any-register/imm32 -6829 68/push 0/imm32/no-stack-offset -6830 68/push 1/imm32/block-depth -6831 ff 6/subop/push *(ecx+4) # Var-type -6832 68/push "dummy"/imm32 -6833 89/<- %ebx 4/r32/esp -6834 # var operand/ebx: (list var) -6835 68/push 0/imm32/next -6836 53/push-ebx/formal-var -6837 89/<- %ebx 4/r32/esp -6838 # var primitive1/ebx: primitive -6839 68/push 0/imm32/next -6840 68/push 0/imm32/output-is-write-only -6841 68/push 0/imm32/no-disp32 -6842 68/push 0/imm32/no-imm32 -6843 68/push 0/imm32/no-r32 -6844 68/push 3/imm32/rm32-in-first-output -6845 68/push "ff 0/subop/increment"/imm32/subx-name -6846 53/push-ebx/outputs/formal-outputs -6847 68/push 0/imm32/inouts -6848 68/push "increment"/imm32/name -6849 89/<- %ebx 4/r32/esp -6850 # var primitives/ebx: primitive -6851 53/push-ebx/next -6852 68/push 0/imm32/output-is-write-only -6853 68/push 0/imm32/no-disp32 -6854 68/push 0/imm32/no-imm32 -6855 68/push 0/imm32/no-r32 -6856 68/push 1/imm32/rm32-is-first-inout -6857 68/push "ff 0/subop/increment"/imm32/subx-name +6116 (write-buffered *(ebp+8) "/disp32") +6117 $emit-subx-disp32:end: +6118 # . restore registers +6119 59/pop-to-ecx +6120 58/pop-to-eax +6121 # . epilogue +6122 89/<- %esp 5/r32/ebp +6123 5d/pop-to-ebp +6124 c3/return +6125 +6126 emit-subx-call: # out: (addr buffered-file), stmt: (handle statement), callee: (handle function) +6127 # . prologue +6128 55/push-ebp +6129 89/<- %ebp 4/r32/esp +6130 # . save registers +6131 50/push-eax +6132 51/push-ecx +6133 # +6134 (write-buffered *(ebp+8) "(") +6135 # - emit function name +6136 8b/-> *(ebp+0x10) 1/r32/ecx +6137 (write-buffered *(ebp+8) *(ecx+4)) # Function-subx-name +6138 # - emit arguments +6139 # var curr/ecx: (handle list var) = stmt->inouts +6140 8b/-> *(ebp+0xc) 1/r32/ecx +6141 8b/-> *(ecx+8) 1/r32/ecx # Stmt1-inouts +6142 { +6143 # if (curr == null) break +6144 81 7/subop/compare %ecx 0/imm32 +6145 74/jump-if-= break/disp8 +6146 # +6147 (emit-subx-call-operand *(ebp+8) *ecx) +6148 # curr = curr->next +6149 8b/-> *(ecx+4) 1/r32/ecx +6150 eb/jump loop/disp8 +6151 } +6152 # +6153 (write-buffered *(ebp+8) ")\n") +6154 $emit-subx-call:end: +6155 # . restore registers +6156 59/pop-to-ecx +6157 58/pop-to-eax +6158 # . epilogue +6159 89/<- %esp 5/r32/ebp +6160 5d/pop-to-ebp +6161 c3/return +6162 +6163 emit-subx-call-operand: # out: (addr buffered-file), operand: (handle variable) +6164 # shares code with emit-subx-var-as-rm32 +6165 # . prologue +6166 55/push-ebp +6167 89/<- %ebp 4/r32/esp +6168 # . save registers +6169 50/push-eax +6170 # eax = operand +6171 8b/-> *(ebp+0xc) 0/r32/eax +6172 # if (operand->register) emit "%__" +6173 { +6174 81 7/subop/compare *(eax+0x10) 0/imm32 # Var-register +6175 74/jump-if-= break/disp8 +6176 $emit-subx-call-operand:register: +6177 (write-buffered *(ebp+8) " %") +6178 (write-buffered *(ebp+8) *(eax+0x10)) # Var-register +6179 e9/jump $emit-subx-call-operand:end/disp32 +6180 } +6181 # else if (operand->stack-offset) emit "*(ebp+__)" +6182 { +6183 81 7/subop/compare *(eax+0xc) 0/imm32 # Var-stack-offset +6184 74/jump-if-= break/disp8 +6185 $emit-subx-call-operand:stack: +6186 (write-buffered *(ebp+8) Space) +6187 (write-buffered *(ebp+8) "*(ebp+") +6188 8b/-> *(ebp+0xc) 0/r32/eax +6189 (print-int32-buffered *(ebp+8) *(eax+0xc)) # Var-stack-offset +6190 (write-buffered *(ebp+8) ")") +6191 e9/jump $emit-subx-call-operand:end/disp32 +6192 } +6193 # else if (operand->type == literal) emit "__" +6194 { +6195 50/push-eax +6196 8b/-> *(eax+4) 0/r32/eax # Var-type +6197 81 7/subop/compare *eax 0/imm32 # Tree-left +6198 58/pop-to-eax +6199 75/jump-if-!= break/disp8 +6200 $emit-subx-call-operand:literal: +6201 (write-buffered *(ebp+8) Space) +6202 (write-buffered *(ebp+8) *eax) +6203 } +6204 $emit-subx-call-operand:end: +6205 # . restore registers +6206 58/pop-to-eax +6207 # . epilogue +6208 89/<- %esp 5/r32/ebp +6209 5d/pop-to-ebp +6210 c3/return +6211 +6212 emit-subx-var-as-rm32: # out: (addr buffered-file), operand: (handle variable) +6213 # . prologue +6214 55/push-ebp +6215 89/<- %ebp 4/r32/esp +6216 # . save registers +6217 50/push-eax +6218 # eax = operand +6219 8b/-> *(ebp+0xc) 0/r32/eax +6220 # if (operand->register) emit "%__" +6221 { +6222 81 7/subop/compare *(eax+0x10) 0/imm32 # Var-register +6223 74/jump-if-= break/disp8 +6224 $emit-subx-var-as-rm32:register: +6225 (write-buffered *(ebp+8) " %") +6226 (write-buffered *(ebp+8) *(eax+0x10)) # Var-register +6227 } +6228 # else if (operand->stack-offset) emit "*(ebp+__)" +6229 { +6230 81 7/subop/compare *(eax+0xc) 0/imm32 # Var-stack-offset +6231 74/jump-if-= break/disp8 +6232 $emit-subx-var-as-rm32:stack: +6233 (write-buffered *(ebp+8) Space) +6234 (write-buffered *(ebp+8) "*(ebp+") +6235 8b/-> *(ebp+0xc) 0/r32/eax +6236 (print-int32-buffered *(ebp+8) *(eax+0xc)) # Var-stack-offset +6237 (write-buffered *(ebp+8) ")") +6238 } +6239 $emit-subx-var-as-rm32:end: +6240 # . restore registers +6241 58/pop-to-eax +6242 # . epilogue +6243 89/<- %esp 5/r32/ebp +6244 5d/pop-to-ebp +6245 c3/return +6246 +6247 find-matching-function: # functions: (addr function), stmt: (handle statement) -> result/eax: (handle function) +6248 # . prologue +6249 55/push-ebp +6250 89/<- %ebp 4/r32/esp +6251 # . save registers +6252 51/push-ecx +6253 # var curr/ecx: (handle function) = functions +6254 8b/-> *(ebp+8) 1/r32/ecx +6255 { +6256 # if (curr == null) break +6257 81 7/subop/compare %ecx 0/imm32 +6258 74/jump-if-= break/disp8 +6259 # if match(stmt, curr) return curr +6260 { +6261 (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax +6262 3d/compare-eax-and 0/imm32 +6263 74/jump-if-= break/disp8 +6264 89/<- %eax 1/r32/ecx +6265 eb/jump $find-matching-function:end/disp8 +6266 } +6267 # curr = curr->next +6268 8b/-> *(ecx+0x14) 1/r32/ecx # Function-next +6269 eb/jump loop/disp8 +6270 } +6271 # return null +6272 b8/copy-to-eax 0/imm32 +6273 $find-matching-function:end: +6274 # . restore registers +6275 59/pop-to-ecx +6276 # . epilogue +6277 89/<- %esp 5/r32/ebp +6278 5d/pop-to-ebp +6279 c3/return +6280 +6281 find-matching-primitive: # primitives: (handle primitive), stmt: (handle statement) -> result/eax: (handle primitive) +6282 # . prologue +6283 55/push-ebp +6284 89/<- %ebp 4/r32/esp +6285 # . save registers +6286 51/push-ecx +6287 # var curr/ecx: (handle primitive) = primitives +6288 8b/-> *(ebp+8) 1/r32/ecx +6289 { +6290 $find-matching-primitive:loop: +6291 # if (curr == null) break +6292 81 7/subop/compare %ecx 0/imm32 +6293 0f 84/jump-if-= break/disp32 +6294 #? (write-buffered Stderr "prim: ") +6295 #? (write-buffered Stderr *ecx) # Primitive-name +6296 #? (write-buffered Stderr " => ") +6297 #? (write-buffered Stderr *(ecx+0xc)) # Primitive-subx-name +6298 #? (write-buffered Stderr Newline) +6299 #? (flush Stderr) +6300 # if match(curr, stmt) return curr +6301 { +6302 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx) # => eax +6303 3d/compare-eax-and 0/imm32 +6304 74/jump-if-= break/disp8 +6305 89/<- %eax 1/r32/ecx +6306 eb/jump $find-matching-primitive:end/disp8 +6307 } +6308 $find-matching-primitive:next-primitive: +6309 # curr = curr->next +6310 8b/-> *(ecx+0x24) 1/r32/ecx # Primitive-next +6311 e9/jump loop/disp32 +6312 } +6313 # return null +6314 b8/copy-to-eax 0/imm32 +6315 $find-matching-primitive:end: +6316 # . restore registers +6317 59/pop-to-ecx +6318 # . epilogue +6319 89/<- %esp 5/r32/ebp +6320 5d/pop-to-ebp +6321 c3/return +6322 +6323 mu-stmt-matches-function?: # stmt: (handle statement), function: (handle function) => result/eax: boolean +6324 # . prologue +6325 55/push-ebp +6326 89/<- %ebp 4/r32/esp +6327 # . save registers +6328 51/push-ecx +6329 # return function->name == stmt->operation +6330 8b/-> *(ebp+8) 1/r32/ecx +6331 8b/-> *(ebp+0xc) 0/r32/eax +6332 (string-equal? *(ecx+4) *eax) # Stmt1-operation, Function-name => eax +6333 $mu-stmt-matches-function?:end: +6334 # . restore registers +6335 59/pop-to-ecx +6336 # . epilogue +6337 89/<- %esp 5/r32/ebp +6338 5d/pop-to-ebp +6339 c3/return +6340 +6341 mu-stmt-matches-primitive?: # stmt: (handle statement), primitive: (handle primitive) => result/eax: boolean +6342 # A mu stmt matches a primitive if the name matches, all the inout vars +6343 # match, and all the output vars match. +6344 # Vars match if types match and registers match. +6345 # In addition, a stmt output matches a primitive's output if types match +6346 # and the primitive has a wildcard register. +6347 # . prologue +6348 55/push-ebp +6349 89/<- %ebp 4/r32/esp +6350 # . save registers +6351 51/push-ecx +6352 52/push-edx +6353 53/push-ebx +6354 56/push-esi +6355 57/push-edi +6356 # ecx = stmt +6357 8b/-> *(ebp+8) 1/r32/ecx +6358 # edx = primitive +6359 8b/-> *(ebp+0xc) 2/r32/edx +6360 { +6361 $mu-stmt-matches-primitive?:check-name: +6362 # if (primitive->name != stmt->operation) return false +6363 (string-equal? *(ecx+4) *edx) # Stmt1-operation, Primitive-name => eax +6364 3d/compare-eax-and 0/imm32 +6365 75/jump-if-!= break/disp8 +6366 b8/copy-to-eax 0/imm32 +6367 e9/jump $mu-stmt-matches-primitive?:end/disp32 +6368 } +6369 $mu-stmt-matches-primitive?:check-inouts: +6370 # for (curr/esi in stmt->inouts, curr2/edi in primitive->inouts) +6371 8b/-> *(ecx+8) 6/r32/esi # Stmt1-inouts +6372 8b/-> *(edx+4) 7/r32/edi # Primitive-inouts +6373 { +6374 # if (curr == 0 && curr2 == 0) move on to check outputs +6375 { +6376 81 7/subop/compare %esi 0/imm32 +6377 75/jump-if-!= break/disp8 +6378 $mu-stmt-matches-primitive?:stmt-inout-is-null: +6379 { +6380 81 7/subop/compare %edi 0/imm32 +6381 75/jump-if-!= break/disp8 +6382 # +6383 e9/jump $mu-stmt-matches-primitive?:check-outputs/disp32 +6384 } +6385 # return false +6386 b8/copy-to-eax 0/imm32/false +6387 e9/jump $mu-stmt-matches-primitive?:end/disp32 +6388 } +6389 # if (curr2 == 0) return false +6390 { +6391 81 7/subop/compare %edi 0/imm32 +6392 75/jump-if-!= break/disp8 +6393 $mu-stmt-matches-primitive?:prim-inout-is-null: +6394 b8/copy-to-eax 0/imm32/false +6395 e9/jump $mu-stmt-matches-primitive?:end/disp32 +6396 } +6397 # if (curr != curr2) return false +6398 { +6399 (operand-matches-primitive? *esi *edi) # => eax +6400 3d/compare-eax-and 0/imm32 +6401 75/jump-if-!= break/disp8 +6402 b8/copy-to-eax 0/imm32/false +6403 e9/jump $mu-stmt-matches-primitive?:end/disp32 +6404 } +6405 # curr=curr->next +6406 8b/-> *(esi+4) 6/r32/esi # Operand-next +6407 # curr2=curr2->next +6408 8b/-> *(edi+4) 7/r32/edi # Operand-next +6409 eb/jump loop/disp8 +6410 } +6411 $mu-stmt-matches-primitive?:check-outputs: +6412 # for (curr/esi in stmt->outputs, curr2/edi in primitive->outputs) +6413 8b/-> *(ecx+0xc) 6/r32/esi # Stmt1-outputs +6414 8b/-> *(edx+8) 7/r32/edi # Primitive-outputs +6415 { +6416 # if (curr == 0) return (curr2 == 0) +6417 { +6418 $mu-stmt-matches-primitive?:check-output: +6419 81 7/subop/compare %esi 0/imm32 +6420 75/jump-if-!= break/disp8 +6421 { +6422 81 7/subop/compare %edi 0/imm32 +6423 75/jump-if-!= break/disp8 +6424 # return true +6425 b8/copy-to-eax 1/imm32 +6426 e9/jump $mu-stmt-matches-primitive?:end/disp32 +6427 } +6428 # return false +6429 b8/copy-to-eax 0/imm32 +6430 e9/jump $mu-stmt-matches-primitive?:end/disp32 +6431 } +6432 # if (curr2 == 0) return false +6433 { +6434 81 7/subop/compare %edi 0/imm32 +6435 75/jump-if-!= break/disp8 +6436 b8/copy-to-eax 0/imm32 +6437 e9/jump $mu-stmt-matches-primitive?:end/disp32 +6438 } +6439 # if (curr != curr2) return false +6440 { +6441 (operand-matches-primitive? *esi *edi) # List-value List-value => eax +6442 3d/compare-eax-and 0/imm32 +6443 75/jump-if-!= break/disp8 +6444 b8/copy-to-eax 0/imm32 +6445 e9/jump $mu-stmt-matches-primitive?:end/disp32 +6446 } +6447 # curr=curr->next +6448 8b/-> *(esi+4) 6/r32/esi # Operand-next +6449 # curr2=curr2->next +6450 8b/-> *(edi+4) 7/r32/edi # Operand-next +6451 eb/jump loop/disp8 +6452 } +6453 $mu-stmt-matches-primitive?:return-true: +6454 b8/copy-to-eax 1/imm32 +6455 $mu-stmt-matches-primitive?:end: +6456 # . restore registers +6457 5f/pop-to-edi +6458 5e/pop-to-esi +6459 5b/pop-to-ebx +6460 5a/pop-to-edx +6461 59/pop-to-ecx +6462 # . epilogue +6463 89/<- %esp 5/r32/ebp +6464 5d/pop-to-ebp +6465 c3/return +6466 +6467 operand-matches-primitive?: # var: (handle var), prim-var: (handle var) => result/eax: boolean +6468 # . prologue +6469 55/push-ebp +6470 89/<- %ebp 4/r32/esp +6471 # . save registers +6472 56/push-esi +6473 57/push-edi +6474 # esi = var +6475 8b/-> *(ebp+8) 6/r32/esi +6476 # edi = prim-var +6477 8b/-> *(ebp+0xc) 7/r32/edi +6478 # if (var->type != prim-var->type) return false +6479 (type-equal? *(esi+4) *(edi+4)) # Var-type, Var-type => eax +6480 3d/compare-eax-and 0/imm32 +6481 b8/copy-to-eax 0/imm32/false +6482 74/jump-if-= $operand-matches-primitive?:end/disp8 +6483 # return false if var->register doesn't match prim-var->register +6484 { +6485 # if addresses are equal, don't return here +6486 8b/-> *(esi+0x10) 0/r32/eax +6487 39/compare *(edi+0x10) 0/r32/eax +6488 74/jump-if-= break/disp8 +6489 # if either address is 0, return false +6490 3d/compare-eax-and 0/imm32 +6491 74/jump-if-= $operand-matches-primitive?:end/disp8 # eax goes from meaning var->register to result +6492 81 7/subop/compare *(edi+0x10) 0/imm32 +6493 74/jump-if-= $operand-matches-primitive?:end/disp8 # eax goes from meaning var->register to result +6494 # if prim-var->register is "*", return true +6495 (string-equal? *(edi+0x10) "*") # Var-register +6496 3d/compare-eax-and 0/imm32 +6497 b8/copy-to-eax 1/imm32/true +6498 75/jump-if-!= $operand-matches-primitive?:end/disp8 +6499 # if string contents don't match, return false +6500 (string-equal? *(esi+0x10) *(edi+0x10)) # Var-register Var-register +6501 3d/compare-eax-and 0/imm32 +6502 b8/copy-to-eax 0/imm32/false +6503 74/jump-if-= $operand-matches-primitive?:end/disp8 +6504 } +6505 # return true +6506 b8/copy-to-eax 1/imm32/true +6507 $operand-matches-primitive?:end: +6508 # . restore registers +6509 5f/pop-to-edi +6510 5e/pop-to-esi +6511 # . epilogue +6512 89/<- %esp 5/r32/ebp +6513 5d/pop-to-ebp +6514 c3/return +6515 +6516 type-equal?: # a: (handle tree type-id), b: (handle tree type-id) => result/eax: boolean +6517 # . prologue +6518 55/push-ebp +6519 89/<- %ebp 4/r32/esp +6520 # . save registers +6521 51/push-ecx +6522 52/push-edx +6523 # ecx = a +6524 8b/-> *(ebp+8) 1/r32/ecx +6525 # edx = b +6526 8b/-> *(ebp+0xc) 2/r32/edx +6527 # if (a == b) return true +6528 8b/-> %ecx 0/r32/eax # Var-type +6529 39/compare %edx 0/r32/eax # Var-type +6530 b8/copy-to-eax 1/imm32/true +6531 74/jump-if-= $type-equal?:end/disp8 +6532 # if (a < MAX_TYPE_ID) return false +6533 81 7/subop/compare %ecx 0x10000/imm32 +6534 b8/copy-to-eax 0/imm32/false +6535 72/jump-if-addr< $type-equal?:end/disp8 +6536 # if (b < MAX_TYPE_ID) return false +6537 81 7/subop/compare %edx 0x10000/imm32 +6538 b8/copy-to-eax 0/imm32/false +6539 72/jump-if-addr< $type-equal?:end/disp8 +6540 # if (!type-equal?(a->left, b->left)) return false +6541 (type-equal? *ecx *edx) # Tree-left, Tree-left => eax +6542 3d/compare-eax-and 0/imm32 +6543 74/jump-if-= $type-equal?:end/disp8 +6544 # return type-equal?(a->right, b->right) +6545 (type-equal? *(ecx+4) *(edx+4)) # Tree-right, Tree-right => eax +6546 $type-equal?:end: +6547 # . restore registers +6548 5a/pop-to-edx +6549 59/pop-to-ecx +6550 # . epilogue +6551 89/<- %esp 5/r32/ebp +6552 5d/pop-to-ebp +6553 c3/return +6554 +6555 test-emit-subx-statement-primitive: +6556 # Primitive operation on a variable on the stack. +6557 # increment foo +6558 # => +6559 # ff 0/subop/increment *(ebp-8) +6560 # +6561 # There's a variable on the var stack as follows: +6562 # name: 'foo' +6563 # type: int +6564 # stack-offset: -8 +6565 # +6566 # There's a primitive with this info: +6567 # name: 'increment' +6568 # inouts: int/mem +6569 # value: 'ff 0/subop/increment' +6570 # +6571 # There's nothing in functions. +6572 # +6573 # . prologue +6574 55/push-ebp +6575 89/<- %ebp 4/r32/esp +6576 # setup +6577 (clear-stream _test-output-stream) +6578 (clear-stream $_test-output-buffered-file->buffer) +6579 # var type/ecx: (handle tree type-id) = int +6580 68/push 0/imm32/right/null +6581 68/push 1/imm32/left/int +6582 89/<- %ecx 4/r32/esp +6583 # var var-foo/ecx: var +6584 68/push 0/imm32/no-register +6585 68/push -8/imm32/stack-offset +6586 68/push 1/imm32/block-depth +6587 51/push-ecx +6588 68/push "foo"/imm32 +6589 89/<- %ecx 4/r32/esp +6590 # var operand/ebx: (list var) +6591 68/push 0/imm32/next +6592 51/push-ecx/var-foo +6593 89/<- %ebx 4/r32/esp +6594 # var stmt/esi: statement +6595 68/push 0/imm32/next +6596 68/push 0/imm32/outputs +6597 53/push-ebx/operands +6598 68/push "increment"/imm32/operation +6599 68/push 1/imm32 +6600 89/<- %esi 4/r32/esp +6601 # var primitives/ebx: primitive +6602 68/push 0/imm32/next +6603 68/push 0/imm32/output-is-write-only +6604 68/push 0/imm32/no-disp32 +6605 68/push 0/imm32/no-imm32 +6606 68/push 0/imm32/no-r32 +6607 68/push 1/imm32/rm32-is-first-inout +6608 68/push "ff 0/subop/increment"/imm32/subx-name +6609 68/push 0/imm32/outputs +6610 53/push-ebx/inouts # hack; in practice we won't have the same var in function definition and call +6611 68/push "increment"/imm32/name +6612 89/<- %ebx 4/r32/esp +6613 # convert +6614 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) +6615 (flush _test-output-buffered-file) +6616 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +6622 # check output +6623 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-statement-primitive") +6624 # . epilogue +6625 89/<- %esp 5/r32/ebp +6626 5d/pop-to-ebp +6627 c3/return +6628 +6629 test-emit-subx-statement-primitive-register: +6630 # Primitive operation on a variable in a register. +6631 # foo <- increment +6632 # => +6633 # ff 0/subop/increment %eax # sub-optimal, but should suffice +6634 # +6635 # There's a variable on the var stack as follows: +6636 # name: 'foo' +6637 # type: int +6638 # register: 'eax' +6639 # +6640 # There's a primitive with this info: +6641 # name: 'increment' +6642 # out: int/reg +6643 # value: 'ff 0/subop/increment' +6644 # +6645 # There's nothing in functions. +6646 # +6647 # . prologue +6648 55/push-ebp +6649 89/<- %ebp 4/r32/esp +6650 # setup +6651 (clear-stream _test-output-stream) +6652 (clear-stream $_test-output-buffered-file->buffer) +6653 # var type/ecx: (handle tree type-id) = int +6654 68/push 0/imm32/right/null +6655 68/push 1/imm32/left/int +6656 89/<- %ecx 4/r32/esp +6657 # var var-foo/ecx: var in eax +6658 68/push "eax"/imm32/register +6659 68/push 0/imm32/no-stack-offset +6660 68/push 1/imm32/block-depth +6661 51/push-ecx +6662 68/push "foo"/imm32 +6663 89/<- %ecx 4/r32/esp +6664 # var operand/ebx: (list var) +6665 68/push 0/imm32/next +6666 51/push-ecx/var-foo +6667 89/<- %ebx 4/r32/esp +6668 # var stmt/esi: statement +6669 68/push 0/imm32/next +6670 53/push-ebx/outputs +6671 68/push 0/imm32/inouts +6672 68/push "increment"/imm32/operation +6673 68/push 1/imm32 +6674 89/<- %esi 4/r32/esp +6675 # var formal-var/ebx: var in any register +6676 68/push Any-register/imm32 +6677 68/push 0/imm32/no-stack-offset +6678 68/push 1/imm32/block-depth +6679 ff 6/subop/push *(ecx+4) # Var-type +6680 68/push "dummy"/imm32 +6681 89/<- %ebx 4/r32/esp +6682 # var operand/ebx: (list var) +6683 68/push 0/imm32/next +6684 53/push-ebx/formal-var +6685 89/<- %ebx 4/r32/esp +6686 # var primitives/ebx: primitive +6687 68/push 0/imm32/next +6688 68/push 0/imm32/output-is-write-only +6689 68/push 0/imm32/no-disp32 +6690 68/push 0/imm32/no-imm32 +6691 68/push 0/imm32/no-r32 +6692 68/push 3/imm32/rm32-in-first-output +6693 68/push "ff 0/subop/increment"/imm32/subx-name +6694 53/push-ebx/outputs +6695 68/push 0/imm32/inouts +6696 68/push "increment"/imm32/name +6697 89/<- %ebx 4/r32/esp +6698 # convert +6699 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) +6700 (flush _test-output-buffered-file) +6701 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +6707 # check output +6708 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-primitive-register") +6709 # . epilogue +6710 89/<- %esp 5/r32/ebp +6711 5d/pop-to-ebp +6712 c3/return +6713 +6714 test-emit-subx-statement-select-primitive: +6715 # Select the right primitive between overloads. +6716 # foo <- increment +6717 # => +6718 # ff 0/subop/increment %eax # sub-optimal, but should suffice +6719 # +6720 # There's a variable on the var stack as follows: +6721 # name: 'foo' +6722 # type: int +6723 # register: 'eax' +6724 # +6725 # There's two primitives, as follows: +6726 # - name: 'increment' +6727 # out: int/reg +6728 # value: 'ff 0/subop/increment' +6729 # - name: 'increment' +6730 # inout: int/mem +6731 # value: 'ff 0/subop/increment' +6732 # +6733 # There's nothing in functions. +6734 # +6735 # . prologue +6736 55/push-ebp +6737 89/<- %ebp 4/r32/esp +6738 # setup +6739 (clear-stream _test-output-stream) +6740 (clear-stream $_test-output-buffered-file->buffer) +6741 # var type/ecx: (handle tree type-id) = int +6742 68/push 0/imm32/right/null +6743 68/push 1/imm32/left/int +6744 89/<- %ecx 4/r32/esp +6745 # var var-foo/ecx: var in eax +6746 68/push "eax"/imm32/register +6747 68/push 0/imm32/no-stack-offset +6748 68/push 1/imm32/block-depth +6749 51/push-ecx +6750 68/push "foo"/imm32 +6751 89/<- %ecx 4/r32/esp +6752 # var real-outputs/edi: (list var) +6753 68/push 0/imm32/next +6754 51/push-ecx/var-foo +6755 89/<- %edi 4/r32/esp +6756 # var stmt/esi: statement +6757 68/push 0/imm32/next +6758 57/push-edi/outputs +6759 68/push 0/imm32/inouts +6760 68/push "increment"/imm32/operation +6761 68/push 1/imm32 +6762 89/<- %esi 4/r32/esp +6763 # var formal-var/ebx: var in any register +6764 68/push Any-register/imm32 +6765 68/push 0/imm32/no-stack-offset +6766 68/push 1/imm32/block-depth +6767 ff 6/subop/push *(ecx+4) # Var-type +6768 68/push "dummy"/imm32 +6769 89/<- %ebx 4/r32/esp +6770 # var formal-outputs/ebx: (list var) = {formal-var, 0} +6771 68/push 0/imm32/next +6772 53/push-ebx/formal-var +6773 89/<- %ebx 4/r32/esp +6774 # var primitive1/ebx: primitive +6775 68/push 0/imm32/next +6776 68/push 0/imm32/output-is-write-only +6777 68/push 0/imm32/no-disp32 +6778 68/push 0/imm32/no-imm32 +6779 68/push 0/imm32/no-r32 +6780 68/push 3/imm32/rm32-in-first-output +6781 68/push "ff 0/subop/increment"/imm32/subx-name +6782 53/push-ebx/outputs/formal-outputs +6783 68/push 0/imm32/inouts +6784 68/push "increment"/imm32/name +6785 89/<- %ebx 4/r32/esp +6786 # var primitives/ebx: primitive +6787 53/push-ebx/next +6788 68/push 0/imm32/output-is-write-only +6789 68/push 0/imm32/no-disp32 +6790 68/push 0/imm32/no-imm32 +6791 68/push 0/imm32/no-r32 +6792 68/push 1/imm32/rm32-is-first-inout +6793 68/push "ff 0/subop/increment"/imm32/subx-name +6794 68/push 0/imm32/outputs +6795 57/push-edi/inouts/real-outputs # hack; in practice we won't have the same var in function definition and call +6796 68/push "increment"/imm32/name +6797 89/<- %ebx 4/r32/esp +6798 # convert +6799 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) +6800 (flush _test-output-buffered-file) +6801 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +6807 # check output +6808 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive") +6809 # . epilogue +6810 89/<- %esp 5/r32/ebp +6811 5d/pop-to-ebp +6812 c3/return +6813 +6814 test-emit-subx-statement-select-primitive-2: +6815 # Select the right primitive between overloads. +6816 # foo <- increment +6817 # => +6818 # ff 0/subop/increment %eax # sub-optimal, but should suffice +6819 # +6820 # There's a variable on the var stack as follows: +6821 # name: 'foo' +6822 # type: int +6823 # register: 'eax' +6824 # +6825 # There's two primitives, as follows: +6826 # - name: 'increment' +6827 # out: int/reg +6828 # value: 'ff 0/subop/increment' +6829 # - name: 'increment' +6830 # inout: int/mem +6831 # value: 'ff 0/subop/increment' +6832 # +6833 # There's nothing in functions. +6834 # +6835 # . prologue +6836 55/push-ebp +6837 89/<- %ebp 4/r32/esp +6838 # setup +6839 (clear-stream _test-output-stream) +6840 (clear-stream $_test-output-buffered-file->buffer) +6841 # var type/ecx: (handle tree type-id) = int +6842 68/push 0/imm32/right/null +6843 68/push 1/imm32/left/int +6844 89/<- %ecx 4/r32/esp +6845 # var var-foo/ecx: var in eax +6846 68/push "eax"/imm32/register +6847 68/push 0/imm32/no-stack-offset +6848 68/push 1/imm32/block-depth +6849 51/push-ecx +6850 68/push "foo"/imm32 +6851 89/<- %ecx 4/r32/esp +6852 # var inouts/edi: (list var) +6853 68/push 0/imm32/next +6854 51/push-ecx/var-foo +6855 89/<- %edi 4/r32/esp +6856 # var stmt/esi: statement +6857 68/push 0/imm32/next 6858 68/push 0/imm32/outputs -6859 57/push-edi/inouts/real-outputs # hack; in practice we won't have the same var in function definition and call -6860 68/push "increment"/imm32/name -6861 89/<- %ebx 4/r32/esp -6862 # convert -6863 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) -6864 (flush _test-output-buffered-file) -6865 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -6871 # check output -6872 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive-2") -6873 # . epilogue -6874 89/<- %esp 5/r32/ebp -6875 5d/pop-to-ebp -6876 c3/return -6877 -6878 test-increment-register: -6879 # Select the right primitive between overloads. -6880 # foo <- increment -6881 # => -6882 # 50/increment-eax -6883 # -6884 # There's a variable on the var stack as follows: -6885 # name: 'foo' -6886 # type: int -6887 # register: 'eax' -6888 # -6889 # Primitives are the global definitions. -6890 # -6891 # There are no functions defined. -6892 # -6893 # . prologue -6894 55/push-ebp -6895 89/<- %ebp 4/r32/esp -6896 # setup -6897 (clear-stream _test-output-stream) -6898 (clear-stream $_test-output-buffered-file->buffer) -6899 # var type/ecx: (handle tree type-id) = int -6900 68/push 0/imm32/right/null -6901 68/push 1/imm32/left/int -6902 89/<- %ecx 4/r32/esp -6903 # var var-foo/ecx: var in eax -6904 68/push "eax"/imm32/register -6905 68/push 0/imm32/no-stack-offset -6906 68/push 1/imm32/block-depth -6907 51/push-ecx -6908 68/push "foo"/imm32 -6909 89/<- %ecx 4/r32/esp -6910 # var real-outputs/edi: (list var) -6911 68/push 0/imm32/next -6912 51/push-ecx/var-foo -6913 89/<- %edi 4/r32/esp -6914 # var stmt/esi: statement -6915 68/push 0/imm32/next -6916 57/push-edi/outputs -6917 68/push 0/imm32/inouts -6918 68/push "increment"/imm32/operation -6919 68/push 1/imm32/regular-statement -6920 89/<- %esi 4/r32/esp -6921 # convert -6922 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -6923 (flush _test-output-buffered-file) -6924 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -6930 # check output -6931 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") -6932 # . epilogue -6933 89/<- %esp 5/r32/ebp -6934 5d/pop-to-ebp -6935 c3/return -6936 -6937 test-increment-var: -6938 # Select the right primitive between overloads. -6939 # foo <- increment -6940 # => -6941 # ff 0/subop/increment %eax # sub-optimal, but should suffice -6942 # -6943 # There's a variable on the var stack as follows: -6944 # name: 'foo' -6945 # type: int -6946 # register: 'eax' -6947 # -6948 # Primitives are the global definitions. -6949 # -6950 # There are no functions defined. -6951 # -6952 # . prologue -6953 55/push-ebp -6954 89/<- %ebp 4/r32/esp -6955 # setup -6956 (clear-stream _test-output-stream) -6957 (clear-stream $_test-output-buffered-file->buffer) -6958 # var type/ecx: (handle tree type-id) = int -6959 68/push 0/imm32/right/null -6960 68/push 1/imm32/left/int -6961 89/<- %ecx 4/r32/esp -6962 # var var-foo/ecx: var in eax -6963 68/push "eax"/imm32/register -6964 68/push 0/imm32/no-stack-offset -6965 68/push 1/imm32/block-depth -6966 51/push-ecx -6967 68/push "foo"/imm32 -6968 89/<- %ecx 4/r32/esp -6969 # var inouts/edi: (list var) -6970 68/push 0/imm32/next -6971 51/push-ecx/var-foo -6972 89/<- %edi 4/r32/esp -6973 # var stmt/esi: statement -6974 68/push 0/imm32/next -6975 68/push 0/imm32/outputs -6976 57/push-edi/inouts -6977 68/push "increment"/imm32/operation -6978 68/push 1/imm32 -6979 89/<- %esi 4/r32/esp -6980 # convert -6981 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -6982 (flush _test-output-buffered-file) -6983 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -6989 # check output -6990 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-increment-var") -6991 # . epilogue -6992 89/<- %esp 5/r32/ebp -6993 5d/pop-to-ebp -6994 c3/return -6995 -6996 test-add-reg-to-reg: -6997 # var1/reg <- add var2/reg -6998 # => -6999 # 01/add %var1 var2 -7000 # -7001 # . prologue -7002 55/push-ebp -7003 89/<- %ebp 4/r32/esp -7004 # setup -7005 (clear-stream _test-output-stream) -7006 (clear-stream $_test-output-buffered-file->buffer) -7007 # var type/ecx: (handle tree type-id) = int -7008 68/push 0/imm32/right/null -7009 68/push 1/imm32/left/int -7010 89/<- %ecx 4/r32/esp -7011 # var var-var1/ecx: var in eax -7012 68/push "eax"/imm32/register -7013 68/push 0/imm32/no-stack-offset -7014 68/push 1/imm32/block-depth -7015 51/push-ecx -7016 68/push "var1"/imm32 -7017 89/<- %ecx 4/r32/esp -7018 # var var-var2/edx: var in ecx -7019 68/push "ecx"/imm32/register -7020 68/push 0/imm32/no-stack-offset -7021 68/push 1/imm32/block-depth -7022 ff 6/subop/push *(ecx+4) # Var-type -7023 68/push "var2"/imm32 -7024 89/<- %edx 4/r32/esp -7025 # var inouts/esi: (list var2) -7026 68/push 0/imm32/next -7027 52/push-edx/var-var2 -7028 89/<- %esi 4/r32/esp -7029 # var outputs/edi: (list var1) -7030 68/push 0/imm32/next -7031 51/push-ecx/var-var1 -7032 89/<- %edi 4/r32/esp -7033 # var stmt/esi: statement -7034 68/push 0/imm32/next -7035 57/push-edi/outputs -7036 56/push-esi/inouts -7037 68/push "add"/imm32/operation -7038 68/push 1/imm32 -7039 89/<- %esi 4/r32/esp -7040 # convert -7041 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -7042 (flush _test-output-buffered-file) -7043 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7049 # check output -7050 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") -7051 # . epilogue -7052 89/<- %esp 5/r32/ebp -7053 5d/pop-to-ebp -7054 c3/return -7055 -7056 test-add-reg-to-mem: -7057 # add-to var1 var2/reg -7058 # => -7059 # 01/add *(ebp+__) var2 -7060 # -7061 # . prologue -7062 55/push-ebp -7063 89/<- %ebp 4/r32/esp -7064 # setup -7065 (clear-stream _test-output-stream) -7066 (clear-stream $_test-output-buffered-file->buffer) -7067 # var type/ecx: (handle tree type-id) = int -7068 68/push 0/imm32/right/null -7069 68/push 1/imm32/left/int -7070 89/<- %ecx 4/r32/esp -7071 # var var-var1/ecx: var -7072 68/push 0/imm32/no-register -7073 68/push 8/imm32/stack-offset -7074 68/push 1/imm32/block-depth -7075 51/push-ecx -7076 68/push "var1"/imm32 -7077 89/<- %ecx 4/r32/esp -7078 # var var-var2/edx: var in ecx -7079 68/push "ecx"/imm32/register -7080 68/push 0/imm32/no-stack-offset -7081 68/push 1/imm32/block-depth -7082 ff 6/subop/push *(ecx+4) # Var-type -7083 68/push "var2"/imm32 -7084 89/<- %edx 4/r32/esp -7085 # var inouts/esi: (list var2) -7086 68/push 0/imm32/next -7087 52/push-edx/var-var2 -7088 89/<- %esi 4/r32/esp -7089 # var inouts = (list var1 var2) -7090 56/push-esi/next -7091 51/push-ecx/var-var1 -7092 89/<- %esi 4/r32/esp -7093 # var stmt/esi: statement -7094 68/push 0/imm32/next -7095 68/push 0/imm32/outputs -7096 56/push-esi/inouts -7097 68/push "add-to"/imm32/operation -7098 68/push 1/imm32 -7099 89/<- %esi 4/r32/esp -7100 # convert -7101 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -7102 (flush _test-output-buffered-file) -7103 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7109 # check output -7110 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") -7111 # . epilogue -7112 89/<- %esp 5/r32/ebp -7113 5d/pop-to-ebp -7114 c3/return -7115 -7116 test-add-mem-to-reg: -7117 # var1/reg <- add var2 -7118 # => -7119 # 03/add *(ebp+__) var1 -7120 # -7121 # . prologue -7122 55/push-ebp -7123 89/<- %ebp 4/r32/esp -7124 # setup -7125 (clear-stream _test-output-stream) -7126 (clear-stream $_test-output-buffered-file->buffer) -7127 # var type/ecx: (handle tree type-id) = int -7128 68/push 0/imm32/right/null -7129 68/push 1/imm32/left/int -7130 89/<- %ecx 4/r32/esp -7131 # var var-var1/ecx: var in eax -7132 68/push "eax"/imm32/register -7133 68/push 0/imm32/no-stack-offset -7134 68/push 1/imm32/block-depth -7135 51/push-ecx -7136 68/push "var1"/imm32 -7137 89/<- %ecx 4/r32/esp -7138 # var var-var2/edx: var -7139 68/push 0/imm32/no-register -7140 68/push 8/imm32/stack-offset -7141 68/push 1/imm32/block-depth -7142 ff 6/subop/push *(ecx+4) # Var-type -7143 68/push "var2"/imm32 -7144 89/<- %edx 4/r32/esp -7145 # var inouts/esi: (list var2) -7146 68/push 0/imm32/next -7147 52/push-edx/var-var2 -7148 89/<- %esi 4/r32/esp -7149 # var outputs/edi: (list var1) -7150 68/push 0/imm32/next -7151 51/push-ecx/var-var1 -7152 89/<- %edi 4/r32/esp -7153 # var stmt/esi: statement -7154 68/push 0/imm32/next -7155 57/push-edi/outputs -7156 56/push-esi/inouts -7157 68/push "add"/imm32/operation -7158 68/push 1/imm32 -7159 89/<- %esi 4/r32/esp -7160 # convert -7161 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -7162 (flush _test-output-buffered-file) -7163 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7169 # check output -7170 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") -7171 # . epilogue -7172 89/<- %esp 5/r32/ebp -7173 5d/pop-to-ebp -7174 c3/return -7175 -7176 test-add-literal-to-eax: -7177 # var1/eax <- add 0x34 -7178 # => -7179 # 05/add-to-eax 0x34/imm32 -7180 # -7181 # . prologue -7182 55/push-ebp -7183 89/<- %ebp 4/r32/esp -7184 # setup -7185 (clear-stream _test-output-stream) -7186 (clear-stream $_test-output-buffered-file->buffer) -7187 # var type/ecx: (handle tree type-id) = int -7188 68/push 0/imm32/right/null -7189 68/push 1/imm32/left/int -7190 89/<- %ecx 4/r32/esp -7191 # var var-var1/ecx: var in eax -7192 68/push "eax"/imm32/register -7193 68/push 0/imm32/no-stack-offset -7194 68/push 1/imm32/block-depth -7195 51/push-ecx -7196 68/push "var1"/imm32 -7197 89/<- %ecx 4/r32/esp -7198 # var type/edx: (handle tree type-id) = literal -7199 68/push 0/imm32/right/null -7200 68/push 0/imm32/left/literal -7201 89/<- %edx 4/r32/esp -7202 # var var-var2/edx: var literal -7203 68/push 0/imm32/no-register -7204 68/push 0/imm32/no-stack-offset -7205 68/push 1/imm32/block-depth -7206 52/push-edx -7207 68/push "0x34"/imm32 -7208 89/<- %edx 4/r32/esp -7209 # var inouts/esi: (list var2) -7210 68/push 0/imm32/next -7211 52/push-edx/var-var2 -7212 89/<- %esi 4/r32/esp -7213 # var outputs/edi: (list var1) -7214 68/push 0/imm32/next -7215 51/push-ecx/var-var1 -7216 89/<- %edi 4/r32/esp -7217 # var stmt/esi: statement -7218 68/push 0/imm32/next -7219 57/push-edi/outputs -7220 56/push-esi/inouts -7221 68/push "add"/imm32/operation -7222 68/push 1/imm32 -7223 89/<- %esi 4/r32/esp -7224 # convert -7225 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -7226 (flush _test-output-buffered-file) -7227 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7233 # check output -7234 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") -7235 # . epilogue -7236 89/<- %esp 5/r32/ebp -7237 5d/pop-to-ebp -7238 c3/return -7239 -7240 test-add-literal-to-reg: -7241 # var1/ecx <- add 0x34 -7242 # => -7243 # 81 0/subop/add %ecx 0x34/imm32 -7244 # -7245 # . prologue -7246 55/push-ebp -7247 89/<- %ebp 4/r32/esp -7248 # setup -7249 (clear-stream _test-output-stream) -7250 (clear-stream $_test-output-buffered-file->buffer) -7251 # var type/ecx: (handle tree type-id) = int -7252 68/push 0/imm32/right/null -7253 68/push 1/imm32/left/int -7254 89/<- %ecx 4/r32/esp -7255 # var var-var1/ecx: var in ecx -7256 68/push "ecx"/imm32/register -7257 68/push 0/imm32/no-stack-offset -7258 68/push 1/imm32/block-depth -7259 51/push-ecx -7260 68/push "var1"/imm32 -7261 89/<- %ecx 4/r32/esp -7262 # var type/edx: (handle tree type-id) = literal -7263 68/push 0/imm32/right/null -7264 68/push 0/imm32/left/literal -7265 89/<- %edx 4/r32/esp -7266 # var var-var2/edx: var literal -7267 68/push 0/imm32/no-register -7268 68/push 0/imm32/no-stack-offset -7269 68/push 1/imm32/block-depth -7270 52/push-edx -7271 68/push "0x34"/imm32 -7272 89/<- %edx 4/r32/esp -7273 # var inouts/esi: (list var2) -7274 68/push 0/imm32/next -7275 52/push-edx/var-var2 -7276 89/<- %esi 4/r32/esp -7277 # var outputs/edi: (list var1) -7278 68/push 0/imm32/next -7279 51/push-ecx/var-var1 -7280 89/<- %edi 4/r32/esp -7281 # var stmt/esi: statement -7282 68/push 0/imm32/next -7283 57/push-edi/outputs -7284 56/push-esi/inouts -7285 68/push "add"/imm32/operation -7286 68/push 1/imm32 -7287 89/<- %esi 4/r32/esp -7288 # convert -7289 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -7290 (flush _test-output-buffered-file) -7291 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7297 # check output -7298 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") -7299 # . epilogue -7300 89/<- %esp 5/r32/ebp -7301 5d/pop-to-ebp -7302 c3/return -7303 -7304 test-add-literal-to-mem: -7305 # add-to var1, 0x34 -7306 # => -7307 # 81 0/subop/add %eax 0x34/imm32 -7308 # -7309 # . prologue -7310 55/push-ebp -7311 89/<- %ebp 4/r32/esp -7312 # setup -7313 (clear-stream _test-output-stream) -7314 (clear-stream $_test-output-buffered-file->buffer) -7315 # var type/ecx: (handle tree type-id) = int -7316 68/push 0/imm32/right/null -7317 68/push 1/imm32/left/int -7318 89/<- %ecx 4/r32/esp -7319 # var var-var1/ecx: var -7320 68/push 0/imm32/no-register -7321 68/push 8/imm32/stack-offset -7322 68/push 1/imm32/block-depth -7323 51/push-ecx -7324 68/push "var1"/imm32 -7325 89/<- %ecx 4/r32/esp -7326 # var type/edx: (handle tree type-id) = literal -7327 68/push 0/imm32/right/null -7328 68/push 0/imm32/left/literal -7329 89/<- %edx 4/r32/esp -7330 # var var-var2/edx: var literal -7331 68/push 0/imm32/no-register -7332 68/push 0/imm32/no-stack-offset -7333 68/push 1/imm32/block-depth -7334 52/push-edx -7335 68/push "0x34"/imm32 -7336 89/<- %edx 4/r32/esp -7337 # var inouts/esi: (list var2) -7338 68/push 0/imm32/next -7339 52/push-edx/var-var2 -7340 89/<- %esi 4/r32/esp -7341 # var inouts = (list var1 inouts) -7342 56/push-esi/next -7343 51/push-ecx/var-var1 -7344 89/<- %esi 4/r32/esp -7345 # var stmt/esi: statement -7346 68/push 0/imm32/next -7347 68/push 0/imm32/outputs -7348 56/push-esi/inouts -7349 68/push "add-to"/imm32/operation -7350 68/push 1/imm32 -7351 89/<- %esi 4/r32/esp -7352 # convert -7353 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -7354 (flush _test-output-buffered-file) -7355 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7361 # check output -7362 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") -7363 # . epilogue -7364 89/<- %esp 5/r32/ebp -7365 5d/pop-to-ebp -7366 c3/return -7367 -7368 test-compare-mem-with-reg: -7369 # compare var1, var2/eax -7370 # => -7371 # 39/compare *(ebp+___) 0/r32/eax -7372 # -7373 # . prologue -7374 55/push-ebp -7375 89/<- %ebp 4/r32/esp -7376 # setup -7377 (clear-stream _test-output-stream) -7378 (clear-stream $_test-output-buffered-file->buffer) -7379 # var type/ecx: (handle tree type-id) = int -7380 68/push 0/imm32/right/null -7381 68/push 1/imm32/left/int -7382 89/<- %ecx 4/r32/esp -7383 # var var-var2/ecx: var in eax -7384 68/push "eax"/imm32/register -7385 68/push 0/imm32/no-stack-offset -7386 68/push 1/imm32/block-depth -7387 51/push-ecx -7388 68/push "var2"/imm32 -7389 89/<- %ecx 4/r32/esp -7390 # var var-var1/edx: var -7391 68/push 0/imm32/no-register -7392 68/push 8/imm32/stack-offset -7393 68/push 1/imm32/block-depth -7394 ff 6/subop/push *(ecx+4) # Var-type -7395 68/push "var1"/imm32 -7396 89/<- %edx 4/r32/esp -7397 # var inouts/esi: (list var1 var2) -7398 68/push 0/imm32/next -7399 51/push-ecx/var-var2 -7400 89/<- %esi 4/r32/esp -7401 56/push-esi -7402 52/push-edx/var-var1 -7403 89/<- %esi 4/r32/esp -7404 # var stmt/esi: statement -7405 68/push 0/imm32/next -7406 68/push 0/imm32/outputs -7407 56/push-esi/inouts -7408 68/push "compare"/imm32/operation -7409 68/push 1/imm32 -7410 89/<- %esi 4/r32/esp -7411 # convert -7412 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -7413 (flush _test-output-buffered-file) -7414 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7420 # check output -7421 (check-next-stream-line-equal _test-output-stream "39/compare *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg") -7422 # . epilogue -7423 89/<- %esp 5/r32/ebp -7424 5d/pop-to-ebp -7425 c3/return -7426 -7427 test-compare-reg-with-mem: -7428 # compare var1/eax, var2 -7429 # => -7430 # 3b/compare *(ebp+___) 0/r32/eax -7431 # -7432 # . prologue -7433 55/push-ebp -7434 89/<- %ebp 4/r32/esp -7435 # setup -7436 (clear-stream _test-output-stream) -7437 (clear-stream $_test-output-buffered-file->buffer) -7438 # var type/ecx: (handle tree type-id) = int -7439 68/push 0/imm32/right/null -7440 68/push 1/imm32/left/int -7441 89/<- %ecx 4/r32/esp -7442 # var var-var1/ecx: var in eax -7443 68/push "eax"/imm32/register -7444 68/push 0/imm32/no-stack-offset -7445 68/push 1/imm32/block-depth -7446 51/push-ecx -7447 68/push "var1"/imm32 -7448 89/<- %ecx 4/r32/esp -7449 # var var-var2/edx: var -7450 68/push 0/imm32/no-register -7451 68/push 8/imm32/stack-offset -7452 68/push 1/imm32/block-depth -7453 ff 6/subop/push *(ecx+4) # Var-type -7454 68/push "var2"/imm32 -7455 89/<- %edx 4/r32/esp -7456 # var inouts/esi: (list var1 var2) -7457 68/push 0/imm32/next -7458 52/push-edx/var-var2 -7459 89/<- %esi 4/r32/esp -7460 56/push-esi -7461 51/push-ecx/var-var1 -7462 89/<- %esi 4/r32/esp -7463 # var stmt/esi: statement -7464 68/push 0/imm32/next -7465 68/push 0/imm32/outputs -7466 56/push-esi/inouts -7467 68/push "compare"/imm32/operation -7468 68/push 1/imm32 -7469 89/<- %esi 4/r32/esp -7470 # convert -7471 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -7472 (flush _test-output-buffered-file) -7473 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7479 # check output -7480 (check-next-stream-line-equal _test-output-stream "3b/compare *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem") -7481 # . epilogue -7482 89/<- %esp 5/r32/ebp -7483 5d/pop-to-ebp -7484 c3/return -7485 -7486 test-compare-mem-with-literal: -7487 # compare var1, 0x34 -7488 # => -7489 # 81 7/subop/compare *(ebp+___) 0x34/imm32 -7490 # -7491 # . prologue -7492 55/push-ebp -7493 89/<- %ebp 4/r32/esp -7494 # setup -7495 (clear-stream _test-output-stream) -7496 (clear-stream $_test-output-buffered-file->buffer) -7497 # var type/ecx: (handle tree type-id) = int -7498 68/push 0/imm32/right/null -7499 68/push 1/imm32/left/int -7500 89/<- %ecx 4/r32/esp -7501 # var var-var1/ecx: var -7502 68/push 0/imm32/no-register -7503 68/push 8/imm32/stack-offset -7504 68/push 1/imm32/block-depth -7505 51/push-ecx -7506 68/push "var1"/imm32 -7507 89/<- %ecx 4/r32/esp -7508 # var type/edx: (handle tree type-id) = literal -7509 68/push 0/imm32/right/null -7510 68/push 0/imm32/left/literal -7511 89/<- %edx 4/r32/esp -7512 # var var-var2/edx: var literal -7513 68/push 0/imm32/no-register -7514 68/push 0/imm32/no-stack-offset -7515 68/push 1/imm32/block-depth -7516 52/push-edx -7517 68/push "0x34"/imm32 -7518 89/<- %edx 4/r32/esp -7519 # var inouts/esi: (list var2) -7520 68/push 0/imm32/next -7521 52/push-edx/var-var2 -7522 89/<- %esi 4/r32/esp -7523 # var inouts = (list var1 inouts) -7524 56/push-esi/next -7525 51/push-ecx/var-var1 -7526 89/<- %esi 4/r32/esp -7527 # var stmt/esi: statement -7528 68/push 0/imm32/next -7529 68/push 0/imm32/outputs -7530 56/push-esi/inouts -7531 68/push "compare"/imm32/operation -7532 68/push 1/imm32 -7533 89/<- %esi 4/r32/esp -7534 # convert -7535 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -7536 (flush _test-output-buffered-file) -7537 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7543 # check output -7544 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal") -7545 # . epilogue -7546 89/<- %esp 5/r32/ebp -7547 5d/pop-to-ebp -7548 c3/return -7549 -7550 test-compare-eax-with-literal: -7551 # compare var1/eax 0x34 -7552 # => -7553 # 3d/compare-eax-with 0x34/imm32 -7554 # -7555 # . prologue -7556 55/push-ebp -7557 89/<- %ebp 4/r32/esp -7558 # setup -7559 (clear-stream _test-output-stream) -7560 (clear-stream $_test-output-buffered-file->buffer) -7561 # var type/ecx: (handle tree type-id) = int -7562 68/push 0/imm32/right/null -7563 68/push 1/imm32/left/int -7564 89/<- %ecx 4/r32/esp -7565 # var var-var1/ecx: var in eax -7566 68/push "eax"/imm32/register -7567 68/push 0/imm32/no-stack-offset -7568 68/push 1/imm32/block-depth -7569 51/push-ecx -7570 68/push "var1"/imm32 -7571 89/<- %ecx 4/r32/esp -7572 # var type/edx: (handle tree type-id) = literal -7573 68/push 0/imm32/right/null -7574 68/push 0/imm32/left/literal -7575 89/<- %edx 4/r32/esp -7576 # var var-var2/edx: var literal -7577 68/push 0/imm32/no-register -7578 68/push 0/imm32/no-stack-offset -7579 68/push 1/imm32/block-depth -7580 52/push-edx -7581 68/push "0x34"/imm32 -7582 89/<- %edx 4/r32/esp -7583 # var inouts/esi: (list var2) -7584 68/push 0/imm32/next -7585 52/push-edx/var-var2 -7586 89/<- %esi 4/r32/esp -7587 # var inouts = (list var1 inouts) -7588 56/push-esi/next -7589 51/push-ecx/var-var1 -7590 89/<- %esi 4/r32/esp -7591 # var stmt/esi: statement -7592 68/push 0/imm32/next -7593 68/push 0/imm32/outputs -7594 56/push-esi/inouts -7595 68/push "compare"/imm32/operation -7596 68/push 1/imm32/regular-stmt -7597 89/<- %esi 4/r32/esp -7598 # convert -7599 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -7600 (flush _test-output-buffered-file) -7601 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7607 # check output -7608 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal") -7609 # . epilogue -7610 89/<- %esp 5/r32/ebp -7611 5d/pop-to-ebp -7612 c3/return -7613 -7614 test-compare-reg-with-literal: -7615 # compare var1/ecx 0x34 -7616 # => -7617 # 81 7/subop/compare %ecx 0x34/imm32 -7618 # -7619 # . prologue -7620 55/push-ebp -7621 89/<- %ebp 4/r32/esp -7622 # setup -7623 (clear-stream _test-output-stream) -7624 (clear-stream $_test-output-buffered-file->buffer) -7625 # var type/ecx: (handle tree type-id) = int -7626 68/push 0/imm32/right/null -7627 68/push 1/imm32/left/int -7628 89/<- %ecx 4/r32/esp -7629 # var var-var1/ecx: var in ecx -7630 68/push "ecx"/imm32/register -7631 68/push 0/imm32/no-stack-offset -7632 68/push 1/imm32/block-depth -7633 51/push-ecx -7634 68/push "var1"/imm32 -7635 89/<- %ecx 4/r32/esp -7636 # var type/edx: (handle tree type-id) = literal -7637 68/push 0/imm32/right/null -7638 68/push 0/imm32/left/literal -7639 89/<- %edx 4/r32/esp -7640 # var var-var2/edx: var literal -7641 68/push 0/imm32/no-register -7642 68/push 0/imm32/no-stack-offset -7643 68/push 1/imm32/block-depth -7644 52/push-edx -7645 68/push "0x34"/imm32 -7646 89/<- %edx 4/r32/esp -7647 # var inouts/esi: (list var2) -7648 68/push 0/imm32/next -7649 52/push-edx/var-var2 -7650 89/<- %esi 4/r32/esp -7651 # var inouts = (list var1 inouts) -7652 56/push-esi/next -7653 51/push-ecx/var-var1 -7654 89/<- %esi 4/r32/esp -7655 # var stmt/esi: statement -7656 68/push 0/imm32/next -7657 68/push 0/imm32/outputs -7658 56/push-esi/inouts -7659 68/push "compare"/imm32/operation -7660 68/push 1/imm32/regular-stmt -7661 89/<- %esi 4/r32/esp -7662 # convert -7663 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) -7664 (flush _test-output-buffered-file) -7665 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7671 # check output -7672 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal") -7673 # . epilogue -7674 89/<- %esp 5/r32/ebp -7675 5d/pop-to-ebp -7676 c3/return -7677 -7678 test-emit-subx-statement-function-call: -7679 # Call a function on a variable on the stack. -7680 # f foo -7681 # => -7682 # (f2 *(ebp-8)) -7683 # (Changing the function name supports overloading in general, but here it -7684 # just serves to help disambiguate things.) -7685 # -7686 # There's a variable on the var stack as follows: -7687 # name: 'foo' -7688 # type: int -7689 # stack-offset: -8 -7690 # -7691 # There's nothing in primitives. -7692 # -7693 # There's a function with this info: -7694 # name: 'f' -7695 # inout: int/mem -7696 # value: 'f2' -7697 # -7698 # . prologue -7699 55/push-ebp -7700 89/<- %ebp 4/r32/esp -7701 # setup -7702 (clear-stream _test-output-stream) -7703 (clear-stream $_test-output-buffered-file->buffer) -7704 # var type/ecx: (handle tree type-id) = int -7705 68/push 0/imm32/right/null -7706 68/push 1/imm32/left/int -7707 89/<- %ecx 4/r32/esp -7708 # var var-foo/ecx: var -7709 68/push 0/imm32/no-register -7710 68/push -8/imm32/stack-offset -7711 68/push 0/imm32/block-depth -7712 51/push-ecx -7713 68/push "foo"/imm32 -7714 89/<- %ecx 4/r32/esp -7715 # var operands/esi: (list var) -7716 68/push 0/imm32/next -7717 51/push-ecx/var-foo -7718 89/<- %esi 4/r32/esp -7719 # var stmt/esi: statement -7720 68/push 0/imm32/next -7721 68/push 0/imm32/outputs -7722 56/push-esi/inouts -7723 68/push "f"/imm32/operation -7724 68/push 1/imm32 -7725 89/<- %esi 4/r32/esp -7726 # var functions/ebx: function -7727 68/push 0/imm32/next -7728 68/push 0/imm32/body -7729 68/push 0/imm32/outputs -7730 51/push-ecx/inouts # hack; in practice we won't have the same var in function definition and call -7731 68/push "f2"/imm32/subx-name -7732 68/push "f"/imm32/name -7733 89/<- %ebx 4/r32/esp -7734 # convert -7735 (emit-subx-statement _test-output-buffered-file %esi 0 %ebx) -7736 (flush _test-output-buffered-file) -7737 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7743 # check output -7744 (check-next-stream-line-equal _test-output-stream "(f2 *(ebp+0xfffffff8))" "F - test-emit-subx-statement-function-call") -7745 # . epilogue -7746 89/<- %esp 5/r32/ebp -7747 5d/pop-to-ebp -7748 c3/return -7749 -7750 test-emit-subx-statement-function-call-with-literal-arg: -7751 # Call a function on a literal. -7752 # f 34 -7753 # => -7754 # (f2 34) -7755 # -7756 # . prologue -7757 55/push-ebp -7758 89/<- %ebp 4/r32/esp -7759 # setup -7760 (clear-stream _test-output-stream) -7761 (clear-stream $_test-output-buffered-file->buffer) -7762 # var type/ecx: (handle tree type-id) = literal -7763 68/push 0/imm32/right/null -7764 68/push 0/imm32/left/literal -7765 89/<- %ecx 4/r32/esp -7766 # var var-foo/ecx: var literal -7767 68/push 0/imm32/no-register -7768 68/push 0/imm32/no-stack-offset -7769 68/push 0/imm32/block-depth -7770 51/push-ecx -7771 68/push "34"/imm32 -7772 89/<- %ecx 4/r32/esp -7773 # var operands/esi: (list var) -7774 68/push 0/imm32/next -7775 51/push-ecx/var-foo -7776 89/<- %esi 4/r32/esp -7777 # var stmt/esi: statement -7778 68/push 0/imm32/next -7779 68/push 0/imm32/outputs -7780 56/push-esi/inouts -7781 68/push "f"/imm32/operation -7782 68/push 1/imm32 -7783 89/<- %esi 4/r32/esp -7784 # var functions/ebx: function -7785 68/push 0/imm32/next -7786 68/push 0/imm32/body -7787 68/push 0/imm32/outputs -7788 51/push-ecx/inouts # hack; in practice we won't have the same var in function definition and call -7789 68/push "f2"/imm32/subx-name -7790 68/push "f"/imm32/name -7791 89/<- %ebx 4/r32/esp -7792 # convert -7793 (emit-subx-statement _test-output-buffered-file %esi 0 %ebx) -7794 (flush _test-output-buffered-file) -7795 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- -7801 # check output -7802 (check-next-stream-line-equal _test-output-stream "(f2 34)" "F - test-emit-subx-statement-function-call-with-literal-arg") -7803 # . epilogue -7804 89/<- %esp 5/r32/ebp -7805 5d/pop-to-ebp -7806 c3/return -7807 -7808 emit-subx-prologue: # out: (addr buffered-file) -7809 # . prologue -7810 55/push-ebp -7811 89/<- %ebp 4/r32/esp -7812 # -7813 (write-buffered *(ebp+8) "# . prologue\n") -7814 (write-buffered *(ebp+8) "55/push-ebp\n") -7815 (write-buffered *(ebp+8) "89/<- %ebp 4/r32/esp\n") -7816 $emit-subx-prologue:end: -7817 # . epilogue -7818 89/<- %esp 5/r32/ebp -7819 5d/pop-to-ebp -7820 c3/return -7821 -7822 emit-subx-epilogue: # out: (addr buffered-file) -7823 # . prologue -7824 55/push-ebp -7825 89/<- %ebp 4/r32/esp -7826 # -7827 (write-buffered *(ebp+8) "# . epilogue\n") -7828 (write-buffered *(ebp+8) "89/<- %esp 5/r32/ebp\n") -7829 (write-buffered *(ebp+8) "5d/pop-to-ebp\n") -7830 (write-buffered *(ebp+8) "c3/return\n") -7831 $emit-subx-epilogue:end: -7832 # . epilogue -7833 89/<- %esp 5/r32/ebp -7834 5d/pop-to-ebp -7835 c3/return +6859 57/push-edi/inouts +6860 68/push "increment"/imm32/operation +6861 68/push 1/imm32 +6862 89/<- %esi 4/r32/esp +6863 # var formal-var/ebx: var in any register +6864 68/push Any-register/imm32 +6865 68/push 0/imm32/no-stack-offset +6866 68/push 1/imm32/block-depth +6867 ff 6/subop/push *(ecx+4) # Var-type +6868 68/push "dummy"/imm32 +6869 89/<- %ebx 4/r32/esp +6870 # var operand/ebx: (list var) +6871 68/push 0/imm32/next +6872 53/push-ebx/formal-var +6873 89/<- %ebx 4/r32/esp +6874 # var primitive1/ebx: primitive +6875 68/push 0/imm32/next +6876 68/push 0/imm32/output-is-write-only +6877 68/push 0/imm32/no-disp32 +6878 68/push 0/imm32/no-imm32 +6879 68/push 0/imm32/no-r32 +6880 68/push 3/imm32/rm32-in-first-output +6881 68/push "ff 0/subop/increment"/imm32/subx-name +6882 53/push-ebx/outputs/formal-outputs +6883 68/push 0/imm32/inouts +6884 68/push "increment"/imm32/name +6885 89/<- %ebx 4/r32/esp +6886 # var primitives/ebx: primitive +6887 53/push-ebx/next +6888 68/push 0/imm32/output-is-write-only +6889 68/push 0/imm32/no-disp32 +6890 68/push 0/imm32/no-imm32 +6891 68/push 0/imm32/no-r32 +6892 68/push 1/imm32/rm32-is-first-inout +6893 68/push "ff 0/subop/increment"/imm32/subx-name +6894 68/push 0/imm32/outputs +6895 57/push-edi/inouts/real-outputs # hack; in practice we won't have the same var in function definition and call +6896 68/push "increment"/imm32/name +6897 89/<- %ebx 4/r32/esp +6898 # convert +6899 (emit-subx-statement _test-output-buffered-file %esi %ebx 0) +6900 (flush _test-output-buffered-file) +6901 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +6907 # check output +6908 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive-2") +6909 # . epilogue +6910 89/<- %esp 5/r32/ebp +6911 5d/pop-to-ebp +6912 c3/return +6913 +6914 test-increment-register: +6915 # Select the right primitive between overloads. +6916 # foo <- increment +6917 # => +6918 # 50/increment-eax +6919 # +6920 # There's a variable on the var stack as follows: +6921 # name: 'foo' +6922 # type: int +6923 # register: 'eax' +6924 # +6925 # Primitives are the global definitions. +6926 # +6927 # There are no functions defined. +6928 # +6929 # . prologue +6930 55/push-ebp +6931 89/<- %ebp 4/r32/esp +6932 # setup +6933 (clear-stream _test-output-stream) +6934 (clear-stream $_test-output-buffered-file->buffer) +6935 # var type/ecx: (handle tree type-id) = int +6936 68/push 0/imm32/right/null +6937 68/push 1/imm32/left/int +6938 89/<- %ecx 4/r32/esp +6939 # var var-foo/ecx: var in eax +6940 68/push "eax"/imm32/register +6941 68/push 0/imm32/no-stack-offset +6942 68/push 1/imm32/block-depth +6943 51/push-ecx +6944 68/push "foo"/imm32 +6945 89/<- %ecx 4/r32/esp +6946 # var real-outputs/edi: (list var) +6947 68/push 0/imm32/next +6948 51/push-ecx/var-foo +6949 89/<- %edi 4/r32/esp +6950 # var stmt/esi: statement +6951 68/push 0/imm32/next +6952 57/push-edi/outputs +6953 68/push 0/imm32/inouts +6954 68/push "increment"/imm32/operation +6955 68/push 1/imm32/regular-statement +6956 89/<- %esi 4/r32/esp +6957 # convert +6958 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +6959 (flush _test-output-buffered-file) +6960 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +6966 # check output +6967 (check-next-stream-line-equal _test-output-stream "40/increment-eax" "F - test-increment-register") +6968 # . epilogue +6969 89/<- %esp 5/r32/ebp +6970 5d/pop-to-ebp +6971 c3/return +6972 +6973 test-increment-var: +6974 # Select the right primitive between overloads. +6975 # foo <- increment +6976 # => +6977 # ff 0/subop/increment %eax # sub-optimal, but should suffice +6978 # +6979 # There's a variable on the var stack as follows: +6980 # name: 'foo' +6981 # type: int +6982 # register: 'eax' +6983 # +6984 # Primitives are the global definitions. +6985 # +6986 # There are no functions defined. +6987 # +6988 # . prologue +6989 55/push-ebp +6990 89/<- %ebp 4/r32/esp +6991 # setup +6992 (clear-stream _test-output-stream) +6993 (clear-stream $_test-output-buffered-file->buffer) +6994 # var type/ecx: (handle tree type-id) = int +6995 68/push 0/imm32/right/null +6996 68/push 1/imm32/left/int +6997 89/<- %ecx 4/r32/esp +6998 # var var-foo/ecx: var in eax +6999 68/push "eax"/imm32/register +7000 68/push 0/imm32/no-stack-offset +7001 68/push 1/imm32/block-depth +7002 51/push-ecx +7003 68/push "foo"/imm32 +7004 89/<- %ecx 4/r32/esp +7005 # var inouts/edi: (list var) +7006 68/push 0/imm32/next +7007 51/push-ecx/var-foo +7008 89/<- %edi 4/r32/esp +7009 # var stmt/esi: statement +7010 68/push 0/imm32/next +7011 68/push 0/imm32/outputs +7012 57/push-edi/inouts +7013 68/push "increment"/imm32/operation +7014 68/push 1/imm32 +7015 89/<- %esi 4/r32/esp +7016 # convert +7017 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +7018 (flush _test-output-buffered-file) +7019 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7025 # check output +7026 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-increment-var") +7027 # . epilogue +7028 89/<- %esp 5/r32/ebp +7029 5d/pop-to-ebp +7030 c3/return +7031 +7032 test-add-reg-to-reg: +7033 # var1/reg <- add var2/reg +7034 # => +7035 # 01/add %var1 var2 +7036 # +7037 # . prologue +7038 55/push-ebp +7039 89/<- %ebp 4/r32/esp +7040 # setup +7041 (clear-stream _test-output-stream) +7042 (clear-stream $_test-output-buffered-file->buffer) +7043 # var type/ecx: (handle tree type-id) = int +7044 68/push 0/imm32/right/null +7045 68/push 1/imm32/left/int +7046 89/<- %ecx 4/r32/esp +7047 # var var-var1/ecx: var in eax +7048 68/push "eax"/imm32/register +7049 68/push 0/imm32/no-stack-offset +7050 68/push 1/imm32/block-depth +7051 51/push-ecx +7052 68/push "var1"/imm32 +7053 89/<- %ecx 4/r32/esp +7054 # var var-var2/edx: var in ecx +7055 68/push "ecx"/imm32/register +7056 68/push 0/imm32/no-stack-offset +7057 68/push 1/imm32/block-depth +7058 ff 6/subop/push *(ecx+4) # Var-type +7059 68/push "var2"/imm32 +7060 89/<- %edx 4/r32/esp +7061 # var inouts/esi: (list var2) +7062 68/push 0/imm32/next +7063 52/push-edx/var-var2 +7064 89/<- %esi 4/r32/esp +7065 # var outputs/edi: (list var1) +7066 68/push 0/imm32/next +7067 51/push-ecx/var-var1 +7068 89/<- %edi 4/r32/esp +7069 # var stmt/esi: statement +7070 68/push 0/imm32/next +7071 57/push-edi/outputs +7072 56/push-esi/inouts +7073 68/push "add"/imm32/operation +7074 68/push 1/imm32 +7075 89/<- %esi 4/r32/esp +7076 # convert +7077 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +7078 (flush _test-output-buffered-file) +7079 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7085 # check output +7086 (check-next-stream-line-equal _test-output-stream "01/add-to %eax 0x00000001/r32" "F - test-add-reg-to-reg") +7087 # . epilogue +7088 89/<- %esp 5/r32/ebp +7089 5d/pop-to-ebp +7090 c3/return +7091 +7092 test-add-reg-to-mem: +7093 # add-to var1 var2/reg +7094 # => +7095 # 01/add *(ebp+__) var2 +7096 # +7097 # . prologue +7098 55/push-ebp +7099 89/<- %ebp 4/r32/esp +7100 # setup +7101 (clear-stream _test-output-stream) +7102 (clear-stream $_test-output-buffered-file->buffer) +7103 # var type/ecx: (handle tree type-id) = int +7104 68/push 0/imm32/right/null +7105 68/push 1/imm32/left/int +7106 89/<- %ecx 4/r32/esp +7107 # var var-var1/ecx: var +7108 68/push 0/imm32/no-register +7109 68/push 8/imm32/stack-offset +7110 68/push 1/imm32/block-depth +7111 51/push-ecx +7112 68/push "var1"/imm32 +7113 89/<- %ecx 4/r32/esp +7114 # var var-var2/edx: var in ecx +7115 68/push "ecx"/imm32/register +7116 68/push 0/imm32/no-stack-offset +7117 68/push 1/imm32/block-depth +7118 ff 6/subop/push *(ecx+4) # Var-type +7119 68/push "var2"/imm32 +7120 89/<- %edx 4/r32/esp +7121 # var inouts/esi: (list var2) +7122 68/push 0/imm32/next +7123 52/push-edx/var-var2 +7124 89/<- %esi 4/r32/esp +7125 # var inouts = (list var1 var2) +7126 56/push-esi/next +7127 51/push-ecx/var-var1 +7128 89/<- %esi 4/r32/esp +7129 # var stmt/esi: statement +7130 68/push 0/imm32/next +7131 68/push 0/imm32/outputs +7132 56/push-esi/inouts +7133 68/push "add-to"/imm32/operation +7134 68/push 1/imm32 +7135 89/<- %esi 4/r32/esp +7136 # convert +7137 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +7138 (flush _test-output-buffered-file) +7139 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7145 # check output +7146 (check-next-stream-line-equal _test-output-stream "01/add-to *(ebp+0x00000008) 0x00000001/r32" "F - test-add-reg-to-mem") +7147 # . epilogue +7148 89/<- %esp 5/r32/ebp +7149 5d/pop-to-ebp +7150 c3/return +7151 +7152 test-add-mem-to-reg: +7153 # var1/reg <- add var2 +7154 # => +7155 # 03/add *(ebp+__) var1 +7156 # +7157 # . prologue +7158 55/push-ebp +7159 89/<- %ebp 4/r32/esp +7160 # setup +7161 (clear-stream _test-output-stream) +7162 (clear-stream $_test-output-buffered-file->buffer) +7163 # var type/ecx: (handle tree type-id) = int +7164 68/push 0/imm32/right/null +7165 68/push 1/imm32/left/int +7166 89/<- %ecx 4/r32/esp +7167 # var var-var1/ecx: var in eax +7168 68/push "eax"/imm32/register +7169 68/push 0/imm32/no-stack-offset +7170 68/push 1/imm32/block-depth +7171 51/push-ecx +7172 68/push "var1"/imm32 +7173 89/<- %ecx 4/r32/esp +7174 # var var-var2/edx: var +7175 68/push 0/imm32/no-register +7176 68/push 8/imm32/stack-offset +7177 68/push 1/imm32/block-depth +7178 ff 6/subop/push *(ecx+4) # Var-type +7179 68/push "var2"/imm32 +7180 89/<- %edx 4/r32/esp +7181 # var inouts/esi: (list var2) +7182 68/push 0/imm32/next +7183 52/push-edx/var-var2 +7184 89/<- %esi 4/r32/esp +7185 # var outputs/edi: (list var1) +7186 68/push 0/imm32/next +7187 51/push-ecx/var-var1 +7188 89/<- %edi 4/r32/esp +7189 # var stmt/esi: statement +7190 68/push 0/imm32/next +7191 57/push-edi/outputs +7192 56/push-esi/inouts +7193 68/push "add"/imm32/operation +7194 68/push 1/imm32 +7195 89/<- %esi 4/r32/esp +7196 # convert +7197 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +7198 (flush _test-output-buffered-file) +7199 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7205 # check output +7206 (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x00000008) 0x00000000/r32" "F - test-add-mem-to-reg") +7207 # . epilogue +7208 89/<- %esp 5/r32/ebp +7209 5d/pop-to-ebp +7210 c3/return +7211 +7212 test-add-literal-to-eax: +7213 # var1/eax <- add 0x34 +7214 # => +7215 # 05/add-to-eax 0x34/imm32 +7216 # +7217 # . prologue +7218 55/push-ebp +7219 89/<- %ebp 4/r32/esp +7220 # setup +7221 (clear-stream _test-output-stream) +7222 (clear-stream $_test-output-buffered-file->buffer) +7223 # var type/ecx: (handle tree type-id) = int +7224 68/push 0/imm32/right/null +7225 68/push 1/imm32/left/int +7226 89/<- %ecx 4/r32/esp +7227 # var var-var1/ecx: var in eax +7228 68/push "eax"/imm32/register +7229 68/push 0/imm32/no-stack-offset +7230 68/push 1/imm32/block-depth +7231 51/push-ecx +7232 68/push "var1"/imm32 +7233 89/<- %ecx 4/r32/esp +7234 # var type/edx: (handle tree type-id) = literal +7235 68/push 0/imm32/right/null +7236 68/push 0/imm32/left/literal +7237 89/<- %edx 4/r32/esp +7238 # var var-var2/edx: var literal +7239 68/push 0/imm32/no-register +7240 68/push 0/imm32/no-stack-offset +7241 68/push 1/imm32/block-depth +7242 52/push-edx +7243 68/push "0x34"/imm32 +7244 89/<- %edx 4/r32/esp +7245 # var inouts/esi: (list var2) +7246 68/push 0/imm32/next +7247 52/push-edx/var-var2 +7248 89/<- %esi 4/r32/esp +7249 # var outputs/edi: (list var1) +7250 68/push 0/imm32/next +7251 51/push-ecx/var-var1 +7252 89/<- %edi 4/r32/esp +7253 # var stmt/esi: statement +7254 68/push 0/imm32/next +7255 57/push-edi/outputs +7256 56/push-esi/inouts +7257 68/push "add"/imm32/operation +7258 68/push 1/imm32 +7259 89/<- %esi 4/r32/esp +7260 # convert +7261 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +7262 (flush _test-output-buffered-file) +7263 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7269 # check output +7270 (check-next-stream-line-equal _test-output-stream "05/add-to-eax 0x34/imm32" "F - test-add-literal-to-eax") +7271 # . epilogue +7272 89/<- %esp 5/r32/ebp +7273 5d/pop-to-ebp +7274 c3/return +7275 +7276 test-add-literal-to-reg: +7277 # var1/ecx <- add 0x34 +7278 # => +7279 # 81 0/subop/add %ecx 0x34/imm32 +7280 # +7281 # . prologue +7282 55/push-ebp +7283 89/<- %ebp 4/r32/esp +7284 # setup +7285 (clear-stream _test-output-stream) +7286 (clear-stream $_test-output-buffered-file->buffer) +7287 # var type/ecx: (handle tree type-id) = int +7288 68/push 0/imm32/right/null +7289 68/push 1/imm32/left/int +7290 89/<- %ecx 4/r32/esp +7291 # var var-var1/ecx: var in ecx +7292 68/push "ecx"/imm32/register +7293 68/push 0/imm32/no-stack-offset +7294 68/push 1/imm32/block-depth +7295 51/push-ecx +7296 68/push "var1"/imm32 +7297 89/<- %ecx 4/r32/esp +7298 # var type/edx: (handle tree type-id) = literal +7299 68/push 0/imm32/right/null +7300 68/push 0/imm32/left/literal +7301 89/<- %edx 4/r32/esp +7302 # var var-var2/edx: var literal +7303 68/push 0/imm32/no-register +7304 68/push 0/imm32/no-stack-offset +7305 68/push 1/imm32/block-depth +7306 52/push-edx +7307 68/push "0x34"/imm32 +7308 89/<- %edx 4/r32/esp +7309 # var inouts/esi: (list var2) +7310 68/push 0/imm32/next +7311 52/push-edx/var-var2 +7312 89/<- %esi 4/r32/esp +7313 # var outputs/edi: (list var1) +7314 68/push 0/imm32/next +7315 51/push-ecx/var-var1 +7316 89/<- %edi 4/r32/esp +7317 # var stmt/esi: statement +7318 68/push 0/imm32/next +7319 57/push-edi/outputs +7320 56/push-esi/inouts +7321 68/push "add"/imm32/operation +7322 68/push 1/imm32 +7323 89/<- %esi 4/r32/esp +7324 # convert +7325 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +7326 (flush _test-output-buffered-file) +7327 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7333 # check output +7334 (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ecx 0x34/imm32" "F - test-add-literal-to-reg") +7335 # . epilogue +7336 89/<- %esp 5/r32/ebp +7337 5d/pop-to-ebp +7338 c3/return +7339 +7340 test-add-literal-to-mem: +7341 # add-to var1, 0x34 +7342 # => +7343 # 81 0/subop/add %eax 0x34/imm32 +7344 # +7345 # . prologue +7346 55/push-ebp +7347 89/<- %ebp 4/r32/esp +7348 # setup +7349 (clear-stream _test-output-stream) +7350 (clear-stream $_test-output-buffered-file->buffer) +7351 # var type/ecx: (handle tree type-id) = int +7352 68/push 0/imm32/right/null +7353 68/push 1/imm32/left/int +7354 89/<- %ecx 4/r32/esp +7355 # var var-var1/ecx: var +7356 68/push 0/imm32/no-register +7357 68/push 8/imm32/stack-offset +7358 68/push 1/imm32/block-depth +7359 51/push-ecx +7360 68/push "var1"/imm32 +7361 89/<- %ecx 4/r32/esp +7362 # var type/edx: (handle tree type-id) = literal +7363 68/push 0/imm32/right/null +7364 68/push 0/imm32/left/literal +7365 89/<- %edx 4/r32/esp +7366 # var var-var2/edx: var literal +7367 68/push 0/imm32/no-register +7368 68/push 0/imm32/no-stack-offset +7369 68/push 1/imm32/block-depth +7370 52/push-edx +7371 68/push "0x34"/imm32 +7372 89/<- %edx 4/r32/esp +7373 # var inouts/esi: (list var2) +7374 68/push 0/imm32/next +7375 52/push-edx/var-var2 +7376 89/<- %esi 4/r32/esp +7377 # var inouts = (list var1 inouts) +7378 56/push-esi/next +7379 51/push-ecx/var-var1 +7380 89/<- %esi 4/r32/esp +7381 # var stmt/esi: statement +7382 68/push 0/imm32/next +7383 68/push 0/imm32/outputs +7384 56/push-esi/inouts +7385 68/push "add-to"/imm32/operation +7386 68/push 1/imm32 +7387 89/<- %esi 4/r32/esp +7388 # convert +7389 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +7390 (flush _test-output-buffered-file) +7391 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7397 # check output +7398 (check-next-stream-line-equal _test-output-stream "81 0/subop/add *(ebp+0x00000008) 0x34/imm32" "F - test-add-literal-to-mem") +7399 # . epilogue +7400 89/<- %esp 5/r32/ebp +7401 5d/pop-to-ebp +7402 c3/return +7403 +7404 test-compare-mem-with-reg: +7405 # compare var1, var2/eax +7406 # => +7407 # 39/compare *(ebp+___) 0/r32/eax +7408 # +7409 # . prologue +7410 55/push-ebp +7411 89/<- %ebp 4/r32/esp +7412 # setup +7413 (clear-stream _test-output-stream) +7414 (clear-stream $_test-output-buffered-file->buffer) +7415 # var type/ecx: (handle tree type-id) = int +7416 68/push 0/imm32/right/null +7417 68/push 1/imm32/left/int +7418 89/<- %ecx 4/r32/esp +7419 # var var-var2/ecx: var in eax +7420 68/push "eax"/imm32/register +7421 68/push 0/imm32/no-stack-offset +7422 68/push 1/imm32/block-depth +7423 51/push-ecx +7424 68/push "var2"/imm32 +7425 89/<- %ecx 4/r32/esp +7426 # var var-var1/edx: var +7427 68/push 0/imm32/no-register +7428 68/push 8/imm32/stack-offset +7429 68/push 1/imm32/block-depth +7430 ff 6/subop/push *(ecx+4) # Var-type +7431 68/push "var1"/imm32 +7432 89/<- %edx 4/r32/esp +7433 # var inouts/esi: (list var1 var2) +7434 68/push 0/imm32/next +7435 51/push-ecx/var-var2 +7436 89/<- %esi 4/r32/esp +7437 56/push-esi +7438 52/push-edx/var-var1 +7439 89/<- %esi 4/r32/esp +7440 # var stmt/esi: statement +7441 68/push 0/imm32/next +7442 68/push 0/imm32/outputs +7443 56/push-esi/inouts +7444 68/push "compare"/imm32/operation +7445 68/push 1/imm32 +7446 89/<- %esi 4/r32/esp +7447 # convert +7448 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +7449 (flush _test-output-buffered-file) +7450 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7456 # check output +7457 (check-next-stream-line-equal _test-output-stream "39/compare *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-mem-with-reg") +7458 # . epilogue +7459 89/<- %esp 5/r32/ebp +7460 5d/pop-to-ebp +7461 c3/return +7462 +7463 test-compare-reg-with-mem: +7464 # compare var1/eax, var2 +7465 # => +7466 # 3b/compare *(ebp+___) 0/r32/eax +7467 # +7468 # . prologue +7469 55/push-ebp +7470 89/<- %ebp 4/r32/esp +7471 # setup +7472 (clear-stream _test-output-stream) +7473 (clear-stream $_test-output-buffered-file->buffer) +7474 # var type/ecx: (handle tree type-id) = int +7475 68/push 0/imm32/right/null +7476 68/push 1/imm32/left/int +7477 89/<- %ecx 4/r32/esp +7478 # var var-var1/ecx: var in eax +7479 68/push "eax"/imm32/register +7480 68/push 0/imm32/no-stack-offset +7481 68/push 1/imm32/block-depth +7482 51/push-ecx +7483 68/push "var1"/imm32 +7484 89/<- %ecx 4/r32/esp +7485 # var var-var2/edx: var +7486 68/push 0/imm32/no-register +7487 68/push 8/imm32/stack-offset +7488 68/push 1/imm32/block-depth +7489 ff 6/subop/push *(ecx+4) # Var-type +7490 68/push "var2"/imm32 +7491 89/<- %edx 4/r32/esp +7492 # var inouts/esi: (list var1 var2) +7493 68/push 0/imm32/next +7494 52/push-edx/var-var2 +7495 89/<- %esi 4/r32/esp +7496 56/push-esi +7497 51/push-ecx/var-var1 +7498 89/<- %esi 4/r32/esp +7499 # var stmt/esi: statement +7500 68/push 0/imm32/next +7501 68/push 0/imm32/outputs +7502 56/push-esi/inouts +7503 68/push "compare"/imm32/operation +7504 68/push 1/imm32 +7505 89/<- %esi 4/r32/esp +7506 # convert +7507 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +7508 (flush _test-output-buffered-file) +7509 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7515 # check output +7516 (check-next-stream-line-equal _test-output-stream "3b/compare *(ebp+0x00000008) 0x00000000/r32" "F - test-compare-reg-with-mem") +7517 # . epilogue +7518 89/<- %esp 5/r32/ebp +7519 5d/pop-to-ebp +7520 c3/return +7521 +7522 test-compare-mem-with-literal: +7523 # compare var1, 0x34 +7524 # => +7525 # 81 7/subop/compare *(ebp+___) 0x34/imm32 +7526 # +7527 # . prologue +7528 55/push-ebp +7529 89/<- %ebp 4/r32/esp +7530 # setup +7531 (clear-stream _test-output-stream) +7532 (clear-stream $_test-output-buffered-file->buffer) +7533 # var type/ecx: (handle tree type-id) = int +7534 68/push 0/imm32/right/null +7535 68/push 1/imm32/left/int +7536 89/<- %ecx 4/r32/esp +7537 # var var-var1/ecx: var +7538 68/push 0/imm32/no-register +7539 68/push 8/imm32/stack-offset +7540 68/push 1/imm32/block-depth +7541 51/push-ecx +7542 68/push "var1"/imm32 +7543 89/<- %ecx 4/r32/esp +7544 # var type/edx: (handle tree type-id) = literal +7545 68/push 0/imm32/right/null +7546 68/push 0/imm32/left/literal +7547 89/<- %edx 4/r32/esp +7548 # var var-var2/edx: var literal +7549 68/push 0/imm32/no-register +7550 68/push 0/imm32/no-stack-offset +7551 68/push 1/imm32/block-depth +7552 52/push-edx +7553 68/push "0x34"/imm32 +7554 89/<- %edx 4/r32/esp +7555 # var inouts/esi: (list var2) +7556 68/push 0/imm32/next +7557 52/push-edx/var-var2 +7558 89/<- %esi 4/r32/esp +7559 # var inouts = (list var1 inouts) +7560 56/push-esi/next +7561 51/push-ecx/var-var1 +7562 89/<- %esi 4/r32/esp +7563 # var stmt/esi: statement +7564 68/push 0/imm32/next +7565 68/push 0/imm32/outputs +7566 56/push-esi/inouts +7567 68/push "compare"/imm32/operation +7568 68/push 1/imm32 +7569 89/<- %esi 4/r32/esp +7570 # convert +7571 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +7572 (flush _test-output-buffered-file) +7573 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7579 # check output +7580 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare *(ebp+0x00000008) 0x34/imm32" "F - test-compare-mem-with-literal") +7581 # . epilogue +7582 89/<- %esp 5/r32/ebp +7583 5d/pop-to-ebp +7584 c3/return +7585 +7586 test-compare-eax-with-literal: +7587 # compare var1/eax 0x34 +7588 # => +7589 # 3d/compare-eax-with 0x34/imm32 +7590 # +7591 # . prologue +7592 55/push-ebp +7593 89/<- %ebp 4/r32/esp +7594 # setup +7595 (clear-stream _test-output-stream) +7596 (clear-stream $_test-output-buffered-file->buffer) +7597 # var type/ecx: (handle tree type-id) = int +7598 68/push 0/imm32/right/null +7599 68/push 1/imm32/left/int +7600 89/<- %ecx 4/r32/esp +7601 # var var-var1/ecx: var in eax +7602 68/push "eax"/imm32/register +7603 68/push 0/imm32/no-stack-offset +7604 68/push 1/imm32/block-depth +7605 51/push-ecx +7606 68/push "var1"/imm32 +7607 89/<- %ecx 4/r32/esp +7608 # var type/edx: (handle tree type-id) = literal +7609 68/push 0/imm32/right/null +7610 68/push 0/imm32/left/literal +7611 89/<- %edx 4/r32/esp +7612 # var var-var2/edx: var literal +7613 68/push 0/imm32/no-register +7614 68/push 0/imm32/no-stack-offset +7615 68/push 1/imm32/block-depth +7616 52/push-edx +7617 68/push "0x34"/imm32 +7618 89/<- %edx 4/r32/esp +7619 # var inouts/esi: (list var2) +7620 68/push 0/imm32/next +7621 52/push-edx/var-var2 +7622 89/<- %esi 4/r32/esp +7623 # var inouts = (list var1 inouts) +7624 56/push-esi/next +7625 51/push-ecx/var-var1 +7626 89/<- %esi 4/r32/esp +7627 # var stmt/esi: statement +7628 68/push 0/imm32/next +7629 68/push 0/imm32/outputs +7630 56/push-esi/inouts +7631 68/push "compare"/imm32/operation +7632 68/push 1/imm32/regular-stmt +7633 89/<- %esi 4/r32/esp +7634 # convert +7635 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +7636 (flush _test-output-buffered-file) +7637 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7643 # check output +7644 (check-next-stream-line-equal _test-output-stream "3d/compare-eax-with 0x34/imm32" "F - test-compare-eax-with-literal") +7645 # . epilogue +7646 89/<- %esp 5/r32/ebp +7647 5d/pop-to-ebp +7648 c3/return +7649 +7650 test-compare-reg-with-literal: +7651 # compare var1/ecx 0x34 +7652 # => +7653 # 81 7/subop/compare %ecx 0x34/imm32 +7654 # +7655 # . prologue +7656 55/push-ebp +7657 89/<- %ebp 4/r32/esp +7658 # setup +7659 (clear-stream _test-output-stream) +7660 (clear-stream $_test-output-buffered-file->buffer) +7661 # var type/ecx: (handle tree type-id) = int +7662 68/push 0/imm32/right/null +7663 68/push 1/imm32/left/int +7664 89/<- %ecx 4/r32/esp +7665 # var var-var1/ecx: var in ecx +7666 68/push "ecx"/imm32/register +7667 68/push 0/imm32/no-stack-offset +7668 68/push 1/imm32/block-depth +7669 51/push-ecx +7670 68/push "var1"/imm32 +7671 89/<- %ecx 4/r32/esp +7672 # var type/edx: (handle tree type-id) = literal +7673 68/push 0/imm32/right/null +7674 68/push 0/imm32/left/literal +7675 89/<- %edx 4/r32/esp +7676 # var var-var2/edx: var literal +7677 68/push 0/imm32/no-register +7678 68/push 0/imm32/no-stack-offset +7679 68/push 1/imm32/block-depth +7680 52/push-edx +7681 68/push "0x34"/imm32 +7682 89/<- %edx 4/r32/esp +7683 # var inouts/esi: (list var2) +7684 68/push 0/imm32/next +7685 52/push-edx/var-var2 +7686 89/<- %esi 4/r32/esp +7687 # var inouts = (list var1 inouts) +7688 56/push-esi/next +7689 51/push-ecx/var-var1 +7690 89/<- %esi 4/r32/esp +7691 # var stmt/esi: statement +7692 68/push 0/imm32/next +7693 68/push 0/imm32/outputs +7694 56/push-esi/inouts +7695 68/push "compare"/imm32/operation +7696 68/push 1/imm32/regular-stmt +7697 89/<- %esi 4/r32/esp +7698 # convert +7699 (emit-subx-statement _test-output-buffered-file %esi Primitives 0) +7700 (flush _test-output-buffered-file) +7701 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7707 # check output +7708 (check-next-stream-line-equal _test-output-stream "81 7/subop/compare %ecx 0x34/imm32" "F - test-compare-reg-with-literal") +7709 # . epilogue +7710 89/<- %esp 5/r32/ebp +7711 5d/pop-to-ebp +7712 c3/return +7713 +7714 test-emit-subx-statement-function-call: +7715 # Call a function on a variable on the stack. +7716 # f foo +7717 # => +7718 # (f2 *(ebp-8)) +7719 # (Changing the function name supports overloading in general, but here it +7720 # just serves to help disambiguate things.) +7721 # +7722 # There's a variable on the var stack as follows: +7723 # name: 'foo' +7724 # type: int +7725 # stack-offset: -8 +7726 # +7727 # There's nothing in primitives. +7728 # +7729 # There's a function with this info: +7730 # name: 'f' +7731 # inout: int/mem +7732 # value: 'f2' +7733 # +7734 # . prologue +7735 55/push-ebp +7736 89/<- %ebp 4/r32/esp +7737 # setup +7738 (clear-stream _test-output-stream) +7739 (clear-stream $_test-output-buffered-file->buffer) +7740 # var type/ecx: (handle tree type-id) = int +7741 68/push 0/imm32/right/null +7742 68/push 1/imm32/left/int +7743 89/<- %ecx 4/r32/esp +7744 # var var-foo/ecx: var +7745 68/push 0/imm32/no-register +7746 68/push -8/imm32/stack-offset +7747 68/push 0/imm32/block-depth +7748 51/push-ecx +7749 68/push "foo"/imm32 +7750 89/<- %ecx 4/r32/esp +7751 # var operands/esi: (list var) +7752 68/push 0/imm32/next +7753 51/push-ecx/var-foo +7754 89/<- %esi 4/r32/esp +7755 # var stmt/esi: statement +7756 68/push 0/imm32/next +7757 68/push 0/imm32/outputs +7758 56/push-esi/inouts +7759 68/push "f"/imm32/operation +7760 68/push 1/imm32 +7761 89/<- %esi 4/r32/esp +7762 # var functions/ebx: function +7763 68/push 0/imm32/next +7764 68/push 0/imm32/body +7765 68/push 0/imm32/outputs +7766 51/push-ecx/inouts # hack; in practice we won't have the same var in function definition and call +7767 68/push "f2"/imm32/subx-name +7768 68/push "f"/imm32/name +7769 89/<- %ebx 4/r32/esp +7770 # convert +7771 (emit-subx-statement _test-output-buffered-file %esi 0 %ebx) +7772 (flush _test-output-buffered-file) +7773 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7779 # check output +7780 (check-next-stream-line-equal _test-output-stream "(f2 *(ebp+0xfffffff8))" "F - test-emit-subx-statement-function-call") +7781 # . epilogue +7782 89/<- %esp 5/r32/ebp +7783 5d/pop-to-ebp +7784 c3/return +7785 +7786 test-emit-subx-statement-function-call-with-literal-arg: +7787 # Call a function on a literal. +7788 # f 34 +7789 # => +7790 # (f2 34) +7791 # +7792 # . prologue +7793 55/push-ebp +7794 89/<- %ebp 4/r32/esp +7795 # setup +7796 (clear-stream _test-output-stream) +7797 (clear-stream $_test-output-buffered-file->buffer) +7798 # var type/ecx: (handle tree type-id) = literal +7799 68/push 0/imm32/right/null +7800 68/push 0/imm32/left/literal +7801 89/<- %ecx 4/r32/esp +7802 # var var-foo/ecx: var literal +7803 68/push 0/imm32/no-register +7804 68/push 0/imm32/no-stack-offset +7805 68/push 0/imm32/block-depth +7806 51/push-ecx +7807 68/push "34"/imm32 +7808 89/<- %ecx 4/r32/esp +7809 # var operands/esi: (list var) +7810 68/push 0/imm32/next +7811 51/push-ecx/var-foo +7812 89/<- %esi 4/r32/esp +7813 # var stmt/esi: statement +7814 68/push 0/imm32/next +7815 68/push 0/imm32/outputs +7816 56/push-esi/inouts +7817 68/push "f"/imm32/operation +7818 68/push 1/imm32 +7819 89/<- %esi 4/r32/esp +7820 # var functions/ebx: function +7821 68/push 0/imm32/next +7822 68/push 0/imm32/body +7823 68/push 0/imm32/outputs +7824 51/push-ecx/inouts # hack; in practice we won't have the same var in function definition and call +7825 68/push "f2"/imm32/subx-name +7826 68/push "f"/imm32/name +7827 89/<- %ebx 4/r32/esp +7828 # convert +7829 (emit-subx-statement _test-output-buffered-file %esi 0 %ebx) +7830 (flush _test-output-buffered-file) +7831 +-- 6 lines: #? # dump _test-output-stream -------------------------------------------------------------------------------------------------------------- +7837 # check output +7838 (check-next-stream-line-equal _test-output-stream "(f2 34)" "F - test-emit-subx-statement-function-call-with-literal-arg") +7839 # . epilogue +7840 89/<- %esp 5/r32/ebp +7841 5d/pop-to-ebp +7842 c3/return +7843 +7844 emit-subx-prologue: # out: (addr buffered-file) +7845 # . prologue +7846 55/push-ebp +7847 89/<- %ebp 4/r32/esp +7848 # +7849 (write-buffered *(ebp+8) "# . prologue\n") +7850 (write-buffered *(ebp+8) "55/push-ebp\n") +7851 (write-buffered *(ebp+8) "89/<- %ebp 4/r32/esp\n") +7852 $emit-subx-prologue:end: +7853 # . epilogue +7854 89/<- %esp 5/r32/ebp +7855 5d/pop-to-ebp +7856 c3/return +7857 +7858 emit-subx-epilogue: # out: (addr buffered-file) +7859 # . prologue +7860 55/push-ebp +7861 89/<- %ebp 4/r32/esp +7862 # +7863 (write-buffered *(ebp+8) "# . epilogue\n") +7864 (write-buffered *(ebp+8) "89/<- %esp 5/r32/ebp\n") +7865 (write-buffered *(ebp+8) "5d/pop-to-ebp\n") +7866 (write-buffered *(ebp+8) "c3/return\n") +7867 $emit-subx-epilogue:end: +7868 # . epilogue +7869 89/<- %esp 5/r32/ebp +7870 5d/pop-to-ebp +7871 c3/return -- cgit 1.4.1-2-gfad0