Unpack more fields in bxInstruction_c -> this increase bxInstruction size by 4 bytes but I have no way but do it if want to support SSE5 dest override later
This commit is contained in:
parent
25a9b9fef1
commit
fb0ce45d28
@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// $Id: ctrl_xfer_pro.cc,v 1.66 2008-02-02 21:46:50 sshwarts Exp $
|
||||
// $Id: ctrl_xfer_pro.cc,v 1.67 2008-02-04 21:28:53 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -103,18 +103,20 @@ BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR efer.lma) {
|
||||
unsigned mode = BX_CPU_THIS_PTR cpu_mode;
|
||||
if (descriptor->u.segment.l) {
|
||||
BX_CPU_THIS_PTR cpu_mode = BX_MODE_LONG_64;
|
||||
BX_DEBUG(("Long Mode Activated"));
|
||||
loadSRegLMNominal(BX_SEG_REG_CS, selector->value, cpl);
|
||||
}
|
||||
else {
|
||||
BX_CPU_THIS_PTR cpu_mode = BX_MODE_LONG_COMPAT;
|
||||
BX_DEBUG(("Compatibility Mode Activated"));
|
||||
if (BX_CPU_THIS_PTR eip_reg.dword.rip_upper != 0) {
|
||||
BX_PANIC(("handleCpuModeChange: leaving long mode with RIP upper != 0 !"));
|
||||
}
|
||||
}
|
||||
if (mode != BX_CPU_THIS_PTR cpu_mode) {
|
||||
BX_DEBUG(("%s activated", cpu_mode_string(BX_CPU_THIS_PTR cpu_mode)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode.cc,v 1.163 2008-02-02 21:46:50 sshwarts Exp $
|
||||
// $Id: fetchdecode.cc,v 1.164 2008-02-04 21:28:53 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -2470,8 +2470,8 @@ BX_CPU_C::fetchDecode32(Bit8u *iptr, bxInstruction_c *i, unsigned remainingInPag
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b;
|
||||
|
||||
i->ResolveModrm = 0;
|
||||
i->initMetaInfo(/*os32*/ is_32, /*as32*/ is_32,
|
||||
/*os64*/ 0, /*as64*/ 0);
|
||||
i->init(/*os32*/ is_32, /*as32*/ is_32,
|
||||
/*os64*/ 0, /*as64*/ 0);
|
||||
|
||||
offset = os_32 << 9; // * 512
|
||||
|
||||
@ -2607,10 +2607,10 @@ fetch_b1:
|
||||
if ((b1 & ~3) == 0x120)
|
||||
mod = 0xc0;
|
||||
|
||||
i->metaData.modRMData1 = rm;
|
||||
i->metaData.modRMData2 = mod;
|
||||
i->setModRM(b2);
|
||||
i->metaData.metaData1 = rm;
|
||||
i->setSibBase(rm); // initialize with rm to use BxResolve32Base
|
||||
i->metaData.modRMData4 = nnn;
|
||||
i->metaData.metaData5 = nnn;
|
||||
|
||||
// initialize displ32 with zero to include cases with no diplacement
|
||||
i->modRMForm.displ32u = 0;
|
||||
@ -2668,9 +2668,9 @@ get_8bit_displ:
|
||||
base = sib & 0x7; sib >>= 3;
|
||||
index = sib & 0x7; sib >>= 3;
|
||||
scale = sib;
|
||||
i->setSibIndex(index);
|
||||
i->setSibScale(scale);
|
||||
i->setSibBase(base);
|
||||
i->metaData.modRMData2 |= (index);
|
||||
i->metaData.modRMData2 |= (scale<<4);
|
||||
if (index == 4)
|
||||
i->ResolveModrm = &BX_CPU_C::BxResolve32Base;
|
||||
else
|
||||
@ -2794,7 +2794,7 @@ modrm_done:
|
||||
// the if() above after fetching the 2nd byte, so this path is
|
||||
// taken in all cases if a modrm byte is NOT required.
|
||||
i->execute = BxOpcodeInfo32R[b1+offset].ExecutePtr;
|
||||
i->metaData.modRMData1 = b1 & 7;
|
||||
i->setOpcodeReg(b1 & 7);
|
||||
}
|
||||
|
||||
if (lock) { // lock prefix invalid opcode
|
||||
@ -2974,7 +2974,7 @@ modrm_done:
|
||||
void BX_CPU_C::BxError(bxInstruction_c *i)
|
||||
{
|
||||
BX_DEBUG(("BxError: i with opcode=0x%x", i->b1()));
|
||||
BX_DEBUG(("mod was %x, nnn was %u, rm was %u", i->mod(), i->nnn(), i->rm()));
|
||||
BX_DEBUG(("modrm was 0x%02x, nnn was %u, rm was %u", i->modrm(), i->nnn(), i->rm()));
|
||||
BX_DEBUG(("WARNING: Encountered an unknown i (signalling illegal i)"));
|
||||
|
||||
BX_CPU_THIS_PTR UndefinedOpcode(i);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode64.cc,v 1.170 2008-02-02 21:46:51 sshwarts Exp $
|
||||
// $Id: fetchdecode64.cc,v 1.171 2008-02-04 21:28:53 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -3372,10 +3372,10 @@ BX_CPU_C::fetchDecode64(Bit8u *iptr, bxInstruction_c *i, unsigned remainingInPag
|
||||
unsigned rex_prefix = 0;
|
||||
|
||||
i->ResolveModrm = 0;
|
||||
i->initMetaInfo(/*os32*/ 1, // operand size 32 override defaults to 1
|
||||
/*as32*/ 1, // address size 32 override defaults to 1
|
||||
/*os64*/ 0, // operand size 64 override defaults to 0
|
||||
/*as64*/ 1); // address size 64 override defaults to 1
|
||||
i->init(/*os32*/ 1, // operand size 32 override defaults to 1
|
||||
/*as32*/ 1, // address size 32 override defaults to 1
|
||||
/*os64*/ 0, // operand size 64 override defaults to 0
|
||||
/*as64*/ 1); // address size 64 override defaults to 1
|
||||
|
||||
fetch_b1:
|
||||
b1 = *iptr++;
|
||||
@ -3534,10 +3534,10 @@ fetch_b1:
|
||||
if ((b1 & ~3) == 0x120)
|
||||
mod = 0xc0;
|
||||
|
||||
i->metaData.modRMData1 = rm;
|
||||
i->metaData.modRMData2 = mod;
|
||||
i->setModRM(b2);
|
||||
i->metaData.metaData1 = rm;
|
||||
i->setSibBase(rm); // initialize with rm to use BxResolve32Base
|
||||
i->metaData.modRMData4 = nnn;
|
||||
i->metaData.metaData5 = nnn;
|
||||
|
||||
// initialize displ32 with zero to include cases with no diplacement
|
||||
i->modRMForm.displ32u = 0;
|
||||
@ -3595,9 +3595,9 @@ get_8bit_displ:
|
||||
base = (sib & 0x7) | rex_b; sib >>= 3;
|
||||
index = (sib & 0x7) | rex_x; sib >>= 3;
|
||||
scale = sib;
|
||||
i->setSibIndex(index);
|
||||
i->setSibScale(scale);
|
||||
i->setSibBase(base);
|
||||
i->metaData.modRMData2 |= (index);
|
||||
i->metaData.modRMData2 |= (scale<<4);
|
||||
if (index == 4)
|
||||
i->ResolveModrm = &BX_CPU_C::BxResolve64Base;
|
||||
else
|
||||
@ -3657,8 +3657,8 @@ get_8bit_displ:
|
||||
index = (sib & 0x7) | rex_x; sib >>= 3;
|
||||
scale = sib;
|
||||
i->setSibBase(base);
|
||||
i->metaData.modRMData2 |= (index);
|
||||
i->metaData.modRMData2 |= (scale<<4);
|
||||
i->metaData.metaData2 |= (index);
|
||||
i->metaData.metaData2 |= (scale<<4);
|
||||
if (index == 4)
|
||||
i->ResolveModrm = &BX_CPU_C::BxResolve32Base;
|
||||
else
|
||||
@ -3748,7 +3748,7 @@ modrm_done:
|
||||
// the if() above after fetching the 2nd byte, so this path is
|
||||
// taken in all cases if a modrm byte is NOT required.
|
||||
i->execute = BxOpcodeInfo64R[b1+offset].ExecutePtr;
|
||||
i->metaData.modRMData1 = (b1 & 7) | rex_b;
|
||||
i->setOpcodeReg((b1 & 7) | rex_b);
|
||||
}
|
||||
|
||||
if (lock) { // lock prefix invalid opcode
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: instr.h,v 1.3 2008-02-02 21:46:51 sshwarts Exp $
|
||||
// $Id: instr.h,v 1.4 2008-02-04 21:28:53 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2008 Stanislav Shwartsman
|
||||
@ -40,16 +40,14 @@ public:
|
||||
#endif
|
||||
|
||||
struct {
|
||||
// 31..29 (unused)
|
||||
// 28..20 b1 (9bits of opcode; 1byte-op=0..255, 2byte-op=256..511
|
||||
// 15...7 b1 (9bits of opcode; 1byte-op=0..255, 2byte-op=256..511
|
||||
// (leave this one on top so no mask is needed)
|
||||
// 19..19 stop trace (used with trace cache)
|
||||
// 18..18 mod==c0 (modrm)
|
||||
// 17..16 repUsed (0=none, 2=0xF2, 3=0xF3)
|
||||
// 6...1 (unused - 6 bits)
|
||||
// 0...0 stop trace (used with trace cache)
|
||||
Bit16u metaInfo3;
|
||||
|
||||
// 15..12 (unused)
|
||||
// 11...8 ilen (0..15)
|
||||
// 7...4 (unused)
|
||||
// 3...0 ilen (0..15)
|
||||
Bit8u metaInfo2;
|
||||
|
||||
// 7...7 extend8bit
|
||||
@ -57,27 +55,42 @@ public:
|
||||
// 5...5 os64
|
||||
// 4...4 as32
|
||||
// 3...3 os32
|
||||
// 2...0 seg
|
||||
// 2...2 mod==c0 (modrm)
|
||||
// 1...0 repUsed (0=none, 2=0xF2, 3=0xF3)
|
||||
Bit8u metaInfo1;
|
||||
} metaInfo;
|
||||
|
||||
struct {
|
||||
// 31..28 (unused)
|
||||
// 27..24 nnn (modrm)
|
||||
Bit8u modRMData4;
|
||||
// (unused, keep for alignment)
|
||||
// (will be used for SSE5 destination override later)
|
||||
Bit8u metaData8;
|
||||
|
||||
// 23..20 (unused)
|
||||
// 19..16 base (sib)
|
||||
Bit8u modRMData3;
|
||||
// 7...0 modrm
|
||||
Bit8u metaData7;
|
||||
|
||||
// 15..14 mod (modrm)
|
||||
// 13..12 scale (sib)
|
||||
// 11...8 index (sib)
|
||||
Bit8u modRMData2;
|
||||
// 7...3 (unused)
|
||||
// 2...0 seg
|
||||
Bit8u metaData6;
|
||||
|
||||
// 7...4 (unused)
|
||||
// 3...0 nnn (modrm)
|
||||
Bit8u metaData5;
|
||||
|
||||
// 7...4 (unused)
|
||||
// 3...0 base (sib)
|
||||
Bit8u metaData4;
|
||||
|
||||
// 7...4 (unused)
|
||||
// 3...0 index (sib)
|
||||
Bit8u metaData3;
|
||||
|
||||
// 7...2 (unused)
|
||||
// 1...0 scale (sib)
|
||||
Bit8u metaData2;
|
||||
|
||||
// 7...4 (unused)
|
||||
// 3...0 rm (modrm) // also used for opcodeReg()
|
||||
Bit8u modRMData1;
|
||||
Bit8u metaData1;
|
||||
} metaData;
|
||||
|
||||
union {
|
||||
@ -114,48 +127,54 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
BX_CPP_INLINE unsigned opcodeReg() {
|
||||
BX_CPP_INLINE void setOpcodeReg(unsigned opreg) {
|
||||
// The opcodeReg form (low 3 bits of the opcode byte (extended
|
||||
// by REX.B on x86-64) to be used with IxIxForm or IqForm.
|
||||
return metaData.modRMData1;
|
||||
metaData.metaData1 = opreg;
|
||||
}
|
||||
BX_CPP_INLINE unsigned opcodeReg() {
|
||||
return metaData.metaData1;
|
||||
}
|
||||
BX_CPP_INLINE void setModRM(unsigned modrm) {
|
||||
metaData.metaData7 = modrm;
|
||||
}
|
||||
// used in FPU only
|
||||
BX_CPP_INLINE unsigned modrm() {
|
||||
#if BX_SUPPORT_X86_64
|
||||
return mod() | (rm() & 7) | ((nnn() & 7) << 3);
|
||||
#else
|
||||
return mod() | rm() | (nnn() << 3);
|
||||
#endif
|
||||
return metaData.metaData7;
|
||||
}
|
||||
BX_CPP_INLINE unsigned mod() { return metaData.modRMData2 & 0xc0; }
|
||||
BX_CPP_INLINE unsigned modC0()
|
||||
{
|
||||
// This is a cheaper way to test for modRM instructions where
|
||||
// the mod field is 0xc0. FetchDecode flags this condition since
|
||||
// it is quite common to be tested for.
|
||||
return metaInfo.metaInfo3 & (1<<2);
|
||||
return metaInfo.metaInfo1 & (1<<2);
|
||||
}
|
||||
BX_CPP_INLINE unsigned assertModC0()
|
||||
{
|
||||
return metaInfo.metaInfo3 |= (1<<2);
|
||||
return metaInfo.metaInfo1 |= (1<<2);
|
||||
}
|
||||
BX_CPP_INLINE unsigned nnn() {
|
||||
return metaData.modRMData4;
|
||||
return metaData.metaData5;
|
||||
}
|
||||
BX_CPP_INLINE unsigned rm() {
|
||||
return metaData.modRMData1;
|
||||
return metaData.metaData1;
|
||||
}
|
||||
BX_CPP_INLINE void setSibScale(unsigned scale) {
|
||||
metaData.metaData2 = scale;
|
||||
}
|
||||
BX_CPP_INLINE unsigned sibScale() {
|
||||
return (metaData.modRMData2 >> 4) & 0x3;
|
||||
return metaData.metaData2;
|
||||
}
|
||||
BX_CPP_INLINE void setSibIndex(unsigned index) {
|
||||
metaData.metaData3 = index;
|
||||
}
|
||||
BX_CPP_INLINE unsigned sibIndex() {
|
||||
return (metaData.modRMData2) & 0xf;
|
||||
return metaData.metaData3;
|
||||
}
|
||||
BX_CPP_INLINE void setSibBase(unsigned base) {
|
||||
metaData.modRMData3 = base;
|
||||
metaData.metaData4 = base;
|
||||
}
|
||||
BX_CPP_INLINE unsigned sibBase() {
|
||||
return metaData.modRMData3;
|
||||
return metaData.metaData4;
|
||||
}
|
||||
BX_CPP_INLINE Bit32u displ32u() { return modRMForm.displ32u; }
|
||||
BX_CPP_INLINE Bit16u displ16u() { return modRMForm.displ16u; }
|
||||
@ -173,18 +192,18 @@ public:
|
||||
// is for Logical comparisons, eg if (i->os32L() && i->as32L()). If you
|
||||
// want a bx_bool value, use os32B() etc. This makes for smaller
|
||||
// code, when a strict 0 or 1 is not necessary.
|
||||
BX_CPP_INLINE void initMetaInfo(unsigned os32, unsigned as32,
|
||||
unsigned os64, unsigned as64)
|
||||
BX_CPP_INLINE void init(unsigned os32, unsigned as32, unsigned os64, unsigned as64)
|
||||
{
|
||||
metaInfo.metaInfo1 = BX_SEG_REG_NULL | (os32<<3) | (as32<<4) | (os64<<5) | (as64<<6);
|
||||
metaInfo.metaInfo1 = (os32<<3) | (as32<<4) | (os64<<5) | (as64<<6);
|
||||
metaInfo.metaInfo2 = 0;
|
||||
metaInfo.metaInfo3 = 0;
|
||||
metaData.metaData6 = BX_SEG_REG_NULL;
|
||||
}
|
||||
BX_CPP_INLINE unsigned seg(void) {
|
||||
return metaInfo.metaInfo1 & 7;
|
||||
return metaData.metaData6;
|
||||
}
|
||||
BX_CPP_INLINE void setSeg(unsigned val) {
|
||||
metaInfo.metaInfo1 = (metaInfo.metaInfo1 & ~7) | val;
|
||||
metaData.metaData6 = val;
|
||||
}
|
||||
|
||||
BX_CPP_INLINE unsigned os32L(void) {
|
||||
@ -249,13 +268,13 @@ public:
|
||||
}
|
||||
|
||||
BX_CPP_INLINE unsigned repUsedL(void) {
|
||||
return metaInfo.metaInfo3 & 3;
|
||||
return metaInfo.metaInfo1 & 3;
|
||||
}
|
||||
BX_CPP_INLINE unsigned repUsedValue(void) {
|
||||
return metaInfo.metaInfo3 & 3;
|
||||
return metaInfo.metaInfo1 & 3;
|
||||
}
|
||||
BX_CPP_INLINE void setRepUsed(unsigned value) {
|
||||
metaInfo.metaInfo3 = (metaInfo.metaInfo3 & ~3) | (value);
|
||||
metaInfo.metaInfo1 = (metaInfo.metaInfo1 & ~3) | (value);
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_TRACE_CACHE
|
||||
@ -270,10 +289,10 @@ public:
|
||||
// Note this is the highest field, and thus needs no masking.
|
||||
// DON'T PUT ANY FIELDS HIGHER THAN THIS ONE WITHOUT ADDING A MASK.
|
||||
BX_CPP_INLINE unsigned b1(void) {
|
||||
return metaInfo.metaInfo3 >> 4;
|
||||
return metaInfo.metaInfo3 >> 7;
|
||||
}
|
||||
BX_CPP_INLINE void setB1(unsigned b1) {
|
||||
metaInfo.metaInfo3 = (metaInfo.metaInfo3 & ~(0x1ff << 4)) | ((b1 & 0x1ff) << 4);
|
||||
metaInfo.metaInfo3 = (metaInfo.metaInfo3 & ~(0x1ff << 7)) | ((b1 & 0x1ff) << 7);
|
||||
}
|
||||
};
|
||||
// <TAG-CLASS-INSTRUCTION-END>
|
||||
|
Loading…
x
Reference in New Issue
Block a user