about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-04-08 19:11:42 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-04-08 19:11:42 +0200
commitd809b59daa15183e83f48d38e7a4440363242728 (patch)
tree96d16e9fb47df43a7db16b4038b3840d93d6bb72 /src
parente14d4042d932d6a9098f2a5082f28387265270ab (diff)
downloadbox64-d809b59daa15183e83f48d38e7a4440363242728.tar.gz
box64-d809b59daa15183e83f48d38e7a4440363242728.zip
Added 67 66 0F 6F/7A opcodes
Diffstat (limited to 'src')
-rw-r--r--src/emu/modrm.h2
-rwxr-xr-xsrc/emu/x64run.c2
-rw-r--r--src/emu/x64run67.c12
-rw-r--r--src/emu/x64run6766.c66
-rw-r--r--src/emu/x64run67660f.c64
-rwxr-xr-xsrc/emu/x64run_private.c8
-rwxr-xr-xsrc/emu/x64run_private.h6
7 files changed, 157 insertions, 3 deletions
diff --git a/src/emu/modrm.h b/src/emu/modrm.h
index f2a5029e..7f5c77ce 100644
--- a/src/emu/modrm.h
+++ b/src/emu/modrm.h
@@ -22,9 +22,11 @@
 #define GETEB_OFFS(D, O)    oped=GetEbO(emu, rex, nextop, D, O)

 #define GETGB               opgd=GetGb(emu, rex, nextop)

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

+#define GETEW32(D)          oped=GetEw32O(emu, rex, nextop, D, 0)

 #define GETEW_OFFS(D, O)    oped=GetEdO(emu, rex, nextop, D, O)

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

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

+#define GETEX32(D)          opex=GetEx32O(emu, rex, nextop, D, 0)

 #define GETEX_OFFS(D, O)    opex=GetExO(emu, rex, nextop, D, O)

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

 #define GETEM(D)            opem=GetEm(emu, rex, nextop, D)

diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 34db888e..3c83e6b0 100755
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -256,7 +256,7 @@ x64emurun:
                 goto fini;
             break;
         case 0x67:                      /* reduce EASize prefix */
-            if(Run67(emu, rex)) {
+            if(Run67(emu, rex, rep)) {
                 unimp = 1;
                 goto fini;
             }
diff --git a/src/emu/x64run67.c b/src/emu/x64run67.c
index e074be4b..75f64125 100644
--- a/src/emu/x64run67.c
+++ b/src/emu/x64run67.c
@@ -22,7 +22,7 @@
 

 #include "modrm.h"

 

-int Run67(x64emu_t *emu, rex_t rex)

+int Run67(x64emu_t *emu, rex_t rex, int rep)

 {

     uint8_t opcode;

     uint8_t nextop;

@@ -34,12 +34,19 @@ int Run67(x64emu_t *emu, rex_t rex)
 

     opcode = F8;

 

+    while(opcode==0x67)

+        opcode = F8;

+

     // REX prefix before the 67 are ignored

     rex.rex = 0;

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

         rex.rex = opcode;

         opcode = F8;

     }

+    while((opcode==0xF2) || (opcode==0xF3)) {

+        rep = opcode-0xF1;

+        opcode = F8;

+    }

 

     switch(opcode) {

     #define GO(B, OP)                                   \

@@ -96,6 +103,9 @@ int Run67(x64emu_t *emu, rex_t rex)
     GO(0x30, xor)                   /* XOR 0x30 -> 0x35 */

     #undef GO

 

+    case 0x66:

+        return Run6766(emu, rex, rep);

+

     case 0x80:                      /* GRP Eb,Ib */

         nextop = F8;

         GETEB32(1);

diff --git a/src/emu/x64run6766.c b/src/emu/x64run6766.c
new file mode 100644
index 00000000..256a2671
--- /dev/null
+++ b/src/emu/x64run6766.c
@@ -0,0 +1,66 @@
+#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 "bridge.h"
+#ifdef DYNAREC
+#include "../dynarec/arm64_lock.h"
+#endif
+
+#include "modrm.h"
+
+int Run6766(x64emu_t *emu, rex_t rex, int rep)
+{
+    uint8_t opcode;
+    uint8_t nextop;
+    int8_t tmp8s;
+    uint8_t tmp8u, tmp8u2;
+    int16_t tmp16s;
+    uint16_t tmp16u, tmp16u2;
+    int32_t tmp32s;
+    int64_t tmp64s;
+    uint64_t tmp64u, tmp64u2, tmp64u3;
+    reg64_t *oped, *opgd;
+
+    opcode = F8;
+
+    while((opcode==0x2E) || (opcode==0x66))   // ignoring CS: or multiple 0x66
+        opcode = F8;
+
+    while((opcode==0xF2) || (opcode==0xF3)) {
+        rep = opcode-0xF1;
+        opcode = F8;
+    }
+    // REX prefix before the F0 are ignored
+    rex.rex = 0;
+    while(opcode>=0x40 && opcode<=0x4f) {
+        rex.rex = opcode;
+        opcode = F8;
+    }
+
+    switch(opcode) {
+
+    case 0x0F:                              /* more opcdes */
+        return Run67660F(emu, rex);
+
+    default:
+        return 1;
+    }
+    return 0;
+}
\ No newline at end of file
diff --git a/src/emu/x64run67660f.c b/src/emu/x64run67660f.c
new file mode 100644
index 00000000..e5a9d1f8
--- /dev/null
+++ b/src/emu/x64run67660f.c
@@ -0,0 +1,64 @@
+#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 "bridge.h"
+
+#include "modrm.h"
+
+int Run67660F(x64emu_t *emu, rex_t rex)
+{
+    uint8_t opcode;
+    uint8_t nextop;
+    uint8_t tmp8u;
+    int8_t tmp8s;
+    int16_t tmp16s;
+    uint16_t tmp16u;
+    int32_t tmp32s;
+    uint32_t tmp32u;
+    uint64_t tmp64u;
+    reg64_t *oped, *opgd;
+    sse_regs_t *opex, *opgx, eax1, *opex2;
+    mmx87_regs_t *opem, *opgm;
+
+    opcode = F8;
+
+    switch(opcode) {
+
+   case 0x6F:                      /* MOVDQA Gx,Ex */
+        nextop = F8;
+        GETEX32(0);
+        GETGX;
+        GX->q[0] = EX->q[0];
+        GX->q[1] = EX->q[1];
+        break;
+   
+    case 0x76:  /* PCMPEQD Gx,Ex */
+        nextop = F8;
+        GETEX32(0);
+        GETGX;
+        for (int i=0; i<4; ++i)
+            GX->ud[i] = (GX->ud[i]==EX->ud[i])?0xffffffff:0;
+        break;
+
+    default:
+        return 1;
+    }
+    return 0;
+}
\ No newline at end of file
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index 738dd603..8b7add60 100755
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -1256,6 +1256,14 @@ sse_regs_t* GetExO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t
     } else return (sse_regs_t*)GetECommonO(emu, rex, m, delta, offset);
 }
 
+sse_regs_t* GetEx32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
+{
+    uint8_t m = v&0xC7;    // filter Ed
+    if(m>=0xC0) {
+         return &emu->xmm[(m&0x07)+(rex.b<<3)];
+    } else return (sse_regs_t*)GetECommon32O(emu, rex, m, delta, offset);
+}
+
 
 reg64_t* GetGd(x64emu_t *emu, rex_t rex, uint8_t v)
 {
diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h
index 358a972e..e465c6b0 100755
--- a/src/emu/x64run_private.h
+++ b/src/emu/x64run_private.h
@@ -83,11 +83,13 @@ reg64_t* GetEdO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t of
 reg64_t* GetEd32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
 reg64_t* GetEb32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
 #define GetEw GetEd
+#define GetEw32O GetEd32O
 reg64_t* GetEw16(x64emu_t *emu, rex_t rex, uint8_t v);
 reg64_t* GetEw16off(x64emu_t *emu, rex_t rex, uint8_t v, uintptr_t offset);
 mmx87_regs_t* GetEm(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta);
 sse_regs_t* GetEx(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta);
 sse_regs_t* GetExO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
+sse_regs_t* GetEx32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
 reg64_t* GetGd(x64emu_t *emu, rex_t rex, uint8_t v);
 #define GetGw GetGd
 reg64_t* GetGb(x64emu_t *emu, rex_t rex, uint8_t v);
@@ -106,7 +108,9 @@ int Run660F(x64emu_t *emu, rex_t rex);
 int Run6664(x64emu_t *emu, rex_t rex);
 int Run66D9(x64emu_t *emu, rex_t rex);
 int Run66DD(x64emu_t *emu, rex_t rex);
-int Run67(x64emu_t *emu, rex_t rex);
+int Run67(x64emu_t *emu, rex_t rex, int rep);
+int Run6766(x64emu_t *emu, rex_t rex, int rep);
+int Run67660F(x64emu_t *emu, rex_t rex);
 int RunD8(x64emu_t *emu, rex_t rex);
 int RunD9(x64emu_t *emu, rex_t rex);
 int RunDA(x64emu_t *emu, rex_t rex);