about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-11-17 15:14:13 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-11-17 15:14:13 +0100
commit56298870f68294b76ef963dd2ea0864789b811c3 (patch)
treef2512bac77711da04fcb3e420c388c20a86295d5 /src
parent48354185dd3ea7fbec26a9078c72816cced1ec3d (diff)
downloadbox64-56298870f68294b76ef963dd2ea0864789b811c3.tar.gz
box64-56298870f68294b76ef963dd2ea0864789b811c3.zip
[ARM64_DYNAREC] Only propagate native flags if at least 1 opcode consume them
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_functions.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c
index a37434d0..8e0827f0 100644
--- a/src/dynarec/arm64/dynarec_arm64_functions.c
+++ b/src/dynarec/arm64/dynarec_arm64_functions.c
@@ -858,12 +858,16 @@ static uint8_t getNativeFlagsUsed(dynarec_arm_t* dyn, int start, uint8_t flags)
 {
     // propagate and check wich flags are actually used
     uint8_t used_flags = 0;
+    int nat_flags_used = 0;
     int ninst = start;
     while(ninst<dyn->size) {
-//printf_log(LOG_INFO, "getNativeFlagsUsed ninst:%d/%d, flags=%x, used_flags=%x, nat_flags_op_before:%x, nat_flags_op:%x, need_after:%x\n", ninst, start, flags, used_flags, dyn->insts[ninst].nat_flags_op_before, dyn->insts[ninst].nat_flags_op, flag2native(dyn->insts[ninst].x64.need_after));
+//printf_log(LOG_INFO, "getNativeFlagsUsed ninst:%d/%d, flags=%x, used_flags=%x(%d), nat_flags_op_before:%x, nat_flags_op:%x, need_after:%x\n", ninst, start, flags, used_flags, nat_flags_used, dyn->insts[ninst].nat_flags_op_before, dyn->insts[ninst].nat_flags_op, flag2native(dyn->insts[ninst].x64.need_after));
         // check if this is an opcode that generate flags but consume flags before
         if(dyn->insts[ninst].nat_flags_op_before)
             return 0;
+        // check if nat flags are used "before"
+        if(dyn->insts[ninst].use_nat_flags_before)
+            nat_flags_used = 1;
         if(dyn->insts[ninst].nat_flags_op==NAT_FLAG_OP_TOUCH && dyn->insts[ninst].use_nat_flags_before)
             used_flags|=dyn->insts[ninst].use_nat_flags_before&flags;
         // if the opcode generate flags, return
@@ -871,15 +875,18 @@ static uint8_t getNativeFlagsUsed(dynarec_arm_t* dyn, int start, uint8_t flags)
             if(used_flags&~dyn->insts[ninst].set_nat_flags) {
                 // check partial changes that would destroy flag state
                 if(dyn->insts[ninst].use_nat_flags_before&flags)
-                    return used_flags;
+                    return nat_flags_used?used_flags:0;
                 // but also check if there is before needed
                 return 0;
             }
-            return used_flags;
+            return nat_flags_used?used_flags:0;
         }
         // check if there is a callret barrier
         if(dyn->insts[ninst].x64.has_callret)
             return 0;
+        // check if nat flags are used
+        if(dyn->insts[ninst].use_nat_flags)
+            nat_flags_used = 1;
         // check if flags are used, but not the natives ones
         if(ninst!=start && dyn->insts[ninst].x64.use_flags) {
             if((flag2native(dyn->insts[ninst].x64.use_flags)&~(dyn->insts[ninst].use_nat_flags))&used_flags)
@@ -893,11 +900,11 @@ static uint8_t getNativeFlagsUsed(dynarec_arm_t* dyn, int start, uint8_t flags)
             if(used_flags&~flag2native(dyn->insts[ninst].x64.gen_flags&dyn->insts[ninst].x64.need_after))
                 return 0;   // partial covert, not supported for now (TODO: this might be fixable)
             else
-                return used_flags;  // full covert... End of propagation
+                return nat_flags_used?used_flags:0;  // full covert... End of propagation
         }
         // check if flags are still needed
         if(!(flag2native(dyn->insts[ninst].x64.need_after)&flags))
-            return used_flags;
+            return nat_flags_used?used_flags:0;
         // check if flags are destroyed, cancel the use then
         if(dyn->insts[ninst].nat_flags_op && (start!=ninst))
             return 0;
@@ -910,11 +917,11 @@ static uint8_t getNativeFlagsUsed(dynarec_arm_t* dyn, int start, uint8_t flags)
             if(dyn->insts[ninst].x64.jmp && (jmp!=-1) && (getNominalPred(dyn, jmp)==ninst))
                 ninst = jmp;
             else
-                return used_flags;
+                return nat_flags_used?used_flags:0;
         } else
             ++ninst;
     }
-    return used_flags;
+    return nat_flags_used?used_flags:0;
 }
 
 static void propagateNativeFlags(dynarec_arm_t* dyn, int start)