about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-03-29 14:55:33 +0800
committerGitHub <noreply@github.com>2023-03-29 08:55:33 +0200
commita665d2f62cb6f841954962005b73fbe371e031b5 (patch)
tree6226a999b0947256c1aa93659431b918e34718a7 /src
parent0baa5a82ad00e0bb3c024be2355dd58a9399e68a (diff)
downloadbox64-a665d2f62cb6f841954962005b73fbe371e031b5.tar.gz
box64-a665d2f62cb6f841954962005b73fbe371e031b5.zip
[RV64_DYNAREC] Added some 66 0F Pxxx opcodes (#650)
* [RV64_DYNAREC] Fixed typos

* [RV64_DYNAREC] Added 66 0F FE PADDD opcode

* [RV64_DYNAREC] Added 66 0F DB PAND opcode

* [RV64_DYNAREC] Added 66 0F 76 PCMPEQD opcode

* [RV64_DYNAREC] Added 66 0F 72 /2 PSRLD opcode

* [RV64_DYNAREC] Added 66 0F DF PANDN opcode

* [RV64_DYNAREC] Added 66 0F EB POR opcode

* [RV64_DYNAREC] Fixed 66 0F 72 PSRLD opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c59
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h43
-rw-r--r--src/emu/x64test.c2
3 files changed, 91 insertions, 13 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index 22c61359..7a32c44c 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -107,7 +107,34 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             SD(x3, gback, 0);
             SD(x4, gback, 8);
             break;
-
+        case 0x72:
+            nextop = F8;
+            switch((nextop>>3)&7) {
+                case 2:
+                    INST_NAME("PSRLD Ex, Ib");
+                    GETEX(x1, 1);
+                    u8 = F8;
+                    if(u8) {
+                        if (u8>31) {
+                            // just zero dest
+                            SD(xZR, x1, fixedaddress+0);
+                            SD(xZR, x1, fixedaddress+8);
+                        } else if(u8) {
+                            SSE_LOOP_DS(x3, SRLI(x3, x3, u8));
+                        }
+                    }
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
+        case 0x76:
+            INST_NAME("PCMPEQD Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            SSE_LOOP_D(x3, x4, XOR(x3, x3, x4); SNEZ(x3, x3); ADDI(x3, x3, -1));
+            break;
         case 0xAF:
             INST_NAME("IMUL Gw,Ew");
             SETFLAGS(X_ALL, SF_PENDING);
@@ -149,7 +176,27 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             AND(x1, x1, x5);
             OR(gd, gd, x1);
             break;
-
+        case 0xDB:
+            INST_NAME("PAND Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            SSE_LOOP_Q(x3, x4, AND(x3, x3, x4));
+            break;
+        case 0xDF:
+            INST_NAME("PANDN Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            SSE_LOOP_Q(x3, x4, NOT(x3, x3); AND(x3, x3, x4));
+            break;
+        case 0xEB:
+            INST_NAME("POR Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            SSE_LOOP_Q(x3, x4, OR(x3, x3, x4));
+            break;
         case 0xEF:
             INST_NAME("PXOR Gx, Ex");
             nextop = F8;
@@ -164,7 +211,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4));
             }
             break;
-
+        case 0xFE:
+            INST_NAME("PADDD Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            SSE_LOOP_D(x3, x4, ADDW(x3, x3, x4));
+            break;
         default:
             DEFAULT;
     }
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 892fd076..b79a1a17 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -315,7 +315,7 @@
     gback = a;                          \
     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. Use wback as load adress!
+// Get Ex address in general register a, will purge SS or SD if it's reg and is loaded. May use x3. Use wback as load address!
 #define GETEX(a, D)                                                                                     \
     if(MODREG) {                                                                                        \
         ed = (nextop&7)+(rex.b<<3);                                                                     \
@@ -329,16 +329,41 @@
         addr = geted(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, 1, D);          \
     }
 
-// Loop for SSE opcode that use 64bits value and write to GX.
-#define SSE_LOOP_Q(GX1, EX1, F)         \
-    LD(GX1, gback, 0);                  \
-    LD(EX1, wback, fixedaddress+0);     \
+#define SSE_LOOP_D_ITEM(GX1, EX1, F, i) \
+    LWU(GX1, gback, i*4);               \
+    LWU(EX1, wback, fixedaddress+i*4);  \
+    F;                                  \
+    SW(GX1, gback, i*4);
+
+// Loop for SSE opcode that use 32bits value and write to GX.
+#define SSE_LOOP_D(GX1, EX1, F)     \
+    SSE_LOOP_D_ITEM(GX1, EX1, F, 0) \
+    SSE_LOOP_D_ITEM(GX1, EX1, F, 1) \
+    SSE_LOOP_D_ITEM(GX1, EX1, F, 2) \
+    SSE_LOOP_D_ITEM(GX1, EX1, F, 3) \
+
+#define SSE_LOOP_DS_ITEM(EX1, F, i)     \
+    LWU(EX1, wback, fixedaddress+i*4);  \
     F;                                  \
-    SD(GX1, gback, 0);                  \
-    LD(GX1, gback, 8);                  \
-    LD(EX1, wback, fixedaddress+8);     \
+    SW(EX1, wback, fixedaddress+i*4);
+
+// Loop for SSE opcode that use 32bits value and write to EX.
+#define SSE_LOOP_DS(EX1, F)     \
+    SSE_LOOP_DS_ITEM(EX1, F, 0) \
+    SSE_LOOP_DS_ITEM(EX1, F, 1) \
+    SSE_LOOP_DS_ITEM(EX1, F, 2) \
+    SSE_LOOP_DS_ITEM(EX1, F, 3)
+
+#define SSE_LOOP_Q_ITEM(GX1, EX1, F, i) \
+    LD(GX1, gback, i*8);                \
+    LD(EX1, wback, fixedaddress+i*8);   \
     F;                                  \
-    SD(GX1, gback, 8)
+    SD(GX1, gback, i*8);
+
+// Loop for SSE opcode that use 64bits value and write to GX.
+#define SSE_LOOP_Q(GX1, EX1, F)     \
+    SSE_LOOP_Q_ITEM(GX1, EX1, F, 0) \
+    SSE_LOOP_Q_ITEM(GX1, EX1, F, 1)
 
 // 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
diff --git a/src/emu/x64test.c b/src/emu/x64test.c
index 151d3c8f..21a5355b 100644
--- a/src/emu/x64test.c
+++ b/src/emu/x64test.c
@@ -25,7 +25,7 @@
 void print_banner(x64emu_t* ref)
 {
     printf_log(LOG_NONE, "Warning, difference between Interpreter and Dynarec in %p\n=======================================\n", (void*)ref->ip.q[0]);
-    printf_log(LOG_NONE, "DIF: Dynarec |  Intepreter\n----------------------\n");
+    printf_log(LOG_NONE, "DIFF: Dynarec |  Interpreter\n----------------------\n");
 }
 #define BANNER if(!banner) {banner=1; print_banner(ref);}
 void x64test_check(x64emu_t* ref, uintptr_t ip)