diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-12-11 17:54:17 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-12-11 17:54:17 +0100 |
| commit | 4c238f0e1777f197f6550a7f99e1cf1d7894c2e7 (patch) | |
| tree | f59718de04d4ea78fa4e7d04d44bf030a57be0f5 /src | |
| parent | 7c000adb8704eee81395a6e2bb52010c8254b4ce (diff) | |
| download | box64-4c238f0e1777f197f6550a7f99e1cf1d7894c2e7.tar.gz box64-4c238f0e1777f197f6550a7f99e1cf1d7894c2e7.zip | |
[ARM64_DYNAREC] Better hadnling of flags on btx opcode familly ([COSIM] and improved undefined flags when running with cosim)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_0f.c | 68 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_660f.c | 69 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_f0.c | 135 |
3 files changed, 222 insertions, 50 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index dbfd4822..5b885ba4 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -1641,7 +1641,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xA3: INST_NAME("BT Ed, Gd"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); nextop = F8; GETGD; @@ -1665,6 +1665,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin LSRxw_REG(x4, ed, x2); BFIw(xFlags, x4, F_CF, 1); } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 0xA4: nextop = F8; @@ -1714,7 +1720,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xAB: INST_NAME("BTS Ed, Gd"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); nextop = F8; GETGD; @@ -1747,6 +1753,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STxw(ed, wback, fixedaddress); SMWRITE(); } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 0xAC: nextop = F8; @@ -1954,7 +1966,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xB3: INST_NAME("BTR Ed, Gd"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); nextop = F8; GETGD; @@ -1987,6 +1999,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STxw(ed, wback, fixedaddress); SMWRITE(); } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 0xB6: @@ -2028,7 +2046,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin switch((nextop>>3)&7) { case 4: INST_NAME("BT Ed, Ib"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); gd = x2; if(MODREG) { @@ -2041,11 +2059,19 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } u8 = F8; u8&=rex.w?0x3f:0x1f; - BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + IFX(X_CF) { + BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 5: INST_NAME("BTS Ed, Ib"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); if(MODREG) { ed = TO_NAT((nextop & 7) + (rex.b << 3)); @@ -2067,10 +2093,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STxw(ed, wback, fixedaddress); SMWRITE(); } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 6: INST_NAME("BTR Ed, Ib"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); if(MODREG) { ed = TO_NAT((nextop & 7) + (rex.b << 3)); @@ -2091,10 +2123,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STxw(ed, wback, fixedaddress); SMWRITE(); } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 7: INST_NAME("BTC Ed, Ib"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); if(MODREG) { ed = TO_NAT((nextop & 7) + (rex.b << 3)); @@ -2116,6 +2154,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STxw(ed, wback, fixedaddress); SMWRITE(); } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; default: DEFAULT; @@ -2123,7 +2167,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xBB: INST_NAME("BTC Ed, Gd"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); nextop = F8; GETGD; @@ -2156,6 +2200,12 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STxw(ed, wback, fixedaddress); SMWRITE(); } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 0xBC: INST_NAME("BSF Gd, Ed"); diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index eb04aca7..8905218c 100644 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -2315,7 +2315,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n case 0xA3: INST_NAME("BT Ew, Gw"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); nextop = F8; gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)); // GETGD @@ -2334,6 +2334,12 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n LSRw_REG(x1, ed, x2); BFIw(xFlags, x1, F_CF, 1); } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 0xA4: INST_NAME("SHLD Ew, Gw, Ib"); @@ -2369,7 +2375,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n case 0xAB: INST_NAME("BTS Ew, Gw"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); nextop = F8; gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)); // GETGD @@ -2394,6 +2400,13 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n ORRx_REG(ed, ed, x1); if(wback) { STH(ed, wback, fixedaddress); + SMWRITE(); + } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} } break; case 0xAC: @@ -2443,7 +2456,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n case 0xB3: INST_NAME("BTR Ew, Gw"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); nextop = F8; gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)); // GETGD @@ -2469,6 +2482,12 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n STH(ed, wback, fixedaddress); SMWRITE(); } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 0xB6: @@ -2513,17 +2532,25 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n switch((nextop>>3)&7) { case 4: INST_NAME("BT Ew, Ib"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); gd = x2; GETEW(x1, 1); u8 = F8; u8&=rex.w?0x3f:0x0f; - BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + IFX(X_CF) { + BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 5: INST_NAME("BTS Ew, Ib"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); GETEW(x1, 1); u8 = F8; @@ -2534,10 +2561,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n mask = convert_bitmask_xw(1<<u8); ORRxw_mask(ed, ed, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F); EWBACK; + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 6: INST_NAME("BTR Ew, Ib"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); GETEW(x1, 1); u8 = F8; @@ -2547,10 +2580,16 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } BFCxw(ed, u8, 1); EWBACK; + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 7: INST_NAME("BTC Ew, Ib"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); GETEW(x1, 1); u8 = F8; @@ -2561,6 +2600,12 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n mask = convert_bitmask_xw(1<<u8); EORxw_mask(ed, ed, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F); EWBACK; + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; default: DEFAULT; @@ -2568,7 +2613,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n break; case 0xBB: INST_NAME("BTC Ew, Gw"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); nextop = F8; gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)); // GETGD @@ -2596,6 +2641,12 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n STH(ed, wback, fixedaddress); SMWRITE(); } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 0xBC: INST_NAME("BSF Gw,Ew"); diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c index 780377af..f4f0bfe1 100644 --- a/src/dynarec/arm64/dynarec_arm64_f0.c +++ b/src/dynarec/arm64/dynarec_arm64_f0.c @@ -33,7 +33,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin int32_t i32; int64_t i64, j64; int64_t fixedaddress; - int unscaled; + int unscaled, mask; MAYUSE(eb1); MAYUSE(eb2); MAYUSE(gb1); @@ -208,7 +208,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xAB: INST_NAME("LOCK BTS Ed, Gd"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); nextop = F8; GETGD; @@ -226,7 +226,9 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { ANDSw_mask(x4, x4, 0, 0); //mask=1 } - BFIw(xFlags, x4, F_CF, 1); + IFX(X_CF) { + BFIw(xFlags, x4, F_CF, 1); + } MOV32w(x4, 1); LSLxw_REG(x4, x4, x2); ORRxw_REG(ed, ed, x4); @@ -235,20 +237,29 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ANDw_mask(x2, gd, 0, 0b00010); //mask=0x000000007 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); ASRxw(x1, gd, 3); // r1 = (gd>>3) - ADDx_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1; + if(!rex.w && !rex.is32bits) {SXTWx(x1, x1);} + ADDz_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1; ed = x1; wback = x3; MOV32w(x5, 1); MARKLOCK; LDAXRB(ed, wback); LSRw_REG(x4, ed, x2); - BFIw(xFlags, x4, F_CF, 1); + IFX(X_CF) { + BFIw(xFlags, x4, F_CF, 1); + } LSLw_REG(x4, x5, x2); ORRw_REG(ed, ed, x4); STLXRB(x4, ed, wback); CBNZw_MARKLOCK(x4); SMDMB(); } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 0xB0: switch(rep) { @@ -395,7 +406,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xB3: INST_NAME("LOCK BTR Ed, Gd"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); nextop = F8; GETGD; @@ -408,12 +419,9 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ANDw_mask(x2, gd, 0, 0b00100); //mask=0x00000001f } LSRxw_REG(x4, ed, x2); - if(rex.w) { - ANDx_mask(x4, x4, 1, 0, 0); //mask=1 - } else { - ANDw_mask(x4, x4, 0, 0); //mask=1 + IFX(X_CF) { + BFIw(xFlags, x4, F_CF, 1); } - BFIw(xFlags, x4, F_CF, 1); MOV32w(x4, 1); LSLxw_REG(x4, x4, x2); BICxw_REG(ed, ed, x4); @@ -422,20 +430,29 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ANDw_mask(x2, gd, 0, 0b00010); //mask=0x000000007 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); ASRx(x1, gd, 3); // r1 = (gd>>3), there might be an issue for negative 32bits values here - ADDx_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1; + if(!rex.w && !rex.is32bits) {SXTWx(x1, x1);} + ADDz_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1; ed = x1; wback = x3; MOV32w(x5, 1); MARKLOCK; LDAXRB(ed, wback); LSRw_REG(x4, ed, x2); - BFIw(xFlags, x4, F_CF, 1); + IFX(X_CF) { + BFIw(xFlags, x4, F_CF, 1); + } LSLw_REG(x4, x5, x2); BICw_REG(ed, ed, x4); STLXRB(x4, ed, wback); CBNZw_MARKLOCK(x4); SMDMB(); } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } break; case 0xBA: @@ -443,14 +460,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin switch((nextop>>3)&7) { case 4: INST_NAME("LOCK BT Ed, Ib"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); gd = x2; if(MODREG) { ed = TO_NAT((nextop & 7) + (rex.b << 3)); u8 = F8; u8&=rex.w?0x3f:0x1f; - BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + IFX(X_CF) { + BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + } } else { // Will fetch only 1 byte, to avoid alignment issue addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); @@ -463,22 +482,37 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin LDAXRB(x1, wback); ed = x1; wback = x3; - BFXILxw(xFlags, x1, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + IFX(X_CF) { + BFXILxw(xFlags, x1, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + } + } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} } break; case 5: INST_NAME("LOCK BTS Ed, Ib"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); if(MODREG) { ed = TO_NAT((nextop & 7) + (rex.b << 3)); wback = 0; u8 = F8; u8&=(rex.w?0x3f:0x1f); - BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) - TBNZ_NEXT(xFlags, 0); // bit already set, jump to next instruction - MOV32w(x4, 1); - ORRxw_REG_LSL(ed, ed, x4, u8); + IFX(X_CF) { + BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } + mask = convert_bitmask_xw(1LL<<u8); + ORRxw_mask(ed, ed, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F); } else { // Will fetch only 1 byte, to avoid alignment issue addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); @@ -488,11 +522,19 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin wback = x3; } ed = x1; - MOV32w(x5, 1); MARKLOCK; LDAXRB(ed, wback); - BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) - BFIw(ed, x5, u8&7, 1); + IFX(X_CF) { + BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } + mask = convert_bitmask_xw(1LL<<(u8&7)); + ORRxw_mask(ed, ed, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F); STLXRB(x4, ed, wback); CBNZw_MARKLOCK(x4); SMDMB(); @@ -500,15 +542,22 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 6: INST_NAME("LOCK BTR Ed, Ib"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); if(MODREG) { ed = TO_NAT((nextop & 7) + (rex.b << 3)); wback = 0; u8 = F8; u8&=(rex.w?0x3f:0x1f); - BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) - TBZ_NEXT(xFlags, 0); // bit already clear, jump to next instruction + IFX(X_CF) { + BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } BFCxw(ed, u8, 1); } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); @@ -521,6 +570,12 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MARKLOCK; LDAXRB(ed, wback); BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } BFCw(ed, u8&7, 1); STLXRB(x4, ed, wback); CBNZw_MARKLOCK(x4); @@ -529,14 +584,22 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 7: INST_NAME("LOCK BTC Ed, Ib"); - SETFLAGS(X_CF, SF_SUBSET); + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); SET_DFNONE(x1); if(MODREG) { ed = TO_NAT((nextop & 7) + (rex.b << 3)); wback = 0; u8 = F8; u8&=(rex.w?0x3f:0x1f); - BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + IFX(X_CF) { + BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } MOV32w(x4, 1); EORxw_REG_LSL(ed, ed, x4, u8); } else { @@ -547,11 +610,19 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin wback = x3; } ed = x1; - MOV32w(x5, 1); MARKLOCK; LDAXRB(ed, wback); - BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) - EORw_REG_LSL(ed, ed, x5, u8&7); + IFX(X_CF) { + BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + } + if(box64_dynarec_test) { + IFX(X_OF) {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) {BFCw(xFlags, F_SF, 1);} + IFX(X_AF) {BFCw(xFlags, F_AF, 1);} + IFX(X_PF) {BFCw(xFlags, F_PF, 1);} + } + mask = convert_bitmask_xw(1LL<<(u8&7)); + ORRxw_mask(ed, ed, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F); STLXRB(x4, ed, wback); CBNZw_MARKLOCK(x4); SMDMB(); |