about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-10-08 19:58:32 +0800
committerGitHub <noreply@github.com>2024-10-08 13:58:32 +0200
commit8414563ad0d217b05dc8656c8d779ae16a66c58b (patch)
treec0981fa88f4ebb08edc26981646f6e038acb69b9 /src
parent85fc57faa32625f6b8294f0081d2af2e821750d9 (diff)
downloadbox64-8414563ad0d217b05dc8656c8d779ae16a66c58b.tar.gz
box64-8414563ad0d217b05dc8656c8d779ae16a66c58b.zip
[RV64_DYNAREC] Added more opcodes and small optimizations (#1914)
* [RV64_DYNAREC] Added more opcodes and small optimizations

* more

* only applies to and32c
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c39
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_logic.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f30f.c27
3 files changed, 66 insertions, 2 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 0db18f45..4529763b 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -1889,6 +1889,24 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         LWU(x4, xEmu, offsetof(x64emu_t, mxcsr));
                         SW(x4, wback, fixedaddress);
                         break;
+                    case 4:
+                        INST_NAME("XSAVE Ed");
+                        MESSAGE(LOG_DUMP, "Need Optimization\n");
+                        fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
+                        addr = geted(dyn, addr, ninst, nextop, &wback, x1, x2, &fixedaddress, rex, NULL, 0, 0);
+                        if (ed != x1) { MV(x1, ed); }
+                        MOV32w(x2, rex.is32bits);
+                        CALL((void*)fpu_xsave, -1);
+                        break;
+                    case 5:
+                        INST_NAME("XRSTOR Ed");
+                        MESSAGE(LOG_DUMP, "Need Optimization\n");
+                        fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
+                        addr = geted(dyn, addr, ninst, nextop, &wback, x1, x2, &fixedaddress, rex, NULL, 0, 0);
+                        if (ed != x1) { MV(x1, ed); }
+                        MOV32w(x2, rex.is32bits);
+                        CALL((void*)fpu_xrstor, -1);
+                        break;
                     case 7:
                         INST_NAME("CLFLUSH Ed");
                         MESSAGE(LOG_DUMP, "Need Optimization?\n");
@@ -2350,7 +2368,26 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             SW(x5, gback, gdoffset + 2 * 4);
             SW(x6, gback, gdoffset + 3 * 4);
             break;
-
+        case 0xC7:
+            // rep has no impact here
+            nextop = F8;
+            if (MODREG) {
+                switch ((nextop >> 3) & 7) {
+                    default:
+                        DEFAULT;
+                }
+            } else {
+                switch ((nextop >> 3) & 7) {
+                    case 4:
+                        INST_NAME("Unsupported XSAVEC Ed");
+                        FAKEED;
+                        UDF();
+                        break;
+                    default:
+                        DEFAULT;
+                }
+            }
+            break;
         case 0xC8:
         case 0xC9:
         case 0xCA:
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_logic.c b/src/dynarec/rv64/dynarec_rv64_emit_logic.c
index e954b32e..99ca4684 100644
--- a/src/dynarec/rv64/dynarec_rv64_emit_logic.c
+++ b/src/dynarec/rv64/dynarec_rv64_emit_logic.c
@@ -422,7 +422,7 @@ void emit_and32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
         MOV64xw(s3, c);
         AND(s1, s1, s3); // res = s1 & s2
     }
-    if (!rex.w) ZEROUP(s1);
+    if (!rex.w && (c > 2047 || c < 0)) ZEROUP(s1);
 
     IFX(X_PEND) {
         SDxw(s1, xEmu, offsetof(x64emu_t, res));
diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c
index 29438f2f..a4f19358 100644
--- a/src/dynarec/rv64/dynarec_rv64_f30f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f30f.c
@@ -355,6 +355,33 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 SW(x3, gback, gdoffset + i * 4);
             }
             break;
+        case 0xAE:
+            nextop = F8;
+            switch ((nextop >> 3) & 7) {
+                case 2:
+                    INST_NAME("(unsupported) WRFSBASE Ed");
+                    FAKEED;
+                    UDF();
+                    break;
+                case 3:
+                    INST_NAME("(unsupported) WRGSBASE Ed");
+                    FAKEED;
+                    UDF();
+                    break;
+                case 5:
+                    INST_NAME("(unsupported) INCSSPD/INCSSPQ Ed");
+                    FAKEED;
+                    UDF();
+                    break;
+                case 6:
+                    INST_NAME("(unsupported) UMONITOR Ed");
+                    FAKEED;
+                    UDF();
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
         case 0xB8:
             INST_NAME("POPCNT Gd, Ed");
             SETFLAGS(X_ALL, SF_SET);