Try to optimize individual instructions after fetchdecode

This commit is contained in:
Stanislav Shwartsman 2008-09-16 19:20:03 +00:00
parent 7566faf948
commit a9c77eb75d
7 changed files with 461 additions and 22 deletions

View File

@ -83,7 +83,7 @@ OBJS = \
stack16.o \
protect_ctrl.o \
mult8.o \
data_xfer.o \
load32.o \
data_xfer8.o \
vm8086.o \
logical8.o \
@ -362,7 +362,7 @@ ctrl_xfer_pro.o: ctrl_xfer_pro.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
lazy_flags.h icache.h apic.h ../cpu/i387.h ../fpu/softfloat.h \
../config.h ../fpu/tag_w.h ../fpu/status_w.h ../fpu/control_w.h \
../cpu/xmm.h stack.h
data_xfer.o: data_xfer.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
load32.o: load32.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \
../gui/siminterface.h ../memory/memory.h ../pc_system.h ../plugin.h \
../extplugin.h ../gui/gui.h ../gui/textconfig.h ../config.h \

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.525 2008-09-16 18:28:53 sshwarts Exp $
// $Id: cpu.h,v 1.526 2008-09-16 19:20:02 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1676,10 +1676,19 @@ public: // for now...
BX_SMF void SMSW_EwM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LMSW_Ew(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
// service methods
// LOAD methods
BX_SMF void LOAD_Eb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOAD_Eb_Resolve16BaseIndex(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOAD_Eb_Resolve32Base(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOAD_Eb_Resolve32BaseIndex(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOAD_Ew(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOAD_Ed(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOAD_Ed_Resolve16BaseIndex(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOAD_Ed_Resolve32Base(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOAD_Ed_Resolve32BaseIndex(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
#if BX_SUPPORT_X86_64
BX_SMF void LOAD_Eq(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
#endif
@ -2712,7 +2721,6 @@ public: // for now...
BX_SMF void UndefinedOpcode(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void BxError(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF bx_address BxResolve16Disp(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF bx_address BxResolve16BaseIndex(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF bx_address BxResolve32Base(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF bx_address BxResolve32BaseIndex(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
@ -2751,8 +2759,10 @@ public: // for now...
BX_SMF unsigned handleAsyncEvent(void);
BX_SMF unsigned fetchDecode32(const Bit8u *fetchPtr, bxInstruction_c *i, unsigned remainingInPage) BX_CPP_AttrRegparmN(3);
BX_SMF void optimize32(bxInstruction_c *i, unsigned resolve) BX_CPP_AttrRegparmN(2);
#if BX_SUPPORT_X86_64
BX_SMF unsigned fetchDecode64(const Bit8u *fetchPtr, bxInstruction_c *i, unsigned remainingInPage) BX_CPP_AttrRegparmN(3);
BX_SMF void optimize64(bxInstruction_c *i, unsigned resolve) BX_CPP_AttrRegparmN(2);
#endif
BX_SMF bx_bool fetchInstruction(bxInstruction_c *iStorage, Bit32u eipBiased);
BX_SMF void boundaryFetch(const Bit8u *fetchPtr, unsigned remainingInPage, bxInstruction_c *);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode.cc,v 1.213 2008-09-16 18:28:53 sshwarts Exp $
// $Id: fetchdecode.cc,v 1.214 2008-09-16 19:20:02 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -2457,8 +2457,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo32M[512*2] = {
};
enum {
BX_RESOLVE16_DISPLACEMENT,
BX_RESOLVE16_BASE_INDEX,
BX_RESOLVE16,
BX_RESOLVE32_BASE,
BX_RESOLVE32_BASE_INDEX,
BX_RESOLVE_NONE
@ -2702,15 +2701,15 @@ fetch_b1:
}
else {
// 16-bit addressing modes, mod==11b handled above
resolve = BX_RESOLVE16_BASE_INDEX;
resolve = BX_RESOLVE16;
i->ResolveModrm = &BX_CPU_C::BxResolve16BaseIndex;
i->setSibBase(Resolve16BaseReg[rm]);
i->setSibIndex(Resolve16IndexReg[rm]);
if (mod == 0x00) { // mod == 00b
seg = sreg_mod00_rm16[rm];
if (rm == 0x06) {
resolve = BX_RESOLVE16_DISPLACEMENT;
i->ResolveModrm = &BX_CPU_C::BxResolve16Disp;
i->setSibBase(BX_NIL_REGISTER);
i->setSibIndex(BX_NIL_REGISTER);
if ((ilen+1) < remain) {
i->modRMForm.displ16u = FetchWORD(iptr);
iptr += 2;
@ -2972,9 +2971,44 @@ modrm_done:
i->ia_opcode = ia_opcode;
#endif
if (i->execute2 != NULL) {
optimize32(i, resolve);
}
return(1);
}
void BX_CPP_AttrRegparmN(2) BX_CPU_C::optimize32(bxInstruction_c *i, unsigned resolve)
{
// LOAD speedups
static const BxExecutePtr_tR BxTableLoad32_Eb[3] = {
&BX_CPU_C::LOAD_Eb_Resolve16BaseIndex,
&BX_CPU_C::LOAD_Eb_Resolve32Base,
&BX_CPU_C::LOAD_Eb_Resolve32BaseIndex
};
static const BxExecutePtr_tR BxTableLoad32_Ew[3] = {
&BX_CPU_C::LOAD_Ew,
&BX_CPU_C::LOAD_Ew,
&BX_CPU_C::LOAD_Ew
};
static const BxExecutePtr_tR BxTableLoad32_Ed[3] = {
&BX_CPU_C::LOAD_Ed_Resolve16BaseIndex,
&BX_CPU_C::LOAD_Ed_Resolve32Base,
&BX_CPU_C::LOAD_Ed_Resolve32BaseIndex
};
if (! BX_CPU_THIS_PTR alignment_check()) {
if (i->execute == &BX_CPU_C::LOAD_Eb)
i->execute = BxTableLoad32_Eb[resolve];
else if (i->execute == &BX_CPU_C::LOAD_Ew)
i->execute = BxTableLoad32_Ew[resolve];
else if (i->execute == &BX_CPU_C::LOAD_Ed)
i->execute = BxTableLoad32_Ed[resolve];
}
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::BxError(bxInstruction_c *i)
{
BX_DEBUG(("BxError: Encountered an unknown instruction b1=0x%02x (signalling #UD)", i->b1()));

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode64.cc,v 1.219 2008-09-16 18:28:53 sshwarts Exp $
// $Id: fetchdecode64.cc,v 1.220 2008-09-16 19:20:02 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -3860,4 +3860,9 @@ modrm_done:
return(1);
}
void BX_CPP_AttrRegparmN(2) BX_CPU_C::optimize64(bxInstruction_c *i, unsigned resolve)
{
// empty for now
}
#endif /* if BX_SUPPORT_X86_64 */

384
bochs/cpu/load32.cc Executable file
View File

@ -0,0 +1,384 @@
/////////////////////////////////////////////////////////////////////////
// $Id: load32.cc,v 1.1 2008-09-16 19:20:02 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008 Stanislav Shwartsman
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
/////////////////////////////////////////////////////////////////////////
#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Eb(bxInstruction_c *i)
{
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
TMP8L = read_virtual_byte(i->seg(), eaddr);
BX_CPU_CALL_METHOD(i->execute2, (i));
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Eb_Resolve16BaseIndex(bxInstruction_c *i)
{
Bit16u offset = BX_READ_16BIT_REG(i->sibBase()) + BX_READ_16BIT_REG(i->sibIndex()) + (Bit16s) i->displ16u();
Bit32u laddr;
unsigned s = i->seg();
bx_segment_reg_t *seg = &BX_CPU_THIS_PTR sregs[s];
BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID, s, offset, 1, BX_READ);
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64);
if (seg->cache.valid & SegAccessROK) {
if (offset <= seg->cache.u.segment.limit_scaled) {
accessOK:
laddr = BX_CPU_THIS_PTR get_laddr32(s, offset);
#if BX_SupportGuest2HostTLB
unsigned tlbIndex = BX_TLB_INDEX_OF(laddr, 0);
Bit32u lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
if (tlbEntry->lpf == lpf && ! (tlbEntry->accessBits & USER_PL)) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
BX_INSTR_LIN_ACCESS(BX_CPU_ID, laddr, tlbEntry->ppf | pageOffset, 1, BX_READ);
Bit8u *hostAddr = (Bit8u*) (hostPageAddr | pageOffset);
TMP8L = *hostAddr;
BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID, laddr,
tlbEntry->ppf | pageOffset, 1, CPL, BX_READ, (Bit8u*) &TMP8L);
}
else
#endif
{
access_read_linear(laddr, 1, CPL, BX_READ, (void *) &TMP8L);
}
BX_CPU_CALL_METHOD(i->execute2, (i));
return;
}
else {
BX_ERROR(("LOAD_Eb(): segment limit violation"));
exception(int_number(s), 0, 0);
}
}
if (!read_virtual_checks(seg, offset, 1))
exception(int_number(s), 0, 0);
goto accessOK;
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Eb_Resolve32Base(bxInstruction_c *i)
{
Bit32u offset = BX_READ_32BIT_REG(i->sibBase()) + (Bit32s) i->displ32u();
Bit32u laddr;
unsigned s = i->seg();
bx_segment_reg_t *seg = &BX_CPU_THIS_PTR sregs[s];
BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID, s, offset, 1, BX_READ);
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64);
if (seg->cache.valid & SegAccessROK) {
if (offset <= seg->cache.u.segment.limit_scaled) {
accessOK:
laddr = BX_CPU_THIS_PTR get_laddr32(s, offset);
#if BX_SupportGuest2HostTLB
unsigned tlbIndex = BX_TLB_INDEX_OF(laddr, 0);
Bit32u lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
if (tlbEntry->lpf == lpf && ! (tlbEntry->accessBits & USER_PL)) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
BX_INSTR_LIN_ACCESS(BX_CPU_ID, laddr, tlbEntry->ppf | pageOffset, 1, BX_READ);
Bit8u *hostAddr = (Bit8u*) (hostPageAddr | pageOffset);
TMP8L = *hostAddr;
BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID, laddr,
tlbEntry->ppf | pageOffset, 1, CPL, BX_READ, (Bit8u*) &TMP8L);
}
else
#endif
{
access_read_linear(laddr, 1, CPL, BX_READ, (void *) &TMP8L);
}
BX_CPU_CALL_METHOD(i->execute2, (i));
return;
}
else {
BX_ERROR(("LOAD_Eb(): segment limit violation"));
exception(int_number(s), 0, 0);
}
}
if (!read_virtual_checks(seg, offset, 1))
exception(int_number(s), 0, 0);
goto accessOK;
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Eb_Resolve32BaseIndex(bxInstruction_c *i)
{
Bit32u offset = BX_READ_32BIT_REG(i->sibBase()) + (BX_READ_32BIT_REG(i->sibIndex()) << i->sibScale()) + (Bit32s) i->displ32u();
Bit32u laddr;
unsigned s = i->seg();
bx_segment_reg_t *seg = &BX_CPU_THIS_PTR sregs[s];
BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID, s, offset, 1, BX_READ);
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64);
if (seg->cache.valid & SegAccessROK) {
if (offset <= seg->cache.u.segment.limit_scaled) {
accessOK:
laddr = BX_CPU_THIS_PTR get_laddr32(s, offset);
#if BX_SupportGuest2HostTLB
unsigned tlbIndex = BX_TLB_INDEX_OF(laddr, 0);
Bit32u lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
if (tlbEntry->lpf == lpf && ! (tlbEntry->accessBits & USER_PL)) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
BX_INSTR_LIN_ACCESS(BX_CPU_ID, laddr, tlbEntry->ppf | pageOffset, 1, BX_READ);
Bit8u *hostAddr = (Bit8u*) (hostPageAddr | pageOffset);
TMP8L = *hostAddr;
BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID, laddr,
tlbEntry->ppf | pageOffset, 1, CPL, BX_READ, (Bit8u*) &TMP8L);
}
else
#endif
{
access_read_linear(laddr, 1, CPL, BX_READ, (void *) &TMP8L);
}
BX_CPU_CALL_METHOD(i->execute2, (i));
return;
}
else {
BX_ERROR(("LOAD_Eb(): segment limit violation"));
exception(int_number(s), 0, 0);
}
}
if (!read_virtual_checks(seg, offset, 1))
exception(int_number(s), 0, 0);
goto accessOK;
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ew(bxInstruction_c *i)
{
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
TMP16 = read_virtual_word(i->seg(), eaddr);
BX_CPU_CALL_METHOD(i->execute2, (i));
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ed(bxInstruction_c *i)
{
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
TMP32 = read_virtual_dword(i->seg(), eaddr);
BX_CPU_CALL_METHOD(i->execute2, (i));
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ed_Resolve16BaseIndex(bxInstruction_c *i)
{
Bit16u offset = BX_READ_16BIT_REG(i->sibBase()) + BX_READ_16BIT_REG(i->sibIndex()) + (Bit16s) i->displ16u();
Bit32u laddr;
unsigned s = i->seg();
bx_segment_reg_t *seg = &BX_CPU_THIS_PTR sregs[s];
BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID, s, offset, 4, BX_READ);
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64);
if (seg->cache.valid & SegAccessROK) {
if (offset < (seg->cache.u.segment.limit_scaled-2)) {
accessOK:
laddr = BX_CPU_THIS_PTR get_laddr32(s, offset);
#if BX_SupportGuest2HostTLB
unsigned tlbIndex = BX_TLB_INDEX_OF(laddr, 3);
Bit32u lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
if (tlbEntry->lpf == lpf && ! (tlbEntry->accessBits & USER_PL)) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
BX_INSTR_LIN_ACCESS(BX_CPU_ID, laddr, tlbEntry->ppf | pageOffset, 4, BX_READ);
Bit32u *hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
ReadHostDWordFromLittleEndian(hostAddr, TMP32);
BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID, laddr,
tlbEntry->ppf | pageOffset, 4, CPL, BX_READ, (Bit8u*) &TMP32);
}
else
#endif
{
access_read_linear(laddr, 4, CPL, BX_READ, (void *) &TMP32);
}
BX_CPU_CALL_METHOD(i->execute2, (i));
return;
}
else {
BX_ERROR(("LOAD_Ed(): segment limit violation"));
exception(int_number(s), 0, 0);
}
}
if (!read_virtual_checks(seg, offset, 4))
exception(int_number(s), 0, 0);
goto accessOK;
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ed_Resolve32Base(bxInstruction_c *i)
{
Bit32u offset = BX_READ_32BIT_REG(i->sibBase()) + (Bit32s) i->displ32u();
Bit32u laddr;
unsigned s = i->seg();
bx_segment_reg_t *seg = &BX_CPU_THIS_PTR sregs[s];
BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID, s, offset, 4, BX_READ);
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64);
if (seg->cache.valid & SegAccessROK) {
if (offset < (seg->cache.u.segment.limit_scaled-2)) {
accessOK:
laddr = BX_CPU_THIS_PTR get_laddr32(s, offset);
#if BX_SupportGuest2HostTLB
unsigned tlbIndex = BX_TLB_INDEX_OF(laddr, 3);
Bit32u lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
if (tlbEntry->lpf == lpf && ! (tlbEntry->accessBits & USER_PL)) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
BX_INSTR_LIN_ACCESS(BX_CPU_ID, laddr, tlbEntry->ppf | pageOffset, 4, BX_READ);
Bit32u *hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
ReadHostDWordFromLittleEndian(hostAddr, TMP32);
BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID, laddr,
tlbEntry->ppf | pageOffset, 4, CPL, BX_READ, (Bit8u*) &TMP32);
}
else
#endif
{
access_read_linear(laddr, 4, CPL, BX_READ, (void *) &TMP32);
}
BX_CPU_CALL_METHOD(i->execute2, (i));
return;
}
else {
BX_ERROR(("LOAD_Ed(): segment limit violation"));
exception(int_number(s), 0, 0);
}
}
if (!read_virtual_checks(seg, offset, 4))
exception(int_number(s), 0, 0);
goto accessOK;
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ed_Resolve32BaseIndex(bxInstruction_c *i)
{
Bit32u offset = BX_READ_32BIT_REG(i->sibBase()) + (BX_READ_32BIT_REG(i->sibIndex()) << i->sibScale()) + (Bit32s) i->displ32u();
Bit32u laddr;
unsigned s = i->seg();
bx_segment_reg_t *seg = &BX_CPU_THIS_PTR sregs[s];
BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID, s, offset, 4, BX_READ);
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64);
if (seg->cache.valid & SegAccessROK) {
if (offset < (seg->cache.u.segment.limit_scaled-2)) {
accessOK:
laddr = BX_CPU_THIS_PTR get_laddr32(s, offset);
#if BX_SupportGuest2HostTLB
unsigned tlbIndex = BX_TLB_INDEX_OF(laddr, 3);
Bit32u lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
if (tlbEntry->lpf == lpf && !(tlbEntry->accessBits & USER_PL)) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
bx_hostpageaddr_t hostPageAddr = tlbEntry->hostPageAddr;
Bit32u pageOffset = PAGE_OFFSET(laddr);
BX_INSTR_LIN_ACCESS(BX_CPU_ID, laddr, tlbEntry->ppf | pageOffset, 4, BX_READ);
Bit32u *hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
ReadHostDWordFromLittleEndian(hostAddr, TMP32);
BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID, laddr,
tlbEntry->ppf | pageOffset, 4, CPL, BX_READ, (Bit8u*) &TMP32);
}
else
#endif
{
access_read_linear(laddr, 4, CPL, BX_READ, (void *) &TMP32);
}
BX_CPU_CALL_METHOD(i->execute2, (i));
return;
}
else {
BX_ERROR(("LOAD_Ed(): segment limit violation"));
exception(int_number(s), 0, 0);
}
}
if (!read_virtual_checks(seg, offset, 4))
exception(int_number(s), 0, 0);
goto accessOK;
}
#if BX_SUPPORT_X86_64
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Eq(bxInstruction_c *i)
{
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
TMP64 = read_virtual_qword_64(i->seg(), eaddr);
BX_CPU_CALL_METHOD(i->execute2, (i));
}
#endif
#if BX_SUPPORT_SSE >= 1
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Wdq(bxInstruction_c *i)
{
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
readVirtualDQwordAligned(i->seg(), eaddr, (Bit8u *)(&BX_READ_XMM_REG(BX_TMP_REGISTER)));
BX_CPU_CALL_METHOD(i->execute2, (i));
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Wss(bxInstruction_c *i)
{
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
Bit32u val_32 = read_virtual_dword(i->seg(), eaddr);
BX_WRITE_XMM_REG_LO_DWORD(BX_TMP_REGISTER, val_32);
BX_CPU_CALL_METHOD(i->execute2, (i));
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Wsd(bxInstruction_c *i)
{
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
Bit64u val_64 = read_virtual_qword(i->seg(), eaddr);
BX_WRITE_XMM_REG_LO_QWORD(BX_TMP_REGISTER, val_64);
BX_CPU_CALL_METHOD(i->execute2, (i));
}
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.259 2008-09-08 20:47:33 sshwarts Exp $
// $Id: proc_ctrl.cc,v 1.260 2008-09-16 19:20:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1149,11 +1149,22 @@ void BX_CPU_C::handleCpuModeChange(void)
void BX_CPU_C::handleAlignmentCheck(void)
{
if (CPL == 3 && BX_CPU_THIS_PTR cr0.get_AM() && BX_CPU_THIS_PTR get_AC()) {
BX_CPU_THIS_PTR alignment_check_mask = 0xF;
BX_INFO(("Enable alignment check (#AC exception)"));
if (BX_CPU_THIS_PTR alignment_check_mask == 0) {
BX_CPU_THIS_PTR alignment_check_mask = 0xF;
BX_INFO(("Enable alignment check (#AC exception)"));
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.flushICacheEntries();
#endif
}
}
else {
BX_CPU_THIS_PTR alignment_check_mask = 0;
if (BX_CPU_THIS_PTR alignment_check_mask != 0) {
BX_CPU_THIS_PTR alignment_check_mask = 0;
BX_INFO(("Disable alignment check (#AC exception)"));
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.flushICacheEntries();
#endif
}
}
}
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: resolve.cc,v 1.4 2008-08-08 09:22:48 sshwarts Exp $
// $Id: resolve.cc,v 1.5 2008-09-16 19:20:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008 Stanislav Shwartsman
@ -30,11 +30,6 @@
// 16 bit address size
//
bx_address BX_CPP_AttrRegparmN(1)
BX_CPU_C::BxResolve16Disp(bxInstruction_c *i)
{
return i->displ16u();
}
bx_address BX_CPP_AttrRegparmN(1)
BX_CPU_C::BxResolve16BaseIndex(bxInstruction_c *i)
{