split 32-bit modermdata variable in BxInstruction_c to 4 Bit8u variables
this way it is possible to save shifts and masking when accessing modrm fields
This commit is contained in:
parent
2f5fa07af3
commit
2653d54e96
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: arith16.cc,v 1.47 2007-11-06 08:39:25 sshwarts Exp $
|
||||
// $Id: arith16.cc,v 1.48 2007-11-08 18:21:37 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -66,30 +66,28 @@ void BX_CPU_C::ADD_EwGw(bxInstruction_c *i)
|
||||
void BX_CPU_C::ADD_GwEEw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, op2_16, sum_16;
|
||||
unsigned nnn = i->nnn();
|
||||
|
||||
op1_16 = BX_READ_16BIT_REG(nnn);
|
||||
op1_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
read_virtual_word(i->seg(), RMAddr(i), &op2_16);
|
||||
|
||||
sum_16 = op1_16 + op2_16;
|
||||
SET_FLAGS_OSZAPC_S1_16(op1_16, sum_16, BX_INSTR_ADD16);
|
||||
|
||||
BX_WRITE_16BIT_REG(nnn, sum_16);
|
||||
BX_WRITE_16BIT_REG(i->nnn(), sum_16);
|
||||
}
|
||||
|
||||
void BX_CPU_C::ADD_GwEGw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, op2_16, sum_16;
|
||||
unsigned nnn = i->nnn();
|
||||
|
||||
op1_16 = BX_READ_16BIT_REG(nnn);
|
||||
op1_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
op2_16 = BX_READ_16BIT_REG(i->rm());
|
||||
sum_16 = op1_16 + op2_16;
|
||||
|
||||
SET_FLAGS_OSZAPC_S1_16(op1_16, sum_16, BX_INSTR_ADD16);
|
||||
|
||||
BX_WRITE_16BIT_REG(nnn, sum_16);
|
||||
BX_WRITE_16BIT_REG(i->nnn(), sum_16);
|
||||
}
|
||||
|
||||
void BX_CPU_C::ADD_AXIw(bxInstruction_c *i)
|
||||
@ -262,9 +260,8 @@ void BX_CPU_C::SUB_EwGw(bxInstruction_c *i)
|
||||
void BX_CPU_C::SUB_GwEw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, op2_16, diff_16;
|
||||
unsigned nnn = i->nnn();
|
||||
|
||||
op1_16 = BX_READ_16BIT_REG(nnn);
|
||||
op1_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
if (i->modC0()) {
|
||||
op2_16 = BX_READ_16BIT_REG(i->rm());
|
||||
@ -276,7 +273,7 @@ void BX_CPU_C::SUB_GwEw(bxInstruction_c *i)
|
||||
diff_16 = op1_16 - op2_16;
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
|
||||
|
||||
BX_WRITE_16BIT_REG(nnn, diff_16);
|
||||
BX_WRITE_16BIT_REG(i->nnn(), diff_16);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SUB_AXIw(bxInstruction_c *i)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.347 2007-11-07 10:40:39 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.348 2007-11-08 18:21:37 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -339,7 +339,7 @@
|
||||
#define BX_MODE_LONG_64 0x4 // EFER.LMA = 1, CR0.PE=1, CS.L=1
|
||||
|
||||
extern const char* cpu_mode_string(unsigned cpu_mode);
|
||||
extern const char* cpu_state_string();
|
||||
extern const char* cpu_state_string(Bit32u debug_trap);
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
#define IsCanonical(offset) ((Bit64u)((((Bit64s)(offset)) >> (BX_LIN_ADDRESS_WIDTH-1)) + 1) < 2)
|
||||
@ -634,18 +634,23 @@ public:
|
||||
union {
|
||||
// Form (longest case): [opcode+modrm+sib/displacement32/immediate32]
|
||||
struct {
|
||||
// Note: if you add more bits, mask the previously upper field,
|
||||
// in the accessor.
|
||||
// 27..20 modRM (modrm)
|
||||
// 19..16 index (sib)
|
||||
Bit16u modRMData2;
|
||||
|
||||
// 15..12 nnn (modrm)
|
||||
// 31..28 (unused)
|
||||
// 27..24 nnn (modrm)
|
||||
Bit8u modRMData4;
|
||||
|
||||
// 23..20 (unused)
|
||||
// 19..16 index (sib)
|
||||
Bit8u modRMData3;
|
||||
|
||||
// 15..14 mod (modrm)
|
||||
// 13..12 scale (sib)
|
||||
// 11...8 base (sib)
|
||||
// 7...6 mod (modrm)
|
||||
// 5...4 scale (sib)
|
||||
Bit8u modRMData2;
|
||||
|
||||
// 7...4 (unused)
|
||||
// 3...0 rm (modrm)
|
||||
Bit16u modRMData1;
|
||||
Bit8u modRMData1;
|
||||
|
||||
union {
|
||||
Bit32u Id;
|
||||
@ -701,8 +706,11 @@ public:
|
||||
// are aligned in the same place, so it doesn't matter.
|
||||
return IxForm.opcodeReg;
|
||||
}
|
||||
BX_CPP_INLINE unsigned modrm() { return (modRMForm.modRMData2>>4) & 0xff; }
|
||||
BX_CPP_INLINE unsigned mod() { return modRMForm.modRMData1 & 0xc0; }
|
||||
// used in FPU only
|
||||
BX_CPP_INLINE unsigned modrm() {
|
||||
return mod() | (rm() & 7) | ((nnn() & 7) << 3);
|
||||
}
|
||||
BX_CPP_INLINE unsigned mod() { return modRMForm.modRMData2 & 0xc0; }
|
||||
BX_CPP_INLINE unsigned modC0()
|
||||
{
|
||||
// This is a cheaper way to test for modRM instructions where
|
||||
@ -715,17 +723,19 @@ public:
|
||||
return metaInfo |= (1<<22);
|
||||
}
|
||||
BX_CPP_INLINE unsigned nnn() {
|
||||
return (modRMForm.modRMData1 >> 12);
|
||||
return modRMForm.modRMData4;
|
||||
}
|
||||
BX_CPP_INLINE unsigned rm() {
|
||||
return modRMForm.modRMData1;
|
||||
}
|
||||
BX_CPP_INLINE unsigned rm() { return modRMForm.modRMData1 & 0xf; }
|
||||
BX_CPP_INLINE unsigned sibScale() {
|
||||
return (modRMForm.modRMData1 >> 4) & 0x3;
|
||||
return (modRMForm.modRMData2 >> 4) & 0x3;
|
||||
}
|
||||
BX_CPP_INLINE unsigned sibIndex() {
|
||||
return (modRMForm.modRMData2) & 0xf;
|
||||
return modRMForm.modRMData3;
|
||||
}
|
||||
BX_CPP_INLINE unsigned sibBase() {
|
||||
return (modRMForm.modRMData1 >> 8) & 0xf;
|
||||
return (modRMForm.modRMData2) & 0xf;
|
||||
}
|
||||
BX_CPP_INLINE Bit32u displ32u() { return modRMForm.displ32u; }
|
||||
BX_CPP_INLINE Bit16u displ16u() { return modRMForm.displ16u; }
|
||||
@ -1271,11 +1281,11 @@ public: // for now...
|
||||
#endif
|
||||
|
||||
struct {
|
||||
bx_address rm_addr; // The address offset after resolution.
|
||||
Bit32u paddress1; // physical address after translation of 1st len1 bytes of data
|
||||
Bit32u paddress2; // physical address after translation of 2nd len2 bytes of data
|
||||
Bit32u len1; // Number of bytes in page 1
|
||||
Bit32u len2; // Number of bytes in page 2
|
||||
bx_address rm_addr; // The address offset after resolution.
|
||||
bx_phy_address paddress1; // physical address after translation of 1st len1 bytes of data
|
||||
bx_phy_address paddress2; // physical address after translation of 2nd len2 bytes of data
|
||||
Bit32u len1; // Number of bytes in page 1
|
||||
Bit32u len2; // Number of bytes in page 2
|
||||
bx_ptr_equiv_t pages; // Number of pages access spans (1 or 2). Also used
|
||||
// for the case when a native host pointer is
|
||||
// available for the R-M-W instructions. The host
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: debugstuff.cc,v 1.84 2007-11-05 16:36:37 sshwarts Exp $
|
||||
// $Id: debugstuff.cc,v 1.85 2007-11-08 18:21:37 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -91,7 +91,7 @@ const char* cpu_mode_string(unsigned cpu_mode)
|
||||
return cpu_mode_name[cpu_mode];
|
||||
}
|
||||
|
||||
const char* cpu_state_string()
|
||||
const char* cpu_state_string(Bit32u debug_trap)
|
||||
{
|
||||
unsigned cpu_state = 5; // unknown state
|
||||
|
||||
@ -104,11 +104,11 @@ const char* cpu_state_string()
|
||||
"unknown state"
|
||||
};
|
||||
|
||||
if(BX_CPU_THIS_PTR debug_trap & BX_DEBUG_TRAP_HALT) cpu_state = 4;
|
||||
else if (BX_CPU_THIS_PTR debug_trap & BX_DEBUG_TRAP_SHUTDOWN) cpu_state = 3;
|
||||
else if (BX_CPU_THIS_PTR debug_trap & BX_DEBUG_TRAP_WAIT_FOR_SIPI) cpu_state = 2;
|
||||
else if (BX_CPU_THIS_PTR debug_trap & BX_DEBUG_TRAP_MWAIT) cpu_state = 1;
|
||||
else if (BX_CPU_THIS_PTR debug_trap & BX_DEBUG_TRAP_SPECIAL) cpu_state = 5;
|
||||
if(debug_trap & BX_DEBUG_TRAP_HALT) cpu_state = 4;
|
||||
else if (debug_trap & BX_DEBUG_TRAP_SHUTDOWN) cpu_state = 3;
|
||||
else if (debug_trap & BX_DEBUG_TRAP_WAIT_FOR_SIPI) cpu_state = 2;
|
||||
else if (debug_trap & BX_DEBUG_TRAP_MWAIT) cpu_state = 1;
|
||||
else if (debug_trap & BX_DEBUG_TRAP_SPECIAL) cpu_state = 5;
|
||||
else cpu_state = 0;
|
||||
return cpu_state_name[cpu_state];
|
||||
}
|
||||
@ -116,7 +116,7 @@ const char* cpu_state_string()
|
||||
void BX_CPU_C::debug(bx_address offset)
|
||||
{
|
||||
BX_INFO(("CPU is in %s (%s)", cpu_mode_string(BX_CPU_THIS_PTR get_cpu_mode()),
|
||||
cpu_state_string()));
|
||||
cpu_state_string(BX_CPU_THIS_PTR debug_trap)));
|
||||
BX_INFO(("CS.d_b = %u bit",
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b ? 32 : 16));
|
||||
BX_INFO(("SS.d_b = %u bit",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode.cc,v 1.114 2007-11-07 10:40:40 sshwarts Exp $
|
||||
// $Id: fetchdecode.cc,v 1.115 2007-11-08 18:21:37 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1678,15 +1678,16 @@ fetch_b1:
|
||||
mod = b2 & 0xc0; // leave unshifted
|
||||
nnn = (b2 >> 3) & 0x07;
|
||||
rm = b2 & 0x07;
|
||||
instruction->modRMForm.modRMData2 = (b2<<4);
|
||||
instruction->modRMForm.modRMData1 = mod;
|
||||
instruction->modRMForm.modRMData1 |= (nnn<<12);
|
||||
instruction->modRMForm.modRMData1 |= rm;
|
||||
|
||||
// MOVs with CRx and DRx always use register ops and ignore the mod field.
|
||||
if ((b1 & ~3) == 0x120)
|
||||
mod = 0xc0;
|
||||
|
||||
instruction->modRMForm.modRMData1 = rm;
|
||||
instruction->modRMForm.modRMData2 = mod;
|
||||
instruction->modRMForm.modRMData3 = 0;
|
||||
instruction->modRMForm.modRMData4 = nnn;
|
||||
|
||||
if (mod == 0xc0) { // mod == 11b
|
||||
instruction->assertModC0();
|
||||
goto modrm_done;
|
||||
@ -1749,9 +1750,9 @@ get_32bit_displ:
|
||||
base = sib & 0x07; sib >>= 3;
|
||||
index = sib & 0x07; sib >>= 3;
|
||||
scale = sib;
|
||||
instruction->modRMForm.modRMData1 |= (base<<8);
|
||||
instruction->modRMForm.modRMData2 |= (index);
|
||||
instruction->modRMForm.modRMData1 |= (scale<<4);
|
||||
instruction->modRMForm.modRMData2 |= (base);
|
||||
instruction->modRMForm.modRMData3 |= (index);
|
||||
instruction->modRMForm.modRMData2 |= (scale<<4);
|
||||
if (mod == 0x00) { // mod==00b, rm==4
|
||||
instruction->ResolveModrm = BxResolve32Mod0Base[base];
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode64.cc,v 1.119 2007-11-07 10:40:40 sshwarts Exp $
|
||||
// $Id: fetchdecode64.cc,v 1.120 2007-11-08 18:21:37 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -2311,14 +2311,16 @@ fetch_b1:
|
||||
mod = b2 & 0xc0;
|
||||
nnn = ((b2 >> 3) & 0x07) | rex_r;
|
||||
rm = b2 & 0x07;
|
||||
instruction->modRMForm.modRMData2 = (b2<<4);
|
||||
instruction->modRMForm.modRMData1 = mod;
|
||||
instruction->modRMForm.modRMData1 |= (nnn<<12);
|
||||
|
||||
// MOVs with CRx and DRx always use register ops and ignore the mod field.
|
||||
if ((b1 & ~3) == 0x120)
|
||||
mod = 0xc0;
|
||||
|
||||
instruction->modRMForm.modRMData1 = 0;
|
||||
instruction->modRMForm.modRMData2 = mod;
|
||||
instruction->modRMForm.modRMData3 = 0;
|
||||
instruction->modRMForm.modRMData4 = nnn;
|
||||
|
||||
if (mod == 0xc0) { // mod == 11b
|
||||
rm |= rex_b;
|
||||
instruction->modRMForm.modRMData1 |= rm;
|
||||
@ -2383,9 +2385,9 @@ fetch_b1:
|
||||
base = (sib & 0x07) | rex_b; sib >>= 3;
|
||||
index = (sib & 0x07) | rex_x; sib >>= 3;
|
||||
scale = sib;
|
||||
instruction->modRMForm.modRMData1 |= (base<<8);
|
||||
instruction->modRMForm.modRMData2 |= (index);
|
||||
instruction->modRMForm.modRMData1 |= (scale<<4);
|
||||
instruction->modRMForm.modRMData2 |= (base);
|
||||
instruction->modRMForm.modRMData3 |= (index);
|
||||
instruction->modRMForm.modRMData2 |= (scale<<4);
|
||||
if (mod == 0x00) { // mod==00b, rm==4
|
||||
instruction->ResolveModrm = BxResolve64Mod0Base[base];
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
@ -2465,9 +2467,9 @@ get_32bit_displ:
|
||||
base = (sib & 0x07) | rex_b; sib >>= 3;
|
||||
index = (sib & 0x07) | rex_x; sib >>= 3;
|
||||
scale = sib;
|
||||
instruction->modRMForm.modRMData1 |= (base<<8);
|
||||
instruction->modRMForm.modRMData2 |= (index);
|
||||
instruction->modRMForm.modRMData1 |= (scale<<4);
|
||||
instruction->modRMForm.modRMData2 |= (base);
|
||||
instruction->modRMForm.modRMData3 |= (index);
|
||||
instruction->modRMForm.modRMData2 |= (scale<<4);
|
||||
if (mod == 0x00) { // mod==00b, rm==4
|
||||
instruction->ResolveModrm = BxResolve32Mod0Base[base];
|
||||
if (BX_NULL_SEG_REG(instruction->seg()))
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: logical16.cc,v 1.28 2007-10-21 23:35:11 sshwarts Exp $
|
||||
// $Id: logical16.cc,v 1.29 2007-11-08 18:21:37 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -55,9 +55,8 @@ void BX_CPU_C::XOR_EwGw(bxInstruction_c *i)
|
||||
void BX_CPU_C::XOR_GwEw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, op2_16;
|
||||
unsigned nnn = i->nnn();
|
||||
|
||||
op1_16 = BX_READ_16BIT_REG(nnn);
|
||||
op1_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
if (i->modC0()) {
|
||||
op2_16 = BX_READ_16BIT_REG(i->rm());
|
||||
@ -68,7 +67,7 @@ void BX_CPU_C::XOR_GwEw(bxInstruction_c *i)
|
||||
|
||||
op1_16 ^= op2_16;
|
||||
|
||||
BX_WRITE_16BIT_REG(nnn, op1_16);
|
||||
BX_WRITE_16BIT_REG(i->nnn(), op1_16);
|
||||
|
||||
SET_FLAGS_OSZAPC_RESULT_16(op1_16, BX_INSTR_LOGIC16);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: logical32.cc,v 1.29 2007-10-21 23:35:11 sshwarts Exp $
|
||||
// $Id: logical32.cc,v 1.30 2007-11-08 18:21:37 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -58,9 +58,8 @@ void BX_CPU_C::XOR_EdGd(bxInstruction_c *i)
|
||||
void BX_CPU_C::XOR_GdEd(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u op1_32, op2_32;
|
||||
unsigned nnn = i->nnn();
|
||||
|
||||
op1_32 = BX_READ_32BIT_REG(nnn);
|
||||
op1_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
if (i->modC0()) {
|
||||
op2_32 = BX_READ_32BIT_REG(i->rm());
|
||||
@ -71,7 +70,7 @@ void BX_CPU_C::XOR_GdEd(bxInstruction_c *i)
|
||||
|
||||
op1_32 ^= op2_32;
|
||||
|
||||
BX_WRITE_32BIT_REGZ(nnn, op1_32);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), op1_32);
|
||||
|
||||
SET_FLAGS_OSZAPC_RESULT_32(op1_32, BX_INSTR_LOGIC32);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user