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:
Stanislav Shwartsman 2007-11-08 18:21:37 +00:00
parent 2f5fa07af3
commit 2653d54e96
7 changed files with 75 additions and 67 deletions

View File

@ -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)

View File

@ -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

View File

@ -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",

View File

@ -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()))

View File

@ -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()))

View File

@ -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);
}

View File

@ -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);
}