Optimization of repeat string

This commit is contained in:
Stanislav Shwartsman 2008-10-08 20:15:37 +00:00
parent 0e66403a25
commit 17040303f7
4 changed files with 190 additions and 63 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: dbg_main.cc,v 1.161 2008-10-08 17:13:35 sshwarts Exp $
// $Id: dbg_main.cc,v 1.162 2008-10-08 20:15:37 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1602,8 +1602,6 @@ one_more:
// I must guard for ICOUNT or one CPU could run forever without giving
// the others a chance.
bx_guard.guard_for |= BX_DBG_GUARD_CTRL_C; // stop on Ctrl-C
for (cpu=0; cpu < BX_SMP_PROCESSORS; cpu++) {
BX_CPU(cpu)->guard_found.guard_found = 0;
BX_CPU(cpu)->guard_found.icount = 0;
@ -1690,9 +1688,6 @@ void bx_dbg_stepN_command(Bit32u count)
// is printed, we will return to config mode.
SIM->set_display_mode(DISP_MODE_SIM);
// single CPU
bx_guard.guard_for |= BX_DBG_GUARD_CTRL_C; // or Ctrl-C
// reset guard counters for all CPUs
int stop = 0;
for (unsigned cpu=0; cpu < BX_SMP_PROCESSORS; cpu++) {
@ -1788,7 +1783,7 @@ void bx_dbg_print_guard_results(void)
for (cpu=0; cpu<BX_SMP_PROCESSORS; cpu++) {
unsigned long found = BX_CPU(cpu)->guard_found.guard_found;
if (found & BX_DBG_GUARD_CTRL_C) { /* ... */ }
if (! found) { /* ... */ }
#if (BX_DBG_MAX_VIR_BPOINTS > 0)
else if (found & BX_DBG_GUARD_IADDR_VIR) {
i = BX_CPU(cpu)->guard_found.iaddr_index;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.244 2008-10-06 22:19:22 sshwarts Exp $
// $Id: cpu.cc,v 1.245 2008-10-08 20:15:37 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -291,15 +291,10 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat(bxInstruction_c *i, BxExecutePtr_tR
#endif
}
void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePtr_tR execute)
// repeat prefix 0xF2
void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxExecutePtr_tR execute)
{
// non repeated instruction
if (! i->repUsedL()) {
BX_CPU_CALL_METHOD(execute, (i));
return;
}
unsigned rep = i->repUsedValue();
BX_ASSERT(i->repUsedL()); // TRUE by design
#if BX_SUPPORT_X86_64
if (i->as64L()) {
@ -309,9 +304,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePt
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
RCX --;
}
if (rep==3 && get_ZF()==0) return;
if (rep==2 && get_ZF()!=0) return;
if (RCX == 0) return;
if (get_ZF() || RCX == 0) return;
#if BX_DEBUGGER == 0
if (BX_CPU_THIS_PTR async_event)
@ -330,9 +323,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePt
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
RCX = ECX - 1;
}
if (rep==3 && get_ZF()==0) return;
if (rep==2 && get_ZF()!=0) return;
if (ECX == 0) return;
if (get_ZF() || ECX == 0) return;
#if BX_DEBUGGER == 0
if (BX_CPU_THIS_PTR async_event)
@ -350,9 +341,80 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePt
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
CX --;
}
if (rep==3 && get_ZF()==0) return;
if (rep==2 && get_ZF()!=0) return;
if (CX == 0) return;
if (get_ZF() || CX == 0) return;
#if BX_DEBUGGER == 0
if (BX_CPU_THIS_PTR async_event)
#endif
break; // exit always if debugger enabled
BX_TICK1_IF_SINGLE_PROCESSOR();
}
}
RIP = BX_CPU_THIS_PTR prev_rip; // repeat loop not done, restore RIP
#if BX_SUPPORT_TRACE_CACHE
// assert magic async_event to stop trace execution
BX_CPU_THIS_PTR async_event |= BX_ASYNC_EVENT_STOP_TRACE;
#endif
}
// repeat prefix 0xF3
void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_NZF(bxInstruction_c *i, BxExecutePtr_tR execute)
{
// non repeated instruction
if (! i->repUsedL()) {
BX_CPU_CALL_METHOD(execute, (i));
return;
}
#if BX_SUPPORT_X86_64
if (i->as64L()) {
while(1) {
if (RCX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
RCX --;
}
if (! get_ZF() || RCX == 0) return;
#if BX_DEBUGGER == 0
if (BX_CPU_THIS_PTR async_event)
#endif
break; // exit always if debugger enabled
BX_TICK1_IF_SINGLE_PROCESSOR();
}
}
else
#endif
if (i->as32L()) {
while(1) {
if (ECX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
RCX = ECX - 1;
}
if (! get_ZF() || ECX == 0) return;
#if BX_DEBUGGER == 0
if (BX_CPU_THIS_PTR async_event)
#endif
break; // exit always if debugger enabled
BX_TICK1_IF_SINGLE_PROCESSOR();
}
}
else // 16bit addrsize
{
while(1) {
if (CX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
CX --;
}
if (! get_ZF() || CX == 0) return;
#if BX_DEBUGGER == 0
if (BX_CPU_THIS_PTR async_event)
@ -919,12 +981,9 @@ bx_bool BX_CPU_C::dbg_check_end_instr_bpoint(void)
return(1); // on a breakpoint
}
// convenient point to see if user typed Ctrl-C
if (bx_guard.interrupt_requested &&
(bx_guard.guard_for & BX_DBG_GUARD_CTRL_C))
{
BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_CTRL_C;
return(1); // Ctrl-C pressed
// convenient point to see if user requested debug break or typed Ctrl-C
if (bx_guard.interrupt_requested) {
return(1);
}
return(0); // no breakpoint

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.533 2008-10-08 11:14:35 sshwarts Exp $
// $Id: cpu.h,v 1.534 2008-10-08 20:15:37 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -3022,8 +3022,9 @@ public: // for now...
Bit16u port, Bit32u wordCount);
#endif
BX_SMF void repeat(bxInstruction_c *, BxExecutePtr_tR execute) BX_CPP_AttrRegparmN(2);
BX_SMF void repeat_ZFL(bxInstruction_c *, BxExecutePtr_tR execute) BX_CPP_AttrRegparmN(2);
BX_SMF void repeat(bxInstruction_c *i, BxExecutePtr_tR execute) BX_CPP_AttrRegparmN(2);
BX_SMF void repeat_ZF(bxInstruction_c *i, BxExecutePtr_tR execute) BX_CPP_AttrRegparmN(2);
BX_SMF void repeat_NZF(bxInstruction_c *i, BxExecutePtr_tR execute) BX_CPP_AttrRegparmN(2);
// linear address for access_linear expected to be canonical !
BX_SMF void access_read_linear(bx_address address, unsigned length, unsigned curr_pl,

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: string.cc,v 1.64 2008-09-08 20:47:33 sshwarts Exp $
// $Id: string.cc,v 1.65 2008-10-08 20:15:37 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -969,51 +969,81 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOVSQ64_XqYq(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_CMPSB_XbYb(bxInstruction_c *i)
{
#if BX_SUPPORT_X86_64
if (i->as64L())
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSB64_XbYb);
if (i->as64L()) {
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::CMPSB64_XbYb);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::CMPSB64_XbYb);
}
else
#endif
if (i->as32L()) {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSB32_XbYb);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::CMPSB32_XbYb);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::CMPSB32_XbYb);
BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RSI); // always clear upper part of RSI/RDI
BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RDI);
}
else {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSB16_XbYb);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::CMPSB16_XbYb);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::CMPSB16_XbYb);
}
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_CMPSW_XwYw(bxInstruction_c *i)
{
#if BX_SUPPORT_X86_64
if (i->as64L())
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSW64_XwYw);
if (i->as64L()) {
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::CMPSW64_XwYw);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::CMPSW64_XwYw);
}
else
#endif
if (i->as32L()) {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSW32_XwYw);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::CMPSW32_XwYw);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::CMPSW32_XwYw);
BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RSI); // always clear upper part of RSI/RDI
BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RDI);
}
else {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSW16_XwYw);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::CMPSW16_XwYw);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::CMPSW16_XwYw);
}
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_CMPSD_XdYd(bxInstruction_c *i)
{
#if BX_SUPPORT_X86_64
if (i->as64L())
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSD64_XdYd);
if (i->as64L()) {
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::CMPSD64_XdYd);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::CMPSD64_XdYd);
}
else
#endif
if (i->as32L()) {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSD32_XdYd);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::CMPSD32_XdYd);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::CMPSD32_XdYd);
BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RSI); // always clear upper part of RSI/RDI
BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RDI);
}
else {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSD16_XdYd);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::CMPSD16_XdYd);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::CMPSD16_XdYd);
}
}
@ -1021,10 +1051,16 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_CMPSD_XdYd(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_CMPSQ_XqYq(bxInstruction_c *i)
{
if (i->as64L()) {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSQ64_XqYq);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::CMPSQ64_XqYq);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::CMPSQ64_XqYq);
}
else {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::CMPSQ32_XqYq);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::CMPSQ32_XqYq);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::CMPSQ32_XqYq);
BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RSI); // always clear upper part of RSI/RDI
BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RDI);
}
@ -1362,48 +1398,78 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CMPSQ64_XqYq(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_SCASB_ALXb(bxInstruction_c *i)
{
#if BX_SUPPORT_X86_64
if (i->as64L())
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASB64_ALXb);
if (i->as64L()) {
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::SCASB64_ALXb);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::SCASB64_ALXb);
}
else
#endif
if (i->as32L()) {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASB32_ALXb);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::SCASB32_ALXb);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::SCASB32_ALXb);
BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RDI); // always clear upper part of RDI
}
else {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASB16_ALXb);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::SCASB16_ALXb);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::SCASB16_ALXb);
}
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_SCASW_AXXw(bxInstruction_c *i)
{
#if BX_SUPPORT_X86_64
if (i->as64L())
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASW64_AXXw);
if (i->as64L()) {
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::SCASW64_AXXw);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::SCASW64_AXXw);
}
else
#endif
if (i->as32L()) {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASW32_AXXw);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::SCASW32_AXXw);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::SCASW32_AXXw);
BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RDI); // always clear upper part of RDI
}
else {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASW16_AXXw);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::SCASW16_AXXw);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::SCASW16_AXXw);
}
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_SCASD_EAXXd(bxInstruction_c *i)
{
#if BX_SUPPORT_X86_64
if (i->as64L())
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASD64_EAXXd);
if (i->as64L()) {
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::SCASD64_EAXXd);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::SCASD64_EAXXd);
}
else
#endif
if (i->as32L()) {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASD32_EAXXd);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::SCASD32_EAXXd);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::SCASD32_EAXXd);
BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RDI); // always clear upper part of RDI
}
else {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASD16_EAXXd);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::SCASD16_EAXXd);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::SCASD16_EAXXd);
}
}
@ -1411,10 +1477,16 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_SCASD_EAXXd(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::REP_SCASQ_RAXXq(bxInstruction_c *i)
{
if (i->as64L()) {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASQ64_RAXXq);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::SCASQ64_RAXXq);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::SCASQ64_RAXXq);
}
else {
BX_CPU_THIS_PTR repeat_ZFL(i, &BX_CPU_C::SCASQ32_RAXXq);
if (i->repUsedValue() == 2)
BX_CPU_THIS_PTR repeat_ZF(i, &BX_CPU_C::SCASQ32_RAXXq);
else
BX_CPU_THIS_PTR repeat_NZF(i, &BX_CPU_C::SCASQ32_RAXXq);
BX_CLEAR_64BIT_HIGH(BX_64BIT_REG_RDI); // always clear upper part of RDI
}
}