about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-07-10 18:32:35 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-07-10 18:32:35 +0200
commit968594ee63e1c1ce9cd537c5df63b97e5bd8d91c (patch)
tree29812c4765e2eccabff01824256f624d16c5aa6b /src
parent3ac62c64d82c292787ba87b37a8bf580525365f3 (diff)
downloadbox64-968594ee63e1c1ce9cd537c5df63b97e5bd8d91c.tar.gz
box64-968594ee63e1c1ce9cd537c5df63b97e5bd8d91c.zip
[ARM64_DYNAREC] Simplified defered flags handling and limited case where UpdateFlags is actualy called (could be simplified more) (TODO on RV64 and LA64)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_functions.c3
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.c34
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h8
-rw-r--r--src/dynarec/arm64/dynarec_arm64_private.h1
-rw-r--r--src/dynarec/dynarec_native_pass.c1
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h4
-rw-r--r--src/dynarec/la64/dynarec_la64_private.h1
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_private.h1
9 files changed, 15 insertions, 42 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c
index e2ed058a..84832f65 100644
--- a/src/dynarec/arm64/dynarec_arm64_functions.c
+++ b/src/dynarec/arm64/dynarec_arm64_functions.c
@@ -774,7 +774,7 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r
     if (!dyn->need_dump && !BOX64ENV(dynarec_gdbjit) && !BOX64ENV(dynarec_perf_map)) return;
 
     static char buf[4096];
-    int length = sprintf(buf, "barrier=%d state=%d/%d/%d(%d:%d->%d:%d/%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d(%d/%d)",
+    int length = sprintf(buf, "barrier=%d state=%d/%d/%d(%d:%d->%d:%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d(%d/%d)",
         dyn->insts[ninst].x64.barrier,
         dyn->insts[ninst].x64.state_flags,
         dyn->f.pending,
@@ -783,7 +783,6 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r
         dyn->insts[ninst].f_entry.dfnone,
         dyn->insts[ninst].f_exit.pending,
         dyn->insts[ninst].f_exit.dfnone,
-        dyn->insts[ninst].f_exit.dfnone_here,
         dyn->insts[ninst].x64.may_set ? "may" : "set",
         dyn->insts[ninst].x64.set_flags,
         dyn->insts[ninst].x64.gen_flags,
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c
index 88ea9846..c8f242d3 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.c
+++ b/src/dynarec/arm64/dynarec_arm64_helper.c
@@ -2498,39 +2498,21 @@ static void flagsCacheTransform(dynarec_arm_t* dyn, int ninst, int s1)
     int jmp = dyn->insts[ninst].x64.jmp_insts;
     if(jmp<0)
         return;
-    if(dyn->f.dfnone || (dyn->insts[jmp].f_exit.dfnone_here && !dyn->insts[jmp].x64.use_flags))  // 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 && !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
-            ) {
-                // only sync if some previous flags are used or if all flags are not regenerated at the instuction
-                if(dyn->insts[jmp].x64.use_flags || (dyn->insts[jmp].x64.set_flags!=X_ALL))
-                    go = 1;
-                else if(go) {
-                    // just clear df flags
-                    go = 0;
-                    STRw_U12(xZR, xEmu, offsetof(x64emu_t, df));
-                }
+        default:
+            if(go && !(dyn->insts[jmp].x64.need_before&X_PEND) && (dyn->f.pending!=SF_UNKNOWN)) {
+                // just clear df flags
+                go = 0;
+                STRw_U12(xZR, xEmu, offsetof(x64emu_t, df));
             }
             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;
-            break;
     }
     if(go) {
         if(dyn->f.pending!=SF_PENDING) {
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 595660fb..266f988c 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -1119,11 +1119,12 @@
     x87_do_pop(dyn, ninst, scratch)
 #endif
 
+#define FORCE_DFNONE()  STRw_U12(wZR, xEmu, offsetof(x64emu_t, df))
+
 #define SET_DFNONE()                                        \
     do {                                                    \
         if (!dyn->f.dfnone) {                               \
-            STRw_U12(wZR, xEmu, offsetof(x64emu_t, df));    \
-            dyn->f.dfnone_here = 1;                         \
+            FORCE_DFNONE();                                 \
         }                                                   \
         if(!dyn->insts[ninst].x64.may_set) {                \
             dyn->f.dfnone = 1;                              \
@@ -1146,7 +1147,7 @@
 #ifndef SET_NODF
 #define SET_NODF()          dyn->f.dfnone = 0
 #endif
-#define SET_DFOK()          dyn->f.dfnone = 1; dyn->f.dfnone_here=1
+#define SET_DFOK()          dyn->f.dfnone = 1
 
 #ifndef READFLAGS
 #define READFLAGS(A) \
@@ -1197,7 +1198,6 @@
 #define UFLAG_RES(A) if(dyn->insts[ninst].x64.gen_flags) {STRxw_U12(A, xEmu, offsetof(x64emu_t, res));}
 #define UFLAG_DF(r, A) if(dyn->insts[ninst].x64.gen_flags) {SET_DF(r, A);}
 #define UFLAG_IF if(dyn->insts[ninst].x64.gen_flags)
-#define UFLAG_IF_DF if(dyn->insts[ninst].x64.gen_flags || (dyn->insts[ninst].f_entry.dfnone && dyn->insts[ninst].f_entry.dfnone_here))
 #define UFLAG_IF2(A) if(dyn->insts[ninst].x64.gen_flags A)
 #ifndef DEFAULT
 #define DEFAULT      *ok = -1; BARRIER(2)
diff --git a/src/dynarec/arm64/dynarec_arm64_private.h b/src/dynarec/arm64/dynarec_arm64_private.h
index 2e7145a9..e3d78d8e 100644
--- a/src/dynarec/arm64/dynarec_arm64_private.h
+++ b/src/dynarec/arm64/dynarec_arm64_private.h
@@ -87,7 +87,6 @@ typedef struct neoncache_s {
 typedef struct flagcache_s {
     int                 pending;    // is there a pending flags here, or to check?
     uint8_t             dfnone;     // if deferred flags is already set to df_none
-    uint8_t             dfnone_here;// defered flags is cleared in this opcode
 } flagcache_t;
 
 typedef struct instruction_arm64_s {
diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c
index a974fc12..dcf798dd 100644
--- a/src/dynarec/dynarec_native_pass.c
+++ b/src/dynarec/dynarec_native_pass.c
@@ -117,7 +117,6 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
         else if(ninst && (dyn->insts[ninst].pred_sz>1 || (dyn->insts[ninst].pred_sz==1 && dyn->insts[ninst].pred[0]!=ninst-1)))
             dyn->last_ip = 0;   // reset IP if some jump are coming here
         #endif
-        dyn->f.dfnone_here = 0;
         NEW_INST;
         MESSAGE(LOG_DUMP, "New Instruction %s:%p, native:%p\n", is32bits?"x86":"x64",(void*)addr, (void*)dyn->block);
         #ifdef ARCH_NOP
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index 9e636cda..b6b646a8 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -852,7 +852,6 @@
     do {                                             \
         if (!dyn->f.dfnone) {                        \
             ST_W(xZR, xEmu, offsetof(x64emu_t, df)); \
-            dyn->f.dfnone_here = 1;                  \
         }                                            \
         if (!dyn->insts[ninst].x64.may_set) {        \
             dyn->f.dfnone = 1;                       \
@@ -876,8 +875,7 @@
 
 #define SET_NODF() dyn->f.dfnone = 0
 #define SET_DFOK()     \
-    dyn->f.dfnone = 1; \
-    dyn->f.dfnone_here = 1
+    dyn->f.dfnone = 1
 
 #define CLEAR_FLAGS_(s)                                                                                       \
     MOV64x(s, (1UL << F_AF) | (1UL << F_CF) | (1UL << F_OF) | (1UL << F_ZF) | (1UL << F_SF) | (1UL << F_PF)); \
diff --git a/src/dynarec/la64/dynarec_la64_private.h b/src/dynarec/la64/dynarec_la64_private.h
index 08e0ffe2..a71557cc 100644
--- a/src/dynarec/la64/dynarec_la64_private.h
+++ b/src/dynarec/la64/dynarec_la64_private.h
@@ -80,7 +80,6 @@ typedef struct lsxcache_s {
 typedef struct flagcache_s {
     int                 pending;    // is there a pending flags here, or to check?
     uint8_t             dfnone;     // if deferred flags is already set to df_none
-    uint8_t             dfnone_here;// defered flags is cleared in this opcode
 } flagcache_t;
 
 typedef struct callret_s callret_t;
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index bbd305cf..d009c0ab 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -892,7 +892,6 @@
     do {                                           \
         if (!dyn->f.dfnone) {                      \
             SW(xZR, xEmu, offsetof(x64emu_t, df)); \
-            dyn->f.dfnone_here = 1;                \
         }                                          \
         if (!dyn->insts[ninst].x64.may_set) {      \
             dyn->f.dfnone = 1;                     \
@@ -913,8 +912,7 @@
         SET_DFNONE()
 #define SET_NODF() dyn->f.dfnone = 0
 #define SET_DFOK()     \
-    dyn->f.dfnone = 1; \
-    dyn->f.dfnone_here = 1
+    dyn->f.dfnone = 1
 
 #define CLEAR_FLAGS() \
     IFX (X_ALL) { ANDI(xFlags, xFlags, ~((1UL << F_AF) | (1UL << F_CF) | (1UL << F_OF2) | (1UL << F_ZF) | (1UL << F_SF) | (1UL << F_PF))); }
diff --git a/src/dynarec/rv64/dynarec_rv64_private.h b/src/dynarec/rv64/dynarec_rv64_private.h
index 4fa1b91c..d50bafab 100644
--- a/src/dynarec/rv64/dynarec_rv64_private.h
+++ b/src/dynarec/rv64/dynarec_rv64_private.h
@@ -96,7 +96,6 @@ typedef struct extcache_s {
 typedef struct flagcache_s {
     int                 pending;    // is there a pending flags here, or to check?
     uint8_t             dfnone;     // if deferred flags is already set to df_none
-    uint8_t             dfnone_here;// defered flags is cleared in this opcode
 } flagcache_t;
 
 typedef struct callret_s callret_t;