about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-05-23 09:09:04 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-05-23 09:09:04 +0200
commit537ca9f724696fe0fb61c12cbb9a2c46aa029884 (patch)
treee2ef437dd03e968a3215885252971bac6f6d3d0a /src
parentfc5f5dab29c614a15a9cd96715ad70145f02eed5 (diff)
downloadbox64-537ca9f724696fe0fb61c12cbb9a2c46aa029884.tar.gz
box64-537ca9f724696fe0fb61c12cbb9a2c46aa029884.zip
Added 64 F3 0F 10 opcode ([DYNAREC] too)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/dynarec_arm64_64.c54
-rw-r--r--src/emu/x64run64.c26
2 files changed, 80 insertions, 0 deletions
diff --git a/src/dynarec/dynarec_arm64_64.c b/src/dynarec/dynarec_arm64_64.c
index 077411ce..a8a7c6e6 100644
--- a/src/dynarec/dynarec_arm64_64.c
+++ b/src/dynarec/dynarec_arm64_64.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_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
 {
@@ -33,12 +34,18 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
     uint8_t gd, ed, eb1, eb2;
     uint8_t wback, wb1, wb2;
     int64_t i64, j64;
+    int v0;
+    int q0;
+    int d0;
     int64_t fixedaddress;
     MAYUSE(eb1);
     MAYUSE(eb2);
     MAYUSE(wb1);
     MAYUSE(wb2);
     MAYUSE(j64);
+    MAYUSE(d0);
+    MAYUSE(q0);
+    MAYUSE(v0);
 
     while((opcode==0xF2) || (opcode==0xF3)) {
         rep = opcode-0xF1;
@@ -63,6 +70,53 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             emit_add32(dyn, ninst, rex, gd, ed, x3, x4);
             break;
 
+        case 0x0F:
+            opcode = F8;
+            switch(opcode) {
+                case 0x10:
+                    switch(rep) {
+                        case 1:
+                            INST_NAME("MOVSD Gx, Ex");
+                            nextop = F8;
+                            GETG;
+                            if(MODREG) {
+                                ed = (nextop&7)+ (rex.b<<3);
+                                v0 = sse_get_reg(dyn, ninst, x1, gd);
+                                d0 = sse_get_reg(dyn, ninst, x1, ed);
+                                VMOVeD(v0, 0, d0, 0);
+                            } else {
+                                grab_segdata(dyn, addr, ninst, x4, _FS);
+                                v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
+                                addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0);
+                                ADDx_REG(x4, x4, ed);
+                                VLDR64_U12(v0, x4, fixedaddress); // upper part reseted
+                            }
+                            break;
+                        case 2:
+                            INST_NAME("MOVSS Gx, Ex");
+                            nextop = F8;
+                            GETG;
+                            if(MODREG) {
+                                v0 = sse_get_reg(dyn, ninst, x1, gd);
+                                q0 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3));
+                                VMOVeS(v0, 0, q0, 0);
+                            } else {
+                                grab_segdata(dyn, addr, ninst, x4, _FS);
+                                v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
+                                addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<2, 3, rex, 0, 0);
+                                ADDx_REG(x4, x4, ed);
+                                VLDR32_U12(v0, x4, fixedaddress);
+                            }
+                            break;
+                        default:
+                            DEFAULT;
+                    }
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
+
         case 0x33:
             INST_NAME("XOR Gd, FS:Ed");
             SETFLAGS(X_ALL, SF_SET);
diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c
index 3b6bb4f2..1708bb79 100644
--- a/src/emu/x64run64.c
+++ b/src/emu/x64run64.c
@@ -108,6 +108,32 @@ int Run64(x64emu_t *emu, rex_t rex)
             opcode = F8;

             switch(opcode) {

 

+                case 0x10:

+                    switch(rep) {

+                        case 1: /* MOVSD Gx, FS:Ex */

+                            nextop = F8;

+                            GETEX_OFFS(0, tlsdata);

+                            GETGX;

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

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

+                                // EX is not a register

+                                GX->q[1] = 0;

+                            }

+                            break;

+                        case 2: /* MOVSS Gx, FS:Ex */

+                            nextop = F8;

+                            GETEX_OFFS(0, tlsdata);

+                            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;

+                        default:

+                            return 1;

+                    }

+                    break;

                 case 0x11:

                     switch(rep) {

                         case 1: /* MOVSD Ex, Gx */