Try to optimize individual instructions after fetchdecode
This commit is contained in:
parent
7566faf948
commit
a9c77eb75d
@ -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 \
|
||||
|
@ -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 *);
|
||||
|
@ -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()));
|
||||
|
@ -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
384
bochs/cpu/load32.cc
Executable 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
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user