about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-02-22 17:39:33 +0800
committerGitHub <noreply@github.com>2024-02-22 10:39:33 +0100
commitf2eb5326af6eabe8b6196279f278f2975094d2d8 (patch)
treef8279ee75c9f2f8dc9ccfc818f85665d396c0c4e /src
parentf09b541ab73dc7eb753a812c3fdd4d0cc17f7b02 (diff)
downloadbox64-f2eb5326af6eabe8b6196279f278f2975094d2d8.tar.gz
box64-f2eb5326af6eabe8b6196279f278f2975094d2d8.zip
[RV64_DYNAREC] Added more opcodes (#1276)
* Added 66 9C/9D PUSHF/POPF opcodes

* Added 0F E2 PSRAD opcode

* Fix

* More readable
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c6
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_2.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c37
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c26
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h12
-rw-r--r--src/dynarec/rv64/rv64_emitter.h12
7 files changed, 68 insertions, 31 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index b59e832d..a4d19285 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -721,10 +721,8 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             SET_DFNONE(x1);

             if(box64_wine) {    // should this be done all the time?

                 TBZ_NEXT(xFlags, F_TF);

-                MOV64x(x1, addr);

-                STORE_XEMU_CALL(x1);

-                CALL(native_singlestep, -1);

-                BFCw(xFlags, F_TF, 1);

+                // go to epilog, TF should trigger at end of next opcode, so using Interpretor only

+                jump_to_epilog(dyn, addr, 0, ninst);

             }

             break;

 

diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c
index bea16d2d..bc6ae6c9 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_2.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_2.c
@@ -491,7 +491,7 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             INST_NAME("POPF");
             SETFLAGS(X_ALL, SF_SET);
             POP1z(xFlags);
-            FLAGS_ADJUST_FROM11(xFlags, x2);
+            FLAGS_ADJUST_FROM11(xFlags, xFlags, x2);
             MOV32w(x1, 0x3F7FD7);
             AND(xFlags, xFlags, x1);
             ORI(xFlags, xFlags, 0x2);
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index f048936c..f98aaec5 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -1861,6 +1861,25 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             AND(x1, x1, x2);
             SD(x1, gback, gdoffset);
             break;
+        case 0xE2:
+            INST_NAME("PSRAD Gm, Em");
+            nextop = F8;
+            GETGM();
+            GETEM(x4, 0);
+            LBU(x1, wback, fixedaddress);
+            ADDI(x2, xZR, 31);
+            if (rv64_zbb) {
+                MINU(x1, x1, x2);
+            } else {
+                BLTU(x1, x2, 4 + 4);
+                MV(x1, x2);
+            }
+            for (int i = 0; i < 2; ++i) {
+                LW(x3, gback, gdoffset + 4 * i);
+                SRAW(x3, x3, x1);
+                SW(x3, gback, gdoffset + 4 * i);
+            }
+            break;
         case 0xE5:
             INST_NAME("PMULHW Gm,Em");
             nextop = F8;
@@ -1874,24 +1893,6 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 SH(x3, gback, gdoffset + 2 * i);
             }
             break;
-            INST_NAME("PSUBSW Gm,Em");
-            nextop = F8;
-            GETGM();
-            GETEM(x2, 0);
-            for (int i = 0; i < 4; ++i) {
-                LH(x3, gback, gdoffset + i * 2);
-                LH(x4, wback, fixedaddress);
-                SUBW(x3, x3, x4);
-                LUI(x4, 0xFFFF8); // -32768
-                BGE(x3, x4, 12);
-                SH(x4, gback, gdoffset + i * 2);
-                J(20);      // continue
-                LUI(x4, 8); // 32768
-                BLT(x3, x4, 8);
-                ADDIW(x3, x4, -1);
-                SH(x4, gback, gdoffset + i * 2);
-            }
-            break;
         case 0xE7:
             INST_NAME("MOVNTQ Em, Gm");
             nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c
index bb7b34f4..59350bcb 100644
--- a/src/dynarec/rv64/dynarec_rv64_66.c
+++ b/src/dynarec/rv64/dynarec_rv64_66.c
@@ -641,6 +641,32 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             SLLI(xRDX, xRDX, 16);
             OR(xRDX, xRDX, x1);
             break;
+        case 0x9C:
+            INST_NAME("PUSHF");
+            NOTEST(x1);
+            READFLAGS(X_ALL);
+            FLAGS_ADJUST_TO11(x3, xFlags, x2);
+            PUSH1_16(x3);
+            break;
+        case 0x9D:
+            INST_NAME("POPF");
+            SETFLAGS(X_ALL, SF_SET);
+            POP1_16(x1);
+            FLAGS_ADJUST_FROM11(x1, x1, x2);
+            LUI(x2, 0xffff0);
+            AND(xFlags, xFlags, x2);
+            OR(xFlags, xFlags, x1);
+            MOV32w(x1, 0x3F7FD7);
+            AND(xFlags, xFlags, x1);
+            ORI(xFlags, xFlags, 0x2);
+            SET_DFNONE();
+            if (box64_wine) { // should this be done all the time?
+                ANDI(x1, xFlags, 1 << F_TF);
+                CBZ_NEXT(x1);
+                // go to epilog, TF should trigger at end of next opcode, so using Interpretor only
+                jump_to_epilog(dyn, addr, 0, ninst);
+            }
+            break;
         case 0xA1:
             INST_NAME("MOV EAX,Od");
             if (rex.is32bits) u64 = F32; else u64 = F64;
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index 68b00042..1bb36b07 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -736,7 +736,7 @@ void call_c(dynarec_rv64_t* dyn, int ninst, void* fnc, int reg, int ret, int sav
     fpu_popcache(dyn, ninst, reg, 0);
     if(saveflags) {
         LD(xFlags, xEmu, offsetof(x64emu_t, eflags));
-        FLAGS_ADJUST_FROM11(xFlags, reg);
+        FLAGS_ADJUST_FROM11(xFlags, xFlags, reg);
     }
     SET_NODF();
     dyn->last_ip = 0;
@@ -799,7 +799,7 @@ void call_n(dynarec_rv64_t* dyn, int ninst, void* fnc, int w)
 
     fpu_popcache(dyn, ninst, x3, 1);
     LD(xFlags, xEmu, offsetof(x64emu_t, eflags));
-    FLAGS_ADJUST_FROM11(xFlags, x3);
+    FLAGS_ADJUST_FROM11(xFlags, xFlags, x3);
     SET_NODF();
 }
 
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 0a1dcfa6..9fd7267d 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -874,11 +874,11 @@
         }                                                             \
     }
 
-// Adjust the xFlags bit 11 -> bit 5, result in reg (can be xFlags, but not s1)
-#define FLAGS_ADJUST_FROM11(reg, s1) \
-    ANDI(reg, xFlags, ~(1 << 5));    \
-    SRLI(s1, reg, 11 - 5);           \
-    ANDI(s1, s1, 1 << 5);            \
+// Adjust the flags bit 11 -> bit 5, result in reg (can be same as flags, but not s1)
+#define FLAGS_ADJUST_FROM11(reg, flags, s1) \
+    ANDI(reg, flags, ~(1 << 5));            \
+    SRLI(s1, reg, 11 - 5);                  \
+    ANDI(s1, s1, 1 << 5);                   \
     OR(reg, reg, s1)
 
 // Adjust the xFlags bit 5 -> bit 11, src and dst can be the same (and can be xFlags, but not s1)
@@ -934,7 +934,7 @@
             BEQ(x3, xZR, j64);                      \
         }                                           \
         CALL_(UpdateFlags, -1, 0);                  \
-        FLAGS_ADJUST_FROM11(xFlags, x3);            \
+        FLAGS_ADJUST_FROM11(xFlags, xFlags, x3);    \
         MARKF;                                      \
         dyn->f.pending = SF_SET;                    \
         SET_DFOK();                                 \
diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h
index fdbfdfe3..6b675f6e 100644
--- a/src/dynarec/rv64/rv64_emitter.h
+++ b/src/dynarec/rv64/rv64_emitter.h
@@ -376,6 +376,18 @@ f28–31  ft8–11  FP temporaries                  Caller
         PUSH1(reg);     \
     }
 
+#define PUSH1_16(reg)        \
+    do {                     \
+        SH(reg, xRSP, -2);   \
+        SUBI(xRSP, xRSP, 2); \
+    } while (0)
+
+#define POP1_16(reg)                          \
+    do {                                      \
+        LHU(reg, xRSP, 0);                    \
+        if (reg != xRSP) ADDI(xRSP, xRSP, 2); \
+    } while (0)
+
 #define FENCE_gen(pred, succ) (((pred) << 24) | ((succ) << 20) | 0b0001111)
 #define FENCE()               EMIT(FENCE_gen(3, 3))