diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-06-05 08:58:51 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-06-05 10:23:38 +0200 |
| commit | 42670c0130172da006357ba0f455a2a209bdebf8 (patch) | |
| tree | 111b87553a9f4648e47115ef8142c6721ca61b1a /src | |
| parent | f4c15979db68706b96380b2e827210b3d178a702 (diff) | |
| download | box64-42670c0130172da006357ba0f455a2a209bdebf8.tar.gz box64-42670c0130172da006357ba0f455a2a209bdebf8.zip | |
Fixed BT/BTC/BTR/BTS opcodes ([DYNAREC] too)
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/dynarec_arm64_0f.c | 48 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_660f.c | 69 | ||||
| -rw-r--r-- | src/emu/x64run0f.c | 43 | ||||
| -rw-r--r-- | src/emu/x64run660f.c | 66 |
4 files changed, 148 insertions, 78 deletions
diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c index 2660fbbf..37107026 100755 --- a/src/dynarec/dynarec_arm64_0f.c +++ b/src/dynarec/dynarec_arm64_0f.c @@ -969,19 +969,18 @@ 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_SET); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(x1); nextop = F8; GETGD; if(MODREG) { ed = xRAX+(nextop&7)+(rex.b<<3); - wback = 0; } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0); - UBFXw(x1, gd, 5+rex.w, 3-rex.w); // r1 = (gd>>5); - ADDx_REG_LSL(x3, wback, x1, 2); //(&ed)+=r1*4; + ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5) + ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; LDRxw_U12(x1, x3, fixedaddress); ed = x1; - wback = x3; } if(rex.w) { ANDx_mask(x2, gd, 1, 0, 0b00101); //mask=0x000000000000003f @@ -1006,7 +1005,8 @@ 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_SET); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(x1); nextop = F8; GETGD; if(MODREG) { @@ -1014,8 +1014,8 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin wback = 0; } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0); - UBFXw(x1, gd, 5+rex.w, 3-rex.w); // r1 = (gd>>5); - ADDx_REG_LSL(x3, wback, x1, 2); //(&ed)+=r1*4; + ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5) + ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; LDRxw_U12(x1, x3, fixedaddress); ed = x1; wback = x3; @@ -1142,7 +1142,8 @@ 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_SET); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(x1); nextop = F8; GETGD; if(MODREG) { @@ -1150,8 +1151,8 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin wback = 0; } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0); - UBFXw(x1, gd, 5+rex.w, 3-rex.w); // r1 = (gd>>5); - ADDx_REG_LSL(x3, wback, x1, 2); //(&ed)+=r1*4; + ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5) + ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; LDRxw_U12(x1, x3, fixedaddress); ed = x1; wback = x3; @@ -1215,17 +1216,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 4: INST_NAME("BT Ed, Ib"); SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(x1); gd = x2; if(MODREG) { ed = xRAX+(nextop&7)+(rex.b<<3); - u8 = F8; } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xff0<<2, 3, rex, 0, 1); - u8 = F8; - fixedaddress+=(u8>>(rex.w?6:5))*(rex.w?8:4); LDRxw_U12(x1, wback, fixedaddress); ed = x1; } + u8 = F8; u8&=rex.w?0x3f:0x1f; if(u8) { LSRxw(x1, ed, u8); @@ -1236,17 +1236,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 5: INST_NAME("BTS Ed, Ib"); SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(x1); if(MODREG) { ed = xRAX+(nextop&7)+(rex.b<<3); - u8 = F8; wback = 0; } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xff0<<2, 3, rex, 0, 1); - u8 = F8; - fixedaddress+=(u8>>(rex.w?6:5))*(rex.w?8:4); LDRxw_U12(x1, wback, fixedaddress); ed = x1; } + u8 = F8; LSRxw(x4, ed, u8&(rex.w?0x3f:0x1f)); BFIw(xFlags, x4, F_CF, 1); TBNZ_MARK3(x4, 0); // bit already set, jump to next instruction @@ -1260,17 +1259,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 6: INST_NAME("BTR Ed, Ib"); SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(x1); if(MODREG) { ed = xRAX+(nextop&7)+(rex.b<<3); - u8 = F8; wback = 0; } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xff0<<2, 3, rex, 0, 1); - u8 = F8; - fixedaddress+=(u8>>(rex.w?6:5))*(rex.w?8:4); LDRxw_U12(x1, wback, fixedaddress); ed = x1; } + u8 = F8; LSRxw(x4, ed, u8&(rex.w?0x3f:0x1f)); BFIw(xFlags, x4, F_CF, 1); TBZ_MARK3(x4, 0); // bit already clear, jump to next instruction @@ -1284,17 +1282,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 7: INST_NAME("BTC Ed, Ib"); SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(x1); if(MODREG) { ed = xRAX+(nextop&7)+(rex.b<<3); - u8 = F8; wback = 0; } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xff0<<2, 3, rex, 0, 1); - u8 = F8; - fixedaddress+=(u8>>(rex.w?6:5))*(rex.w?8:4); LDRxw_U12(x1, wback, fixedaddress); ed = x1; } + u8 = F8; LSRxw(x4, ed, u8&(rex.w?0x3f:0x1f)); BFIw(xFlags, x4, F_CF, 1); MOV32w(x4, 1); @@ -1311,6 +1308,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xBB: INST_NAME("BTC Ed, Gd"); SETFLAGS(X_CF, SF_SET); + SET_DFNONE(x1); nextop = F8; GETGD; if(MODREG) { @@ -1318,8 +1316,8 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin wback = 0; } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0); - UBFXw(x1, gd, 5+rex.w, 3-rex.w); // r1 = (gd>>5); - ADDx_REG_LSL(x3, wback, x1, 2); //(&ed)+=r1*4; + ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5) + ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; LDRxw_U12(x1, x3, fixedaddress); ed = x1; wback = x3; diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c index 999dc6e5..3cb870bf 100755 --- a/src/dynarec/dynarec_arm64_660f.c +++ b/src/dynarec/dynarec_arm64_660f.c @@ -850,10 +850,19 @@ 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_SET); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(x1); nextop = F8; gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); // GETGD - GETEW(x4, 0); + if(MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<2, (1<<2)-1, rex, 0, 0); + SBFXw(x1, gd, 4, 12); // r1 = (gw>>4) + ADDx_REG_LSL(x3, wback, x1, 1); //(&ed)+=r1*2; + LDRH_U12(x1, x3, fixedaddress); + ed = x1; + } ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f LSRw_REG(x1, ed, x2); BFIw(xFlags, x1, F_CF, 1); @@ -880,10 +889,20 @@ 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_SET); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(x1); nextop = F8; gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); // GETGD - GETEW(x4, 0); + if(MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + wback = 0; + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<2, (1<<2)-1, rex, 0, 0); + SBFXw(x4, gd, 4, 12); // r1 = (gw>>4) + ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2; + LDRH_U12(x4, x3, fixedaddress); + ed = x4; + } ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f LSRw_REG(x1, ed, x2); BFIw(xFlags, x1, F_CF, 1); @@ -892,7 +911,9 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n MOV32w(x1, 1); LSLxw_REG(x1, x1, x2); EORxw_REG(ed, ed, x1); - EWBACK; + if(wback) { + STRH_U12(ed, wback, fixedaddress); + } break; case 0xAC: case 0xAD: @@ -928,10 +949,21 @@ 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_SET); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(x1); nextop = F8; gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); // GETGD - GETEW(x4, 0); + if(MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + wback = 0; + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<2, (1<<2)-1, rex, 0, 0); + SBFXw(x4, gd, 4, 12); // r1 = (gw>>4) + ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2; + LDRH_U12(x4, x3, fixedaddress); + wback = x3; + ed = x4; + } ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f LSRw_REG(x1, ed, x2); BFIw(xFlags, x1, F_CF, 1); @@ -940,7 +972,9 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n MOV32w(x1, 1); LSLxw_REG(x1, x1, x2); EORxw_REG(ed, ed, x1); - EWBACK; + if(wback) { + STRH_U12(ed, wback, fixedaddress); + } break; case 0xB6: @@ -966,10 +1000,21 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n case 0xBB: INST_NAME("BTC Ew, Gw"); - SETFLAGS(X_CF, SF_SET); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(x1); nextop = F8; gd = xRAX+((nextop&0x38)>>3)+(rex.r<<3); // GETGD - GETEW(x4, 0); + if(MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + wback = 0; + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff<<2, (1<<2)-1, rex, 0, 0); + SBFXw(x4, gd, 4, 12); // r1 = (gw>>4) + ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2; + LDRH_U12(x4, x3, fixedaddress); + wback = x3; + ed = x4; + } ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f LSRw_REG(x1, ed, x2); BFIw(xFlags, x1, F_CF, 1); @@ -977,7 +1022,9 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n MOV32w(x1, 1); LSLxw_REG(x1, x1, x2); EORxw_REG(ed, ed, x1); - EWBACK; + if(wback) { + STRH_U12(ed, wback, fixedaddress); + } break; case 0xBC: INST_NAME("BSF Ew,Gw"); diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c index 887ca31c..30c89c0b 100644 --- a/src/emu/x64run0f.c +++ b/src/emu/x64run0f.c @@ -712,19 +712,19 @@ int Run0F(x64emu_t *emu, rex_t rex) nextop = F8; GETED(0); GETGD; - tmp8u = GD->byte[0]; + tmp32s = GD->sdword[0]; + tmp8u=tmp32s&(rex.w?63:31); + tmp32s >>= (rex.w?6:5); if(!MODREG) { - ED=(reg64_t*)(((uint32_t*)(ED))+(tmp8u>>5)); + ED=(reg64_t*)(((uintptr_t)(ED))+(tmp32s<<(rex.w?3:2))); } if(rex.w) { - tmp8u&=63; if(ED->q[0] & (1LL<<tmp8u)) SET_FLAG(F_CF); else CLEAR_FLAG(F_CF); } else { - tmp8u&=31; if(ED->dword[0] & (1<<tmp8u)) SET_FLAG(F_CF); else @@ -755,13 +755,14 @@ int Run0F(x64emu_t *emu, rex_t rex) nextop = F8; GETED(0); GETGD; - tmp8u = GD->byte[0]; + tmp32s = GD->sdword[0]; + tmp8u=tmp32s&(rex.w?63:31); + tmp32s >>= (rex.w?6:5); if(!MODREG) { - ED=(reg64_t*)(((uint32_t*)(ED))+(tmp8u>>5)); + ED=(reg64_t*)(((uintptr_t)(ED))+(tmp32s<<(rex.w?3:2))); } if(rex.w) { - tmp8u&=63; if(ED->q[0] & (1LL<<tmp8u)) SET_FLAG(F_CF); else { @@ -769,7 +770,6 @@ int Run0F(x64emu_t *emu, rex_t rex) CLEAR_FLAG(F_CF); } } else { - tmp8u&=31; if(ED->dword[0] & (1<<tmp8u)) SET_FLAG(F_CF); else { @@ -882,20 +882,20 @@ int Run0F(x64emu_t *emu, rex_t rex) nextop = F8; GETED(0); GETGD; - tmp8u = GD->byte[0]; + tmp32s = GD->sdword[0]; + tmp8u=tmp32s&(rex.w?63:31); + tmp32s >>= (rex.w?6:5); if(!MODREG) { - ED=(reg64_t*)(((uint32_t*)(ED))+(tmp8u>>5)); + ED=(reg64_t*)(((uintptr_t)(ED))+(tmp32s<<(rex.w?3:2))); } if(rex.w) { - tmp8u&=63; if(ED->q[0] & (1LL<<tmp8u)) { SET_FLAG(F_CF); ED->q[0] ^= (1LL<<tmp8u); } else CLEAR_FLAG(F_CF); } else { - tmp8u&=31; if(ED->dword[0] & (1<<tmp8u)) { SET_FLAG(F_CF); ED->dword[0] ^= (1<<tmp8u); @@ -926,8 +926,6 @@ int Run0F(x64emu_t *emu, rex_t rex) CHECK_FLAGS(emu); GETED(1); tmp8u = F8; - if(!MODREG) - ED=(reg64_t*)(((uintptr_t*)(ED))+(tmp8u>>5)); if(rex.w) { tmp8u&=63; if(ED->q[0] & (1LL<<tmp8u)) @@ -946,8 +944,6 @@ int Run0F(x64emu_t *emu, rex_t rex) CHECK_FLAGS(emu); GETED(1); tmp8u = F8; - if(!MODREG) - ED=(reg64_t*)(((uintptr_t*)(ED))+(tmp8u>>5)); if(rex.w) { tmp8u&=63; if(ED->q[0] & (1LL<<tmp8u)) { @@ -970,8 +966,6 @@ int Run0F(x64emu_t *emu, rex_t rex) CHECK_FLAGS(emu); GETED(1); tmp8u = F8; - if(!MODREG) - ED=(reg64_t*)(((uintptr_t*)(ED))+(tmp8u>>5)); if(rex.w) { tmp8u&=63; if(ED->q[0] & (1LL<<tmp8u)) { @@ -992,8 +986,6 @@ int Run0F(x64emu_t *emu, rex_t rex) CHECK_FLAGS(emu); GETED(1); tmp8u = F8; - if(!MODREG) - ED=(reg64_t*)(((uintptr_t*)(ED))+(tmp8u>>5)); if(rex.w) { tmp8u&=63; if(ED->q[0] & (1LL<<tmp8u)) @@ -1020,23 +1012,20 @@ int Run0F(x64emu_t *emu, rex_t rex) nextop = F8; GETED(0); GETGD; - tmp8u = GD->byte[0]; + tmp32s = GD->sdword[0]; + tmp8u=tmp32s&(rex.w?63:31); + tmp32s >>= (rex.w?6:5); if(!MODREG) { - if(rex.w) - ED=(reg64_t*)(((uint64_t*)(ED))+(tmp8u>>6)); - else - ED=(reg64_t*)(((uint32_t*)(ED))+(tmp8u>>5)); + ED=(reg64_t*)(((uintptr_t)(ED))+(tmp32s<<(rex.w?3:2))); } if(rex.w) { - tmp8u&=63; if(ED->q[0] & (1LL<<tmp8u)) SET_FLAG(F_CF); else CLEAR_FLAG(F_CF); ED->q[0] ^= (1LL<<tmp8u); } else { - tmp8u&=31; if(ED->dword[0] & (1<<tmp8u)) SET_FLAG(F_CF); else diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c index 9b23c1f2..be9b29ca 100644 --- a/src/emu/x64run660f.c +++ b/src/emu/x64run660f.c @@ -756,13 +756,20 @@ int Run660F(x64emu_t *emu, rex_t rex) nextop = F8; GETEW(0); GETGW; + tmp32s = rex.w?GW->sdword[0]:GW->sword[0]; + tmp8u=tmp32s&(rex.w?63:15); + tmp32s >>= (rex.w?6:4); + if(!MODREG) + { + EW=(reg64_t*)(((uintptr_t)(EW))+(tmp32s<<(rex.w?3:1))); + } if(rex.w) { - if(EW->q[0] & (1LL<<(GW->q[0]&63))) + if(EW->q[0] & (1LL<<tmp8u)) SET_FLAG(F_CF); else CLEAR_FLAG(F_CF); } else { - if(EW->word[0] & (1<<(GW->word[0]&15))) + if(EW->word[0] & (1<<tmp8u)) SET_FLAG(F_CF); else CLEAR_FLAG(F_CF); @@ -788,18 +795,25 @@ int Run660F(x64emu_t *emu, rex_t rex) nextop = F8; GETEW(0); GETGW; + tmp32s = rex.w?GW->sdword[0]:GW->sword[0]; + tmp8u=tmp32s&(rex.w?63:15); + tmp32s >>= (rex.w?6:4); + if(!MODREG) + { + EW=(reg64_t*)(((uintptr_t)(EW))+(tmp32s<<(rex.w?3:1))); + } if(rex.w) { - if(EW->q[0] & (1LL<<(GW->q[0]&63))) + if(EW->q[0] & (1LL<<tmp8u)) SET_FLAG(F_CF); else { - EW->q[0] |= (1LL<<(GW->q[0]&63)); + EW->q[0] |= (1LL<<tmp8u); CLEAR_FLAG(F_CF); } } else { - if(EW->word[0] & (1<<(GW->word[0]&15))) + if(EW->word[0] & (1<<tmp8u)) SET_FLAG(F_CF); else { - EW->word[0] |= (1<<(GW->word[0]&15)); + EW->word[0] |= (1<<tmp8u); CLEAR_FLAG(F_CF); } } @@ -855,16 +869,23 @@ int Run660F(x64emu_t *emu, rex_t rex) nextop = F8; GETEW(0); GETGW; + tmp32s = rex.w?GW->sdword[0]:GW->sword[0]; + tmp8u=tmp32s&(rex.w?63:15); + tmp32s >>= (rex.w?6:4); + if(!MODREG) + { + EW=(reg64_t*)(((uintptr_t)(EW))+(tmp32s<<(rex.w?3:1))); + } if(rex.w) { - if(EW->q[0] & (1LL<<(GW->q[0]&63))) { + if(EW->q[0] & (1LL<<tmp8u)) { SET_FLAG(F_CF); - EW->q[0] ^= (1LL<<(GW->q[0]&63)); + EW->q[0] ^= (1LL<<tmp8u); } else CLEAR_FLAG(F_CF); } else { - if(EW->word[0] & (1<<(GW->word[0]&15))) { + if(EW->word[0] & (1<<tmp8u)) { SET_FLAG(F_CF); - EW->word[0] ^= (1<<(GW->word[0]&15)); + EW->word[0] ^= (1<<tmp8u); } else CLEAR_FLAG(F_CF); } @@ -882,11 +903,26 @@ int Run660F(x64emu_t *emu, rex_t rex) nextop = F8; GETEW(0); GETGW; - if(EW->word[0] & (1<<(GW->word[0]&15))) - SET_FLAG(F_CF); - else - CLEAR_FLAG(F_CF); - EW->word[0] ^= (1<<(GW->word[0]&15)); + tmp32s = rex.w?GW->sdword[0]:GW->sword[0]; + tmp8u=tmp32s&(rex.w?63:15); + tmp32s >>= (rex.w?6:4); + if(!MODREG) + { + EW=(reg64_t*)(((uintptr_t)(EW))+(tmp32s<<(rex.w?3:1))); + } + if(rex.w) { + if(EW->q[0] & (1LL<<tmp8u)) + SET_FLAG(F_CF); + else + CLEAR_FLAG(F_CF); + EW->q[0] ^= (1LL<<tmp8u); + } else { + if(EW->word[0] & (1<<tmp8u)) + SET_FLAG(F_CF); + else + CLEAR_FLAG(F_CF); + EW->word[0] ^= (1<<tmp8u); + } break; case 0xBC: /* BSF Ew,Gw */ CHECK_FLAGS(emu); |