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. // 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) void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPXCHG8B(bxInstruction_c *i)
{ {
#if BX_CPU_LEVEL >= 5 #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)); BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
// check write permission for following write // check write permission for following write
op1_64_lo = read_RMW_virtual_dword(i->seg(), RMAddr(i)); op1_64 = read_RMW_virtual_qword(i->seg(), RMAddr(i));
op1_64_hi = read_RMW_virtual_dword(i->seg(), RMAddr(i) + 4); op2_64 = ((Bit64u) EDX << 32) | EAX;
diff = EAX - op1_64_lo; if (op1_64 == op2_64) { // if accumulator == dest
diff |= EDX - op1_64_hi; // dest <-- src (ECX:EBX)
op2_64 = ((Bit64u) ECX << 32) | EBX;
if (diff == 0) { // if accumulator == dest write_RMW_virtual_dword(op2_64);
// dest <-- src
write_RMW_virtual_dword(ECX);
// write permissions already checked by read_RMW_virtual_dword
write_virtual_dword(i->seg(), RMAddr(i), EBX);
assert_ZF(); assert_ZF();
} }
else { else {
clear_ZF();
// accumulator <-- dest // accumulator <-- dest
RAX = op1_64_lo; RAX = GET32L(op1_64);
RDX = op1_64_hi; RDX = GET32H(op1_64);
clear_ZF();
} }
#else #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. // 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; diff |= RDX - op1_64_hi;
if (diff == 0) { // if accumulator == dest if (diff == 0) { // if accumulator == dest
// dest <-- src // dest <-- src (RCX:RBX)
write_RMW_virtual_qword(RCX); write_RMW_virtual_qword(RCX);
// write permissions already checked by read_RMW_virtual_qword // write permissions already checked by read_RMW_virtual_qword
write_virtual_qword(i->seg(), RMAddr(i), RBX); 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. // 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); 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); BX_INSTR_WRMSR(BX_CPU_ID, ECX, val64);