X86: Precompute the default and alternate address and operand size and the stack size.
This commit is contained in:
parent
b6bfe8af26
commit
7146eb79f1
5 changed files with 69 additions and 64 deletions
|
@ -97,7 +97,7 @@ using namespace std;
|
||||||
class Checkpoint;
|
class Checkpoint;
|
||||||
|
|
||||||
void MiscRegFile::updateHandyM5Reg(Efer efer, CR0 cr0,
|
void MiscRegFile::updateHandyM5Reg(Efer efer, CR0 cr0,
|
||||||
SegAttr csAttr, RFLAGS rflags)
|
SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags)
|
||||||
{
|
{
|
||||||
HandyM5Reg m5reg;
|
HandyM5Reg m5reg;
|
||||||
if (efer.lma) {
|
if (efer.lma) {
|
||||||
|
@ -120,6 +120,37 @@ void MiscRegFile::updateHandyM5Reg(Efer efer, CR0 cr0,
|
||||||
m5reg.cpl = csAttr.dpl;
|
m5reg.cpl = csAttr.dpl;
|
||||||
m5reg.paging = cr0.pg;
|
m5reg.paging = cr0.pg;
|
||||||
m5reg.prot = cr0.pe;
|
m5reg.prot = cr0.pe;
|
||||||
|
|
||||||
|
// Compute the default and alternate operand size.
|
||||||
|
if (m5reg.submode == SixtyFourBitMode || csAttr.defaultSize) {
|
||||||
|
m5reg.defOp = 2;
|
||||||
|
m5reg.altOp = 1;
|
||||||
|
} else {
|
||||||
|
m5reg.defOp = 1;
|
||||||
|
m5reg.altOp = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the default and alternate address size.
|
||||||
|
if (m5reg.submode == SixtyFourBitMode) {
|
||||||
|
m5reg.defAddr = 3;
|
||||||
|
m5reg.altAddr = 2;
|
||||||
|
} else if (csAttr.defaultSize) {
|
||||||
|
m5reg.defAddr = 2;
|
||||||
|
m5reg.altAddr = 1;
|
||||||
|
} else {
|
||||||
|
m5reg.defAddr = 1;
|
||||||
|
m5reg.altAddr = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the stack size
|
||||||
|
if (m5reg.submode == SixtyFourBitMode) {
|
||||||
|
m5reg.stack = 3;
|
||||||
|
} else if (ssAttr.defaultSize) {
|
||||||
|
m5reg.stack = 2;
|
||||||
|
} else {
|
||||||
|
m5reg.stack = 1;
|
||||||
|
}
|
||||||
|
|
||||||
regVal[MISCREG_M5_REG] = m5reg;
|
regVal[MISCREG_M5_REG] = m5reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,6 +230,7 @@ void MiscRegFile::setReg(MiscRegIndex miscReg,
|
||||||
updateHandyM5Reg(regVal[MISCREG_EFER],
|
updateHandyM5Reg(regVal[MISCREG_EFER],
|
||||||
newCR0,
|
newCR0,
|
||||||
regVal[MISCREG_CS_ATTR],
|
regVal[MISCREG_CS_ATTR],
|
||||||
|
regVal[MISCREG_SS_ATTR],
|
||||||
regVal[MISCREG_RFLAGS]);
|
regVal[MISCREG_RFLAGS]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -239,9 +271,17 @@ void MiscRegFile::setReg(MiscRegIndex miscReg,
|
||||||
updateHandyM5Reg(regVal[MISCREG_EFER],
|
updateHandyM5Reg(regVal[MISCREG_EFER],
|
||||||
regVal[MISCREG_CR0],
|
regVal[MISCREG_CR0],
|
||||||
newCSAttr,
|
newCSAttr,
|
||||||
|
regVal[MISCREG_SS_ATTR],
|
||||||
regVal[MISCREG_RFLAGS]);
|
regVal[MISCREG_RFLAGS]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MISCREG_SS_ATTR:
|
||||||
|
updateHandyM5Reg(regVal[MISCREG_EFER],
|
||||||
|
regVal[MISCREG_CR0],
|
||||||
|
regVal[MISCREG_CS_ATTR],
|
||||||
|
val,
|
||||||
|
regVal[MISCREG_RFLAGS]);
|
||||||
|
break;
|
||||||
// These segments always actually use their bases, or in other words
|
// These segments always actually use their bases, or in other words
|
||||||
// their effective bases must stay equal to their actual bases.
|
// their effective bases must stay equal to their actual bases.
|
||||||
case MISCREG_FS_BASE:
|
case MISCREG_FS_BASE:
|
||||||
|
@ -346,6 +386,7 @@ void MiscRegFile::setReg(MiscRegIndex miscReg,
|
||||||
updateHandyM5Reg(regVal[MISCREG_EFER],
|
updateHandyM5Reg(regVal[MISCREG_EFER],
|
||||||
regVal[MISCREG_CR0],
|
regVal[MISCREG_CR0],
|
||||||
regVal[MISCREG_CS_ATTR],
|
regVal[MISCREG_CS_ATTR],
|
||||||
|
regVal[MISCREG_SS_ATTR],
|
||||||
regVal[MISCREG_RFLAGS]);
|
regVal[MISCREG_RFLAGS]);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -108,7 +108,7 @@ namespace X86ISA
|
||||||
protected:
|
protected:
|
||||||
MiscReg regVal[NumMiscRegs];
|
MiscReg regVal[NumMiscRegs];
|
||||||
void updateHandyM5Reg(Efer efer, CR0 cr0,
|
void updateHandyM5Reg(Efer efer, CR0 cr0,
|
||||||
SegAttr csAttr, RFLAGS rflags);
|
SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void clear();
|
void clear();
|
||||||
|
|
|
@ -520,6 +520,11 @@ namespace X86ISA
|
||||||
Bitfield<5, 4> cpl;
|
Bitfield<5, 4> cpl;
|
||||||
Bitfield<6> paging;
|
Bitfield<6> paging;
|
||||||
Bitfield<7> prot;
|
Bitfield<7> prot;
|
||||||
|
Bitfield<9, 8> defOp;
|
||||||
|
Bitfield<11, 10> altOp;
|
||||||
|
Bitfield<13, 12> defAddr;
|
||||||
|
Bitfield<15, 14> altAddr;
|
||||||
|
Bitfield<17, 16> stack;
|
||||||
EndBitUnion(HandyM5Reg)
|
EndBitUnion(HandyM5Reg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -80,9 +80,9 @@ namespace X86ISA
|
||||||
|
|
||||||
emi.modRM = 0;
|
emi.modRM = 0;
|
||||||
emi.sib = 0;
|
emi.sib = 0;
|
||||||
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
m5Reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
||||||
emi.mode.mode = m5reg.mode;
|
emi.mode.mode = m5Reg.mode;
|
||||||
emi.mode.submode = m5reg.submode;
|
emi.mode.submode = m5Reg.submode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Predecoder::process()
|
void Predecoder::process()
|
||||||
|
@ -216,34 +216,15 @@ namespace X86ISA
|
||||||
DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
|
DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
|
||||||
emi.opcode.op = nextByte;
|
emi.opcode.op = nextByte;
|
||||||
|
|
||||||
SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
|
|
||||||
|
|
||||||
//Figure out the effective operand size. This can be overriden to
|
//Figure out the effective operand size. This can be overriden to
|
||||||
//a fixed value at the decoder level.
|
//a fixed value at the decoder level.
|
||||||
int logOpSize;
|
int logOpSize;
|
||||||
if (emi.mode.submode == SixtyFourBitMode)
|
if (emi.rex.w)
|
||||||
{
|
logOpSize = 3; // 64 bit operand size
|
||||||
if(emi.rex.w)
|
else if (emi.legacy.op)
|
||||||
logOpSize = 3; // 64 bit operand size
|
logOpSize = m5Reg.altOp;
|
||||||
else if(emi.legacy.op)
|
else
|
||||||
logOpSize = 1; // 16 bit operand size
|
logOpSize = m5Reg.defOp;
|
||||||
else
|
|
||||||
logOpSize = 2; // 32 bit operand size
|
|
||||||
}
|
|
||||||
else if(csAttr.defaultSize)
|
|
||||||
{
|
|
||||||
if(emi.legacy.op)
|
|
||||||
logOpSize = 1; // 16 bit operand size
|
|
||||||
else
|
|
||||||
logOpSize = 2; // 32 bit operand size
|
|
||||||
}
|
|
||||||
else // 16 bit default operand size
|
|
||||||
{
|
|
||||||
if(emi.legacy.op)
|
|
||||||
logOpSize = 2; // 32 bit operand size
|
|
||||||
else
|
|
||||||
logOpSize = 1; // 16 bit operand size
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set the actual op size
|
//Set the actual op size
|
||||||
emi.opSize = 1 << logOpSize;
|
emi.opSize = 1 << logOpSize;
|
||||||
|
@ -251,41 +232,18 @@ namespace X86ISA
|
||||||
//Figure out the effective address size. This can be overriden to
|
//Figure out the effective address size. This can be overriden to
|
||||||
//a fixed value at the decoder level.
|
//a fixed value at the decoder level.
|
||||||
int logAddrSize;
|
int logAddrSize;
|
||||||
if(emi.mode.submode == SixtyFourBitMode)
|
if(emi.legacy.addr)
|
||||||
{
|
logAddrSize = m5Reg.altAddr;
|
||||||
if(emi.legacy.addr)
|
|
||||||
logAddrSize = 2; // 32 bit address size
|
|
||||||
else
|
|
||||||
logAddrSize = 3; // 64 bit address size
|
|
||||||
}
|
|
||||||
else if(csAttr.defaultSize)
|
|
||||||
{
|
|
||||||
if(emi.legacy.addr)
|
|
||||||
logAddrSize = 1; // 16 bit address size
|
|
||||||
else
|
|
||||||
logAddrSize = 2; // 32 bit address size
|
|
||||||
}
|
|
||||||
else // 16 bit default operand size
|
|
||||||
{
|
|
||||||
if(emi.legacy.addr)
|
|
||||||
logAddrSize = 2; // 32 bit address size
|
|
||||||
else
|
|
||||||
logAddrSize = 1; // 16 bit address size
|
|
||||||
}
|
|
||||||
|
|
||||||
SegAttr ssAttr = tc->readMiscRegNoEffect(MISCREG_SS_ATTR);
|
|
||||||
//Figure out the effective stack width. This can be overriden to
|
|
||||||
//a fixed value at the decoder level.
|
|
||||||
if(emi.mode.submode == SixtyFourBitMode)
|
|
||||||
emi.stackSize = 8; // 64 bit stack width
|
|
||||||
else if(ssAttr.defaultSize)
|
|
||||||
emi.stackSize = 4; // 32 bit stack width
|
|
||||||
else
|
else
|
||||||
emi.stackSize = 2; // 16 bit stack width
|
logAddrSize = m5Reg.defAddr;
|
||||||
|
|
||||||
//Set the actual address size
|
//Set the actual address size
|
||||||
emi.addrSize = 1 << logAddrSize;
|
emi.addrSize = 1 << logAddrSize;
|
||||||
|
|
||||||
|
//Figure out the effective stack width. This can be overriden to
|
||||||
|
//a fixed value at the decoder level.
|
||||||
|
emi.stackSize = 1 << m5Reg.stack;
|
||||||
|
|
||||||
//Figure out how big of an immediate we'll retreive based
|
//Figure out how big of an immediate we'll retreive based
|
||||||
//on the opcode.
|
//on the opcode.
|
||||||
int immType = ImmediateType[emi.opcode.num - 1][nextByte];
|
int immType = ImmediateType[emi.opcode.num - 1][nextByte];
|
||||||
|
@ -318,9 +276,7 @@ namespace X86ISA
|
||||||
ModRM modRM;
|
ModRM modRM;
|
||||||
modRM = nextByte;
|
modRM = nextByte;
|
||||||
DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte);
|
DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte);
|
||||||
SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
|
if (m5Reg.defOp == 1) {
|
||||||
if (emi.mode.submode != SixtyFourBitMode &&
|
|
||||||
!csAttr.defaultSize) {
|
|
||||||
//figure out 16 bit displacement size
|
//figure out 16 bit displacement size
|
||||||
if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2)
|
if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2)
|
||||||
displacementSize = 2;
|
displacementSize = 2;
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include "arch/x86/types.hh"
|
#include "arch/x86/types.hh"
|
||||||
|
#include "arch/x86/miscregs.hh"
|
||||||
#include "base/bitfield.hh"
|
#include "base/bitfield.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
|
@ -91,10 +92,11 @@ namespace X86ISA
|
||||||
int offset;
|
int offset;
|
||||||
//The extended machine instruction being generated
|
//The extended machine instruction being generated
|
||||||
ExtMachInst emi;
|
ExtMachInst emi;
|
||||||
|
HandyM5Reg m5Reg;
|
||||||
|
|
||||||
inline uint8_t getNextByte()
|
inline uint8_t getNextByte()
|
||||||
{
|
{
|
||||||
return (fetchChunk >> (offset * 8)) & 0xff;
|
return ((uint8_t *)&fetchChunk)[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
void getImmediate(int &collected, uint64_t ¤t, int size)
|
void getImmediate(int &collected, uint64_t ¤t, int size)
|
||||||
|
@ -182,6 +184,7 @@ namespace X86ISA
|
||||||
{
|
{
|
||||||
emi.mode.mode = LongMode;
|
emi.mode.mode = LongMode;
|
||||||
emi.mode.submode = SixtyFourBitMode;
|
emi.mode.submode = SixtyFourBitMode;
|
||||||
|
m5Reg = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
|
|
Loading…
Reference in a new issue