about summary refs log tree commit diff stats
path: root/subx/018jump_disp32.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-07-12 12:56:57 -0700
committerKartik Agaram <vc@akkartik.com>2019-07-12 12:56:57 -0700
commit94f2de6d060a8dec6d01f58c9ccf257cd4c46ac7 (patch)
tree1a351ee525527f2675b03e71ce85785a6c5fbae4 /subx/018jump_disp32.cc
parent066e01f868bacff4615661152854091d83b2e6b9 (diff)
downloadmu-94f2de6d060a8dec6d01f58c9ccf257cd4c46ac7.tar.gz
.
Continuation of commit 6f6d458fcd to support unsigned comparisons in
32-bit jumps.

Once again, no tests.
Diffstat (limited to 'subx/018jump_disp32.cc')
-rw-r--r--subx/018jump_disp32.cc44
1 files changed, 40 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() {