about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-03-25 10:21:46 +0000
committerptitSeb <sebastien.chev@gmail.com>2023-03-25 10:21:46 +0000
commit206bc9afb659eeb4e8393170e0dc8bcb87792c3c (patch)
treea501c0467d326360d0e6108a715ff3b7f46967e9 /src
parentffcfa5b2cbdae6087d1c6bf790b5e2165d9ab580 (diff)
downloadbox64-206bc9afb659eeb4e8393170e0dc8bcb87792c3c.tar.gz
box64-206bc9afb659eeb4e8393170e0dc8bcb87792c3c.zip
[RV64_DYNAREC] Added 66 0F EF PXOR opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c23
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h19
3 files changed, 43 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index aabaa019..03e44fc8 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -122,6 +122,29 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             OR(gd, gd, x1);
             break;
 
+        case 0xEF:
+            INST_NAME("PXOR Gx, Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            if(gd==ed) {
+                // just zero dest
+                SD(xZR, x1, 0);
+                SD(xZR, x1, 8);
+            } else {
+                //1st
+                LD(x3, x1, 0);
+                LD(x4, x2, 0);
+                XOR(x3, x3, x4);
+                SD(x3, x1, 0);
+                // 2nd
+                LD(x3, x1, 8);
+                LD(x4, x2, 8);
+                XOR(x3, x3, x4);
+                SD(x3, x1, 8);
+            }
+            break;
+
         default:
             DEFAULT;
     }
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index fe7d0804..6a45f9bb 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -1116,7 +1116,7 @@ int sse_get_reg_empty(dynarec_rv64_t* dyn, int ninst, int s1, int a, int single)
     dyn->e.ssecache[a].single = single;
     return dyn->e.ssecache[a].reg;
 }
-// forget ext register for a SSE reg, create the entry if needed
+// forget ext register for a SSE reg, does nothing if the regs is not loaded
 void sse_forget_reg(dynarec_rv64_t* dyn, int ninst, int a)
 {
     if(dyn->e.ssecache[a].v==-1)
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 4a6147ac..32e509b4 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -292,6 +292,25 @@
         FLW(a, ed, fixedaddress);                                                                       \
     }
 
+// Will get pointer to GX in general register a, will purge SS or SD if loaded
+#define GETGX(a)                        \
+    gd = ((nextop&0x38)>>3)+(rex.r<<3); \
+    sse_forget_reg(dyn, ninst, gd);     \
+    ADDI(a, xEmu, offsetof(x64emu_t, xmm[gd]))
+
+// Get Ex address in regenal register a, will purge SS or SD or it's reg and is loaded. May use x3
+#define GETEX(a, D)                                                                                     \
+    if(MODREG) {                                                                                        \
+        ed = (nextop&7)+(rex.b<<3);                                                                     \
+        sse_forget_reg(dyn, ninst, ed);                                                                 \
+        fixedaddress = 0;                                                                               \
+        ADDI(a, xEmu, offsetof(x64emu_t, xmm[ed]));                                                     \
+    } else {                                                                                            \
+        SMREAD();                                                                                       \
+        ed=16;                                                                                          \
+        addr = geted(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, 1, D);          \
+    }
+
 // CALL will use x6 for the call address. Return value can be put in ret (unless ret is -1)
 // R0 will not be pushed/popd if ret is -2
 #define CALL(F, ret) call_c(dyn, ninst, F, x6, ret, 1, 0)