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