about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.c29
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h18
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c31
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h17
-rw-r--r--src/tools/env.c4
5 files changed, 41 insertions, 58 deletions
diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c
index 4fb7f95e..c334765e 100644
--- a/src/dynarec/la64/dynarec_la64_helper.c
+++ b/src/dynarec/la64/dynarec_la64_helper.c
@@ -1666,29 +1666,20 @@ static void flagsCacheTransform(dynarec_la64_t* dyn, int ninst, int s1)
     int jmp = dyn->insts[ninst].x64.jmp_insts;
     if (jmp < 0)
         return;
-    if (dyn->f.dfnone) // flags are fully known, nothing we can do more
+    if (dyn->f.dfnone || ((dyn->insts[jmp].f_exit.dfnone && !dyn->insts[jmp].f_entry.dfnone) && !dyn->insts[jmp].x64.use_flags)) // flags are fully known, nothing we can do more
         return;
     MESSAGE(LOG_DUMP, "\tFlags fetch ---- ninst=%d -> %d\n", ninst, jmp);
-    int go = (dyn->insts[jmp].f_entry.dfnone && !dyn->f.dfnone) ? 1 : 0;
+    int go = (dyn->insts[jmp].f_entry.dfnone && !dyn->f.dfnone && !dyn->insts[jmp].df_notneeded) ? 1 : 0;
     switch (dyn->insts[jmp].f_entry.pending) {
-        case SF_UNKNOWN: break;
-        case SF_SET:
-            if (dyn->f.pending != SF_SET && dyn->f.pending != SF_SET_PENDING)
-                go = 1;
+        case SF_UNKNOWN:
+            go = 0;
             break;
-        case SF_SET_PENDING:
-            if (dyn->f.pending != SF_SET
-                && dyn->f.pending != SF_SET_PENDING
-                && dyn->f.pending != SF_PENDING)
-                go = 1;
-            break;
-        case SF_PENDING:
-            if (dyn->f.pending != SF_SET
-                && dyn->f.pending != SF_SET_PENDING
-                && dyn->f.pending != SF_PENDING)
-                go = 1;
-            else if (dyn->insts[jmp].f_entry.dfnone != dyn->f.dfnone)
-                go = 1;
+        default:
+            if (go && !(dyn->insts[jmp].x64.need_before & X_PEND) && (dyn->f.pending != SF_UNKNOWN)) {
+                // just clear df flags
+                go = 0;
+                ST_W(xZR, xEmu, offsetof(x64emu_t, df));
+            }
             break;
     }
     if (go) {
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index 68219e77..92f271bf 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -858,14 +858,16 @@
     LOAD_REG(R14);      \
     LOAD_REG(R15);
 
-#define SET_DFNONE()                                 \
-    do {                                             \
-        if (!dyn->f.dfnone) {                        \
-            ST_W(xZR, xEmu, offsetof(x64emu_t, df)); \
-        }                                            \
-        if (!dyn->insts[ninst].x64.may_set) {        \
-            dyn->f.dfnone = 1;                       \
-        }                                            \
+#define FORCE_DFNONE() ST_W(xZR, xEmu, offsetof(x64emu_t, df))
+
+#define SET_DFNONE()                          \
+    do {                                      \
+        if (!dyn->f.dfnone) {                 \
+            FORCE_DFNONE();                   \
+        }                                     \
+        if (!dyn->insts[ninst].x64.may_set) { \
+            dyn->f.dfnone = 1;                \
+        }                                     \
     } while (0)
 
 #define SET_DF(S, N)                                           \
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index 0b597163..8a21e80e 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -2762,33 +2762,22 @@ static void flagsCacheTransform(dynarec_rv64_t* dyn, int ninst, int s1)
     int jmp = dyn->insts[ninst].x64.jmp_insts;
     if (jmp < 0)
         return;
-    if (dyn->f.dfnone) // flags are fully known, nothing we can do more
+    if (dyn->f.dfnone || ((dyn->insts[jmp].f_exit.dfnone && !dyn->insts[jmp].f_entry.dfnone) && !dyn->insts[jmp].x64.use_flags)) // flags are fully known, nothing we can do more
         return;
     MESSAGE(LOG_DUMP, "\tFlags fetch ---- ninst=%d -> %d\n", ninst, jmp);
-    int go = 0;
+    int go = (dyn->insts[jmp].f_entry.dfnone && !dyn->f.dfnone && !dyn->insts[jmp].df_notneeded) ? 1 : 0;
     switch (dyn->insts[jmp].f_entry.pending) {
-        case SF_UNKNOWN: break;
-        case SF_SET:
-            if (dyn->f.pending != SF_SET && dyn->f.pending != SF_SET_PENDING)
-                go = 1;
+        case SF_UNKNOWN:
+            go = 0;
             break;
-        case SF_SET_PENDING:
-            if (dyn->f.pending != SF_SET
-                && dyn->f.pending != SF_SET_PENDING
-                && dyn->f.pending != SF_PENDING)
-                go = 1;
-            break;
-        case SF_PENDING:
-            if (dyn->f.pending != SF_SET
-                && dyn->f.pending != SF_SET_PENDING
-                && dyn->f.pending != SF_PENDING)
-                go = 1;
-            else
-                go = (dyn->insts[jmp].f_entry.dfnone == dyn->f.dfnone) ? 0 : 1;
+        default:
+            if (go && !(dyn->insts[jmp].x64.need_before & X_PEND) && (dyn->f.pending != SF_UNKNOWN)) {
+                // just clear df flags
+                go = 0;
+                SW(xZR, xEmu, offsetof(x64emu_t, df));
+            }
             break;
     }
-    if (dyn->insts[jmp].f_entry.dfnone && !dyn->f.dfnone)
-        go = 1;
     if (go) {
         if (dyn->f.pending != SF_PENDING) {
             LW(s1, xEmu, offsetof(x64emu_t, df));
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index d009c0ab..0d3a976e 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -887,15 +887,16 @@
     LOAD_REG(R14);        \
     LOAD_REG(R15);
 
+#define FORCE_DFNONE() SW(xZR, xEmu, offsetof(x64emu_t, df))
 
-#define SET_DFNONE()                               \
-    do {                                           \
-        if (!dyn->f.dfnone) {                      \
-            SW(xZR, xEmu, offsetof(x64emu_t, df)); \
-        }                                          \
-        if (!dyn->insts[ninst].x64.may_set) {      \
-            dyn->f.dfnone = 1;                     \
-        }                                          \
+#define SET_DFNONE()                          \
+    do {                                      \
+        if (!dyn->f.dfnone) {                 \
+            FORCE_DFNONE();                   \
+        }                                     \
+        if (!dyn->insts[ninst].x64.may_set) { \
+            dyn->f.dfnone = 1;                \
+        }                                     \
     } while (0)
 
 #define SET_DF(S, N)                                                                                                            \
diff --git a/src/tools/env.c b/src/tools/env.c
index 877a9fc8..5b4c4ee3 100644
--- a/src/tools/env.c
+++ b/src/tools/env.c
@@ -809,9 +809,9 @@ done:
 #ifdef ARM64
 #define ARCH_VERSION SET_VERSION(0, 0, 3)
 #elif defined(RV64)
-#define ARCH_VERSION SET_VERSION(0, 0, 1)
+#define ARCH_VERSION SET_VERSION(0, 0, 2)
 #elif defined(LA64)
-#define ARCH_VERSION SET_VERSION(0, 0, 1)
+#define ARCH_VERSION SET_VERSION(0, 0, 2)
 #else
 #error meh!
 #endif