about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--subx/018jump_disp32.cc44
-rw-r--r--subx/031check_operands.cc4
2 files changed, 44 insertions, 4 deletions
diff --git a/subx/018jump_disp32.cc b/subx/018jump_disp32.cc
index d6b6a810..86e06e9f 100644
--- a/subx/018jump_disp32.cc
+++ b/subx/018jump_disp32.cc
@@ -135,7 +135,8 @@ void test_jne_disp32_fail() {
 //:: jump if greater
 
 :(before "End Initialize Op Names")
-put_new(Name_0f, "8f", "jump disp32 bytes away if greater, if ZF is unset and SF == OF (jcc/jg/jnle)");
+put_new(Name_0f, "8f", "jump disp32 bytes away if greater (signed), if ZF is unset and SF == OF (jcc/jg/jnle)");
+put_new(Name_0f, "87", "jump disp32 bytes away if greater (unsigned), if ZF is unset and CF is unset (jcc/ja/jnbe)");
 
 :(code)
 void test_jg_disp32_success() {
@@ -166,6 +167,14 @@ case 0x8f: {  // jump disp32 if !SF and !ZF
   }
   break;
 }
+case 0x87: {  // jump disp32 if !CF and !ZF
+  const int32_t offset = next();
+  if (!CF && !ZF) {
+    trace(Callstack_depth+1, "run") << "jump " << offset << end();
+    EIP += offset;
+  }
+  break;
+}
 
 :(code)
 void test_jg_disp32_fail() {
@@ -190,7 +199,8 @@ void test_jg_disp32_fail() {
 //:: jump if greater or equal
 
 :(before "End Initialize Op Names")
-put_new(Name_0f, "8d", "jump disp32 bytes away if greater or equal, if SF == OF (jcc/jge/jnl)");
+put_new(Name_0f, "8d", "jump disp32 bytes away if greater or equal (signed), if SF == OF (jcc/jge/jnl)");
+put_new(Name_0f, "83", "jump disp32 bytes away if greater or equal (unsigned), if CF is unset (jcc/jae/jnb)");
 
 :(code)
 void test_jge_disp32_success() {
@@ -220,6 +230,14 @@ case 0x8d: {  // jump disp32 if !SF
   }
   break;
 }
+case 0x83: {  // jump disp32 if !CF
+  const int32_t offset = next32();
+  if (!CF) {
+    trace(Callstack_depth+1, "run") << "jump " << offset << end();
+    EIP += offset;
+  }
+  break;
+}
 
 :(code)
 void test_jge_disp32_fail() {
@@ -243,7 +261,8 @@ void test_jge_disp32_fail() {
 //:: jump if lesser
 
 :(before "End Initialize Op Names")
-put_new(Name_0f, "8c", "jump disp32 bytes away if lesser, if SF != OF (jcc/jl/jnge)");
+put_new(Name_0f, "8c", "jump disp32 bytes away if lesser (signed), if SF != OF (jcc/jl/jnge)");
+put_new(Name_0f, "82", "jump disp32 bytes away if lesser (unsigned), if CF is set (jcc/jb/jnae)");
 
 :(code)
 void test_jl_disp32_success() {
@@ -274,6 +293,14 @@ case 0x8c: {  // jump disp32 if SF and !ZF
   }
   break;
 }
+case 0x72: {  // jump disp32 if CF
+  const int32_t offset = next32();
+  if (CF) {
+    trace(Callstack_depth+1, "run") << "jump " << offset << end();
+    EIP += offset;
+  }
+  break;
+}
 
 :(code)
 void test_jl_disp32_fail() {
@@ -298,7 +325,8 @@ void test_jl_disp32_fail() {
 //:: jump if lesser or equal
 
 :(before "End Initialize Op Names")
-put_new(Name_0f, "8e", "jump disp32 bytes away if lesser or equal, if ZF is set or SF != OF (jcc/jle/jng)");
+put_new(Name_0f, "8e", "jump disp32 bytes away if lesser or equal (signed), if ZF is set or SF != OF (jcc/jle/jng)");
+put_new(Name_0f, "86", "jump disp8 bytes away if lesser or equal (unsigned), if ZF is set or CF is set (jcc/jbe/jna)");
 
 :(code)
 void test_jle_disp32_equal() {
@@ -349,6 +377,14 @@ case 0x8e: {  // jump disp32 if SF or ZF
   }
   break;
 }
+case 0x86: {  // jump disp32 if ZF or CF
+  const int32_t offset = next32();
+  if (ZF || CF) {
+    trace(Callstack_depth+1, "run") << "jump " << offset << end();
+    EIP += offset;
+  }
+  break;
+}
 
 :(code)
 void test_jle_disp32_greater() {
diff --git a/subx/031check_operands.cc b/subx/031check_operands.cc
index 7b97d2b1..bf5d3719 100644
--- a/subx/031check_operands.cc
+++ b/subx/031check_operands.cc
@@ -626,8 +626,12 @@ map</*op*/string, /*bitvector*/uint8_t> Permitted_operands_0f;
 //// Class D: just op and disp32
 //  imm32 imm8  disp32 |disp16  disp8 subop modrm
 //  0     0     1      |0       0     0     0
+put_new(Permitted_operands_0f, "82", 0x10);
+put_new(Permitted_operands_0f, "83", 0x10);
 put_new(Permitted_operands_0f, "84", 0x10);
 put_new(Permitted_operands_0f, "85", 0x10);
+put_new(Permitted_operands_0f, "86", 0x10);
+put_new(Permitted_operands_0f, "87", 0x10);
 put_new(Permitted_operands_0f, "8c", 0x10);
 put_new(Permitted_operands_0f, "8d", 0x10);
 put_new(Permitted_operands_0f, "8e", 0x10);