diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-04-27 17:37:44 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-04-27 17:37:44 +0200 |
| commit | b552de33f98a573a1548372e970bf5c7a3bf1849 (patch) | |
| tree | 93051adcfce57f2c7cead228846e12bae73a2faf /src | |
| parent | 35c8beb15faa3e99390fabc2afdba575b5d5bf43 (diff) | |
| download | box64-b552de33f98a573a1548372e970bf5c7a3bf1849.tar.gz box64-b552de33f98a573a1548372e970bf5c7a3bf1849.zip | |
[ARM64_DYNAREC] Some work on UD flags on (66) F3 0F BC/BD opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_0f.c | 38 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_660f.c | 42 |
2 files changed, 64 insertions, 16 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index 7850393d..5df3ba2d 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -2321,11 +2321,17 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xBC: INST_NAME("BSF Gd, Ed"); - SETFLAGS(X_ZF, SF_SET); + if(!BOX64ENV(dynarec_safeflags) || BOX64ENV(cputype)) { + SETFLAGS(X_ZF, SF_SUBSET); + } else { + SETFLAGS(X_ALL, SF_SET); + } SET_DFNONE(); nextop = F8; GETED(0); GETGD; + if(ed!=gd) + MOVxw_REG(gd, ed); // to handle ed=0, setting UD gd to 0 IFX(X_ZF) { TSTxw_REG(ed, ed); B_MARK(cEQ); @@ -2337,18 +2343,31 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MARK; IFX(X_ZF) { IFNATIVE(NF_EQ) {} else { - CSETw(x1, cEQ); //other flags are undefined - BFIw(xFlags, x1, F_ZF, 1); + CSETw(x2, cEQ); //other flags are undefined + BFIw(xFlags, x2, F_ZF, 1); } } + if(BOX64ENV(dynarec_safeflags) && !BOX64ENV(cputype)) { + IFX(X_CF) BFCw(xFlags, F_CF, 1); + IFX(X_AF) BFCw(xFlags, F_AF, 1); + IFX(X_SF) BFCw(xFlags, F_SF, 1); + IFX(X_OF) BFCw(xFlags, F_OF, 1); + IFX(X_PF) emit_pf(dyn, ninst, gd, x2); + } break; case 0xBD: INST_NAME("BSR Gd, Ed"); - SETFLAGS(X_ZF, SF_SET); + if(!BOX64ENV(dynarec_safeflags) || BOX64ENV(cputype)) { + SETFLAGS(X_ZF, SF_SUBSET); + } else { + SETFLAGS(X_ALL, SF_SET); + } SET_DFNONE(); nextop = F8; GETED(0); GETGD; + if(ed!=gd) + MOVxw_REG(gd, ed); // to handle ed=0, setting UD gd to 0 IFX(X_ZF) { TSTxw_REG(ed, ed); B_MARK(cEQ); @@ -2361,10 +2380,17 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MARK; IFX(X_ZF) { IFNATIVE(NF_EQ) {} else { - CSETw(x1, cEQ); //other flags are undefined - BFIw(xFlags, x1, F_ZF, 1); + CSETw(x2, cEQ); //other flags are undefined + BFIw(xFlags, x2, F_ZF, 1); } } + if(BOX64ENV(dynarec_safeflags) && !BOX64ENV(cputype)) { + IFX(X_CF) BFCw(xFlags, F_CF, 1); + IFX(X_AF) BFCw(xFlags, F_AF, 1); + IFX(X_SF) BFCw(xFlags, F_SF, 1); + IFX(X_OF) BFCw(xFlags, F_OF, 1); + IFX(X_PF) emit_pf(dyn, ninst, gd, x2); + } break; case 0xBE: INST_NAME("MOVSX Gd, Eb"); diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index cc9a6d63..40d9f7f3 100644 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -2742,7 +2742,11 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n break; case 0xBC: INST_NAME("BSF Gw,Ew"); - SETFLAGS(X_ZF, SF_SUBSET); + if(!BOX64ENV(dynarec_safeflags) || BOX64ENV(cputype)) { + SETFLAGS(X_ZF, SF_SUBSET); + } else { + SETFLAGS(X_ALL, SF_SET); + } SET_DFNONE(); nextop = F8; GETGD; @@ -2754,19 +2758,30 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n CBZw_MARK(x1); } RBITw(x1, x1); // reverse - CLZw(x2, x1); // x2 gets leading 0 == BSF - BFIx(gd, x2, 0, 16); + CLZw(x1, x1); // x2 gets leading 0 == BSF MARK; + BFIx(gd, x1, 0, 16); IFX(X_ZF) { IFNATIVE(NF_EQ) {} else { - CSETw(x1, cEQ); //ZF not set - BFIw(xFlags, x1, F_ZF, 1); + CSETw(x2, cEQ); //ZF not set + BFIw(xFlags, x2, F_ZF, 1); } } + if(BOX64ENV(dynarec_safeflags) && !BOX64ENV(cputype)) { + IFX(X_CF) BFCw(xFlags, F_CF, 1); + IFX(X_AF) BFCw(xFlags, F_AF, 1); + IFX(X_SF) BFCw(xFlags, F_SF, 1); + IFX(X_OF) BFCw(xFlags, F_OF, 1); + IFX(X_PF) emit_pf(dyn, ninst, x1, x2); + } break; case 0xBD: INST_NAME("BSR Gw,Ew"); - SETFLAGS(X_ZF, SF_SUBSET); + if(!BOX64ENV(dynarec_safeflags) || BOX64ENV(cputype)) { + SETFLAGS(X_ZF, SF_SUBSET); + } else { + SETFLAGS(X_ALL, SF_SET); + } SET_DFNONE(); nextop = F8; GETGD; @@ -2780,15 +2795,22 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n LSLw(x1, x1, 16); // put bits on top CLZw(x2, x1); // x2 gets leading 0 SUBw_U12(x2, x2, 15); - NEGw_REG(x2, x2); // complement - BFIx(gd, x2, 0, 16); + NEGw_REG(x1, x2); // complement MARK; + BFIx(gd, x1, 0, 16); IFX(X_ZF) { IFNATIVE(NF_EQ) {} else { - CSETw(x1, cEQ); //ZF not set - BFIw(xFlags, x1, F_ZF, 1); + CSETw(x2, cEQ); //ZF not set + BFIw(xFlags, x2, F_ZF, 1); } } + if(BOX64ENV(dynarec_safeflags) && !BOX64ENV(cputype)) { + IFX(X_CF) BFCw(xFlags, F_CF, 1); + IFX(X_AF) BFCw(xFlags, F_AF, 1); + IFX(X_SF) BFCw(xFlags, F_SF, 1); + IFX(X_OF) BFCw(xFlags, F_OF, 1); + IFX(X_PF) emit_pf(dyn, ninst, x1, x2); + } break; case 0xBE: INST_NAME("MOVSX Gw, Eb"); |