Naturally speedup repeat execution functions, fix TLB index calculations

This commit is contained in:
Stanislav Shwartsman 2007-10-30 22:15:42 +00:00
parent afdcadad73
commit ce0e0287fb
4 changed files with 75 additions and 45 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: access.cc,v 1.75 2007-10-24 23:01:45 sshwarts Exp $
// $Id: access.cc,v 1.76 2007-10-30 22:15:41 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -31,12 +31,6 @@
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR
#if BX_SUPPORT_X86_64
#define LPFOf(laddr) ((laddr) & BX_CONST64(0xfffffffffffff000))
#else
#define LPFOf(laddr) ((laddr) & 0xfffff000)
#endif
void BX_CPP_AttrRegparmN(3)
BX_CPU_C::write_virtual_checks(bx_segment_reg_t *seg, bx_address offset, unsigned length)
{

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.176 2007-10-14 19:04:49 sshwarts Exp $
// $Id: cpu.cc,v 1.177 2007-10-30 22:15:42 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -306,42 +306,60 @@ void BX_CPU_C::repeat(bxInstruction_c *i, BxExecutePtr_t execute)
return;
}
while(1) {
#if BX_SUPPORT_X86_64
if (i->as64L()) {
if (i->as64L()) {
while(1) {
if (RCX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
RCX --;
}
if (RCX == 0) return;
}
else
BX_TICK1_IF_SINGLE_PROCESSOR();
#if BX_DEBUGGER == 0
if (BX_CPU_THIS_PTR async_event)
#endif
if (i->as32L()) {
break; // exit always if debugger enabled
}
}
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 (ECX == 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
}
else { // 16bit addrsize
}
else // 16bit addrsize
{
while(1) {
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();
BX_TICK1_IF_SINGLE_PROCESSOR();
#if BX_DEBUGGER == 0
if (BX_CPU_THIS_PTR async_event)
if (BX_CPU_THIS_PTR async_event)
#endif
break; // exit always if debugger enabled
break; // exit always if debugger enabled
}
}
RIP = BX_CPU_THIS_PTR prev_eip; // repeat loop not done, restore RIP
@ -355,10 +373,9 @@ void BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePtr_t execute)
return;
}
while(1) {
#if BX_SUPPORT_X86_64
if (i->as64L()) {
if (i->as64L()) {
while(1) {
if (RCX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
@ -367,10 +384,19 @@ void BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePtr_t execute)
if ((i->repUsedValue()==3) && (get_ZF()==0)) return;
if ((i->repUsedValue()==2) && (get_ZF()!=0)) return;
if (RCX == 0) return;
}
else
BX_TICK1_IF_SINGLE_PROCESSOR();
#if BX_DEBUGGER == 0
if (BX_CPU_THIS_PTR async_event)
#endif
if (i->as32L()) {
break; // exit always if debugger enabled
}
}
else
#endif
if (i->as32L()) {
while(1) {
if (ECX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
@ -379,8 +405,18 @@ void BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePtr_t execute)
if ((i->repUsedValue()==3) && (get_ZF()==0)) return;
if ((i->repUsedValue()==2) && (get_ZF()!=0)) return;
if (ECX == 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
}
else {
}
else // 16bit addrsize
{
while(1) {
if (CX != 0) {
BX_CPU_CALL_METHOD(execute, (i));
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
@ -389,14 +425,14 @@ void BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePtr_t execute)
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();
BX_TICK1_IF_SINGLE_PROCESSOR();
#if BX_DEBUGGER == 0
if (BX_CPU_THIS_PTR async_event)
if (BX_CPU_THIS_PTR async_event)
#endif
break; // exit always if debugger enabled
break; // exit always if debugger enabled
}
}
RIP = BX_CPU_THIS_PTR prev_eip; // repeat loop not done, restore RIP

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.343 2007-10-24 23:02:09 sshwarts Exp $
// $Id: cpu.h,v 1.344 2007-10-30 22:15:42 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1216,6 +1216,7 @@ public: // for now...
// for paging
#if BX_USE_TLB
struct {
bx_TLB_entry entry[BX_TLB_SIZE] BX_CPP_AlignN(16);
@ -1226,6 +1227,13 @@ public: // for now...
# define BX_TLB_LPF_VALUE(lpf) (lpf)
#endif
} TLB;
#if BX_SUPPORT_X86_64
#define LPFOf(laddr) ((laddr) & BX_CONST64(0xfffffffffffff000))
#else
#define LPFOf(laddr) ((laddr) & 0xfffff000)
#endif
#endif // #if BX_USE_TLB
// An instruction cache. Each entry should be exactly 32 bytes, and

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: paging.cc,v 1.87 2007-10-08 20:45:30 sshwarts Exp $
// $Id: paging.cc,v 1.88 2007-10-30 22:15:42 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -615,7 +615,6 @@ void BX_CPU_C::page_fault(unsigned fault, bx_address laddr, unsigned pl, unsigne
// Translate a linear address to a physical address
bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigned rw, unsigned access_type)
{
bx_address lpf;
Bit32u accessBits, combined_access = 0;
unsigned priv_index;
@ -625,19 +624,12 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigne
// note - we assume physical memory < 4gig so for brevity & speed, we'll use
// 32 bit entries although cr3 is expanded to 64 bits.
bx_phy_address paddress, ppf, poffset;
bx_bool isWrite = (rw >= BX_WRITE); // write or r-m-w
#if BX_SUPPORT_PAE
if (BX_CPU_THIS_PTR cr4.get_PAE())
lpf = laddr & BX_CONST64(0xfffffffffffff000); // linear page frame
else
#endif
lpf = laddr & 0xfffff000;
poffset = laddr & 0x00000fff; // physical offset
#if BX_USE_TLB
bx_address lpf = LPFOf(laddr);
Bit32u TLB_index = BX_TLB_INDEX_OF(lpf);
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[TLB_index];
@ -1066,7 +1058,7 @@ bx_bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy)
return 1;
}
bx_address lpf = laddr & BX_CONST64(0xfffffffffffff000); // linear page frame
bx_address lpf = LPFOf(laddr); // linear page frame
bx_address poffset = laddr & 0x00000fff; // physical offset
bx_phy_address paddress;
@ -1262,7 +1254,7 @@ BX_CPU_C::access_linear(bx_address laddr, unsigned length, unsigned pl,
#if BX_SupportGuest2HostTLB
Bit32u tlbIndex = BX_TLB_INDEX_OF(laddr);
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
Bit32u lpf = laddr & 0xfffff000;
bx_address lpf = LPFOf(laddr);
if (tlbEntry->lpf == BX_TLB_LPF_VALUE(lpf)) {
BX_CPU_THIS_PTR mem->readPhysicalPage(BX_CPU_THIS, laddr, length, data);
@ -1290,7 +1282,7 @@ BX_CPU_C::access_linear(bx_address laddr, unsigned length, unsigned pl,
}
else {
// Got direct write pointer OK. Mark for any operation to succeed.
tlbEntry->accessBits =(TLB_ReadSysOK | TLB_ReadUserOK | TLB_WriteSysOK | TLB_WriteUserOK |
tlbEntry->accessBits = (TLB_ReadSysOK | TLB_ReadUserOK | TLB_WriteSysOK | TLB_WriteUserOK |
TLB_ReadSysPtrOK | TLB_ReadUserPtrOK | TLB_WriteSysPtrOK | TLB_WriteUserPtrOK);
}
#endif // BX_SupportGuest2HostTLB
@ -1303,7 +1295,7 @@ BX_CPU_C::access_linear(bx_address laddr, unsigned length, unsigned pl,
#if BX_SupportGuest2HostTLB
Bit32u tlbIndex = BX_TLB_INDEX_OF(laddr);
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
Bit32u lpf = laddr & 0xfffff000;
bx_address lpf = LPFOf(laddr);
if (tlbEntry->lpf == BX_TLB_LPF_VALUE(lpf)) {
BX_CPU_THIS_PTR mem->writePhysicalPage(BX_CPU_THIS, laddr, length, data);