X86: Keep handy values like the operating mode in one register.
This commit is contained in:
@@ -1100,6 +1100,11 @@ let {{
|
||||
DestReg = TscOp;
|
||||
'''
|
||||
|
||||
class Rdm5reg(RdRegOp):
|
||||
code = '''
|
||||
DestReg = M5Reg;
|
||||
'''
|
||||
|
||||
class Wrdl(RegOp):
|
||||
code = '''
|
||||
SegDescriptor desc = SrcReg1;
|
||||
|
||||
@@ -151,5 +151,6 @@ def operands {{
|
||||
'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207),
|
||||
'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208),
|
||||
'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 209),
|
||||
'M5Reg': ('ControlReg', 'udw', 'MISCREG_M5_REG', (None, None, None), 210),
|
||||
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300)
|
||||
}};
|
||||
|
||||
@@ -300,17 +300,39 @@ void MiscRegFile::setReg(int miscReg,
|
||||
CR0 toggled = regVal[miscReg] ^ val;
|
||||
CR0 newCR0 = val;
|
||||
Efer efer = regVal[MISCREG_EFER];
|
||||
HandyM5Reg m5reg = regVal[MISCREG_M5_REG];
|
||||
if (toggled.pg && efer.lme) {
|
||||
if (newCR0.pg) {
|
||||
//Turning on long mode
|
||||
efer.lma = 1;
|
||||
m5reg.mode = LongMode;
|
||||
regVal[MISCREG_EFER] = efer;
|
||||
} else {
|
||||
//Turning off long mode
|
||||
efer.lma = 0;
|
||||
m5reg.mode = LegacyMode;
|
||||
regVal[MISCREG_EFER] = efer;
|
||||
}
|
||||
}
|
||||
// Figure out what submode we're in.
|
||||
if (m5reg.mode == LongMode) {
|
||||
SegAttr csAttr = regVal[MISCREG_CS_ATTR];
|
||||
if (csAttr.longMode)
|
||||
m5reg.submode = SixtyFourBitMode;
|
||||
else
|
||||
m5reg.submode = CompatabilityMode;
|
||||
} else {
|
||||
if (newCR0.pe) {
|
||||
RFLAGS rflags = regVal[MISCREG_RFLAGS];
|
||||
if (rflags.vm)
|
||||
m5reg.submode = Virtual8086Mode;
|
||||
else
|
||||
m5reg.submode = ProtectedMode;
|
||||
} else {
|
||||
m5reg.submode = RealMode;
|
||||
}
|
||||
}
|
||||
regVal[MISCREG_M5_REG] = m5reg;
|
||||
if (toggled.pg) {
|
||||
tc->getITBPtr()->invalidateAll();
|
||||
tc->getDTBPtr()->invalidateAll();
|
||||
@@ -341,20 +363,26 @@ void MiscRegFile::setReg(int miscReg,
|
||||
{
|
||||
SegAttr toggled = regVal[miscReg] ^ val;
|
||||
SegAttr newCSAttr = val;
|
||||
HandyM5Reg m5reg = regVal[MISCREG_M5_REG];
|
||||
if (toggled.longMode) {
|
||||
SegAttr newCSAttr = val;
|
||||
if (newCSAttr.longMode) {
|
||||
if (m5reg.mode == LongMode)
|
||||
m5reg.submode = SixtyFourBitMode;
|
||||
regVal[MISCREG_ES_EFF_BASE] = 0;
|
||||
regVal[MISCREG_CS_EFF_BASE] = 0;
|
||||
regVal[MISCREG_SS_EFF_BASE] = 0;
|
||||
regVal[MISCREG_DS_EFF_BASE] = 0;
|
||||
} else {
|
||||
if (m5reg.mode == LongMode)
|
||||
m5reg.submode = CompatabilityMode;
|
||||
regVal[MISCREG_ES_EFF_BASE] = regVal[MISCREG_ES_BASE];
|
||||
regVal[MISCREG_CS_EFF_BASE] = regVal[MISCREG_CS_BASE];
|
||||
regVal[MISCREG_SS_EFF_BASE] = regVal[MISCREG_SS_BASE];
|
||||
regVal[MISCREG_DS_EFF_BASE] = regVal[MISCREG_DS_BASE];
|
||||
}
|
||||
}
|
||||
m5reg.cpl = newCSAttr.dpl;
|
||||
regVal[MISCREG_M5_REG] = m5reg;
|
||||
}
|
||||
break;
|
||||
// These segments always actually use their bases, or in other words
|
||||
|
||||
@@ -130,6 +130,9 @@ namespace X86ISA
|
||||
// Flags register
|
||||
MISCREG_RFLAGS = MISCREG_DR_BASE + NumDRegs,
|
||||
|
||||
//Register to keep handy values like the CPU mode in.
|
||||
MISCREG_M5_REG,
|
||||
|
||||
/*
|
||||
* Model Specific Registers
|
||||
*/
|
||||
@@ -563,6 +566,12 @@ namespace X86ISA
|
||||
Bitfield<0> cf; // Carry Flag
|
||||
EndBitUnion(RFLAGS)
|
||||
|
||||
BitUnion64(HandyM5Reg)
|
||||
Bitfield<0> mode;
|
||||
Bitfield<3, 1> submode;
|
||||
Bitfield<5, 4> cpl;
|
||||
EndBitUnion(HandyM5Reg)
|
||||
|
||||
/**
|
||||
* Control registers
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user