about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-07-30 09:04:21 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-07-30 09:04:21 +0200
commit6207b3fa386467fb4533136d4bd716d2bae3d4fd (patch)
tree9786893fc01f6f3205f22be494ae40d7471adced /src
parent35d210318977bd8a02d2405bca4647a3f3cccc05 (diff)
downloadbox64-6207b3fa386467fb4533136d4bd716d2bae3d4fd.tar.gz
box64-6207b3fa386467fb4533136d4bd716d2bae3d4fd.zip
Added 64 66 89 and changed 64 66 0F D6 opcodes ([DYNAREC] too) (for #77)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/dynarec_arm64_64.c4
-rw-r--r--src/dynarec/dynarec_arm64_6664.c51
-rw-r--r--src/emu/x64run64.c29
-rw-r--r--src/emu/x64run6664.c28
4 files changed, 83 insertions, 29 deletions
diff --git a/src/dynarec/dynarec_arm64_64.c b/src/dynarec/dynarec_arm64_64.c
index 18bb65de..642322c2 100644
--- a/src/dynarec/dynarec_arm64_64.c
+++ b/src/dynarec/dynarec_arm64_64.c
@@ -199,6 +199,10 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             emit_xor32(dyn, ninst, rex, gd, ed, x3, x4);
             break;
                     
+        case 0x66:
+            addr = dynarec64_6664(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+            break;
+
         case 0x80:
             nextop = F8;
             grab_segdata(dyn, addr, ninst, x1, seg);
diff --git a/src/dynarec/dynarec_arm64_6664.c b/src/dynarec/dynarec_arm64_6664.c
index 0ffd8282..9d65c104 100644
--- a/src/dynarec/dynarec_arm64_6664.c
+++ b/src/dynarec/dynarec_arm64_6664.c
@@ -22,6 +22,7 @@
 #include "dynarec_arm64_helper.h"
 #include "dynarec_arm64_functions.h"
 
+#define GETG        gd = ((nextop&0x38)>>3)+(rex.r<<3)
 
 uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
 {
@@ -30,6 +31,7 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
     uint8_t opcode = F8;
     uint8_t nextop;
     uint8_t gd, ed;
+    int v0, v1;
     int64_t fixedaddress;
 
     // REX prefix before the 66 are ignored
@@ -46,10 +48,56 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
 
     switch(opcode) {
 
+        case 0x0F:
+            opcode = F8;
+            switch(opcode) {
+
+            case 0xD6:
+                INST_NAME("MOVQ Ex, Gx");
+                nextop = F8;
+                GETG;
+                v0 = sse_get_reg(dyn, ninst, x1, gd);
+                if(MODREG) {
+                    v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7) + (rex.b<<3));
+                    FMOVD(v1, v0);
+                } else {
+                    grab_segdata(dyn, addr, ninst, x4, _FS);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, rex, 0, 0);
+                    VSTR64_REG(v0, ed, x4);
+                }
+                break;
+
+                default:
+                    DEFAULT;
+            }
+            break;
+
+        case 0x89:
+            INST_NAME("MOV FS:Ew, Gw");
+            nextop = F8;
+            GETGD;  // don't need GETGW here
+            if(MODREG) {
+                ed = xRAX+(nextop&7)+(rex.b<<3);
+                if(rex.w) {
+                    MOVx_REG(ed, gd);
+                } else {
+                    if(ed!=gd) {
+                        BFIx(ed, gd, 0, 16);
+                    }
+                }
+            } else {
+                grab_segdata(dyn, addr, ninst, x4, _FS);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, rex, 0, 0);
+                if(rex.w) {
+                    STRx_REG(gd, ed, x4);
+                } else {
+                    STRH_REG(gd, ed, x4);
+                }
+            }
+            break;
 
         case 0x8B:
             INST_NAME("MOV Gd, FS:Ed");
-            grab_segdata(dyn, addr, ninst, x4, _FS);
             nextop=F8;
             GETGD;
             if(MODREG) {   // reg <= reg
@@ -62,6 +110,7 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     }
                 }
             } else {                    // mem <= reg
+                grab_segdata(dyn, addr, ninst, x4, _FS);
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, rex, 0, 0);
                 if(rex.w) {
                     LDRx_REG(gd, ed, x4);
diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c
index c7cbbc4b..9897efdd 100644
--- a/src/emu/x64run64.c
+++ b/src/emu/x64run64.c
@@ -231,34 +231,7 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
 

 

         case 0x66:

-            opcode = F8;

-

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

-                rex.rex = opcode;

-                opcode = F8;

-            }

-            switch(opcode) {

-                case 0x0F:

-                    opcode = F8;

-                    switch(opcode) {

-                        case 0xD6:                      /* MOVQ Ex,Gx */

-                            nextop = F8;

-                            GETEX_OFFS(0, tlsdata);

-                            GETGX;

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

-                            if(MODREG)

-                                EX->q[1] = 0;

-                            break;

-

-                        default:

-                            return 1;

-                    }

-                    break;

-

-                default:

-                    return 1;

-            }

-            break;

+            return Run6664(emu, rex);

 

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

             nextop = F8;

diff --git a/src/emu/x64run6664.c b/src/emu/x64run6664.c
index c61938be..14c59677 100644
--- a/src/emu/x64run6664.c
+++ b/src/emu/x64run6664.c
@@ -27,6 +27,7 @@ int Run6664(x64emu_t *emu, rex_t rex)
     uint8_t opcode;

     uint8_t nextop;

     reg64_t *oped, *opgd;

+    sse_regs_t *opex, *opgx;

     uintptr_t tlsdata = GetFSBaseEmu(emu);

 

     opcode = F8;

@@ -39,6 +40,33 @@ int Run6664(x64emu_t *emu, rex_t rex)
 

     switch(opcode) {

 

+        case 0x0F:

+            opcode = F8;

+            switch(opcode) {

+                case 0xD6:                      /* MOVQ Ex,Gx */

+                    nextop = F8;

+                    GETEX_OFFS(0, tlsdata);

+                    GETGX;

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

+                    if(MODREG)

+                        EX->q[1] = 0;

+                    break;

+

+                default:

+                    return 1;

+            }

+            break;

+

+        case 0x89:                              /* MOV Ew,Gw */

+            nextop = F8;

+            GETEW_OFFS(0, tlsdata);

+            GETGW;

+            if(rex.w)

+                EW->q[0] = GW->q[0];

+            else

+                EW->word[0] = GW->word[0];

+            break;

+

         case 0x8B:                      /* MOV Gd,Ed */

             nextop = F8;

             GETEW_OFFS(0, tlsdata);