about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-05 18:34:12 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-05 18:34:12 +0100
commit7694594f8b346cda6c9f79014ca7e563496d86f7 (patch)
treeba9a1baf650ad6d6fa7a5e1c19e4d5f054cd8f29 /src
parent51194642742de3f182328815c8aabdd6256a562e (diff)
downloadbox64-7694594f8b346cda6c9f79014ca7e563496d86f7.tar.gz
box64-7694594f8b346cda6c9f79014ca7e563496d86f7.zip
Added F2/F3 prefix handling and a bunch of F2 0F and F3 0F opcodes
Diffstat (limited to 'src')
-rw-r--r--src/emu/modrm.h4
-rwxr-xr-xsrc/emu/x64run.c29
-rwxr-xr-xsrc/emu/x64run_private.h2
-rw-r--r--src/emu/x64runf20f.c63
-rw-r--r--src/emu/x64runf30f.c83
5 files changed, 178 insertions, 3 deletions
diff --git a/src/emu/modrm.h b/src/emu/modrm.h
index b2c0580e..233b1bb8 100644
--- a/src/emu/modrm.h
+++ b/src/emu/modrm.h
@@ -19,12 +19,16 @@
 #define GETGB opgd=GetGb(emu, rex, nextop)

 #define GETEW oped=GetEw(emu, rex, nextop)

 #define GETGW opgd=GetGw(emu, rex, nextop)

+#define GETEX opex=GetEx(emu, rex, nextop)

+#define GETGX opgx=GetGx(emu, rex, nextop)

 #define ED  oped

 #define GD  opgd

 #define EB  oped

 #define GB  opgd->byte[0]

 #define EW  oped

 #define GW  opgd

+#define EX  opex

+#define GX  opgx

 

 #define GOCOND(BASE, PREFIX, CONDITIONAL)       \

     case BASE+0x0:                              \

diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 35dc865a..96bf5aa8 100755
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -40,6 +40,7 @@ int Run(x64emu_t *emu, int step)
     uint64_t tmp64u;
     int32_t tmp32s;
     rex_t rex;
+    int rep;    // 0 none, 1=F2 prefix, 2=F3 prefix
     int unimp = 0;
 
     if(emu->quit)
@@ -62,6 +63,12 @@ x64emurun:
         emu->old_ip = R_RIP;
 
         opcode = F8;
+        
+        rep = 0;
+        while((opcode==0xF2) || (opcode==0xF3)) {
+            rep = opcode-0xF1;
+            opcode = F8;
+        }
         if(opcode>=0x40 && opcode<=0x4f) {
             rex.rex = opcode;
             opcode = F8;
@@ -114,9 +121,25 @@ x64emurun:
         GO(0x00, add)                   /* ADD 0x00 -> 0x05 */
         GO(0x08, or)                    /*  OR 0x08 -> 0x0D */
         case 0x0F:                      /* More instructions */
-            if(Run0F(emu, rex)) {
-                unimp = 1;
-                goto fini;
+            switch(rep) {
+                case 1:
+                    if(RunF20F(emu, rex)) {
+                        unimp = 1;
+                        goto fini;
+                    }
+                    break;
+                case 2:
+                    if(RunF30F(emu, rex)) {
+                        unimp = 1;
+                        goto fini;
+                    }
+                    break;
+                default:
+                    if(Run0F(emu, rex)) {
+                        unimp = 1;
+                        goto fini;
+                    }
+                    break;
             }
             if(emu->quit)
                 goto fini;
diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h
index 6dda57ec..4d53a98e 100755
--- a/src/emu/x64run_private.h
+++ b/src/emu/x64run_private.h
@@ -231,6 +231,8 @@ int Run66(x64emu_t *emu, rex_t rex);
 //int Run67(x64emu_t *emu, rex_t rex);
 int RunD9(x64emu_t *emu, rex_t rex);
 int RunDB(x64emu_t *emu, rex_t rex);
+int RunF20F(x64emu_t *emu, rex_t rex);
+int RunF30F(x64emu_t *emu, rex_t rex);
 //void Run660F(x64emu_t *emu);
 //void Run66D9(x64emu_t *emu);    // x87
 //void Run6766(x64emu_t *emu);
diff --git a/src/emu/x64runf20f.c b/src/emu/x64runf20f.c
new file mode 100644
index 00000000..4188e0fd
--- /dev/null
+++ b/src/emu/x64runf20f.c
@@ -0,0 +1,63 @@
+#define _GNU_SOURCE

+#include <stdint.h>

+#include <stdio.h>

+#include <stdlib.h>

+#include <math.h>

+#include <string.h>

+#include <signal.h>

+#include <sys/types.h>

+#include <unistd.h>

+

+#include "debug.h"

+#include "box64stack.h"

+#include "x64emu.h"

+#include "x64run.h"

+#include "x64emu_private.h"

+#include "x64run_private.h"

+#include "x64primop.h"

+#include "x64trace.h"

+#include "x87emu_private.h"

+#include "box64context.h"

+//#include "my_cpuid.h"

+#include "bridge.h"

+//#include "signals.h"

+#ifdef DYNAREC

+#include "../dynarec/arm_lock_helper.h"

+#endif

+

+#include "modrm.h"

+

+int RunF20F(x64emu_t *emu, rex_t rex)

+{

+    uint8_t opcode;

+    uint8_t nextop;

+    int32_t tmp32s;

+    reg64_t *oped, *opgd;

+    sse_regs_t *opex, *opgx;

+

+    opcode = F8;

+

+    switch(opcode) {

+

+    case 0x10:  /* MOVSD Gx, Ex */

+        nextop = F8;

+        GETEX;

+        GETGX;

+        GX->q[0] = EX->q[0];

+        if((nextop&0xC0)!=0xC0) {

+            // EX is not a register

+            GX->q[1] = 0;

+        }

+        break;

+    case 0x11:  /* MOVSD Ex, Gx */

+        nextop = F8;

+        GETEX;

+        GETGX;

+        EX->q[0] = GX->q[0];

+        break;

+

+    default:

+        return 1;

+    }

+    return 0;

+}
\ No newline at end of file
diff --git a/src/emu/x64runf30f.c b/src/emu/x64runf30f.c
new file mode 100644
index 00000000..e712d362
--- /dev/null
+++ b/src/emu/x64runf30f.c
@@ -0,0 +1,83 @@
+#define _GNU_SOURCE

+#include <stdint.h>

+#include <stdio.h>

+#include <stdlib.h>

+#include <math.h>

+#include <string.h>

+#include <signal.h>

+#include <sys/types.h>

+#include <unistd.h>

+

+#include "debug.h"

+#include "box64stack.h"

+#include "x64emu.h"

+#include "x64run.h"

+#include "x64emu_private.h"

+#include "x64run_private.h"

+#include "x64primop.h"

+#include "x64trace.h"

+#include "x87emu_private.h"

+#include "box64context.h"

+//#include "my_cpuid.h"

+#include "bridge.h"

+//#include "signals.h"

+#ifdef DYNAREC

+#include "../dynarec/arm_lock_helper.h"

+#endif

+

+#include "modrm.h"

+

+int RunF30F(x64emu_t *emu, rex_t rex)

+{

+    uint8_t opcode;

+    uint8_t nextop;

+    int32_t tmp32s;

+    reg64_t *oped, *opgd;

+    sse_regs_t *opex, *opgx;

+

+    opcode = F8;

+

+    switch(opcode) {

+

+    case 0x10:  /* MOVSS Gx Ex */

+        nextop = F8;

+        GETEX;

+        GETGX;

+        GX->ud[0] = EX->ud[0];

+        if((nextop&0xC0)!=0xC0) {

+            // EX is not a register (reg to reg only move 31:0)

+            GX->ud[1] = GX->ud[2] = GX->ud[3] = 0;

+        }

+        break;

+    case 0x11:  /* MOVSS Ex Gx */

+        nextop = F8;

+        GETEX;

+        GETGX;

+        EX->ud[0] = GX->ud[0];

+        break;

+

+    case 0x2A:  /* CVTSI2SS Gx, Ed */

+        nextop = F8;

+        GETED;

+        GETGX;

+        GX->f[0] = ED->sdword[0];

+        break;

+

+    case 0x59:  /* MULSS Gx, Ex */

+        nextop = F8;

+        GETEX;

+        GETGX;

+        GX->f[0] *= EX->f[0];

+        break;

+    case 0x5A:  /* CVTSS2SD Gx, Ex */

+        nextop = F8;

+        GETEX;

+        GETGX;

+        GX->d[0] = EX->f[0];

+        break;

+

+    default:

+        return 1;

+    }

+    return 0;

+}
\ No newline at end of file