diff options
Diffstat (limited to 'src/dynarec/la64/dynarec_la64_pass0.h')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_pass0.h | 24 |
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) \ |