X86: Precompute the default and alternate address and operand size and the stack size.

This commit is contained in:
Gabe Black 2009-04-26 16:49:24 -07:00
parent b6bfe8af26
commit 7146eb79f1
5 changed files with 69 additions and 64 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -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 &current, int size)
@ -182,6 +184,7 @@ namespace X86ISA
{
emi.mode.mode = LongMode;
emi.mode.submode = SixtyFourBitMode;
m5Reg = 0;
}
void reset()