Reorganize ctrl_xfer8.cc code, allows to inline branch32 method

This commit is contained in:
Stanislav Shwartsman 2008-06-22 03:45:55 +00:00
parent 599a9b2e32
commit 678ac970aa
10 changed files with 469 additions and 369 deletions

View File

@ -89,7 +89,6 @@ OBJS = \
logical32.o \
arith16.o \
segment_ctrl.o \
ctrl_xfer8.o \
data_xfer16.o \
data_xfer32.o \
exception.o \
@ -344,15 +343,6 @@ ctrl_xfer64.o: ctrl_xfer64.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
lazy_flags.h icache.h apic.h ../cpu/i387.h ../fpu/softfloat.h \
../config.h ../fpu/tag_w.h ../fpu/status_w.h ../fpu/control_w.h \
../cpu/xmm.h stack.h
ctrl_xfer8.o: ctrl_xfer8.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \
../gui/siminterface.h ../memory/memory.h ../pc_system.h ../plugin.h \
../extplugin.h ../gui/gui.h ../gui/textconfig.h ../config.h \
../gui/keymap.h ../instrument/stubs/instrument.h cpu.h \
../disasm/disasm.h ../config.h crregs.h descriptor.h instr.h \
lazy_flags.h icache.h apic.h ../cpu/i387.h ../fpu/softfloat.h \
../config.h ../fpu/tag_w.h ../fpu/status_w.h ../fpu/control_w.h \
../cpu/xmm.h stack.h
ctrl_xfer_pro.o: ctrl_xfer_pro.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \
../gui/siminterface.h ../memory/memory.h ../pc_system.h ../plugin.h \

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.488 2008-06-13 08:17:52 sshwarts Exp $
// $Id: cpu.h,v 1.489 2008-06-22 03:45:53 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1228,10 +1228,14 @@ public: // for now...
BX_SMF void SALC(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void XLAT(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOOPNE_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOOPE_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOOP_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOOPNE16_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOOPE16_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOOP16_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOOPNE32_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOOPE32_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOOP32_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void JCXZ_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void JECXZ_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void IN_ALIb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void IN_AXIb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void IN_EAXIb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
@ -2743,7 +2747,7 @@ public: // for now...
BX_SMF void LOOPNE64_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOOPE64_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void LOOP64_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void JCXZ64_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void JRCXZ_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void MOVQ_EqPq(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void MOVQ_EqVq(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
@ -3000,6 +3004,7 @@ public: // for now...
BX_SMF Bit8u* v2h_write(bx_address laddr, unsigned curr_pl, unsigned len) BX_CPP_AttrRegparmN(3);
#endif
BX_SMF void branch_near16(Bit16u new_IP) BX_CPP_AttrRegparmN(1);
BX_SMF void branch_near32(Bit32u new_EIP) BX_CPP_AttrRegparmN(1);
#if BX_SUPPORT_X86_64
BX_SMF void branch_near64(bxInstruction_c *) BX_CPP_AttrRegparmN(1);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer16.cc,v 1.56 2008-06-12 20:27:38 sshwarts Exp $
// $Id: ctrl_xfer16.cc,v 1.57 2008-06-22 03:45:53 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -33,8 +33,26 @@
// Make code more tidy with a few macros.
#if BX_SUPPORT_X86_64==0
#define RSP ESP
#define RIP EIP
#endif
BX_CPP_INLINE void BX_CPP_AttrRegparmN(1) BX_CPU_C::branch_near16(Bit16u new_IP)
{
// check always, not only in protected mode
if (new_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
{
BX_ERROR(("branch_near16: offset outside of CS limits"));
exception(BX_GP_EXCEPTION, 0, 0);
}
RIP = new_IP;
#if BX_SUPPORT_TRACE_CACHE && !defined(BX_TRACE_CACHE_NO_SPECULATIVE_TRACING)
// assert magic async_event to stop trace execution
BX_CPU_THIS_PTR async_event |= BX_ASYNC_EVENT_STOP_TRACE;
#endif
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear16_Iw(bxInstruction_c *i)
{
#if BX_DEBUGGER
@ -52,7 +70,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear16_Iw(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0, 0);
}
EIP = return_IP;
RIP = return_IP;
Bit16u imm16 = i->Iw();
@ -83,7 +101,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear16(bxInstruction_c *i)
exception(BX_GP_EXCEPTION, 0, 0);
}
EIP = return_IP;
RIP = return_IP;
BX_CPU_THIS_PTR speculative_rsp = 0;
@ -115,7 +133,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETfar16_Iw(bxInstruction_c *i)
cs_raw = pop_16();
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = (Bit32u) ip;
RIP = (Bit32u) ip;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
ESP += imm16;
@ -152,7 +170,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETfar16(bxInstruction_c *i)
cs_raw = pop_16();
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = (Bit32u) ip;
RIP = (Bit32u) ip;
done:
@ -164,24 +182,21 @@ done:
void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_Jw(bxInstruction_c *i)
{
Bit32u new_EIP;
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call;
#endif
new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
if (new_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
{
BX_ERROR(("CALL_Jw: new_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].limit"));
BX_ERROR(("CALL_Jw: IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].limit"));
exception(BX_GP_EXCEPTION, 0, 0);
}
/* push 16 bit EA of next instruction */
push_16(IP);
EIP = new_EIP;
RIP = new_IP;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, EIP);
}
@ -212,7 +227,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL16_Ap(bxInstruction_c *i)
push_16((Bit16u) EIP);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = (Bit32u) disp16;
RIP = (Bit32u) disp16;
done:
@ -239,7 +254,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_EwM(bxInstruction_c *i)
}
push_16(IP);
EIP = op1_16;
RIP = op1_16;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, EIP);
}
@ -259,7 +274,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_EwR(bxInstruction_c *i)
}
push_16(IP);
EIP = op1_16;
RIP = op1_16;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, EIP);
}
@ -292,7 +307,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL16_Ep(bxInstruction_c *i)
push_16(IP);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = op1_16;
RIP = op1_16;
done:
@ -304,27 +319,17 @@ done:
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_Jw(bxInstruction_c *i)
{
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
{
BX_ERROR(("JMP_Jw: offset outside of CS limits"));
exception(BX_GP_EXCEPTION, 0, 0);
}
EIP = new_EIP;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, new_IP);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JO_Jw(bxInstruction_c *i)
{
if (get_OF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -334,10 +339,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JO_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNO_Jw(bxInstruction_c *i)
{
if (! get_OF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -347,10 +351,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNO_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JB_Jw(bxInstruction_c *i)
{
if (get_CF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -360,10 +363,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JB_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNB_Jw(bxInstruction_c *i)
{
if (! get_CF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -373,10 +375,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNB_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JZ_Jw(bxInstruction_c *i)
{
if (get_ZF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -386,10 +387,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JZ_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNZ_Jw(bxInstruction_c *i)
{
if (! get_ZF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -399,10 +399,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNZ_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JBE_Jw(bxInstruction_c *i)
{
if (get_CF() || get_ZF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -412,10 +411,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JBE_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNBE_Jw(bxInstruction_c *i)
{
if (! (get_CF() || get_ZF())) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -425,10 +423,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNBE_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JS_Jw(bxInstruction_c *i)
{
if (get_SF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -438,10 +435,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JS_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNS_Jw(bxInstruction_c *i)
{
if (! get_SF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -451,10 +447,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNS_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JP_Jw(bxInstruction_c *i)
{
if (get_PF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -464,10 +459,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JP_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNP_Jw(bxInstruction_c *i)
{
if (! get_PF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -477,10 +471,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNP_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JL_Jw(bxInstruction_c *i)
{
if (getB_SF() != getB_OF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -490,10 +483,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JL_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNL_Jw(bxInstruction_c *i)
{
if (getB_SF() == getB_OF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -503,10 +495,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNL_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JLE_Jw(bxInstruction_c *i)
{
if (get_ZF() || (getB_SF() != getB_OF())) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -516,10 +507,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JLE_Jw(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JNLE_Jw(bxInstruction_c *i)
{
if (! get_ZF() && (getB_SF() == getB_OF())) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
@ -531,14 +521,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_EwM(bxInstruction_c *i)
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
Bit16u new_IP = read_virtual_word(i->seg(), RMAddr(i));
if (new_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
{
BX_ERROR(("JMP_Ew: offset outside of CS limits"));
exception(BX_GP_EXCEPTION, 0, 0);
}
EIP = new_IP;
branch_near16(new_IP);
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, new_IP);
}
@ -546,15 +529,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_EwM(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_EwR(bxInstruction_c *i)
{
Bit16u new_IP = BX_READ_16BIT_REG(i->rm());
if (new_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
{
BX_ERROR(("JMP_Ew: offset outside of CS limits"));
exception(BX_GP_EXCEPTION, 0, 0);
}
EIP = new_IP;
branch_near16(new_IP);
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, new_IP);
}
@ -578,7 +553,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP16_Ep(bxInstruction_c *i)
}
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = op1_16;
RIP = op1_16;
done:
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP,
@ -616,7 +591,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET16(bxInstruction_c *i)
flags = pop_16();
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = (Bit32u) ip;
RIP = (Bit32u) ip;
write_flags(flags, /* change IOPL? */ 1, /* change IF? */ 1);
done:
@ -625,3 +600,158 @@ done:
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JCXZ_Jb(bxInstruction_c *i)
{
// it is impossible to get this instruction in long mode
BX_ASSERT(i->as64L() == 0);
Bit32u temp_ECX;
if (i->as32L())
temp_ECX = ECX;
else
temp_ECX = CX;
if (temp_ECX == 0) {
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
return;
}
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
//
// There is some weirdness in LOOP instructions definition. If an exception
// was generated during the instruction execution (for example #GP fault
// because EIP was beyond CS segment limits) CPU state should restore the
// state prior to instruction execution.
//
// The final point that we are not allowed to decrement ECX register before
// it is known that no exceptions can happen.
//
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOPNE16_Jb(bxInstruction_c *i)
{
// it is impossible to get this instruction in long mode
BX_ASSERT(i->as64L() == 0);
if (i->as32L()) {
Bit32u count = ECX;
count--;
if (count != 0 && (get_ZF()==0)) {
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
ECX = count;
}
else {
Bit16u count = CX;
count--;
if (count != 0 && (get_ZF()==0)) {
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
CX = count;
}
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOPE16_Jb(bxInstruction_c *i)
{
// it is impossible to get this instruction in long mode
BX_ASSERT(i->as64L() == 0);
if (i->as32L()) {
Bit32u count = ECX;
count--;
if (count != 0 && get_ZF()) {
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
ECX = count;
}
else {
Bit16u count = CX;
count--;
if (count != 0 && get_ZF()) {
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
CX = count;
}
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOP16_Jb(bxInstruction_c *i)
{
// it is impossible to get this instruction in long mode
BX_ASSERT(i->as64L() == 0);
if (i->as32L()) {
Bit32u count = ECX;
count--;
if (count != 0) {
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
ECX = count;
}
else {
Bit16u count = CX;
count--;
if (count != 0) {
Bit16u new_IP = (Bit16u)(IP + (Bit32s) i->Id());
branch_near16(new_IP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_IP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
CX = count;
}
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer32.cc,v 1.73 2008-06-12 20:27:38 sshwarts Exp $
// $Id: ctrl_xfer32.cc,v 1.74 2008-06-22 03:45:53 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -33,9 +33,12 @@
// Make code more tidy with a few macros.
#if BX_SUPPORT_X86_64==0
#define RSP ESP
#define RIP EIP
#endif
void BX_CPP_AttrRegparmN(1) BX_CPU_C::branch_near32(Bit32u new_EIP)
#if BX_CPU_LEVEL >= 3
BX_CPP_INLINE void BX_CPP_AttrRegparmN(1) BX_CPU_C::branch_near32(Bit32u new_EIP)
{
// check always, not only in protected mode
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
@ -44,16 +47,14 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::branch_near32(Bit32u new_EIP)
exception(BX_GP_EXCEPTION, 0, 0);
}
RIP = new_EIP;
#if BX_SUPPORT_TRACE_CACHE && !defined(BX_TRACE_CACHE_NO_SPECULATIVE_TRACING)
// assert magic async_event to stop trace execution
BX_CPU_THIS_PTR async_event |= BX_ASYNC_EVENT_STOP_TRACE;
#endif
EIP = new_EIP;
}
#if BX_CPU_LEVEL >= 3
void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear32_Iw(bxInstruction_c *i)
{
#if BX_DEBUGGER
@ -70,7 +71,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear32_Iw(bxInstruction_c *i)
BX_ERROR(("RETnear32_Iw: offset outside of CS limits"));
exception(BX_GP_EXCEPTION, 0, 0);
}
EIP = return_EIP;
RIP = return_EIP;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
ESP += imm16;
@ -97,7 +98,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear32(bxInstruction_c *i)
BX_ERROR(("RETnear32: offset outside of CS limits"));
exception(BX_GP_EXCEPTION, 0, 0);
}
EIP = return_EIP;
RIP = return_EIP;
BX_CPU_THIS_PTR speculative_rsp = 0;
@ -135,7 +136,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETfar32_Iw(bxInstruction_c *i)
cs_raw = (Bit16u) pop_32(); /* 32bit pop, MSW discarded */
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = eip;
RIP = eip;
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
ESP += imm16;
@ -179,7 +180,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETfar32(bxInstruction_c *i)
cs_raw = (Bit16u) pop_32(); /* 32bit pop, MSW discarded */
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = eip;
RIP = eip;
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
@ -203,7 +204,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_Jd(bxInstruction_c *i)
/* push 32 bit EA of next instruction */
push_32(EIP);
EIP = new_EIP;
RIP = new_EIP;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, EIP);
}
@ -240,7 +241,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL32_Ap(bxInstruction_c *i)
push_32(EIP);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = disp32;
RIP = disp32;
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
@ -266,7 +267,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_EdM(bxInstruction_c *i)
}
push_32(EIP);
EIP = op1_32;
RIP = op1_32;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, EIP);
}
@ -286,7 +287,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_EdR(bxInstruction_c *i)
}
push_32(EIP);
EIP = op1_32;
RIP = op1_32;
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, EIP);
}
@ -326,7 +327,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL32_Ep(bxInstruction_c *i)
push_32(EIP);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = op1_32;
RIP = op1_32;
done:
BX_CPU_THIS_PTR speculative_rsp = 0;
@ -339,13 +340,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_Jd(bxInstruction_c *i)
{
Bit32u new_EIP = EIP + (Bit32s) i->Id();
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
{
BX_ERROR(("JMP_Jd: offset outside of CS limits"));
exception(BX_GP_EXCEPTION, 0, 0);
}
EIP = new_EIP;
branch_near32(new_EIP);
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, new_EIP);
}
@ -570,7 +565,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_Ap(bxInstruction_c *i)
}
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = disp32;
RIP = disp32;
done:
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP,
@ -583,30 +578,14 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_EdM(bxInstruction_c *i)
/* pointer, segment address pair */
Bit32u new_EIP = read_virtual_dword(i->seg(), RMAddr(i));
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
{
BX_ERROR(("JMP_Ed: offset outside of CS limits"));
exception(BX_GP_EXCEPTION, 0, 0);
}
EIP = new_EIP;
branch_near32(new_EIP);
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, new_EIP);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP_EdR(bxInstruction_c *i)
{
Bit32u new_EIP = BX_READ_32BIT_REG(i->rm());
if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled)
{
BX_ERROR(("JMP_Ed: offset outside of CS limits"));
exception(BX_GP_EXCEPTION, 0, 0);
}
EIP = new_EIP;
branch_near32(new_EIP);
BX_INSTR_UCNEAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, new_EIP);
}
@ -637,7 +616,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JMP32_Ep(bxInstruction_c *i)
}
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = op1_32;
RIP = op1_32;
done:
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP,
@ -683,7 +662,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET32(bxInstruction_c *i)
eflags32 = pop_32();
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
EIP = eip;
RIP = eip;
writeEFlags(eflags32, 0x00257fd5); // VIF, VIP, VM unchanged
done:
@ -693,4 +672,159 @@ done:
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JECXZ_Jb(bxInstruction_c *i)
{
// it is impossible to get this instruction in long mode
BX_ASSERT(i->as64L() == 0);
Bit32u temp_ECX;
if (i->as32L())
temp_ECX = ECX;
else
temp_ECX = CX;
if (temp_ECX == 0) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
return;
}
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
//
// There is some weirdness in LOOP instructions definition. If an exception
// was generated during the instruction execution (for example #GP fault
// because EIP was beyond CS segment limits) CPU state should restore the
// state prior to instruction execution.
//
// The final point that we are not allowed to decrement ECX register before
// it is known that no exceptions can happen.
//
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOPNE32_Jb(bxInstruction_c *i)
{
// it is impossible to get this instruction in long mode
BX_ASSERT(i->as64L() == 0);
if (i->as32L()) {
Bit32u count = ECX;
count--;
if (count != 0 && (get_ZF()==0)) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
ECX = count;
}
else {
Bit16u count = CX;
count--;
if (count != 0 && (get_ZF()==0)) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
CX = count;
}
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOPE32_Jb(bxInstruction_c *i)
{
// it is impossible to get this instruction in long mode
BX_ASSERT(i->as64L() == 0);
if (i->as32L()) {
Bit32u count = ECX;
count--;
if (count != 0 && get_ZF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
ECX = count;
}
else {
Bit16u count = CX;
count--;
if (count != 0 && get_ZF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
CX = count;
}
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOP32_Jb(bxInstruction_c *i)
{
// it is impossible to get this instruction in long mode
BX_ASSERT(i->as64L() == 0);
if (i->as32L()) {
Bit32u count = ECX;
count--;
if (count != 0) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
ECX = count;
}
else {
Bit16u count = CX;
count--;
if (count != 0) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
CX = count;
}
}
#endif

View File

@ -1,5 +1,5 @@
////////c/////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer64.cc,v 1.68 2008-05-11 20:46:11 sshwarts Exp $
// $Id: ctrl_xfer64.cc,v 1.69 2008-06-22 03:45:53 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -41,12 +41,12 @@ BX_CPP_INLINE void BX_CPP_AttrRegparmN(1) BX_CPU_C::branch_near64(bxInstruction_
exception(BX_GP_EXCEPTION, 0, 0);
}
RIP = new_RIP;
#if BX_SUPPORT_TRACE_CACHE && !defined(BX_TRACE_CACHE_NO_SPECULATIVE_TRACING)
// assert magic async_event to stop trace execution
BX_CPU_THIS_PTR async_event |= BX_ASYNC_EVENT_STOP_TRACE;
#endif
RIP = new_RIP;
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear64_Iw(bxInstruction_c *i)
@ -467,7 +467,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET64(bxInstruction_c *i)
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JCXZ64_Jb(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JRCXZ_Jb(bxInstruction_c *i)
{
if (i->as64L()) {
if (RCX == 0) {
@ -493,7 +493,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::JCXZ64_Jb(bxInstruction_c *i)
// because EIP was beyond CS segment limits) CPU state should restore the
// state prior to instruction execution.
//
// The final point that we are not allowed to decrement ECX register before
// The final point that we are not allowed to decrement RCX register before
// it is known that no exceptions can happen.
//

View File

@ -1,163 +0,0 @@
/////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer8.cc,v 1.28 2008-06-12 20:27:38 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
//
// MandrakeSoft S.A.
// 43, rue d'Aboukir
// 75002 Paris - France
// http://www.linux-mandrake.com/
// http://www.mandrakesoft.com/
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////
#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR
void BX_CPP_AttrRegparmN(1) BX_CPU_C::JCXZ_Jb(bxInstruction_c *i)
{
// it is impossible to get this instruction in long mode
BX_ASSERT(i->as64L() == 0);
Bit32u temp_ECX;
if (i->as32L())
temp_ECX = ECX;
else
temp_ECX = CX;
if (temp_ECX == 0) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
if (i->os32L()==0) new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
return;
}
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
//
// There is some weirdness in LOOP instructions definition. If an exception
// was generated during the instruction execution (for example #GP fault
// because EIP was beyond CS segment limits) CPU state should restore the
// state prior to instruction execution.
//
// The final point that we are not allowed to decrement ECX register before
// it is known that no exceptions can happen.
//
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOPNE_Jb(bxInstruction_c *i)
{
// it is impossible to get this instruction in long mode
BX_ASSERT(i->as64L() == 0);
Bit32u count;
#if BX_CPU_LEVEL >= 3
if (i->as32L())
count = ECX;
else
#endif
count = CX;
count--;
if ((count!=0) && (get_ZF()==0)) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
if (i->os32L()==0) new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
if (i->as32L())
ECX--;
else
CX--;
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOPE_Jb(bxInstruction_c *i)
{
// it is impossible to get this instruction in long mode
BX_ASSERT(i->as64L() == 0);
Bit32u count;
#if BX_CPU_LEVEL >= 3
if (i->as32L())
count = ECX;
else
#endif
count = CX;
count--;
if ((count!=0) && get_ZF()) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
if (i->os32L()==0) new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
if (i->as32L())
ECX--;
else
CX--;
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOOP_Jb(bxInstruction_c *i)
{
// it is impossible to get this instruction in long mode
BX_ASSERT(i->as64L() == 0);
Bit32u count;
#if BX_CPU_LEVEL >= 3
if (i->as32L())
count = ECX;
else
#endif
count = CX;
count--;
if (count != 0) {
Bit32u new_EIP = EIP + (Bit32s) i->Id();
if (i->os32L()==0) new_EIP &= 0xffff;
branch_near32(new_EIP);
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, new_EIP);
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(BX_CPU_ID);
}
#endif
if (i->as32L())
ECX--;
else
CX--;
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: data_xfer8.cc,v 1.39 2008-03-22 21:29:39 sshwarts Exp $
// $Id: data_xfer8.cc,v 1.40 2008-06-22 03:45:54 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -90,18 +90,18 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XLAT(bxInstruction_c *i)
#if BX_SUPPORT_X86_64
if (i->as64L()) {
offset = RBX + AL;
offset = RBX;
}
else
#endif
if (i->as32L()) {
offset = EBX + AL;
offset = EBX;
}
else {
offset = BX + AL;
offset = BX;
}
AL = read_virtual_byte(i->seg(), offset);
AL = read_virtual_byte(i->seg(), offset + AL);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::XCHG_EbGbM(bxInstruction_c *i)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode.cc,v 1.191 2008-06-11 20:58:28 sshwarts Exp $
// $Id: fetchdecode.cc,v 1.192 2008-06-22 03:45:54 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -432,9 +432,9 @@ static const BxOpcodeInfo_t BxOpcodeInfo32R[512*2] = {
/* DE /wr */ { 0, BX_IA_FPU_ESC },
/* DF /wr */ { 0, BX_IA_FPU_ESC },
#endif
/* E0 /wr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE_Jb },
/* E1 /wr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE_Jb },
/* E2 /wr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP_Jb },
/* E0 /wr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE16_Jb },
/* E1 /wr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE16_Jb },
/* E2 /wr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP16_Jb },
/* E3 /wr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JCXZ_Jb },
/* E4 /wr */ { BxImmediate_Ib, BX_IA_IN_ALIb },
/* E5 /wr */ { BxImmediate_Ib, BX_IA_IN_AXIb },
@ -995,10 +995,10 @@ static const BxOpcodeInfo_t BxOpcodeInfo32R[512*2] = {
/* DE /dr */ { 0, BX_IA_FPU_ESC },
/* DF /dr */ { 0, BX_IA_FPU_ESC },
#endif
/* E0 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE_Jb },
/* E1 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE_Jb },
/* E2 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP_Jb },
/* E3 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JCXZ_Jb },
/* E0 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE32_Jb },
/* E1 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE32_Jb },
/* E2 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP32_Jb },
/* E3 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JECXZ_Jb },
/* E4 /dr */ { BxImmediate_Ib, BX_IA_IN_ALIb },
/* E5 /dr */ { BxImmediate_Ib, BX_IA_IN_EAXIb },
/* E6 /dr */ { BxImmediate_Ib, BX_IA_OUT_IbAL },
@ -1565,9 +1565,9 @@ static const BxOpcodeInfo_t BxOpcodeInfo32M[512*2] = {
/* DE /wm */ { 0, BX_IA_FPU_ESC },
/* DF /wm */ { 0, BX_IA_FPU_ESC },
#endif
/* E0 /wm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE_Jb },
/* E1 /wm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE_Jb },
/* E2 /wm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP_Jb },
/* E0 /wm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE16_Jb },
/* E1 /wm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE16_Jb },
/* E2 /wm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP16_Jb },
/* E3 /wm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JCXZ_Jb },
/* E4 /wm */ { BxImmediate_Ib, BX_IA_IN_ALIb },
/* E5 /wm */ { BxImmediate_Ib, BX_IA_IN_AXIb },
@ -2128,10 +2128,10 @@ static const BxOpcodeInfo_t BxOpcodeInfo32M[512*2] = {
/* DE /dm */ { 0, BX_IA_FPU_ESC },
/* DF /dm */ { 0, BX_IA_FPU_ESC },
#endif
/* E0 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE_Jb },
/* E1 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE_Jb },
/* E2 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP_Jb },
/* E3 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JCXZ_Jb },
/* E0 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE32_Jb },
/* E1 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE32_Jb },
/* E2 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP32_Jb },
/* E3 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JECXZ_Jb },
/* E4 /dm */ { BxImmediate_Ib, BX_IA_IN_ALIb },
/* E5 /dm */ { BxImmediate_Ib, BX_IA_IN_EAXIb },
/* E6 /dm */ { BxImmediate_Ib, BX_IA_OUT_IbAL },

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode64.cc,v 1.200 2008-06-11 20:58:29 sshwarts Exp $
// $Id: fetchdecode64.cc,v 1.201 2008-06-22 03:45:54 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -408,7 +408,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64R[512*3] = {
/* E0 /wr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE64_Jb },
/* E1 /wr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE64_Jb },
/* E2 /wr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP64_Jb },
/* E3 /wr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JCXZ64_Jb },
/* E3 /wr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JRCXZ_Jb },
/* E4 /wr */ { BxImmediate_Ib, BX_IA_IN_ALIb },
/* E5 /wr */ { BxImmediate_Ib, BX_IA_IN_AXIb },
/* E6 /wr */ { BxImmediate_Ib, BX_IA_OUT_IbAL },
@ -935,7 +935,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64R[512*3] = {
/* E0 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE64_Jb },
/* E1 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE64_Jb },
/* E2 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP64_Jb },
/* E3 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JCXZ64_Jb },
/* E3 /dr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JRCXZ_Jb },
/* E4 /dr */ { BxImmediate_Ib, BX_IA_IN_ALIb },
/* E5 /dr */ { BxImmediate_Ib, BX_IA_IN_EAXIb },
/* E6 /dr */ { BxImmediate_Ib, BX_IA_OUT_IbAL },
@ -1462,7 +1462,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64R[512*3] = {
/* E0 /qr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE64_Jb },
/* E1 /qr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE64_Jb },
/* E2 /qr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP64_Jb },
/* E3 /qr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JCXZ64_Jb },
/* E3 /qr */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JRCXZ_Jb },
/* E4 /qr */ { BxImmediate_Ib, BX_IA_IN_ALIb },
/* E5 /qr */ { BxImmediate_Ib, BX_IA_IN_EAXIb },
/* E6 /qr */ { BxImmediate_Ib, BX_IA_OUT_IbAL },
@ -1995,7 +1995,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64M[512*3] = {
/* E0 /wm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE64_Jb },
/* E1 /wm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE64_Jb },
/* E2 /wm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP64_Jb },
/* E3 /wm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JCXZ64_Jb },
/* E3 /wm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JRCXZ_Jb },
/* E4 /wm */ { BxImmediate_Ib, BX_IA_IN_ALIb },
/* E5 /wm */ { BxImmediate_Ib, BX_IA_IN_AXIb },
/* E6 /wm */ { BxImmediate_Ib, BX_IA_OUT_IbAL },
@ -2522,7 +2522,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64M[512*3] = {
/* E0 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE64_Jb },
/* E1 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE64_Jb },
/* E2 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP64_Jb },
/* E3 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JCXZ64_Jb },
/* E3 /dm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JRCXZ_Jb },
/* E4 /dm */ { BxImmediate_Ib, BX_IA_IN_ALIb },
/* E5 /dm */ { BxImmediate_Ib, BX_IA_IN_EAXIb },
/* E6 /dm */ { BxImmediate_Ib, BX_IA_OUT_IbAL },
@ -3049,7 +3049,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64M[512*3] = {
/* E0 /qm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPNE64_Jb },
/* E1 /qm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOPE64_Jb },
/* E2 /qm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_LOOP64_Jb },
/* E3 /qm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JCXZ64_Jb },
/* E3 /qm */ { BxImmediate_BrOff8 | BxTraceEnd, BX_IA_JRCXZ_Jb },
/* E4 /qm */ { BxImmediate_Ib, BX_IA_IN_ALIb },
/* E5 /qm */ { BxImmediate_Ib, BX_IA_IN_EAXIb },
/* E6 /qm */ { BxImmediate_Ib, BX_IA_OUT_IbAL },

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: ia_opcodes.h,v 1.9 2008-06-04 16:31:03 sshwarts Exp $
// $Id: ia_opcodes.h,v 1.10 2008-06-22 03:45:55 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008 Stanislav Shwartsman
@ -297,6 +297,7 @@ bx_define_opcode(BX_IA_JB_Jw, BX_CPU_C::JB_Jw)
bx_define_opcode(BX_IA_JBE_Jd, BX_CPU_C::JBE_Jd)
bx_define_opcode(BX_IA_JBE_Jw, BX_CPU_C::JBE_Jw)
bx_define_opcode(BX_IA_JCXZ_Jb, BX_CPU_C::JCXZ_Jb)
bx_define_opcode(BX_IA_JECXZ_Jb, BX_CPU_C::JECXZ_Jb)
bx_define_opcode(BX_IA_JL_Jd, BX_CPU_C::JL_Jd)
bx_define_opcode(BX_IA_JL_Jw, BX_CPU_C::JL_Jw)
bx_define_opcode(BX_IA_JLE_Jd, BX_CPU_C::JLE_Jd)
@ -351,9 +352,12 @@ bx_define_opcode(BX_IA_LGS_GwMp, BX_CPU_C::LGS_GwMp)
bx_define_opcode(BX_IA_LIDT_Ms, BX_CPU_C::LIDT_Ms)
bx_define_opcode(BX_IA_LLDT_Ew, BX_CPU_C::LLDT_Ew)
bx_define_opcode(BX_IA_LMSW_Ew, BX_CPU_C::LMSW_Ew)
bx_define_opcode(BX_IA_LOOP_Jb, BX_CPU_C::LOOP_Jb)
bx_define_opcode(BX_IA_LOOPE_Jb, BX_CPU_C::LOOPE_Jb)
bx_define_opcode(BX_IA_LOOPNE_Jb, BX_CPU_C::LOOPNE_Jb)
bx_define_opcode(BX_IA_LOOP16_Jb, BX_CPU_C::LOOP16_Jb)
bx_define_opcode(BX_IA_LOOPE16_Jb, BX_CPU_C::LOOPE16_Jb)
bx_define_opcode(BX_IA_LOOPNE16_Jb, BX_CPU_C::LOOPNE16_Jb)
bx_define_opcode(BX_IA_LOOP32_Jb, BX_CPU_C::LOOP32_Jb)
bx_define_opcode(BX_IA_LOOPE32_Jb, BX_CPU_C::LOOPE32_Jb)
bx_define_opcode(BX_IA_LOOPNE32_Jb, BX_CPU_C::LOOPNE32_Jb)
bx_define_opcode(BX_IA_LSL_GvEw, BX_CPU_C::LSL_GvEw)
bx_define_opcode(BX_IA_LSS_GdMp, BX_CPU_C::LSS_GdMp)
bx_define_opcode(BX_IA_LSS_GwMp, BX_CPU_C::LSS_GwMp)
@ -1527,7 +1531,7 @@ bx_define_opcode(BX_IA_CMPXCHG16B, BX_CPU_C::CMPXCHG16B)
bx_define_opcode(BX_IA_LOOPNE64_Jb, BX_CPU_C::LOOPNE64_Jb)
bx_define_opcode(BX_IA_LOOPE64_Jb, BX_CPU_C::LOOPE64_Jb)
bx_define_opcode(BX_IA_LOOP64_Jb, BX_CPU_C::LOOP64_Jb)
bx_define_opcode(BX_IA_JCXZ64_Jb, BX_CPU_C::JCXZ64_Jb)
bx_define_opcode(BX_IA_JRCXZ_Jb, BX_CPU_C::JRCXZ_Jb)
bx_define_opcode(BX_IA_MOVQ_EqPq, BX_CPU_C::MOVQ_EqPq)
bx_define_opcode(BX_IA_MOVQ_EqVq, BX_CPU_C::MOVQ_EqVq)
bx_define_opcode(BX_IA_MOVQ_PqEq, BX_CPU_C::MOVQ_PqEq)