Eliminate saving of RSP from heart of cpu_loop

Now save RSP only where it is really required
This commit is contained in:
Stanislav Shwartsman 2007-11-24 14:22:34 +00:00
parent d0052dcd3e
commit e51184c8cf
24 changed files with 427 additions and 98 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: dbg_main.cc,v 1.105 2007-11-01 20:53:20 sshwarts Exp $
// $Id: dbg_main.cc,v 1.106 2007-11-24 14:22:32 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -207,9 +207,9 @@ int bx_dbg_main(void)
// in the disassembly code to decide what instruction to print.
for (int i=0; i<BX_SMP_PROCESSORS; i++) {
BX_CPU(i)->guard_found.cs = BX_CPU(i)->sregs[BX_SEG_REG_CS].selector.value;
BX_CPU(i)->guard_found.eip = BX_CPU(i)->prev_eip;
BX_CPU(i)->guard_found.eip = BX_CPU(i)->prev_rip;
BX_CPU(i)->guard_found.laddr =
(BX_CPU(i)->get_segment_base(BX_SEG_REG_CS) + BX_CPU(i)->prev_eip);
(BX_CPU(i)->get_segment_base(BX_SEG_REG_CS) + BX_CPU(i)->prev_rip);
BX_CPU(i)->guard_found.is_32bit_code =
(BX_CPU(i)->sregs[BX_SEG_REG_CS].cache.u.segment.d_b);
BX_CPU(i)->guard_found.is_64bit_code =

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.182 2007-11-17 23:28:30 sshwarts Exp $
// $Id: cpu.cc,v 1.183 2007-11-24 14:22:32 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -220,8 +220,8 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count)
// back from an exception() call. In either case, commit the
// new EIP/ESP, and set up other environmental fields. This code
// mirrors similar code below, after the interrupt() call.
BX_CPU_THIS_PTR prev_eip = RIP; // commit new EIP
BX_CPU_THIS_PTR prev_esp = RSP; // commit new ESP
BX_CPU_THIS_PTR prev_rip = RIP; // commit new EIP
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_CPU_THIS_PTR EXT = 0;
BX_CPU_THIS_PTR errorno = 0;
@ -263,7 +263,7 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count)
#if BX_DEBUGGER
bx_dbg_disassemble_current(BX_CPU_ID, 1); // only one cpu, print time stamp
#else
debug_disasm_instruction(BX_CPU_THIS_PTR prev_eip);
debug_disasm_instruction(BX_CPU_THIS_PTR prev_rip);
#endif
}
#endif
@ -272,8 +272,7 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count)
BX_INSTR_BEFORE_EXECUTION(BX_CPU_ID, i);
RIP += i->ilen();
BX_CPU_CALL_METHOD(i->execute, (i)); // might iterate repeat instruction
BX_CPU_THIS_PTR prev_eip = RIP; // commit new RIP
BX_CPU_THIS_PTR prev_esp = RSP; // commit new RSP
BX_CPU_THIS_PTR prev_rip = RIP; // commit new RIP
BX_INSTR_AFTER_EXECUTION(BX_CPU_ID, i);
BX_TICK1_IF_SINGLE_PROCESSOR();
@ -353,7 +352,7 @@ void BX_CPU_C::repeat(bxInstruction_c *i, BxExecutePtr_t execute)
}
}
RIP = BX_CPU_THIS_PTR prev_eip; // repeat loop not done, restore RIP
RIP = BX_CPU_THIS_PTR prev_rip; // repeat loop not done, restore RIP
}
void BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePtr_t execute)
@ -428,7 +427,7 @@ void BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePtr_t execute)
}
}
RIP = BX_CPU_THIS_PTR prev_eip; // repeat loop not done, restore RIP
RIP = BX_CPU_THIS_PTR prev_rip; // repeat loop not done, restore RIP
}
unsigned BX_CPU_C::handleAsyncEvent(void)
@ -575,8 +574,8 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
// the new EIP/ESP values. But here, we call interrupt() much like
// it was a sofware interrupt instruction, and need to effect the
// commit here. This code mirrors similar code above.
BX_CPU_THIS_PTR prev_eip = RIP; // commit new RIP
BX_CPU_THIS_PTR prev_esp = RSP; // commit new RSP
BX_CPU_THIS_PTR prev_rip = RIP; // commit new RIP
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_CPU_THIS_PTR EXT = 0;
BX_CPU_THIS_PTR errorno = 0;
}
@ -627,7 +626,7 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
else {
// only bother comparing if any breakpoints enabled
if (BX_CPU_THIS_PTR dr7 & 0x000000ff) {
bx_address iaddr = BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_CS) + BX_CPU_THIS_PTR prev_eip;
bx_address iaddr = BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_CS) + BX_CPU_THIS_PTR prev_rip;
Bit32u dr6_bits = hwdebug_compare(iaddr, 1, BX_HWDebugInstruction, BX_HWDebugInstruction);
if (dr6_bits)
{
@ -785,7 +784,7 @@ void BX_CPU_C::boundaryFetch(Bit8u *fetchPtr, unsigned remainingInPage, bxInstru
}
// Restore EIP since we fudged it to start at the 2nd page boundary.
RIP = BX_CPU_THIS_PTR prev_eip;
RIP = BX_CPU_THIS_PTR prev_rip;
// Since we cross an instruction boundary, note that we need a prefetch()
// again on the next instruction. Perhaps we can optimize this to

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.374 2007-11-23 22:49:54 sshwarts Exp $
// $Id: cpu.h,v 1.375 2007-11-24 14:22:32 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -440,23 +440,29 @@ typedef struct {
(BX_CPU_THIS_PTR eflags.val32&~(1<<bitnum))|((val)<<bitnum); \
}
#if BX_SUPPORT_ALIGNMENT_CHECK
#if BX_SUPPORT_ALIGNMENT_CHECK && BX_CPU_LEVEL >= 4
#define DECLARE_EFLAG_ACCESSOR_AC(bitnum) \
BX_CPP_INLINE void clear_AC (); \
BX_CPP_INLINE void clear_AC(); \
BX_CPP_INLINE Bit32u get_AC(); \
BX_CPP_INLINE bx_bool getB_AC(); \
BX_CPP_INLINE void set_AC(bx_bool val); \
#define IMPLEMENT_EFLAG_ACCESSOR_AC(bitnum) \
BX_CPP_INLINE void BX_CPU_C::clear_AC () { \
BX_CPU_THIS_PTR eflags.val32 &= ~(1<<bitnum); \
BX_CPU_THIS_PTR alignment_check = 0; \
} \
BX_CPP_INLINE Bit32u BX_CPU_C::get_AC() { \
BX_CPP_INLINE Bit32u BX_CPU_C::get_AC() { \
return BX_CPU_THIS_PTR eflags.val32 & (1 << bitnum); \
} \
BX_CPP_INLINE Bit32u BX_CPU_C::getB_AC() { \
BX_CPP_INLINE Bit32u BX_CPU_C::getB_AC() { \
return 1 & (BX_CPU_THIS_PTR eflags.val32 >> bitnum); \
} \
BX_CPP_INLINE void BX_CPU_C::set_AC(bx_bool val) { \
BX_CPU_THIS_PTR eflags.val32 = \
(BX_CPU_THIS_PTR eflags.val32&~(1<<bitnum))|((val)<<bitnum); \
handleAlignmentCheck(); \
}
#endif
@ -1099,8 +1105,9 @@ public: // for now...
// so that we can back up when handling faults, exceptions, etc.
// we need to store the value of the instruction pointer, before
// each fetch/execute cycle.
bx_address prev_eip;
bx_address prev_esp;
bx_address prev_rip;
bx_address prev_rsp;
bx_bool speculative_rsp;
#define BX_INHIBIT_INTERRUPTS 0x01
#define BX_INHIBIT_DEBUG 0x02
@ -3276,7 +3283,7 @@ public: // for now...
DECLARE_EFLAG_ACCESSOR (ID, 21)
DECLARE_EFLAG_ACCESSOR (VIP, 20)
DECLARE_EFLAG_ACCESSOR (VIF, 19)
#if BX_SUPPORT_ALIGNMENT_CHECK
#if BX_SUPPORT_ALIGNMENT_CHECK && BX_CPU_LEVEL >= 4
DECLARE_EFLAG_ACCESSOR_AC( 18)
#else
DECLARE_EFLAG_ACCESSOR (AC, 18)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer16.cc,v 1.42 2007-11-18 18:24:45 sshwarts Exp $
// $Id: ctrl_xfer16.cc,v 1.43 2007-11-24 14:22:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -31,6 +31,11 @@
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR
// Make code more tidy with a few macros.
#if BX_SUPPORT_X86_64==0
#define RSP ESP
#endif
void BX_CPU_C::RETnear16_Iw(bxInstruction_c *i)
{
@ -40,6 +45,9 @@ void BX_CPU_C::RETnear16_Iw(bxInstruction_c *i)
BX_CPU_THIS_PTR show_flag |= Flag_ret;
#endif
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_16(&return_IP);
if (return_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
@ -55,7 +63,9 @@ void BX_CPU_C::RETnear16_Iw(bxInstruction_c *i)
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
ESP += imm16;
else
SP += imm16;
SP += imm16;
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, EIP);
}
@ -68,6 +78,9 @@ void BX_CPU_C::RETnear16(bxInstruction_c *i)
BX_CPU_THIS_PTR show_flag |= Flag_ret;
#endif
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_16(&return_IP);
if (return_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
@ -78,6 +91,8 @@ void BX_CPU_C::RETnear16(bxInstruction_c *i)
EIP = return_IP;
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, EIP);
}
@ -94,12 +109,13 @@ void BX_CPU_C::RETfar16_Iw(bxInstruction_c *i)
imm16 = i->Iw();
#if BX_CPU_LEVEL >= 2
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (protected_mode()) {
BX_CPU_THIS_PTR return_protected(i, imm16);
goto done;
}
#endif
pop_16(&ip);
pop_16(&cs_raw);
@ -110,9 +126,12 @@ void BX_CPU_C::RETfar16_Iw(bxInstruction_c *i)
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
ESP += imm16;
else
SP += imm16;
SP += imm16;
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
@ -127,12 +146,13 @@ void BX_CPU_C::RETfar16(bxInstruction_c *i)
BX_CPU_THIS_PTR show_flag |= Flag_ret;
#endif
#if BX_CPU_LEVEL >= 2
if ( protected_mode() ) {
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (protected_mode()) {
BX_CPU_THIS_PTR return_protected(i, 0);
goto done;
}
#endif
pop_16(&ip);
pop_16(&cs_raw);
@ -141,6 +161,9 @@ void BX_CPU_C::RETfar16(bxInstruction_c *i)
EIP = (Bit32u) ip;
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
@ -183,12 +206,13 @@ void BX_CPU_C::CALL16_Ap(bxInstruction_c *i)
disp16 = i->Iw();
cs_raw = i->Iw2();
#if BX_CPU_LEVEL >= 2
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (protected_mode()) {
BX_CPU_THIS_PTR call_protected(i, cs_raw, disp16);
goto done;
}
#endif
push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
push_16((Bit16u) EIP);
@ -197,6 +221,9 @@ void BX_CPU_C::CALL16_Ap(bxInstruction_c *i)
EIP = (Bit32u) disp16;
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
@ -216,13 +243,11 @@ void BX_CPU_C::CALL_Ew(bxInstruction_c *i)
read_virtual_word(i->seg(), RMAddr(i), &op1_16);
}
#if BX_CPU_LEVEL >= 2
if (op1_16 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
{
BX_ERROR(("CALL_Ew: IP out of CS limits!"));
exception(BX_GP_EXCEPTION, 0, 0);
}
#endif
push_16(IP);
EIP = op1_16;
@ -244,6 +269,9 @@ void BX_CPU_C::CALL16_Ep(bxInstruction_c *i)
read_virtual_word(i->seg(), RMAddr(i), &op1_16);
read_virtual_word(i->seg(), RMAddr(i)+2, &cs_raw);
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (protected_mode()) {
BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_16);
goto done;
@ -256,6 +284,9 @@ void BX_CPU_C::CALL16_Ep(bxInstruction_c *i)
EIP = op1_16;
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
@ -535,17 +566,20 @@ void BX_CPU_C::JMP16_Ep(bxInstruction_c *i)
read_virtual_word(i->seg(), RMAddr(i), &op1_16);
read_virtual_word(i->seg(), RMAddr(i)+2, &cs_raw);
#if BX_CPU_LEVEL >= 2
if ( protected_mode() ) {
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (protected_mode()) {
BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_16);
goto done;
}
#endif
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = op1_16;
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
@ -562,6 +596,9 @@ void BX_CPU_C::IRET16(bxInstruction_c *i)
BX_CPU_THIS_PTR nmi_disable = 0;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (v8086_mode()) {
// IOPL check in stack_return_from_v86()
iret16_stack_return_from_v86(i);
@ -587,6 +624,8 @@ void BX_CPU_C::IRET16(bxInstruction_c *i)
write_flags(flags, /* change IOPL? */ 1, /* change IF? */ 1);
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer32.cc,v 1.54 2007-11-17 18:08:46 sshwarts Exp $
// $Id: ctrl_xfer32.cc,v 1.55 2007-11-24 14:22:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -31,6 +31,10 @@
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR
// Make code more tidy with a few macros.
#if BX_SUPPORT_X86_64==0
#define RSP ESP
#endif
#if BX_CPU_LEVEL >= 3
@ -42,13 +46,18 @@ void BX_CPU_C::RETnear32_Iw(bxInstruction_c *i)
BX_CPU_THIS_PTR show_flag |= Flag_ret;
#endif
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
Bit16u imm16 = i->Iw();
pop_32(&return_EIP);
branch_near32(return_EIP);
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
ESP += imm16;
else
SP += imm16;
SP += imm16;
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, EIP);
}
@ -61,9 +70,14 @@ void BX_CPU_C::RETnear32(bxInstruction_c *i)
BX_CPU_THIS_PTR show_flag |= Flag_ret;
#endif
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_32(&return_EIP);
branch_near32(return_EIP);
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, EIP);
}
@ -79,6 +93,9 @@ void BX_CPU_C::RETfar32_Iw(bxInstruction_c *i)
Bit16u imm16 = i->Iw();
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (protected_mode()) {
BX_CPU_THIS_PTR return_protected(i, imm16);
goto done;
@ -93,9 +110,11 @@ void BX_CPU_C::RETfar32_Iw(bxInstruction_c *i)
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
ESP += imm16;
else
SP += imm16;
SP += imm16;
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
@ -110,7 +129,10 @@ void BX_CPU_C::RETfar32(bxInstruction_c *i)
BX_CPU_THIS_PTR show_flag |= Flag_ret;
#endif
if ( protected_mode() ) {
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (protected_mode()) {
BX_CPU_THIS_PTR return_protected(i, 0);
goto done;
}
@ -122,6 +144,8 @@ void BX_CPU_C::RETfar32(bxInstruction_c *i)
EIP = eip;
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
@ -160,6 +184,9 @@ void BX_CPU_C::CALL32_Ap(bxInstruction_c *i)
disp32 = i->Id();
cs_raw = i->Iw2();
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (protected_mode()) {
BX_CPU_THIS_PTR call_protected(i, cs_raw, disp32);
goto done;
@ -172,6 +199,8 @@ void BX_CPU_C::CALL32_Ap(bxInstruction_c *i)
EIP = disp32;
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
@ -218,7 +247,10 @@ void BX_CPU_C::CALL32_Ep(bxInstruction_c *i)
read_virtual_dword(i->seg(), RMAddr(i), &op1_32);
read_virtual_word(i->seg(), RMAddr(i)+4, &cs_raw);
if ( protected_mode() ) {
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (protected_mode()) {
BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_32);
goto done;
}
@ -230,6 +262,8 @@ void BX_CPU_C::CALL32_Ep(bxInstruction_c *i)
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
@ -480,6 +514,9 @@ void BX_CPU_C::JMP_Ap(bxInstruction_c *i)
}
cs_raw = i->Iw2();
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (protected_mode()) {
BX_CPU_THIS_PTR jump_protected(i, cs_raw, disp32);
}
@ -488,6 +525,8 @@ void BX_CPU_C::JMP_Ap(bxInstruction_c *i)
EIP = disp32;
}
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
@ -522,6 +561,9 @@ void BX_CPU_C::JMP32_Ep(bxInstruction_c *i)
read_virtual_dword(i->seg(), RMAddr(i), &op1_32);
read_virtual_word(i->seg(), RMAddr(i)+4, &cs_raw);
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (protected_mode()) {
BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_32);
}
@ -530,6 +572,8 @@ void BX_CPU_C::JMP32_Ep(bxInstruction_c *i)
EIP = op1_32;
}
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
@ -544,6 +588,9 @@ void BX_CPU_C::IRET32(bxInstruction_c *i)
BX_CPU_THIS_PTR nmi_disable = 0;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (v8086_mode()) {
// IOPL check in stack_return_from_v86()
iret32_stack_return_from_v86(i);
@ -579,6 +626,8 @@ void BX_CPU_C::IRET32(bxInstruction_c *i)
writeEFlags(eflags, 0x00257fd5); // VIF, VIP, VM unchanged
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer64.cc,v 1.53 2007-11-17 12:44:09 sshwarts Exp $
// $Id: ctrl_xfer64.cc,v 1.54 2007-11-24 14:22:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -44,6 +44,9 @@ void BX_CPU_C::RETnear64_Iw(bxInstruction_c *i)
Bit16u imm16 = i->Iw();
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_64(&return_RIP);
if (! IsCanonical(return_RIP)) {
@ -54,6 +57,8 @@ void BX_CPU_C::RETnear64_Iw(bxInstruction_c *i)
RIP = return_RIP;
RSP += imm16;
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, RIP);
}
@ -65,6 +70,9 @@ void BX_CPU_C::RETnear64(bxInstruction_c *i)
BX_CPU_THIS_PTR show_flag |= Flag_ret;
#endif
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_64(&return_RIP);
if (! IsCanonical(return_RIP)) {
@ -74,6 +82,8 @@ void BX_CPU_C::RETnear64(bxInstruction_c *i)
RIP = return_RIP;
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, RIP);
}
@ -87,10 +97,14 @@ void BX_CPU_C::RETfar64_Iw(bxInstruction_c *i)
BX_ASSERT(protected_mode());
BX_INFO(("RETfar64_Iw instruction executed ..."));
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
// return_protected is not RSP safe
return_protected(i, i->Iw());
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
}
@ -105,10 +119,14 @@ void BX_CPU_C::RETfar64(bxInstruction_c *i)
BX_ASSERT(protected_mode());
BX_INFO(("RETfar64 instruction executed ..."));
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
// return_protected is not RSP safe
return_protected(i, 0);
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
}
@ -177,7 +195,13 @@ void BX_CPU_C::CALL64_Ep(bxInstruction_c *i)
BX_ASSERT(protected_mode());
BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_32);
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
// call_protected is not RSP safe
call_protected(i, cs_raw, op1_32);
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
@ -430,7 +454,14 @@ void BX_CPU_C::JMP64_Ep(bxInstruction_c *i)
read_virtual_word(i->seg(), RMAddr(i)+4, &cs_raw);
BX_ASSERT(protected_mode());
BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_32);
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
// jump_protected is nto RSP safe
jump_protected(i, cs_raw, op1_32);
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
@ -447,7 +478,14 @@ void BX_CPU_C::IRET64(bxInstruction_c *i)
BX_CPU_THIS_PTR nmi_disable = 0;
BX_ASSERT(protected_mode());
iret_protected(i);
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
// long_iret is not RSP safe
long_iret(i);
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: debugstuff.cc,v 1.85 2007-11-08 18:21:37 sshwarts Exp $
// $Id: debugstuff.cc,v 1.86 2007-11-24 14:22:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -238,8 +238,8 @@ void BX_CPU_C::debug(bx_address offset)
#if BX_SUPPORT_X86_64
BX_INFO(("| RIP=%08x%08x (%08x%08x)",
(unsigned) BX_CPU_THIS_PTR eip_reg.dword.rip_upper, (unsigned) EIP,
(unsigned) (BX_CPU_THIS_PTR prev_eip >> 32),
(unsigned) (BX_CPU_THIS_PTR prev_eip & 0xffffffff)));
(unsigned) (BX_CPU_THIS_PTR prev_rip >> 32),
(unsigned) (BX_CPU_THIS_PTR prev_rip & 0xffffffff)));
BX_INFO(("| CR0=0x%08x CR1=0x%x CR2=0x%08x%08x",
(unsigned) (BX_CPU_THIS_PTR cr0.val32), 0,
(unsigned) (BX_CPU_THIS_PTR cr2 >> 32),
@ -248,7 +248,7 @@ void BX_CPU_C::debug(bx_address offset)
(unsigned) BX_CPU_THIS_PTR cr3, BX_CPU_THIS_PTR cr4.getRegister()));
#else
BX_INFO(("| EIP=%08x (%08x)", (unsigned) EIP,
(unsigned) BX_CPU_THIS_PTR prev_eip));
(unsigned) BX_CPU_THIS_PTR prev_rip));
#if BX_CPU_LEVEL >= 2 && BX_CPU_LEVEL < 4
BX_INFO(("| CR0=0x%08x CR1=%x CR2=0x%08x CR3=0x%08x",
@ -440,5 +440,5 @@ void BX_CPU_C::dbg_get_idtr(bx_dbg_global_sreg_t *sreg)
void BX_CPU_C::atexit(void)
{
debug(BX_CPU_THIS_PTR prev_eip);
debug(BX_CPU_THIS_PTR prev_rip);
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: exception.cc,v 1.95 2007-11-06 19:17:42 sshwarts Exp $
// $Id: exception.cc,v 1.96 2007-11-24 14:22:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -851,7 +851,7 @@ void BX_CPU_C::exception(unsigned vector, Bit16u error_code, bx_bool is_INT)
// if 1st was a double fault (software INT?), then shutdown
(BX_CPU_THIS_PTR errorno == 2 && BX_CPU_THIS_PTR curr_exception[0]==BX_ET_DOUBLE_FAULT))
{
debug(BX_CPU_THIS_PTR prev_eip); // print debug information to the log
debug(BX_CPU_THIS_PTR prev_rip); // print debug information to the log
#if BX_DEBUGGER
// trap into debugger (similar as done when PANIC occured)
bx_debug_break();
@ -998,8 +998,9 @@ void BX_CPU_C::exception(unsigned vector, Bit16u error_code, bx_bool is_INT)
if (exception_class == BX_EXCEPTION_CLASS_FAULT)
{
// restore RIP/RSP to value before error occurred
RIP = BX_CPU_THIS_PTR prev_eip;
RSP = BX_CPU_THIS_PTR prev_esp;
RIP = BX_CPU_THIS_PTR prev_rip;
if (BX_CPU_THIS_PTR speculative_rsp)
RSP = BX_CPU_THIS_PTR prev_rsp;
if (vector != BX_DB_EXCEPTION) BX_CPU_THIS_PTR assert_RF();
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode64.cc,v 1.147 2007-11-23 16:37:06 sshwarts Exp $
// $Id: fetchdecode64.cc,v 1.148 2007-11-24 14:22:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -909,7 +909,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64R[512*3] = {
/* CC /dr */ { 0, &BX_CPU_C::INT3 },
/* CD /dr */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib },
/* CE /dr */ { 0, &BX_CPU_C::BxError },
/* CF /dr */ { 0, &BX_CPU_C::IRET32 },
/* CF /dr */ { 0, &BX_CPU_C::IRET64 },
/* D0 /dr */ { BxGroup2, NULL, BxOpcodeInfoG2Eb },
/* D1 /dr */ { BxGroup2, NULL, BxOpcodeInfoG2Ed },
/* D2 /dr */ { BxGroup2, NULL, BxOpcodeInfoG2Eb },
@ -1973,7 +1973,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64M[512*3] = {
/* CC /wm */ { 0, &BX_CPU_C::INT3 },
/* CD /wm */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib },
/* CE /wm */ { 0, &BX_CPU_C::BxError },
/* CF /wm */ { 0, &BX_CPU_C::IRET16 },
/* CF /wm */ { 0, &BX_CPU_C::IRET64 },
/* D0 /wm */ { BxGroup2, NULL, BxOpcodeInfoG2Eb },
/* D1 /wm */ { BxGroup2, NULL, BxOpcodeInfoG2Ew },
/* D2 /wm */ { BxGroup2, NULL, BxOpcodeInfoG2Eb },
@ -2502,7 +2502,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64M[512*3] = {
/* CC /dm */ { 0, &BX_CPU_C::INT3 },
/* CD /dm */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib },
/* CE /dm */ { 0, &BX_CPU_C::BxError },
/* CF /dm */ { 0, &BX_CPU_C::IRET32 },
/* CF /dm */ { 0, &BX_CPU_C::IRET64 },
/* D0 /dm */ { BxGroup2, NULL, BxOpcodeInfoG2Eb },
/* D1 /dm */ { BxGroup2, NULL, BxOpcodeInfoG2Ed },
/* D2 /dm */ { BxGroup2, NULL, BxOpcodeInfoG2Eb },

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: flag_ctrl.cc,v 1.31 2007-11-22 21:52:55 sshwarts Exp $
// $Id: flag_ctrl.cc,v 1.32 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -31,6 +31,11 @@
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR
// Make code more tidy with a few macros.
#if BX_SUPPORT_X86_64==0
#define RSP ESP
#endif
void BX_CPU_C::SAHF(bxInstruction_c *i)
{
@ -214,6 +219,9 @@ void BX_CPU_C::POPF_Fw(bxInstruction_c *i)
BX_DEBUG(("POPFW: #GP(0) in v8086 (no VME) mode"));
exception(BX_GP_EXCEPTION, 0, 0);
}
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_16(&flags16);
#if BX_SUPPORT_VME
if (CR4_VME_ENABLED && BX_CPU_THIS_PTR get_IOPL() < 3) {
@ -233,6 +241,8 @@ void BX_CPU_C::POPF_Fw(bxInstruction_c *i)
}
#endif
changeMask |= EFlagsIFMask;
BX_CPU_THIS_PTR speculative_rsp = 0;
}
else {
pop_16(&flags16);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: init.cc,v 1.144 2007-11-18 21:07:40 sshwarts Exp $
// $Id: init.cc,v 1.145 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -718,9 +718,9 @@ void BX_CPU_C::reset(unsigned source)
/* instruction pointer */
#if BX_CPU_LEVEL < 2
BX_CPU_THIS_PTR prev_eip = EIP = 0x00000000;
BX_CPU_THIS_PTR prev_rip = EIP = 0x00000000;
#else /* from 286 up */
BX_CPU_THIS_PTR prev_eip = RIP = 0x0000FFF0;
BX_CPU_THIS_PTR prev_rip = RIP = 0x0000FFF0;
#endif
/* CS (Code Segment) and descriptor cache */

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////
// $Id: iret.cc,v 1.22 2007-11-17 23:28:31 sshwarts Exp $
// $Id: iret.cc,v 1.23 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005 Stanislav Shwartsman
@ -47,7 +47,7 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
}
#endif
if (BX_CPU_THIS_PTR get_NT ()) /* NT = 1: RETURN FROM NESTED TASK */
if (BX_CPU_THIS_PTR get_NT()) /* NT = 1: RETURN FROM NESTED TASK */
{
/* what's the deal with NT & VM ? */
Bit16u raw_link_selector;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: resolve64.cc,v 1.13 2007-11-18 19:46:14 sshwarts Exp $
// $Id: resolve64.cc,v 1.14 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -38,13 +38,13 @@
BX_CPU_C::BxResolve32Rip(bxInstruction_c *i)
{
// RIP hasn't been bumped yet when this is called. must choose the saved value.
RMAddr(i) = (Bit32u) (BX_CPU_THIS_PTR prev_eip + i->ilen() + (Bit32s) i->displ32u());
RMAddr(i) = (Bit32u) (BX_CPU_THIS_PTR prev_rip + i->ilen() + (Bit32s) i->displ32u());
}
void BX_CPP_AttrRegparmN(1)
BX_CPU_C::BxResolve64Rip(bxInstruction_c *i)
{
// RIP hasn't been bumped yet when this is called. must choose the saved value.
RMAddr(i) = BX_CPU_THIS_PTR prev_eip + i->ilen() + (Bit32s) i->displ32u();
RMAddr(i) = BX_CPU_THIS_PTR prev_rip + i->ilen() + (Bit32s) i->displ32u();
}
void BX_CPP_AttrRegparmN(1)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: segment_ctrl_pro.cc,v 1.75 2007-11-20 21:22:03 sshwarts Exp $
// $Id: segment_ctrl_pro.cc,v 1.76 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -684,7 +684,7 @@ BX_CPU_C::fetch_raw_descriptor(const bx_selector_t *selector,
else { /* LDT */
if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
BX_PANIC(("fetch_raw_descriptor: LDTR.valid=0"));
debug(BX_CPU_THIS_PTR prev_eip);
debug(BX_CPU_THIS_PTR prev_rip);
}
if ((index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled) {
BX_ERROR(("fetch_raw_descriptor: LDT: index (%x)%x > limit (%x)",
@ -746,7 +746,7 @@ void BX_CPU_C::fetch_raw_descriptor64(const bx_selector_t *selector,
else { /* LDT */
if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
BX_PANIC(("fetch_raw_descriptor: LDTR.valid=0"));
debug(BX_CPU_THIS_PTR prev_eip);
debug(BX_CPU_THIS_PTR prev_rip);
}
if ((index*8 + 15) > BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled) {
BX_ERROR(("fetch_raw_descriptor64: LDT: index (%x)%x > limit (%x)",

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: smm.cc,v 1.28 2007-11-20 21:22:03 sshwarts Exp $
// $Id: smm.cc,v 1.29 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006 Stanislav Shwartsman
@ -106,7 +106,7 @@ void BX_CPU_C::enter_system_management_mode(void)
BX_INFO(("Enter to System Management Mode"));
// debug(BX_CPU_THIS_PTR prev_eip);
// debug(BX_CPU_THIS_PTR prev_rip);
BX_CPU_THIS_PTR in_smm = 1;
@ -124,7 +124,7 @@ void BX_CPU_C::enter_system_management_mode(void)
}
BX_CPU_THIS_PTR setEFlags(0x2); // Bit1 is always set
BX_CPU_THIS_PTR prev_eip = RIP = 0x00008000;
BX_CPU_THIS_PTR prev_rip = RIP = 0x00008000;
BX_CPU_THIS_PTR dr7 = 0x00000400;
// CR0 - PE, EM, TS, and PG flags set to 0; others unmodified

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: soft_int.cc,v 1.34 2007-11-17 23:28:32 sshwarts Exp $
// $Id: soft_int.cc,v 1.35 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -34,6 +34,11 @@
#include "extdb.h"
#endif
// Make code more tidy with a few macros.
#if BX_SUPPORT_X86_64==0
#define RSP ESP
#endif
void BX_CPU_C::BOUND_GwMa(bxInstruction_c *i)
{
Bit16s bound_min, bound_max;
@ -75,7 +80,14 @@ void BX_CPU_C::INT1(bxInstruction_c *i)
trap_debugger(0);
#endif
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
// interrupt is not RSP safe
interrupt(1, 1, 0, 0);
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
EIP);
@ -89,7 +101,14 @@ void BX_CPU_C::INT3(bxInstruction_c *i)
BX_CPU_THIS_PTR show_flag |= Flag_softint;
#endif
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
// interrupt is not RSP safe
interrupt(3, 1, 0, 0);
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
EIP);
@ -104,6 +123,9 @@ void BX_CPU_C::INT_Ib(bxInstruction_c *i)
Bit8u vector = i->Ib();
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
if (v8086_mode()) {
#if BX_SUPPORT_VME
if (BX_CPU_THIS_PTR cr4.get_VME())
@ -120,7 +142,7 @@ void BX_CPU_C::INT_Ib(bxInstruction_c *i)
{
// redirect interrupt through virtual-mode idt
v86_redirect_interrupt(vector);
return;
goto done;
}
}
#endif
@ -139,6 +161,11 @@ void BX_CPU_C::INT_Ib(bxInstruction_c *i)
#endif
interrupt(vector, 1, 0, 0);
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
EIP);
@ -151,7 +178,14 @@ void BX_CPU_C::INTO(bxInstruction_c *i)
#endif
if (get_OF()) {
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
// interrupt is not RSP safe
interrupt(4, 1, 0, 0);
BX_CPU_THIS_PTR speculative_rsp = 0;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_INT,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
EIP);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: stack16.cc,v 1.26 2007-11-20 17:15:33 sshwarts Exp $
// $Id: stack16.cc,v 1.27 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -30,6 +30,10 @@
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR
// Make code more tidy with a few macros.
#if BX_SUPPORT_X86_64==0
#define RSP ESP
#endif
void BX_CPU_C::PUSH_RX(bxInstruction_c *i)
{
@ -69,37 +73,68 @@ void BX_CPU_C::PUSH16_SS(bxInstruction_c *i)
void BX_CPU_C::POP16_DS(bxInstruction_c *i)
{
Bit16u ds;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_16(&ds);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], ds);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::POP16_ES(bxInstruction_c *i)
{
Bit16u es;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_16(&es);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], es);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::POP16_FS(bxInstruction_c *i)
{
Bit16u fs;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_16(&fs);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], fs);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::POP16_GS(bxInstruction_c *i)
{
Bit16u gs;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_16(&gs);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], gs);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::POP16_SS(bxInstruction_c *i)
{
Bit16u ss;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_16(&ss);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], ss);
BX_CPU_THIS_PTR speculative_rsp = 0;
// POP SS inhibits interrupts, debug exceptions and single-step
// trap exceptions until the execution boundary following the
// next instruction is reached.
@ -120,6 +155,9 @@ void BX_CPU_C::POP_EwM(bxInstruction_c *i)
{
Bit16u val16;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_16(&val16);
// Note: there is one little weirdism here. It is possible to use
@ -129,6 +167,8 @@ void BX_CPU_C::POP_EwM(bxInstruction_c *i)
BX_CPU_CALL_METHODR (i->ResolveModrm, (i));
}
write_virtual_word(i->seg(), RMAddr(i), &val16);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::POP_EwR(bxInstruction_c *i)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: stack32.cc,v 1.40 2007-11-22 17:33:06 sshwarts Exp $
// $Id: stack32.cc,v 1.41 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -30,10 +30,18 @@
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR
// Make code more tidy with a few macros.
#if BX_SUPPORT_X86_64==0
#define RSP ESP
#endif
void BX_CPU_C::POP_EdM(bxInstruction_c *i)
{
Bit32u val32;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_32(&val32);
// Note: there is one little weirdism here. It is possible to use
@ -44,6 +52,8 @@ void BX_CPU_C::POP_EdM(bxInstruction_c *i)
BX_CPU_CALL_METHODR (i->ResolveModrm, (i));
}
write_virtual_dword(i->seg(), RMAddr(i), &val32);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::POP_EdR(bxInstruction_c *i)
@ -79,6 +89,13 @@ void BX_CPU_C::PUSH32_DS(bxInstruction_c *i)
decrementESPForPush(4, &eSP);
write_virtual_word(BX_SEG_REG_SS, eSP,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
ESP = eSP;
}
else {
SP = (Bit16u) eSP;
}
}
void BX_CPU_C::PUSH32_ES(bxInstruction_c *i)
@ -87,6 +104,13 @@ void BX_CPU_C::PUSH32_ES(bxInstruction_c *i)
decrementESPForPush(4, &eSP);
write_virtual_word(BX_SEG_REG_SS, eSP,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
ESP = eSP;
}
else {
SP = (Bit16u) eSP;
}
}
void BX_CPU_C::PUSH32_FS(bxInstruction_c *i)
@ -95,6 +119,13 @@ void BX_CPU_C::PUSH32_FS(bxInstruction_c *i)
decrementESPForPush(4, &eSP);
write_virtual_word(BX_SEG_REG_SS, eSP,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
ESP = eSP;
}
else {
SP = (Bit16u) eSP;
}
}
void BX_CPU_C::PUSH32_GS(bxInstruction_c *i)
@ -103,6 +134,13 @@ void BX_CPU_C::PUSH32_GS(bxInstruction_c *i)
decrementESPForPush(4, &eSP);
write_virtual_word(BX_SEG_REG_SS, eSP,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
ESP = eSP;
}
else {
SP = (Bit16u) eSP;
}
}
void BX_CPU_C::PUSH32_SS(bxInstruction_c *i)
@ -111,42 +149,79 @@ void BX_CPU_C::PUSH32_SS(bxInstruction_c *i)
decrementESPForPush(4, &eSP);
write_virtual_word(BX_SEG_REG_SS, eSP,
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
ESP = eSP;
}
else {
SP = (Bit16u) eSP;
}
}
void BX_CPU_C::POP32_DS(bxInstruction_c *i)
{
Bit32u ds;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_32(&ds);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], (Bit16u) ds);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::POP32_ES(bxInstruction_c *i)
{
Bit32u es;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_32(&es);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], (Bit16u) es);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::POP32_FS(bxInstruction_c *i)
{
Bit32u fs;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_32(&fs);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], (Bit16u) fs);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::POP32_GS(bxInstruction_c *i)
{
Bit32u gs;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_32(&gs);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], (Bit16u) gs);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::POP32_SS(bxInstruction_c *i)
{
Bit32u ss;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_32(&ss);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], (Bit16u) ss);
BX_CPU_THIS_PTR speculative_rsp = 0;
// POP SS inhibits interrupts, debug exceptions and single-step
// trap exceptions until the execution boundary following the
// next instruction is reached.
@ -254,6 +329,9 @@ void BX_CPU_C::ENTER16_IwIb(bxInstruction_c *i)
Bit8u level = i->Ib2();
level &= 0x1F;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
Bit32u ebp; // Use temp copy in case of exception.
push_16(BP);
@ -286,6 +364,8 @@ void BX_CPU_C::ENTER16_IwIb(bxInstruction_c *i)
push_16((Bit16u)frame_ptr32);
}
BX_CPU_THIS_PTR speculative_rsp = 0;
if (ss32) {
EBP = frame_ptr32;
ESP -= imm16;
@ -304,6 +384,9 @@ void BX_CPU_C::ENTER32_IwIb(bxInstruction_c *i)
Bit8u level = i->Ib2();
level &= 0x1F;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
Bit32u ebp; // Use temp copy in case of exception.
push_32(EBP);
@ -336,6 +419,8 @@ void BX_CPU_C::ENTER32_IwIb(bxInstruction_c *i)
push_32(frame_ptr32);
}
BX_CPU_THIS_PTR speculative_rsp = 0;
if (ss32) {
EBP = frame_ptr32;
ESP -= imm16;
@ -372,13 +457,16 @@ void BX_CPU_C::LEAVE(bxInstruction_c *i)
}
}
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
// delete frame
#if BX_CPU_LEVEL >= 3
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
ESP = EBP;
else
#endif
SP = BP;
SP = BP;
// restore frame pointer
#if BX_CPU_LEVEL >= 3
@ -394,5 +482,7 @@ void BX_CPU_C::LEAVE(bxInstruction_c *i)
pop_16(&temp16);
BP = temp16;
}
BX_CPU_THIS_PTR speculative_rsp = 0;
}
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: stack64.cc,v 1.28 2007-11-22 21:52:55 sshwarts Exp $
// $Id: stack64.cc,v 1.29 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -36,6 +36,9 @@ void BX_CPU_C::POP_EqM(bxInstruction_c *i)
{
Bit64u val64;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_64(&val64);
// Note: there is one little weirdism here. It is possible to use
@ -46,6 +49,8 @@ void BX_CPU_C::POP_EqM(bxInstruction_c *i)
BX_CPU_CALL_METHODR (i->ResolveModrm, (i));
}
write_virtual_qword(i->seg(), RMAddr(i), &val64);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::POP_EqR(bxInstruction_c *i)
@ -57,7 +62,7 @@ void BX_CPU_C::POP_EqR(bxInstruction_c *i)
void BX_CPU_C::PUSH_RRX(bxInstruction_c *i)
{
push_64(BX_CPU_THIS_PTR gen_reg[i->opcodeReg()].rrx);
push_64(BX_READ_64BIT_REG(i->opcodeReg()));
}
void BX_CPU_C::POP_RRX(bxInstruction_c *i)
@ -80,15 +85,27 @@ void BX_CPU_C::PUSH64_GS(bxInstruction_c *i)
void BX_CPU_C::POP64_FS(bxInstruction_c *i)
{
Bit64u fs;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_64(&fs);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], (Bit16u) fs);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::POP64_GS(bxInstruction_c *i)
{
Bit64u gs;
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
pop_64(&gs);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], (Bit16u) gs);
BX_CPU_THIS_PTR speculative_rsp = 0;
}
void BX_CPU_C::PUSH64_Id(bxInstruction_c *i)
@ -118,6 +135,9 @@ void BX_CPU_C::ENTER64_IwIb(bxInstruction_c *i)
level &= 0x1F;
Bit64u bytes_to_push = 8 + level*8 + i->Iw();
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
push_64(RBP);
Bit64u frame_ptr64 = RSP;
@ -138,13 +158,17 @@ void BX_CPU_C::ENTER64_IwIb(bxInstruction_c *i)
write_virtual_qword(BX_SEG_REG_SS, RSP, &frame_ptr64);
} /* if (level > 0) ... */
RBP = frame_ptr64;
BX_CPU_THIS_PTR speculative_rsp = 0;
RBP = frame_ptr64;
RSP -= i->Iw();
}
void BX_CPU_C::LEAVE64(bxInstruction_c *i)
{
BX_CPU_THIS_PTR speculative_rsp = 1;
BX_CPU_THIS_PTR prev_rsp = RSP;
// delete frame
RSP = RBP;
@ -152,6 +176,8 @@ void BX_CPU_C::LEAVE64(bxInstruction_c *i)
Bit64u temp64;
pop_64(&temp64);
RBP = temp64;
BX_CPU_THIS_PTR speculative_rsp = 0;
}
#endif /* if BX_SUPPORT_X86_64 */

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: stack_pro.cc,v 1.31 2007-11-17 23:28:33 sshwarts Exp $
// $Id: stack_pro.cc,v 1.32 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -353,11 +353,9 @@ void BX_CPU_C::decrementESPForPush(unsigned nBytes, Bit32u *eSP_ptr)
// And finally, decrement eSP and return the new eSP value.
eSP -= nBytes;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
ESP = eSP;
*eSP_ptr = eSP;
}
else {
SP = (Bit16u) eSP;
*eSP_ptr = SP;
}
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: tasking.cc,v 1.41 2007-11-20 21:22:03 sshwarts Exp $
// $Id: tasking.cc,v 1.42 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -429,7 +429,7 @@ void BX_CPU_C::task_switch(bx_selector_t *tss_selector,
}
}
BX_CPU_THIS_PTR prev_eip = EIP = newEIP;
BX_CPU_THIS_PTR prev_rip = EIP = newEIP;
EAX = newEAX;
ECX = newECX;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fpu.cc,v 1.26 2007-10-30 18:52:25 sshwarts Exp $
// $Id: fpu.cc,v 1.27 2007-11-24 14:22:34 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2003 Stanislav Shwartsman
@ -47,7 +47,7 @@ void BX_CPU_C::prepareFPU(bxInstruction_c *i,
{
BX_CPU_THIS_PTR the_i387.foo = ((Bit32u)(i->b1()) << 8) | (Bit32u)(i->modrm()) & 0x7ff;
BX_CPU_THIS_PTR the_i387.fcs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
BX_CPU_THIS_PTR the_i387.fip = BX_CPU_THIS_PTR prev_eip;
BX_CPU_THIS_PTR the_i387.fip = BX_CPU_THIS_PTR prev_rip;
if (! i->modC0()) {
BX_CPU_THIS_PTR the_i387.fds = BX_CPU_THIS_PTR sregs[i->seg()].selector.value;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: load32bitOShack.cc,v 1.23 2007-10-18 22:44:38 sshwarts Exp $
// $Id: load32bitOShack.cc,v 1.24 2007-11-24 14:22:32 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -235,8 +235,7 @@ void bx_load_null_kernel_hack(void)
bx_load_kernel_image(SIM->get_param_string(BXPN_LOAD32BITOS_PATH)->getptr(), 0x100000);
// EIP deltas
BX_CPU(0)->prev_eip =
BX_CPU(0)->eip_reg.dword.eip = 0x00100000;
BX_CPU(0)->prev_rip = BX_CPU(0)->eip_reg.dword.eip = 0x00100000;
// CS deltas
BX_CPU(0)->sregs[BX_SEG_REG_CS].cache.u.segment.base = 0x00000000;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
//// $Id: plex86-interface.cc,v 1.9 2007-10-18 22:44:38 sshwarts Exp $
//// $Id: plex86-interface.cc,v 1.10 2007-11-24 14:22:32 sshwarts Exp $
///////////////////////////////////////////////////////////////////////////
////
//// Copyright (C) 2002 Kevin P. Lawton
@ -305,8 +305,7 @@ void copyPlex86StateToBochs(BX_CPU_C *cpu)
cpu->eip_reg.dword.eip = plex86GuestCPU->eip;
// Set fields used for exception processing.
cpu->prev_eip = plex86GuestCPU->eip;
cpu->prev_esp = plex86GuestCPU->esp;
cpu->prev_rip = plex86GuestCPU->eip;
// ES/CS/SS/DS/FS/GS
for (unsigned s=0; s<6; s++) {