diff --git a/apps/mu b/apps/mu
index 9cd19eb8..d77798f9 100755
Binary files a/apps/mu and b/apps/mu differ
diff --git a/apps/mu.subx b/apps/mu.subx
index ddac7bb8..9a54e06e 100644
--- a/apps/mu.subx
+++ b/apps/mu.subx
@@ -1086,19 +1086,6 @@ $emit-subx-imm32:end:
5d/pop-to-ebp
c3/return
-#? # var args/ecx : (list var) = stmt->inouts
-#? 8b/-> *(ebp+0xc) 1/r32/ecx
-#? 8b/-> *(ecx+4) 1/r32/ecx # Stmt-inouts
-#? {
-#? # if (curr == null) break
-#? 81 7/subop/compare %ecx 0/imm32
-#? 74/jump-if-equal break/disp8
-#? #
-#? (emit-subx-call-operand *(ebp+8) *ecx)
-#? # args = args->next
-#? 8b/-> *(ecx+4) 1/r32/ecx
-#? }
-
emit-subx-call: # out : (address buffered-file), stmt : (address statement), vars : (address variable), callee : (address function)
# . prologue
55/push-ebp
@@ -1213,6 +1200,7 @@ find-matching-primitive: # primitives : (address primitive), stmt : (address st
# var curr/ecx : (address primitive) = primitives
8b/-> *(ebp+8) 1/r32/ecx
{
+$find-matching-primitive:loop:
# if (curr == null) break
81 7/subop/compare %ecx 0/imm32
74/jump-if-equal break/disp8
@@ -1224,8 +1212,9 @@ find-matching-primitive: # primitives : (address primitive), stmt : (address st
89/<- %eax 1/r32/ecx
eb/jump $find-matching-function:end/disp8
}
+$find-matching-primitive:next-primitive:
# curr = curr->next
- 8b/-> *(ecx+0x18) 1/r32/ecx # Primitive-next
+ 8b/-> *(ecx+0x1c) 1/r32/ecx # Primitive-next
eb/jump loop/disp8
}
# return null
@@ -1257,23 +1246,219 @@ $mu-stmt-matches-function?:end:
c3/return
mu-stmt-matches-primitive?: # stmt : (address statement), primitive : (address primitive) => result/eax : boolean
+ # A mu stmt matches a primitive if the name matches, all the inout vars
+ # match, and all the output vars match.
+ # Vars match if types match and registers match.
+ # In addition, a stmt output matches a primitive's output if types match
+ # and the primitive has a wildcard register.
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# . save registers
51/push-ecx
- # return primitive->name == stmt->operation
+ 52/push-edx
+ 53/push-ebx
+ 56/push-esi
+ 57/push-edi
+ # ecx = stmt
8b/-> *(ebp+8) 1/r32/ecx
- 8b/-> *(ebp+0xc) 0/r32/eax
- (string-equal? *ecx *eax) # => eax
+ # edx = primitive
+ 8b/-> *(ebp+0xc) 2/r32/edx
+ {
+$mu-stmt-matches-primitive?:check-name:
+ # if (primitive->name != stmt->operation) return false
+ (string-equal? *ecx *edx) # => eax
+ 3d/compare-eax-and 0/imm32
+ 75/jump-if-not-equal break/disp8
+ b8/copy-to-eax 0/imm32
+ e9/jump $mu-stmt-matches-primitive?:end/disp32
+ }
+$mu-stmt-matches-primitive?:check-inouts:
+ # curr = stmt->inouts
+ 8b/-> *(ecx+4) 6/r32/esi # Stmt-inouts
+ # curr2 = primitive->inouts
+ 8b/-> *(edx+4) 7/r32/edi # Primitive-inouts
+ {
+ # if (curr == 0) return (curr2 == 0)
+ {
+ 81 7/subop/compare %esi 0/imm32
+ 75/jump-if-not-equal break/disp8
+ {
+ 81 7/subop/compare %edi 0/imm32
+ 75/jump-if-not-equal break/disp8
+ # return true
+ b8/copy-to-eax 1/imm32
+ e9/jump $mu-stmt-matches-primitive?:end/disp32
+ }
+ # return false
+ b8/copy-to-eax 0/imm32
+ e9/jump $mu-stmt-matches-primitive?:end/disp32
+ }
+ # if (curr2 == 0) return false
+ {
+ 81 7/subop/compare %edi 0/imm32
+ 75/jump-if-not-equal break/disp8
+ b8/copy-to-eax 0/imm32
+ e9/jump $mu-stmt-matches-primitive?:end/disp32
+ }
+ # if (curr != curr2) return false
+ {
+ (operand-matches-primitive? *esi *edi) # => eax
+ 3d/compare-eax-and 0/imm32
+ 75/jump-if-not-equal break/disp8
+ b8/copy-to-eax 0/imm32
+ e9/jump $mu-stmt-matches-primitive?:end/disp32
+ }
+ # curr=curr->next
+ 8b/-> *(ecx+4) 1/r32/ecx # Operand-next
+ # curr2=curr2->next
+ 8b/-> *(edx+4) 2/r32/edx # Operand-next
+ }
+$mu-stmt-matches-primitive?:check-outputs:
+ # ecx = stmt
+ 8b/-> *(ebp+8) 1/r32/ecx
+ # edx = primitive
+ 8b/-> *(ebp+0xc) 2/r32/edx
+ # curr = stmt->outputs
+ 8b/-> *(ecx+8) 6/r32/esi # Stmt-outputs
+ # curr2 = primitive->outputs
+ 8b/-> *(edx+8) 7/r32/edi # Primitive-outputs
+ {
+ # if (curr == 0) return (curr2 == 0)
+ {
+ 81 7/subop/compare %esi 0/imm32
+ 75/jump-if-not-equal break/disp8
+ {
+ 81 7/subop/compare %edi 0/imm32
+ 75/jump-if-not-equal break/disp8
+ # return true
+ b8/copy-to-eax 1/imm32
+ e9/jump $mu-stmt-matches-primitive?:end/disp32
+ }
+ # return false
+ b8/copy-to-eax 0/imm32
+ e9/jump $mu-stmt-matches-primitive?:end/disp32
+ }
+ # if (curr2 == 0) return false
+ {
+ 81 7/subop/compare %edi 0/imm32
+ 75/jump-if-not-equal break/disp8
+ b8/copy-to-eax 0/imm32
+ e9/jump $mu-stmt-matches-primitive?:end/disp32
+ }
+ # if (curr != curr2) return false
+ {
+ (output-operand-matches-primitive? *esi *edi) # => eax
+ 3d/compare-eax-and 0/imm32
+ 75/jump-if-not-equal break/disp8
+ b8/copy-to-eax 0/imm32
+ e9/jump $mu-stmt-matches-primitive?:end/disp32
+ }
+ # curr=curr->next
+ 8b/-> *(ecx+4) 1/r32/ecx # Operand-next
+ # curr2=curr2->next
+ 8b/-> *(edx+4) 2/r32/edx # Operand-next
+ }
+$mu-stmt-matches-primitive?:return-true:
+ b8/copy-to-eax 1/imm32
$mu-stmt-matches-primitive?:end:
# . restore registers
+ 5f/pop-to-edi
+ 5e/pop-to-esi
+ 5b/pop-to-ebx
+ 5a/pop-to-edx
59/pop-to-ecx
# . epilogue
89/<- %esp 5/r32/ebp
5d/pop-to-ebp
c3/return
+operand-matches-primitive?: # var1 : (address var), var2 : (address var) => result/eax : boolean
+ # . prologue
+ 55/push-ebp
+ 89/<- %ebp 4/r32/esp
+ # . save registers
+ 56/push-esi
+ 57/push-edi
+ # esi = var1
+ 8b/-> *(ebp+8) 6/r32/esi
+ # edi = var2
+ 8b/-> *(ebp+0xc) 7/r32/edi
+ # if (var1->type != var2->type) return false
+ # if (var1->register != var1->register) return false
+ {
+ # if addresses are equal, don't return here
+ 8b/-> *(esi+0x10) 0/r32/eax
+ 39/compare *(edi+0x10) 0/r32/eax
+ 74/jump-if-equal break/disp8
+ # if either address is 0, return false
+ 3d/compare-eax-and 0/imm32
+ 74/jump-if-equal $operand-matches-primitive?:end/disp8 # eax goes from meaning var1->register to result
+ 81 7/subop/compare *(edi+0x10) 0/imm32
+ 74/jump-if-equal $operand-matches-primitive?:end/disp8 # eax goes from meaning var1->register to result
+ # if string contents don't match, return false
+ (string-equal? *(esi+0x10) *(edi+0x10)) # Var-register Var-register
+ 3d/compare-eax-and 0/imm32
+ b8/copy-to-eax 0/imm32/false
+ 74/jump-if-equal $operand-matches-primitive?:end/disp8
+ }
+ # return true
+ b8/copy-to-eax 1/imm32/true
+$operand-matches-primitive?:end:
+ # . restore registers
+ 5f/pop-to-edi
+ 5e/pop-to-esi
+ # . epilogue
+ 89/<- %esp 5/r32/ebp
+ 5d/pop-to-ebp
+ c3/return
+
+# like operand-matches-primitive? but also handles "*" register in primitive
+output-operand-matches-primitive?: # var : (address var), primout-var : (address var) => result/eax : boolean
+ # . prologue
+ 55/push-ebp
+ 89/<- %ebp 4/r32/esp
+ # . save registers
+ 56/push-esi
+ 57/push-edi
+ # esi = var
+ 8b/-> *(ebp+8) 6/r32/esi
+ # edi = primout-var
+ 8b/-> *(ebp+0xc) 7/r32/edi
+ # if (var->type != primout-var->type) return false
+ # return false if var->register doesn't match primout-var->register
+ {
+ # if addresses are equal, don't return here
+ 8b/-> *(esi+0x10) 0/r32/eax
+ 39/compare *(edi+0x10) 0/r32/eax
+ 74/jump-if-equal break/disp8
+ # if either address is 0, return false
+ 3d/compare-eax-and 0/imm32
+ 74/jump-if-equal $operand-matches-primitive?:end/disp8 # eax goes from meaning var->register to result
+ 81 7/subop/compare *(edi+0x10) 0/imm32
+ 74/jump-if-equal $operand-matches-primitive?:end/disp8 # eax goes from meaning var->register to result
+ # if primout-var->register is "*", return true
+ (string-equal? *(edi+0x10) "*") # Var-register
+ 3d/compare-eax-and 0/imm32
+ b8/copy-to-eax 1/imm32/true
+ 75/jump-if-not-equal $operand-matches-primitive?:end/disp8
+ # if string contents don't match, return false
+ (string-equal? *(esi+0x10) *(edi+0x10)) # Var-register Var-register
+ 3d/compare-eax-and 0/imm32
+ b8/copy-to-eax 0/imm32/false
+ 74/jump-if-equal $operand-matches-primitive?:end/disp8
+ }
+ # return true
+ b8/copy-to-eax 1/imm32/true
+$output-operand-matches-primitive?:end:
+ # . restore registers
+ 5f/pop-to-edi
+ 5e/pop-to-esi
+ # . epilogue
+ 89/<- %esp 5/r32/ebp
+ 5d/pop-to-ebp
+ c3/return
+
test-emit-subx-statement-primitive:
# Primitive operation on a variable on the stack.
# increment foo
@@ -1305,21 +1490,25 @@ test-emit-subx-statement-primitive:
68/push 1/imm32/type-int
68/push "foo"/imm32
89/<- %ecx 4/r32/esp
+#? $aa-var-in-ecx:
# vars/edx : (stack 1)
51/push-ecx/var-foo
68/push 1/imm32/data-length
68/push 1/imm32/top
89/<- %edx 4/r32/esp
- # operand/esi : (list var)
+#? $aa-vars-in-edx:
+ # operand/ebx : (list var)
68/push 0/imm32/next
51/push-ecx/var-foo
- 89/<- %esi 4/r32/esp
+ 89/<- %ebx 4/r32/esp
+#? $aa-stmt-operand-in-ebx:
# stmt/esi : statement
68/push 0/imm32/next
68/push 0/imm32/outputs
- 56/push-esi/operands
+ 53/push-ebx/operands
68/push "increment"/imm32/operation
89/<- %esi 4/r32/esp
+#? $aa-stmt-in-esi:
# primitives/ebx : primitive
68/push 0/imm32/next
68/push 0/imm32/no-imm32
@@ -1327,9 +1516,10 @@ test-emit-subx-statement-primitive:
68/push 1/imm32/rm32-is-first-inout
68/push "ff 0/subop/increment"/imm32/subx-name
68/push 0/imm32/outputs
- 51/push-ecx/inouts # hack; in practice we won't have the same var in function definition and call
+ 53/push-ebx/inouts # hack; in practice we won't have the same var in function definition and call
68/push "increment"/imm32/name
89/<- %ebx 4/r32/esp
+$aa-primitive-in-ebx:
# convert
(emit-subx-statement _test-output-buffered-file %esi %edx %ebx 0)
(flush _test-output-buffered-file)
@@ -1361,7 +1551,7 @@ test-emit-subx-statement-primitive-register:
#
# There's a primitive with this info:
# name: 'increment'
- # inout: int/reg
+ # out: int/reg
# value: 'ff 0/subop/increment'
#
# There's nothing in functions.
@@ -1384,13 +1574,13 @@ test-emit-subx-statement-primitive-register:
68/push 1/imm32/data-length
68/push 1/imm32/top
89/<- %edx 4/r32/esp
- # operand/esi : (list var)
+ # operand/ebx : (list var)
68/push 0/imm32/next
51/push-ecx/var-foo
- 89/<- %esi 4/r32/esp
+ 89/<- %ebx 4/r32/esp
# stmt/esi : statement
68/push 0/imm32/next
- 56/push-esi/outputs
+ 53/push-ebx/outputs
68/push 0/imm32/inouts
68/push "increment"/imm32/operation
89/<- %esi 4/r32/esp
@@ -1433,6 +1623,202 @@ test-emit-subx-statement-primitive-register:
5d/pop-to-ebp
c3/return
+test-emit-subx-statement-select-primitive:
+ # Select the right primitive between overloads.
+ # foo <- increment
+ # =>
+ # ff 0/subop/increment %eax # sub-optimal, but should suffice
+ #
+ # There's a variable on the var stack as follows:
+ # name: 'foo'
+ # type: int
+ # register: 'eax'
+ #
+ # There's two primitives, as follows:
+ # - name: 'increment'
+ # out: int/reg
+ # value: 'ff 0/subop/increment'
+ # - name: 'increment'
+ # inout: int/mem
+ # value: 'ff 0/subop/increment'
+ #
+ # There's nothing in functions.
+ #
+ # . prologue
+ 55/push-ebp
+ 89/<- %ebp 4/r32/esp
+ # setup
+ (clear-stream _test-output-stream)
+ (clear-stream _test-output-buffered-file->buffer)
+ # var-foo/ecx : var in eax
+ 68/push "eax"/imm32/register
+ 68/push 0/imm32/no-stack-offset
+ 68/push 1/imm32/block-depth
+ 68/push 1/imm32/type-int
+ 68/push "foo"/imm32
+ 89/<- %ecx 4/r32/esp
+ # vars/edx : (stack 1)
+ 51/push-ecx/var-foo
+ 68/push 1/imm32/data-length
+ 68/push 1/imm32/top
+ 89/<- %edx 4/r32/esp
+ # real-outputs/edi : (list var)
+ 68/push 0/imm32/next
+ 51/push-ecx/var-foo
+ 89/<- %edi 4/r32/esp
+ # stmt/esi : statement
+ 68/push 0/imm32/next
+ 57/push-edi/outputs
+ 68/push 0/imm32/inouts
+ 68/push "increment"/imm32/operation
+ 89/<- %esi 4/r32/esp
+ # formal-var/ebx : var in any register
+ 68/push Any-register/imm32
+ 68/push 0/imm32/no-stack-offset
+ 68/push 1/imm32/block-depth
+ 68/push 1/imm32/type-int
+ 68/push "dummy"/imm32
+ 89/<- %ebx 4/r32/esp
+ # formal-outputs/ebx : (list var)
+ 68/push 0/imm32/next
+ 53/push-ebx/formal-var
+ 89/<- %ebx 4/r32/esp
+ # primitive1/ebx : primitive
+ 68/push 0/imm32/next
+ 68/push 0/imm32/no-imm32
+ 68/push 0/imm32/no-r32
+ 68/push 3/imm32/rm32-in-first-output
+ 68/push "ff 0/subop/increment"/imm32/subx-name
+ 53/push-ebx/outputs/formal-outputs
+ 68/push 0/imm32/inouts
+ 68/push "increment"/imm32/name
+ 89/<- %ebx 4/r32/esp
+ # primitives/ebx : primitive
+ 53/push-ebx/next
+ 68/push 0/imm32/no-imm32
+ 68/push 0/imm32/no-r32
+ 68/push 1/imm32/rm32-is-first-inout
+ 68/push "ff 0/subop/increment"/imm32/subx-name
+ 68/push 0/imm32/outputs
+ 57/push-edi/inouts/real-outputs # hack; in practice we won't have the same var in function definition and call
+ 68/push "increment"/imm32/name
+ 89/<- %ebx 4/r32/esp
+ # convert
+ (emit-subx-statement _test-output-buffered-file %esi %edx %ebx 0)
+ (flush _test-output-buffered-file)
+#? # dump _test-output-stream {{{
+#? (write 2 "^")
+#? (write-stream 2 _test-output-stream)
+#? (write 2 "$\n")
+#? (rewind-stream _test-output-stream)
+#? # }}}
+ # check output
+ (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive/0")
+ # . reclaim locals
+ 81 0/subop/add %esp 0x48/imm32
+ # . epilogue
+ 89/<- %esp 5/r32/ebp
+ 5d/pop-to-ebp
+ c3/return
+
+test-emit-subx-statement-select-primitive-2:
+ # Select the right primitive between overloads.
+ # foo <- increment
+ # =>
+ # ff 0/subop/increment %eax # sub-optimal, but should suffice
+ #
+ # There's a variable on the var stack as follows:
+ # name: 'foo'
+ # type: int
+ # register: 'eax'
+ #
+ # There's two primitives, as follows:
+ # - name: 'increment'
+ # out: int/reg
+ # value: 'ff 0/subop/increment'
+ # - name: 'increment'
+ # inout: int/mem
+ # value: 'ff 0/subop/increment'
+ #
+ # There's nothing in functions.
+ #
+ # . prologue
+ 55/push-ebp
+ 89/<- %ebp 4/r32/esp
+ # setup
+ (clear-stream _test-output-stream)
+ (clear-stream _test-output-buffered-file->buffer)
+ # var-foo/ecx : var in eax
+ 68/push "eax"/imm32/register
+ 68/push 0/imm32/no-stack-offset
+ 68/push 1/imm32/block-depth
+ 68/push 1/imm32/type-int
+ 68/push "foo"/imm32
+ 89/<- %ecx 4/r32/esp
+ # vars/edx : (stack 1)
+ 51/push-ecx/var-foo
+ 68/push 1/imm32/data-length
+ 68/push 1/imm32/top
+ 89/<- %edx 4/r32/esp
+ # inouts/edi : (list var)
+ 68/push 0/imm32/next
+ 51/push-ecx/var-foo
+ 89/<- %edi 4/r32/esp
+ # stmt/esi : statement
+ 68/push 0/imm32/next
+ 68/push 0/imm32/outputs
+ 57/push-edi/inouts
+ 68/push "increment"/imm32/operation
+ 89/<- %esi 4/r32/esp
+ # formal-var/ebx : var in any register
+ 68/push Any-register/imm32
+ 68/push 0/imm32/no-stack-offset
+ 68/push 1/imm32/block-depth
+ 68/push 1/imm32/type-int
+ 68/push "dummy"/imm32
+ 89/<- %ebx 4/r32/esp
+ # operand/ebx : (list var)
+ 68/push 0/imm32/next
+ 53/push-ebx/formal-var
+ 89/<- %ebx 4/r32/esp
+ # primitive1/ebx : primitive
+ 68/push 0/imm32/next
+ 68/push 0/imm32/no-imm32
+ 68/push 0/imm32/no-r32
+ 68/push 3/imm32/rm32-in-first-output
+ 68/push "ff 0/subop/increment"/imm32/subx-name
+ 53/push-ebx/outputs/formal-outputs
+ 68/push 0/imm32/inouts
+ 68/push "increment"/imm32/name
+ 89/<- %ebx 4/r32/esp
+ # primitives/ebx : primitive
+ 53/push-ebx/next
+ 68/push 0/imm32/no-imm32
+ 68/push 0/imm32/no-r32
+ 68/push 1/imm32/rm32-is-first-inout
+ 68/push "ff 0/subop/increment"/imm32/subx-name
+ 68/push 0/imm32/outputs
+ 57/push-edi/inouts/real-outputs # hack; in practice we won't have the same var in function definition and call
+ 68/push "increment"/imm32/name
+ 89/<- %ebx 4/r32/esp
+ # convert
+ (emit-subx-statement _test-output-buffered-file %esi %edx %ebx 0)
+ (flush _test-output-buffered-file)
+#? # dump _test-output-stream {{{
+#? (write 2 "^")
+#? (write-stream 2 _test-output-stream)
+#? (write 2 "$\n")
+#? (rewind-stream _test-output-stream)
+#? # }}}
+ # check output
+ (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive-2/0")
+ # . reclaim locals
+ 81 0/subop/add %esp 0x48/imm32
+ # . epilogue
+ 89/<- %esp 5/r32/ebp
+ 5d/pop-to-ebp
+ c3/return
+
test-emit-subx-statement-function-call:
# Call a function on a variable on the stack.
# f foo
diff --git a/html/apps/mu.subx.html b/html/apps/mu.subx.html
index a4adfb27..c33a1111 100644
--- a/html/apps/mu.subx.html
+++ b/html/apps/mu.subx.html
@@ -911,9 +911,9 @@ if ('onhashchange' in window) {
870
871 (write-buffered %edi *ecx)
872 (write-buffered %edi ":\n")
- 873 (emit-subx-prologue %edi)
+ 873 (emit-subx-prologue %edi)
874 (emit-subx-block %edi *(ecx+0x10))
- 875 (emit-subx-epilogue %edi)
+ 875 (emit-subx-epilogue %edi)
876 $emit-subx-function:end:
877
878 5f/pop-to-edi
@@ -945,7 +945,7 @@ if ('onhashchange' in window) {
904
905 {
906 $emit-subx-statement:primitive:
- 907 (find-matching-primitive *(ebp+0x14) *(ebp+0xc))
+ 907 (find-matching-primitive *(ebp+0x14) *(ebp+0xc))
908 3d/compare-eax-and 0/imm32
909 74/jump-if-equal break/disp8
910 (emit-subx-primitive *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax)
@@ -954,10 +954,10 @@ if ('onhashchange' in window) {
913
914 {
915 $emit-subx-statement:call:
- 916 (find-matching-function *(ebp+0x18) *(ebp+0xc))
+ 916 (find-matching-function *(ebp+0x18) *(ebp+0xc))
917 3d/compare-eax-and 0/imm32
918 74/jump-if-equal break/disp8
- 919 (emit-subx-call *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax)
+ 919 (emit-subx-call *(ebp+8) *(ebp+0xc) *(ebp+0x10) %eax)
920 e9/jump $emit-subx-statement:end/disp32
921 }
922
@@ -1020,7 +1020,7 @@ if ('onhashchange' in window) {
979 74/jump-if-equal $emit-subx-rm32:end/disp8
980
981 (get-stmt-operand-from-arg-location *(ebp+0x10) *(ebp+0xc))
- 982 (emit-subx-call-operand *(ebp+8) %eax)
+ 982 (emit-subx-call-operand *(ebp+8) %eax)
983 $emit-subx-rm32:end:
984
985 58/pop-to-eax
@@ -1127,440 +1127,816 @@ if ('onhashchange' in window) {
1086 5d/pop-to-ebp
1087 c3/return
1088
-1089
-1090
-1091
-1092
-1093
-1094
-1095
-1096
-1097
-1098
-1099
-1100
-1101
-1102 emit-subx-call:
-1103
-1104 55/push-ebp
-1105 89/<- %ebp 4/r32/esp
-1106
-1107 50/push-eax
-1108 51/push-ecx
-1109
-1110 (write-buffered *(ebp+8) "(")
-1111
-1112 8b/-> *(ebp+0x14) 1/r32/ecx
-1113 (write-buffered *(ebp+8) *(ecx+4))
-1114
-1115
-1116 8b/-> *(ebp+0xc) 1/r32/ecx
-1117 8b/-> *(ecx+4) 1/r32/ecx
-1118 {
-1119
-1120 81 7/subop/compare %ecx 0/imm32
-1121 74/jump-if-equal break/disp8
-1122
-1123 (emit-subx-call-operand *(ebp+8) *ecx)
-1124
-1125 8b/-> *(ecx+4) 1/r32/ecx
-1126 }
-1127
-1128 (write-buffered *(ebp+8) ")")
-1129 $emit-subx-call:end:
-1130
-1131 59/pop-to-ecx
-1132 58/pop-to-eax
-1133
-1134 89/<- %esp 5/r32/ebp
-1135 5d/pop-to-ebp
-1136 c3/return
-1137
-1138 emit-subx-call-operand:
-1139
-1140 55/push-ebp
-1141 89/<- %ebp 4/r32/esp
-1142
-1143 50/push-eax
-1144
-1145 8b/-> *(ebp+0xc) 0/r32/eax
-1146
-1147 {
-1148 81 7/subop/compare *(eax+0x10) 0/imm32
-1149 74/jump-if-equal break/disp8
-1150 $emit-subx-call-operand:register:
-1151 (write-buffered *(ebp+8) " %")
-1152 (write-buffered *(ebp+8) *(eax+0x10))
-1153 }
-1154
-1155 {
-1156 81 7/subop/compare *(eax+0xc) 0/imm32
-1157 74/jump-if-equal break/disp8
-1158 $emit-subx-call-operand:stack:
-1159 (write-buffered *(ebp+8) Space)
-1160 (write-buffered *(ebp+8) "*(ebp+")
-1161 8b/-> *(ebp+0xc) 0/r32/eax
-1162 (print-int32-buffered *(ebp+8) *(eax+0xc))
-1163 (write-buffered *(ebp+8) ")")
-1164 }
-1165 $emit-subx-call-operand:end:
-1166
-1167 58/pop-to-eax
-1168
-1169 89/<- %esp 5/r32/ebp
-1170 5d/pop-to-ebp
-1171 c3/return
-1172
-1173 find-matching-function:
-1174
-1175 55/push-ebp
-1176 89/<- %ebp 4/r32/esp
-1177
-1178 51/push-ecx
-1179
-1180 8b/-> *(ebp+8) 1/r32/ecx
-1181 {
-1182
-1183 81 7/subop/compare %ecx 0/imm32
-1184 74/jump-if-equal break/disp8
-1185
-1186 {
-1187 (mu-stmt-matches-function? *(ebp+0xc) %ecx)
-1188 3d/compare-eax-and 0/imm32
-1189 74/jump-if-equal break/disp8
-1190 89/<- %eax 1/r32/ecx
-1191 eb/jump $find-matching-function:end/disp8
-1192 }
-1193
-1194 8b/-> *(ecx+0x10) 1/r32/ecx
-1195 eb/jump loop/disp8
-1196 }
-1197
-1198 b8/copy-to-eax 0/imm32
-1199 $find-matching-function:end:
-1200
-1201 59/pop-to-ecx
-1202
-1203 89/<- %esp 5/r32/ebp
-1204 5d/pop-to-ebp
-1205 c3/return
-1206
-1207 find-matching-primitive:
-1208
-1209 55/push-ebp
-1210 89/<- %ebp 4/r32/esp
-1211
-1212 51/push-ecx
-1213
-1214 8b/-> *(ebp+8) 1/r32/ecx
-1215 {
-1216
-1217 81 7/subop/compare %ecx 0/imm32
-1218 74/jump-if-equal break/disp8
-1219
-1220 {
-1221 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx)
-1222 3d/compare-eax-and 0/imm32
-1223 74/jump-if-equal break/disp8
-1224 89/<- %eax 1/r32/ecx
-1225 eb/jump $find-matching-function:end/disp8
-1226 }
-1227
-1228 8b/-> *(ecx+0x18) 1/r32/ecx
-1229 eb/jump loop/disp8
-1230 }
-1231
-1232 b8/copy-to-eax 0/imm32
-1233 $find-matching-primitive:end:
-1234
-1235 59/pop-to-ecx
-1236
-1237 89/<- %esp 5/r32/ebp
-1238 5d/pop-to-ebp
-1239 c3/return
-1240
-1241 mu-stmt-matches-function?:
-1242
-1243 55/push-ebp
-1244 89/<- %ebp 4/r32/esp
-1245
-1246 51/push-ecx
-1247
-1248 8b/-> *(ebp+8) 1/r32/ecx
-1249 8b/-> *(ebp+0xc) 0/r32/eax
-1250 (string-equal? *ecx *eax)
-1251 $mu-stmt-matches-function?:end:
-1252
-1253 59/pop-to-ecx
-1254
-1255 89/<- %esp 5/r32/ebp
-1256 5d/pop-to-ebp
-1257 c3/return
-1258
-1259 mu-stmt-matches-primitive?:
-1260
-1261 55/push-ebp
-1262 89/<- %ebp 4/r32/esp
-1263
-1264 51/push-ecx
-1265
-1266 8b/-> *(ebp+8) 1/r32/ecx
-1267 8b/-> *(ebp+0xc) 0/r32/eax
-1268 (string-equal? *ecx *eax)
-1269 $mu-stmt-matches-primitive?:end:
-1270
-1271 59/pop-to-ecx
-1272
-1273 89/<- %esp 5/r32/ebp
-1274 5d/pop-to-ebp
-1275 c3/return
-1276
-1277 test-emit-subx-statement-primitive:
-1278
-1279
-1280
-1281
-1282
-1283
-1284
-1285
-1286
-1287
-1288
-1289
-1290
-1291
-1292
-1293
-1294
-1295
-1296 55/push-ebp
-1297 89/<- %ebp 4/r32/esp
-1298
-1299 (clear-stream _test-output-stream)
-1300 (clear-stream _test-output-buffered-file->buffer)
-1301
-1302 68/push 0/imm32/no-register
-1303 68/push -8/imm32/stack-offset
-1304 68/push 1/imm32/block-depth
-1305 68/push 1/imm32/type-int
-1306 68/push "foo"/imm32
-1307 89/<- %ecx 4/r32/esp
-1308
-1309 51/push-ecx/var-foo
-1310 68/push 1/imm32/data-length
-1311 68/push 1/imm32/top
-1312 89/<- %edx 4/r32/esp
-1313
-1314 68/push 0/imm32/next
-1315 51/push-ecx/var-foo
-1316 89/<- %esi 4/r32/esp
-1317
-1318 68/push 0/imm32/next
-1319 68/push 0/imm32/outputs
-1320 56/push-esi/operands
-1321 68/push "increment"/imm32/operation
-1322 89/<- %esi 4/r32/esp
-1323
-1324 68/push 0/imm32/next
-1325 68/push 0/imm32/no-imm32
-1326 68/push 0/imm32/no-r32
-1327 68/push 1/imm32/rm32-is-first-inout
-1328 68/push "ff 0/subop/increment"/imm32/subx-name
-1329 68/push 0/imm32/outputs
-1330 51/push-ecx/inouts
-1331 68/push "increment"/imm32/name
-1332 89/<- %ebx 4/r32/esp
-1333
-1334 (emit-subx-statement _test-output-buffered-file %esi %edx %ebx 0)
-1335 (flush _test-output-buffered-file)
-1336 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
-1342
-1343 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-statement-primitive/0")
-1344
-1345 81 0/subop/add %esp 0x48/imm32
-1346
-1347 89/<- %esp 5/r32/ebp
-1348 5d/pop-to-ebp
-1349 c3/return
-1350
-1351 test-emit-subx-statement-primitive-register:
-1352
-1353
-1354
-1355
-1356
-1357
-1358
-1359
-1360
-1361
-1362
-1363
-1364
-1365
-1366
-1367
-1368
-1369
-1370 55/push-ebp
-1371 89/<- %ebp 4/r32/esp
-1372
-1373 (clear-stream _test-output-stream)
-1374 (clear-stream _test-output-buffered-file->buffer)
-1375
-1376 68/push "eax"/imm32/register
-1377 68/push 0/imm32/no-stack-offset
-1378 68/push 1/imm32/block-depth
-1379 68/push 1/imm32/type-int
-1380 68/push "foo"/imm32
-1381 89/<- %ecx 4/r32/esp
-1382
-1383 51/push-ecx/var-foo
-1384 68/push 1/imm32/data-length
-1385 68/push 1/imm32/top
-1386 89/<- %edx 4/r32/esp
-1387
-1388 68/push 0/imm32/next
-1389 51/push-ecx/var-foo
-1390 89/<- %esi 4/r32/esp
-1391
-1392 68/push 0/imm32/next
-1393 56/push-esi/outputs
-1394 68/push 0/imm32/inouts
-1395 68/push "increment"/imm32/operation
-1396 89/<- %esi 4/r32/esp
-1397
-1398 68/push Any-register/imm32
-1399 68/push 0/imm32/no-stack-offset
-1400 68/push 1/imm32/block-depth
-1401 68/push 1/imm32/type-int
-1402 68/push "dummy"/imm32
-1403 89/<- %ebx 4/r32/esp
-1404
-1405 68/push 0/imm32/next
-1406 53/push-ebx/formal-var
-1407 89/<- %ebx 4/r32/esp
-1408
-1409 68/push 0/imm32/next
-1410 68/push 0/imm32/no-imm32
-1411 68/push 0/imm32/no-r32
-1412 68/push 3/imm32/rm32-in-first-output
-1413 68/push "ff 0/subop/increment"/imm32/subx-name
-1414 53/push-ebx/outputs
-1415 68/push 0/imm32/inouts
-1416 68/push "increment"/imm32/name
-1417 89/<- %ebx 4/r32/esp
-1418
-1419 (emit-subx-statement _test-output-buffered-file %esi %edx %ebx 0)
-1420 (flush _test-output-buffered-file)
-1421 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
-1427
-1428 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-primitive-register/0")
-1429
-1430 81 0/subop/add %esp 0x48/imm32
-1431
-1432 89/<- %esp 5/r32/ebp
-1433 5d/pop-to-ebp
-1434 c3/return
-1435
-1436 test-emit-subx-statement-function-call:
-1437
-1438
-1439
-1440
-1441
-1442
-1443
-1444
-1445
-1446
-1447
-1448
-1449
-1450
-1451
-1452
-1453
-1454
-1455
-1456
-1457 55/push-ebp
-1458 89/<- %ebp 4/r32/esp
-1459
-1460 (clear-stream _test-output-stream)
-1461 (clear-stream _test-output-buffered-file->buffer)
-1462
-1463 68/push 0/imm32/no-register
-1464 68/push -8/imm32/stack-offset
-1465 68/push 0/imm32/block-depth
-1466 68/push 1/imm32/type-int
-1467 68/push "foo"/imm32
-1468 89/<- %ecx 4/r32/esp
-1469
-1470 51/push-ecx/var-foo
-1471 68/push 1/imm32/data-length
-1472 68/push 1/imm32/top
-1473 89/<- %edx 4/r32/esp
-1474
-1475 68/push 0/imm32/next
-1476 51/push-ecx/var-foo
-1477 89/<- %esi 4/r32/esp
-1478
-1479 68/push 0/imm32/next
-1480 68/push 0/imm32/outputs
-1481 56/push-esi/inouts
-1482 68/push "f"/imm32/operation
-1483 89/<- %esi 4/r32/esp
-1484
-1485 68/push 0/imm32/next
-1486 68/push 0/imm32/body
-1487 68/push 0/imm32/outputs
-1488 51/push-ecx/inouts
-1489 68/push "f2"/imm32/subx-name
-1490 68/push "f"/imm32/name
-1491 89/<- %ebx 4/r32/esp
-1492
-1493 (emit-subx-statement _test-output-buffered-file %esi %edx 0 %ebx)
-1494 (flush _test-output-buffered-file)
-1495 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
-1501
-1502 (check-next-stream-line-equal _test-output-stream "(f2 *(ebp+0xfffffff8))" "F - test-emit-subx-statement-function-call/0")
-1503
-1504 81 0/subop/add %esp 0x3c/imm32
-1505
-1506 89/<- %esp 5/r32/ebp
-1507 5d/pop-to-ebp
-1508 c3/return
-1509
-1510 emit-subx-prologue:
-1511
-1512 55/push-ebp
-1513 89/<- %ebp 4/r32/esp
-1514
-1515 (write-buffered *(ebp+8) "# . prologue\n")
-1516 (write-buffered *(ebp+8) "55/push-ebp\n")
-1517 (write-buffered *(ebp+8) "89/<- %ebp 4/r32/esp\n")
-1518 $emit-subx-prologue:end:
-1519
-1520 89/<- %esp 5/r32/ebp
-1521 5d/pop-to-ebp
-1522 c3/return
-1523
-1524 emit-subx-epilogue:
-1525
-1526 55/push-ebp
-1527 89/<- %ebp 4/r32/esp
-1528
-1529 (write-buffered *(ebp+8) "# . epilogue\n")
-1530 (write-buffered *(ebp+8) "89/<- %esp 5/r32/ebp\n")
-1531 (write-buffered *(ebp+8) "5d/pop-to-ebp\n")
-1532 (write-buffered *(ebp+8) "c3/return\n")
-1533 $emit-subx-epilogue:end:
-1534
-1535 89/<- %esp 5/r32/ebp
-1536 5d/pop-to-ebp
-1537 c3/return
+1089 emit-subx-call:
+1090
+1091 55/push-ebp
+1092 89/<- %ebp 4/r32/esp
+1093
+1094 50/push-eax
+1095 51/push-ecx
+1096
+1097 (write-buffered *(ebp+8) "(")
+1098
+1099 8b/-> *(ebp+0x14) 1/r32/ecx
+1100 (write-buffered *(ebp+8) *(ecx+4))
+1101
+1102
+1103 8b/-> *(ebp+0xc) 1/r32/ecx
+1104 8b/-> *(ecx+4) 1/r32/ecx
+1105 {
+1106
+1107 81 7/subop/compare %ecx 0/imm32
+1108 74/jump-if-equal break/disp8
+1109
+1110 (emit-subx-call-operand *(ebp+8) *ecx)
+1111
+1112 8b/-> *(ecx+4) 1/r32/ecx
+1113 }
+1114
+1115 (write-buffered *(ebp+8) ")")
+1116 $emit-subx-call:end:
+1117
+1118 59/pop-to-ecx
+1119 58/pop-to-eax
+1120
+1121 89/<- %esp 5/r32/ebp
+1122 5d/pop-to-ebp
+1123 c3/return
+1124
+1125 emit-subx-call-operand:
+1126
+1127 55/push-ebp
+1128 89/<- %ebp 4/r32/esp
+1129
+1130 50/push-eax
+1131
+1132 8b/-> *(ebp+0xc) 0/r32/eax
+1133
+1134 {
+1135 81 7/subop/compare *(eax+0x10) 0/imm32
+1136 74/jump-if-equal break/disp8
+1137 $emit-subx-call-operand:register:
+1138 (write-buffered *(ebp+8) " %")
+1139 (write-buffered *(ebp+8) *(eax+0x10))
+1140 }
+1141
+1142 {
+1143 81 7/subop/compare *(eax+0xc) 0/imm32
+1144 74/jump-if-equal break/disp8
+1145 $emit-subx-call-operand:stack:
+1146 (write-buffered *(ebp+8) Space)
+1147 (write-buffered *(ebp+8) "*(ebp+")
+1148 8b/-> *(ebp+0xc) 0/r32/eax
+1149 (print-int32-buffered *(ebp+8) *(eax+0xc))
+1150 (write-buffered *(ebp+8) ")")
+1151 }
+1152 $emit-subx-call-operand:end:
+1153
+1154 58/pop-to-eax
+1155
+1156 89/<- %esp 5/r32/ebp
+1157 5d/pop-to-ebp
+1158 c3/return
+1159
+1160 find-matching-function:
+1161
+1162 55/push-ebp
+1163 89/<- %ebp 4/r32/esp
+1164
+1165 51/push-ecx
+1166
+1167 8b/-> *(ebp+8) 1/r32/ecx
+1168 {
+1169
+1170 81 7/subop/compare %ecx 0/imm32
+1171 74/jump-if-equal break/disp8
+1172
+1173 {
+1174 (mu-stmt-matches-function? *(ebp+0xc) %ecx)
+1175 3d/compare-eax-and 0/imm32
+1176 74/jump-if-equal break/disp8
+1177 89/<- %eax 1/r32/ecx
+1178 eb/jump $find-matching-function:end/disp8
+1179 }
+1180
+1181 8b/-> *(ecx+0x10) 1/r32/ecx
+1182 eb/jump loop/disp8
+1183 }
+1184
+1185 b8/copy-to-eax 0/imm32
+1186 $find-matching-function:end:
+1187
+1188 59/pop-to-ecx
+1189
+1190 89/<- %esp 5/r32/ebp
+1191 5d/pop-to-ebp
+1192 c3/return
+1193
+1194 find-matching-primitive:
+1195
+1196 55/push-ebp
+1197 89/<- %ebp 4/r32/esp
+1198
+1199 51/push-ecx
+1200
+1201 8b/-> *(ebp+8) 1/r32/ecx
+1202 {
+1203 $find-matching-primitive:loop:
+1204
+1205 81 7/subop/compare %ecx 0/imm32
+1206 74/jump-if-equal break/disp8
+1207
+1208 {
+1209 (mu-stmt-matches-primitive? *(ebp+0xc) %ecx)
+1210 3d/compare-eax-and 0/imm32
+1211 74/jump-if-equal break/disp8
+1212 89/<- %eax 1/r32/ecx
+1213 eb/jump $find-matching-function:end/disp8
+1214 }
+1215 $find-matching-primitive:next-primitive:
+1216
+1217 8b/-> *(ecx+0x1c) 1/r32/ecx
+1218 eb/jump loop/disp8
+1219 }
+1220
+1221 b8/copy-to-eax 0/imm32
+1222 $find-matching-primitive:end:
+1223
+1224 59/pop-to-ecx
+1225
+1226 89/<- %esp 5/r32/ebp
+1227 5d/pop-to-ebp
+1228 c3/return
+1229
+1230 mu-stmt-matches-function?:
+1231
+1232 55/push-ebp
+1233 89/<- %ebp 4/r32/esp
+1234
+1235 51/push-ecx
+1236
+1237 8b/-> *(ebp+8) 1/r32/ecx
+1238 8b/-> *(ebp+0xc) 0/r32/eax
+1239 (string-equal? *ecx *eax)
+1240 $mu-stmt-matches-function?:end:
+1241
+1242 59/pop-to-ecx
+1243
+1244 89/<- %esp 5/r32/ebp
+1245 5d/pop-to-ebp
+1246 c3/return
+1247
+1248 mu-stmt-matches-primitive?:
+1249
+1250
+1251
+1252
+1253
+1254
+1255 55/push-ebp
+1256 89/<- %ebp 4/r32/esp
+1257
+1258 51/push-ecx
+1259 52/push-edx
+1260 53/push-ebx
+1261 56/push-esi
+1262 57/push-edi
+1263
+1264 8b/-> *(ebp+8) 1/r32/ecx
+1265
+1266 8b/-> *(ebp+0xc) 2/r32/edx
+1267 {
+1268 $mu-stmt-matches-primitive?:check-name:
+1269
+1270 (string-equal? *ecx *edx)
+1271 3d/compare-eax-and 0/imm32
+1272 75/jump-if-not-equal break/disp8
+1273 b8/copy-to-eax 0/imm32
+1274 e9/jump $mu-stmt-matches-primitive?:end/disp32
+1275 }
+1276 $mu-stmt-matches-primitive?:check-inouts:
+1277
+1278 8b/-> *(ecx+4) 6/r32/esi
+1279
+1280 8b/-> *(edx+4) 7/r32/edi
+1281 {
+1282
+1283 {
+1284 81 7/subop/compare %esi 0/imm32
+1285 75/jump-if-not-equal break/disp8
+1286 {
+1287 81 7/subop/compare %edi 0/imm32
+1288 75/jump-if-not-equal break/disp8
+1289
+1290 b8/copy-to-eax 1/imm32
+1291 e9/jump $mu-stmt-matches-primitive?:end/disp32
+1292 }
+1293
+1294 b8/copy-to-eax 0/imm32
+1295 e9/jump $mu-stmt-matches-primitive?:end/disp32
+1296 }
+1297
+1298 {
+1299 81 7/subop/compare %edi 0/imm32
+1300 75/jump-if-not-equal break/disp8
+1301 b8/copy-to-eax 0/imm32
+1302 e9/jump $mu-stmt-matches-primitive?:end/disp32
+1303 }
+1304
+1305 {
+1306 (operand-matches-primitive? *esi *edi)
+1307 3d/compare-eax-and 0/imm32
+1308 75/jump-if-not-equal break/disp8
+1309 b8/copy-to-eax 0/imm32
+1310 e9/jump $mu-stmt-matches-primitive?:end/disp32
+1311 }
+1312
+1313 8b/-> *(ecx+4) 1/r32/ecx
+1314
+1315 8b/-> *(edx+4) 2/r32/edx
+1316 }
+1317 $mu-stmt-matches-primitive?:check-outputs:
+1318
+1319 8b/-> *(ebp+8) 1/r32/ecx
+1320
+1321 8b/-> *(ebp+0xc) 2/r32/edx
+1322
+1323 8b/-> *(ecx+8) 6/r32/esi
+1324
+1325 8b/-> *(edx+8) 7/r32/edi
+1326 {
+1327
+1328 {
+1329 81 7/subop/compare %esi 0/imm32
+1330 75/jump-if-not-equal break/disp8
+1331 {
+1332 81 7/subop/compare %edi 0/imm32
+1333 75/jump-if-not-equal break/disp8
+1334
+1335 b8/copy-to-eax 1/imm32
+1336 e9/jump $mu-stmt-matches-primitive?:end/disp32
+1337 }
+1338
+1339 b8/copy-to-eax 0/imm32
+1340 e9/jump $mu-stmt-matches-primitive?:end/disp32
+1341 }
+1342
+1343 {
+1344 81 7/subop/compare %edi 0/imm32
+1345 75/jump-if-not-equal break/disp8
+1346 b8/copy-to-eax 0/imm32
+1347 e9/jump $mu-stmt-matches-primitive?:end/disp32
+1348 }
+1349
+1350 {
+1351 (output-operand-matches-primitive? *esi *edi)
+1352 3d/compare-eax-and 0/imm32
+1353 75/jump-if-not-equal break/disp8
+1354 b8/copy-to-eax 0/imm32
+1355 e9/jump $mu-stmt-matches-primitive?:end/disp32
+1356 }
+1357
+1358 8b/-> *(ecx+4) 1/r32/ecx
+1359
+1360 8b/-> *(edx+4) 2/r32/edx
+1361 }
+1362 $mu-stmt-matches-primitive?:return-true:
+1363 b8/copy-to-eax 1/imm32
+1364 $mu-stmt-matches-primitive?:end:
+1365
+1366 5f/pop-to-edi
+1367 5e/pop-to-esi
+1368 5b/pop-to-ebx
+1369 5a/pop-to-edx
+1370 59/pop-to-ecx
+1371
+1372 89/<- %esp 5/r32/ebp
+1373 5d/pop-to-ebp
+1374 c3/return
+1375
+1376 operand-matches-primitive?:
+1377
+1378 55/push-ebp
+1379 89/<- %ebp 4/r32/esp
+1380
+1381 56/push-esi
+1382 57/push-edi
+1383
+1384 8b/-> *(ebp+8) 6/r32/esi
+1385
+1386 8b/-> *(ebp+0xc) 7/r32/edi
+1387
+1388
+1389 {
+1390
+1391 8b/-> *(esi+0x10) 0/r32/eax
+1392 39/compare *(edi+0x10) 0/r32/eax
+1393 74/jump-if-equal break/disp8
+1394
+1395 3d/compare-eax-and 0/imm32
+1396 74/jump-if-equal $operand-matches-primitive?:end/disp8
+1397 81 7/subop/compare *(edi+0x10) 0/imm32
+1398 74/jump-if-equal $operand-matches-primitive?:end/disp8
+1399
+1400 (string-equal? *(esi+0x10) *(edi+0x10))
+1401 3d/compare-eax-and 0/imm32
+1402 b8/copy-to-eax 0/imm32/false
+1403 74/jump-if-equal $operand-matches-primitive?:end/disp8
+1404 }
+1405
+1406 b8/copy-to-eax 1/imm32/true
+1407 $operand-matches-primitive?:end:
+1408
+1409 5f/pop-to-edi
+1410 5e/pop-to-esi
+1411
+1412 89/<- %esp 5/r32/ebp
+1413 5d/pop-to-ebp
+1414 c3/return
+1415
+1416
+1417 output-operand-matches-primitive?:
+1418
+1419 55/push-ebp
+1420 89/<- %ebp 4/r32/esp
+1421
+1422 56/push-esi
+1423 57/push-edi
+1424
+1425 8b/-> *(ebp+8) 6/r32/esi
+1426
+1427 8b/-> *(ebp+0xc) 7/r32/edi
+1428
+1429
+1430 {
+1431
+1432 8b/-> *(esi+0x10) 0/r32/eax
+1433 39/compare *(edi+0x10) 0/r32/eax
+1434 74/jump-if-equal break/disp8
+1435
+1436 3d/compare-eax-and 0/imm32
+1437 74/jump-if-equal $operand-matches-primitive?:end/disp8
+1438 81 7/subop/compare *(edi+0x10) 0/imm32
+1439 74/jump-if-equal $operand-matches-primitive?:end/disp8
+1440
+1441 (string-equal? *(edi+0x10) "*")
+1442 3d/compare-eax-and 0/imm32
+1443 b8/copy-to-eax 1/imm32/true
+1444 75/jump-if-not-equal $operand-matches-primitive?:end/disp8
+1445
+1446 (string-equal? *(esi+0x10) *(edi+0x10))
+1447 3d/compare-eax-and 0/imm32
+1448 b8/copy-to-eax 0/imm32/false
+1449 74/jump-if-equal $operand-matches-primitive?:end/disp8
+1450 }
+1451
+1452 b8/copy-to-eax 1/imm32/true
+1453 $output-operand-matches-primitive?:end:
+1454
+1455 5f/pop-to-edi
+1456 5e/pop-to-esi
+1457
+1458 89/<- %esp 5/r32/ebp
+1459 5d/pop-to-ebp
+1460 c3/return
+1461
+1462 test-emit-subx-statement-primitive:
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481 55/push-ebp
+1482 89/<- %ebp 4/r32/esp
+1483
+1484 (clear-stream _test-output-stream)
+1485 (clear-stream _test-output-buffered-file->buffer)
+1486
+1487 68/push 0/imm32/no-register
+1488 68/push -8/imm32/stack-offset
+1489 68/push 1/imm32/block-depth
+1490 68/push 1/imm32/type-int
+1491 68/push "foo"/imm32
+1492 89/<- %ecx 4/r32/esp
+1493
+1494
+1495 51/push-ecx/var-foo
+1496 68/push 1/imm32/data-length
+1497 68/push 1/imm32/top
+1498 89/<- %edx 4/r32/esp
+1499
+1500
+1501 68/push 0/imm32/next
+1502 51/push-ecx/var-foo
+1503 89/<- %ebx 4/r32/esp
+1504
+1505
+1506 68/push 0/imm32/next
+1507 68/push 0/imm32/outputs
+1508 53/push-ebx/operands
+1509 68/push "increment"/imm32/operation
+1510 89/<- %esi 4/r32/esp
+1511
+1512
+1513 68/push 0/imm32/next
+1514 68/push 0/imm32/no-imm32
+1515 68/push 0/imm32/no-r32
+1516 68/push 1/imm32/rm32-is-first-inout
+1517 68/push "ff 0/subop/increment"/imm32/subx-name
+1518 68/push 0/imm32/outputs
+1519 53/push-ebx/inouts
+1520 68/push "increment"/imm32/name
+1521 89/<- %ebx 4/r32/esp
+1522 $aa-primitive-in-ebx:
+1523
+1524 (emit-subx-statement _test-output-buffered-file %esi %edx %ebx 0)
+1525 (flush _test-output-buffered-file)
+1526 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
+1532
+1533 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment *(ebp+0xfffffff8)" "F - test-emit-subx-statement-primitive/0")
+1534
+1535 81 0/subop/add %esp 0x48/imm32
+1536
+1537 89/<- %esp 5/r32/ebp
+1538 5d/pop-to-ebp
+1539 c3/return
+1540
+1541 test-emit-subx-statement-primitive-register:
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560 55/push-ebp
+1561 89/<- %ebp 4/r32/esp
+1562
+1563 (clear-stream _test-output-stream)
+1564 (clear-stream _test-output-buffered-file->buffer)
+1565
+1566 68/push "eax"/imm32/register
+1567 68/push 0/imm32/no-stack-offset
+1568 68/push 1/imm32/block-depth
+1569 68/push 1/imm32/type-int
+1570 68/push "foo"/imm32
+1571 89/<- %ecx 4/r32/esp
+1572
+1573 51/push-ecx/var-foo
+1574 68/push 1/imm32/data-length
+1575 68/push 1/imm32/top
+1576 89/<- %edx 4/r32/esp
+1577
+1578 68/push 0/imm32/next
+1579 51/push-ecx/var-foo
+1580 89/<- %ebx 4/r32/esp
+1581
+1582 68/push 0/imm32/next
+1583 53/push-ebx/outputs
+1584 68/push 0/imm32/inouts
+1585 68/push "increment"/imm32/operation
+1586 89/<- %esi 4/r32/esp
+1587
+1588 68/push Any-register/imm32
+1589 68/push 0/imm32/no-stack-offset
+1590 68/push 1/imm32/block-depth
+1591 68/push 1/imm32/type-int
+1592 68/push "dummy"/imm32
+1593 89/<- %ebx 4/r32/esp
+1594
+1595 68/push 0/imm32/next
+1596 53/push-ebx/formal-var
+1597 89/<- %ebx 4/r32/esp
+1598
+1599 68/push 0/imm32/next
+1600 68/push 0/imm32/no-imm32
+1601 68/push 0/imm32/no-r32
+1602 68/push 3/imm32/rm32-in-first-output
+1603 68/push "ff 0/subop/increment"/imm32/subx-name
+1604 53/push-ebx/outputs
+1605 68/push 0/imm32/inouts
+1606 68/push "increment"/imm32/name
+1607 89/<- %ebx 4/r32/esp
+1608
+1609 (emit-subx-statement _test-output-buffered-file %esi %edx %ebx 0)
+1610 (flush _test-output-buffered-file)
+1611 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
+1617
+1618 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-primitive-register/0")
+1619
+1620 81 0/subop/add %esp 0x48/imm32
+1621
+1622 89/<- %esp 5/r32/ebp
+1623 5d/pop-to-ebp
+1624 c3/return
+1625
+1626 test-emit-subx-statement-select-primitive:
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648 55/push-ebp
+1649 89/<- %ebp 4/r32/esp
+1650
+1651 (clear-stream _test-output-stream)
+1652 (clear-stream _test-output-buffered-file->buffer)
+1653
+1654 68/push "eax"/imm32/register
+1655 68/push 0/imm32/no-stack-offset
+1656 68/push 1/imm32/block-depth
+1657 68/push 1/imm32/type-int
+1658 68/push "foo"/imm32
+1659 89/<- %ecx 4/r32/esp
+1660
+1661 51/push-ecx/var-foo
+1662 68/push 1/imm32/data-length
+1663 68/push 1/imm32/top
+1664 89/<- %edx 4/r32/esp
+1665
+1666 68/push 0/imm32/next
+1667 51/push-ecx/var-foo
+1668 89/<- %edi 4/r32/esp
+1669
+1670 68/push 0/imm32/next
+1671 57/push-edi/outputs
+1672 68/push 0/imm32/inouts
+1673 68/push "increment"/imm32/operation
+1674 89/<- %esi 4/r32/esp
+1675
+1676 68/push Any-register/imm32
+1677 68/push 0/imm32/no-stack-offset
+1678 68/push 1/imm32/block-depth
+1679 68/push 1/imm32/type-int
+1680 68/push "dummy"/imm32
+1681 89/<- %ebx 4/r32/esp
+1682
+1683 68/push 0/imm32/next
+1684 53/push-ebx/formal-var
+1685 89/<- %ebx 4/r32/esp
+1686
+1687 68/push 0/imm32/next
+1688 68/push 0/imm32/no-imm32
+1689 68/push 0/imm32/no-r32
+1690 68/push 3/imm32/rm32-in-first-output
+1691 68/push "ff 0/subop/increment"/imm32/subx-name
+1692 53/push-ebx/outputs/formal-outputs
+1693 68/push 0/imm32/inouts
+1694 68/push "increment"/imm32/name
+1695 89/<- %ebx 4/r32/esp
+1696
+1697 53/push-ebx/next
+1698 68/push 0/imm32/no-imm32
+1699 68/push 0/imm32/no-r32
+1700 68/push 1/imm32/rm32-is-first-inout
+1701 68/push "ff 0/subop/increment"/imm32/subx-name
+1702 68/push 0/imm32/outputs
+1703 57/push-edi/inouts/real-outputs
+1704 68/push "increment"/imm32/name
+1705 89/<- %ebx 4/r32/esp
+1706
+1707 (emit-subx-statement _test-output-buffered-file %esi %edx %ebx 0)
+1708 (flush _test-output-buffered-file)
+1709 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
+1715
+1716 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive/0")
+1717
+1718 81 0/subop/add %esp 0x48/imm32
+1719
+1720 89/<- %esp 5/r32/ebp
+1721 5d/pop-to-ebp
+1722 c3/return
+1723
+1724 test-emit-subx-statement-select-primitive-2:
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746 55/push-ebp
+1747 89/<- %ebp 4/r32/esp
+1748
+1749 (clear-stream _test-output-stream)
+1750 (clear-stream _test-output-buffered-file->buffer)
+1751
+1752 68/push "eax"/imm32/register
+1753 68/push 0/imm32/no-stack-offset
+1754 68/push 1/imm32/block-depth
+1755 68/push 1/imm32/type-int
+1756 68/push "foo"/imm32
+1757 89/<- %ecx 4/r32/esp
+1758
+1759 51/push-ecx/var-foo
+1760 68/push 1/imm32/data-length
+1761 68/push 1/imm32/top
+1762 89/<- %edx 4/r32/esp
+1763
+1764 68/push 0/imm32/next
+1765 51/push-ecx/var-foo
+1766 89/<- %edi 4/r32/esp
+1767
+1768 68/push 0/imm32/next
+1769 68/push 0/imm32/outputs
+1770 57/push-edi/inouts
+1771 68/push "increment"/imm32/operation
+1772 89/<- %esi 4/r32/esp
+1773
+1774 68/push Any-register/imm32
+1775 68/push 0/imm32/no-stack-offset
+1776 68/push 1/imm32/block-depth
+1777 68/push 1/imm32/type-int
+1778 68/push "dummy"/imm32
+1779 89/<- %ebx 4/r32/esp
+1780
+1781 68/push 0/imm32/next
+1782 53/push-ebx/formal-var
+1783 89/<- %ebx 4/r32/esp
+1784
+1785 68/push 0/imm32/next
+1786 68/push 0/imm32/no-imm32
+1787 68/push 0/imm32/no-r32
+1788 68/push 3/imm32/rm32-in-first-output
+1789 68/push "ff 0/subop/increment"/imm32/subx-name
+1790 53/push-ebx/outputs/formal-outputs
+1791 68/push 0/imm32/inouts
+1792 68/push "increment"/imm32/name
+1793 89/<- %ebx 4/r32/esp
+1794
+1795 53/push-ebx/next
+1796 68/push 0/imm32/no-imm32
+1797 68/push 0/imm32/no-r32
+1798 68/push 1/imm32/rm32-is-first-inout
+1799 68/push "ff 0/subop/increment"/imm32/subx-name
+1800 68/push 0/imm32/outputs
+1801 57/push-edi/inouts/real-outputs
+1802 68/push "increment"/imm32/name
+1803 89/<- %ebx 4/r32/esp
+1804
+1805 (emit-subx-statement _test-output-buffered-file %esi %edx %ebx 0)
+1806 (flush _test-output-buffered-file)
+1807 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
+1813
+1814 (check-next-stream-line-equal _test-output-stream "ff 0/subop/increment %eax" "F - test-emit-subx-statement-select-primitive-2/0")
+1815
+1816 81 0/subop/add %esp 0x48/imm32
+1817
+1818 89/<- %esp 5/r32/ebp
+1819 5d/pop-to-ebp
+1820 c3/return
+1821
+1822 test-emit-subx-statement-function-call:
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843 55/push-ebp
+1844 89/<- %ebp 4/r32/esp
+1845
+1846 (clear-stream _test-output-stream)
+1847 (clear-stream _test-output-buffered-file->buffer)
+1848
+1849 68/push 0/imm32/no-register
+1850 68/push -8/imm32/stack-offset
+1851 68/push 0/imm32/block-depth
+1852 68/push 1/imm32/type-int
+1853 68/push "foo"/imm32
+1854 89/<- %ecx 4/r32/esp
+1855
+1856 51/push-ecx/var-foo
+1857 68/push 1/imm32/data-length
+1858 68/push 1/imm32/top
+1859 89/<- %edx 4/r32/esp
+1860
+1861 68/push 0/imm32/next
+1862 51/push-ecx/var-foo
+1863 89/<- %esi 4/r32/esp
+1864
+1865 68/push 0/imm32/next
+1866 68/push 0/imm32/outputs
+1867 56/push-esi/inouts
+1868 68/push "f"/imm32/operation
+1869 89/<- %esi 4/r32/esp
+1870
+1871 68/push 0/imm32/next
+1872 68/push 0/imm32/body
+1873 68/push 0/imm32/outputs
+1874 51/push-ecx/inouts
+1875 68/push "f2"/imm32/subx-name
+1876 68/push "f"/imm32/name
+1877 89/<- %ebx 4/r32/esp
+1878
+1879 (emit-subx-statement _test-output-buffered-file %esi %edx 0 %ebx)
+1880 (flush _test-output-buffered-file)
+1881 +-- 6 lines: #? # dump _test-output-stream --------------------------------------------------------------------------------------------------------------
+1887
+1888 (check-next-stream-line-equal _test-output-stream "(f2 *(ebp+0xfffffff8))" "F - test-emit-subx-statement-function-call/0")
+1889
+1890 81 0/subop/add %esp 0x3c/imm32
+1891
+1892 89/<- %esp 5/r32/ebp
+1893 5d/pop-to-ebp
+1894 c3/return
+1895
+1896 emit-subx-prologue:
+1897
+1898 55/push-ebp
+1899 89/<- %ebp 4/r32/esp
+1900
+1901 (write-buffered *(ebp+8) "# . prologue\n")
+1902 (write-buffered *(ebp+8) "55/push-ebp\n")
+1903 (write-buffered *(ebp+8) "89/<- %ebp 4/r32/esp\n")
+1904 $emit-subx-prologue:end:
+1905
+1906 89/<- %esp 5/r32/ebp
+1907 5d/pop-to-ebp
+1908 c3/return
+1909
+1910 emit-subx-epilogue:
+1911
+1912 55/push-ebp
+1913 89/<- %ebp 4/r32/esp
+1914
+1915 (write-buffered *(ebp+8) "# . epilogue\n")
+1916 (write-buffered *(ebp+8) "89/<- %esp 5/r32/ebp\n")
+1917 (write-buffered *(ebp+8) "5d/pop-to-ebp\n")
+1918 (write-buffered *(ebp+8) "c3/return\n")
+1919 $emit-subx-epilogue:end:
+1920
+1921 89/<- %esp 5/r32/ebp
+1922 5d/pop-to-ebp
+1923 c3/return