Speed simulation between 3 to 5% by eliminating several checks from cpu loop.

The checks were related to repeat instructions - handle them differently
This commit is contained in:
Stanislav Shwartsman 2007-01-05 13:40:47 +00:00
parent b7be2eb0b1
commit 5c21f7821f
7 changed files with 431 additions and 194 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: bochs.h,v 1.204 2006-10-31 19:26:34 vruppert Exp $
// $Id: bochs.h,v 1.205 2007-01-05 13:40:46 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -208,6 +208,12 @@ void print_tree(bx_param_c *node, int level = 0);
# define A20ADDR(x) (x)
#endif
#if BX_SUPPORT_SMP
# define BX_TICK1_IF_SINGLE_PROCESSOR()
#else
# define BX_TICK1_IF_SINGLE_PROCESSOR() BX_TICK1()
#endif
// you can't use static member functions on the CPU, if there are going
// to be 2 cpus. Check this early on.
#if BX_SUPPORT_SMP

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.168 2006-09-26 19:16:10 sshwarts Exp $
// $Id: cpu.cc,v 1.169 2007-01-05 13:40:46 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -112,12 +112,6 @@ static unsigned iCacheMisses=0;
if (count == 0) return; \
}
#if BX_SUPPORT_SMP
# define BX_TICK1_IF_SINGLE_PROCESSOR()
#else
# define BX_TICK1_IF_SINGLE_PROCESSOR() BX_TICK1()
#endif
// Make code more tidy with a few macros.
#if BX_SUPPORT_X86_64==0
#define RIP EIP
@ -290,93 +284,9 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count)
// decoding instruction compeleted -> continue with execution
BX_INSTR_BEFORE_EXECUTION(BX_CPU_ID, i);
RIP += i->ilen();
if ( !(i->repUsedL() && i->repeatableL()) ) {
// non repeating instruction
BX_CPU_CALL_METHOD(execute, (i));
}
else {
repeat_loop:
if (i->repeatableZFL()) {
#if BX_SUPPORT_X86_64
if (i->as64L()) {
if (RCX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
RCX --;
}
if ((i->repUsedValue()==3) && (get_ZF()==0)) goto debugger_check;
if ((i->repUsedValue()==2) && (get_ZF()!=0)) goto debugger_check;
if (RCX == 0) goto debugger_check;
}
else
#endif
if (i->as32L()) {
if (ECX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
ECX --;
}
if ((i->repUsedValue()==3) && (get_ZF()==0)) goto debugger_check;
if ((i->repUsedValue()==2) && (get_ZF()!=0)) goto debugger_check;
if (ECX == 0) goto debugger_check;
}
else {
if (CX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
CX --;
}
if ((i->repUsedValue()==3) && (get_ZF()==0)) goto debugger_check;
if ((i->repUsedValue()==2) && (get_ZF()!=0)) goto debugger_check;
if (CX == 0) goto debugger_check;
}
}
else { // normal repeat, no concern for ZF
#if BX_SUPPORT_X86_64
if (i->as64L()) {
if (RCX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
RCX --;
}
if (RCX == 0) goto debugger_check;
}
else
#endif
if (i->as32L()) {
if (ECX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
ECX --;
}
if (ECX == 0) goto debugger_check;
}
else { // 16bit addrsize
if (CX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
CX --;
}
if (CX == 0) goto debugger_check;
}
}
BX_TICK1_IF_SINGLE_PROCESSOR();
#if BX_DEBUGGER == 0
// when debugger is not enabled, directly jump to next iteration
if (! BX_CPU_THIS_PTR async_event) goto repeat_loop;
#endif
// invalidate_prefetch_q(); // why do we need invalidate_prefetch_q ?
RIP = BX_CPU_THIS_PTR prev_eip; // repeat loop not done, restore RIP
goto debugger_check;
}
debugger_check:
BX_CPU_THIS_PTR prev_eip = RIP; // commit new EIP
BX_CPU_THIS_PTR prev_esp = RSP; // commit new ESP
BX_CPU_CALL_METHOD(execute, (i)); // might iterate repeat instruction
BX_CPU_THIS_PTR prev_eip = RIP; // commit new RIP
BX_CPU_THIS_PTR prev_esp = RSP; // commit new RSP
BX_INSTR_AFTER_EXECUTION(BX_CPU_ID, i);
BX_TICK1_IF_SINGLE_PROCESSOR();
@ -406,6 +316,110 @@ debugger_check:
} // while (1)
}
void BX_CPU_C::repeat(bxInstruction_c *i, BxExecutePtr_t execute)
{
// non repeated instruction
if (! i->repUsedL()) {
BX_CPU_CALL_METHOD(execute, (i));
return;
}
while(1) {
#if BX_SUPPORT_X86_64
if (i->as64L()) {
if (RCX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
RCX --;
}
if (RCX == 0) return;
}
else
#endif
if (i->as32L()) {
if (ECX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
ECX --;
}
if (ECX == 0) return;
}
else { // 16bit addrsize
if (CX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
CX --;
}
if (CX == 0) return;
}
BX_TICK1_IF_SINGLE_PROCESSOR();
#if BX_DEBUGGER == 0
if (BX_CPU_THIS_PTR async_event)
#endif
break; // exit always if debugger enabled
}
RIP = BX_CPU_THIS_PTR prev_eip; // repeat loop not done, restore RIP
}
void BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePtr_t execute)
{
// non repeated instruction
if (! i->repUsedL()) {
BX_CPU_CALL_METHOD(execute, (i));
return;
}
while(1) {
#if BX_SUPPORT_X86_64
if (i->as64L()) {
if (RCX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
RCX --;
}
if ((i->repUsedValue()==3) && (get_ZF()==0)) return;
if ((i->repUsedValue()==2) && (get_ZF()!=0)) return;
if (RCX == 0) return;
}
else
#endif
if (i->as32L()) {
if (ECX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
ECX --;
}
if ((i->repUsedValue()==3) && (get_ZF()==0)) return;
if ((i->repUsedValue()==2) && (get_ZF()!=0)) return;
if (ECX == 0) return;
}
else {
if (CX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
CX --;
}
if ((i->repUsedValue()==3) && (get_ZF()==0)) return;
if ((i->repUsedValue()==2) && (get_ZF()!=0)) return;
if (CX == 0) return;
}
BX_TICK1_IF_SINGLE_PROCESSOR();
#if BX_DEBUGGER == 0
if (BX_CPU_THIS_PTR async_event)
#endif
break; // exit always if debugger enabled
}
RIP = BX_CPU_THIS_PTR prev_eip; // repeat loop not done, restore RIP
}
unsigned BX_CPU_C::handleAsyncEvent(void)
{
//

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.306 2006-10-29 08:48:30 vruppert Exp $
// $Id: cpu.h,v 1.307 2007-01-05 13:40:46 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -649,8 +649,8 @@ public:
// 26..23 ilen (0..15). Leave this one on top so no mask is needed.
// 22..22 mod==c0 (modrm)
// 21..13 b1 (9bits of opcode; 1byte-op=0..255, 2byte-op=256..511.
// 12..12 BxRepeatableZF (pass-thru from fetchdecode attributes)
// 11..11 BxRepeatable (pass-thru from fetchdecode attributes)
// 12..12 (unused)
// 11..11 (unused)
// 10...9 repUsed (0=none, 2=0xF2, 3=0xF3).
// 8...8 extend8bit
// 7...7 as64
@ -846,20 +846,6 @@ public:
BX_CPP_INLINE void setRepUsed(unsigned value) {
metaInfo = (metaInfo & ~(3<<9)) | (value<<9);
}
BX_CPP_INLINE void setRepAttr(unsigned value) {
// value is expected to be masked, and only contain bits
// for BxRepeatable and BxRepeatableZF. We don't need to
// keep masking out these bits before we add in new ones,
// since the fetch process won't start with repeatable attributes
// and then delete them.
metaInfo |= value;
}
BX_CPP_INLINE unsigned repeatableL(void) {
return metaInfo & (1<<11);
}
BX_CPP_INLINE unsigned repeatableZFL(void) {
return metaInfo & (1<<12);
}
BX_CPP_INLINE unsigned b1(void) {
return (metaInfo >> 13) & 0x1ff;
@ -1408,6 +1394,7 @@ public: // for now...
BX_SMF void ARPL_EwGw(bxInstruction_c *);
BX_SMF void PUSH_Id(bxInstruction_c *);
BX_SMF void PUSH_Iw(bxInstruction_c *);
BX_SMF void INSB_YbDX(bxInstruction_c *);
BX_SMF void INSW_YwDX(bxInstruction_c *);
BX_SMF void INSD_YdDX(bxInstruction_c *);
@ -1415,6 +1402,13 @@ public: // for now...
BX_SMF void OUTSW_DXXw(bxInstruction_c *);
BX_SMF void OUTSD_DXXd(bxInstruction_c *);
BX_SMF void REP_INSB_YbDX(bxInstruction_c *);
BX_SMF void REP_INSW_YwDX(bxInstruction_c *);
BX_SMF void REP_INSD_YdDX(bxInstruction_c *);
BX_SMF void REP_OUTSB_DXXb(bxInstruction_c *);
BX_SMF void REP_OUTSW_DXXw(bxInstruction_c *);
BX_SMF void REP_OUTSD_DXXd(bxInstruction_c *);
BX_SMF void BOUND_GwMa(bxInstruction_c *);
BX_SMF void BOUND_GdMa(bxInstruction_c *);
@ -1481,6 +1475,22 @@ public: // for now...
BX_SMF void LODSD_EAXXd(bxInstruction_c *);
BX_SMF void SCASD_EAXXd(bxInstruction_c *);
BX_SMF void REP_MOVSB_XbYb(bxInstruction_c *);
BX_SMF void REP_MOVSW_XwYw(bxInstruction_c *);
BX_SMF void REP_MOVSD_XdYd(bxInstruction_c *);
BX_SMF void REP_CMPSB_XbYb(bxInstruction_c *);
BX_SMF void REP_CMPSW_XwYw(bxInstruction_c *);
BX_SMF void REP_CMPSD_XdYd(bxInstruction_c *);
BX_SMF void REP_STOSB_YbAL(bxInstruction_c *);
BX_SMF void REP_LODSB_ALXb(bxInstruction_c *);
BX_SMF void REP_SCASB_ALXb(bxInstruction_c *);
BX_SMF void REP_STOSW_YwAX(bxInstruction_c *);
BX_SMF void REP_LODSW_AXXw(bxInstruction_c *);
BX_SMF void REP_SCASW_AXXw(bxInstruction_c *);
BX_SMF void REP_STOSD_YdEAX(bxInstruction_c *);
BX_SMF void REP_LODSD_EAXXd(bxInstruction_c *);
BX_SMF void REP_SCASD_EAXXd(bxInstruction_c *);
BX_SMF void RETnear32(bxInstruction_c *);
BX_SMF void RETnear16(bxInstruction_c *);
BX_SMF void MOV_EbIb(bxInstruction_c *);
@ -2371,11 +2381,16 @@ public: // for now...
BX_SMF void MOVSQ_XqYq(bxInstruction_c *);
BX_SMF void CMPSQ_XqYq(bxInstruction_c *);
BX_SMF void STOSQ_YqRAX(bxInstruction_c *);
BX_SMF void LODSQ_RAXXq(bxInstruction_c *);
BX_SMF void SCASQ_RAXXq(bxInstruction_c *);
BX_SMF void REP_MOVSQ_XqYq(bxInstruction_c *);
BX_SMF void REP_CMPSQ_XqYq(bxInstruction_c *);
BX_SMF void REP_STOSQ_YqRAX(bxInstruction_c *);
BX_SMF void REP_LODSQ_RAXXq(bxInstruction_c *);
BX_SMF void REP_SCASQ_RAXXq(bxInstruction_c *);
BX_SMF void RETnear64(bxInstruction_c *);
BX_SMF void ENTER64_IwIb(bxInstruction_c *);
BX_SMF void LEAVE64(bxInstruction_c *);
@ -2735,6 +2750,9 @@ public: // for now...
Bit16u port, Bit32u wordCount);
#endif
BX_SMF void repeat(bxInstruction_c *i, BxExecutePtr_t execute);
BX_SMF void repeat_ZFL(bxInstruction_c *i, BxExecutePtr_t execute);
BX_SMF void access_linear(bx_address address, unsigned length, unsigned pl,
unsigned rw, void *data) BX_CPP_AttrRegparmN(3);
BX_SMF bx_phy_address translate_linear(bx_address laddr,
@ -3324,9 +3342,6 @@ IMPLEMENT_EFLAG_ACCESSOR (TF, 8)
#define BxLockable 0x0200 // bit 9
#define Bx3ByteOpcode 0x0400 // bit 10
#define BxRepeatable 0x0800 // bit 11 (pass through to metaInfo field)
#define BxRepeatableZF 0x1000 // bit 12 (pass through to metaInfo field)
#define BxGroup1 BxGroupN
#define BxGroup2 BxGroupN
#define BxGroup3 BxGroupN

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode.cc,v 1.98 2006-06-09 22:29:07 sshwarts Exp $
// $Id: fetchdecode.cc,v 1.99 2007-01-05 13:40:46 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -508,10 +508,10 @@ static const BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
/* 69 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::IMUL_GwEwIw },
/* 6A */ { BxImmediate_Ib_SE, &BX_CPU_C::PUSH_Iw },
/* 6B */ { BxAnother | BxImmediate_Ib_SE, &BX_CPU_C::IMUL_GwEwIw },
/* 6C */ { BxRepeatable, &BX_CPU_C::INSB_YbDX },
/* 6D */ { BxRepeatable, &BX_CPU_C::INSW_YwDX },
/* 6E */ { BxRepeatable, &BX_CPU_C::OUTSB_DXXb },
/* 6F */ { BxRepeatable, &BX_CPU_C::OUTSW_DXXw },
/* 6C */ { 0, &BX_CPU_C::REP_INSB_YbDX },
/* 6D */ { 0, &BX_CPU_C::REP_INSW_YwDX },
/* 6E */ { 0, &BX_CPU_C::REP_OUTSB_DXXb },
/* 6F */ { 0, &BX_CPU_C::REP_OUTSW_DXXw },
/* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
/* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
/* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
@ -564,18 +564,18 @@ static const BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
/* A1 */ { BxImmediate_O, &BX_CPU_C::MOV_AXOw },
/* A2 */ { BxImmediate_O, &BX_CPU_C::MOV_ObAL },
/* A3 */ { BxImmediate_O, &BX_CPU_C::MOV_OwAX },
/* A4 */ { BxRepeatable, &BX_CPU_C::MOVSB_XbYb },
/* A5 */ { BxRepeatable, &BX_CPU_C::MOVSW_XwYw },
/* A6 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSB_XbYb },
/* A7 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSW_XwYw },
/* A4 */ { 0, &BX_CPU_C::REP_MOVSB_XbYb },
/* A5 */ { 0, &BX_CPU_C::REP_MOVSW_XwYw },
/* A6 */ { 0, &BX_CPU_C::REP_CMPSB_XbYb },
/* A7 */ { 0, &BX_CPU_C::REP_CMPSW_XwYw },
/* A8 */ { BxImmediate_Ib, &BX_CPU_C::TEST_ALIb },
/* A9 */ { BxImmediate_Iv, &BX_CPU_C::TEST_AXIw },
/* AA */ { BxRepeatable, &BX_CPU_C::STOSB_YbAL },
/* AB */ { BxRepeatable, &BX_CPU_C::STOSW_YwAX },
/* AC */ { BxRepeatable, &BX_CPU_C::LODSB_ALXb },
/* AD */ { BxRepeatable, &BX_CPU_C::LODSW_AXXw },
/* AE */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASB_ALXb },
/* AF */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASW_AXXw },
/* AA */ { 0, &BX_CPU_C::REP_STOSB_YbAL },
/* AB */ { 0, &BX_CPU_C::REP_STOSW_YwAX },
/* AC */ { 0, &BX_CPU_C::REP_LODSB_ALXb },
/* AD */ { 0, &BX_CPU_C::REP_LODSW_AXXw },
/* AE */ { 0, &BX_CPU_C::REP_SCASB_ALXb },
/* AF */ { 0, &BX_CPU_C::REP_SCASW_AXXw },
/* B0 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
/* B1 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
/* B2 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
@ -1066,10 +1066,10 @@ static const BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
/* 69 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::IMUL_GdEdId },
/* 6A */ { BxImmediate_Ib_SE, &BX_CPU_C::PUSH_Id },
/* 6B */ { BxAnother | BxImmediate_Ib_SE, &BX_CPU_C::IMUL_GdEdId },
/* 6C */ { BxRepeatable, &BX_CPU_C::INSB_YbDX },
/* 6D */ { BxRepeatable, &BX_CPU_C::INSD_YdDX },
/* 6E */ { BxRepeatable, &BX_CPU_C::OUTSB_DXXb },
/* 6F */ { BxRepeatable, &BX_CPU_C::OUTSD_DXXd },
/* 6C */ { 0, &BX_CPU_C::REP_INSB_YbDX },
/* 6D */ { 0, &BX_CPU_C::REP_INSD_YdDX },
/* 6E */ { 0, &BX_CPU_C::REP_OUTSB_DXXb },
/* 6F */ { 0, &BX_CPU_C::REP_OUTSD_DXXd },
/* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
/* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
/* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
@ -1122,18 +1122,18 @@ static const BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
/* A1 */ { BxImmediate_O, &BX_CPU_C::MOV_EAXOd },
/* A2 */ { BxImmediate_O, &BX_CPU_C::MOV_ObAL },
/* A3 */ { BxImmediate_O, &BX_CPU_C::MOV_OdEAX },
/* A4 */ { BxRepeatable, &BX_CPU_C::MOVSB_XbYb },
/* A5 */ { BxRepeatable, &BX_CPU_C::MOVSD_XdYd },
/* A6 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSB_XbYb },
/* A7 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSD_XdYd },
/* A4 */ { 0, &BX_CPU_C::REP_MOVSB_XbYb },
/* A5 */ { 0, &BX_CPU_C::REP_MOVSD_XdYd },
/* A6 */ { 0, &BX_CPU_C::REP_CMPSB_XbYb },
/* A7 */ { 0, &BX_CPU_C::REP_CMPSD_XdYd },
/* A8 */ { BxImmediate_Ib, &BX_CPU_C::TEST_ALIb },
/* A9 */ { BxImmediate_Iv, &BX_CPU_C::TEST_EAXId },
/* AA */ { BxRepeatable, &BX_CPU_C::STOSB_YbAL },
/* AB */ { BxRepeatable, &BX_CPU_C::STOSD_YdEAX },
/* AC */ { BxRepeatable, &BX_CPU_C::LODSB_ALXb },
/* AD */ { BxRepeatable, &BX_CPU_C::LODSD_EAXXd },
/* AE */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASB_ALXb },
/* AF */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASD_EAXXd },
/* AA */ { 0, &BX_CPU_C::REP_STOSB_YbAL },
/* AB */ { 0, &BX_CPU_C::REP_STOSD_YdEAX },
/* AC */ { 0, &BX_CPU_C::REP_LODSB_ALXb },
/* AD */ { 0, &BX_CPU_C::REP_LODSD_EAXXd },
/* AE */ { 0, &BX_CPU_C::REP_SCASB_ALXb },
/* AF */ { 0, &BX_CPU_C::REP_SCASD_EAXXd },
/* B0 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
/* B1 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
/* B2 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
@ -1641,7 +1641,6 @@ fetch_b1:
}
attr = BxOpcodeInfo[b1+offset].Attr;
instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
#if BX_SUPPORT_SSE >= 4
// handle 3-byte escape
@ -1863,7 +1862,6 @@ modrm_done:
}
instruction->execute = OpcodeInfoPtr->ExecutePtr;
instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
}
else {
// Opcode does not require a MODRM byte.

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode64.cc,v 1.100 2006-08-11 17:23:36 sshwarts Exp $
// $Id: fetchdecode64.cc,v 1.101 2007-01-05 13:40:46 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -660,10 +660,10 @@ static const BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
/* 69 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::IMUL_GwEwIw },
/* 6A */ { BxImmediate_Ib_SE, &BX_CPU_C::PUSH_Iw },
/* 6B */ { BxAnother | BxImmediate_Ib_SE, &BX_CPU_C::IMUL_GwEwIw },
/* 6C */ { BxRepeatable, &BX_CPU_C::INSB_YbDX },
/* 6D */ { BxRepeatable, &BX_CPU_C::INSW_YwDX },
/* 6E */ { BxRepeatable, &BX_CPU_C::OUTSB_DXXb },
/* 6F */ { BxRepeatable, &BX_CPU_C::OUTSW_DXXw },
/* 6C */ { 0, &BX_CPU_C::REP_INSB_YbDX },
/* 6D */ { 0, &BX_CPU_C::REP_INSW_YwDX },
/* 6E */ { 0, &BX_CPU_C::REP_OUTSB_DXXb },
/* 6F */ { 0, &BX_CPU_C::REP_OUTSW_DXXw },
/* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq },
/* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq },
/* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq },
@ -716,18 +716,18 @@ static const BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
/* A1 */ { BxImmediate_O, &BX_CPU_C::MOV_AXOq },
/* A2 */ { BxImmediate_O, &BX_CPU_C::MOV_OqAL },
/* A3 */ { BxImmediate_O, &BX_CPU_C::MOV_OqAX },
/* A4 */ { BxRepeatable, &BX_CPU_C::MOVSB_XbYb },
/* A5 */ { BxRepeatable, &BX_CPU_C::MOVSW_XwYw },
/* A6 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSB_XbYb },
/* A7 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSW_XwYw },
/* A4 */ { 0, &BX_CPU_C::REP_MOVSB_XbYb },
/* A5 */ { 0, &BX_CPU_C::REP_MOVSW_XwYw },
/* A6 */ { 0, &BX_CPU_C::REP_CMPSB_XbYb },
/* A7 */ { 0, &BX_CPU_C::REP_CMPSW_XwYw },
/* A8 */ { BxImmediate_Ib, &BX_CPU_C::TEST_ALIb },
/* A9 */ { BxImmediate_Iv, &BX_CPU_C::TEST_AXIw },
/* AA */ { BxRepeatable, &BX_CPU_C::STOSB_YbAL },
/* AB */ { BxRepeatable, &BX_CPU_C::STOSW_YwAX },
/* AC */ { BxRepeatable, &BX_CPU_C::LODSB_ALXb },
/* AD */ { BxRepeatable, &BX_CPU_C::LODSW_AXXw },
/* AE */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASB_ALXb },
/* AF */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASW_AXXw },
/* AA */ { 0, &BX_CPU_C::REP_STOSB_YbAL },
/* AB */ { 0, &BX_CPU_C::REP_STOSW_YwAX },
/* AC */ { 0, &BX_CPU_C::REP_LODSB_ALXb },
/* AD */ { 0, &BX_CPU_C::REP_LODSW_AXXw },
/* AE */ { 0, &BX_CPU_C::REP_SCASB_ALXb },
/* AF */ { 0, &BX_CPU_C::REP_SCASW_AXXw },
/* B0 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
/* B1 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
/* B2 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
@ -1189,10 +1189,10 @@ static const BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
/* 69 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::IMUL_GdEdId },
/* 6A */ { BxImmediate_Ib_SE, &BX_CPU_C::PUSH64_Id },
/* 6B */ { BxAnother | BxImmediate_Ib_SE, &BX_CPU_C::IMUL_GdEdId },
/* 6C */ { BxRepeatable, &BX_CPU_C::INSB_YbDX },
/* 6D */ { BxRepeatable, &BX_CPU_C::INSD_YdDX },
/* 6E */ { BxRepeatable, &BX_CPU_C::OUTSB_DXXb },
/* 6F */ { BxRepeatable, &BX_CPU_C::OUTSD_DXXd },
/* 6C */ { 0, &BX_CPU_C::REP_INSB_YbDX },
/* 6D */ { 0, &BX_CPU_C::REP_INSD_YdDX },
/* 6E */ { 0, &BX_CPU_C::REP_OUTSB_DXXb },
/* 6F */ { 0, &BX_CPU_C::REP_OUTSD_DXXd },
/* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq },
/* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq },
/* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq },
@ -1245,18 +1245,18 @@ static const BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
/* A1 */ { BxImmediate_O, &BX_CPU_C::MOV_EAXOq },
/* A2 */ { BxImmediate_O, &BX_CPU_C::MOV_OqAL },
/* A3 */ { BxImmediate_O, &BX_CPU_C::MOV_OqEAX },
/* A4 */ { BxRepeatable, &BX_CPU_C::MOVSB_XbYb },
/* A5 */ { BxRepeatable, &BX_CPU_C::MOVSD_XdYd },
/* A6 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSB_XbYb },
/* A7 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSD_XdYd },
/* A4 */ { 0, &BX_CPU_C::REP_MOVSB_XbYb },
/* A5 */ { 0, &BX_CPU_C::REP_MOVSD_XdYd },
/* A6 */ { 0, &BX_CPU_C::REP_CMPSB_XbYb },
/* A7 */ { 0, &BX_CPU_C::REP_CMPSD_XdYd },
/* A8 */ { BxImmediate_Ib, &BX_CPU_C::TEST_ALIb },
/* A9 */ { BxImmediate_Iv, &BX_CPU_C::TEST_EAXId },
/* AA */ { BxRepeatable, &BX_CPU_C::STOSB_YbAL },
/* AB */ { BxRepeatable, &BX_CPU_C::STOSD_YdEAX },
/* AC */ { BxRepeatable, &BX_CPU_C::LODSB_ALXb },
/* AD */ { BxRepeatable, &BX_CPU_C::LODSD_EAXXd },
/* AE */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASB_ALXb },
/* AF */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASD_EAXXd },
/* AA */ { 0, &BX_CPU_C::REP_STOSB_YbAL },
/* AB */ { 0, &BX_CPU_C::REP_STOSD_YdEAX },
/* AC */ { 0, &BX_CPU_C::REP_LODSB_ALXb },
/* AD */ { 0, &BX_CPU_C::REP_LODSD_EAXXd },
/* AE */ { 0, &BX_CPU_C::REP_SCASB_ALXb },
/* AF */ { 0, &BX_CPU_C::REP_SCASD_EAXXd },
/* B0 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
/* B1 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
/* B2 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
@ -1718,10 +1718,10 @@ static const BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
/* 69 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::IMUL_GqEqId },
/* 6A */ { BxImmediate_Ib_SE, &BX_CPU_C::PUSH64_Id },
/* 6B */ { BxAnother | BxImmediate_Ib_SE, &BX_CPU_C::IMUL_GqEqId },
/* 6C */ { BxRepeatable, &BX_CPU_C::INSB_YbDX },
/* 6D */ { BxRepeatable, &BX_CPU_C::INSD_YdDX },
/* 6E */ { BxRepeatable, &BX_CPU_C::OUTSB_DXXb },
/* 6F */ { BxRepeatable, &BX_CPU_C::OUTSD_DXXd },
/* 6C */ { 0, &BX_CPU_C::REP_INSB_YbDX },
/* 6D */ { 0, &BX_CPU_C::REP_INSD_YdDX },
/* 6E */ { 0, &BX_CPU_C::REP_OUTSB_DXXb },
/* 6F */ { 0, &BX_CPU_C::REP_OUTSD_DXXd },
/* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq },
/* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq },
/* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jq },
@ -1774,18 +1774,18 @@ static const BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
/* A1 */ { BxImmediate_O, &BX_CPU_C::MOV_RAXOq },
/* A2 */ { BxImmediate_O, &BX_CPU_C::MOV_OqAL },
/* A3 */ { BxImmediate_O, &BX_CPU_C::MOV_OqRAX },
/* A4 */ { BxRepeatable, &BX_CPU_C::MOVSB_XbYb },
/* A5 */ { BxRepeatable, &BX_CPU_C::MOVSQ_XqYq },
/* A6 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSB_XbYb },
/* A7 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSQ_XqYq },
/* A4 */ { 0, &BX_CPU_C::REP_MOVSB_XbYb },
/* A5 */ { 0, &BX_CPU_C::REP_MOVSQ_XqYq },
/* A6 */ { 0, &BX_CPU_C::REP_CMPSB_XbYb },
/* A7 */ { 0, &BX_CPU_C::REP_CMPSQ_XqYq },
/* A8 */ { BxImmediate_Ib, &BX_CPU_C::TEST_ALIb },
/* A9 */ { BxImmediate_Iv, &BX_CPU_C::TEST_RAXId },
/* AA */ { BxRepeatable, &BX_CPU_C::STOSB_YbAL },
/* AB */ { BxRepeatable, &BX_CPU_C::STOSQ_YqRAX },
/* AC */ { BxRepeatable, &BX_CPU_C::LODSB_ALXb },
/* AD */ { BxRepeatable, &BX_CPU_C::LODSQ_RAXXq },
/* AE */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASB_ALXb },
/* AF */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASQ_RAXXq },
/* AA */ { 0, &BX_CPU_C::REP_STOSB_YbAL },
/* AB */ { 0, &BX_CPU_C::REP_STOSQ_YqRAX },
/* AC */ { 0, &BX_CPU_C::REP_LODSB_ALXb },
/* AD */ { 0, &BX_CPU_C::REP_LODSQ_RAXXq },
/* AE */ { 0, &BX_CPU_C::REP_SCASB_ALXb },
/* AF */ { 0, &BX_CPU_C::REP_SCASQ_RAXXq },
/* B0 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
/* B1 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
/* B2 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
@ -2276,7 +2276,6 @@ fetch_b1:
}
attr = BxOpcodeInfo64[b1+offset].Attr;
instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
#if BX_SUPPORT_SSE >= 4
// handle 3-byte escape
@ -2553,7 +2552,6 @@ modrm_done:
}
instruction->execute = OpcodeInfoPtr->ExecutePtr;
instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
}
else {
// Opcode does not require a MODRM byte.

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: io.cc,v 1.36 2006-08-01 17:09:05 vruppert Exp $
// $Id: io.cc,v 1.37 2007-01-05 13:40:47 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -39,6 +39,10 @@
#define RAX EAX
#endif
//
// Repeat Speedups methods
//
#if BX_SupportRepeatSpeedups
Bit32u BX_CPU_C::FastRepINSW(bxInstruction_c *i, bx_address dstOff, Bit16u port, Bit32u wordCount)
{
@ -281,6 +285,29 @@ Bit32u BX_CPU_C::FastRepOUTSW(bxInstruction_c *i, unsigned srcSeg, bx_address sr
#endif
//
// REP INS methods
//
void BX_CPU_C::REP_INSB_YbDX(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::INSB_YbDX);
}
void BX_CPU_C::REP_INSW_YwDX(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::INSW_YwDX);
}
void BX_CPU_C::REP_INSD_YdDX(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::INSD_YdDX);
}
//
// INSB/INSW/INSD methods
//
void BX_CPU_C::INSB_YbDX(bxInstruction_c *i)
{
Bit8u value8=0;
@ -502,6 +529,29 @@ void BX_CPU_C::INSD_YdDX(bxInstruction_c *i)
}
}
//
// REP OUTS methods
//
void BX_CPU_C::REP_OUTSB_DXXb(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::OUTSB_DXXb);
}
void BX_CPU_C::REP_OUTSW_DXXw(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::OUTSW_DXXw);
}
void BX_CPU_C::REP_OUTSD_DXXd(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::OUTSD_DXXd);
}
//
// OUTSB/OUTSW/OUTSD methods
//
void BX_CPU_C::OUTSB_DXXb(bxInstruction_c *i)
{
Bit8u value8;
@ -701,6 +751,10 @@ void BX_CPU_C::OUTSD_DXXd(bxInstruction_c *i)
}
}
//
// non repeatable IN/OUT methods
//
void BX_CPU_C::IN_ALIb(bxInstruction_c *i)
{
AL = BX_CPU_THIS_PTR inp8(i->Ib());

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: string.cc,v 1.35 2006-05-24 20:57:37 sshwarts Exp $
// $Id: string.cc,v 1.36 2007-01-05 13:40:47 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -38,6 +38,9 @@
#define RAX EAX
#endif
//
// Repeat Speedups methods
//
#if BX_SupportRepeatSpeedups
Bit32u BX_CPU_C::FastRepMOVSB(bxInstruction_c *i, unsigned srcSeg, bx_address srcOff, unsigned dstSeg, bx_address dstOff, Bit32u count)
@ -739,6 +742,35 @@ Bit32u BX_CPU_C::FastRepSTOSD(bxInstruction_c *i, unsigned dstSeg, bx_address ds
}
#endif
//
// REP MOVS methods
//
void BX_CPU_C::REP_MOVSB_XbYb(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::MOVSB_XbYb);
}
void BX_CPU_C::REP_MOVSW_XwYw(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::MOVSW_XwYw);
}
void BX_CPU_C::REP_MOVSD_XdYd(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::MOVSD_XdYd);
}
#if BX_SUPPORT_X86_64
void BX_CPU_C::REP_MOVSQ_XqYq(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::MOVSQ_XqYq);
}
#endif
//
// MOVSB/MOVSW/MOVSD/MOVSQ methods
//
/* MOVSB ES:[EDI], DS:[ESI] DS may be overridden
* mov string from DS:[ESI] into ES:[EDI]
@ -1121,6 +1153,36 @@ void BX_CPU_C::MOVSQ_XqYq(bxInstruction_c *i)
#endif
//
// REP CMPS methods
//
void BX_CPU_C::REP_CMPSB_XbYb(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSB_XbYb);
}
void BX_CPU_C::REP_CMPSW_XwYw(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSW_XwYw);
}
void BX_CPU_C::REP_CMPSD_XdYd(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSD_XdYd);
}
#if BX_SUPPORT_X86_64
void BX_CPU_C::REP_CMPSQ_XqYq(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSQ_XqYq);
}
#endif
//
// CMPSB/CMPSW/CMPSD/CMPSQ methods
//
void BX_CPU_C::CMPSB_XbYb(bxInstruction_c *i)
{
Bit8u op1_8, op2_8, diff_8;
@ -1423,6 +1485,36 @@ void BX_CPU_C::CMPSQ_XqYq(bxInstruction_c *i)
#endif
//
// REP SCAS methods
//
void BX_CPU_C::REP_SCASB_ALXb(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASB_ALXb);
}
void BX_CPU_C::REP_SCASW_AXXw(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASW_AXXw);
}
void BX_CPU_C::REP_SCASD_EAXXd(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASD_EAXXd);
}
#if BX_SUPPORT_X86_64
void BX_CPU_C::REP_SCASQ_RAXXq(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASQ_RAXXq);
}
#endif
//
// SCASB/SCASW/SCASD/SCASQ methods
//
void BX_CPU_C::SCASB_ALXb(bxInstruction_c *i)
{
Bit8u op1_8 = AL, op2_8, diff_8;
@ -1661,6 +1753,36 @@ void BX_CPU_C::SCASQ_RAXXq(bxInstruction_c *i)
#endif
//
// REP STOS methods
//
void BX_CPU_C::REP_STOSB_YbAL(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::STOSB_YbAL);
}
void BX_CPU_C::REP_STOSW_YwAX(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::STOSW_YwAX);
}
void BX_CPU_C::REP_STOSD_YdEAX(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::STOSD_YdEAX);
}
#if BX_SUPPORT_X86_64
void BX_CPU_C::REP_STOSQ_YqRAX(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::STOSQ_YqRAX);
}
#endif
//
// STOSB/STOSW/STOSD/STOSQ methods
//
void BX_CPU_C::STOSB_YbAL(bxInstruction_c *i)
{
Bit8u al = AL;
@ -1906,6 +2028,36 @@ void BX_CPU_C::STOSQ_YqRAX(bxInstruction_c *i)
#endif
//
// REP LODS methods
//
void BX_CPU_C::REP_LODSB_ALXb(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::LODSB_ALXb);
}
void BX_CPU_C::REP_LODSW_AXXw(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::LODSW_AXXw);
}
void BX_CPU_C::REP_LODSD_EAXXd(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::LODSD_EAXXd);
}
#if BX_SUPPORT_X86_64
void BX_CPU_C::REP_LODSQ_RAXXq(bxInstruction_c *i)
{
BX_CPU_THIS_PTR repeat(i, &BX_CPU_C::LODSQ_RAXXq);
}
#endif
//
// LODSB/LODSW/LODSD/LODSQ methods
//
void BX_CPU_C::LODSB_ALXb(bxInstruction_c *i)
{
Bit8u al;