about summary refs log tree commit diff stats
path: root/src/dynarec/la64/dynarec_la64_pass0.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynarec/la64/dynarec_la64_pass0.h')
-rw-r--r--src/dynarec/la64/dynarec_la64_pass0.h24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/dynarec/la64/dynarec_la64_pass0.h b/src/dynarec/la64/dynarec_la64_pass0.h
index 3ed6c608..a35c9669 100644
--- a/src/dynarec/la64/dynarec_la64_pass0.h
+++ b/src/dynarec/la64/dynarec_la64_pass0.h
@@ -10,11 +10,25 @@
     dyn->insts[ninst].x64.use_flags = A; \
     dyn->f.dfnone = 1;                   \
     dyn->f.pending = SF_SET
-#define SETFLAGS(A, B)                     \
-    dyn->insts[ninst].x64.set_flags = A;   \
-    dyn->insts[ninst].x64.state_flags = B; \
-    dyn->f.pending = (B) & SF_SET_PENDING; \
-    dyn->f.dfnone = ((B) & SF_SET) ? 1 : 0;
+
+#define READFLAGS_FUSION(A, s1, s2, s3, s4, s5)                                                                 \
+    if (box64_dynarec_nativeflags && ninst > 0 && !dyn->insts[ninst - 1].nat_flags_nofusion) {                  \
+        if ((A) == (X_ZF))                                                                                      \
+            dyn->insts[ninst].nat_flags_fusion = 1;                                                             \
+        else if (dyn->insts[ninst - 1].nat_flags_carry && ((A) == (X_CF) || (A) == (X_CF | X_ZF)))              \
+            dyn->insts[ninst].nat_flags_fusion = 1;                                                             \
+        else if (dyn->insts[ninst - 1].nat_flags_sign && ((A) == (X_SF | X_OF) || (A) == (X_SF | X_OF | X_ZF))) \
+            dyn->insts[ninst].nat_flags_fusion = 1;                                                             \
+    }                                                                                                           \
+    READFLAGS(A);
+
+#define SETFLAGS(A, B, FUSION)                                           \
+    dyn->insts[ninst].x64.set_flags = A;                                 \
+    dyn->insts[ninst].x64.state_flags = (B) & ~SF_DF;                    \
+    dyn->f.pending = (B) & SF_SET_PENDING;                               \
+    dyn->f.dfnone = ((B) & SF_SET) ? (((B) == SF_SET_NODF) ? 0 : 1) : 0; \
+    dyn->insts[ninst].nat_flags_nofusion = (FUSION)
+
 #define EMIT(A) dyn->native_size += 4
 #define JUMP(A, C)         add_jump(dyn, ninst); add_next(dyn, (uintptr_t)A); SMEND(); dyn->insts[ninst].x64.jmp = A; dyn->insts[ninst].x64.jmp_cond = C; dyn->insts[ninst].x64.jmp_insts = 0
 #define BARRIER(A)                                 \