6158 - standardize opcode names

At the lowest level, SubX without syntax sugar uses names without prepositions.
For example, 01 and 03 are both called 'add', irrespective of source and
destination operand. Horizontal space is at a premium, and we rely on the
comments at the end of each line to fully describe what is happening.

Above that, however, we standardize on a slightly different naming convention
across:
  a) SubX with syntax sugar,
  b) Mu, and
  c) the SubX code that the Mu compiler emits.

Conventions, in brief:
  - by default, the source is on the left and destination on the right.
    e.g. add %eax, 1/r32/ecx ("add eax to ecx")
  - prepositions reverse the direction.
    e.g. add-to %eax, 1/r32/ecx ("add ecx to eax")
         subtract-from %eax, 1/r32/ecx ("subtract ecx from eax")
  - by default, comparisons are left to right while 'compare<-' reverses.

Before, I was sometimes swapping args to make the operation more obvious,
but that would complicate the code-generation of the Mu compiler, and it's
nice to be able to read the output of the compiler just like hand-written
code.

One place where SubX differs from Mu: copy opcodes are called '<-' and
'->'. Hopefully that fits with the spirit of Mu rather than the letter
of the 'copy' and 'copy-to' instructions.
This commit is contained in:
Kartik Agaram 2020-03-21 15:32:30 -07:00
parent c6886c1c97
commit df609237c1
5 changed files with 87 additions and 107 deletions

View File

@ -48,7 +48,7 @@ $array-equal?:lengths:
# var currb/edi: (addr byte) = b->data
81 0/subop/add %edi 4/imm32
# var i/ecx: int = 0
31/xor %ecx 1/r32/ecx
31/xor-with %ecx 1/r32/ecx
# var vala/eax: int
# var valb/ebx: int
$array-equal?:loop:
@ -213,9 +213,9 @@ parse-array-of-ints: # ad: (addr allocation-descriptor), s: (addr string) -> re
# . edx = s->length
8b/-> *esi 2/r32/edx
# . edx += curr
01/add %edx 1/r32/ecx
01/add-to %edx 1/r32/ecx
# var size/ebx: int = 0
31/xor %ebx 3/r32/ebx
31/xor-with %ebx 3/r32/ebx
$parse-array-of-ints:loop1:
# if (curr >= end) break
39/compare %ecx 2/r32/edx
@ -235,7 +235,7 @@ $parse-array-of-ints:loop1:
$parse-array-of-ints:break1:
# var result/edi: (handle array int)
89/<- %eax 3/r32/ebx
05/add-eax 4/imm32
05/add-to-eax 4/imm32
(allocate *(ebp+8) %eax)
89/<- %edi 0/r32/eax
# result->size = size

View File

@ -149,7 +149,7 @@ $subx-calls:check0:
# . ecx = line->read
8b/-> *(esi+4) 1/r32/ecx
# . eax = line->data[line->read]
31/xor %eax 0/r32/eax
31/xor-with %eax 0/r32/eax
8a/copy-byte *(esi+ecx+0xc) 0/r32/AL
# . if (eax == '(') goto convert-call
3d/compare-eax-and 0x28/imm32/open-paren
@ -824,7 +824,7 @@ $next-word-string-or-expression-without-metadata:check0:
# . ecx = line->read
8b/-> *(esi+4) 1/r32/ecx
# . if (ecx >= line->write) abort
3b/compare 1/r32/ecx *esi
3b/compare<- *esi 1/r32/ecx
0f 8d/jump-if->= $next-word-string-or-expression-without-metadata:error0/disp32
$next-word-string-or-expression-without-metadata:check-for-comment:
# out->start = &line->data[line->read]
@ -832,7 +832,7 @@ $next-word-string-or-expression-without-metadata:check-for-comment:
89/<- *edi 0/r32/eax
# if (line->data[line->read] != '#') goto next check
# . var eax: byte = line->data[line->read]
31/xor %eax 0/r32/eax
31/xor-with %eax 0/r32/eax
8a/copy-byte *(esi+ecx+0xc) 0/r32/AL
# . if (eax != '#') goto next check
3d/compare-eax-and 0x23/imm32/pound
@ -910,7 +910,7 @@ $next-word-string-or-expression-without-metadata:check-for-end-of-call:
# . ecx = line->read
8b/-> *(esi+4) 1/r32/ecx
# . if (ecx >= line->write) return {0, 0}
3b/compare 1/r32/ecx *esi
3b/compare<- *esi 1/r32/ecx
0f 8d/jump-if->= $next-word-string-or-expression-without-metadata:return-eol/disp32
# if (line->data[line->read] == '/') goto error3
# . eax = line->data[line->read]
@ -929,7 +929,7 @@ $next-word-string-or-expression-without-metadata:check-for-end-of-call:
# . ecx = line->read
8b/-> *(esi+4) 1/r32/ecx
# . if (ecx >= line->write) return {0, 0}
3b/compare 1/r32/ecx *esi
3b/compare<- *esi 1/r32/ecx
0f 8d/jump-if->= $next-word-string-or-expression-without-metadata:return-eol/disp32
# if (line->data[line->read] == '#') return out = {0, 0}
# . eax = line->data[line->read]
@ -945,7 +945,7 @@ $next-word-string-or-expression-without-metadata:regular-word-without-metadata:
# . ecx = line->read
8b/-> *(esi+4) 1/r32/ecx
# . if (ecx >= line->write) break
3b/compare *esi 1/r32/ecx
3b/compare<- *esi 1/r32/ecx
7d/jump-if->= $next-word-string-or-expression-without-metadata:regular-word-break/disp8
# if (line->data[line->read] == ' ') break
# . eax = line->data[line->read]

BIN
apps/mu

Binary file not shown.

View File

@ -736,7 +736,7 @@ test-convert-function-returns-result:
(check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-returns-result/3")
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-returns-result/4")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-returns-result/5")
(check-next-stream-line-equal _test-output-stream " 8b/copy-from *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-returns-result/6")
(check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-returns-result/6")
(check-next-stream-line-equal _test-output-stream " 40/increment-eax" "F - test-convert-function-returns-result/7")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-returns-result/8")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-returns-result/9")
@ -779,7 +779,7 @@ test-convert-function-with-literal-arg:
(check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg/3")
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg/4")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg/5")
(check-next-stream-line-equal _test-output-stream " 8b/copy-from *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-with-literal-arg/6")
(check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-with-literal-arg/6")
(check-next-stream-line-equal _test-output-stream " 05/add-to-eax 1/imm32" "F - test-convert-function-with-literal-arg/7")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg/8")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg/9")
@ -822,7 +822,7 @@ test-convert-function-with-literal-arg-2:
(check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-literal-arg-2/3")
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-literal-arg-2/4")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-literal-arg-2/5")
(check-next-stream-line-equal _test-output-stream " 8b/copy-from *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/6")
(check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-with-literal-arg-2/6")
(check-next-stream-line-equal _test-output-stream " 81 0/subop/add %ebx 1/imm32" "F - test-convert-function-with-literal-arg-2/7")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-literal-arg-2/8")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-literal-arg-2/9")
@ -881,7 +881,7 @@ test-convert-function-call-with-literal-arg:
(check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-call-with-literal-arg/16")
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-literal-arg/17")
(check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:loop:" "F - test-convert-function-call-with-literal-arg/18")
(check-next-stream-line-equal _test-output-stream " 8b/copy-from *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/19")
(check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/19")
(check-next-stream-line-equal _test-output-stream " 03/add *(ebp+0x0000000c) 0x00000003/r32" "F - test-convert-function-call-with-literal-arg/20")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-literal-arg/21")
(check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:break:" "F - test-convert-function-call-with-literal-arg/22")
@ -1498,7 +1498,7 @@ _pending-test-local-clobbered-by-output:
(check-next-stream-line-equal _test-output-stream " {" "F - test-local-clobbered-by-output/4")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-local-clobbered-by-output/5")
(check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 4/imm32" "F - test-local-clobbered-by-output/6")
(check-next-stream-line-equal _test-output-stream " 89/copy-to %ecx 0x00000001/r32" "F - test-local-clobbered-by-output/7")
(check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0x00000001/r32" "F - test-local-clobbered-by-output/7")
(check-next-stream-line-equal _test-output-stream " }" "F - test-local-clobbered-by-output/8")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-local-clobbered-by-output/9")
(check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-local-clobbered-by-output/10")
@ -2335,8 +2335,8 @@ test-convert-length-of-array:
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-length-of-array/4")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-length-of-array/5")
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array/6")
(check-next-stream-line-equal _test-output-stream " 8b/copy-from *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array/7")
(check-next-stream-line-equal _test-output-stream " 8b/copy-from *eax 0x00000000/r32" "F - test-convert-length-of-array/9")
(check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-length-of-array/7")
(check-next-stream-line-equal _test-output-stream " 8b/-> *eax 0x00000000/r32" "F - test-convert-length-of-array/9")
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array/11")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array/12")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-length-of-array/13")
@ -2383,7 +2383,7 @@ test-convert-length-of-array-on-stack:
(check-next-stream-line-equal _test-output-stream " (push-n-zero-bytes 0x0000000c)" "F - test-convert-length-of-array-on-stack/6")
(check-next-stream-line-equal _test-output-stream " 68/push 0x0000000c/imm32" "F - test-convert-length-of-array-on-stack/7")
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-length-of-array-on-stack/8")
(check-next-stream-line-equal _test-output-stream " 8b/copy-from *(ebp+0xfffffff0) 0x00000000/r32" "F - test-convert-length-of-array-on-stack/9")
(check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0xfffffff0) 0x00000000/r32" "F - test-convert-length-of-array-on-stack/9")
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-length-of-array-on-stack/10")
(check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000010/imm32" "F - test-convert-length-of-array-on-stack/11")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-length-of-array-on-stack/12")
@ -2636,7 +2636,7 @@ test-convert-index-into-array-using-offset:
(check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset/7")
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset/8")
(check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 3/imm32" "F - test-convert-index-into-array-using-offset/9")
(check-next-stream-line-equal _test-output-stream " 69/multiply 0x00000004/imm32 %ecx 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10")
(check-next-stream-line-equal _test-output-stream " 69/multiply %ecx 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset/10")
(check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset/11")
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset/12")
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-using-offset/13")
@ -2687,7 +2687,7 @@ test-convert-index-into-array-using-offset-on-stack:
(check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/7")
(check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-index-into-array-using-offset-on-stack/8")
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-index-into-array-using-offset-on-stack/9")
(check-next-stream-line-equal _test-output-stream " 69/multiply 0x00000004/imm32 *(ebp+0xfffffff8) 0x00000001/r32" "F - test-convert-index-into-array-using-offset-on-stack/10")
(check-next-stream-line-equal _test-output-stream " 69/multiply *(ebp+0xfffffff8) 0x00000004/imm32 0x00000001/r32" "F - test-convert-index-into-array-using-offset-on-stack/10")
(check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + ecx + 4) 0x00000000/r32" "F - test-convert-index-into-array-using-offset-on-stack/11")
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-index-into-array-using-offset-on-stack/12")
(check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000004/imm32" "F - test-convert-index-into-array-using-offset-on-stack/13")
@ -2739,7 +2739,7 @@ test-convert-function-and-type-definition:
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-and-type-definition/4")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-and-type-definition/5")
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-function-and-type-definition/6")
(check-next-stream-line-equal _test-output-stream " 8b/copy-from *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7")
(check-next-stream-line-equal _test-output-stream " 8b/-> *(ebp+0x00000008) 0x00000000/r32" "F - test-convert-function-and-type-definition/7")
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-and-type-definition/8")
(check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000000) 0x00000001/r32" "F - test-convert-function-and-type-definition/9")
(check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x00000004) 0x00000001/r32" "F - test-convert-function-and-type-definition/11")
@ -2992,7 +2992,7 @@ test-convert-function-call-with-arg-of-user-defined-type-by-reference:
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/24")
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/25")
(check-next-stream-line-equal _test-output-stream " 89/copy-to %ecx 0x00000001/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/26")
(check-next-stream-line-equal _test-output-stream " 89/<- %ecx 0x00000001/r32" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/26")
(check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/27")
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/28")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29")
@ -3481,7 +3481,7 @@ test-function-header-with-arg:
(clear-stream _test-input-stream)
(write _test-input-stream "foo n: int {\n")
# var result/ecx: function
2b/subtract-> *Function-size 4/r32/esp
2b/subtract *Function-size 4/r32/esp
89/<- %ecx 4/r32/esp
(zero-out %ecx *Function-size)
# var vars/ebx: (stack (addr var) 16)
@ -3514,7 +3514,7 @@ test-function-header-with-multiple-args:
(clear-stream _test-input-stream)
(write _test-input-stream "foo a: int, b: int c: int {\n")
# result/ecx: (handle function)
2b/subtract-> *Function-size 4/r32/esp
2b/subtract *Function-size 4/r32/esp
89/<- %ecx 4/r32/esp
(zero-out %ecx *Function-size)
# var vars/ebx: (stack (addr var) 16)
@ -3566,7 +3566,7 @@ test-function-with-multiple-args-and-outputs:
(clear-stream _test-input-stream)
(write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx: int {\n")
# result/ecx: (handle function)
2b/subtract-> *Function-size 4/r32/esp
2b/subtract *Function-size 4/r32/esp
89/<- %ecx 4/r32/esp
(zero-out %ecx *Function-size)
# var vars/ebx: (stack (addr var) 16)
@ -3954,7 +3954,7 @@ $next-mu-token:check0:
# . ecx = in->read
8b/-> *(esi+4) 1/r32/ecx
# . if (ecx >= in->write) return out = {0, 0}
3b/compare 1/r32/ecx *esi
3b/compare<- *esi 1/r32/ecx
c7 0/subop/copy *edi 0/imm32
c7 0/subop/copy *(edi+4) 0/imm32
0f 8d/jump-if->= $next-mu-token:end/disp32
@ -3962,7 +3962,7 @@ $next-mu-token:check0:
8d/copy-address *(esi+ecx+0xc) 0/r32/eax
89/<- *edi 0/r32/eax
# var curr-byte/eax: byte = in->data[in->read]
31/xor %eax 0/r32/eax
31/xor-with %eax 0/r32/eax
8a/copy-byte *(esi+ecx+0xc) 0/r32/AL
{
$next-mu-token:check-for-comma:
@ -4017,10 +4017,10 @@ $next-mu-token:regular-word-without-metadata:
# . ecx = in->read
8b/-> *(esi+4) 1/r32/ecx
# . if (ecx >= in->write) break
3b/compare *esi 1/r32/ecx
3b/compare<- *esi 1/r32/ecx
7d/jump-if->= break/disp8
# var c/eax: byte = in->data[in->read]
31/xor %eax 0/r32/eax
31/xor-with %eax 0/r32/eax
8a/copy-byte *(esi+ecx+0xc) 0/r32/AL
# if (c == ' ') break
3d/compare-eax-and 0x20/imm32/space
@ -4813,7 +4813,7 @@ new-block-name: # fn: (handle function) -> result/eax: (handle var)
05/add-to-eax 0xd/imm32 # 10 + 2 for '$:'
89/<- %ecx 0/r32/eax
# var name/edx: (stream byte n)
29/subtract %esp 1/r32/ecx
29/subtract-from %esp 1/r32/ecx
ff 6/subop/push %ecx
68/push 0/imm32/read
68/push 0/imm32/write
@ -4834,7 +4834,7 @@ new-block-name: # fn: (handle function) -> result/eax: (handle var)
# . edx = name->data
8d/copy-address *(edx+0xc) 2/r32/edx
# . eax = name->write + name->data
01/add %eax 2/r32/edx
01/add-to %eax 2/r32/edx
# . push {edx, eax}
ff 6/subop/push %eax
ff 6/subop/push %edx
@ -4845,7 +4845,7 @@ $new-block-name:end:
# . reclaim locals
81 0/subop/add %ecx 0xc/imm32 # name.{read/write/len}
81 0/subop/add %ecx 8/imm32 # slice
01/add %esp 1/r32/ecx
01/add-to %esp 1/r32/ecx
# . restore registers
5a/pop-to-edx
59/pop-to-ecx
@ -5429,7 +5429,7 @@ lookup-var-helper: # name: (addr array byte), vars: (addr stack (handle var)) -
# ebx = vars->top
8b/-> *esi 3/r32/ebx
# if (vars->top > vars->length) abort
3b/compare 0/r32/eax *(esi+4)
3b/compare<- *(esi+4) 0/r32/eax
0f 8f/jump-if-> $lookup-var-helper:error1/disp32
# var min/edx: (addr handle var) = vars->data
8d/copy-address *(esi+8) 2/r32/edx
@ -6649,7 +6649,7 @@ is-mu-array?: # t: (handle tree type-id) -> result/eax: boolean
8b/-> *(ebp+8) 1/r32/ecx
8b/-> *ecx 1/r32/ecx # Tree-left
# if t is an atomic type, return false
3b/compare 1/r32/ecx *Max-type-id
3b/compare<- *Max-type-id 1/r32/ecx
b8/copy-to-eax 0/imm32/false
72/jump-if-addr< $is-mu-array?:end/disp8
# return ecx->value == array
@ -6875,7 +6875,7 @@ $populate-mu-type-offsets-in-inouts:loop:
89/<- *(ebx+0xc) 2/r32/edx # Var-offset
# next-offset += size-of(v)
(size-of %ebx) # => eax
01/add %edx 0/r32/eax
01/add-to %edx 0/r32/eax
# curr = curr->next
8b/-> *(ecx+4) 1/r32/ecx # List-next
eb/jump loop/disp8
@ -7646,7 +7646,7 @@ $clean-up-blocks:reclaim-loop:
75/jump-if-!= break/disp8
$clean-up-blocks:reclaim-var-on-stack:
(size-of %eax) # => eax
01/add *Curr-local-stack-offset 0/r32/eax
01/add-to *Curr-local-stack-offset 0/r32/eax
}
(pop %esi)
e9/jump loop/disp32
@ -7810,7 +7810,7 @@ translate-mu-length-stmt: # out: (address buffered-file), stmt: (handle stmt)
8b/-> *(ebp+0xc) 1/r32/ecx
#
(emit-indent *(ebp+8) *Curr-block-depth)
(write-buffered *(ebp+8) "8b/copy-from *")
(write-buffered *(ebp+8) "8b/-> *")
# var base/eax: (handle var) = inouts[0]
8b/-> *(ecx+8) 0/r32/eax # Stmt1-inouts or Regvardef-inouts
8b/-> *eax 0/r32/eax # Stmt-var-value
@ -7951,7 +7951,7 @@ $translate-mu-index-stmt-with-array-in-register:emit-int-register-index:
# if index->type is any other atom, abort
8b/-> *(edx+4) 0/r32/eax # Var-type
8b/-> *eax 0/r32/eax # Tree-left or Atom-value
3b/compare 0/r32/eax *Max-type-id
3b/compare<- *Max-type-id 0/r32/eax
0f 82/jump-if-addr< $translate-mu-index-stmt-with-array:error2/disp32
# if index has type (offset ...)
(is-simple-mu-type? %eax 7) # offset => eax
@ -8061,7 +8061,7 @@ $translate-mu-index-stmt-with-array-on-stack:emit-int-register-index:
# if index->type is any other atom, abort
8b/-> *(edx+4) 0/r32/eax # Var-type
8b/-> *eax 0/r32/eax # Tree-left or Atom-value
3b/compare 0/r32/eax *Max-type-id
3b/compare<- *Max-type-id 0/r32/eax
0f 82/jump-if-addr< $translate-mu-index-stmt-with-array:error2/disp32
# if index has type (offset ...)
(is-simple-mu-type? %eax 7) # offset => eax
@ -8090,7 +8090,7 @@ $translate-mu-index-stmt-with-array-on-stack:emit-literal-index:
(size-of-type-id %eax) # => eax
f7 4/subop/multiply-into-eax %ebx # clobbers edx
# offset += base->offset
03/add-to 0/r32/eax *(ecx+0xc) # Var-offset
03/add *(ecx+0xc) 0/r32/eax # Var-offset
# offset += 4 for array size
05/add-to-eax 4/imm32
# TODO: check edx for overflow
@ -8131,22 +8131,22 @@ translate-mu-compute-index-stmt: # out: (address buffered-file), stmt: (handle
53/push-ebx
#
(emit-indent *(ebp+8) *Curr-block-depth)
(write-buffered *(ebp+8) "69/multiply ")
$translate-mu-compute-index-stmt:emit-elem-size:
(write-buffered *(ebp+8) "69/multiply")
# ecx = stmt
8b/-> *(ebp+0xc) 1/r32/ecx
# var first-inout/edx: (handle stmt-var) = stmt->inouts[0]
8b/-> *(ecx+8) 2/r32/edx # Stmt1-inouts
$translate-mu-compute-index-stmt:emit-index:
(emit-subx-var-as-rm32 *(ebp+8) *(edx+4)) # Stmt-var-next
(write-buffered *(ebp+8) Space)
$translate-mu-compute-index-stmt:emit-elem-size:
# var base/ebx: (handle var)
8b/-> *edx 3/r32/ebx # Stmt-var-value
# print size-of(element(base->type))
(array-element-type-id %ebx) # => eax
(size-of-type-id %eax) # => eax
(print-int32-buffered *(ebp+8) %eax)
(write-buffered *(ebp+8) "/imm32")
$translate-mu-compute-index-stmt:emit-index:
(emit-subx-var-as-rm32 *(ebp+8) *(edx+4)) # Stmt-var-next
(write-buffered *(ebp+8) Space)
(write-buffered *(ebp+8) "/imm32 ")
$translate-mu-compute-index-stmt:emit-output:
# outputs[0] "/r32"
8b/-> *(ecx+0xc) 0/r32/eax # Stmt1-outputs
@ -8202,7 +8202,7 @@ $translate-mu-get-stmt:emit-register-input:
$translate-mu-get-stmt:emit-stack-input:
# "*(ebp + " inouts[0]->offset + offset ")"
(write-buffered *(ebp+8) "*(ebp+")
03/add-from *(eax+0xc) 2/r32/edx # Var-offset
03/add *(eax+0xc) 2/r32/edx # Var-offset
(print-int32-buffered *(ebp+8) %edx)
(write-buffered *(ebp+8) ") ")
eb/jump $translate-mu-get-stmt:emit-output/disp8
@ -8246,26 +8246,6 @@ $array-element-type-id:end:
5d/pop-to-ebp
c3/return
power-of-2?: # n: int -> result/eax: boolean
# precondition: n is positive
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# var tmp/eax: int = n-1
8b/-> *(ebp+8) 0/r32/eax
48/decrement-eax
# var tmp2/eax: int = n & tmp
0b/and-> *(ebp+8) 0/r32/eax
# return (tmp2 == 0)
3d/compare-eax-and 0/imm32
0f 94/set-byte-if-= %al
81 4/subop/and %eax 0xff/imm32
$power-of-2?:end:
# . epilogue
89/<- %esp 5/r32/ebp
5d/pop-to-ebp
c3/return
num-shift-rights: # n: int -> result/eax: int
# precondition: n is a positive power of 2
# . prologue
@ -8995,11 +8975,11 @@ _Primitive-copy-to-edi:
1/imm32/output-is-write-only
_Primitive-copy-reg-to-reg/imm32/next
_Primitive-copy-reg-to-reg:
# var1/reg <- copy var2/reg => 89/copy-to var1/rm32 var2/r32
# var1/reg <- copy var2/reg => 89/<- var1/rm32 var2/r32
"copy"/imm32/name
Single-int-var-in-some-register/imm32/inouts
Single-int-var-in-some-register/imm32/outputs
"89/copy-to"/imm32/subx-name
"89/<-"/imm32/subx-name
3/imm32/rm32-is-first-output
1/imm32/r32-is-first-inout
0/imm32/no-imm32
@ -9007,11 +8987,11 @@ _Primitive-copy-reg-to-reg:
1/imm32/output-is-write-only
_Primitive-copy-reg-to-mem/imm32/next
_Primitive-copy-reg-to-mem:
# copy-to var1 var2/reg => 89/copy-to var1 var2/r32
# copy-to var1 var2/reg => 89/<- var1 var2/r32
"copy-to"/imm32/name
Two-args-int-stack-int-reg/imm32/inouts
0/imm32/outputs
"89/copy-to"/imm32/subx-name
"89/<-"/imm32/subx-name
1/imm32/rm32-is-first-inout
2/imm32/r32-is-second-inout
0/imm32/no-imm32
@ -9019,11 +8999,11 @@ _Primitive-copy-reg-to-mem:
1/imm32/output-is-write-only
_Primitive-copy-mem-to-reg/imm32/next
_Primitive-copy-mem-to-reg:
# var1/reg <- copy var2 => 8b/copy-from var2/rm32 var1/r32
# var1/reg <- copy var2 => 8b/-> var2/rm32 var1/r32
"copy"/imm32/name
Single-int-var-in-mem/imm32/inouts
Single-int-var-in-some-register/imm32/outputs
"8b/copy-from"/imm32/subx-name
"8b/->"/imm32/subx-name
1/imm32/rm32-is-first-inout
3/imm32/r32-is-first-output
0/imm32/no-imm32
@ -9069,7 +9049,7 @@ _Primitive-address:
_Primitive-compare-mem-with-reg/imm32/next
# - compare
_Primitive-compare-mem-with-reg:
# compare var1 var2/reg => 39/compare-> var1/rm32 var2/r32
# compare var1 var2/reg => 39/compare var1/rm32 var2/r32
"compare"/imm32/name
Two-args-int-stack-int-reg/imm32/inouts
0/imm32/outputs
@ -10165,7 +10145,7 @@ emit-subx-call-operand-stack: # out: (addr buffered-file), v: (handle var)
# var max/eax: int = v->offset + size-of(v)
(size-of %esi) # => eax
# TODO: assert size is a multiple of 4
01/add %eax 1/r32/ecx
01/add-to %eax 1/r32/ecx
{
$emit-subx-call-operand-stack:loop:
# if (curr >= max) break
@ -11081,7 +11061,7 @@ test-increment-var:
test-add-reg-to-reg:
# var1/reg <- add var2/reg
# =>
# 01/add %var1 var2
# 01/add-to %var1 var2
#
# . prologue
55/push-ebp
@ -11144,7 +11124,7 @@ test-add-reg-to-reg:
test-add-reg-to-mem:
# add-to var1 var2/reg
# =>
# 01/add *(ebp+__) var2
# 01/add-to *(ebp+__) var2
#
# . prologue
55/push-ebp
@ -11533,7 +11513,7 @@ test-compare-mem-with-reg:
test-compare-reg-with-mem:
# compare var1/eax, var2
# =>
# 3b/compare *(ebp+___) 0/r32/eax
# 3b/compare<- *(ebp+___) 0/r32/eax
#
# . prologue
55/push-ebp

View File

@ -26,14 +26,14 @@ There are no checks for types yet, because Mu programs only have `int` types so
Example 1 (use the widest screen you can for this page):
-- instruction form -- | -------------------------- data structure ----------------------------
|<------------- pattern matching ---------->|<--- code generation ------------------->
var/reg <- add var2/reg {.name="add", .inouts=[reg], .outputs=[reg], .subx-name="01/add<-", .rm32=outputs[0], .r32=inouts[0]}
var/reg <- add var2/reg {.name="add", .inouts=[reg], .outputs=[reg], .subx-name="01/add-to", .rm32=outputs[0], .r32=inouts[0]}
Read this as:
if an instruction's name is "add"
and it has one inout that's in a register
and it has one output that's in a register,
then emit the following on a single line
"01/add<-" (the opcode or subx-name)
"01/add-to" (the opcode or subx-name)
"%{reg}", interpolating the output's register
"{reg}/r32", interpolating the inout's register code.
@ -74,46 +74,46 @@ var/edi <- decrement {.name="decrement", .outputs=[
decrement var {.name="decrement", .inouts=[var], .subx-name="ff 1/subop/decrement", .rm32="*(ebp+" inouts[0].stack-offset ")"}
decrement *var/reg {.name="decrement", .inouts=[reg], .subx-name="ff 1/subop/decrement", .rm32="*" inouts[0]}
var1/reg1 <- add var2/reg2 {.name="add", .inouts=[reg2], .outputs=[reg1], .subx-name="01/add<-", .rm32=outputs[0], .r32=inouts[0]}
var/reg <- add var2 {.name="add", .inouts=[var2], .outputs=[reg], .subx-name="03/add->", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
var/reg <- add *var2/reg2 {.name="add", .inouts=[reg2], .outputs=[reg], .subx-name="03/add->", .rm32="*" inouts[0], .r32=outputs[0]}
add-to var1, var2/reg {.name="add-to", .inouts=[var1, var2], .subx-name="01/add<-", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
var1/reg1 <- add var2/reg2 {.name="add", .inouts=[reg2], .outputs=[reg1], .subx-name="01/add-to", .rm32=outputs[0], .r32=inouts[0]}
var/reg <- add var2 {.name="add", .inouts=[var2], .outputs=[reg], .subx-name="03/add", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
var/reg <- add *var2/reg2 {.name="add", .inouts=[reg2], .outputs=[reg], .subx-name="03/add", .rm32="*" inouts[0], .r32=outputs[0]}
add-to var1, var2/reg {.name="add-to", .inouts=[var1, var2], .subx-name="01/add-to", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
var/eax <- add n {.name="add", .inouts=[n], .outputs=[eax], .subx-name="05/add-to-eax", .imm32=inouts[0]}
var/reg <- add n {.name="add", .inouts=[n], .outputs=[reg], .subx-name="81 0/subop/add", .rm32=outputs[0], .imm32=inouts[0]}
add-to var, n {.name="add-to", .inouts=[var, n], .subx-name="81 0/subop/add", .rm32="*(ebp+" inouts[0].stack-offset ")", .imm32=inouts[1]}
add-to *var/reg, n {.name="add-to", .inouts=[reg, n], .subx-name="81 0/subop/add", .rm32="*" inouts[0], .imm32=inouts[1]}
var1/reg1 <- sub var2/reg2 {.name="sub", .inouts=[reg2], .outputs=[reg1], .subx-name="29/sub<-", .rm32=outputs[0], .r32=inouts[0]}
var/reg <- sub var2 {.name="sub", .inouts=[var2], .outputs=[reg], .subx-name="2b/sub->", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
var/reg <- sub *var2/reg2 {.name="sub", .inouts=[reg2], .outputs=[reg], .subx-name="2b/sub->", .rm32="*" inouts[0], .r32=outputs[0]}
sub-from var1, var2/reg {.name="sub-from", .inouts=[var1, var2], .subx-name="29/sub<-", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
var/eax <- sub n {.name="sub", .inouts=[n], .outputs=[eax], .subx-name="2d/sub-from-eax", .imm32=inouts[0]}
var1/reg1 <- sub var2/reg2 {.name="sub", .inouts=[reg2], .outputs=[reg1], .subx-name="29/subtract-from", .rm32=outputs[0], .r32=inouts[0]}
var/reg <- sub var2 {.name="sub", .inouts=[var2], .outputs=[reg], .subx-name="2b/subtract", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
var/reg <- sub *var2/reg2 {.name="sub", .inouts=[reg2], .outputs=[reg], .subx-name="2b/subtract", .rm32="*" inouts[0], .r32=outputs[0]}
sub-from var1, var2/reg {.name="sub-from", .inouts=[var1, var2], .subx-name="29/subtract-from", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
var/eax <- sub n {.name="sub", .inouts=[n], .outputs=[eax], .subx-name="2d/subtract-from-eax", .imm32=inouts[0]}
var/reg <- sub n {.name="sub", .inouts=[n], .outputs=[reg], .subx-name="81 5/subop/subtract", .rm32=outputs[0], .imm32=inouts[0]}
sub-from var, n {.name="sub-from", .inouts=[var, n], .subx-name="81 5/subop/subtract", .rm32="*(ebp+" inouts[0].stack-offset ")", .imm32=inouts[1]}
sub-from *var/reg, n {.name="sub-from", .inouts=[reg, n], .subx-name="81 5/subop/subtract", .rm32="*" inouts[0], .imm32=inouts[1]}
var1/reg1 <- and var2/reg2 {.name="and", .inouts=[reg2], .outputs=[reg1], .subx-name="21/and<-", .rm32=outputs[0], .r32=inouts[0]}
var/reg <- and var2 {.name="and", .inouts=[var2], .outputs=[reg], .subx-name="23/and->", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
var/reg <- and *var2/reg2 {.name="and", .inouts=[reg2], .outputs=[reg], .subx-name="23/and->", .rm32="*" inouts[0], .r32=outputs[0]}
and-with var1, var2/reg {.name="and-with", .inouts=[var1, reg], .subx-name="21/and<-", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
var1/reg1 <- and var2/reg2 {.name="and", .inouts=[reg2], .outputs=[reg1], .subx-name="21/and-with", .rm32=outputs[0], .r32=inouts[0]}
var/reg <- and var2 {.name="and", .inouts=[var2], .outputs=[reg], .subx-name="23/and", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
var/reg <- and *var2/reg2 {.name="and", .inouts=[reg2], .outputs=[reg], .subx-name="23/and", .rm32="*" inouts[0], .r32=outputs[0]}
and-with var1, var2/reg {.name="and-with", .inouts=[var1, reg], .subx-name="21/and-with", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
var/eax <- and n {.name="and", .inouts=[n], .outputs=[eax], .subx-name="25/and-with-eax", .imm32=inouts[0]}
var/reg <- and n {.name="and", .inouts=[n], .outputs=[reg], .subx-name="81 4/subop/and", .rm32=outputs[0], .imm32=inouts[0]}
and-with var, n {.name="and-with", .inouts=[var, n], .subx-name="81 4/subop/and", .rm32="*(ebp+" inouts[0].stack-offset ")", .imm32=inouts[1]}
and-with *var/reg, n {.name="and-with", .inouts=[reg, n], .subx-name="81 4/subop/and", .rm32="*" inouts[0], .imm32=inouts[1]}
var1/reg1 <- or var2/reg2 {.name="or", .inouts=[reg2], .outputs=[reg1], .subx-name="09/or<-", .rm32=outputs[0], .r32=inouts[0]}
var/reg <- or var2 {.name="or", .inouts=[var2], .outputs=[reg], .subx-name="0b/or->", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
var/reg <- or *var2/reg2 {.name="or", .inouts=[reg2], .outputs=[reg], .subx-name="0b/or->", .rm32="*" inouts[0], .r32=outputs[0]}
or-with var1, var2/reg {.name="or-with", .inouts=[var1, reg], .subx-name="09/or<-", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
var1/reg1 <- or var2/reg2 {.name="or", .inouts=[reg2], .outputs=[reg1], .subx-name="09/or-with", .rm32=outputs[0], .r32=inouts[0]}
var/reg <- or var2 {.name="or", .inouts=[var2], .outputs=[reg], .subx-name="0b/or", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
var/reg <- or *var2/reg2 {.name="or", .inouts=[reg2], .outputs=[reg], .subx-name="0b/or", .rm32="*" inouts[0], .r32=outputs[0]}
or-with var1, var2/reg {.name="or-with", .inouts=[var1, reg], .subx-name="09/or-with", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
var/eax <- or n {.name="or", .inouts=[n], .outputs=[eax], .subx-name="0d/or-with-eax", .imm32=inouts[0]}
var/reg <- or n {.name="or", .inouts=[n], .outputs=[reg], .subx-name="81 1/subop/or", .rm32=outputs[0], .imm32=inouts[0]}
or-with var, n {.name="or-with", .inouts=[var, n], .subx-name="81 1/subop/or", .rm32="*(ebp+" inouts[0].stack-offset ")", .imm32=inouts[1]}
or-with *var/reg, n {.name="or-with", .inouts=[reg, n], .subx-name="81 1/subop/or", .rm32="*" inouts[0], .imm32=inouts[1]}
var1/reg1 <- xor var2/reg2 {.name="xor", .inouts=[reg2], .outputs=[reg1], .subx-name="31/xor<-", .rm32=outputs[0], .r32=inouts[0]}
var/reg <- xor var2 {.name="xor", .inouts=[var2], .outputs=[reg], .subx-name="33/xor->", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
var/reg <- xor *var2/reg2 {.name="xor", .inouts=[reg2], .outputs=[reg], .subx-name="33/xor->", .rm32="*" inouts[0], .r32=outputs[0]}
xor-with var1, var2/reg {.name="xor-with", .inouts=[var1, reg], .subx-name="31/xor<-", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
var1/reg1 <- xor var2/reg2 {.name="xor", .inouts=[reg2], .outputs=[reg1], .subx-name="31/xor-with", .rm32=outputs[0], .r32=inouts[0]}
var/reg <- xor var2 {.name="xor", .inouts=[var2], .outputs=[reg], .subx-name="33/xor", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
var/reg <- xor *var2/reg2 {.name="xor", .inouts=[reg2], .outputs=[reg], .subx-name="33/xor", .rm32="*" inouts[0], .r32=outputs[0]}
xor-with var1, var2/reg {.name="xor-with", .inouts=[var1, reg], .subx-name="31/xor-with", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
var/eax <- xor n {.name="xor", .inouts=[n], .outputs=[eax], .subx-name="35/xor-with-eax", .imm32=inouts[0]}
var/reg <- xor n {.name="xor", .inouts=[n], .outputs=[reg], .subx-name="81 6/subop/xor", .rm32=outputs[0], .imm32=inouts[0]}
xor-with var, n {.name="xor-with", .inouts=[var, n], .subx-name="81 6/subop/xor", .rm32="*(ebp+" inouts[0].stack-offset ")", .imm32=inouts[1]}
@ -125,16 +125,16 @@ var/edx <- copy n {.name="copy", .inouts=[n], .outputs=[
var/ebx <- copy n {.name="copy", .inouts=[n], .outputs=[ebx], .subx-name="bb/copy-to-ebx", .imm32=inouts[0]}
var/esi <- copy n {.name="copy", .inouts=[n], .outputs=[esi], .subx-name="be/copy-to-esi", .imm32=inouts[0]}
var/edi <- copy n {.name="copy", .inouts=[n], .outputs=[edi], .subx-name="bf/copy-to-edi", .imm32=inouts[0]}
var1/reg1 <- copy var2/reg2 {.name="copy", .inouts=[reg2], .outputs=[reg1], .subx-name="89/copy-to", .rm32=outputs[0], .r32=inouts[0]}
copy-to var1, var2/reg {.name="copy-to", .inouts=[var1, var2], .subx-name="01/add<-", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
var/reg <- copy var2 {.name="copy", .inouts=[var2], .outputs=[reg], .subx-name="8b/copy-from", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
var1/reg <- copy *var2/reg2 {.name="copy", .inouts=[reg2], .outputs=[reg], .subx-name="8b/copy-from", .rm32="*" inouts[0], .r32=outputs[0]}
var1/reg1 <- copy var2/reg2 {.name="copy", .inouts=[reg2], .outputs=[reg1], .subx-name="89/<-", .rm32=outputs[0], .r32=inouts[0]}
copy-to var1, var2/reg {.name="copy-to", .inouts=[var1, var2], .subx-name="89/<-", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
var/reg <- copy var2 {.name="copy", .inouts=[var2], .outputs=[reg], .subx-name="8b/->", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=outputs[0]}
var1/reg <- copy *var2/reg2 {.name="copy", .inouts=[reg2], .outputs=[reg], .subx-name="8b/->", .rm32="*" inouts[0], .r32=outputs[0]}
var/reg <- copy n {.name="copy", .inouts=[n], .outputs=[reg], .subx-name="c7 0/subop/copy", .rm32=outputs[0], .imm32=inouts[0]}
copy-to var, n {.name="copy-to", .inouts=[var, n], .subx-name="c7 0/subop/copy", .rm32="*(ebp+" inouts[0].stack-offset ")", .imm32=inouts[1]}
copy-to *var/reg, n {.name="copy-to", .inouts=[reg, n], .subx-name="c7 0/subop/copy", .rm32="*" inouts[0], .imm32=inouts[1]}
compare var1, var2/reg {.name="compare", .inouts=[var1, reg], .subx-name="39/compare->", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
compare *var1/reg1, var/reg {.name="compare", .inouts=[reg1, reg], .subx-name="39/compare->", .rm32="*" inouts[0], .r32=inouts[1]}
compare var1, var2/reg {.name="compare", .inouts=[var1, reg], .subx-name="39/compare", .rm32="*(ebp+" inouts[0].stack-offset ")", .r32=inouts[1]}
compare *var1/reg1, var/reg {.name="compare", .inouts=[reg1, reg], .subx-name="39/compare", .rm32="*" inouts[0], .r32=inouts[1]}
compare var1/reg, var2 {.name="compare", .inouts=[reg, var2], .subx-name="3b/compare<-", .rm32="*(ebp+" inouts[1].stack-offset ")", .r32=inouts[0]}
compare var/reg, *var2/reg2 {.name="compare", .inouts=[reg, reg2], .subx-name="3b/compare<-", .rm32="*" inouts[1], .r32=inouts[0]}
compare var/eax, n {.name="compare", .inouts=[eax, n], .subx-name="3d/compare-eax-with", .imm32=inouts[1]}