about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-09-30 21:17:37 -0700
committerKartik Agaram <vc@akkartik.com>2020-09-30 21:17:37 -0700
commit72c42f90cfc817ab99815f44c02788ebc2bf7ffb (patch)
tree23c8286131422eea70680896d79db546e14ccd8a
parent558bf57587dd3fbb0fb75b8c2cfa056c64c44400 (diff)
downloadmu-72c42f90cfc817ab99815f44c02788ebc2bf7ffb.tar.gz
6908 - compiling all floating-point operations
We don't yet support emulating these instructions in `bootstrap`. But generated
binaries containing them run natively just fine.
-rw-r--r--112read-byte.subx52
-rw-r--r--115write-byte.subx68
-rwxr-xr-xapps/assortbin44674 -> 46466 bytes
-rwxr-xr-xapps/bracesbin46729 -> 48521 bytes
-rwxr-xr-xapps/callsbin51376 -> 53168 bytes
-rwxr-xr-xapps/crenshaw2-1bin44015 -> 45807 bytes
-rwxr-xr-xapps/crenshaw2-1bbin44562 -> 46354 bytes
-rwxr-xr-xapps/dquotesbin48296 -> 50088 bytes
-rwxr-xr-xapps/factorialbin43118 -> 44910 bytes
-rwxr-xr-xapps/hexbin46854 -> 48646 bytes
-rwxr-xr-xapps/mubin403432 -> 413884 bytes
-rw-r--r--apps/mu.subx766
-rwxr-xr-xapps/packbin57364 -> 59156 bytes
-rwxr-xr-xapps/sigilsbin59098 -> 60890 bytes
-rwxr-xr-xapps/surveybin54606 -> 56398 bytes
-rwxr-xr-xapps/testsbin43465 -> 45257 bytes
-rw-r--r--mu_instructions4
17 files changed, 843 insertions, 47 deletions
diff --git a/112read-byte.subx b/112read-byte.subx
index 06da3a64..7510a9e8 100644
--- a/112read-byte.subx
+++ b/112read-byte.subx
@@ -334,8 +334,56 @@ _test-input-stream:  # (stream byte)
     # current read index
     0/imm32
     # size
-    0x100/imm32  # 256 bytes
-    # data (16 lines x 16 bytes/line)
+    0x400/imm32  # 1024 bytes
+    # data (64 lines x 16 bytes/line)
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/115write-byte.subx b/115write-byte.subx
index 889439f6..4fe793a8 100644
--- a/115write-byte.subx
+++ b/115write-byte.subx
@@ -288,8 +288,72 @@ _test-output-stream:  # (stream byte)
     # current read index
     0/imm32
     # size
-    0x400/imm32  # 1024 bytes
-    # data (64 lines x 16 bytes/line)
+    0x800/imm32  # 2048 bytes
+    # data (128 lines x 16 bytes/line)
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/apps/assort b/apps/assort
index eaf99cc4..59229721 100755
--- a/apps/assort
+++ b/apps/assort
Binary files differdiff --git a/apps/braces b/apps/braces
index 2a7f5ec2..cb648e0f 100755
--- a/apps/braces
+++ b/apps/braces
Binary files differdiff --git a/apps/calls b/apps/calls
index 97e8f67c..781eb04d 100755
--- a/apps/calls
+++ b/apps/calls
Binary files differdiff --git a/apps/crenshaw2-1 b/apps/crenshaw2-1
index 80927e73..68bd7758 100755
--- a/apps/crenshaw2-1
+++ b/apps/crenshaw2-1
Binary files differdiff --git a/apps/crenshaw2-1b b/apps/crenshaw2-1b
index 17c7945f..7d81f937 100755
--- a/apps/crenshaw2-1b
+++ b/apps/crenshaw2-1b
Binary files differdiff --git a/apps/dquotes b/apps/dquotes
index a39d796f..81421c0b 100755
--- a/apps/dquotes
+++ b/apps/dquotes
Binary files differdiff --git a/apps/factorial b/apps/factorial
index bdb55aaa..b4f7fff5 100755
--- a/apps/factorial
+++ b/apps/factorial
Binary files differdiff --git a/apps/hex b/apps/hex
index 144ada1a..62dcf42a 100755
--- a/apps/hex
+++ b/apps/hex
Binary files differdiff --git a/apps/mu b/apps/mu
index eafc749b..bf7f31cd 100755
--- a/apps/mu
+++ b/apps/mu
Binary files differdiff --git a/apps/mu.subx b/apps/mu.subx
index 67375327..7d5a8881 100644
--- a/apps/mu.subx
+++ b/apps/mu.subx
@@ -4237,7 +4237,7 @@ test-convert-address:
     5d/pop-to-ebp
     c3/return
 
-test-convert-floating-point-operation:
+test-convert-floating-point-convert:
     # . prologue
     55/push-ebp
     89/<- %ebp 4/r32/esp
@@ -4261,32 +4261,32 @@ test-convert-floating-point-operation:
 #?     (rewind-stream _test-output-stream)
 #?     # }}}
     # check output
-    (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-floating-point-operation/0")
-    (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-floating-point-operation/1")
-    (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-floating-point-operation/2")
-    (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-floating-point-operation/3")
-    (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-floating-point-operation/4")
-    (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-floating-point-operation/5")
-    (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-convert-floating-point-operation/6")
-    (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"  "F - test-convert-floating-point-operation/7")
-    (check-next-stream-line-equal _test-output-stream "    81 5/subop/subtract %esp 4/imm32"  "F - test-convert-floating-point-operation/8")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 11/<- *esp 1/x32"  "F - test-convert-floating-point-operation/9")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 2a/convert-to-float %eax 0x00000001/x32"  "F - test-convert-floating-point-operation/10")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 10/-> *esp 1/x32"  "F - test-convert-floating-point-operation/11")
+    (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-floating-point-convert/0")
+    (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-floating-point-convert/1")
+    (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-floating-point-convert/2")
+    (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-floating-point-convert/3")
+    (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-floating-point-convert/4")
+    (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-floating-point-convert/5")
+    (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-convert-floating-point-convert/6")
+    (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"  "F - test-convert-floating-point-convert/7")
+    (check-next-stream-line-equal _test-output-stream "    81 5/subop/subtract %esp 4/imm32"  "F - test-convert-floating-point-convert/8")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 11/<- *esp 1/x32"  "F - test-convert-floating-point-convert/9")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 2a/convert-to-float %eax 0x00000001/x32"  "F - test-convert-floating-point-convert/10")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 10/-> *esp 1/x32"  "F - test-convert-floating-point-convert/11")
     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 4/imm32"  "F - test-convert-length-of-array-on-stack/12")
-    (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax" "F - test-convert-floating-point-operation/13")
-    (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-floating-point-operation/14")
-    (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-floating-point-operation/15")
-    (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-floating-point-operation/16")
-    (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-floating-point-operation/17")
-    (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-floating-point-operation/18")
-    (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-floating-point-operation/19")
+    (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax" "F - test-convert-floating-point-convert/13")
+    (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-floating-point-convert/14")
+    (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-floating-point-convert/15")
+    (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-floating-point-convert/16")
+    (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-floating-point-convert/17")
+    (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-floating-point-convert/18")
+    (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-floating-point-convert/19")
     # . epilogue
     89/<- %esp 5/r32/ebp
     5d/pop-to-ebp
     c3/return
 
-test-convert-floating-point-operation-2:
+test-convert-floating-point-convert-2:
     # . prologue
     55/push-ebp
     89/<- %ebp 4/r32/esp
@@ -4311,27 +4311,125 @@ test-convert-floating-point-operation-2:
 #?     (rewind-stream _test-output-stream)
 #?     # }}}
     # check output
-    (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-floating-point-operation-2/0")
-    (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-floating-point-operation-2/1")
-    (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-floating-point-operation-2/2")
-    (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-floating-point-operation-2/3")
-    (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-floating-point-operation-2/4")
-    (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-floating-point-operation-2/5")
-    (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-convert-floating-point-operation-2/6")
-    (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"  "F - test-convert-floating-point-operation-2/7")
-    (check-next-stream-line-equal _test-output-stream "    81 5/subop/subtract %esp 4/imm32"  "F - test-convert-floating-point-operation-2/8")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 11/<- *esp 1/x32"  "F - test-convert-floating-point-operation-2/9")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 2a/convert-to-float %eax 0x00000001/x32"  "F - test-convert-floating-point-operation-2/10")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 2d/convert-to-int 3/mod 0x00000001/xm32 0x00000000/r32"  "F - test-convert-floating-point-operation-2/11")
-    (check-next-stream-line-equal _test-output-stream "    f3 0f 10/-> *esp 1/x32"  "F - test-convert-floating-point-operation-2/12")
+    (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-floating-point-convert-2/0")
+    (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-floating-point-convert-2/1")
+    (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-floating-point-convert-2/2")
+    (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-floating-point-convert-2/3")
+    (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-floating-point-convert-2/4")
+    (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-floating-point-convert-2/5")
+    (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-convert-floating-point-convert-2/6")
+    (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"  "F - test-convert-floating-point-convert-2/7")
+    (check-next-stream-line-equal _test-output-stream "    81 5/subop/subtract %esp 4/imm32"  "F - test-convert-floating-point-convert-2/8")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 11/<- *esp 1/x32"  "F - test-convert-floating-point-convert-2/9")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 2a/convert-to-float %eax 0x00000001/x32"  "F - test-convert-floating-point-convert-2/10")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 2d/convert-to-int 3/mod 0x00000001/xm32 0x00000000/r32"  "F - test-convert-floating-point-convert-2/11")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 10/-> *esp 1/x32"  "F - test-convert-floating-point-convert-2/12")
     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 4/imm32"  "F - test-convert-length-of-array-on-stack/13")
-    (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax" "F - test-convert-floating-point-operation-2/14")
-    (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-floating-point-operation-2/15")
-    (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-floating-point-operation-2/16")
-    (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-floating-point-operation-2/17")
-    (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-floating-point-operation-2/18")
-    (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-floating-point-operation-2/19")
-    (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-floating-point-operation-2/20")
+    (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax" "F - test-convert-floating-point-convert-2/14")
+    (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-floating-point-convert-2/15")
+    (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-floating-point-convert-2/16")
+    (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-floating-point-convert-2/17")
+    (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-floating-point-convert-2/18")
+    (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-floating-point-convert-2/19")
+    (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-floating-point-convert-2/20")
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
+test-convert-floating-point-operation:
+    # . 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 f {\n")
+    (write _test-input-stream "  var m: float\n")
+    (write _test-input-stream "  var x/xmm1: float <- copy m\n")
+    (write _test-input-stream "  var y/xmm5: float <- copy m\n")
+    (write _test-input-stream "  x <- copy y\n")
+    (write _test-input-stream "  copy-to m, y\n")
+    (write _test-input-stream "  x <- add y\n")
+    (write _test-input-stream "  x <- add m\n")
+    (write _test-input-stream "  x <- subtract y\n")
+    (write _test-input-stream "  x <- subtract m\n")
+    (write _test-input-stream "  x <- multiply y\n")
+    (write _test-input-stream "  x <- multiply m\n")
+    (write _test-input-stream "  x <- divide y\n")
+    (write _test-input-stream "  x <- divide m\n")
+    (write _test-input-stream "  x <- reciprocal y\n")
+    (write _test-input-stream "  x <- reciprocal m\n")
+    (write _test-input-stream "  x <- square-root y\n")
+    (write _test-input-stream "  x <- square-root m\n")
+    (write _test-input-stream "  x <- inverse-square-root y\n")
+    (write _test-input-stream "  x <- inverse-square-root m\n")
+    (write _test-input-stream "  x <- max y\n")
+    (write _test-input-stream "  x <- max m\n")
+    (write _test-input-stream "  x <- min y\n")
+    (write _test-input-stream "  x <- min m\n")
+    (write _test-input-stream "  compare x, y\n")
+    (write _test-input-stream "  compare x, m\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 "f:"                                                                     "F - test-convert-floating-point-operation/0")
+    (check-next-stream-line-equal _test-output-stream "  # . prologue"                                                         "F - test-convert-floating-point-operation/1")
+    (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                                                          "F - test-convert-floating-point-operation/2")
+    (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                                                 "F - test-convert-floating-point-operation/3")
+    (check-next-stream-line-equal _test-output-stream "  {"                                                                    "F - test-convert-floating-point-operation/4")
+    (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:"                                                    "F - test-convert-floating-point-operation/5")
+    (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"                                                    "F - test-convert-floating-point-operation/6")
+    (check-next-stream-line-equal _test-output-stream "    81 5/subop/subtract %esp 4/imm32"                                   "F - test-convert-floating-point-operation/7")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 11/<- *esp 1/x32"                                             "F - test-convert-floating-point-operation/8")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 10/copy *(ebp+0xfffffffc) 0x00000001/x32"                     "F - test-convert-floating-point-operation/9")
+    (check-next-stream-line-equal _test-output-stream "    81 5/subop/subtract %esp 4/imm32"                                   "F - test-convert-floating-point-operation/10")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 11/<- *esp 5/x32"                                             "F - test-convert-floating-point-operation/11")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 10/copy *(ebp+0xfffffffc) 0x00000005/x32"                     "F - test-convert-floating-point-operation/12")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 11/copy 3/mod 0x00000001/xm32 0x00000005/x32"                 "F - test-convert-floating-point-operation/13")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 11/copy *(ebp+0xfffffffc) 0x00000005/x32"                     "F - test-convert-floating-point-operation/14")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 58/add 3/mod 0x00000005/xm32 0x00000001/x32"                  "F - test-convert-floating-point-operation/15")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 58/add *(ebp+0xfffffffc) 0x00000001/x32"                      "F - test-convert-floating-point-operation/16")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 5c/subtract 3/mod 0x00000005/xm32 0x00000001/x32"             "F - test-convert-floating-point-operation/17")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 5c/subtract *(ebp+0xfffffffc) 0x00000001/x32"                 "F - test-convert-floating-point-operation/18")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 59/multiply 3/mod 0x00000005/xm32 0x00000001/x32"             "F - test-convert-floating-point-operation/19")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 59/multiply *(ebp+0xfffffffc) 0x00000001/x32"                 "F - test-convert-floating-point-operation/20")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 5e/divide 3/mod 0x00000005/xm32 0x00000001/x32"               "F - test-convert-floating-point-operation/21")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 5e/divide *(ebp+0xfffffffc) 0x00000001/x32"                   "F - test-convert-floating-point-operation/22")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 53/reciprocal 3/mod 0x00000005/xm32 0x00000001/x32"           "F - test-convert-floating-point-operation/23")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 53/reciprocal *(ebp+0xfffffffc) 0x00000001/x32"               "F - test-convert-floating-point-operation/24")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 51/square-root 3/mod 0x00000005/xm32 0x00000001/x32"          "F - test-convert-floating-point-operation/25")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 51/square-root *(ebp+0xfffffffc) 0x00000001/x32"              "F - test-convert-floating-point-operation/26")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 52/inverse-square-root 3/mod 0x00000005/xm32 0x00000001/x32"  "F - test-convert-floating-point-operation/27")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 52/inverse-square-root *(ebp+0xfffffffc) 0x00000001/x32"      "F - test-convert-floating-point-operation/28")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 5f/max 3/mod 0x00000005/xm32 0x00000001/x32"                  "F - test-convert-floating-point-operation/29")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 5f/max *(ebp+0xfffffffc) 0x00000001/x32"                      "F - test-convert-floating-point-operation/30")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 5d/min 3/mod 0x00000005/xm32 0x00000001/x32"                  "F - test-convert-floating-point-operation/31")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 5d/min *(ebp+0xfffffffc) 0x00000001/x32"                      "F - test-convert-floating-point-operation/32")
+    (check-next-stream-line-equal _test-output-stream "    0f 2f/compare 3/mod 0x00000001/xm32 0x00000005/x32"                 "F - test-convert-floating-point-operation/33")
+    (check-next-stream-line-equal _test-output-stream "    0f 2f/compare *(ebp+0xfffffffc) 0x00000001/x32"                     "F - test-convert-floating-point-operation/34")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 10/-> *esp 5/x32"                                             "F - test-convert-floating-point-operation/35")
+    (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 4/imm32"                                        "F - test-convert-floating-point-operation/36")
+    (check-next-stream-line-equal _test-output-stream "    f3 0f 10/-> *esp 1/x32"                                             "F - test-convert-floating-point-operation/37")
+    (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 4/imm32"                                        "F - test-convert-floating-point-operation/38")
+    (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000004/imm32"                               "F - test-convert-floating-point-operation/39")
+    (check-next-stream-line-equal _test-output-stream "  }"                                                                    "F - test-convert-floating-point-operation/40")
+    (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:"                                                   "F - test-convert-floating-point-operation/41")
+    (check-next-stream-line-equal _test-output-stream "  # . epilogue"                                                         "F - test-convert-floating-point-operation/42")
+    (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                                                 "F - test-convert-floating-point-operation/43")
+    (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                                                        "F - test-convert-floating-point-operation/44")
+    (check-next-stream-line-equal _test-output-stream "  c3/return"                                                            "F - test-convert-floating-point-operation/45")
     # . epilogue
     89/<- %esp 5/r32/ebp
     5d/pop-to-ebp
@@ -13344,6 +13442,11 @@ $check-mu-numberlike-output:check-int:
     (is-simple-mu-type? %esi 1)  # int => eax
     3d/compare-eax-and 0/imm32/false
     75/jump-if-!= $check-mu-numberlike-output:end/disp8
+$check-mu-numberlike-output:check-float:
+    # if t is a float, return
+    (is-simple-mu-type? %esi 0xf)  # float => eax
+    3d/compare-eax-and 0/imm32/false
+    75/jump-if-!= $check-mu-numberlike-output:end/disp8
 $check-mu-numberlike-output:check-boolean:
     # if t is a boolean, return
     (is-simple-mu-type? %esi 5)  # boolean => eax
@@ -19523,6 +19626,476 @@ _Primitive-convert-xreg-to-reg:  # (payload primitive)
     1/imm32/xm32-is-first-inout
     0/imm32/no-x32
     0x11/imm32/alloc-id:fake
+    _Primitive-copy-xreg-to-xreg/imm32/next
+_Primitive-copy-xreg-to-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- copy var2/xreg => f3 0f 11/<- var1/xm32 var2/x32
+    0x11/imm32/alloc-id:fake
+    _string-copy/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_11_copy/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    3/imm32/xm32-is-first-output
+    1/imm32/x32-is-first-inout
+    0x11/imm32/alloc-id:fake
+    _Primitive-copy-xreg-to-mem/imm32/next
+_Primitive-copy-xreg-to-mem:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # copy-to var1 var2/xreg => f3 0f 11/<- var1 var2/x32
+    0x11/imm32/alloc-id:fake
+    _string-copy-to/imm32/name
+    0x11/imm32/alloc-id:fake
+    Two-args-float-stack-float-reg/imm32/inouts
+    0/imm32/no-outputs
+    0/imm32/no-outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_11_copy/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    2/imm32/x32-is-second-inout
+    0x11/imm32/alloc-id:fake
+    _Primitive-copy-mem-to-xreg/imm32/next
+_Primitive-copy-mem-to-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- copy var2 => f3 0f 10/-> var2/rm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-copy/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-mem/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_10_copy/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-add-xreg-to-xreg/imm32/next
+# add floats
+_Primitive-add-xreg-to-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- add var2/xreg => f3 0f 58/add var1/xm32 var2/x32
+    0x11/imm32/alloc-id:fake
+    _string-add/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_58_add/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-add-mem-to-xreg/imm32/next
+_Primitive-add-mem-to-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- add var2 => f3 0f 58/add var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-add/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-mem/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_58_add/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-subtract-xreg-from-xreg/imm32/next
+# subtract floats
+_Primitive-subtract-xreg-from-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- subtract var2/xreg => f3 0f 5c/subtract var1/xm32 var2/x32
+    0x11/imm32/alloc-id:fake
+    _string-subtract/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_5c_subtract/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-subtract-mem-from-xreg/imm32/next
+_Primitive-subtract-mem-from-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- subtract var2 => f3 0f 5c/subtract var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-subtract/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-mem/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_5c_subtract/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-multiply-xreg-by-xreg/imm32/next
+# - multiply
+_Primitive-multiply-xreg-by-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- multiply var2 => f3 0f 59/multiply var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-multiply/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_59_multiply/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-multiply-xreg-by-mem/imm32/next
+_Primitive-multiply-xreg-by-mem:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- multiply var2 => 53 0f 59/multiply var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-multiply/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-mem/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_59_multiply/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-divide-xreg-by-xreg/imm32/next
+# - divide
+_Primitive-divide-xreg-by-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- divide var2 => f3 0f 5e/divide var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-divide/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_5e_divide/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-divide-xreg-by-mem/imm32/next
+_Primitive-divide-xreg-by-mem:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- divide var2 => f3 0f 5e/divide var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-divide/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-mem/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_5e_divide/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-max-xreg-with-xreg/imm32/next
+# - maximum
+_Primitive-max-xreg-with-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- max var2 => f3 0f 5f/max var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-max/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_5f_max/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-max-xreg-with-mem/imm32/next
+_Primitive-max-xreg-with-mem:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- divide var2 => f3 0f 5f/max var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-max/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-mem/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_5f_max/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-min-xreg-with-xreg/imm32/next
+# - minimum
+_Primitive-min-xreg-with-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- divide var2 => f3 0f 5d/min var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-min/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_5d_min/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-min-xreg-with-mem/imm32/next
+_Primitive-min-xreg-with-mem:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- divide var2 => f3 0f 5d/min var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-min/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-mem/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_5d_min/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-reciprocal-xreg-to-xreg/imm32/next
+# - reciprocal
+_Primitive-reciprocal-xreg-to-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- reciprocal var2 => f3 0f 53/reciprocal var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-reciprocal/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_53_reciprocal/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-reciprocal-mem-to-xreg/imm32/next
+_Primitive-reciprocal-mem-to-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- divide var2 => f3 0f 53/reciprocal var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-reciprocal/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-mem/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_53_reciprocal/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-square-root-xreg-to-xreg/imm32/next
+# - square root
+_Primitive-square-root-xreg-to-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- square-root var2 => f3 0f 51/square-root var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-square-root/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_51_square_root/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-square-root-mem-to-xreg/imm32/next
+_Primitive-square-root-mem-to-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- divide var2 => f3 0f 51/square-root var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-square-root/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-mem/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_51_square_root/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-inverse-square-root-xreg-to-xreg/imm32/next
+# - inverse square root 1/sqrt(x)
+_Primitive-inverse-square-root-xreg-to-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- reciprocal var2 => f3 0f 52/inverse-square-root var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-inverse-square-root/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_52_inverse_square_root/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-inverse-square-root-mem-to-xreg/imm32/next
+_Primitive-inverse-square-root-mem-to-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # var1/xreg <- divide var2 => f3 0f 52/inverse-square-root var2/xm32 var1/x32
+    0x11/imm32/alloc-id:fake
+    _string-inverse-square-root/imm32/name
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-mem/imm32/inouts
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/outputs
+    0x11/imm32/alloc-id:fake
+    _string_f3_0f_52_inverse_square_root/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    3/imm32/x32-is-first-output
+    0x11/imm32/alloc-id:fake
+    _Primitive-compare-xreg-with-xreg/imm32/next
+# - compare
+_Primitive-compare-xreg-with-xreg:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # compare var1/reg1 var2/reg2 => 0f 2f/compare var2/x32 var1/xm32
+    0x11/imm32/alloc-id:fake
+    _string-compare/imm32/name
+    0x11/imm32/alloc-id:fake
+    Two-float-args-in-regs/imm32/inouts
+    0/imm32/no-outputs
+    0/imm32/no-outputs
+    0x11/imm32/alloc-id:fake
+    _string_0f_2f_compare/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    1/imm32/xm32-is-first-inout
+    2/imm32/x32-is-second-inout
+    0x11/imm32/alloc-id:fake
+    _Primitive-compare-xreg-with-mem/imm32/next
+_Primitive-compare-xreg-with-mem:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    # compare var1/xreg var2 => 0f 2f/compare var1/x32 var2/xm32
+    0x11/imm32/alloc-id:fake
+    _string-compare/imm32/name
+    0x11/imm32/alloc-id:fake
+    Two-args-float-reg-float-stack/imm32/inouts
+    0/imm32/no-outputs
+    0/imm32/no-outputs
+    0x11/imm32/alloc-id:fake
+    _string_0f_2f_compare/imm32/subx-name
+    0/imm32/no-rm32
+    0/imm32/no-r32
+    0/imm32/no-imm32
+    0/imm32/no-imm8
+    0/imm32/no-disp32
+    2/imm32/xm32-is-second-inout
+    1/imm32/x32-is-first-inout
+    0x11/imm32/alloc-id:fake
     _Primitive-break-if-addr</imm32/next
 # - branches
 _Primitive-break-if-addr<:  # (payload primitive)
@@ -20544,6 +21117,36 @@ _string-convert:  # (payload array byte)
     # "convert"
     0x7/imm32/size
     0x63/c 0x6f/o 0x6e/n 0x76/v 0x65/e 0x72/r 0x74/t
+_string-divide:
+    0x11/imm32/alloc-id:fake:payload
+    # "divide"
+    0x6/imm32/size
+    0x64/d 0x69/i 0x76/v 0x69/i 0x64/d 0x65/e
+_string-max:
+    0x11/imm32/alloc-id:fake:payload
+    # "max"
+    0x3/imm32/size
+    0x6d/m 0x61/a 0x78/x
+_string-min:
+    0x11/imm32/alloc-id:fake:payload
+    # "min"
+    0x3/imm32/size
+    0x6d/m 0x69/i 0x6e/n
+_string-reciprocal:
+    0x11/imm32/alloc-id:fake:payload
+    # "reciprocal"
+    0xa/imm32/size
+    0x72/r 0x65/e 0x63/c 0x69/i 0x70/p 0x72/r 0x6f/o 0x63/c 0x61/a 0x6c/l
+_string-square-root:
+    0x11/imm32/alloc-id:fake:payload
+    # "square-root"
+    0xb/imm32/size
+    0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/- 0x72/r 0x6f/o 0x6f/o 0x74/t
+_string-inverse-square-root:
+    0x11/imm32/alloc-id:fake:payload
+    # "inverse-square-root"
+    0x13/imm32/size
+    0x69/i 0x6e/n 0x76/v 0x65/e 0x72/r 0x73/s 0x65/e 0x2d/- 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/- 0x72/r 0x6f/o 0x6f/o 0x74/t
 _string-negate:  # (payload array byte)
     0x11/imm32/alloc-id:fake:payload
     # "negate"
@@ -20791,6 +21394,66 @@ _string_f3_0f_2d_convert_to_int:
     # "f3 0f 2d/convert-to-int"
     0x17/imm32/size
     0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x32/2 0x64/d 0x2f/slash 0x63/c 0x6f/o 0x6e/n 0x76/v 0x65/e 0x72/r 0x74/t 0x2d/dash 0x74/t 0x6f/o 0x2d/dash 0x69/i 0x6e/n 0x74/t
+_string_f3_0f_58_add:
+    0x11/imm32/alloc-id:fake:payload
+    # "f3 0f 58/add"
+    0xc/imm32/size
+    0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x38/8 0x2f/slash 0x61/a 0x64/d 0x64/d
+_string_f3_0f_5c_subtract:
+    0x11/imm32/alloc-id:fake:payload
+    # "f3 0f 5c/subtract"
+    0x11/imm32/size
+    0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x63/c 0x2f/slash 0x73/s 0x75/u 0x62/b 0x74/t 0x72/r 0x61/a 0x63/c 0x74/t
+_string_f3_0f_59_multiply:
+    0x11/imm32/alloc-id:fake:payload
+    # "f3 0f 59/multiply"
+    0x11/imm32/size
+    0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x39/9 0x2f/slash 0x6d/m 0x75/u 0x6c/l 0x74/t 0x69/i 0x70/p 0x6c/l 0x79/y
+_string_f3_0f_5e_divide:
+    0x11/imm32/alloc-id:fake:payload
+    # "f3 0f 5e/divide"
+    0xf/imm32/size
+    0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x65/e 0x2f/slash 0x64/d 0x69/i 0x76/v 0x69/i 0x64/d 0x65/e
+_string_f3_0f_53_reciprocal:
+    0x11/imm32/alloc-id:fake:payload
+    # "f3 0f 53/reciprocal"
+    0x13/imm32/size
+    0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x33/3 0x2f/slash 0x72/r 0x65/e 0x63/c 0x69/i 0x70/p 0x72/r 0x6f/o 0x63/c 0x61/a 0x6c/l
+_string_f3_0f_51_square_root:
+    0x11/imm32/alloc-id:fake:payload
+    # "f3 0f 51/square-root"
+    0x14/imm32/size
+    0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x31/1 0x2f/slash 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t
+_string_f3_0f_52_inverse_square_root:
+    0x11/imm32/alloc-id:fake:payload
+    # "f3 0f 52/inverse-square-root"
+    0x1c/imm32/size
+    0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x32/2 0x2f/slash 0x69/i 0x6e/n 0x76/v 0x65/e 0x72/r 0x73/s 0x65/e 0x2d/dash 0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 0x72/r 0x6f/o 0x6f/o 0x74/t
+_string_f3_0f_5d_min:
+    0x11/imm32/alloc-id:fake:payload
+    # "f3 0f 5d/min"
+    0xc/imm32/size
+    0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x64/d 0x2f/slash 0x6d/m 0x69/i 0x6e/n
+_string_f3_0f_5f_max:
+    0x11/imm32/alloc-id:fake:payload
+    # "f3 0f 5f/max"
+    0xc/imm32/size
+    0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x35/5 0x66/f 0x2f/slash 0x6d/m 0x61/a 0x78/x
+_string_f3_0f_10_copy:
+    0x11/imm32/alloc-id:fake:payload
+    # "f3 0f 10/copy"
+    0xd/imm32/size
+    0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x31/1 0x30/0 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y
+_string_f3_0f_11_copy:
+    0x11/imm32/alloc-id:fake:payload
+    # "f3 0f 11/copy"
+    0xd/imm32/size
+    0x66/f 0x33/3 0x20/space 0x30/0 0x66/f 0x20/space 0x31/1 0x31/1 0x2f/slash 0x63/c 0x6f/o 0x70/p 0x79/y
+_string_0f_2f_compare:
+    0x11/imm32/alloc-id:fake:payload
+    # "0f 2f/compare"
+    0xd/imm32/size
+    0x30/0 0x66/f 0x20/space 0x32/2 0x66/f 0x2f/slash 0x63/c 0x6f/o 0x6d/m 0x70/p 0x61/a 0x72/r 0x65/e
 _string_21_and_with:  # (payload array byte)
     0x11/imm32/alloc-id:fake:payload
     # "21/and-with"
@@ -21135,6 +21798,27 @@ Int-var-in-register-and-literal:  # (payload list var)
     0x11/imm32/alloc-id:fake
     Single-lit-var/imm32/next
 
+Two-float-args-in-regs:  # (payload list var)
+    0x11/imm32/alloc-id:fake:payload
+    0x11/imm32/alloc-id:fake
+    Float-var-in-some-register/imm32
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/next
+
+Two-args-float-reg-float-stack:  # (payload list var)
+    0x11/imm32/alloc-id:fake:payload
+    0x11/imm32/alloc-id:fake
+    Float-var-in-some-register/imm32
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-mem/imm32/next
+
+Two-args-float-stack-float-reg:  # (payload list var)
+    0x11/imm32/alloc-id:fake:payload
+    0x11/imm32/alloc-id:fake
+    Float-var-in-mem/imm32
+    0x11/imm32/alloc-id:fake
+    Single-float-var-in-some-register/imm32/next
+
 Single-int-var-in-some-register:  # (payload list var)
     0x11/imm32/alloc-id:fake:payload
     0x11/imm32/alloc-id:fake
diff --git a/apps/pack b/apps/pack
index cd4fa5b1..38b33328 100755
--- a/apps/pack
+++ b/apps/pack
Binary files differdiff --git a/apps/sigils b/apps/sigils
index 7c99b943..b734f16a 100755
--- a/apps/sigils
+++ b/apps/sigils
Binary files differdiff --git a/apps/survey b/apps/survey
index 11709e1e..cf95124b 100755
--- a/apps/survey
+++ b/apps/survey
Binary files differdiff --git a/apps/tests b/apps/tests
index 3652e6a3..872f64fb 100755
--- a/apps/tests
+++ b/apps/tests
Binary files differdiff --git a/mu_instructions b/mu_instructions
index fe11aaba..2013c764 100644
--- a/mu_instructions
+++ b/mu_instructions
@@ -336,7 +336,7 @@ var/xreg <- copy *var2/reg2       => "f3 0f 10/-> *" reg2 " " xreg "/x32"
 
 Comparisons must always start with a register:
 
-compare var1/xreg1, var2/xreg2    => "0f 2f 3/mod " xreg2 "/xm32 " xreg1 "/x32"
-compare var1/xreg1, var2          => "0f 2f 2/mod *(ebp+" var2.stack-offset ") " xreg1 "/x32"
+compare var1/xreg1, var2/xreg2    => "0f 2f/compare 3/mod " xreg2 "/xm32 " xreg1 "/x32"
+compare var1/xreg1, var2          => "0f 2f/compare 2/mod *(ebp+" var2.stack-offset ") " xreg1 "/x32"
 
 vim:ft=mu:nowrap:textwidth=0