Fixes in CMPXHG8B instruction - slight speedup and correct #AC check

This commit is contained in:
Stanislav Shwartsman 2008-05-05 21:48:07 +00:00
parent f182f11a8e
commit eedf26627f
3 changed files with 15 additions and 19 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: arith32.cc,v 1.76 2008-04-04 22:39:45 sshwarts Exp $
// $Id: arith32.cc,v 1.77 2008-05-05 21:48:07 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -717,29 +717,25 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG_EdGdR(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG8B(bxInstruction_c *i)
{
#if BX_CPU_LEVEL >= 5
Bit32u op1_64_lo, op1_64_hi, diff;
Bit64u op1_64, op2_64;
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
// check write permission for following write
op1_64_lo = read_RMW_virtual_dword(i->seg(), RMAddr(i));
op1_64_hi = read_RMW_virtual_dword(i->seg(), RMAddr(i) + 4);
op1_64 = read_RMW_virtual_qword(i->seg(), RMAddr(i));
op2_64 = ((Bit64u) EDX << 32) | EAX;
diff = EAX - op1_64_lo;
diff |= EDX - op1_64_hi;
if (diff == 0) { // if accumulator == dest
// dest <-- src
write_RMW_virtual_dword(ECX);
// write permissions already checked by read_RMW_virtual_dword
write_virtual_dword(i->seg(), RMAddr(i), EBX);
if (op1_64 == op2_64) { // if accumulator == dest
// dest <-- src (ECX:EBX)
op2_64 = ((Bit64u) ECX << 32) | EBX;
write_RMW_virtual_dword(op2_64);
assert_ZF();
}
else {
clear_ZF();
// accumulator <-- dest
RAX = op1_64_lo;
RDX = op1_64_hi;
RAX = GET32L(op1_64);
RDX = GET32H(op1_64);
clear_ZF();
}
#else

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: arith64.cc,v 1.51 2008-04-04 22:39:45 sshwarts Exp $
// $Id: arith64.cc,v 1.52 2008-05-05 21:48:07 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -718,7 +718,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG16B(bxInstruction_c *i)
diff |= RDX - op1_64_hi;
if (diff == 0) { // if accumulator == dest
// dest <-- src
// dest <-- src (RCX:RBX)
write_RMW_virtual_qword(RCX);
// write permissions already checked by read_RMW_virtual_qword
write_virtual_qword(i->seg(), RMAddr(i), RBX);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.224 2008-05-04 21:25:16 sshwarts Exp $
// $Id: proc_ctrl.cc,v 1.225 2008-05-05 21:48:07 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1702,7 +1702,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::WRMSR(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0, 0);
}
Bit64u val64 = ((Bit64u) EDX << 32) + EAX;
Bit64u val64 = ((Bit64u) EDX << 32) | EAX;
BX_INSTR_WRMSR(BX_CPU_ID, ECX, val64);