diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-11-13 14:38:14 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-11-13 14:38:14 +0100 |
| commit | f66aa575947ce827fc99f694ee74a3509d2c5c00 (patch) | |
| tree | 432b6f61aee0d8d2fd7c6ec0bc492893a7189aec /src | |
| parent | 506cb980b10b8850c9a2aaac1e4d97104617ba15 (diff) | |
| download | box64-f66aa575947ce827fc99f694ee74a3509d2c5c00.tar.gz box64-f66aa575947ce827fc99f694ee74a3509d2c5c00.zip | |
[ARM64_DYNAREC] Improved div/idiv opcode flags (non)handling
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 30 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_64.c | 14 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_66.c | 14 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_67.c | 14 |
4 files changed, 60 insertions, 12 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 0e4b22c2..bc0140ce 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -3270,7 +3270,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 6: INST_NAME("DIV Eb"); SETFLAGS(X_ALL, SF_SET); - SET_DFNONE(x1); GETEB(x1, 0); UXTHw(x2, xRAX); if(box64_dynarec_div0) { @@ -3287,12 +3286,17 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed) BFIx(xRAX, x3, 0, 8); BFIx(xRAX, x4, 8, 8); + SET_DFNONE(x2); + IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) + if(box64_dynarec_test) { + MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF)); + BICw(xFlags, xFlags, x1); + } break; case 7: INST_NAME("IDIV Eb"); SKIPTEST(x1); SETFLAGS(X_ALL, SF_SET); - SET_DFNONE(x1); GETSEB(x1, 0); if(box64_dynarec_div0) { CBNZw_MARK3(ed); @@ -3309,6 +3313,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed) BFIx(xRAX, x3, 0, 8); BFIx(xRAX, x4, 8, 8); + SET_DFNONE(x2); + IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) + if(box64_dynarec_test) { + MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF)); + BICw(xFlags, xFlags, x1); + } break; } break; @@ -3410,7 +3420,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("DIV Ed"); SETFLAGS(X_ALL, SF_SET); if(!rex.w) { - SET_DFNONE(x2); GETED(0); if(ninst && (nextop==0xF0) && dyn->insts[ninst-1].x64.addr @@ -3449,7 +3458,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin && dyn->insts[ninst-1].x64.addr && *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x31 && *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0xD2) { - SET_DFNONE(x2); GETED(0); if(box64_dynarec_div0) { CBNZx_MARK3(ed); @@ -3484,15 +3492,19 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin UDIVx(x2, xRAX, ed); MSUBx(xRDX, x2, ed, xRAX); MOVx_REG(xRAX, x2); - SET_DFNONE(x2); } } + SET_DFNONE(x2); + IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) + if(box64_dynarec_test) { + MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF)); + BICw(xFlags, xFlags, x1); + } break; case 7: INST_NAME("IDIV Ed"); SKIPTEST(x1); SETFLAGS(X_ALL, SF_SET); - SET_DFNONE(x2) if(!rex.w) { GETSEDw(0); if(box64_dynarec_div0) { @@ -3560,6 +3572,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOVx_REG(xRAX, x2); } } + SET_DFNONE(x2); + IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) + if(box64_dynarec_test) { + MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF)); + BICw(xFlags, xFlags, x1); + } break; } break; diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c index 1fcca3e6..d674c622 100644 --- a/src/dynarec/arm64/dynarec_arm64_64.c +++ b/src/dynarec/arm64/dynarec_arm64_64.c @@ -1388,7 +1388,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 6: INST_NAME("DIV Ed"); SETFLAGS(X_ALL, SF_SET); - SET_DFNONE(x2); if(!rex.w) { GETEDO(x6, 0); if(box64_dynarec_div0) { @@ -1452,12 +1451,17 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOVx_REG(xRAX, x2); } } + SET_DFNONE(x2); + IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) + if(box64_dynarec_test) { + MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF)); + BICw(xFlags, xFlags, x1); + } break; case 7: INST_NAME("IDIV Ed"); NOTEST(x1); SETFLAGS(X_ALL, SF_SET); - SET_DFNONE(x2) if(!rex.w) { GETSEDOw(x6, 0); MOVw_REG(x3, xRAX); @@ -1519,6 +1523,12 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOVx_REG(xRAX, x2); } } + SET_DFNONE(x2); + IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) + if(box64_dynarec_test) { + MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF)); + BICw(xFlags, xFlags, x1); + } break; } break; diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c index 8a270619..ac14430a 100644 --- a/src/dynarec/arm64/dynarec_arm64_66.c +++ b/src/dynarec/arm64/dynarec_arm64_66.c @@ -1374,7 +1374,6 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 6: INST_NAME("DIV Ew"); SETFLAGS(X_ALL, SF_SET); - SET_DFNONE(x1); GETEW(x1, 0); UXTHw(x2, xRAX); BFIw(x2, xRDX, 16, 16); @@ -1392,12 +1391,17 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed) BFIz(xRAX, x3, 0, 16); BFIz(xRDX, x4, 0, 16); + SET_DFNONE(x2); + IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) + if(box64_dynarec_test) { + MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF)); + BICw(xFlags, xFlags, x1); + } break; case 7: INST_NAME("IDIV Ew"); SKIPTEST(x1); SETFLAGS(X_ALL, SF_SET); - SET_DFNONE(x1); GETSEW(x1, 0); if(box64_dynarec_div0) { CBNZw_MARK3(ed); @@ -1415,6 +1419,12 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MSUBw(x4, x3, ed, x2); // x4 = x2 mod ed (i.e. x2 - x3*ed) BFIz(xRAX, x3, 0, 16); BFIz(xRDX, x4, 0, 16); + SET_DFNONE(x2); + IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) + if(box64_dynarec_test) { + MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF)); + BICw(xFlags, xFlags, x1); + } break; } break; diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c index c3df1bf6..b6210534 100644 --- a/src/dynarec/arm64/dynarec_arm64_67.c +++ b/src/dynarec/arm64/dynarec_arm64_67.c @@ -1517,7 +1517,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 6: INST_NAME("DIV Ed"); SETFLAGS(X_ALL, SF_SET); - SET_DFNONE(x2); if(!rex.w) { GETED32(0); MOVw_REG(x3, xRAX); @@ -1551,12 +1550,17 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOVx_REG(xRAX, x2); } } + SET_DFNONE(x2); + IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) + if(box64_dynarec_test) { + MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF)); + BICw(xFlags, xFlags, x1); + } break; case 7: INST_NAME("IDIV Ed"); NOTEST(x1); SETFLAGS(X_ALL, SF_SET); - SET_DFNONE(x2); if(!rex.w) { GETSED32w(0); MOVw_REG(x3, xRAX); @@ -1588,6 +1592,12 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOVx_REG(xRAX, x2); } } + SET_DFNONE(x2); + IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) + if(box64_dynarec_test) { + MOV32w(x1, (1<<F_AF) | (1<<F_SF) | (1<<F_CF) | (1<<F_PF) | (1<<F_ZF) | (1<<F_OF)); + BICw(xFlags, xFlags, x1); + } break; } break; |