about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-05 11:12:48 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-05 11:12:48 +0100
commit386479f408e4e9c0b103e511c1d23c32ae9cf4be (patch)
tree8727b9e76fc648222605ae1c6a491defccf4a5e2
parent0bf9a5af347778ed1e6d7f20bf684259573794be (diff)
downloadbox64-386479f408e4e9c0b103e511c1d23c32ae9cf4be.tar.gz
box64-386479f408e4e9c0b103e511c1d23c32ae9cf4be.zip
Added REX 0F 40..4F CMOVcc opcodes
-rw-r--r--src/emu/modrm.h121
-rwxr-xr-xsrc/emu/x64run.c108
-rw-r--r--src/emu/x64run0f.c32
3 files changed, 134 insertions, 127 deletions
diff --git a/src/emu/modrm.h b/src/emu/modrm.h
new file mode 100644
index 00000000..7d1c5c76
--- /dev/null
+++ b/src/emu/modrm.h
@@ -0,0 +1,121 @@
+#define F8      *(uint8_t*)(R_RIP++)

+#define F8S     *(int8_t*)(R_RIP++)

+#define F16     *(uint16_t*)(R_RIP+=2, R_RIP-2)

+#define F32     *(uint32_t*)(R_RIP+=4, R_RIP-4)

+#define F32S    *(int32_t*)(R_RIP+=4, R_RIP-4)

+#define F32S64  (uint64_t)(int64_t)F32S

+#define F64     *(uint64_t*)(R_RIP+=8, R_RIP-8)

+#define F64S    *(int64_t*)(R_RIP+=8, R_RIP-8)

+#define PK(a)   *(uint8_t*)(R_RIP+a)

+#ifdef DYNAREC

+#define STEP if(step) return 0;

+#else

+#define STEP

+#endif

+

+#define GETED oped=GetEd(emu, rex, nextop)

+#define GETGD opgd=GetGd(emu, rex, nextop)

+#define GETEB oped=GetEb(emu, rex, nextop)

+#define GETGB oped=GetGb(emu, rex, nextop)

+#define ED  oped

+#define GD  opgd

+#define EB  oped

+#define GB  oped->byte[0]

+

+#define GOCOND(BASE, PREFIX, CONDITIONAL)       \

+    case BASE+0x0:                              \

+        PREFIX                                  \

+        if(ACCESS_FLAG(F_OF)) {                 \

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0x1:                              \

+        PREFIX                                  \

+        if(!ACCESS_FLAG(F_OF)) {                \

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0x2:                              \

+        PREFIX                                  \

+        if(ACCESS_FLAG(F_CF)) {                 \

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0x3:                              \

+        PREFIX                                  \

+        if(!ACCESS_FLAG(F_CF)) {                \

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0x4:                              \

+        PREFIX                                  \

+        if(ACCESS_FLAG(F_ZF)) {                 \

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0x5:                              \

+        PREFIX                                  \

+        if(!ACCESS_FLAG(F_ZF)) {                \

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0x6:                              \

+        PREFIX                                  \

+        if((ACCESS_FLAG(F_ZF) || ACCESS_FLAG(F_CF))) {  \

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0x7:                              \

+        PREFIX                                  \

+        if(!(ACCESS_FLAG(F_ZF) || ACCESS_FLAG(F_CF))) { \

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0x8:                              \

+        PREFIX                                  \

+        if(ACCESS_FLAG(F_SF)) {                 \

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0x9:                              \

+        PREFIX                                  \

+        if(!ACCESS_FLAG(F_SF)) {                \

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0xA:                              \

+        PREFIX                                  \

+        if(ACCESS_FLAG(F_PF)) {                 \

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0xB:                              \

+        PREFIX                                  \

+        if(!ACCESS_FLAG(F_PF)) {                \

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0xC:                              \

+        PREFIX                                  \

+        if(ACCESS_FLAG(F_SF) != ACCESS_FLAG(F_OF)) {\

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0xD:                              \

+        PREFIX                                  \

+        if(ACCESS_FLAG(F_SF) == ACCESS_FLAG(F_OF)) {\

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0xE:                              \

+        PREFIX                                  \

+        if(ACCESS_FLAG(F_ZF) || (ACCESS_FLAG(F_SF) != ACCESS_FLAG(F_OF))) {\

+            CONDITIONAL                         \

+        }                                       \

+        break;                                  \

+    case BASE+0xF:                              \

+        PREFIX                                  \

+        if(!ACCESS_FLAG(F_ZF) && (ACCESS_FLAG(F_SF) == ACCESS_FLAG(F_OF))) {\

+            CONDITIONAL                         \

+        }                                       \

+        break;

diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 4031ec69..478f87c5 100755
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -25,6 +25,8 @@
 #include "../dynarec/arm_lock_helper.h"
 #endif
 
+#include "modrm.h"
+
 int my_setcontext(x64emu_t* emu, void* ucp);
 
 int Run(x64emu_t *emu, int step)
@@ -50,33 +52,9 @@ int Run(x64emu_t *emu, int step)
 
     //ref opcode: http://ref.x64asm.net/geek32.html#xA1
     printf_log(LOG_DEBUG, "Run X86 (%p), RIP=%p, Stack=%p\n", emu, (void*)R_RIP, emu->context->stack);
-#define F8      *(uint8_t*)(R_RIP++)
-#define F8S     *(int8_t*)(R_RIP++)
-#define F16     *(uint16_t*)(R_RIP+=2, R_RIP-2)
-#define F32     *(uint32_t*)(R_RIP+=4, R_RIP-4)
-#define F32S    *(int32_t*)(R_RIP+=4, R_RIP-4)
-#define F32S64  (uint64_t)(int64_t)F32S
-#define F64     *(uint64_t*)(R_RIP+=8, R_RIP-8)
-#define F64S    *(int64_t*)(R_RIP+=8, R_RIP-8)
-#define PK(a)   *(uint8_t*)(R_RIP+a)
-#ifdef DYNAREC
-#define STEP if(step) return 0;
-#else
-#define STEP
-#endif
-
-#define GETED oped=GetEd(emu, rex, nextop)
-#define GETGD opgd=GetGd(emu, rex, nextop)
-#define GETEB oped=GetEb(emu, rex, nextop)
-#define GETGB oped=GetGb(emu, rex, nextop)
-#define ED  oped
-#define GD  opgd
-#define EB  oped
-#define GB  oped->byte[0]
 
 x64emurun:
 
-//#include "modrm.h"
     while(1) {
 #ifdef HAVE_TRACE
         __builtin_prefetch((void*)R_RIP, 0, 0); 
@@ -247,92 +225,10 @@ x64emurun:
             Push(emu, F32S64);
             break;
 
-        #define GOCOND(B, PREFIX, CONDITIONAL)  \
-        case B+0x0:                             \
-            PREFIX                              \
-            if(ACCESS_FLAG(F_OF))               \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0x1:                             \
-            PREFIX                              \
-            if(!ACCESS_FLAG(F_OF))              \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0x2:                             \
-            PREFIX                              \
-            if(ACCESS_FLAG(F_CF))               \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0x3:                             \
-            PREFIX                              \
-            if(!ACCESS_FLAG(F_CF))              \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0x4:                             \
-            PREFIX                              \
-            if(ACCESS_FLAG(F_ZF))               \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0x5:                             \
-            PREFIX                              \
-            if(!ACCESS_FLAG(F_ZF))              \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0x6:                             \
-            PREFIX                              \
-            if((ACCESS_FLAG(F_ZF) || ACCESS_FLAG(F_CF)))  \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0x7:                             \
-            PREFIX                              \
-            if(!(ACCESS_FLAG(F_ZF) || ACCESS_FLAG(F_CF))) \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0x8:                             \
-            PREFIX                              \
-            if(ACCESS_FLAG(F_SF))               \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0x9:                             \
-            PREFIX                              \
-            if(!ACCESS_FLAG(F_SF))              \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0xA:                             \
-            PREFIX                              \
-            if(ACCESS_FLAG(F_PF))               \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0xB:                             \
-            PREFIX                              \
-            if(!ACCESS_FLAG(F_PF))              \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0xC:                             \
-            PREFIX                              \
-            if(ACCESS_FLAG(F_SF) != ACCESS_FLAG(F_OF))  \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0xD:                             \
-            PREFIX                              \
-            if(ACCESS_FLAG(F_SF) == ACCESS_FLAG(F_OF)) \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0xE:                             \
-            PREFIX                              \
-            if(ACCESS_FLAG(F_ZF) || (ACCESS_FLAG(F_SF) != ACCESS_FLAG(F_OF))) \
-                CONDITIONAL                     \
-            break;                              \
-        case B+0xF:                             \
-            PREFIX                              \
-            if(!ACCESS_FLAG(F_ZF) && (ACCESS_FLAG(F_SF) == ACCESS_FLAG(F_OF))) \
-                CONDITIONAL                     \
-            break;
         GOCOND(0x70
             ,   tmp8s = F8S; CHECK_FLAGS(emu);
             ,   R_RIP += tmp8s;
             )                           /* Jxx Ib */
-        #undef GOCOND
         
         case 0x81:                      /* GRP Ed,Id */
         case 0x83:                      /* GRP Ed,Ib */
diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index a46e488e..c922c2d3 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -25,23 +25,7 @@
 #include "../dynarec/arm_lock_helper.h"

 #endif

 

-#define F8      *(uint8_t*)(R_RIP++)

-#define F8S     *(int8_t*)(R_RIP++)

-#define F16     *(uint16_t*)(R_RIP+=2, R_RIP-2)

-#define F32     *(uint32_t*)(R_RIP+=4, R_RIP-4)

-#define F32S    *(int32_t*)(R_RIP+=4, R_RIP-4)

-#define F64     *(uint64_t*)(R_RIP+=8, R_RIP-8)

-#define F64S    *(int64_t*)(R_RIP+=8, R_RIP-8)

-#define PK(a)   *(uint8_t*)(R_RIP+a)

-

-#define GETED oped=GetEd(emu, rex, nextop)

-#define GETGD opgd=GetGd(emu, rex, nextop)

-#define GETEB oped=GetEb(emu, rex, nextop)

-#define GETGB oped=GetGb(emu, rex, nextop)

-#define ED  oped

-#define GD  opgd

-#define EB  oped

-#define GB  oped->byte[0]

+#include "modrm.h"

 

 int Run0F(x64emu_t *emu, rex_t rex)

 {

@@ -50,10 +34,6 @@ int Run0F(x64emu_t *emu, rex_t rex)
     reg64_t *oped, *opgd;

 

     opcode = F8;

-    while(opcode>=0x40 && opcode<=0x4f) {

-        rex.rex = opcode;

-        opcode = F8;

-    }

 

     switch(opcode) {

 

@@ -66,6 +46,16 @@ int Run0F(x64emu_t *emu, rex_t rex)
             GETED;

             break;

         

+

+        GOCOND(0x40

+            , nextop = F8;

+            GETED;

+            GETGD;

+            CHECK_FLAGS(emu);

+            , if(rex.w) {GD->q[0] = ED->q[0]; } else {GD->dword[0] = ED->dword[0];}

+        )                               /* 0x40 -> 0x4F CMOVxx Gd,Ed */ // conditional move, no sign

+        

+        #undef GOCOND

         case 0xAF:                      /* IMUL Gd,Ed */

             nextop = F8;

             GETED;