class Checkpoint;
void MiscRegFile::updateHandyM5Reg(Efer efer, CR0 cr0,
- SegAttr csAttr, RFLAGS rflags)
+ SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags)
{
HandyM5Reg m5reg;
if (efer.lma) {
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;
}
updateHandyM5Reg(regVal[MISCREG_EFER],
newCR0,
regVal[MISCREG_CS_ATTR],
+ regVal[MISCREG_SS_ATTR],
regVal[MISCREG_RFLAGS]);
}
break;
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:
updateHandyM5Reg(regVal[MISCREG_EFER],
regVal[MISCREG_CR0],
regVal[MISCREG_CS_ATTR],
+ regVal[MISCREG_SS_ATTR],
regVal[MISCREG_RFLAGS]);
return;
default:
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()
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;
//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];
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;