about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--linux/bootstrap/017jump_disp8.cc24
-rw-r--r--linux/bootstrap/018jump_disp32.cc24
-rw-r--r--linux/branches.mu40
-rw-r--r--linux/branches.out161
-rwxr-xr-xlinux/mubin607182 -> 608328 bytes
-rw-r--r--linux/mu.subx248
-rw-r--r--mu_instructions25
-rw-r--r--subx_opcodes4
8 files changed, 517 insertions, 9 deletions
diff --git a/linux/bootstrap/017jump_disp8.cc b/linux/bootstrap/017jump_disp8.cc
index 30e60a74..37df6d5b 100644
--- a/linux/bootstrap/017jump_disp8.cc
+++ b/linux/bootstrap/017jump_disp8.cc
@@ -405,3 +405,27 @@ void test_jle_disp8_greater() {
   );
   CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
 }
+
+//:: jump if overflow
+
+:(before "End Initialize Op Names")
+put_new(Name, "70", "jump disp8 bytes away if OF is set (jcc/jo)");
+put_new(Name, "71", "jump disp8 bytes away if OF is unset (jcc/jno)");
+
+:(before "End Single-Byte Opcodes")
+case 0x70: {  // jump disp8 if OF is set
+  const int8_t offset = static_cast<int>(next());
+  if (OF) {
+    trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
+    EIP += offset;
+  }
+  break;
+}
+case 0x71: {  // jump disp8 if OF is unset
+  const int8_t offset = static_cast<int>(next());
+  if (!OF) {
+    trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
+    EIP += offset;
+  }
+  break;
+}
diff --git a/linux/bootstrap/018jump_disp32.cc b/linux/bootstrap/018jump_disp32.cc
index e77bc584..75fb576a 100644
--- a/linux/bootstrap/018jump_disp32.cc
+++ b/linux/bootstrap/018jump_disp32.cc
@@ -405,3 +405,27 @@ void test_jle_disp32_greater() {
   );
   CHECK_TRACE_DOESNT_CONTAIN("run: jump 5");
 }
+
+//:: jump if overflow
+
+:(before "End Initialize Op Names")
+put_new(Name_0f, "80", "jump disp32 bytes away if OF is set (jcc/jo)");
+put_new(Name_0f, "81", "jump disp32 bytes away if OF is unset (jcc/jno)");
+
+:(before "End Two-Byte Opcodes Starting With 0f")
+case 0x80: {  // jump disp8 if OF is set
+  const int32_t offset = next32();
+  if (OF) {
+    trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
+    EIP += offset;
+  }
+  break;
+}
+case 0x81: {  // jump disp8 if OF is unset
+  const int32_t offset = next32();
+  if (!OF) {
+    trace(Callstack_depth+1, "run") << "jump " << NUM(offset) << end();
+    EIP += offset;
+  }
+  break;
+}
diff --git a/linux/branches.mu b/linux/branches.mu
new file mode 100644
index 00000000..411eaa0d
--- /dev/null
+++ b/linux/branches.mu
@@ -0,0 +1,40 @@
+fn foo {
+  $foo: {
+    break-if-=
+    break-if-= $foo
+    break-if-!=
+    break-if-!= $foo
+    break-if-<=
+    break-if-<= $foo
+    break-if->=
+    break-if->= $foo
+    break-if-<
+    break-if-< $foo
+    break-if->
+    break-if-> $foo
+    break-if-carry
+    break-if-carry $foo
+    break-if-overflow
+    break-if-overflow $foo
+    loop-if-=
+    loop-if-= $foo
+    loop-if-!=
+    loop-if-!= $foo
+    loop-if-<=
+    loop-if-<= $foo
+    loop-if->=
+    loop-if->= $foo
+    loop-if-<
+    loop-if-< $foo
+    loop-if->
+    loop-if-> $foo
+    loop-if-carry
+    loop-if-carry $foo
+    loop-if-not-carry
+    loop-if-not-carry $foo
+    loop-if-overflow
+    loop-if-overflow $foo
+    loop-if-not-overflow
+    loop-if-not-overflow $foo
+  }
+}
diff --git a/linux/branches.out b/linux/branches.out
new file mode 100644
index 00000000..878a91e5
--- /dev/null
+++ b/linux/branches.out
@@ -0,0 +1,161 @@
+== code
+foo:
+  # . prologue
+  55/push-ebp
+  89/<- %ebp 4/r32/esp
+  {
+$foo:0x00000001:loop:
+    {
+$foo:loop:
+      {
+        0f 85/jump-if-!= break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 85/jump-if-!= break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 84/jump-if-= break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 84/jump-if-= break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 8f/jump-if-> break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 8f/jump-if-> break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 8c/jump-if-< break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 8c/jump-if-< break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 8d/jump-if->= break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 8d/jump-if->= break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 8e/jump-if-<= break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 8e/jump-if-<= break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 83/jump-if-addr>= break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 83/jump-if-addr>= break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 81/jump-if-not-overflow break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 81/jump-if-not-overflow break/disp32
+        e9/jump $foo:break/disp32
+      }
+      {
+        0f 85/jump-if-!= break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 85/jump-if-!= break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 84/jump-if-= break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 84/jump-if-= break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 8f/jump-if-> break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 8f/jump-if-> break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 8c/jump-if-< break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 8c/jump-if-< break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 8d/jump-if->= break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 8d/jump-if->= break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 8e/jump-if-<= break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 8e/jump-if-<= break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 83/jump-if-addr>= break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 83/jump-if-addr>= break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 82/jump-if-addr< break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 82/jump-if-addr< break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 81/jump-if-not-overflow break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 81/jump-if-not-overflow break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 80/jump-if-overflow break/disp32
+        e9/jump $foo:loop/disp32
+      }
+      {
+        0f 80/jump-if-overflow break/disp32
+        e9/jump $foo:loop/disp32
+      }
+    }
+$foo:break:
+  }
+$foo:0x00000001:break:
+  # . epilogue
+  89/<- %esp 5/r32/ebp
+  5d/pop-to-ebp
+  c3/return
diff --git a/linux/mu b/linux/mu
index 74374bee..2508cda4 100755
--- a/linux/mu
+++ b/linux/mu
Binary files differdiff --git a/linux/mu.subx b/linux/mu.subx
index 07ba75a8..93065326 100644
--- a/linux/mu.subx
+++ b/linux/mu.subx
@@ -27610,9 +27610,9 @@ $emit-reverse-break:end:
 # Table from Mu branch instructions to the reverse SubX opcodes for them.
 Reverse-branch:  # (table (handle array byte) (handle array byte))
   # a table is a stream
-  0x1c0/imm32/write
+  0x240/imm32/write
   0/imm32/read
-  0x1c0/imm32/size
+  0x240/imm32/size
   # data
   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
@@ -27642,6 +27642,14 @@ Reverse-branch:  # (table (handle array byte) (handle array byte))
   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
+  0x11/imm32/alloc-id   _string-break-if-carry/imm32            0x11/imm32/alloc-id   _string_0f_83_jump_label/imm32
+  0x11/imm32/alloc-id   _string-loop-if-carry/imm32             0x11/imm32/alloc-id   _string_0f_83_jump_label/imm32
+  0x11/imm32/alloc-id   _string-break-if-not-carry/imm32        0x11/imm32/alloc-id   _string_0f_82_jump_label/imm32
+  0x11/imm32/alloc-id   _string-loop-if-not-carry/imm32         0x11/imm32/alloc-id   _string_0f_82_jump_label/imm32
+  0x11/imm32/alloc-id   _string-break-if-overflow/imm32         0x11/imm32/alloc-id   _string_0f_81_jump_label/imm32
+  0x11/imm32/alloc-id   _string-loop-if-overflow/imm32          0x11/imm32/alloc-id   _string_0f_81_jump_label/imm32
+  0x11/imm32/alloc-id   _string-break-if-not-overflow/imm32     0x11/imm32/alloc-id   _string_0f_80_jump_label/imm32
+  0x11/imm32/alloc-id   _string-loop-if-not-overflow/imm32      0x11/imm32/alloc-id   _string_0f_80_jump_label/imm32
 
 == code
 
@@ -32836,6 +32844,82 @@ _Primitive-break-if->:  # (payload primitive)
     0/imm32/no-xm32
     0/imm32/no-x32
     0x11/imm32/alloc-id:fake
+    _Primitive-break-if-carry/imm32/next
+_Primitive-break-if-carry:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    0x11/imm32/alloc-id:fake
+    _string-break-if-carry/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-not-carry/imm32/next
+_Primitive-break-if-not-carry:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    0x11/imm32/alloc-id:fake
+    _string-break-if-not-carry/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-overflow/imm32/next
+_Primitive-break-if-overflow:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    0x11/imm32/alloc-id:fake
+    _string-break-if-overflow/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_80_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-not-overflow/imm32/next
+_Primitive-break-if-not-overflow:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    0x11/imm32/alloc-id:fake
+    _string-break-if-not-overflow/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_81_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/imm32/next
 _Primitive-break:  # (payload primitive)
     0x11/imm32/alloc-id:fake:payload
@@ -33045,6 +33129,82 @@ _Primitive-loop-if->:  # (payload primitive)
     0/imm32/no-xm32
     0/imm32/no-x32
     0x11/imm32/alloc-id:fake
+    _Primitive-loop-if-carry/imm32/next
+_Primitive-loop-if-carry:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    0x11/imm32/alloc-id:fake
+    _string-loop-if-carry/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-not-carry/imm32/next
+_Primitive-loop-if-not-carry:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    0x11/imm32/alloc-id:fake
+    _string-loop-if-not-carry/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-overflow/imm32/next
+_Primitive-loop-if-overflow:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    0x11/imm32/alloc-id:fake
+    _string-loop-if-overflow/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_80_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-not-overflow/imm32/next
+_Primitive-loop-if-not-overflow:  # (payload primitive)
+    0x11/imm32/alloc-id:fake:payload
+    0x11/imm32/alloc-id:fake
+    _string-loop-if-not-overflow/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_81_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/imm32/next  # we probably don't need an unconditional break
 _Primitive-loop:  # (payload primitive)
     0x11/imm32/alloc-id:fake:payload
@@ -33891,6 +34051,26 @@ _string-break-if-float>=:  # (payload array byte)
     # "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-break-if-carry:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "break-if-carry"
+    0xe/imm32/size
+    0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y
+_string-break-if-not-carry:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "break-if-not-carry"
+    0x12/imm32/size
+    0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y
+_string-break-if-overflow:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "break-if-overflow"
+    0x11/imm32/size
+    0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
+_string-break-if-not-overflow:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "break-if-not-overflow"
+    0x15/imm32/size
+    0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
 _string-compare:  # (payload array byte)
     0x11/imm32/alloc-id:fake:payload
     # "compare"
@@ -33910,12 +34090,12 @@ _string-copy-byte:
     0x11/imm32/alloc-id:fake:payload
     # "copy-byte"
     0x9/imm32/size
-    0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e
+    0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x62/b 0x79/y 0x74/t 0x65/e
 _string-copy-byte-to:
     0x11/imm32/alloc-id:fake:payload
     # "copy-byte-to"
     0xc/imm32/size
-    0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/- 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x74/t 0x6f/o
+    0x63/c 0x6f/o 0x70/p 0x79/y 0x2d/dash 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/dash 0x74/t 0x6f/o
 _string-decrement:  # (payload array byte)
     0x11/imm32/alloc-id:fake:payload
     # "decrement"
@@ -34001,6 +34181,26 @@ _string-loop-if-float>=:  # (payload array byte)
     # "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-loop-if-carry:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "loop-if-carry"
+    0xd/imm32/size
+    0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y
+_string-loop-if-not-carry:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "loop-if-not-carry"
+    0x11/imm32/size
+    0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x63/c 0x61/a 0x72/r 0x72/r 0x79/y
+_string-loop-if-overflow:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "loop-if-overflow"
+    0x10/imm32/size
+    0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
+_string-loop-if-not-overflow:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "loop-if-not-overflow"
+    0x14/imm32/size
+    0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
 _string-multiply:  # (payload array byte)
     0x11/imm32/alloc-id:fake:payload
     # "multiply"
@@ -34045,12 +34245,12 @@ _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
+    0x73/s 0x71/q 0x75/u 0x61/a 0x72/r 0x65/e 0x2d/dash 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
+    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-negate:  # (payload array byte)
     0x11/imm32/alloc-id:fake:payload
     # "negate"
@@ -34133,6 +34333,36 @@ _string_0d_or_with_eax:  # (payload array byte)
     # "0d/or-with-eax"
     0xe/imm32/size
     0x30/0 0x64/d 0x2f/slash 0x6f/o 0x72/r 0x2d/dash 0x77/w 0x69/i 0x74/t 0x68/h 0x2d/dash 0x65/e 0x61/a 0x78/x
+_string_0f_80_jump_label:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "0f 80/jump-if-overflow"
+    0x16/imm32/size
+    0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
+_string_0f_80_jump_break:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "0f 80/jump-if-overflow break/disp32"
+    0x23/imm32/size
+    0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
+_string_0f_80_jump_loop:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "0f 80/jump-if-overflow loop/disp32"
+    0x22/imm32/size
+    0x30/0 0x66/f 0x20/space 0x38/8 0x30/0 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
+_string_0f_81_jump_label:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "0f 81/jump-if-not-overflow"
+    0x1a/imm32/size
+    0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w
+_string_0f_81_jump_break:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "0f 81/jump-if-not-overflow break/disp32"
+    0x27/imm32/size
+    0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x62/b 0x72/r 0x65/e 0x61/a 0x6b/k 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
+_string_0f_81_jump_loop:  # (payload array byte)
+    0x11/imm32/alloc-id:fake:payload
+    # "0f 81/jump-if-not-overflow loop/disp32"
+    0x26/imm32/size
+    0x30/0 0x66/f 0x20/space 0x38/8 0x31/1 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x6e/n 0x6f/o 0x74/t 0x2d/dash 0x6f/o 0x76/v 0x65/e 0x72/r 0x66/f 0x6c/l 0x6f/o 0x77/w 0x20/space 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
 _string_0f_82_jump_label:  # (payload array byte)
     0x11/imm32/alloc-id:fake:payload
     # "0f 82/jump-if-addr<"
@@ -34176,7 +34406,7 @@ _string_0f_84_jump_break:  # (payload array byte)
 _string_0f_84_jump_loop:  # (payload array byte)
     0x11/imm32/alloc-id:fake:payload
     # "0f 84/jump-if-= loop/disp32"
-    0x1b/imm32/size
+    0x1a/imm32/size
     0x30/0 0x66/f 0x20/space 0x38/8 0x34/4 0x2f/slash 0x6a/j 0x75/u 0x6d/m 0x70/p 0x2d/dash 0x69/i 0x66/f 0x2d/dash 0x3d/= 0x6c/l 0x6f/o 0x6f/o 0x70/p 0x2f/slash 0x64/d 0x69/i 0x73/s 0x70/p 0x33/3 0x32/2
 _string_0f_85_jump_label:  # (payload array byte)
     0x11/imm32/alloc-id:fake:payload
@@ -34527,12 +34757,12 @@ _string_8a_copy_byte:
     0x11/imm32/alloc-id:fake:payload
     # "8a/byte->"
     0x9/imm32/size
-    0x38/8 0x61/a 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/- 0x3e/>
+    0x38/8 0x61/a 0x2f/slash 0x62/b 0x79/y 0x74/t 0x65/e 0x2d/dash 0x3e/>
 _string_88_copy_byte:
     0x11/imm32/alloc-id:fake:payload
     # "88/byte<-"
     0x9/imm32/size
-    0x38/8 0x38/8 0x2f// 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/-
+    0x38/8 0x38/8 0x2f/slash 0x62/b 0x79/y 0x74/t 0x65/e 0x3c/< 0x2d/-
 _string_8d_copy_address:  # (payload array byte)
     0x11/imm32/alloc-id:fake:payload
     # "8d/copy-address"
diff --git a/mu_instructions b/mu_instructions
index 10d00f10..7a458660 100644
--- a/mu_instructions
+++ b/mu_instructions
@@ -293,6 +293,31 @@ Similar float variants like `break-if-float<` are aliases for the corresponding
 `addr` equivalents. The x86 instruction set stupidly has floating-point
 operations only update a subset of flags.
 
+Four sets of conditional jumps are useful for detecting overflow.
+
+break-if-carry                    => "0f 82/jump-if-carry break/disp32"
+break-if-carry label              => "0f 82/jump-if-carry " label "/disp32"
+loop-if-carry                     => "0f 82/jump-if-carry break/disp32"
+loop-if-carry label               => "0f 82/jump-if-carry " label "/disp32"
+
+break-if-not-carry                => "0f 83/jump-if-not-carry break/disp32"
+break-if-not-carry label          => "0f 83/jump-if-not-carry " label "/disp32"
+loop-if-not-carry                 => "0f 83/jump-if-not-carry break/disp32"
+loop-if-not-carry label           => "0f 83/jump-if-not-carry " label "/disp32"
+
+break-if-overflow                 => "0f 80/jump-if-overflow break/disp32"
+break-if-overflow label           => "0f 80/jump-if-overflow " label ":break/disp32"
+loop-if-overflow                  => "0f 80/jump-if-overflow loop/disp32"
+loop-if-overflow label            => "0f 80/jump-if-overflow " label ":loop/disp32"
+
+break-if-not-overflow             => "0f 81/jump-if-not-overflow break/disp32"
+break-if-not-overflow label       => "0f 81/jump-if-not-overflow " label ":break/disp32"
+loop-if-not-overflow              => "0f 81/jump-if-not-overflow loop/disp32"
+loop-if-not-overflow label        => "0f 81/jump-if-not-overflow " label ":loop/disp32"
+
+All this relies on a convention that every `{}` block is delimited by labels
+ending in `:loop` and `:break`.
+
 ## Returns
 
 The `return` instruction cleans up variable declarations just like an unconditional
diff --git a/subx_opcodes b/subx_opcodes
index f8bdc045..19fa1dbd 100644
--- a/subx_opcodes
+++ b/subx_opcodes
@@ -51,6 +51,8 @@ Opcodes currently supported by SubX:
   5f: pop top of stack to EDI (pop)
   68: push imm32 to stack (push)
   69: multiply rm32 by imm32 and store result in r32 (imul)
+  70: jump disp8 bytes away if OF is set (jcc/jo)
+  71: jump disp8 bytes away if OF is unset (jcc/jno)
   72: jump disp8 bytes away if lesser (addr, float), if CF is set (jcc/jb/jnae)
   73: jump disp8 bytes away if greater or equal (addr, float), if CF is unset (jcc/jae/jnb)
   74: jump disp8 bytes away if equal, if ZF is set (jcc/jz/je)
@@ -91,6 +93,8 @@ Opcodes currently supported by SubX:
   f7: negate/multiply/divide rm32 (with EAX and EDX if necessary) depending on subop (neg/mul/idiv)
   ff: increment/decrement/jump/push/call rm32 based on subop (inc/dec/jmp/push/call)
   0f 2f: compare: set CF if x32 < xm32 (comiss)
+  0f 80: jump disp32 bytes away if OF is set (jcc/jo)
+  0f 81: jump disp32 bytes away if OF is unset (jcc/jno)
   0f 82: jump disp32 bytes away if lesser (addr, float), if CF is set (jcc/jb/jnae)
   0f 83: jump disp32 bytes away if greater or equal (addr, float), if CF is unset (jcc/jae/jnb)
   0f 84: jump disp32 bytes away if equal, if ZF is set (jcc/jz/je)
class='oid'>08f4628e ^
760f683f ^
94c59817 ^









6f65d591 ^



94c59817 ^
94c59817 ^

760f683f ^
08f4628e ^
94c59817 ^
08f4628e ^
760f683f ^
94c59817 ^








6f65d591 ^



94c59817 ^
94c59817 ^
760f683f ^
94c59817 ^

51b0936f ^
94c59817 ^

08f4628e ^
94c59817 ^
08f4628e ^
760f683f ^
94c59817 ^









6f65d591 ^

94c59817 ^
94c59817 ^
7a84094a ^
94c59817 ^





56e00e88 ^

8e64ab8b ^
56e00e88 ^

f116818c ^
56e00e88 ^






6f65d591 ^



56e00e88 ^
56e00e88 ^
048a33c2 ^
56e00e88 ^







760f683f ^
fca48e92 ^
fca48e92 ^
d6ae0078 ^
fca48e92 ^



afb467ea ^
760f683f ^
afb467ea ^
afb467ea ^
d6ae0078 ^
afb467ea ^



d6ae0078 ^
fca48e92 ^
fca48e92 ^


6e45be30 ^
1ead3562 ^
fca48e92 ^




760f683f ^
7a84094a ^
1ead3562 ^
44bab2e4 ^
fca48e92 ^
51b0936f ^
afb467ea ^



1ead3562 ^
afb467ea ^





1ead3562 ^
afb467ea ^

44bab2e4 ^
fca48e92 ^
6e45be30 ^

6f65d591 ^
6e45be30 ^
6f65d591 ^


6e45be30 ^



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354