diff --git a/bochs/bochs.h b/bochs/bochs.h index b389880b6..f1595238d 100644 --- a/bochs/bochs.h +++ b/bochs/bochs.h @@ -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 diff --git a/bochs/cpu/cpu.cc b/bochs/cpu/cpu.cc index 06766c708..d12ebb2be 100644 --- a/bochs/cpu/cpu.cc +++ b/bochs/cpu/cpu.cc @@ -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) { // diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 0f4da17ea..a2d6ea99d 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -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 diff --git a/bochs/cpu/fetchdecode.cc b/bochs/cpu/fetchdecode.cc index a619bed4f..7bfb6be5a 100644 --- a/bochs/cpu/fetchdecode.cc +++ b/bochs/cpu/fetchdecode.cc @@ -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. diff --git a/bochs/cpu/fetchdecode64.cc b/bochs/cpu/fetchdecode64.cc index 0eb68d04b..9c65232e4 100644 --- a/bochs/cpu/fetchdecode64.cc +++ b/bochs/cpu/fetchdecode64.cc @@ -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. diff --git a/bochs/cpu/io.cc b/bochs/cpu/io.cc index 36946159d..e477b4adf 100644 --- a/bochs/cpu/io.cc +++ b/bochs/cpu/io.cc @@ -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()); diff --git a/bochs/cpu/string.cc b/bochs/cpu/string.cc index a796e86e5..507258120 100644 --- a/bochs/cpu/string.cc +++ b/bochs/cpu/string.cc @@ -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;