* Authors: Gabe Black
*/
-#include "arch/x86/floatregs.hh"
+#include "arch/x86/decoder.hh"
#include "arch/x86/isa.hh"
#include "arch/x86/tlb.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
+#include "params/X86ISA.hh"
#include "sim/serialize.hh"
namespace X86ISA
void
ISA::updateHandyM5Reg(Efer efer, CR0 cr0,
- SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags)
+ SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags,
+ ThreadContext *tc)
{
- HandyM5Reg m5reg;
+ HandyM5Reg m5reg = 0;
if (efer.lma) {
m5reg.mode = LongMode;
if (csAttr.longMode)
}
regVal[MISCREG_M5_REG] = m5reg;
+ if (tc)
+ tc->getDecoderPtr()->setM5Reg(m5reg);
}
void
regVal[MISCREG_DR7] = 1 << 10;
}
+ISA::ISA(Params *p)
+ : SimObject(p)
+{
+ clear();
+}
+
+const X86ISAParams *
+ISA::params() const
+{
+ return dynamic_cast<const Params *>(_params);
+}
+
MiscReg
ISA::readMiscRegNoEffect(int miscReg)
{
if (miscReg == MISCREG_TSC) {
return regVal[MISCREG_TSC] + tc->getCpuPtr()->curCycle();
}
+
+ if (miscReg == MISCREG_FSW) {
+ MiscReg fsw = regVal[MISCREG_FSW];
+ MiscReg top = regVal[MISCREG_X87_TOP];
+ return (fsw & (~(7ULL << 11))) + (top << 11);
+ }
+
return readMiscRegNoEffect(miscReg);
}
}
}
if (toggled.pg) {
- tc->getITBPtr()->invalidateAll();
- tc->getDTBPtr()->invalidateAll();
+ tc->getITBPtr()->flushAll();
+ tc->getDTBPtr()->flushAll();
}
//This must always be 1.
newCR0.et = 1;
newCR0,
regVal[MISCREG_CS_ATTR],
regVal[MISCREG_SS_ATTR],
- regVal[MISCREG_RFLAGS]);
+ regVal[MISCREG_RFLAGS],
+ tc);
}
break;
case MISCREG_CR2:
break;
case MISCREG_CR3:
- tc->getITBPtr()->invalidateNonGlobal();
- tc->getDTBPtr()->invalidateNonGlobal();
+ tc->getITBPtr()->flushNonGlobal();
+ tc->getDTBPtr()->flushNonGlobal();
break;
case MISCREG_CR4:
{
CR4 toggled = regVal[miscReg] ^ val;
if (toggled.pae || toggled.pse || toggled.pge) {
- tc->getITBPtr()->invalidateAll();
- tc->getDTBPtr()->invalidateAll();
+ tc->getITBPtr()->flushAll();
+ tc->getDTBPtr()->flushAll();
}
}
break;
regVal[MISCREG_CR0],
newCSAttr,
regVal[MISCREG_SS_ATTR],
- regVal[MISCREG_RFLAGS]);
+ regVal[MISCREG_RFLAGS],
+ tc);
}
break;
case MISCREG_SS_ATTR:
regVal[MISCREG_CR0],
regVal[MISCREG_CS_ATTR],
val,
- regVal[MISCREG_RFLAGS]);
+ regVal[MISCREG_RFLAGS],
+ tc);
break;
// These segments always actually use their bases, or in other words
// their effective bases must stay equal to their actual bases.
regVal[MISCREG_CR0],
regVal[MISCREG_CS_ATTR],
regVal[MISCREG_SS_ATTR],
- regVal[MISCREG_RFLAGS]);
+ regVal[MISCREG_RFLAGS],
+ tc);
return;
default:
break;
}
void
-ISA::serialize(EventManager *em, std::ostream & os)
+ISA::serialize(std::ostream & os)
{
SERIALIZE_ARRAY(regVal, NumMiscRegs);
}
void
-ISA::unserialize(EventManager *em, Checkpoint * cp,
- const std::string & section)
+ISA::unserialize(Checkpoint * cp, const std::string & section)
{
UNSERIALIZE_ARRAY(regVal, NumMiscRegs);
+ updateHandyM5Reg(regVal[MISCREG_EFER],
+ regVal[MISCREG_CR0],
+ regVal[MISCREG_CS_ATTR],
+ regVal[MISCREG_SS_ATTR],
+ regVal[MISCREG_RFLAGS],
+ NULL);
}
-int
-ISA::flattenIntIndex(int reg)
+void
+ISA::startup(ThreadContext *tc)
{
- //If we need to fold over the index to match byte semantics, do that.
- //Otherwise, just strip off any extra bits and pass it through.
- if (reg & (1 << 6))
- return (reg & (~(1 << 6) - 0x4));
- else
- return (reg & ~(1 << 6));
+ tc->getDecoderPtr()->setM5Reg(regVal[MISCREG_M5_REG]);
}
-int
-ISA::flattenFloatIndex(int reg)
-{
- if (reg >= NUM_FLOATREGS) {
- int top = readMiscRegNoEffect(MISCREG_X87_TOP);
- reg = FLOATREG_STACK(reg - NUM_FLOATREGS, top);
- }
- return reg;
}
+X86ISA::ISA *
+X86ISAParams::create()
+{
+ return new X86ISA::ISA(this);
}