Skip to content

Commit

Permalink
Merge branch 'bochs-emu:master' into floppy
Browse files Browse the repository at this point in the history
  • Loading branch information
fysnet authored Nov 17, 2023
2 parents 395d9b5 + a3fe8c2 commit 87f2052
Show file tree
Hide file tree
Showing 32 changed files with 189 additions and 154 deletions.
4 changes: 2 additions & 2 deletions bochs/CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The Bochs source tree is transitioning from SVN to GIT hosted on github (https:/
We welcome every new contributor !

Brief summary :
- Bugfixes for CPU emulation correctness (MONITOR/MWAIT, VMX/SVM, AVX-512, SHA fixes)
- Bugfixes for CPU emulation correctness (MONITOR/MWAIT, VMX/SVM, AVX-512, CET, SHA fixes)
! Implemented VMX MBE (Mode Based Execution Control) emulation required for Windows 11 guest
! Implemented Linear Address Separation (LASS) extension
! Implemented recently published Intel instruction sets:
Expand All @@ -23,7 +23,7 @@ Brief summary :
Detailed change log :

- CPU/CPUDB
- Bugfixes for CPU emulation correctness (MONITOR/MWAIT, VMX/SVM, AVX-512, SHA fixes)
- Bugfixes for CPU emulation correctness (MONITOR/MWAIT, VMX/SVM, AVX-512, CET, SHA fixes)
- Implemented VMX MBE (Mode Based Execution Control) emulation required for Windows 11 guest
- Implemented Linear Address Separation (LASS) extension
- Implemented recently published Intel instruction sets:
Expand Down
2 changes: 2 additions & 0 deletions bochs/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,8 @@
#define GET32L(val64) ((Bit32u)(((Bit64u)(val64)) & 0xFFFFFFFF))
#define GET32H(val64) ((Bit32u)(((Bit64u)(val64)) >> 32))

#define GET64_FROM_HI32_LO32(hi, lo) (Bit64u(lo) | (Bit64u(hi) << 32))

// now that Bit32u and Bit64u exist, defined bx_address
#if BX_SUPPORT_X86_64
typedef Bit64u bx_address;
Expand Down
52 changes: 34 additions & 18 deletions bochs/cpu/access.cc
Original file line number Diff line number Diff line change
Expand Up @@ -299,9 +299,8 @@ BX_CPU_C::system_read_byte(bx_address laddr)
bx_address lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = BX_DTLB_ENTRY_OF(laddr, 0);
if (tlbEntry->lpf == lpf) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
if (tlbEntry->accessBits & 0x01) {
// See if the TLB entry privilege level allows us read access from CPL=0
if (isReadOK(tlbEntry, 0)) {
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
Bit8u *hostAddr = (Bit8u*) (hostPageAddr | pageOffset);
Expand All @@ -325,9 +324,8 @@ BX_CPU_C::system_read_word(bx_address laddr)
bx_address lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = BX_DTLB_ENTRY_OF(laddr, 1);
if (tlbEntry->lpf == lpf) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
if (tlbEntry->accessBits & 0x01) {
// See if the TLB entry privilege level allows us read access from CPL=0
if (isReadOK(tlbEntry, 0)) {
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
Bit16u *hostAddr = (Bit16u*) (hostPageAddr | pageOffset);
Expand All @@ -351,9 +349,8 @@ BX_CPU_C::system_read_dword(bx_address laddr)
bx_address lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = BX_DTLB_ENTRY_OF(laddr, 3);
if (tlbEntry->lpf == lpf) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
if (tlbEntry->accessBits & 0x01) {
// See if the TLB entry privilege level allows us read access from CPL=0
if (isReadOK(tlbEntry, 0)) {
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
Bit32u *hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
Expand All @@ -377,9 +374,8 @@ BX_CPU_C::system_read_qword(bx_address laddr)
bx_address lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = BX_DTLB_ENTRY_OF(laddr, 7);
if (tlbEntry->lpf == lpf) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
if (tlbEntry->accessBits & 0x01) {
// See if the TLB entry privilege level allows us read access from CPL=0
if (isReadOK(tlbEntry, 0)) {
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
Bit64u *hostAddr = (Bit64u*) (hostPageAddr | pageOffset);
Expand All @@ -401,8 +397,7 @@ BX_CPU_C::system_write_byte(bx_address laddr, Bit8u data)
bx_address lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = BX_DTLB_ENTRY_OF(laddr, 0);
if (tlbEntry->lpf == lpf) {
// See if the TLB entry privilege level allows us write access
// from this CPL.
// See if the TLB entry privilege level allows us write access from CPL=0
if (isWriteOK(tlbEntry, 0)) {
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
Expand All @@ -425,8 +420,7 @@ BX_CPU_C::system_write_word(bx_address laddr, Bit16u data)
bx_address lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = BX_DTLB_ENTRY_OF(laddr, 1);
if (tlbEntry->lpf == lpf) {
// See if the TLB entry privilege level allows us write access
// from this CPL.
// See if the TLB entry privilege level allows us write access from CPL=0
if (isWriteOK(tlbEntry, 0)) {
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
Expand All @@ -449,8 +443,7 @@ BX_CPU_C::system_write_dword(bx_address laddr, Bit32u data)
bx_address lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = BX_DTLB_ENTRY_OF(laddr, 3);
if (tlbEntry->lpf == lpf) {
// See if the TLB entry privilege level allows us write access
// from this CPL.
// See if the TLB entry privilege level allows us write access from CPL=0
if (isWriteOK(tlbEntry, 0)) {
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
Expand All @@ -467,6 +460,29 @@ BX_CPU_C::system_write_dword(bx_address laddr, Bit32u data)
exception(BX_GP_EXCEPTION, 0);
}

void BX_CPP_AttrRegparmN(2)
BX_CPU_C::system_write_qword(bx_address laddr, Bit64u data)
{
bx_address lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = BX_DTLB_ENTRY_OF(laddr, 7);
if (tlbEntry->lpf == lpf) {
// See if the TLB entry privilege level allows us write access from CPL=0
if (isWriteOK(tlbEntry, 0)) {
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
bx_phy_address pAddr = tlbEntry->ppf | pageOffset;
BX_NOTIFY_LIN_MEMORY_ACCESS(laddr, pAddr, 8, tlbEntry->get_memtype(), BX_WRITE, (Bit8u*) &data);
Bit64u *hostAddr = (Bit64u*) (hostPageAddr | pageOffset);
pageWriteStampTable.decWriteStamp(pAddr, 8);
WriteHostQWordToLittleEndian(hostAddr, data);
return;
}
}

if (access_write_linear(laddr, 8, 0, BX_WRITE, 0x0, (void *) &data) < 0)
exception(BX_GP_EXCEPTION, 0);
}

Bit8u* BX_CPP_AttrRegparmN(2)
BX_CPU_C::v2h_read_byte(bx_address laddr, bool user)
{
Expand Down
2 changes: 1 addition & 1 deletion bochs/cpu/access2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,7 @@ void BX_CPP_AttrRegparmN(3) BX_CPU_C::shadow_stack_write_qword(bx_address offset

bool BX_CPP_AttrRegparmN(4) BX_CPU_C::shadow_stack_lock_cmpxchg8b(bx_address offset, unsigned curr_pl, Bit64u data, Bit64u expected_data)
{
Bit64u val64 = shadow_stack_read_qword(offset, curr_pl);
Bit64u val64 = shadow_stack_read_qword(offset, curr_pl); // should be locked and RMW
if (val64 == expected_data) {
shadow_stack_write_qword(offset, curr_pl, data);
return true;
Expand Down
2 changes: 1 addition & 1 deletion bochs/cpu/apic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1239,7 +1239,7 @@ bool bx_local_apic_c::read_x2apic(unsigned index, Bit64u *val_64)
break;
// full 64-bit access to ICR
case BX_LAPIC_ICR_LO:
*val_64 = ((Bit64u) icr_lo) | (((Bit64u) icr_hi) << 32);
*val_64 = GET64_FROM_HI32_LO32(icr_hi, icr_lo);
break;
// not supported/not readable in x2apic mode
case BX_LAPIC_ARBITRATION_PRIORITY:
Expand Down
4 changes: 2 additions & 2 deletions bochs/cpu/arith32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -582,11 +582,11 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG8B(bxInstruction_c *i)

// check write permission for following write
Bit64u op1_64 = read_RMW_virtual_qword(i->seg(), eaddr);
Bit64u op2_64 = ((Bit64u) EDX << 32) | EAX;
Bit64u op2_64 = GET64_FROM_HI32_LO32(EDX, EAX);

if (op1_64 == op2_64) { // if accumulator == dest
// dest <-- src (ECX:EBX)
op2_64 = ((Bit64u) ECX << 32) | EBX;
op2_64 = GET64_FROM_HI32_LO32(ECX, EBX);
write_RMW_linear_qword(op2_64);
assert_ZF();
}
Expand Down
8 changes: 4 additions & 4 deletions bochs/cpu/avx/avx512_helpers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ void BX_CPU_C::avx_masked_store8(bxInstruction_c *i, bx_address eaddr, const BxP
// see if you can successfully write all the elements first
for (int n=BYTE_ELEMENTS(len)-1; n >= 0; n--) {
if (mask & (BX_CONST64(1)<<n))
read_RMW_virtual_byte(i->seg(), eaddr + n);
read_RMW_virtual_byte(i->seg(), eaddr + n); // no lock
}

for (unsigned n=0; n < BYTE_ELEMENTS(len); n++) {
Expand Down Expand Up @@ -195,7 +195,7 @@ void BX_CPU_C::avx_masked_store16(bxInstruction_c *i, bx_address eaddr, const Bx
// see if you can successfully write all the elements first
for (int n=WORD_ELEMENTS(len)-1; n >= 0; n--) {
if (mask & (1<<n))
read_RMW_virtual_word(i->seg(), eaddr + 2*n);
read_RMW_virtual_word(i->seg(), eaddr + 2*n); // no lock
}

for (unsigned n=0; n < WORD_ELEMENTS(len); n++) {
Expand Down Expand Up @@ -232,7 +232,7 @@ void BX_CPU_C::avx_masked_store32(bxInstruction_c *i, bx_address eaddr, const Bx
// see if you can successfully write all the elements first
for (int n=DWORD_ELEMENTS(len)-1; n >= 0; n--) {
if (mask & (1<<n))
read_RMW_virtual_dword(i->seg(), eaddr + 4*n);
read_RMW_virtual_dword(i->seg(), eaddr + 4*n); // no lock
}

for (unsigned n=0; n < DWORD_ELEMENTS(len); n++) {
Expand Down Expand Up @@ -269,7 +269,7 @@ void BX_CPU_C::avx_masked_store64(bxInstruction_c *i, bx_address eaddr, const Bx
// see if you can successfully write all the elements first
for (int n=QWORD_ELEMENTS(len)-1; n >= 0; n--) {
if (mask & (1<<n))
read_RMW_virtual_qword(i->seg(), eaddr + 8*n);
read_RMW_virtual_qword(i->seg(), eaddr + 8*n); // no lock
}

for (unsigned n=0; n < QWORD_ELEMENTS(len); n++) {
Expand Down
4 changes: 2 additions & 2 deletions bochs/cpu/cet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RSTORSSP(bxInstruction_c *i)

Bit64u previous_ssp_token = SSP | long64_mode() | 0x02;

// should be done atomically
// should be done atomically using RMW
Bit64u SSP_tmp = shadow_stack_read_qword(laddr, CPL); // should be LWSI
if ((SSP_tmp & 0x03) != long64_mode()) {
BX_ERROR(("%s: CS.L of shadow stack token doesn't match or bit1 is not 0", i->getIaOpcodeNameShort()));
Expand All @@ -256,7 +256,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RSTORSSP(bxInstruction_c *i)
exception(BX_CP_EXCEPTION, BX_CP_RSTORSSP);
}
shadow_stack_write_qword(laddr, CPL, previous_ssp_token);
// should be done atomically
// should be done atomically using RMW

SSP = laddr;

Expand Down
32 changes: 16 additions & 16 deletions bochs/cpu/cmpccxadd32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPBEXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword((get_CF() || get_ZF()) ? op1_32 + op3_32 : op1_32);
Expand All @@ -59,7 +59,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPBXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword(get_CF() ? op1_32 + op3_32 : op1_32);
Expand All @@ -80,7 +80,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPLEXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword((get_ZF() || getB_SF() != getB_OF()) ? op1_32 + op3_32 : op1_32);
Expand All @@ -101,7 +101,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPLXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword((getB_SF() != getB_OF()) ? op1_32 + op3_32 : op1_32);
Expand All @@ -122,7 +122,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPNBEXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword((!get_CF() && !get_ZF()) ? op1_32 + op3_32 : op1_32);
Expand All @@ -143,7 +143,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPNBXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword(!get_CF() ? op1_32 + op3_32 : op1_32);
Expand All @@ -164,7 +164,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPNLEXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword((!get_ZF() && getB_SF() == getB_OF()) ? op1_32 + op3_32 : op1_32);
Expand All @@ -185,7 +185,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPNLXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword((getB_SF() == getB_OF()) ? op1_32 + op3_32 : op1_32);
Expand All @@ -206,7 +206,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPNOXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword(!get_OF() ? op1_32 + op3_32 : op1_32);
Expand All @@ -227,7 +227,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPNPXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword(!get_PF() ? op1_32 + op3_32 : op1_32);
Expand All @@ -248,7 +248,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPNSXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword(!get_SF() ? op1_32 + op3_32 : op1_32);
Expand All @@ -269,7 +269,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPNZXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword((!get_ZF()) ? op1_32 + op3_32 : op1_32);
Expand All @@ -290,7 +290,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPOXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword(get_OF() ? op1_32 + op3_32 : op1_32);
Expand All @@ -311,7 +311,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPPXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword(get_PF() ? op1_32 + op3_32 : op1_32);
Expand All @@ -332,7 +332,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPSXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword(get_SF() ? op1_32 + op3_32 : op1_32);
Expand All @@ -353,7 +353,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPZXADD_EdGdBd(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0);
}

Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr);
Bit32u op1_32 = read_RMW_linear_dword(i->seg(), laddr); // implicit lock
Bit32u diff_32 = op1_32 - op2_32;
SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32);
write_RMW_linear_dword(get_ZF() ? op1_32 + op3_32 : op1_32);
Expand Down
Loading

0 comments on commit 87f2052

Please sign in to comment.