From 35c8beb15faa3e99390fabc2afdba575b5d5bf43 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sun, 27 Apr 2025 16:18:57 +0200 Subject: [ARM64_DYNAREC] More work on UD flags for (66) F3 0F BC/BD opcodes --- src/dynarec/arm64/dynarec_arm64_66f30f.c | 32 ++++++++++++++++++++++++++++++-- src/dynarec/arm64/dynarec_arm64_f30f.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/dynarec/arm64/dynarec_arm64_66f30f.c b/src/dynarec/arm64/dynarec_arm64_66f30f.c index 2b6c0779..35c3b9ff 100644 --- a/src/dynarec/arm64/dynarec_arm64_66f30f.c +++ b/src/dynarec/arm64/dynarec_arm64_66f30f.c @@ -85,7 +85,15 @@ uintptr_t dynarec64_66F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int case 0xBC: INST_NAME("TZCNT Gw, Ew"); - SETFLAGS(X_CF|X_ZF, SF_SUBSET); + if(!BOX64ENV(dynarec_safeflags)) { + SETFLAGS(X_CF|X_ZF, SF_SUBSET); + } else { + if(BOX64ENV(cputype)) { + SETFLAGS(X_ALL&~X_OF, SF_SUBSET); + } else { + SETFLAGS(X_ALL, SF_SET); + } + } SET_DFNONE(); nextop = F8; GETEW(x1, 0); @@ -104,12 +112,26 @@ uintptr_t dynarec64_66F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int CSETw(x3, cEQ); BFIw(xFlags, x3, F_ZF, 1); // ZF = is dest 0? } + if(BOX64ENV(dynarec_safeflags)) { + IFX(X_AF) BFCw(xFlags, F_AF, 1); + IFX(X_PF) BFCw(xFlags, F_PF, 1); + IFX(X_SF) BFCw(xFlags, F_SF, 1); + IFX2(X_OF, && !BOX64ENV(cputype)) BFCw(xFlags, F_OF, 1); + } GWBACK; break; case 0xBD: INST_NAME("LZCNT Gw, Ew"); - SETFLAGS(X_CF|X_ZF, SF_SUBSET); + if(!BOX64ENV(dynarec_safeflags)) { + SETFLAGS(X_CF|X_ZF, SF_SUBSET); + } else { + if(BOX64ENV(cputype)) { + SETFLAGS(X_ALL&~X_OF, SF_SUBSET); + } else { + SETFLAGS(X_ALL, SF_SET); + } + } SET_DFNONE(); nextop = F8; GETEW(x1, 0); @@ -126,6 +148,12 @@ uintptr_t dynarec64_66F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int CSETw(x3, cEQ); BFIw(xFlags, x3, F_ZF, 1); // ZF = is dest 0? } + if(BOX64ENV(dynarec_safeflags)) { + IFX(X_AF) BFCw(xFlags, F_AF, 1); + IFX(X_PF) BFCw(xFlags, F_PF, 1); + IFX(X_SF) BFCw(xFlags, F_SF, 1); + IFX2(X_OF, && !BOX64ENV(cputype)) BFCw(xFlags, F_OF, 1); + } GWBACK; break; diff --git a/src/dynarec/arm64/dynarec_arm64_f30f.c b/src/dynarec/arm64/dynarec_arm64_f30f.c index 048e9193..558491f8 100644 --- a/src/dynarec/arm64/dynarec_arm64_f30f.c +++ b/src/dynarec/arm64/dynarec_arm64_f30f.c @@ -545,7 +545,15 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n case 0xBC: INST_NAME("TZCNT Gd, Ed"); - SETFLAGS(X_CF|X_ZF, SF_SUBSET); + if(!BOX64ENV(dynarec_safeflags)) { + SETFLAGS(X_CF|X_ZF, SF_SUBSET); + } else { + if(BOX64ENV(cputype)) { + SETFLAGS(X_ALL&~X_OF, SF_SUBSET); + } else { + SETFLAGS(X_ALL, SF_SET); + } + } SET_DFNONE(); nextop = F8; GETED(0); @@ -562,10 +570,24 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n CSETw(x3, cEQ); BFIw(xFlags, x3, F_ZF, 1); // ZF = is dest 0? } + if(BOX64ENV(dynarec_safeflags)) { + IFX(X_AF) BFCw(xFlags, F_AF, 1); + IFX(X_PF) BFCw(xFlags, F_PF, 1); + IFX(X_SF) BFCw(xFlags, F_SF, 1); + IFX2(X_OF, && !BOX64ENV(cputype)) BFCw(xFlags, F_OF, 1); + } break; case 0xBD: INST_NAME("LZCNT Gd, Ed"); - SETFLAGS(X_CF|X_ZF, SF_SUBSET); + if(!BOX64ENV(dynarec_safeflags)) { + SETFLAGS(X_CF|X_ZF, SF_SUBSET); + } else { + if(BOX64ENV(cputype)) { + SETFLAGS(X_ALL&~X_OF, SF_SUBSET); + } else { + SETFLAGS(X_ALL, SF_SET); + } + } SET_DFNONE(); nextop = F8; GETED(0); @@ -581,6 +603,12 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n CSETw(x3, cEQ); BFIw(xFlags, x3, F_ZF, 1); // ZF = is dest 0? } + if(BOX64ENV(dynarec_safeflags)) { + IFX(X_AF) BFCw(xFlags, F_AF, 1); + IFX(X_PF) BFCw(xFlags, F_PF, 1); + IFX(X_SF) BFCw(xFlags, F_SF, 1); + IFX2(X_OF, && !BOX64ENV(cputype)) BFCw(xFlags, F_OF, 1); + } break; case 0xC2: -- cgit 1.4.1