diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-02-12 11:04:46 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-02-12 11:04:46 +0100 |
| commit | c7ff0f658bc326c29dfbf79e9aac22250939e329 (patch) | |
| tree | 607b2f3c1d9869544502f07c5cbca10b623f2c91 /src | |
| parent | b8cc8594f6d9cbe4a47b8a98ba9878da803a7243 (diff) | |
| download | box64-c7ff0f658bc326c29dfbf79e9aac22250939e329.tar.gz box64-c7ff0f658bc326c29dfbf79e9aac22250939e329.zip | |
[ARM64_DYNAREC] More work on flag
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 191 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_0f.c | 13 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_64.c | 63 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_66.c | 70 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_660f.c | 35 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_67.c | 48 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_emit_shift.c | 607 | ||||
| -rw-r--r-- | src/emu/x64primop.c | 50 |
8 files changed, 472 insertions, 605 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index c9e8abb7..0b01123c 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -900,10 +900,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SMULH(x3, ed, x4); MULx(gd, ed, x4); SET_DFNONE(); - IFX(X_ZF | X_PF | X_AF | X_SF) { - MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x1); - } IFX(X_CF | X_OF) { CMPSx_REG_ASR(x3, gd, 63); CSETw(x1, cNE); @@ -924,10 +920,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin LSRx(x3, gd, 32); MOVw_REG(gd, gd); SET_DFNONE(); - IFX(X_ZF | X_PF | X_AF | X_SF) { - MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x1); - } IFX(X_CF | X_OF) { CMPSw_REG_ASR(x3, gd, 31); CSETw(x1, cNE); @@ -942,6 +934,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MULxw(gd, ed, x4); } } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, gd, rex.w?63:31); + BFIw(xFlags, x3, F_SF, 1); + } + IFX(X_PF) emit_pf(dyn, ninst, gd, x3); break; case 0x6A: INST_NAME("PUSH Ib"); @@ -964,10 +963,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SMULH(x3, ed, x4); MULx(gd, ed, x4); SET_DFNONE(); - IFX(X_ZF | X_PF | X_AF | X_SF) { - MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x1); - } IFX(X_CF | X_OF) { CMPSx_REG_ASR(x3, gd, 63); CSETw(x1, cNE); @@ -988,10 +983,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin LSRx(x3, gd, 32); MOVw_REG(gd, gd); SET_DFNONE(); - IFX(X_ZF | X_PF | X_AF | X_SF) { - MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x1); - } IFX(X_CF | X_OF) { CMPSw_REG_ASR(x3, gd, 31); CSETw(x1, cNE); @@ -1006,6 +997,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MULxw(gd, ed, x4); } } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, gd, rex.w?63:31); + BFIw(xFlags, x3, F_SF, 1); + } + IFX(X_PF) emit_pf(dyn, ninst, gd, x3); break; case 0x6C: case 0x6D: @@ -2786,8 +2784,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SETFLAGS(X_OF|X_CF, SF_SUBSET); if(BOX64DRENV(dynarec_safeflags)>1) MAYSETFLAGS(); + SET_DFNONE(); UFLAG_IF { - UFLAG_DF(x2, d_none); ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f CBZw_NEXT(x2); } @@ -2798,17 +2796,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ORRw_REG_LSL(ed, ed, ed, 8); LSRw_REG(ed, ed, x2); EBBACK; - UFLAG_IF { // calculate flags directly - IFX(X_OF) { - SUBw_U12(x3, x2, 7); - CBNZw_MARK(x3); - EORxw_REG_LSR(x3, ed, ed, 7); - BFIw(xFlags, x3, F_OF, 1); - MARK; - } - IFX(X_CF) { - BFIw(xFlags, ed, F_CF, 1); - } + IFX(X_OF) { + EORxw_REG_LSR(x3, ed, ed, 7); + BFIw(xFlags, x3, F_OF, 1); + } + IFX(X_CF) { + BFIw(xFlags, ed, F_CF, 1); } break; case 1: @@ -2816,28 +2809,27 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SETFLAGS(X_OF|X_CF, SF_SUBSET); if(BOX64DRENV(dynarec_safeflags)>1) MAYSETFLAGS(); + SET_DFNONE(); UFLAG_IF { - UFLAG_DF(x2, d_none); ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f CBZw_NEXT(x2); } ANDw_mask(x2, xRCX, 0, 0b00010); //mask=0x000000007 GETEB(x1, 0); + IFX2(X_OF, && !BOX64ENV(cputype)) { + EORw_REG_LSR(x4, ed, ed, 7); + BFIw(xFlags, x4, F_OF, 1); + } ORRw_REG_LSL(ed, ed, ed, 8); LSRw_REG(ed, ed, x2); EBBACK; - UFLAG_IF { // calculate flags directly - IFX(X_OF) { - SUBw_U12(x3, x2, 1); - CBNZw_MARK(x3); - LSRxw(x2, ed, 6); // x2 = d>>6 - EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>6) ^ ((d>>6)>>1)) - BFIw(xFlags, x2, F_OF, 1); - MARK; - } - IFX(X_CF) { - BFXILw(xFlags, ed, 7, 1); - } + IFX2(X_OF, && BOX64ENV(cputype)) { + LSRxw(x2, ed, 6); // x2 = d>>6 + EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>6) ^ ((d>>6)>>1)) + BFIw(xFlags, x2, F_OF, 1); + } + IFX(X_CF) { + BFXILw(xFlags, ed, 7, 1); } break; case 2: @@ -2846,7 +2838,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SETFLAGS(X_OF|X_CF, SF_SUBSET); if(BOX64DRENV(dynarec_safeflags)>1) MAYSETFLAGS(); - UFLAG_DF(x2, d_none); + SET_DFNONE(); ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f // get CL % 9 MOV32w(x3, 0x1c72); // 0x10000 / 9 + 1 (this is precise enough in the 0..31 range) @@ -2866,11 +2858,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin LSRw_REG(ed, ed, x2); EBBACK; IFX(X_OF) { - SUBw_U12(x3, x2, 8); - CBNZw_MARK(x3); - EORw_REG_LSR(x2, x5, ed, 7); - BFIw(xFlags, x2, F_OF, 1); - MARK; + EORw_REG_LSR(x2, x5, ed, 7); + BFIw(xFlags, x2, F_OF, 1); } IFX(X_CF) { BFXILw(xFlags, x5, 0, 1); @@ -2882,7 +2871,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SETFLAGS(X_OF|X_CF, SF_SUBSET); if(BOX64DRENV(dynarec_safeflags)>1) MAYSETFLAGS(); - UFLAG_DF(x2, d_none); + SET_DFNONE(); ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f // get CL % 9 MOV32w(x3, 0x1c72); // 0x10000 / 9 + 1 @@ -2894,16 +2883,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin GETEB(x1, 0); BFIw(ed, xFlags, 8, 1); // insert CF ORRw_REG_LSL(ed, ed, ed, 9); // insert rest of ed - IFX(X_OF|X_CF) { - SUBw_U12(x4, x2, 1); - } IFX(X_OF) { - CBNZw_MARK(x4); - EORw_REG_LSR(x5, xFlags, ed, 7); - BFIw(xFlags, x5, F_OF, 1); - MARK; + EORw_REG_LSR(x5, xFlags, ed, 7); + BFIw(xFlags, x5, F_OF, 1); } IFX(X_CF) { + SUBw_U12(x4, x2, 1); LSRw_REG(x5, ed, x4); BFIw(xFlags, x5, F_CF, 1); } @@ -2977,17 +2962,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SUBx_REG(x3, x4, x3); RORxw_REG(ed, ed, x3); WBACK; - UFLAG_IF { // calculate flags directly - IFX(X_OF) { - SUBw_U12(x3, x3, rex.w?63:31); - CBNZw_MARK(x3); - EORxw_REG_LSR(x1, ed, ed, rex.w?63:31); - BFIw(xFlags, x1, F_OF, 1); - MARK; - } - IFX(X_CF) { - BFIw(xFlags, ed, F_CF, 1); - } + IFX(X_OF) { + EORxw_REG_LSR(x3, ed, ed, rex.w?63:31); + BFIw(xFlags, x3, F_OF, 1); + } + IFX(X_CF) { + BFIw(xFlags, ed, F_CF, 1); } break; case 1: @@ -3000,28 +2980,25 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { ANDw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f } - UFLAG_IF { - UFLAG_DF(x2, d_none); - } + SET_DFNONE(); GETED(0); UFLAG_IF { if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);} CBZw_NEXT(x3); } + IFX2(X_OF, && !BOX64ENV(cputype)) { + EORxw_REG_LSR(x4, ed, ed, rex.w?63:31); + BFIw(xFlags, x4, F_OF, 1); + } RORxw_REG(ed, ed, x3); WBACK; - UFLAG_IF { // calculate flags directly - IFX(X_OF) { - SUBw_U12(x2, x3, 1); - CBNZw_MARK(x2); - LSRxw(x2, ed, rex.w?62:30); // x2 = d>>30 - EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>30) ^ ((d>>30)>>1)) - BFIw(xFlags, x2, F_OF, 1); - MARK; - } - IFX(X_CF) { - BFXILxw(xFlags, ed, rex.w?63:31, 1); - } + IFX2(X_OF, && BOX64ENV(cputype)) { + LSRxw(x2, ed, rex.w?62:30); // x2 = d>>30 + EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>30) ^ ((d>>30)>>1)) + BFIw(xFlags, x2, F_OF, 1); + } + IFX(X_CF) { + BFXILxw(xFlags, ed, rex.w?63:31, 1); } break; case 2: @@ -3037,8 +3014,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f } GETEDW(x4, x1, 0); - if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);} - CBZw_NEXT(x2); CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x4); WBACK; break; @@ -3055,8 +3030,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ANDw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f } GETEDW(x4, x1, 0); - if(!rex.w && !rex.is32bits && MODREG) {MOVw_REG(ed, ed);} - CBZw_NEXT(x2); CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4); WBACK; break; @@ -3543,13 +3516,14 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BFIw(xFlags, x3, F_OF, 1); } } - IFX(X_AF | X_PF | X_ZF | X_SF) - if (BOX64ENV(dynarec_test)) { - // to avoid noise during test - MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x3); - } - break; + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, xRAX, 15); + BFIw(xFlags, x3, F_SF, 1); + } + IFX(X_PF) emit_pf(dyn, ninst, xRAX, x3); + break; case 6: INST_NAME("DIV Eb"); SETFLAGS(X_ALL, SF_SET); @@ -3677,25 +3651,24 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOVw_REG(xRAX, xRDX); LSRx(xRDX, xRDX, 32); } - UFLAG_IF { - SET_DFNONE(); - IFX(X_CF|X_OF) { - CMPSxw_REG_ASR(xRDX, xRAX, rex.w?63:31); - CSETw(x3, cNE); - IFX(X_CF) { - BFIw(xFlags, x3, F_CF, 1); - } - IFX(X_OF) { - BFIw(xFlags, x3, F_OF, 1); - } + SET_DFNONE(); + IFX(X_CF|X_OF) { + CMPSxw_REG_ASR(xRDX, xRAX, rex.w?63:31); + CSETw(x3, cNE); + IFX(X_CF) { + BFIw(xFlags, x3, F_CF, 1); } - IFX(X_AF | X_PF | X_ZF | X_SF) - if (BOX64ENV(dynarec_test)) { - // to avoid noise during test - MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x3); - } + IFX(X_OF) { + BFIw(xFlags, x3, F_OF, 1); + } + } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, xRAX, rex.w?63:31); + BFIw(xFlags, x3, F_SF, 1); } + IFX(X_PF) emit_pf(dyn, ninst, xRAX, x3); break; case 6: INST_NAME("DIV Ed"); diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index 13e988a9..afa1f6d0 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -2041,12 +2041,13 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MULxw(gd, gd, ed); } } - IFX(X_AF | X_PF | X_ZF | X_SF) - if (BOX64ENV(dynarec_test)) { - // to avoid noise during test - MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x1); - } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, gd, rex.w?63:31); + BFIw(xFlags, x3, F_SF, 1); + } + IFX(X_PF) emit_pf(dyn, ninst, gd, x3); break; case 0xB1: diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c index 64421bcd..1bfc1fe3 100644 --- a/src/dynarec/arm64/dynarec_arm64_64.c +++ b/src/dynarec/arm64/dynarec_arm64_64.c @@ -319,12 +319,13 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MULxw(gd, gd, ed); } } - IFX(X_AF | X_PF | X_ZF | X_SF) - if (BOX64ENV(dynarec_test)) { - // to avoid noise during test - MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x1); - } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, gd, rex.w?63:31); + BFIw(xFlags, x3, F_SF, 1); + } + IFX(X_PF) emit_pf(dyn, ninst, gd, x3); break; default: DEFAULT; @@ -549,10 +550,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SMULH(x3, ed, x4); MULx(gd, ed, x4); SET_DFNONE(); - IFX(X_ZF | X_PF | X_AF | X_SF) { - MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x1); - } IFX(X_CF | X_OF) { ASRx(x4, gd, 63); CMPSx_REG(x3, x4); @@ -574,10 +571,6 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin LSRx(x3, gd, 32); MOVw_REG(gd, gd); SET_DFNONE(); - IFX(X_ZF | X_PF | X_AF | X_SF) { - MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x1); - } IFX(X_CF | X_OF) { ASRw(x4, gd, 31); CMPSw_REG(x3, x4); @@ -593,6 +586,13 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MULxw(gd, ed, x4); } } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, gd, rex.w?63:31); + BFIw(xFlags, x3, F_SF, 1); + } + IFX(X_PF) emit_pf(dyn, ninst, gd, x3); break; case 0x6C: @@ -1342,26 +1342,25 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOVw_REG(xRAX, xRDX); LSRx(xRDX, xRDX, 32); } - UFLAG_IF { - SET_DFNONE(); - IFX(X_CF|X_OF) { - ASRxw(x4, xRAX, rex.w?63:31); - CMPSxw_REG(xRDX, x4); - CSETw(x3, cNE); - IFX(X_CF) { - BFIw(xFlags, x3, F_CF, 1); - } - IFX(X_OF) { - BFIw(xFlags, x3, F_OF, 1); - } + SET_DFNONE(); + IFX(X_CF|X_OF) { + ASRxw(x4, xRAX, rex.w?63:31); + CMPSxw_REG(xRDX, x4); + CSETw(x3, cNE); + IFX(X_CF) { + BFIw(xFlags, x3, F_CF, 1); } - IFX(X_AF | X_PF | X_ZF | X_SF) - if (BOX64ENV(dynarec_test)) { - // to avoid noise during test - MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x3); - } + IFX(X_OF) { + BFIw(xFlags, x3, F_OF, 1); + } + } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, xRAX, rex.w?63:31); + BFIw(xFlags, x3, F_SF, 1); } + IFX(X_PF) emit_pf(dyn, ninst, xRAX, x3); break; case 6: INST_NAME("DIV Ed"); diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c index 73767538..0b110ce4 100644 --- a/src/dynarec/arm64/dynarec_arm64_66.c +++ b/src/dynarec/arm64/dynarec_arm64_66.c @@ -444,26 +444,25 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MULw(x2, x2, x1); gd=x2; GWBACK; - UFLAG_IF { - SET_DFNONE(); - IFX(X_CF|X_OF) { - ASRw(x1, x2, 16); - CMPSw_REG_ASR(x1, x2, 31); - CSETw(x3, cNE); - IFX(X_CF) { - BFIw(xFlags, x3, F_CF, 1); - } - IFX(X_OF) { - BFIw(xFlags, x3, F_OF, 1); - } + SET_DFNONE(); + IFX(X_CF|X_OF) { + ASRw(x1, x2, 16); + CMPSw_REG_ASR(x1, x2, 31); + CSETw(x3, cNE); + IFX(X_CF) { + BFIw(xFlags, x3, F_CF, 1); } - IFX(X_AF | X_PF | X_ZF | X_SF) - if (BOX64ENV(dynarec_test)) { - // to avoid noise during test - MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x3); - } + IFX(X_OF) { + BFIw(xFlags, x3, F_OF, 1); + } + } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, x2, 15); + BFIw(xFlags, x3, F_SF, 1); } + IFX(X_PF) emit_pf(dyn, ninst, x2, x3); break; case 0x6A: INST_NAME("PUSH Ib"); @@ -1422,26 +1421,25 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MULw(x1, x2, x1); BFIz(xRAX, x1, 0, 16); BFXILx(xRDX, x1, 16, 16); - UFLAG_IF { - SET_DFNONE(); - IFX(X_CF|X_OF) { - ASRw(x2, x1, 16); - CMPSw_REG_ASR(x2, x1, 31); - CSETw(x3, cNE); - IFX(X_CF) { - BFIw(xFlags, x3, F_CF, 1); - } - IFX(X_OF) { - BFIw(xFlags, x3, F_OF, 1); - } + SET_DFNONE(); + IFX(X_CF|X_OF) { + ASRw(x2, x1, 16); + CMPSw_REG_ASR(x2, x1, 31); + CSETw(x3, cNE); + IFX(X_CF) { + BFIw(xFlags, x3, F_CF, 1); } - IFX(X_AF | X_PF | X_ZF | X_SF) - if (BOX64ENV(dynarec_test)) { - // to avoid noise during test - MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x3); - } + IFX(X_OF) { + BFIw(xFlags, x3, F_OF, 1); + } + } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, xRAX, 15); + BFIw(xFlags, x3, F_SF, 1); } + IFX(X_PF) emit_pf(dyn, ninst, xRAX, x3); break; case 6: INST_NAME("DIV Ew"); diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index 412d2b62..2a30bc9c 100644 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -2494,26 +2494,25 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n GETSGW(x2); MULw(x2, x2, x1); GWBACK; - UFLAG_IF { - SET_DFNONE(); - IFX(X_CF|X_OF) { - ASRw(x1, x2, 16); - CMPSw_REG_ASR(x1, x2, 31); - CSETw(x3, cNE); - IFX(X_CF) { - BFIw(xFlags, x3, F_CF, 1); - } - IFX(X_OF) { - BFIw(xFlags, x3, F_OF, 1); - } + SET_DFNONE(); + IFX(X_CF|X_OF) { + ASRw(x1, x2, 16); + CMPSw_REG_ASR(x1, x2, 31); + CSETw(x3, cNE); + IFX(X_CF) { + BFIw(xFlags, x3, F_CF, 1); } - IFX(X_AF | X_PF | X_ZF | X_SF) - if (BOX64ENV(dynarec_test)) { - // to avoid noise during test - MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x3); - } + IFX(X_OF) { + BFIw(xFlags, x3, F_OF, 1); + } + } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, gd, 15); + BFIw(xFlags, x3, F_SF, 1); } + IFX(X_PF) emit_pf(dyn, ninst, gd, x3); break; case 0xB3: diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c index 9c255932..4473c491 100644 --- a/src/dynarec/arm64/dynarec_arm64_67.c +++ b/src/dynarec/arm64/dynarec_arm64_67.c @@ -929,10 +929,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SMULH(x3, ed, x4); MULx(gd, ed, x4); SET_DFNONE(); - IFX(X_ZF | X_PF | X_AF | X_SF) { - MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x1); - } IFX(X_CF | X_OF) { CMPSx_REG_ASR(x3, gd, 63); CSETw(x1, cNE); @@ -953,10 +949,6 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin LSRx(x3, gd, 32); MOVw_REG(gd, gd); SET_DFNONE(); - IFX(X_ZF | X_PF | X_AF | X_SF) { - MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x1); - } IFX(X_CF | X_OF) { CMPSw_REG_ASR(x3, gd, 31); CSETw(x1, cNE); @@ -971,6 +963,13 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MULxw(gd, ed, x4); } } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, gd, rex.w?63:31); + BFIw(xFlags, x3, F_SF, 1); + } + IFX(X_PF) emit_pf(dyn, ninst, gd, x3); break; case 0x70: @@ -1509,25 +1508,24 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOVw_REG(xRAX, xRDX); LSRx(xRDX, xRDX, 32); } - UFLAG_IF { - SET_DFNONE(); - IFX(X_CF|X_OF) { - CMPSxw_REG_ASR(xRDX, xRAX, rex.w?63:31); - CSETw(x3, cNE); - IFX(X_CF) { - BFIw(xFlags, x3, F_CF, 1); - } - IFX(X_OF) { - BFIw(xFlags, x3, F_OF, 1); - } + SET_DFNONE(); + IFX(X_CF|X_OF) { + CMPSxw_REG_ASR(xRDX, xRAX, rex.w?63:31); + CSETw(x3, cNE); + IFX(X_CF) { + BFIw(xFlags, x3, F_CF, 1); } - IFX(X_AF | X_PF | X_ZF | X_SF) - if (BOX64ENV(dynarec_test)) { - // to avoid noise during test - MOV32w(x3, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); - BICw(xFlags, xFlags, x3); - } + IFX(X_OF) { + BFIw(xFlags, x3, F_OF, 1); + } + } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_ZF) {BFCw(xFlags, F_ZF, 1);} + IFX(X_SF) { + LSRxw(x3, xRAX, rex.w?63:31); + BFIw(xFlags, x3, F_SF, 1); } + IFX(X_PF) emit_pf(dyn, ninst, xRAX, x3); break; case 6: INST_NAME("DIV Ed"); diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c index ebd138a1..6637ca51 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c @@ -35,32 +35,43 @@ void emit_shl32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3 } else { SET_DFNONE(); } - IFX(X_CF | X_OF) { - MOV32w(s4, rex.w?64:32); - SUBxw_REG(s4, s4, s2); - LSRxw_REG(s4, s1, s4); - BFIw(xFlags, s4, F_CF, 1); + if(BOX64ENV(cputype)) { + IFX(X_CF | X_OF) { + MOV32w(s4, rex.w?64:32); + SUBxw_REG(s4, s4, s2); + LSRxw_REG(s4, s1, s4); + BFIw(xFlags, s4, F_CF, 1); + } + } else { + IFX(X_OF) { + LSRxw(s4, s1, rex.w?62:30); + EORw_REG_LSR(s4, s4, s4, 1); + BFIw(xFlags, s4, F_OF, 1); + } + IFX(X_CF) { + MOV32w(s4, rex.w?64:32); + SUBxw_REG(s4, s4, s2); + LSRxw_REG(s4, s1, s4); + BFIw(xFlags, s4, F_CF, 1); + } } LSLxw_REG(s1, s1, s2); IFX(X_PEND) { STRxw_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_OF) { - LSRxw(s4, s1, (rex.w)?63:31); - EORxw_REG(s3, s4, xFlags); // CF is set if OF is asked - if(BOX64ENV(dynarec_test)) { - CMPSxw_U12(s2, 1); // if s2==1 - CSELw(s3, s3, wZR, cEQ); + if(BOX64ENV(cputype)) + IFX(X_OF) { + LSRxw(s4, s1, (rex.w)?63:31); + EORxw_REG(s3, s4, xFlags); // CF is set if OF is asked + BFIw(xFlags, s3, F_OF, 1); } - BFIw(xFlags, s3, F_OF, 1); - } int need_tst = 0; IFX(X_ZF) need_tst = 1; IFXNATIVE(X_SF, NF_SF) need_tst = 1; if(need_tst) TSTxw_REG(s1, s1); IFX(X_SF) { IFNATIVE(NF_SF) {} else { - IFX(X_OF) {} else {LSRxw(s4, s1, (rex.w)?63:31);} + IFX2(X_OF, && BOX64ENV(cputype)) {} else {LSRxw(s4, s1, (rex.w)?63:31);} BFIw(xFlags, s4, F_SF, 1); } } @@ -92,9 +103,21 @@ void emit_shl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i } else { SET_DFNONE(); } - IFX(X_CF|X_OF) { - LSRxw(s3, s1, (rex.w?64:32)-c); - BFIxw(xFlags, s3, F_CF, 1); + if(BOX64ENV(cputype)) { + IFX(X_CF|X_OF) { + LSRxw(s3, s1, (rex.w?64:32)-c); + BFIxw(xFlags, s3, F_CF, 1); + } + } else { + IFX(X_OF) { + LSRxw(s3, s1, rex.w?62:30); + EORw_REG_LSR(s3, s3, s3, 1); + BFIw(xFlags, s3, F_OF, 1); + } + IFX(X_CF) { + LSRxw(s3, s1, (rex.w?64:32)-c); + BFIxw(xFlags, s3, F_CF, 1); + } } LSLxw(s1, s1, c); @@ -117,19 +140,15 @@ void emit_shl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i BFIw(xFlags, s4, F_SF, 1); } } - IFX(X_OF) { - if(c==1 || BOX64DRENV(dynarec_safeflags)>1) { + if(BOX64ENV(cputype)) + IFX(X_OF) { IFX(X_SF) {} else {LSRxw(s4, s1, (rex.w)?63:31);} EORxw_REG(s4, s4, xFlags); // CF is set if OF is asked BFIw(xFlags, s4, F_OF, 1); - } else { - BFCw(xFlags, F_OF, 1); } + IFX(X_AF) { + BFCw(xFlags, F_AF, 1); } - if (BOX64ENV(dynarec_test)) - IFX(X_AF) { - BFCw(xFlags, F_AF, 1); - } IFX(X_PF) { if(c>7) { // the 0xff area will be 0, so PF is known @@ -161,10 +180,6 @@ void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3 } IFX(X_OF) { LSRxw(s4, s1, rex.w?63:31); - if(BOX64ENV(dynarec_test)) { - CMPSxw_U12(s2, 1); // if s2==1 - CSELw(s4, s4, xZR, cEQ); // clear bit if c!=1 - } BFIw(xFlags, s4, F_OF, 1); } LSRxw_REG(s1, s1, s2); @@ -187,10 +202,9 @@ void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3 BFIx(xFlags, s4, F_SF, 1); } } - if (BOX64ENV(dynarec_test)) - IFX(X_AF) { - BFCw(xFlags, F_AF, 1); - } + IFX(X_AF) { + BFCw(xFlags, F_AF, 1); + } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -217,7 +231,7 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i BFIw(xFlags, s3, 0, 1); } } - IFX2(X_OF, && (c==1 || BOX64DRENV(dynarec_safeflags)>1)) { + IFX(X_OF) { LSRxw(s4, s1, rex.w?63:31); BFIw(xFlags, s4, F_OF, 1); } @@ -241,13 +255,8 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i BFCw(xFlags, F_SF, 1); } } - if (BOX64ENV(dynarec_test)) { - IFX(X_AF) { - BFCw(xFlags, F_AF, 1); - } - IFX(X_OF) if(c>1) { - BFCw(xFlags, F_OF, 1); - } + IFX(X_AF) { + BFCw(xFlags, F_AF, 1); } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); @@ -296,10 +305,9 @@ void emit_sar32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3 BFIx(xFlags, s4, F_SF, 1); } } - if (BOX64ENV(dynarec_test)) - IFX(X_AF) { - BFCw(xFlags, F_AF, 1); - } + IFX(X_AF) { + BFCw(xFlags, F_AF, 1); + } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -342,14 +350,12 @@ void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i BFIx(xFlags, s4, F_SF, 1); } } - IFX(X_OF) - if (c == 1 || BOX64ENV(dynarec_test) || BOX64DRENV(dynarec_safeflags)>1) { - BFCw(xFlags, F_OF, 1); - } - if (BOX64ENV(dynarec_test)) - IFX(X_AF) { - BFCw(xFlags, F_AF, 1); - } + IFX(X_OF) { + BFCw(xFlags, F_OF, 1); + } + IFX(X_AF) { + BFCw(xFlags, F_AF, 1); + } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -369,30 +375,40 @@ void emit_shl8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) } else { SET_DFNONE(); } - IFX(X_CF | X_OF) { - MOV32w(s4, 8); - SUBw_REG(s4, s4, s2); - LSRw_REG(s4, s1, s4); - BFIw(xFlags, s4, F_CF, 1); + if(BOX64ENV(cputype)) { + IFX(X_CF | X_OF) { + MOV32w(s4, 8); + SUBw_REG(s4, s4, s2); + LSRw_REG(s4, s1, s4); + BFIw(xFlags, s4, F_CF, 1); + } + } else { + IFX(X_OF) { + LSRw(s4, s1, 6); + EORw_REG_LSR(s4, s4, s4, 1); + BFIw(xFlags, s4, F_OF, 1); + } + IFX(X_CF) { + MOV32w(s4, 8); + SUBw_REG(s4, s4, s2); + LSRw_REG(s4, s1, s4); + BFIw(xFlags, s4, F_CF, 1); + } } LSLw_REG(s1, s1, s2); IFX(X_PEND) { STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_OF) { - LSRw(s3, s1, 7); - EORw_REG(s4, s3, xFlags); // CF is set if OF is asked - if(BOX64ENV(dynarec_test)) { - CMPSw_U12(s2, 1); // if s2==1 - CSELw(s4, s4, wZR, cEQ); + if(BOX64ENV(cputype)) + IFX(X_OF) { + LSRw(s3, s1, 7); + EORw_REG(s4, s3, xFlags); // CF is set if OF is asked + BFIw(xFlags, s4, F_OF, 1); } - BFIw(xFlags, s4, F_OF, 1); - } COMP_ZFSF(s1, 8) - if (BOX64ENV(dynarec_test)) - IFX(X_AF) { - BFCw(xFlags, F_AF, 1); - } + IFX(X_AF) { + BFCw(xFlags, F_AF, 1); + } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -412,8 +428,19 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s SET_DFNONE(); } if(c<8) { - IFX(X_CF|X_OF) { - BFXILw(xFlags, s1, 8-c, 1); + if(BOX64ENV(cputype)) { + IFX(X_CF|X_OF) { + BFXILw(xFlags, s1, 8-c, 1); + } + } else { + IFX(X_OF) { + LSRw(s4, s1, 6); + EORw_REG_LSR(s4, s4, s4, 1); + BFIw(xFlags, s4, F_OF, 1); + } + IFX(X_CF) { + BFXILw(xFlags, s1, 8-c, 1); + } } LSLw(s1, s1, c); @@ -421,19 +448,15 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); } COMP_ZFSF(s1, 8) - IFX(X_OF) { - if(c==1 || BOX64DRENV(dynarec_safeflags)>1) { + if(BOX64ENV(cputype)) + IFX(X_OF) { IFX2(X_SF, && !arm64_flagm) {} else {LSRw(s3, s1, 7);} //use COMP_ZFSF operation EORw_REG(s4, s3, xFlags); // CF is set if OF is asked BFIw(xFlags, s4, F_OF, 1); - } else { - BFCw(xFlags, F_OF, 1); } + IFX (X_AF) { + BFCw(xFlags, F_AF, 1); } - if (BOX64ENV(dynarec_test)) - IFX (X_AF) { - BFCw(xFlags, F_AF, 1); - } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -451,15 +474,14 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s IFNATIVE(NF_CF) {GEN_INVERTED_CARRY();} else {BFCw(xFlags, F_CF, 1);} } IFX(X_OF) { - BFCw(xFlags, F_OF, 1); + IFNATIVE(NF_VF) {} else BFCw(xFlags, F_OF, 1); } IFX(X_SF) { IFNATIVE(NF_SF) {} else BFCw(xFlags, F_SF, 1); } - if (BOX64ENV(dynarec_test)) - IFX (X_AF) { - BFCw(xFlags, F_AF, 1); - } + IFX (X_AF) { + BFCw(xFlags, F_AF, 1); + } IFX(X_ZF) { IFNATIVE(NF_EQ) {} else { ORRw_mask(xFlags, xFlags, 26, 0); //1<<F_ZF @@ -492,10 +514,6 @@ void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) } IFX(X_OF) { LSRw(s4, s1, 7); - if(BOX64ENV(dynarec_test)) { - CMPSw_U12(s2, 1); // if s2==1 - CSELw(s4, s4, xZR, cEQ); - } BFIw(xFlags, s4, F_OF, 1); } LSRw_REG(s1, s1, s2); @@ -503,10 +521,9 @@ void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); } COMP_ZFSF(s1, 8) - if (BOX64ENV(dynarec_test)) - IFX(X_AF) { - BFCw(xFlags, F_AF, 1); - } + IFX(X_AF) { + BFCw(xFlags, F_AF, 1); + } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -533,22 +550,17 @@ void emit_shr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s } } IFX(X_OF) { - if(c==1 || BOX64DRENV(dynarec_safeflags)>1) { - LSRw(s4, s1, 7); - BFIw(xFlags, s4, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); - } + LSRw(s4, s1, 7); + BFIw(xFlags, s4, F_OF, 1); } LSRw(s1, s1, c); IFX(X_PEND) { STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); } COMP_ZFSF(s1, 8) - if (BOX64ENV(dynarec_test)) - IFX(X_AF) { - BFCw(xFlags, F_AF, 1); - } + IFX(X_AF) { + BFCw(xFlags, F_AF, 1); + } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -575,9 +587,7 @@ void emit_sar8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) } COMP_ZFSF(s1, 8) IFX(X_OF) { - //SUBw_U12(s4, s2, 1); - //CBNZw(s4, 4+4); - BFCw(xFlags, F_OF, 1); + BFCw(xFlags, F_OF, 1); } if (BOX64ENV(dynarec_test)) IFX(X_AF) { @@ -609,10 +619,9 @@ void emit_sar8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s } if(c<8) { COMP_ZFSF(s1, 8) - IFX(X_OF) - if ((c == 1) || BOX64ENV(dynarec_test) || BOX64DRENV(dynarec_safeflags)>1) { - BFCw(xFlags, F_OF, 1); - } + IFX(X_OF) { + BFCw(xFlags, F_OF, 1); + } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -625,7 +634,7 @@ void emit_sar8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s EORw_mask(s3, s3, 0, 0); //1 BFIw(xFlags, s3, F_ZF, 1); } - IFX(X_OF){if(BOX64ENV(dynarec_test) || BOX64DRENV(dynarec_safeflags)>1) BFCw(xFlags, F_OF, 1);} + IFX(X_OF){BFCw(xFlags, F_OF, 1);} IFX(X_PF) { ORRw_mask(xFlags, xFlags, 30, 0); //1<<F_PF } @@ -647,30 +656,40 @@ void emit_shl16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) } else { SET_DFNONE(); } - IFX(X_CF | X_OF) { - MOV32w(s4, 16); - SUBw_REG(s4, s4, s2); - LSRw_REG(s4, s1, s4); - BFIw(xFlags, s4, F_CF, 1); + if(BOX64ENV(cputype)) { + IFX(X_CF | X_OF) { + MOV32w(s4, 16); + SUBw_REG(s4, s4, s2); + LSRw_REG(s4, s1, s4); + BFIw(xFlags, s4, F_CF, 1); + } + } else { + IFX(F_OF) { + LSRw(s4, s1, 14); + EORw_REG_LSR(s4, s4, s4, 1); + BFIw(xFlags, s4, F_OF, 1); + } + IFX(X_CF) { + MOV32w(s4, 16); + SUBw_REG(s4, s4, s2); + LSRw_REG(s4, s1, s4); + BFIw(xFlags, s4, F_CF, 1); + } } LSLw_REG(s1, s1, s2); IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_OF) { - LSRw(s3, s1, 15); - EORw_REG(s4, s3, xFlags); // CF is set if OF is asked - if(BOX64ENV(dynarec_test)) { - CMPSw_U12(s2, 1); // if s2==1 - CSELw(s4, s4, wZR, cEQ); + if(BOX64ENV(cputype)) + IFX(X_OF) { + LSRw(s3, s1, 15); + EORw_REG(s4, s3, xFlags); // CF is set if OF is asked + BFIw(xFlags, s4, F_OF, 1); } - BFIw(xFlags, s4, F_OF, 1); - } COMP_ZFSF(s1, 16) - if (BOX64ENV(dynarec_test)) - IFX(X_AF) { - BFCw(xFlags, F_AF, 1); - } + IFX(X_AF) { + BFCw(xFlags, F_AF, 1); + } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -689,9 +708,21 @@ void emit_shl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int SET_DFNONE(); } if(c<16) { - IFX(X_CF|X_OF) { - LSRw(s3, s1, 16-c); - BFIw(xFlags, s3, F_CF, 1); + if(BOX64ENV(cputype)) { + IFX(X_CF|X_OF) { + LSRw(s3, s1, 16-c); + BFIw(xFlags, s3, F_CF, 1); + } + } else { + IFX(F_OF) { + LSRw(s4, s1, 14); + EORw_REG_LSR(s4, s4, s4, 1); + BFIw(xFlags, s4, F_OF, 1); + } + IFX(X_CF) { + LSRw(s3, s1, 16-c); + BFIw(xFlags, s3, F_CF, 1); + } } LSLw(s1, s1, c); @@ -699,19 +730,15 @@ void emit_shl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } COMP_ZFSF(s1, 16) - IFX(X_OF) { - if(c==1 || BOX64DRENV(dynarec_safeflags)>1) { + if(BOX64ENV(cputype)) + IFX(X_OF) { IFX2(X_SF, && !arm64_flagm) {} else {LSRw(s3, s1, 15);} // use COMP_ZFSF operation EORw_REG(s4, s3, xFlags); // CF is set if OF is asked BFIw(xFlags, s4, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); } + IFX (X_AF) { + BFCw(xFlags, F_AF, 1); } - if (BOX64ENV(dynarec_test)) - IFX (X_AF) { - BFCw(xFlags, F_AF, 1); - } IFX(X_PF) { if(c>7) { // the 0xff area will be 0, so PF is known @@ -738,10 +765,9 @@ void emit_shl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int IFX(X_SF) { IFNATIVE(NF_SF) {} else BFCw(xFlags, F_SF, 1); } - if (BOX64ENV(dynarec_test)) - IFX (X_AF) { - BFCw(xFlags, F_AF, 1); - } + IFX (X_AF) { + BFCw(xFlags, F_AF, 1); + } IFX(X_ZF) { IFNATIVE(NF_EQ) {} else { ORRw_mask(xFlags, xFlags, 26, 0); //1<<F_ZF @@ -770,10 +796,6 @@ void emit_shr16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) } IFX(X_OF) { LSRw(s4, s1, 15); - if(BOX64DRENV(dynarec_test)) { - CMPSw_U12(s2, 1); // if s2==1 - CSELw(s4, s4, xZR, cEQ); - } BFIw(xFlags, s4, F_OF, 1); } LSRw_REG(s1, s1, s2); @@ -812,22 +834,17 @@ void emit_shr16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int } } IFX(X_OF) { - if(c==1 || BOX64DRENV(dynarec_safeflags)>1) { - LSRw(s4, s1, 15); - BFIw(xFlags, s4, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); - } + LSRw(s4, s1, 15); + BFIw(xFlags, s4, F_OF, 1); } LSRw(s1, s1, c); IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } COMP_ZFSF(s1, 16) - if (BOX64ENV(dynarec_test)) - IFX(X_AF) { - BFCw(xFlags, F_AF, 1); - } + IFX(X_AF) { + BFCw(xFlags, F_AF, 1); + } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -853,15 +870,12 @@ void emit_sar16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } IFX(X_OF) { - //SUBw_U12(s4, s2, 1); - //CBNZw(s4, 4+4); - BFCw(xFlags, F_OF, 1); + BFCw(xFlags, F_OF, 1); } COMP_ZFSF(s1, 16) - if (BOX64ENV(dynarec_test)) - IFX(X_AF) { - BFCw(xFlags, F_AF, 1); - } + IFX(X_AF) { + BFCw(xFlags, F_AF, 1); + } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -888,14 +902,12 @@ void emit_sar16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } COMP_ZFSF(s1, 16) - IFX(X_OF) - if ((c == 1) || BOX64ENV(dynarec_test) || BOX64DRENV(dynarec_safeflags)>1) { - BFCw(xFlags, F_OF, 1); - } - if (BOX64ENV(dynarec_test)) - IFX(X_AF) { - BFCw(xFlags, F_AF, 1); - } + IFX(X_OF) { + BFCw(xFlags, F_OF, 1); + } + IFX(X_AF) { + BFCw(xFlags, F_AF, 1); + } IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -914,12 +926,8 @@ void emit_rol32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i BFIw(xFlags, s1, F_CF, 1); } IFX(X_OF) { - if(c==1) { - EORxw_REG_LSR(s3, s1, s1, rex.w?63:31); - BFIw(xFlags, s3, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); - } + EORxw_REG_LSR(s3, s1, s1, rex.w?63:31); + BFIw(xFlags, s3, F_OF, 1); } } @@ -932,19 +940,22 @@ void emit_ror32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i SET_DFNONE(); + if(!BOX64ENV(cputype)) + IFX(X_OF) { + EORxw_REG_LSR(s3, s1, s1, rex.w?63:31); + BFIw(xFlags, s3, F_OF, 1); + } + RORxw(s1, s1, c); IFX(X_CF) { BFXILxw(xFlags, s1, rex.w?63:31, 1); } - IFX(X_OF) { - if(c==1) { + if(BOX64ENV(cputype)) + IFX(X_OF) { LSRxw(s3, s1, rex.w?62:30); EORxw_REG_LSR(s3, s3, s3, 1); BFIw(xFlags, s3, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); } - } } // emit ROL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch @@ -965,12 +976,8 @@ void emit_rol8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s BFIw(xFlags, s1, F_CF, 1); } IFX(X_OF) { - if(c==1) { - EORw_REG_LSR(s3, s1, s1, 7); - BFIw(xFlags, s3, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); - } + EORw_REG_LSR(s3, s1, s1, 7); + BFIw(xFlags, s3, F_OF, 1); } } @@ -983,6 +990,12 @@ void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s SET_DFNONE(); + if(!BOX64ENV(cputype)) + IFX(X_OF) { + EORw_REG_LSR(s3, s1, s1, 7); + BFIw(xFlags, s3, F_OF, 1); + } + if(c&7) { ORRw_REG_LSL(s1, s1, s1, 8); LSRw(s1, s1, c&7); @@ -990,15 +1003,12 @@ void emit_ror8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s IFX(X_CF) { BFXILw(xFlags, s1, 7, 1); } - IFX(X_OF) { - if(c==1) { + if(BOX64ENV(cputype)) + IFX(X_OF) { LSRw(s3, s1, 6); EORw_REG_LSR(s3, s3, s3, 1); BFIw(xFlags, s3, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); } - } } // emit ROL16 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch @@ -1019,12 +1029,8 @@ void emit_rol16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int BFIw(xFlags, s1, F_CF, 1); } IFX(X_OF) { - if(c==1) { - EORw_REG_LSR(s3, s1, s1, 15); - BFIw(xFlags, s3, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); - } + EORw_REG_LSR(s3, s1, s1, 15); + BFIw(xFlags, s3, F_OF, 1); } } @@ -1037,6 +1043,11 @@ void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int SET_DFNONE(); + if(!BOX64ENV(cputype)) + IFX(X_OF) { + EORw_REG_LSR(s3, s1, s1, 15); + BFIw(xFlags, s3, F_OF, 1); + } if(c&15) { ORRw_REG_LSL(s1, s1, s1, 16); LSRw(s1, s1, c&15); @@ -1044,15 +1055,12 @@ void emit_ror16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int IFX(X_CF) { BFXILw(xFlags, s1, 15, 1); } - IFX(X_OF) { - if(c==1) { + if(BOX64ENV(cputype)) + IFX(X_OF) { LSRw(s3, s1, 14); EORw_REG_LSR(s3, s3, s3, 1); BFIw(xFlags, s3, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); } - } } // emit RCL8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch @@ -1074,18 +1082,12 @@ void emit_rcl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s } ORRw_REG_LSL(s1, s1, s1, 9); // insert s1 again LSRw_IMM(s1, s1, 9-c); // do the rcl - IFX(X_OF|X_CF) { - IFX(X_CF) { - BFIw(xFlags, s3, F_CF, 1); - } - IFX(X_OF) { - if(c==1) { - EORw_REG_LSR(s3, s3, s1, 7); - BFIw(xFlags, s3, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); - } - } + IFX(X_CF) { + BFIw(xFlags, s3, F_CF, 1); + } + IFX(X_OF) { + EORw_REG_LSR(s3, s3, s1, 7); + BFIw(xFlags, s3, F_OF, 1); } } @@ -1099,12 +1101,8 @@ void emit_rcr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s c%=9; IFX(X_OF) { - if(c==1) { - EORw_REG_LSR(s3, xFlags, s1, 7); - BFIw(xFlags, s3, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); - } + EORw_REG_LSR(s3, xFlags, s1, 7); + BFIw(xFlags, s3, F_OF, 1); } BFIw(s1, xFlags, 8, 1); // insert cf IFX(X_CF) { @@ -1139,12 +1137,8 @@ void emit_rcl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int BFIw(xFlags, s3, F_CF, 1); } IFX(X_OF) { - if(c==1) { - EORw_REG_LSR(s3, s3, s1, 15); - BFIw(xFlags, s3, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); - } + EORw_REG_LSR(s3, s3, s1, 15); + BFIw(xFlags, s3, F_OF, 1); } } @@ -1159,12 +1153,8 @@ void emit_rcr16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int c%=17; BFIw(s1, xFlags, 16, 1); // insert cf IFX(X_OF) { - if(c==1) { - EORw_REG_LSR(s3, xFlags, s1, 15); - BFIw(xFlags, s3, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); - } + EORw_REG_LSR(s3, xFlags, s1, 15); + BFIw(xFlags, s3, F_OF, 1); } IFX(X_CF) { BFXILx(xFlags, s1, c-1, 1); @@ -1199,12 +1189,8 @@ void emit_rcl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i BFIw(xFlags, s3, F_CF, 1); } IFX(X_OF) { - if(c==1) { - EORxw_REG_LSR(s3, s3, s1, rex.w?63:31); - BFIw(xFlags, s3, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); - } + EORxw_REG_LSR(s3, s3, s1, rex.w?63:31); + BFIw(xFlags, s3, F_OF, 1); } } // emit RCR32/RCR64 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch @@ -1217,12 +1203,8 @@ void emit_rcr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i SET_DFNONE(); IFX(X_OF) { - if(c==1) { - EORxw_REG_LSR(s3, xFlags, s1, rex.w?63:31); - BFIw(xFlags, s3, F_OF, 1); - } else if (BOX64ENV(dynarec_test)) { - BFCw(xFlags, F_OF, 1); - } + EORxw_REG_LSR(s3, xFlags, s1, rex.w?63:31); + BFIw(xFlags, s3, F_OF, 1); } IFX(X_CF) { BFXILxw(s3, s1, c-1, 1); @@ -1255,19 +1237,15 @@ void emit_shrd32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint BFXILxw(xFlags, s1, c-1, 1); // set CF } IFX(X_OF) { - if(c==1) { - LSRxw(s4, s1, rex.w?63:31); - } + LSRxw(s4, s1, rex.w?63:31); } EXTRxw(s1, s2, s1, c); IFX(X_PEND) { STRxw_U12(s1, xEmu, offsetof(x64emu_t, res)); } IFX(X_OF) { - if(c==1) { - EORx_REG_LSR(s3, s4, s1, rex.w?63:31); // OF is set if sign changed - BFIw(xFlags, s3, F_OF, 1); - } + EORx_REG_LSR(s3, s4, s1, rex.w?63:31); // OF is set if sign changed + BFIw(xFlags, s3, F_OF, 1); } int need_tst = 0; IFX(X_ZF) need_tst = 1; @@ -1285,10 +1263,7 @@ void emit_shrd32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint BFIx(xFlags, s4, F_SF, 1); } } - if (BOX64ENV(dynarec_test)) { - IFX(X_AF) {BFCw(xFlags, F_AF, 1);} - IFX2(X_OF, && (c>1)) {BFCw(xFlags, F_OF, 1);} - } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -1307,10 +1282,8 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint IFX(X_CF) { BFXILx(xFlags, s1, (rex.w?64:32)-c, 1); } - if(c==1) { - IFX(X_OF) { - LSRxw(s4, s1, rex.w?63:31); - } + IFX(X_OF) { + LSRxw(s4, s1, rex.w?63:31); } EXTRxw(s1, s1, s2, (rex.w?64:32)-c); @@ -1318,7 +1291,7 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint STRxw_U12(s1, xEmu, offsetof(x64emu_t, res)); } IFX(X_OF) { - if(c==1) { + if((c==1) || (BOX64DRENV(dynarec_safeflags)>1)) { EORx_REG_LSR(s3, s4, s1, rex.w?63:31); // OF is set if sign changed BFIw(xFlags, s3, F_OF, 1); } @@ -1339,10 +1312,7 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, uint BFIx(xFlags, s4, F_SF, 1); } } - if (BOX64ENV(dynarec_test)) { - IFX(X_AF) {BFCw(xFlags, F_AF, 1);} - IFX2(X_OF, && (c>1)) {BFCw(xFlags, F_OF, 1);} - } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -1380,17 +1350,8 @@ void emit_shrd32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s STRxw_U12(s1, xEmu, offsetof(x64emu_t, res)); } IFX(X_OF) { - if (BOX64ENV(dynarec_test)) { - CMPSw_U12(s5, 1); - EORxw_REG_LSR(s3, s4, s1, rex.w?63:31); // OF is set if sign changed - CSELw(s3, s3, xZR, cEQ); - BFIw(xFlags, s3, F_OF, 1); - } else { - // CMPSw_U12(s5, 1); - EORxw_REG_LSR(s3, s4, s1, rex.w?63:31); // OF is set if sign changed - // CSELw(s3, s3, xZR, cEQ); - BFIw(xFlags, s3, F_OF, 1); - } + EORxw_REG_LSR(s3, s4, s1, rex.w?63:31); // OF is set if sign changed + BFIw(xFlags, s3, F_OF, 1); } int need_tst = 0; IFX(X_ZF) need_tst = 1; @@ -1408,9 +1369,7 @@ void emit_shrd32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s BFIx(xFlags, s4, F_SF, 1); } } - if (BOX64ENV(dynarec_test)) { - IFX(X_AF) {BFCw(xFlags, F_AF, 1);} - } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -1446,17 +1405,8 @@ void emit_shld32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s STRxw_U12(s1, xEmu, offsetof(x64emu_t, res)); } IFX(X_OF) { - if (BOX64ENV(dynarec_test)) { - CMPSw_U12(s5, 1); - EORx_REG_LSR(s3, s4, s1, rex.w?63:31); // OF is set if sign changed - CSELw(s3, s3, xZR, cEQ); - BFIw(xFlags, s3, F_OF, 1); - } else { - // CMPSw_U12(s5, 1); - EORx_REG_LSR(s3, s4, s1, rex.w?63:31); // OF is set if sign changed - // CSELw(s3, s3, xZR, cEQ); - BFIw(xFlags, s3, F_OF, 1); - } + EORx_REG_LSR(s3, s4, s1, rex.w?63:31); // OF is set if sign changed + BFIw(xFlags, s3, F_OF, 1); } int need_tst = 0; IFX(X_ZF) need_tst = 1; @@ -1474,9 +1424,7 @@ void emit_shld32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s BFIx(xFlags, s4, F_SF, 1); } } - if (BOX64ENV(dynarec_test)) { - IFX(X_AF) {BFCw(xFlags, F_AF, 1);} - } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -1505,9 +1453,7 @@ void emit_shrd16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int BFXILw(xFlags, s1, c-1, 1); // set CF } IFX(X_OF) { - if(c==1) { - LSRw(s4, s1, 15); - } + LSRw(s4, s1, 15); } RORw(s1, s1, c); IFX(X_PEND) { @@ -1515,15 +1461,10 @@ void emit_shrd16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int } COMP_ZFSF(s1, 16) IFX(X_OF) { - if(c==1) { - EORx_REG_LSR(s3, s4, s1, 15); // OF is set if sign changed - BFIw(xFlags, s3, F_OF, 1); - } - } - if (BOX64ENV(dynarec_test)) { - IFX(X_AF) {BFCw(xFlags, F_AF, 1);} - IFX2(X_OF, && (c>1)) {BFCw(xFlags, F_OF, 1);} + EORx_REG_LSR(s3, s4, s1, 15); // OF is set if sign changed + BFIw(xFlags, s3, F_OF, 1); } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -1554,19 +1495,11 @@ void emit_shrd16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s5, int s3, STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } IFX(X_OF) { - if (BOX64ENV(dynarec_test)) { - CMPSw_U12(s5, 1); - EORw_REG_LSR(s3, s4, s1, 15); // OF is set if sign changed - CSELw(s3, s3, xZR, cEQ); - BFIw(xFlags, s3, F_OF, 1); - } else { - // CMPSw_U12(s5, 1); - EORw_REG_LSR(s3, s4, s1, 15); // OF is set if sign changed - // CSELw(s3, s3, xZR, cEQ); - BFIw(xFlags, s3, F_OF, 1); - } + EORw_REG_LSR(s3, s4, s1, 15); // OF is set if sign changed + BFIw(xFlags, s3, F_OF, 1); } COMP_ZFSF(s1, 16) + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -1583,17 +1516,8 @@ void emit_shld16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int } else { SET_DFNONE(); } - if(c==0) { - IFX(X_OF) { - BFCw(xFlags, F_OF, 1); - } - IFX(X_PEND) { - STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); - } - return; - } BFIw(s1, s2, 16, 16); // create concat first - IFX(X_CF) { + IFX2(X_CF, && c) { if(c<16) LSRw(s3, s1, 16-c); else @@ -1603,22 +1527,18 @@ void emit_shld16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int IFX(X_OF) { LSRw(s4, s1, 15); } - RORw(s1, s1, 32-c); + if(c) + RORw(s1, s1, 32-c); IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } COMP_ZFSF(s1, 16) IFX(X_OF) { - if(c==1) { - EORw_REG_LSR(s3, s4, s1, 15); // OF is set if sign changed - BFIw(xFlags, s3, F_OF, 1); - } - } - if (BOX64ENV(dynarec_test)) { - IFX(X_AF) {BFCw(xFlags, F_AF, 1);} - IFX2(X_OF, && (c>1)) {BFCw(xFlags, F_OF, 1);} + EORw_REG_LSR(s3, s4, s1, 15); // OF is set if sign changed + BFIw(xFlags, s3, F_OF, 1); } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } @@ -1652,22 +1572,11 @@ void emit_shld16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s5, int s3, STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } IFX(X_OF) { - if (BOX64ENV(dynarec_test)) { - CMPSw_U12(s5, 1); - EORw_REG_LSR(s3, s4, s1, 15); // OF is set if sign changed - CSELw(s3, s3, xZR, cEQ); + EORw_REG_LSR(s3, s4, s1, 15); // OF is set if sign changed BFIw(xFlags, s3, F_OF, 1); - } else { - // CMPSw_U12(s5, 1); - EORw_REG_LSR(s3, s4, s1, 15); // OF is set if sign changed - // CSELw(s3, s3, xZR, cEQ); - BFIw(xFlags, s3, F_OF, 1); - } } COMP_ZFSF(s1, 16) - if (BOX64ENV(dynarec_test)) { - IFX(X_AF) {BFCw(xFlags, F_AF, 1);} - } + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} IFX(X_PF) { emit_pf(dyn, ninst, s1, s4); } diff --git a/src/emu/x64primop.c b/src/emu/x64primop.c index 85abdd07..e1961434 100644 --- a/src/emu/x64primop.c +++ b/src/emu/x64primop.c @@ -521,8 +521,7 @@ uint8_t rcl8(x64emu_t *emu, uint8_t d, uint8_t s) CONDITIONAL_SET_FLAG(cf, F_CF); /* OVERFLOW is set *IFF* cnt==1, then it is the xor of CF and the most significant bit. Blecck. */ - if(cnt == 1) - CONDITIONAL_SET_FLAG((cf ^ (res >> 7)) & 0x1, F_OF); + CONDITIONAL_SET_FLAG((cf ^ (res >> 7)) & 0x1, F_OF); } return (uint8_t)res; @@ -544,8 +543,7 @@ uint16_t rcl16(x64emu_t *emu, uint16_t d, uint8_t s) res |= 1 << (cnt - 1); } CONDITIONAL_SET_FLAG(cf, F_CF); - if(cnt == 1) - CONDITIONAL_SET_FLAG((cf ^ (res >> 15)) & 0x1, F_OF); + CONDITIONAL_SET_FLAG((cf ^ (res >> 15)) & 0x1, F_OF); } return (uint16_t)res; } @@ -566,10 +564,7 @@ uint32_t rcl32(x64emu_t *emu, uint32_t d, uint8_t s) res |= 1 << (cnt - 1); } CONDITIONAL_SET_FLAG(cf, F_CF); - if(cnt == 1) - CONDITIONAL_SET_FLAG((cf ^ (res >> 31)) & 0x1, F_OF); - else - CLEAR_FLAG(F_OF); // UND, but clear for dynarec_test + CONDITIONAL_SET_FLAG((cf ^ (res >> 31)) & 0x1, F_OF); } return res; } @@ -590,10 +585,7 @@ uint64_t rcl64(x64emu_t *emu, uint64_t d, uint8_t s) res |= 1LL << (cnt - 1); } CONDITIONAL_SET_FLAG(cf, F_CF); - if(cnt == 1) - CONDITIONAL_SET_FLAG((cf ^ (res >> 63)) & 0x1, F_OF); - else - CLEAR_FLAG(F_OF); // UND, but clear for dynarec_test + CONDITIONAL_SET_FLAG((cf ^ (res >> 63)) & 0x1, F_OF); } return res; } @@ -634,7 +626,13 @@ uint8_t rcr8(x64emu_t *emu, uint8_t d, uint8_t s) if ((cnt = s % 9) != 0) { /* extract the new CARRY FLAG. */ /* CF <- b_(n-1) */ - if (cnt == 1) { + ocf = ACCESS_FLAG(F_CF) != 0; + /* OVERFLOW is set *IFF* cnt==1, then it is the + xor of CF and the most significant bit. Blecck. */ + /* parenthesized... */ + CONDITIONAL_SET_FLAG((ocf ^ (d >> 7)) & 0x1, + F_OF); + if (cnt == 1) { cf = d & 0x1; /* note hackery here. Access_flag(..) evaluates to either 0 if flag not set @@ -643,12 +641,6 @@ uint8_t rcr8(x64emu_t *emu, uint8_t d, uint8_t s) 0..1 in any representation of the flags register (i.e. packed bit array or unpacked.) */ - ocf = ACCESS_FLAG(F_CF) != 0; - /* OVERFLOW is set *IFF* cnt==1, then it is the - xor of CF and the most significant bit. Blecck. */ - /* parenthesized... */ - CONDITIONAL_SET_FLAG((ocf ^ (d >> 7)) & 0x1, - F_OF); } else cf = (d >> (cnt - 1)) & 0x1; @@ -691,11 +683,11 @@ uint16_t rcr16(x64emu_t *emu, uint16_t d, uint8_t s) /* rotate right through carry */ res = d; if ((cnt = s % 17) != 0) { + ocf = ACCESS_FLAG(F_CF) != 0; + CONDITIONAL_SET_FLAG((ocf ^ (d >> 15)) & 0x1, + F_OF); if (cnt == 1) { cf = d & 0x1; - ocf = ACCESS_FLAG(F_CF) != 0; - CONDITIONAL_SET_FLAG((ocf ^ (d >> 15)) & 0x1, - F_OF); } else cf = (d >> (cnt - 1)) & 0x1; mask = (1 << (16 - cnt)) - 1; @@ -719,14 +711,13 @@ uint32_t rcr32(x64emu_t *emu, uint32_t d, uint8_t s) /* rotate right through carry */ res = d; if ((cnt = s) != 0) { + ocf = ACCESS_FLAG(F_CF) != 0; + CONDITIONAL_SET_FLAG((ocf ^ (d >> 31)) & 0x1, + F_OF); if (cnt == 1) { cf = d & 0x1; - ocf = ACCESS_FLAG(F_CF) != 0; - CONDITIONAL_SET_FLAG((ocf ^ (d >> 31)) & 0x1, - F_OF); } else { cf = (d >> (cnt - 1)) & 0x1; - CLEAR_FLAG(F_OF); // UND, but clear for dynarec_test } mask = (1 << (32 - cnt)) - 1; res = (d >> cnt) & mask; @@ -750,14 +741,13 @@ uint64_t rcr64(x64emu_t *emu, uint64_t d, uint8_t s) /* rotate right through carry */ res = d; if ((cnt = s) != 0) { + ocf = ACCESS_FLAG(F_CF) != 0; + CONDITIONAL_SET_FLAG((ocf ^ (d >> 63)) & 0x1, + F_OF); if (cnt == 1) { cf = d & 0x1; - ocf = ACCESS_FLAG(F_CF) != 0; - CONDITIONAL_SET_FLAG((ocf ^ (d >> 63)) & 0x1, - F_OF); } else { cf = (d >> (cnt - 1)) & 0x1; - CLEAR_FLAG(F_OF); // UND, but clear for dynarec_test } mask = (1LL << (64 - cnt)) - 1; res = (d >> cnt) & mask; |