stack direct access optimization - 5% emu speedup to all 32-bit guests, for 64-bit guests speedup is less because they have less stack accesses

This commit is contained in:
Stanislav Shwartsman 2012-03-25 11:54:32 +00:00
parent c43cf378f4
commit 3ca29cbdf3
25 changed files with 650 additions and 251 deletions

View File

@ -1,6 +1,8 @@
Changes after 2.5.1 release:
- CPU
- Another 10% CPU emulation speedup with even more optimal lazy flags
handling and stack access optimizations
- Support for AMD's SVM hardware emulation in Bochs CPU, to enable
configure with --enable-svm option
- Implemented AMD Extended XAPIC support, to enable set .bochsrc CPU
@ -14,7 +16,7 @@ Changes after 2.5.1 release:
- Implemented new debugger command 'info device [string]' that shows the
state of the device specified in 'string'
- Improved debug dump for pci, pic and vga/cirrus devices
- Added debug dump for pci2isa and DMA controller devices
- Added debug dump for pci2isa, floppy and DMA controller devices
- Configure and compile
- Moved networking, sound and USB devices to subdirectories in iodev

View File

@ -75,6 +75,7 @@ OBJS = \
shift32.o \
shift8.o \
arith8.o \
stack.o \
stack16.o \
protect_ctrl.o \
mult8.o \
@ -741,6 +742,13 @@ sse_string.o: sse_string.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
descriptor.h instr.h ia_opcodes.h lazy_flags.h icache.h apic.h i387.h \
../fpu/softfloat.h ../fpu/tag_w.h ../fpu/status_w.h ../fpu/control_w.h \
xmm.h vmx.h svm.h stack.h
stack.o: stack.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
../bx_debug/debug.h ../config.h ../osdep.h ../gui/siminterface.h \
../cpudb.h ../gui/paramtree.h ../memory/memory.h ../pc_system.h \
../gui/gui.h ../instrument/stubs/instrument.h cpu.h cpuid.h crregs.h \
descriptor.h instr.h ia_opcodes.h lazy_flags.h icache.h apic.h i387.h \
../fpu/softfloat.h ../fpu/tag_w.h ../fpu/status_w.h ../fpu/control_w.h \
xmm.h vmx.h svm.h stack.h
stack16.o: stack16.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
../bx_debug/debug.h ../config.h ../osdep.h ../gui/siminterface.h \
../cpudb.h ../gui/paramtree.h ../memory/memory.h ../pc_system.h \

View File

@ -353,7 +353,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate(bx_descriptor_t *gate_descriptor
for (unsigned n=param_count; n>0; n--) {
temp_ESP -= 4;
Bit32u param = read_virtual_dword_32(BX_SEG_REG_SS, return_ESP + (n-1)*4);
Bit32u param = stack_read_dword(return_ESP + (n-1)*4);
write_new_stack_dword_32(&new_stack, temp_ESP, cs_descriptor.dpl, param);
}
// push return address onto new stack
@ -368,7 +368,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate(bx_descriptor_t *gate_descriptor
for (unsigned n=param_count; n>0; n--) {
temp_ESP -= 2;
Bit16u param = read_virtual_word_32(BX_SEG_REG_SS, return_ESP + (n-1)*2);
Bit16u param = stack_read_word(return_ESP + (n-1)*2);
write_new_stack_word_32(&new_stack, temp_ESP, cs_descriptor.dpl, param);
}
// push return address onto new stack
@ -390,7 +390,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate(bx_descriptor_t *gate_descriptor
for (unsigned n=param_count; n>0; n--) {
temp_SP -= 4;
Bit32u param = read_virtual_dword_32(BX_SEG_REG_SS, return_ESP + (n-1)*4);
Bit32u param = stack_read_dword(return_ESP + (n-1)*4);
write_new_stack_dword_32(&new_stack, temp_SP, cs_descriptor.dpl, param);
}
// push return address onto new stack
@ -405,7 +405,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate(bx_descriptor_t *gate_descriptor
for (unsigned n=param_count; n>0; n--) {
temp_SP -= 2;
Bit16u param = read_virtual_word_32(BX_SEG_REG_SS, return_ESP + (n-1)*2);
Bit16u param = stack_read_word(return_ESP + (n-1)*2);
write_new_stack_word_32(&new_stack, temp_SP, cs_descriptor.dpl, param);
}
// push return address onto new stack

View File

@ -1117,12 +1117,18 @@ public: // for now...
jmp_buf jmp_buf_env;
Bit8u curr_exception;
// Boundaries of current page, based on EIP
// Boundaries of current code page, based on EIP
bx_address eipPageBias;
Bit32u eipPageWindowSize;
const Bit8u *eipFetchPtr;
bx_phy_address pAddrFetchPage; // Guest physical address of current instruction page
// Boundaries of current stack page, based on ESP
bx_address espPageBias; // Linear address of current stack page
Bit32u espPageWindowSize;
const Bit8u *espHostPtr;
bx_phy_address pAddrStackPage; // Guest physical address of current stack page
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
unsigned alignment_check_mask;
#endif
@ -1464,6 +1470,9 @@ public: // for now...
BX_SMF BX_INSF_TYPE MOV32_GdEdM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF BX_INSF_TYPE MOV32_EdGdM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF BX_INSF_TYPE MOV32S_GdEdM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF BX_INSF_TYPE MOV32S_EdGdM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF BX_INSF_TYPE MOV_EwSwM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF BX_INSF_TYPE MOV_EwSwR(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF BX_INSF_TYPE MOV_SwEw(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
@ -3306,6 +3315,9 @@ public: // for now...
BX_SMF BX_INSF_TYPE MOV_EqIdR(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF BX_INSF_TYPE MOV_EqIdM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF BX_INSF_TYPE MOV64S_EqGqM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF BX_INSF_TYPE MOV64S_GqEqM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
// repeatable instructions
BX_SMF BX_INSF_TYPE REP_MOVSQ_XqYq(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF BX_INSF_TYPE REP_CMPSQ_XqYq(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
@ -3637,6 +3649,11 @@ public: // for now...
BX_CPU_THIS_PTR eipPageWindowSize = 0;
}
BX_SMF BX_CPP_INLINE void invalidate_stack_cache(void)
{
BX_CPU_THIS_PTR espPageWindowSize = 0;
}
BX_SMF bx_bool write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned len) BX_CPP_AttrRegparmN(3);
BX_SMF bx_bool read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned len) BX_CPP_AttrRegparmN(3);
BX_SMF bx_bool execute_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned len) BX_CPP_AttrRegparmN(3);
@ -3889,6 +3906,18 @@ public: // for now...
#endif
BX_SMF void stack_write_byte(bx_address offset, Bit8u data) BX_CPP_AttrRegparmN(2);
BX_SMF void stack_write_word(bx_address offset, Bit16u data) BX_CPP_AttrRegparmN(2);
BX_SMF void stack_write_dword(bx_address offset, Bit32u data) BX_CPP_AttrRegparmN(2);
BX_SMF void stack_write_qword(bx_address offset, Bit64u data) BX_CPP_AttrRegparmN(2);
BX_SMF Bit8u stack_read_byte(bx_address offset) BX_CPP_AttrRegparmN(1);
BX_SMF Bit16u stack_read_word(bx_address offset) BX_CPP_AttrRegparmN(1);
BX_SMF Bit32u stack_read_dword(bx_address offset) BX_CPP_AttrRegparmN(1);
BX_SMF Bit64u stack_read_qword(bx_address offset) BX_CPP_AttrRegparmN(1);
BX_SMF void stackPrefetch(bx_address offset, unsigned len) BX_CPP_AttrRegparmN(2);
BX_SMF Bit8u system_read_byte(bx_address laddr) BX_CPP_AttrRegparmN(1);
BX_SMF Bit16u system_read_word(bx_address laddr) BX_CPP_AttrRegparmN(1);
BX_SMF Bit32u system_read_dword(bx_address laddr) BX_CPP_AttrRegparmN(1);
@ -4016,6 +4045,7 @@ public: // for now...
BX_SMF void reset(unsigned source);
BX_SMF void shutdown(void);
BX_SMF void handleCpuModeChange(void);
BX_SMF void handleCpuContextChange(void);
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
BX_SMF void handleAlignmentCheck(void);
#endif
@ -4848,6 +4878,7 @@ enum {
#define BxTraceEnd 0x4000 // bit 14
#ifdef BX_TRACE_CACHE_NO_SPECULATIVE_TRACING
#define BxTraceJCC BxTraceEnd
#else

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2011 The Bochs Project
// Copyright (C) 2001-2012 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -49,7 +49,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear64_Iw(bxInstruction_c *i)
BX_CPU_THIS_PTR show_flag |= Flag_ret;
#endif
Bit64u return_RIP = read_virtual_qword_64(BX_SEG_REG_SS, RSP);
Bit64u return_RIP = stack_read_qword(RSP);
if (! IsCanonical(return_RIP)) {
BX_ERROR(("RETnear64_Iw: canonical RIP violation"));
@ -70,7 +70,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear64(bxInstruction_c *i)
BX_CPU_THIS_PTR show_flag |= Flag_ret;
#endif
Bit64u return_RIP = read_virtual_qword_64(BX_SEG_REG_SS, RSP);
Bit64u return_RIP = stack_read_qword(RSP);
if (! IsCanonical(return_RIP)) {
BX_ERROR(("RETnear64: canonical RIP violation %08x%08x", GET32H(return_RIP), GET32L(return_RIP)));
@ -113,7 +113,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_Jq(bxInstruction_c *i)
#endif
/* push 64 bit EA of next instruction */
write_virtual_qword_64(BX_SEG_REG_SS, RSP-8, RIP);
stack_write_qword(RSP-8, RIP);
if (! IsCanonical(new_RIP)) {
BX_ERROR(("CALL_Jq: canonical RIP violation"));
@ -137,7 +137,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_EqR(bxInstruction_c *i)
Bit64u new_RIP = BX_READ_64BIT_REG(i->rm());
/* push 64 bit EA of next instruction */
write_virtual_qword_64(BX_SEG_REG_SS, RSP-8, RIP);
stack_write_qword(RSP-8, RIP);
if (! IsCanonical(new_RIP))
{

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2011 The Bochs Project
// Copyright (C) 2001-2012 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -55,6 +55,15 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV32_EdGdM(bxInstruction_c *i)
BX_NEXT_INSTR(i);
}
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV32S_EdGdM(bxInstruction_c *i)
{
Bit32u eaddr = (Bit32u) BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
stack_write_dword(eaddr, BX_READ_32BIT_REG(i->nnn()));
BX_NEXT_INSTR(i);
}
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GdEdR(bxInstruction_c *i)
{
BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
@ -65,8 +74,18 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GdEdR(bxInstruction_c *i)
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV32_GdEdM(bxInstruction_c *i)
{
Bit32u eaddr = (Bit32u) BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
Bit32u val32 = read_virtual_dword_32(i->seg(), eaddr);
BX_WRITE_32BIT_REGZ(i->nnn(), val32);
BX_NEXT_INSTR(i);
}
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV32S_GdEdM(bxInstruction_c *i)
{
Bit32u eaddr = (Bit32u) BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
Bit32u val32 = stack_read_dword(eaddr);
BX_WRITE_32BIT_REGZ(i->nnn(), val32);
BX_NEXT_INSTR(i);

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2011 The Bochs Project
// Copyright (C) 2001-2012 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -45,8 +45,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RRXIq(bxInstruction_c *i)
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV64_GdEdM(bxInstruction_c *i)
{
Bit64u eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
Bit32u val32 = read_virtual_dword_64(i->seg(), eaddr);
BX_WRITE_32BIT_REGZ(i->nnn(), val32);
BX_NEXT_INSTR(i);
@ -70,16 +70,34 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EqGqM(bxInstruction_c *i)
BX_NEXT_INSTR(i);
}
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GqEqM(bxInstruction_c *i)
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV64S_EqGqM(bxInstruction_c *i)
{
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
stack_write_qword(eaddr, BX_READ_64BIT_REG(i->nnn()));
BX_NEXT_INSTR(i);
}
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GqEqM(bxInstruction_c *i)
{
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
Bit64u val64 = read_virtual_qword_64(i->seg(), eaddr);
BX_WRITE_64BIT_REG(i->nnn(), val64);
BX_NEXT_INSTR(i);
}
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV64S_GqEqM(bxInstruction_c *i)
{
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
BX_WRITE_64BIT_REG(i->nnn(), stack_read_qword(eaddr));
BX_NEXT_INSTR(i);
}
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GqEqR(bxInstruction_c *i)
{
BX_WRITE_64BIT_REG(i->nnn(), BX_READ_64BIT_REG(i->rm()));

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2011 The Bochs Project
// Copyright (C) 2001-2012 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -1937,6 +1937,15 @@ modrm_done:
if (mod_mem) {
i->execute = BxOpcodesTable[ia_opcode].execute1;
i->execute2 = BxOpcodesTable[ia_opcode].execute2;
if (ia_opcode == BX_IA_MOV32_GdEd) {
if (seg == BX_SEG_REG_SS)
i->execute = &BX_CPU_C::MOV32S_GdEdM;
}
if (ia_opcode == BX_IA_MOV32_EdGd) {
if (seg == BX_SEG_REG_SS)
i->execute = &BX_CPU_C::MOV32S_EdGdM;
}
}
else {
i->execute = BxOpcodesTable[ia_opcode].execute2;

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2011 The Bochs Project
// Copyright (C) 2001-2012 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -2362,6 +2362,15 @@ modrm_done:
if (mod_mem) {
i->execute = BxOpcodesTable[ia_opcode].execute1;
i->execute2 = BxOpcodesTable[ia_opcode].execute2;
if (ia_opcode == BX_IA_MOV_GqEq) {
if (seg == BX_SEG_REG_SS)
i->execute = &BX_CPU_C::MOV64S_GqEqM;
}
if (ia_opcode == BX_IA_MOV32_EdGd) {
if (seg == BX_SEG_REG_SS)
i->execute = &BX_CPU_C::MOV64S_EqGqM;
}
}
else {
i->execute = BxOpcodesTable[ia_opcode].execute2;

View File

@ -1060,11 +1060,16 @@ void BX_CPU_C::reset(unsigned source)
TLB_flush();
// invalidate the prefetch queue
// invalidate the code prefetch queue
BX_CPU_THIS_PTR eipPageBias = 0;
BX_CPU_THIS_PTR eipPageWindowSize = 0;
BX_CPU_THIS_PTR eipFetchPtr = NULL;
// invalidate current stack page
BX_CPU_THIS_PTR espPageBias = 0;
BX_CPU_THIS_PTR espPageWindowSize = 0;
BX_CPU_THIS_PTR espHostPtr = NULL;
handleCpuModeChange();
#if BX_DEBUGGER

View File

@ -124,9 +124,9 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
temp_ESP = SP;
if (i->os32L()) {
new_eflags = read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP + 8);
raw_cs_selector = (Bit16u) read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP + 4);
new_eip = read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP + 0);
new_eflags = stack_read_dword(temp_ESP + 8);
raw_cs_selector = (Bit16u) stack_read_dword(temp_ESP + 4);
new_eip = stack_read_dword(temp_ESP + 0);
// if VM=1 in flags image on stack then STACK_RETURN_TO_V86
if (new_eflags & EFlagsVMMask) {
@ -138,9 +138,9 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
}
}
else {
new_flags = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 4);
raw_cs_selector = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 2);
new_ip = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 0);
new_flags = stack_read_word(temp_ESP + 4);
raw_cs_selector = stack_read_word(temp_ESP + 2);
new_ip = stack_read_word(temp_ESP + 0);
}
parse_selector(raw_cs_selector, &cs_selector);
@ -216,10 +216,10 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
/* examine return SS selector and associated descriptor */
if (i->os32L()) {
raw_ss_selector = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 16);
raw_ss_selector = stack_read_word(temp_ESP + 16);
}
else {
raw_ss_selector = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 8);
raw_ss_selector = stack_read_word(temp_ESP + 8);
}
/* selector must be non-null, else #GP(0) */
@ -267,14 +267,14 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
}
if (i->os32L()) {
new_esp = read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP + 12);
new_eflags = read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP + 8);
new_eip = read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP + 0);
new_esp = stack_read_dword(temp_ESP + 12);
new_eflags = stack_read_dword(temp_ESP + 8);
new_eip = stack_read_dword(temp_ESP + 0);
}
else {
new_esp = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 6);
new_eflags = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 4);
new_eip = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 0);
new_esp = stack_read_word(temp_ESP + 6);
new_eflags = stack_read_word(temp_ESP + 4);
new_eip = stack_read_word(temp_ESP + 0);
}
// ID,VIP,VIF,AC,VM,RF,x,NT,IOPL,OF,DF,IF,TF,SF,ZF,x,AF,x,PF,x,CF
@ -351,23 +351,23 @@ BX_CPU_C::long_iret(bxInstruction_c *i)
#if BX_SUPPORT_X86_64
if (i->os64L()) {
new_eflags = (Bit32u) read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 16);
raw_cs_selector = (Bit16u) read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 8);
new_rip = read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 0);
new_eflags = (Bit32u) stack_read_qword(temp_RSP + 16);
raw_cs_selector = (Bit16u) stack_read_qword(temp_RSP + 8);
new_rip = stack_read_qword(temp_RSP + 0);
top_nbytes_same = 24;
}
else
#endif
if (i->os32L()) {
new_eflags = read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 8);
raw_cs_selector = (Bit16u) read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 4);
new_rip = (Bit64u) read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 0);
new_eflags = stack_read_dword(temp_RSP + 8);
raw_cs_selector = (Bit16u) stack_read_dword(temp_RSP + 4);
new_rip = (Bit64u) stack_read_dword(temp_RSP + 0);
top_nbytes_same = 12;
}
else {
new_eflags = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 4);
raw_cs_selector = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 2);
new_rip = (Bit64u) read_virtual_word(BX_SEG_REG_SS, temp_RSP + 0);
new_eflags = stack_read_word(temp_RSP + 4);
raw_cs_selector = stack_read_word(temp_RSP + 2);
new_rip = (Bit64u) stack_read_word(temp_RSP + 0);
top_nbytes_same = 6;
}
@ -446,19 +446,19 @@ BX_CPU_C::long_iret(bxInstruction_c *i)
/* examine return SS selector and associated descriptor */
#if BX_SUPPORT_X86_64
if (i->os64L()) {
raw_ss_selector = (Bit16u) read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 32);
new_rsp = read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 24);
raw_ss_selector = (Bit16u) stack_read_qword(temp_RSP + 32);
new_rsp = stack_read_qword(temp_RSP + 24);
}
else
#endif
{
if (i->os32L()) {
raw_ss_selector = (Bit16u) read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 16);
new_rsp = (Bit64u) read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 12);
raw_ss_selector = (Bit16u) stack_read_dword(temp_RSP + 16);
new_rsp = (Bit64u) stack_read_dword(temp_RSP + 12);
}
else {
raw_ss_selector = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 8);
new_rsp = (Bit64u) read_virtual_word(BX_SEG_REG_SS, temp_RSP + 6);
raw_ss_selector = stack_read_word(temp_RSP + 8);
new_rsp = (Bit64u) stack_read_word(temp_RSP + 6);
}
}

View File

@ -374,6 +374,8 @@ void BX_CPU_C::TLB_flush(void)
invalidate_prefetch_q();
invalidate_stack_cache();
for (unsigned n=0; n<BX_TLB_SIZE; n++) {
BX_CPU_THIS_PTR TLB.entry[n].lpf = BX_INVALID_TLB_ENTRY;
BX_CPU_THIS_PTR TLB.entry[n].accessBits = 0;
@ -399,6 +401,8 @@ void BX_CPU_C::TLB_flushNonGlobal(void)
invalidate_prefetch_q();
invalidate_stack_cache();
BX_CPU_THIS_PTR TLB.split_large = 0;
Bit32u lpf_mask = 0;
@ -428,6 +432,8 @@ void BX_CPU_C::TLB_invlpg(bx_address laddr)
{
invalidate_prefetch_q();
invalidate_stack_cache();
BX_DEBUG(("TLB_invlpg(0x"FMT_ADDRX"): invalidate TLB entry", laddr));
#if BX_CPU_LEVEL >= 5

View File

@ -442,6 +442,26 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BxNoAVX(bxInstruction_c *i)
#endif
void BX_CPU_C::handleCpuContextChange(void)
{
TLB_flush();
#if BX_SUPPORT_MONITOR_MWAIT
BX_CPU_THIS_PTR monitor.reset_monitor();
#endif
invalidate_prefetch_q();
invalidate_stack_cache();
#if BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck();
#endif
handleCpuModeChange();
handleSseModeChange();
#if BX_SUPPORT_AVX
handleAvxModeChange();
#endif
}
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RDPMC(bxInstruction_c *i)
{
#if BX_CPU_LEVEL >= 5

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2009 Stanislav Shwartsman
// Copyright (c) 2005-2012 Stanislav Shwartsman
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
// This library is free software; you can redistribute it and/or
@ -56,20 +56,20 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes)
#if BX_SUPPORT_X86_64
if (i->os64L()) {
raw_cs_selector = (Bit16u) read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 8);
return_RIP = read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP);
raw_cs_selector = (Bit16u) stack_read_qword(temp_RSP + 8);
return_RIP = stack_read_qword(temp_RSP);
stack_param_offset = 16;
}
else
#endif
if (i->os32L()) {
raw_cs_selector = (Bit16u) read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 4);
return_RIP = read_virtual_dword(BX_SEG_REG_SS, temp_RSP);
raw_cs_selector = (Bit16u) stack_read_dword(temp_RSP + 4);
return_RIP = stack_read_dword(temp_RSP);
stack_param_offset = 8;
}
else {
raw_cs_selector = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 2);
return_RIP = read_virtual_word(BX_SEG_REG_SS, temp_RSP);
raw_cs_selector = stack_read_word(temp_RSP + 2);
return_RIP = stack_read_word(temp_RSP);
stack_param_offset = 4;
}
@ -132,18 +132,18 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes)
#if BX_SUPPORT_X86_64
if (i->os64L()) {
raw_ss_selector = read_virtual_word_64(BX_SEG_REG_SS, temp_RSP + 24 + pop_bytes);
return_RSP = read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 16 + pop_bytes);
raw_ss_selector = stack_read_word(temp_RSP + 24 + pop_bytes);
return_RSP = stack_read_qword(temp_RSP + 16 + pop_bytes);
}
else
#endif
if (i->os32L()) {
raw_ss_selector = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 12 + pop_bytes);
return_RSP = read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 8 + pop_bytes);
raw_ss_selector = stack_read_word(temp_RSP + 12 + pop_bytes);
return_RSP = stack_read_dword(temp_RSP + 8 + pop_bytes);
}
else {
raw_ss_selector = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 6 + pop_bytes);
return_RSP = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 4 + pop_bytes);
raw_ss_selector = stack_read_word(temp_RSP + 6 + pop_bytes);
return_RSP = stack_read_word(temp_RSP + 4 + pop_bytes);
}
/* selector index must be within its descriptor table limits,

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2009 The Bochs Project
// Copyright (C) 2001-2012 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -91,6 +91,8 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = descriptor;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1;
invalidate_stack_cache();
return;
}
else if ((seg==&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS]) ||
@ -201,6 +203,9 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
handleAlignmentCheck(/* CPL change */);
#endif
}
if (seg == &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS])
invalidate_stack_cache();
}
void BX_CPP_AttrRegparmN(2)
@ -227,6 +232,8 @@ BX_CPU_C::load_null_selector(bx_segment_reg_t *seg, unsigned value)
#if BX_SUPPORT_X86_64
seg->cache.u.segment.l = 0;
#endif
invalidate_stack_cache();
}
BX_CPP_INLINE void BX_CPU_C::validate_seg_reg(unsigned seg)
@ -526,6 +533,8 @@ BX_CPU_C::load_ss(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = *descriptor;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = cpl;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1;
invalidate_stack_cache();
}
void BX_CPU_C::fetch_raw_descriptor(const bx_selector_t *selector,

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006-2011 Stanislav Shwartsman
// Copyright (c) 2006-2012 Stanislav Shwartsman
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
// This library is free software; you can redistribute it and/or
@ -81,8 +81,6 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RSM(bxInstruction_c *i)
}
#endif
invalidate_prefetch_q();
BX_INFO(("RSM: Resuming from System Management Mode"));
BX_CPU_THIS_PTR disable_NMI = 0;
@ -113,8 +111,6 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RSM(bxInstruction_c *i)
void BX_CPU_C::enter_system_management_mode(void)
{
invalidate_prefetch_q();
BX_INFO(("Enter to System Management Mode"));
// debug(BX_CPU_THIS_PTR prev_rip);
@ -180,9 +176,6 @@ void BX_CPU_C::enter_system_management_mode(void)
BX_CPU_THIS_PTR cr4.set32(0);
#endif
// paging mode was changed - flush TLB
TLB_flush(); // Flush Global entries also
#if BX_CPU_LEVEL >= 5
BX_CPU_THIS_PTR efer.set32(0);
#endif
@ -205,19 +198,6 @@ void BX_CPU_C::enter_system_management_mode(void)
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l = 0; /* 16bit default size */
#endif
handleCpuModeChange();
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck();
#endif
#if BX_CPU_LEVEL >= 6
handleSseModeChange();
#if BX_SUPPORT_AVX
handleAvxModeChange();
#endif
#endif
/* DS (Data Segment) and descriptor cache */
parse_selector(0x0000,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector);
@ -243,6 +223,8 @@ void BX_CPU_C::enter_system_management_mode(void)
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS] = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS];
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS] = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS];
handleCpuContextChange();
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);
}
@ -656,13 +638,6 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
}
}
handleCpuModeChange();
handleSseModeChange();
#if BX_SUPPORT_AVX
handleAvxModeChange();
#endif
Bit16u ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) >> 16;
if (set_segment_ar_data(&BX_CPU_THIS_PTR ldtr,
(ar_data >> 8) & 1,
@ -696,6 +671,8 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
BX_CPU_THIS_PTR smbase = SMRAM_FIELD(saved_state, SMRAM_FIELD_SMBASE_OFFSET);
handleCpuContextChange();
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);
return 1;

332
bochs/cpu/stack.cc Executable file
View File

@ -0,0 +1,332 @@
/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012 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., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
//
/////////////////////////////////////////////////////////////////////////
#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR
void BX_CPP_AttrRegparmN(2) BX_CPU_C::stackPrefetch(bx_address offset, unsigned len)
{
bx_address laddr;
BX_CPU_THIS_PTR espHostPtr = 0; // initialize with NULL pointer
BX_CPU_THIS_PTR espPageWindowSize = 0;
len--;
#if BX_SUPPORT_X86_64
if (long64_mode()) {
laddr = offset;
unsigned pageOffset = PAGE_OFFSET(offset);
// canonical violations will miss the TLB below
if (pageOffset + len >= 4096) // don't care for page split accesses
return;
BX_CPU_THIS_PTR espPageBias = pageOffset - offset;
BX_CPU_THIS_PTR espPageWindowSize = 4096;
}
else
#endif
{
laddr = (Bit32u) (offset + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base);
unsigned pageOffset = PAGE_OFFSET(laddr);
if (pageOffset + len >= 4096) // don't care for page split accesses
return;
BX_CPU_THIS_PTR espPageBias = (bx_address) pageOffset - offset;
Bit32u limit = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled;
Bit32u pageStart = offset - pageOffset;
BX_ASSERT(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid);
BX_ASSERT(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p);
// check that the begining of the page is within stack segment limits
// problem can happen with EXPAND DOWN segments
if (IS_DATA_SEGMENT_EXPAND_DOWN(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type)) {
Bit32u upper_limit;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
upper_limit = 0xffffffff;
else
upper_limit = 0x0000ffff;
if (offset <= limit || offset > upper_limit || (upper_limit - offset) < len) {
BX_ERROR(("stackPrefetch(%d): access [0x%08x] > SS.limit [0x%08x] ED", len+1, (Bit32u) offset, limit));
exception(BX_SS_EXCEPTION, 0);
}
// check that the begining of the page is within stack segment limits
// handle correctly the wrap corner case for EXPAND DOWN
Bit32u pageEnd = pageStart + 0xfff;
if (pageStart > limit && pageStart < pageEnd) {
BX_CPU_THIS_PTR espPageWindowSize = 4096;
if ((upper_limit - offset) < (4096 - pageOffset))
BX_CPU_THIS_PTR espPageWindowSize = (Bit32u)(upper_limit - offset + 1);
}
}
else {
if (offset > (limit - len) || len > limit) {
BX_ERROR(("stackPrefetch(%d): access [0x%08x] > SS.limit [0x%08x]", len+1, (Bit32u) offset, limit));
exception(BX_SS_EXCEPTION, 0);
}
if (pageStart <= limit) {
BX_CPU_THIS_PTR espPageWindowSize = 4096;
if ((limit - offset) < (4096 - pageOffset))
BX_CPU_THIS_PTR espPageWindowSize = (Bit32u)(limit - offset + 1);
}
}
}
unsigned tlbIndex = BX_TLB_INDEX_OF(laddr, 0);
Bit64u lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
if (tlbEntry->lpf == lpf) {
// See if the TLB entry privilege level allows us write access from this CPL
// Assuming that we always can read if write access is OK
if (! (tlbEntry->accessBits & (0x2 | USER_PL))) {
BX_CPU_THIS_PTR pAddrStackPage = tlbEntry->ppf;
BX_CPU_THIS_PTR espHostPtr = (Bit8u*) tlbEntry->hostPageAddr;
}
}
if (! BX_CPU_THIS_PTR espHostPtr || BX_CPU_THIS_PTR espPageWindowSize < 7)
BX_CPU_THIS_PTR espPageWindowSize = 0;
else
BX_CPU_THIS_PTR espPageWindowSize -= 7;
}
void BX_CPP_AttrRegparmN(2) BX_CPU_C::stack_write_byte(bx_address offset, Bit8u data)
{
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
stackPrefetch(offset, 1);
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
}
if (BX_CPU_THIS_PTR espHostPtr) {
Bit8u *hostPageAddr = (Bit8u*)(BX_CPU_THIS_PTR espHostPtr + espBiased);
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset), pAddr, 1, CPL, BX_WRITE, (Bit8u*) &data);
pageWriteStampTable.decWriteStamp(pAddr, 1);
*hostPageAddr = data;
}
else {
write_virtual_byte(BX_SEG_REG_SS, offset, data);
}
}
void BX_CPP_AttrRegparmN(2) BX_CPU_C::stack_write_word(bx_address offset, Bit16u data)
{
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
stackPrefetch(offset, 2);
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
}
if (BX_CPU_THIS_PTR espHostPtr) {
Bit16u *hostPageAddr = (Bit16u*)(BX_CPU_THIS_PTR espHostPtr + espBiased);
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (BX_CPU_THIS_PTR alignment_check() && (pAddr & 1) != 0) {
BX_ERROR(("stack_write_word(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0);
}
#endif
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset), pAddr, 2, CPL, BX_WRITE, (Bit8u*) &data);
pageWriteStampTable.decWriteStamp(pAddr, 2);
WriteHostWordToLittleEndian(hostPageAddr, data);
}
else {
write_virtual_word(BX_SEG_REG_SS, offset, data);
}
}
void BX_CPP_AttrRegparmN(2) BX_CPU_C::stack_write_dword(bx_address offset, Bit32u data)
{
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
stackPrefetch(offset, 4);
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
}
if (BX_CPU_THIS_PTR espHostPtr) {
Bit32u *hostPageAddr = (Bit32u*)(BX_CPU_THIS_PTR espHostPtr + espBiased);
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (BX_CPU_THIS_PTR alignment_check() && (pAddr & 3) != 0) {
BX_ERROR(("stack_write_dword(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0);
}
#endif
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset), pAddr, 4, CPL, BX_WRITE, (Bit8u*) &data);
pageWriteStampTable.decWriteStamp(pAddr, 4);
WriteHostDWordToLittleEndian(hostPageAddr, data);
}
else {
write_virtual_dword(BX_SEG_REG_SS, offset, data);
}
}
void BX_CPP_AttrRegparmN(2) BX_CPU_C::stack_write_qword(bx_address offset, Bit64u data)
{
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
stackPrefetch(offset, 8);
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
}
if (BX_CPU_THIS_PTR espHostPtr) {
Bit64u *hostPageAddr = (Bit64u*)(BX_CPU_THIS_PTR espHostPtr + espBiased);
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (BX_CPU_THIS_PTR alignment_check() && (pAddr & 7) != 0) {
BX_ERROR(("stack_write_qword(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0);
}
#endif
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset), pAddr, 8, CPL, BX_WRITE, (Bit8u*) &data);
pageWriteStampTable.decWriteStamp(pAddr, 8);
WriteHostQWordToLittleEndian(hostPageAddr, data);
}
else {
write_virtual_qword(BX_SEG_REG_SS, offset, data);
}
}
Bit8u BX_CPP_AttrRegparmN(1) BX_CPU_C::stack_read_byte(bx_address offset)
{
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
stackPrefetch(offset, 1);
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
}
if (BX_CPU_THIS_PTR espHostPtr) {
Bit8u *hostPageAddr = (Bit8u*)(BX_CPU_THIS_PTR espHostPtr + espBiased), data;
data = *hostPageAddr;
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset),
(BX_CPU_THIS_PTR pAddrStackPage + espBiased), 1, CPL, BX_READ, (Bit8u*) &data);
return data;
}
else {
return read_virtual_byte(BX_SEG_REG_SS, offset);
}
}
Bit16u BX_CPP_AttrRegparmN(1) BX_CPU_C::stack_read_word(bx_address offset)
{
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
stackPrefetch(offset, 2);
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
}
if (BX_CPU_THIS_PTR espHostPtr) {
Bit16u *hostPageAddr = (Bit16u*)(BX_CPU_THIS_PTR espHostPtr + espBiased), data;
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (BX_CPU_THIS_PTR alignment_check()) {
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
if (pAddr & 1) {
BX_ERROR(("stack_read_word(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0);
}
}
#endif
ReadHostWordFromLittleEndian(hostPageAddr, data);
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset),
(BX_CPU_THIS_PTR pAddrStackPage + espBiased), 2, CPL, BX_READ, (Bit8u*) &data);
return data;
}
else {
return read_virtual_word(BX_SEG_REG_SS, offset);
}
}
Bit32u BX_CPP_AttrRegparmN(1) BX_CPU_C::stack_read_dword(bx_address offset)
{
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
stackPrefetch(offset, 4);
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
}
if (BX_CPU_THIS_PTR espHostPtr) {
Bit32u *hostPageAddr = (Bit32u*)(BX_CPU_THIS_PTR espHostPtr + espBiased), data;
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (BX_CPU_THIS_PTR alignment_check()) {
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
if (pAddr & 3) {
BX_ERROR(("stack_read_dword(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0);
}
}
#endif
ReadHostDWordFromLittleEndian(hostPageAddr, data);
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset),
(BX_CPU_THIS_PTR pAddrStackPage + espBiased), 4, CPL, BX_READ, (Bit8u*) &data);
return data;
}
else {
return read_virtual_dword(BX_SEG_REG_SS, offset);
}
}
Bit64u BX_CPP_AttrRegparmN(1) BX_CPU_C::stack_read_qword(bx_address offset)
{
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
stackPrefetch(offset, 8);
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
}
if (BX_CPU_THIS_PTR espHostPtr) {
Bit64u *hostPageAddr = (Bit64u*)(BX_CPU_THIS_PTR espHostPtr + espBiased), data;
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (BX_CPU_THIS_PTR alignment_check()) {
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
if (pAddr & 7) {
BX_ERROR(("stack_read_qword(): #AC misaligned access"));
exception(BX_AC_EXCEPTION, 0);
}
}
#endif
ReadHostQWordFromLittleEndian(hostPageAddr, data);
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset),
(BX_CPU_THIS_PTR pAddrStackPage + espBiased), 8, CPL, BX_READ, (Bit8u*) &data);
return data;
}
else {
return read_virtual_qword(BX_SEG_REG_SS, offset);
}
}

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-2009 Stanislav Shwartsman
// Copyright (c) 2007-2012 Stanislav Shwartsman
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
// This library is free software; you can redistribute it and/or
@ -29,18 +29,18 @@ BX_CPU_C::push_16(Bit16u value16)
{
#if BX_SUPPORT_X86_64
if (long64_mode()) { /* StackAddrSize = 64 */
write_virtual_word_64(BX_SEG_REG_SS, RSP-2, value16);
stack_write_word(RSP-2, value16);
RSP -= 2;
}
else
#endif
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u) (ESP-2), value16);
stack_write_word((Bit32u) (ESP-2), value16);
ESP -= 2;
}
else /* StackAddrSize = 16 */
{
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u) (SP-2), value16);
stack_write_word((Bit16u) (SP-2), value16);
SP -= 2;
}
}
@ -50,18 +50,18 @@ BX_CPU_C::push_32(Bit32u value32)
{
#if BX_SUPPORT_X86_64
if (long64_mode()) { /* StackAddrSize = 64 */
write_virtual_dword_64(BX_SEG_REG_SS, RSP-4, value32);
stack_write_dword(RSP-4, value32);
RSP -= 4;
}
else
#endif
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (ESP-4), value32);
stack_write_dword((Bit32u) (ESP-4), value32);
ESP -= 4;
}
else /* StackAddrSize = 16 */
{
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (SP-4), value32);
stack_write_dword((Bit16u) (SP-4), value32);
SP -= 4;
}
}
@ -72,7 +72,7 @@ BX_CPU_C::push_32(Bit32u value32)
BX_CPU_C::push_64(Bit64u value64)
{
/* StackAddrSize = 64 */
write_virtual_qword_64(BX_SEG_REG_SS, RSP-8, value64);
stack_write_qword(RSP-8, value64);
RSP -= 8;
}
#endif
@ -84,17 +84,17 @@ BX_CPP_INLINE Bit16u BX_CPU_C::pop_16(void)
#if BX_SUPPORT_X86_64
if (long64_mode()) { /* StackAddrSize = 64 */
value16 = read_virtual_word_64(BX_SEG_REG_SS, RSP);
value16 = stack_read_word(RSP);
RSP += 2;
}
else
#endif
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
value16 = read_virtual_word_32(BX_SEG_REG_SS, ESP);
value16 = stack_read_word(ESP);
ESP += 2;
}
else { /* StackAddrSize = 16 */
value16 = read_virtual_word_32(BX_SEG_REG_SS, SP);
value16 = stack_read_word(SP);
SP += 2;
}
@ -108,17 +108,17 @@ BX_CPP_INLINE Bit32u BX_CPU_C::pop_32(void)
#if BX_SUPPORT_X86_64
if (long64_mode()) { /* StackAddrSize = 64 */
value32 = read_virtual_dword_64(BX_SEG_REG_SS, RSP);
value32 = stack_read_dword(RSP);
RSP += 4;
}
else
#endif
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
value32 = read_virtual_dword_32(BX_SEG_REG_SS, ESP);
value32 = stack_read_dword(ESP);
ESP += 4;
}
else { /* StackAddrSize = 16 */
value32 = read_virtual_dword_32(BX_SEG_REG_SS, SP);
value32 = stack_read_dword(SP);
SP += 4;
}
@ -130,7 +130,7 @@ BX_CPP_INLINE Bit32u BX_CPU_C::pop_32(void)
BX_CPP_INLINE Bit64u BX_CPU_C::pop_64(void)
{
/* StackAddrSize = 64 */
Bit64u value64 = read_virtual_qword_64(BX_SEG_REG_SS, RSP);
Bit64u value64 = stack_read_qword(RSP);
RSP += 8;
return value64;

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2011 The Bochs Project
// Copyright (C) 2001-2012 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -108,26 +108,26 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSHAD16(bxInstruction_c *i)
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
{
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 2), AX);
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 4), CX);
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 6), DX);
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 8), BX);
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 10), temp_SP);
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 12), BP);
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 14), SI);
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 16), DI);
stack_write_word((Bit32u)(temp_ESP - 2), AX);
stack_write_word((Bit32u)(temp_ESP - 4), CX);
stack_write_word((Bit32u)(temp_ESP - 6), DX);
stack_write_word((Bit32u)(temp_ESP - 8), BX);
stack_write_word((Bit32u)(temp_ESP - 10), temp_SP);
stack_write_word((Bit32u)(temp_ESP - 12), BP);
stack_write_word((Bit32u)(temp_ESP - 14), SI);
stack_write_word((Bit32u)(temp_ESP - 16), DI);
ESP -= 16;
}
else
{
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 2), AX);
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 4), CX);
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 6), DX);
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 8), BX);
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 10), temp_SP);
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 12), BP);
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 14), SI);
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 16), DI);
stack_write_word((Bit16u)(temp_SP - 2), AX);
stack_write_word((Bit16u)(temp_SP - 4), CX);
stack_write_word((Bit16u)(temp_SP - 6), DX);
stack_write_word((Bit16u)(temp_SP - 8), BX);
stack_write_word((Bit16u)(temp_SP - 10), temp_SP);
stack_write_word((Bit16u)(temp_SP - 12), BP);
stack_write_word((Bit16u)(temp_SP - 14), SI);
stack_write_word((Bit16u)(temp_SP - 16), DI);
SP -= 16;
}
@ -141,27 +141,27 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POPAD16(bxInstruction_c *i)
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
{
Bit32u temp_ESP = ESP;
di = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 0));
si = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 2));
bp = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 4));
read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 6));
bx = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 8));
dx = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 10));
cx = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 12));
ax = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 14));
di = stack_read_word((Bit32u)(temp_ESP + 0));
si = stack_read_word((Bit32u)(temp_ESP + 2));
bp = stack_read_word((Bit32u)(temp_ESP + 4));
stack_read_word((Bit32u)(temp_ESP + 6));
bx = stack_read_word((Bit32u)(temp_ESP + 8));
dx = stack_read_word((Bit32u)(temp_ESP + 10));
cx = stack_read_word((Bit32u)(temp_ESP + 12));
ax = stack_read_word((Bit32u)(temp_ESP + 14));
ESP += 16;
}
else
{
Bit16u temp_SP = SP;
di = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 0));
si = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 2));
bp = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 4));
read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 6));
bx = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 8));
dx = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 10));
cx = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 12));
ax = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 14));
di = stack_read_word((Bit16u)(temp_SP + 0));
si = stack_read_word((Bit16u)(temp_SP + 2));
bp = stack_read_word((Bit16u)(temp_SP + 4));
stack_read_word((Bit16u)(temp_SP + 6));
bx = stack_read_word((Bit16u)(temp_SP + 8));
dx = stack_read_word((Bit16u)(temp_SP + 10));
cx = stack_read_word((Bit16u)(temp_SP + 12));
ax = stack_read_word((Bit16u)(temp_SP + 14));
SP += 16;
}
@ -194,7 +194,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER16_IwIb(bxInstruction_c *i)
/* do level-1 times */
while (--level) {
ebp -= 2;
Bit16u temp16 = read_virtual_word_32(BX_SEG_REG_SS, ebp);
Bit16u temp16 = stack_read_word(ebp);
push_16(temp16);
}
@ -218,7 +218,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER16_IwIb(bxInstruction_c *i)
/* do level-1 times */
while (--level) {
bp -= 2;
Bit16u temp16 = read_virtual_word_32(BX_SEG_REG_SS, bp);
Bit16u temp16 = stack_read_word(bp);
push_16(temp16);
}
@ -248,11 +248,11 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LEAVE16(bxInstruction_c *i)
Bit16u value16;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
value16 = read_virtual_word_32(BX_SEG_REG_SS, EBP);
value16 = stack_read_word(EBP);
ESP = EBP + 2;
}
else {
value16 = read_virtual_word_32(BX_SEG_REG_SS, BP);
value16 = stack_read_word(BP);
SP = BP + 2;
}

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2011 The Bochs Project
// Copyright (C) 2001-2012 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -61,12 +61,12 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH32_Sw(bxInstruction_c *i)
Bit16u val_16 = BX_CPU_THIS_PTR sregs[i->nnn()].selector.value;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u) (ESP-4), val_16);
stack_write_word((Bit32u) (ESP-4), val_16);
ESP -= 4;
}
else
{
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u) (SP-4), val_16);
stack_write_word((Bit16u) (SP-4), val_16);
SP -= 4;
}
@ -78,12 +78,12 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POP32_Sw(bxInstruction_c *i)
Bit16u selector;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
selector = read_virtual_word_32(BX_SEG_REG_SS, ESP);
selector = stack_read_word(ESP);
load_seg_reg(&BX_CPU_THIS_PTR sregs[i->nnn()], selector);
ESP += 4;
}
else {
selector = read_virtual_word_32(BX_SEG_REG_SS, SP);
selector = stack_read_word(SP);
load_seg_reg(&BX_CPU_THIS_PTR sregs[i->nnn()], selector);
SP += 4;
}
@ -124,26 +124,26 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSHAD32(bxInstruction_c *i)
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
{
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 4), EAX);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 8), ECX);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 12), EDX);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 16), EBX);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 20), temp_ESP);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 24), EBP);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 28), ESI);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 32), EDI);
stack_write_dword((Bit32u) (temp_ESP - 4), EAX);
stack_write_dword((Bit32u) (temp_ESP - 8), ECX);
stack_write_dword((Bit32u) (temp_ESP - 12), EDX);
stack_write_dword((Bit32u) (temp_ESP - 16), EBX);
stack_write_dword((Bit32u) (temp_ESP - 20), temp_ESP);
stack_write_dword((Bit32u) (temp_ESP - 24), EBP);
stack_write_dword((Bit32u) (temp_ESP - 28), ESI);
stack_write_dword((Bit32u) (temp_ESP - 32), EDI);
ESP -= 32;
}
else
{
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 4), EAX);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 8), ECX);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 12), EDX);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 16), EBX);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 20), temp_ESP);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 24), EBP);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 28), ESI);
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 32), EDI);
stack_write_dword((Bit16u) (temp_SP - 4), EAX);
stack_write_dword((Bit16u) (temp_SP - 8), ECX);
stack_write_dword((Bit16u) (temp_SP - 12), EDX);
stack_write_dword((Bit16u) (temp_SP - 16), EBX);
stack_write_dword((Bit16u) (temp_SP - 20), temp_ESP);
stack_write_dword((Bit16u) (temp_SP - 24), EBP);
stack_write_dword((Bit16u) (temp_SP - 28), ESI);
stack_write_dword((Bit16u) (temp_SP - 32), EDI);
SP -= 32;
}
@ -157,27 +157,27 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POPAD32(bxInstruction_c *i)
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
{
Bit32u temp_ESP = ESP;
edi = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 0));
esi = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 4));
ebp = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 8));
read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 12));
ebx = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 16));
edx = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 20));
ecx = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 24));
eax = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 28));
edi = stack_read_dword((Bit32u) (temp_ESP + 0));
esi = stack_read_dword((Bit32u) (temp_ESP + 4));
ebp = stack_read_dword((Bit32u) (temp_ESP + 8));
stack_read_dword((Bit32u) (temp_ESP + 12));
ebx = stack_read_dword((Bit32u) (temp_ESP + 16));
edx = stack_read_dword((Bit32u) (temp_ESP + 20));
ecx = stack_read_dword((Bit32u) (temp_ESP + 24));
eax = stack_read_dword((Bit32u) (temp_ESP + 28));
ESP += 32;
}
else
{
Bit16u temp_SP = SP;
edi = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 0));
esi = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 4));
ebp = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 8));
read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 12));
ebx = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 16));
edx = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 20));
ecx = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 24));
eax = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 28));
edi = stack_read_dword((Bit16u) (temp_SP + 0));
esi = stack_read_dword((Bit16u) (temp_SP + 4));
ebp = stack_read_dword((Bit16u) (temp_SP + 8));
stack_read_dword((Bit16u) (temp_SP + 12));
ebx = stack_read_dword((Bit16u) (temp_SP + 16));
edx = stack_read_dword((Bit16u) (temp_SP + 20));
ecx = stack_read_dword((Bit16u) (temp_SP + 24));
eax = stack_read_dword((Bit16u) (temp_SP + 28));
SP += 32;
}
@ -210,7 +210,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER32_IwIb(bxInstruction_c *i)
/* do level-1 times */
while (--level) {
ebp -= 4;
Bit32u temp32 = read_virtual_dword_32(BX_SEG_REG_SS, ebp);
Bit32u temp32 = stack_read_dword(ebp);
push_32(temp32);
}
@ -232,7 +232,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER32_IwIb(bxInstruction_c *i)
/* do level-1 times */
while (--level) {
bp -= 4;
Bit32u temp32 = read_virtual_dword_32(BX_SEG_REG_SS, bp);
Bit32u temp32 = stack_read_dword(bp);
push_32(temp32);
}
@ -262,11 +262,11 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LEAVE32(bxInstruction_c *i)
Bit32u value32;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
value32 = read_virtual_dword_32(BX_SEG_REG_SS, EBP);
value32 = stack_read_dword(EBP);
ESP = EBP + 4;
}
else {
value32 = read_virtual_dword_32(BX_SEG_REG_SS, BP);
value32 = stack_read_dword(BP);
SP = BP + 4;
}

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2011 The Bochs Project
// Copyright (C) 2001-2012 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -67,7 +67,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH64_Sw(bxInstruction_c *i)
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POP64_Sw(bxInstruction_c *i)
{
Bit16u selector = read_virtual_word_64(BX_SEG_REG_SS, RSP);
Bit16u selector = stack_read_word(RSP);
load_seg_reg(&BX_CPU_THIS_PTR sregs[i->nnn()], selector);
RSP += 8;
@ -101,7 +101,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER64_IwIb(bxInstruction_c *i)
Bit64u temp_RSP = RSP, temp_RBP = RBP;
temp_RSP -= 8;
write_virtual_qword_64(BX_SEG_REG_SS, temp_RSP, temp_RBP);
stack_write_qword(temp_RSP, temp_RBP);
Bit64u frame_ptr64 = temp_RSP;
@ -109,14 +109,14 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER64_IwIb(bxInstruction_c *i)
/* do level-1 times */
while (--level) {
temp_RBP -= 8;
Bit64u temp64 = read_virtual_qword_64(BX_SEG_REG_SS, temp_RBP);
Bit64u temp64 = stack_read_qword(temp_RBP);
temp_RSP -= 8;
write_virtual_qword_64(BX_SEG_REG_SS, temp_RSP, temp64);
stack_write_qword(temp_RSP, temp64);
} /* while (--level) */
/* push(frame pointer) */
temp_RSP -= 8;
write_virtual_qword_64(BX_SEG_REG_SS, temp_RSP, frame_ptr64);
stack_write_qword(temp_RSP, frame_ptr64);
} /* if (level > 0) ... */
temp_RSP -= i->Iw();
@ -135,7 +135,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER64_IwIb(bxInstruction_c *i)
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LEAVE64(bxInstruction_c *i)
{
// restore frame pointer
Bit64u temp64 = read_virtual_qword_64(BX_SEG_REG_SS, RBP);
Bit64u temp64 = stack_read_qword(RBP);
RSP = RBP + 8;
RBP = temp64;

View File

@ -255,21 +255,7 @@ void BX_CPU_C::SvmExitLoadHostState(SVM_HOST_STATE *host)
CPL = 0;
TLB_flush(); // CR0/CR4 updated
#if BX_SUPPORT_MONITOR_MWAIT
BX_CPU_THIS_PTR monitor.reset_monitor();
#endif
invalidate_prefetch_q();
#if BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck();
#endif
handleCpuModeChange();
handleSseModeChange();
#if BX_SUPPORT_AVX
handleAvxModeChange();
#endif
handleCpuContextChange();
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);
}
@ -567,19 +553,7 @@ bx_bool BX_CPU_C::SvmEnterLoadCheckGuestState(void)
if (SVM_V_IRQ)
BX_CPU_THIS_PTR async_event = 1;
#if BX_SUPPORT_MONITOR_MWAIT
BX_CPU_THIS_PTR monitor.reset_monitor();
#endif
invalidate_prefetch_q();
#if BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck();
#endif
handleCpuModeChange();
handleSseModeChange();
#if BX_SUPPORT_AVX
handleAvxModeChange();
#endif
handleCpuContextChange();
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);

View File

@ -591,6 +591,8 @@ void BX_CPU_C::task_switch(bxInstruction_c *i, bx_selector_t *tss_selector,
// All checks pass, fill in shadow cache
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = ss_descriptor;
invalidate_stack_cache();
}
else {
// SS selector is valid, else #TS(new stack segment)

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2009 The Bochs Project
// Copyright (C) 2001-2012 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -67,14 +67,14 @@ void BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector, Bit32
temp_ESP = SP;
// load SS:ESP from stack
new_esp = read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP+12);
raw_ss_selector = (Bit16u) read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP+16);
new_esp = stack_read_dword(temp_ESP+12);
raw_ss_selector = (Bit16u) stack_read_dword(temp_ESP+16);
// load ES,DS,FS,GS from stack
raw_es_selector = (Bit16u) read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP+20);
raw_ds_selector = (Bit16u) read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP+24);
raw_fs_selector = (Bit16u) read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP+28);
raw_gs_selector = (Bit16u) read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP+32);
raw_es_selector = (Bit16u) stack_read_dword(temp_ESP+20);
raw_ds_selector = (Bit16u) stack_read_dword(temp_ESP+24);
raw_fs_selector = (Bit16u) stack_read_dword(temp_ESP+28);
raw_gs_selector = (Bit16u) stack_read_dword(temp_ESP+32);
writeEFlags(flags32, EFlagsValidMask);
@ -258,6 +258,8 @@ void BX_CPU_C::init_v8086_mode(void)
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck(/* CPL change */);
#endif
invalidate_stack_cache();
}
#endif /* BX_CPU_LEVEL >= 3 */

View File

@ -1631,19 +1631,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
BX_CPU_THIS_PTR vmx_interrupt_window = 1; // set up interrupt window exiting
}
#if BX_SUPPORT_MONITOR_MWAIT
BX_CPU_THIS_PTR monitor.reset_monitor();
#endif
invalidate_prefetch_q();
#if BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck();
#endif
handleCpuModeChange();
handleSseModeChange();
#if BX_SUPPORT_AVX
handleAvxModeChange();
#endif
handleCpuContextChange();
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);
@ -2070,19 +2058,7 @@ void BX_CPU_C::VMexitLoadHostState(void)
// Update lazy flags state
setEFlagsOSZAPC(0);
#if BX_SUPPORT_MONITOR_MWAIT
BX_CPU_THIS_PTR monitor.reset_monitor();
#endif
invalidate_prefetch_q();
#if BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck();
#endif
handleCpuModeChange();
handleSseModeChange();
#if BX_SUPPORT_AVX
handleAvxModeChange();
#endif
handleCpuContextChange();
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);
}