6915 - a new family of Mu branch instructions

The realization of commit 6916 means that we should be using jump-if-addr*
after comparing floats. Which is super ugly. Let's create aliases to them
called jump-if-float*.
This commit is contained in:
Kartik Agaram 2020-09-30 23:46:43 -07:00
parent bc3ebe820b
commit 8d32a9aab9
3 changed files with 432 additions and 2 deletions

View File

@ -3177,6 +3177,65 @@ test-convert-function-with-branches-in-block:
5d/pop-to-ebp 5d/pop-to-ebp
c3/return c3/return
test-convert-function-with-branches-in-block-2:
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# setup
(clear-stream _test-input-stream)
(clear-stream $_test-input-buffered-file->buffer)
(clear-stream _test-output-stream)
(clear-stream $_test-output-buffered-file->buffer)
#
(write _test-input-stream "fn foo x: int {\n")
(write _test-input-stream " {\n")
(write _test-input-stream " break-if->=\n")
(write _test-input-stream " loop-if-float<\n")
(write _test-input-stream " increment x\n")
(write _test-input-stream " loop\n")
(write _test-input-stream " }\n")
(write _test-input-stream "}\n")
# convert
(convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 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 "foo:" "F - test-convert-function-with-branches-in-block/0")
(check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-branches-in-block/1")
(check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-branches-in-block/2")
(check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-branches-in-block/3")
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/4")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-branches-in-block/5")
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/6")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:" "F - test-convert-function-with-branches-in-block/7")
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/8")
(check-next-stream-line-equal _test-output-stream " 0f 8c/jump-if-< break/disp32" "F - test-convert-function-with-branches-in-block/9")
(check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:break/disp32" "F - test-convert-function-with-branches-in-block/10")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/11")
(check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-branches-in-block/12")
(check-next-stream-line-equal _test-output-stream " 0f 83/jump-if-addr>= break/disp32" "F - test-convert-function-with-branches-in-block/13")
(check-next-stream-line-equal _test-output-stream " e9/jump $foo:0x00000002:loop/disp32" "F - test-convert-function-with-branches-in-block/14")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/15")
(check-next-stream-line-equal _test-output-stream " ff 0/subop/increment *(ebp+0x00000008)" "F - test-convert-function-with-branches-in-block/16")
(check-next-stream-line-equal _test-output-stream " e9/jump loop/disp32" "F - test-convert-function-with-branches-in-block/17")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/18")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:" "F - test-convert-function-with-branches-in-block/19")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-branches-in-block/20")
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-branches-in-block/21")
(check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-branches-in-block/22")
(check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-branches-in-block/23")
(check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-branches-in-block/24")
(check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-branches-in-block/25")
# . epilogue
89/<- %esp 5/r32/ebp
5d/pop-to-ebp
c3/return
test-convert-function-with-branches-in-named-block: test-convert-function-with-branches-in-named-block:
# . prologue # . prologue
55/push-ebp 55/push-ebp
@ -15616,9 +15675,9 @@ $emit-reverse-break:end:
# Table from Mu branch instructions to the reverse SubX opcodes for them. # Table from Mu branch instructions to the reverse SubX opcodes for them.
Reverse-branch: # (table (handle array byte) (handle array byte)) Reverse-branch: # (table (handle array byte) (handle array byte))
# a table is a stream # a table is a stream
0x140/imm32/write 0x1c0/imm32/write
0/imm32/read 0/imm32/read
0x140/imm32/size 0x1c0/imm32/size
# data # data
0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 0x11/imm32/alloc-id _string-break-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32
0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32 0x11/imm32/alloc-id _string-loop-if-=/imm32 0x11/imm32/alloc-id _string_0f_85_jump_label/imm32
@ -15640,6 +15699,14 @@ Reverse-branch: # (table (handle array byte) (handle array byte))
0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32 0x11/imm32/alloc-id _string-loop-if-addr<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32
0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 0x11/imm32/alloc-id _string-break-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32 0x11/imm32/alloc-id _string-loop-if-addr>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
0x11/imm32/alloc-id _string-break-if-float</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32
0x11/imm32/alloc-id _string-loop-if-float</imm32 0x11/imm32/alloc-id _string_0f_83_jump_label/imm32
0x11/imm32/alloc-id _string-break-if-float>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32
0x11/imm32/alloc-id _string-loop-if-float>/imm32 0x11/imm32/alloc-id _string_0f_86_jump_label/imm32
0x11/imm32/alloc-id _string-break-if-float<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32
0x11/imm32/alloc-id _string-loop-if-float<=/imm32 0x11/imm32/alloc-id _string_0f_87_jump_label/imm32
0x11/imm32/alloc-id _string-break-if-float>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
0x11/imm32/alloc-id _string-loop-if-float>=/imm32 0x11/imm32/alloc-id _string_0f_82_jump_label/imm32
== code == code
@ -20933,6 +21000,311 @@ _Primitive-loop-named: # (payload primitive)
1/imm32/disp32-is-first-inout 1/imm32/disp32-is-first-inout
0/imm32/no-xm32 0/imm32/no-xm32
0/imm32/no-x32 0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-break-if-float</imm32/next
# - branches based on floating-point comparisons
_Primitive-break-if-float<: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-break-if-float</imm32/name
0/imm32/no-inouts
0/imm32/no-inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_82_jump_break/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
0/imm32/no-disp32
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-break-if-float>=/imm32/next
_Primitive-break-if-float>=: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-break-if-float>=/imm32/name
0/imm32/no-inouts
0/imm32/no-inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_83_jump_break/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
0/imm32/no-disp32
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-break-if-float<=/imm32/next
_Primitive-break-if-float<=: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-break-if-float<=/imm32/name
0/imm32/no-inouts
0/imm32/no-inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_86_jump_break/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
0/imm32/no-disp32
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-break-if-float>/imm32/next
_Primitive-break-if-float>: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-break-if-float>/imm32/name
0/imm32/no-inouts
0/imm32/no-inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_87_jump_break/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
0/imm32/no-disp32
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-loop-if-float</imm32/next
_Primitive-loop-if-float<: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-loop-if-float</imm32/name
0/imm32/no-inouts
0/imm32/no-inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_82_jump_loop/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
0/imm32/no-disp32
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-loop-if-float>=/imm32/next
_Primitive-loop-if-float>=: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-loop-if-float>=/imm32/name
0/imm32/no-inouts
0/imm32/no-inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_83_jump_loop/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
0/imm32/no-disp32
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-loop-if-float<=/imm32/next
_Primitive-loop-if-float<=: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-loop-if-float<=/imm32/name
0/imm32/no-inouts
0/imm32/no-inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_86_jump_loop/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
0/imm32/no-disp32
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-loop-if-float>/imm32/next
_Primitive-loop-if-float>: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-loop-if-float>/imm32/name
0/imm32/no-inouts
0/imm32/no-inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_87_jump_loop/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
0/imm32/no-disp32
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-break-if-float<-named/imm32/next
_Primitive-break-if-float<-named: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-break-if-float</imm32/name
0x11/imm32/alloc-id:fake
Single-lit-var/imm32/inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_82_jump_label/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
1/imm32/disp32-is-first-inout
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-break-if-float>=-named/imm32/next
_Primitive-break-if-float>=-named: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-break-if-float>=/imm32/name
0x11/imm32/alloc-id:fake
Single-lit-var/imm32/inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_83_jump_label/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
1/imm32/disp32-is-first-inout
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-break-if-float<=-named/imm32/next
_Primitive-break-if-float<=-named: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-break-if-float<=/imm32/name
0x11/imm32/alloc-id:fake
Single-lit-var/imm32/inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_86_jump_label/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
1/imm32/disp32-is-first-inout
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-break-if-float>-named/imm32/next
_Primitive-break-if-float>-named: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-break-if-float>/imm32/name
0x11/imm32/alloc-id:fake
Single-lit-var/imm32/inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_87_jump_label/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
1/imm32/disp32-is-first-inout
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-loop-if-float<-named/imm32/next
_Primitive-loop-if-float<-named: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-loop-if-float</imm32/name
0x11/imm32/alloc-id:fake
Single-lit-var/imm32/inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_82_jump_label/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
1/imm32/disp32-is-first-inout
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-loop-if-float>=-named/imm32/next
_Primitive-loop-if-float>=-named: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-loop-if-float>=/imm32/name
0x11/imm32/alloc-id:fake
Single-lit-var/imm32/inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_83_jump_label/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
1/imm32/disp32-is-first-inout
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-loop-if-float<=-named/imm32/next
_Primitive-loop-if-float<=-named: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-loop-if-float<=/imm32/name
0x11/imm32/alloc-id:fake
Single-lit-var/imm32/inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_86_jump_label/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
1/imm32/disp32-is-first-inout
0/imm32/no-xm32
0/imm32/no-x32
0x11/imm32/alloc-id:fake
_Primitive-loop-if-float>-named/imm32/next
_Primitive-loop-if-float>-named: # (payload primitive)
0x11/imm32/alloc-id:fake:payload
0x11/imm32/alloc-id:fake
_string-loop-if-float>/imm32/name
0x11/imm32/alloc-id:fake
Single-lit-var/imm32/inouts
0/imm32/no-outputs
0/imm32/no-outputs
0x11/imm32/alloc-id:fake
_string_0f_87_jump_label/imm32/subx-name
0/imm32/no-rm32
0/imm32/no-r32
0/imm32/no-imm32
0/imm32/no-imm8
1/imm32/disp32-is-first-inout
0/imm32/no-xm32
0/imm32/no-x32
0/imm32/next 0/imm32/next
0/imm32/next 0/imm32/next
@ -21017,6 +21389,26 @@ _string-break-if-addr>=: # (payload array byte)
# "break-if-addr>=" # "break-if-addr>="
0xf/imm32/size 0xf/imm32/size
0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/=
_string-break-if-float<: # (payload array byte)
0x11/imm32/alloc-id:fake:payload
# "break-if-float<"
0xf/imm32/size
0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/<
_string-break-if-float<=: # (payload array byte)
0x11/imm32/alloc-id:fake:payload
# "break-if-float<="
0x10/imm32/size
0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/< 0x3d/=
_string-break-if-float>: # (payload array byte)
0x11/imm32/alloc-id:fake:payload
# "break-if-float>"
0xf/imm32/size
0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/>
_string-break-if-float>=: # (payload array byte)
0x11/imm32/alloc-id:fake:payload
# "break-if-float>="
0x10/imm32/size
0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> 0x3d/=
_string-compare: # (payload array byte) _string-compare: # (payload array byte)
0x11/imm32/alloc-id:fake:payload 0x11/imm32/alloc-id:fake:payload
# "compare" # "compare"
@ -21107,6 +21499,26 @@ _string-loop-if-addr>=: # (payload array byte)
# "loop-if-addr>=" # "loop-if-addr>="
0xe/imm32/size 0xe/imm32/size
0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/= 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x61/a 0x64/d 0x64/d 0x72/r 0x3e/> 0x3d/=
_string-loop-if-float<: # (payload array byte)
0x11/imm32/alloc-id:fake:payload
# "loop-if-float<"
0xe/imm32/size
0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/<
_string-loop-if-float<=: # (payload array byte)
0x11/imm32/alloc-id:fake:payload
# "loop-if-float<="
0xf/imm32/size
0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3c/< 0x3d/=
_string-loop-if-float>: # (payload array byte)
0x11/imm32/alloc-id:fake:payload
# "loop-if-float>"
0xe/imm32/size
0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/>
_string-loop-if-float>=: # (payload array byte)
0x11/imm32/alloc-id:fake:payload
# "loop-if-float>="
0xf/imm32/size
0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x66/f 0x6c/l 0x6f/o 0x61/a 0x74/t 0x3e/> 0x3d/=
_string-multiply: # (payload array byte) _string-multiply: # (payload array byte)
0x11/imm32/alloc-id:fake:payload 0x11/imm32/alloc-id:fake:payload
# "multiply" # "multiply"
@ -22748,6 +23160,9 @@ $mu-stmt-matches-primitive?:check-name:
89/<- %esi 0/r32/eax 89/<- %esi 0/r32/eax
# . var edi: (addr array byte) = lookup(primitive->name) # . var edi: (addr array byte) = lookup(primitive->name)
(lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax (lookup *edx *(edx+4)) # Primitive-name Primitive-name => eax
#? (write-buffered Stderr %eax)
#? (write-buffered Stderr Newline)
#? (flush Stderr)
89/<- %edi 0/r32/eax 89/<- %edi 0/r32/eax
(string-equal? %esi %edi) # => eax (string-equal? %esi %edi) # => eax
3d/compare-eax-and 0/imm32/false 3d/compare-eax-and 0/imm32/false

9
mu.md
View File

@ -371,6 +371,15 @@ break-if-addr<=
break-if-addr<= label break-if-addr<= label
break-if-addr>= break-if-addr>=
break-if-addr>= label break-if-addr>= label
break-if-float<
break-if-float< label
break-if-float>
break-if-float> label
break-if-float<=
break-if-float<= label
break-if-float>=
break-if-float>= label
``` ```
Similarly, conditional loops: Similarly, conditional loops:

View File

@ -177,6 +177,12 @@ break-if-addr>= label => "0f 83/jump-if-addr>= " label ":break/disp3
loop-if-addr>= => "0f 83/jump-if-addr>= loop/disp32" loop-if-addr>= => "0f 83/jump-if-addr>= loop/disp32"
loop-if-addr>= label => "0f 83/jump-if-addr>= " label ":loop/disp32" loop-if-addr>= label => "0f 83/jump-if-addr>= " label ":loop/disp32"
Similar float variants like `break-if-loop<` are aliases for the corresponding
`addr` equivalents. The x86 instruction set stupidly has floating-point
operations only update a subset of flags.
---
In the following instructions types are provided for clarity even if they must In the following instructions types are provided for clarity even if they must
be provided in an earlier 'var' declaration. be provided in an earlier 'var' declaration.