ARM: Cleanup implementation of ITSTATE and put important code in PCState.
Consolidate all code to handle ITSTATE in the PCState object rather than touching a variety of structures/objects.
This commit is contained in:
parent
ac650199ee
commit
a679cd917a
21 changed files with 81 additions and 277 deletions
|
@ -76,12 +76,6 @@ class Predecoder
|
||||||
emiIsReady = false;
|
emiIsReady = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
reset(const ExtMachInst &old_emi)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use this to give data to the predecoder. This should be used
|
// Use this to give data to the predecoder. This should be used
|
||||||
// when there is control flow.
|
// when there is control flow.
|
||||||
void
|
void
|
||||||
|
|
|
@ -108,7 +108,9 @@ ArmFault::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) |
|
CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) |
|
||||||
tc->readIntReg(INTREG_CONDCODES);
|
tc->readIntReg(INTREG_CONDCODES);
|
||||||
Addr curPc M5_VAR_USED = tc->pcState().pc();
|
Addr curPc M5_VAR_USED = tc->pcState().pc();
|
||||||
|
ITSTATE it = tc->pcState().itstate();
|
||||||
|
saved_cpsr.it2 = it.top6;
|
||||||
|
saved_cpsr.it1 = it.bottom2;
|
||||||
|
|
||||||
cpsr.mode = nextMode();
|
cpsr.mode = nextMode();
|
||||||
cpsr.it1 = cpsr.it2 = 0;
|
cpsr.it1 = cpsr.it2 = 0;
|
||||||
|
@ -159,7 +161,7 @@ Reset::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
tc->getCpuPtr()->clearInterrupts();
|
tc->getCpuPtr()->clearInterrupts();
|
||||||
tc->clearArchRegs();
|
tc->clearArchRegs();
|
||||||
ArmFault::invoke(tc);
|
ArmFault::invoke(tc, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -203,7 +205,7 @@ template<class T>
|
||||||
void
|
void
|
||||||
AbortFault<T>::invoke(ThreadContext *tc, StaticInstPtr inst)
|
AbortFault<T>::invoke(ThreadContext *tc, StaticInstPtr inst)
|
||||||
{
|
{
|
||||||
ArmFaultVals<T>::invoke(tc);
|
ArmFaultVals<T>::invoke(tc, inst);
|
||||||
FSR fsr = 0;
|
FSR fsr = 0;
|
||||||
fsr.fsLow = bits(status, 3, 0);
|
fsr.fsLow = bits(status, 3, 0);
|
||||||
fsr.fsHigh = bits(status, 4);
|
fsr.fsHigh = bits(status, 4);
|
||||||
|
@ -223,7 +225,6 @@ FlushPipe::invoke(ThreadContext *tc, StaticInstPtr inst) {
|
||||||
// start refetching from the next instruction.
|
// start refetching from the next instruction.
|
||||||
PCState pc = tc->pcState();
|
PCState pc = tc->pcState();
|
||||||
assert(inst);
|
assert(inst);
|
||||||
pc.forcedItState(inst->machInst.newItstate);
|
|
||||||
inst->advancePC(pc);
|
inst->advancePC(pc);
|
||||||
tc->pcState(pc);
|
tc->pcState(pc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,18 +266,6 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
|
||||||
miscRegName[misc_reg], val);
|
miscRegName[misc_reg], val);
|
||||||
} else {
|
} else {
|
||||||
switch (misc_reg) {
|
switch (misc_reg) {
|
||||||
case MISCREG_ITSTATE:
|
|
||||||
{
|
|
||||||
ITSTATE itstate = newVal;
|
|
||||||
CPSR cpsr = miscRegs[MISCREG_CPSR];
|
|
||||||
cpsr.it1 = itstate.bottom2;
|
|
||||||
cpsr.it2 = itstate.top6;
|
|
||||||
miscRegs[MISCREG_CPSR] = cpsr;
|
|
||||||
DPRINTF(MiscRegs,
|
|
||||||
"Updating ITSTATE -> %#x in CPSR -> %#x.\n",
|
|
||||||
(uint8_t)itstate, (uint32_t)cpsr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MISCREG_CPACR:
|
case MISCREG_CPACR:
|
||||||
{
|
{
|
||||||
CPACR newCpacr = 0;
|
CPACR newCpacr = 0;
|
||||||
|
|
|
@ -245,7 +245,7 @@ let {{
|
||||||
CondCodes = CondCodesMask & newCpsr;
|
CondCodes = CondCodesMask & newCpsr;
|
||||||
NextThumb = ((CPSR)newCpsr).t;
|
NextThumb = ((CPSR)newCpsr).t;
|
||||||
NextJazelle = ((CPSR)newCpsr).j;
|
NextJazelle = ((CPSR)newCpsr).j;
|
||||||
ForcedItState = ((((CPSR)newCpsr).it2 << 2) & 0xFC)
|
NextItState = ((((CPSR)newCpsr).it2 << 2) & 0xFC)
|
||||||
| (((CPSR)newCpsr).it1 & 0x3);
|
| (((CPSR)newCpsr).it1 & 0x3);
|
||||||
'''
|
'''
|
||||||
buildImmDataInst(mnem + 's', code, flagType,
|
buildImmDataInst(mnem + 's', code, flagType,
|
||||||
|
|
|
@ -94,7 +94,7 @@ let {{
|
||||||
Cpsr = ~CondCodesMask & newCpsr;
|
Cpsr = ~CondCodesMask & newCpsr;
|
||||||
CondCodes = CondCodesMask & newCpsr;
|
CondCodes = CondCodesMask & newCpsr;
|
||||||
IWNPC = cSwap(%s, cpsr.e) | ((Spsr & 0x20) ? 1 : 0);
|
IWNPC = cSwap(%s, cpsr.e) | ((Spsr & 0x20) ? 1 : 0);
|
||||||
ForcedItState = ((((CPSR)Spsr).it2 << 2) & 0xFC)
|
NextItState = ((((CPSR)Spsr).it2 << 2) & 0xFC)
|
||||||
| (((CPSR)Spsr).it1 & 0x3);
|
| (((CPSR)Spsr).it1 & 0x3);
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -628,7 +628,7 @@ let {{
|
||||||
Cpsr = ~CondCodesMask & newCpsr;
|
Cpsr = ~CondCodesMask & newCpsr;
|
||||||
NextThumb = ((CPSR)newCpsr).t;
|
NextThumb = ((CPSR)newCpsr).t;
|
||||||
NextJazelle = ((CPSR)newCpsr).j;
|
NextJazelle = ((CPSR)newCpsr).j;
|
||||||
ForcedItState = ((((CPSR)URb).it2 << 2) & 0xFC)
|
NextItState = ((((CPSR)URb).it2 << 2) & 0xFC)
|
||||||
| (((CPSR)URb).it1 & 0x3);
|
| (((CPSR)URb).it1 & 0x3);
|
||||||
CondCodes = CondCodesMask & newCpsr;
|
CondCodes = CondCodesMask & newCpsr;
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -83,10 +83,6 @@ let {{
|
||||||
uint32_t newCpsr =
|
uint32_t newCpsr =
|
||||||
cpsrWriteByInstr(Cpsr | CondCodes, Op1, byteMask, false, sctlr.nmfi);
|
cpsrWriteByInstr(Cpsr | CondCodes, Op1, byteMask, false, sctlr.nmfi);
|
||||||
Cpsr = ~CondCodesMask & newCpsr;
|
Cpsr = ~CondCodesMask & newCpsr;
|
||||||
NextThumb = ((CPSR)newCpsr).t;
|
|
||||||
NextJazelle = ((CPSR)newCpsr).j;
|
|
||||||
ForcedItState = ((((CPSR)Op1).it2 << 2) & 0xFC)
|
|
||||||
| (((CPSR)Op1).it1 & 0x3);
|
|
||||||
CondCodes = CondCodesMask & newCpsr;
|
CondCodes = CondCodesMask & newCpsr;
|
||||||
'''
|
'''
|
||||||
msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
|
msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
|
||||||
|
@ -111,10 +107,6 @@ let {{
|
||||||
uint32_t newCpsr =
|
uint32_t newCpsr =
|
||||||
cpsrWriteByInstr(Cpsr | CondCodes, imm, byteMask, false, sctlr.nmfi);
|
cpsrWriteByInstr(Cpsr | CondCodes, imm, byteMask, false, sctlr.nmfi);
|
||||||
Cpsr = ~CondCodesMask & newCpsr;
|
Cpsr = ~CondCodesMask & newCpsr;
|
||||||
NextThumb = ((CPSR)newCpsr).t;
|
|
||||||
NextJazelle = ((CPSR)newCpsr).j;
|
|
||||||
ForcedItState = ((((CPSR)imm).it2 << 2) & 0xFC)
|
|
||||||
| (((CPSR)imm).it1 & 0x3);
|
|
||||||
CondCodes = CondCodesMask & newCpsr;
|
CondCodes = CondCodesMask & newCpsr;
|
||||||
'''
|
'''
|
||||||
msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",
|
msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",
|
||||||
|
@ -538,7 +530,7 @@ let {{
|
||||||
exec_output += PredOpExecute.subst(sevIop)
|
exec_output += PredOpExecute.subst(sevIop)
|
||||||
|
|
||||||
itIop = InstObjParams("it", "ItInst", "PredOp", \
|
itIop = InstObjParams("it", "ItInst", "PredOp", \
|
||||||
{ "code" : "Itstate = machInst.newItstate;",
|
{ "code" : ";",
|
||||||
"predicate_test" : predicateTest },
|
"predicate_test" : predicateTest },
|
||||||
["IsNonSpeculative", "IsSerializeAfter"])
|
["IsNonSpeculative", "IsSerializeAfter"])
|
||||||
header_output += BasicDeclare.subst(itIop)
|
header_output += BasicDeclare.subst(itIop)
|
||||||
|
|
|
@ -217,7 +217,6 @@ def operands {{
|
||||||
|
|
||||||
#Fixed index control regs
|
#Fixed index control regs
|
||||||
'Cpsr': cntrlReg('MISCREG_CPSR', srtCpsr),
|
'Cpsr': cntrlReg('MISCREG_CPSR', srtCpsr),
|
||||||
'Itstate': cntrlRegNC('MISCREG_ITSTATE', type = 'ub'),
|
|
||||||
'Spsr': cntrlRegNC('MISCREG_SPSR'),
|
'Spsr': cntrlRegNC('MISCREG_SPSR'),
|
||||||
'Fpsr': cntrlRegNC('MISCREG_FPSR'),
|
'Fpsr': cntrlRegNC('MISCREG_FPSR'),
|
||||||
'Fpsid': cntrlRegNC('MISCREG_FPSID'),
|
'Fpsid': cntrlRegNC('MISCREG_FPSID'),
|
||||||
|
@ -247,7 +246,8 @@ def operands {{
|
||||||
'Thumb': pcStateReg('thumb', srtPC),
|
'Thumb': pcStateReg('thumb', srtPC),
|
||||||
'NextThumb': pcStateReg('nextThumb', srtMode),
|
'NextThumb': pcStateReg('nextThumb', srtMode),
|
||||||
'NextJazelle': pcStateReg('nextJazelle', srtMode),
|
'NextJazelle': pcStateReg('nextJazelle', srtMode),
|
||||||
'ForcedItState': pcStateReg('forcedItState', srtMode),
|
'NextItState': pcStateReg('nextItstate', srtMode),
|
||||||
|
'Itstate': pcStateReg('itstate', srtMode),
|
||||||
|
|
||||||
#Register operands depending on a field in the instruction encoding. These
|
#Register operands depending on a field in the instruction encoding. These
|
||||||
#should be avoided since they may not be portable across different
|
#should be avoided since they may not be portable across different
|
||||||
|
|
|
@ -241,10 +241,6 @@ def template MicroNeonMixExecute {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -102,11 +102,6 @@ def template SwapExecute {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0 &&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -135,11 +130,6 @@ def template SwapInitiateAcc {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0 &&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -166,10 +156,6 @@ def template SwapCompleteAcc {{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -199,11 +185,6 @@ def template LoadExecute {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0 &&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -238,11 +219,6 @@ def template NeonLoadExecute {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0 &&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -276,11 +252,6 @@ def template StoreExecute {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0 &&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -319,11 +290,6 @@ def template NeonStoreExecute {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0 &&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -363,11 +329,6 @@ def template StoreExExecute {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0 &&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -396,10 +357,6 @@ def template StoreExInitiateAcc {{
|
||||||
} else {
|
} else {
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
if (fault == NoFault && machInst.itstateMask != 0 &&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
|
@ -430,11 +387,6 @@ def template StoreInitiateAcc {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0 &&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -467,11 +419,6 @@ def template NeonStoreInitiateAcc {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0 &&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -494,10 +441,6 @@ def template LoadInitiateAcc {{
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
if (fault == NoFault && machInst.itstateMask != 0 &&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
|
@ -523,10 +466,6 @@ def template NeonLoadInitiateAcc {{
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
if (fault == NoFault && machInst.itstateMask != 0 &&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
|
@ -557,10 +496,6 @@ def template LoadCompleteAcc {{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -591,10 +526,6 @@ def template NeonLoadCompleteAcc {{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -604,10 +535,6 @@ def template StoreCompleteAcc {{
|
||||||
%(CPU_exec_context)s *xc,
|
%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
if (machInst.itstateMask != 0) {
|
|
||||||
warn_once("Complete acc isn't called on normal stores in O3.");
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
return NoFault;
|
return NoFault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -618,10 +545,6 @@ def template NeonStoreCompleteAcc {{
|
||||||
PacketPtr pkt, %(CPU_exec_context)s *xc,
|
PacketPtr pkt, %(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
if (machInst.itstateMask != 0) {
|
|
||||||
warn_once("Complete acc isn't called on normal stores in O3.");
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
return NoFault;
|
return NoFault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -646,10 +569,6 @@ def template StoreExCompleteAcc {{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -438,9 +438,6 @@ def template ClrexInitiateAcc {{
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
if (fault == NoFault && machInst.itstateMask != 0) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
|
@ -452,10 +449,6 @@ def template ClrexCompleteAcc {{
|
||||||
%(CPU_exec_context)s *xc,
|
%(CPU_exec_context)s *xc,
|
||||||
Trace::InstRecord *traceData) const
|
Trace::InstRecord *traceData) const
|
||||||
{
|
{
|
||||||
if (machInst.itstateMask != 0) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NoFault;
|
return NoFault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -229,10 +229,6 @@ def template NeonEqualRegExecute {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -281,10 +277,6 @@ def template NeonUnequalRegExecute {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -174,11 +174,6 @@ def template PredOpExecute {{
|
||||||
xc->setPredicate(false);
|
xc->setPredicate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0&&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -206,11 +201,6 @@ def template QuiescePredOpExecute {{
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fault == NoFault && machInst.itstateMask != 0&&
|
|
||||||
(!isMicroop() || isLastMicroop())) {
|
|
||||||
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -67,7 +67,6 @@ namespace ArmISA
|
||||||
|
|
||||||
enum MiscRegIndex {
|
enum MiscRegIndex {
|
||||||
MISCREG_CPSR = 0,
|
MISCREG_CPSR = 0,
|
||||||
MISCREG_ITSTATE,
|
|
||||||
MISCREG_SPSR,
|
MISCREG_SPSR,
|
||||||
MISCREG_SPSR_FIQ,
|
MISCREG_SPSR_FIQ,
|
||||||
MISCREG_SPSR_IRQ,
|
MISCREG_SPSR_IRQ,
|
||||||
|
@ -207,7 +206,7 @@ namespace ArmISA
|
||||||
unsigned crm, unsigned opc2);
|
unsigned crm, unsigned opc2);
|
||||||
|
|
||||||
const char * const miscRegName[NUM_MISCREGS] = {
|
const char * const miscRegName[NUM_MISCREGS] = {
|
||||||
"cpsr", "itstate", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc",
|
"cpsr", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc",
|
||||||
"spsr_mon", "spsr_und", "spsr_abt",
|
"spsr_mon", "spsr_und", "spsr_abt",
|
||||||
"fpsr", "fpsid", "fpscr", "fpscr_qc", "fpscr_exc", "fpexc",
|
"fpsr", "fpsid", "fpscr", "fpscr_qc", "fpscr_exc", "fpexc",
|
||||||
"mvfr0", "mvfr1",
|
"mvfr0", "mvfr1",
|
||||||
|
@ -264,20 +263,6 @@ namespace ArmISA
|
||||||
Bitfield<4, 0> mode;
|
Bitfield<4, 0> mode;
|
||||||
EndBitUnion(CPSR)
|
EndBitUnion(CPSR)
|
||||||
|
|
||||||
BitUnion8(ITSTATE)
|
|
||||||
/* Note that the split (cond, mask) below is not as in ARM ARM.
|
|
||||||
* But it is more convenient for simulation. The condition
|
|
||||||
* is always the concatenation of the top 3 bits and the next bit,
|
|
||||||
* which applies when one of the bottom 4 bits is set.
|
|
||||||
* Refer to predecoder.cc for the use case.
|
|
||||||
*/
|
|
||||||
Bitfield<7, 4> cond;
|
|
||||||
Bitfield<3, 0> mask;
|
|
||||||
// Bitfields for moving to/from CPSR
|
|
||||||
Bitfield<7, 2> top6;
|
|
||||||
Bitfield<1, 0> bottom2;
|
|
||||||
EndBitUnion(ITSTATE)
|
|
||||||
|
|
||||||
// This mask selects bits of the CPSR that actually go in the CondCodes
|
// This mask selects bits of the CPSR that actually go in the CondCodes
|
||||||
// integer register to allow renaming.
|
// integer register to allow renaming.
|
||||||
static const uint32_t CondCodesMask = 0xF80F0000;
|
static const uint32_t CondCodesMask = 0xF80F0000;
|
||||||
|
|
|
@ -50,27 +50,6 @@
|
||||||
namespace ArmISA
|
namespace ArmISA
|
||||||
{
|
{
|
||||||
|
|
||||||
void
|
|
||||||
Predecoder::advanceThumbCond()
|
|
||||||
{
|
|
||||||
uint8_t condMask = itstate.mask;
|
|
||||||
uint8_t thumbCond = itstate.cond;
|
|
||||||
DPRINTF(Predecoder, "Advancing ITSTATE from %#x, %#x.\n",
|
|
||||||
thumbCond, condMask);
|
|
||||||
condMask = condMask << 1;
|
|
||||||
uint8_t newBit = bits(condMask, 4);
|
|
||||||
condMask &= mask(4);
|
|
||||||
if (condMask == 0) {
|
|
||||||
thumbCond = 0;
|
|
||||||
} else {
|
|
||||||
replaceBits(thumbCond, 0, newBit);
|
|
||||||
}
|
|
||||||
DPRINTF(Predecoder, "Advancing ITSTATE to %#x, %#x.\n",
|
|
||||||
thumbCond, condMask);
|
|
||||||
itstate.mask = condMask;
|
|
||||||
itstate.cond = thumbCond;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Predecoder::process()
|
Predecoder::process()
|
||||||
{
|
{
|
||||||
|
@ -93,11 +72,6 @@ Predecoder::process()
|
||||||
consumeBytes(2);
|
consumeBytes(2);
|
||||||
DPRINTF(Predecoder, "Second half of 32 bit Thumb: %#x.\n",
|
DPRINTF(Predecoder, "Second half of 32 bit Thumb: %#x.\n",
|
||||||
emi.instBits);
|
emi.instBits);
|
||||||
if (itstate.mask) {
|
|
||||||
emi.itstate = itstate;
|
|
||||||
advanceThumbCond();
|
|
||||||
emi.newItstate = itstate;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
uint16_t highBits = word & 0xF800;
|
uint16_t highBits = word & 0xF800;
|
||||||
if (highBits == 0xE800 || highBits == 0xF000 ||
|
if (highBits == 0xE800 || highBits == 0xF000 ||
|
||||||
|
@ -110,11 +84,6 @@ Predecoder::process()
|
||||||
DPRINTF(Predecoder, "All of 32 bit Thumb: %#x.\n",
|
DPRINTF(Predecoder, "All of 32 bit Thumb: %#x.\n",
|
||||||
emi.instBits);
|
emi.instBits);
|
||||||
consumeBytes(4);
|
consumeBytes(4);
|
||||||
if (itstate.mask) {
|
|
||||||
emi.itstate = itstate;
|
|
||||||
advanceThumbCond();
|
|
||||||
emi.newItstate = itstate;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// We only have the first half word.
|
// We only have the first half word.
|
||||||
DPRINTF(Predecoder,
|
DPRINTF(Predecoder,
|
||||||
|
@ -135,16 +104,11 @@ Predecoder::process()
|
||||||
emi.instBits);
|
emi.instBits);
|
||||||
if (bits(word, 15, 8) == 0xbf &&
|
if (bits(word, 15, 8) == 0xbf &&
|
||||||
bits(word, 3, 0) != 0x0) {
|
bits(word, 3, 0) != 0x0) {
|
||||||
emi.itstate = itstate;
|
foundIt = true;
|
||||||
itstate = bits(word, 7, 0);
|
itBits = bits(word, 7, 0);
|
||||||
emi.newItstate = itstate;
|
|
||||||
DPRINTF(Predecoder,
|
DPRINTF(Predecoder,
|
||||||
"IT detected, cond = %#x, mask = %#x\n",
|
"IT detected, cond = %#x, mask = %#x\n",
|
||||||
itstate.cond, itstate.mask);
|
itBits.cond, itBits.mask);
|
||||||
} else if (itstate.mask) {
|
|
||||||
emi.itstate = itstate;
|
|
||||||
advanceThumbCond();
|
|
||||||
emi.newItstate = itstate;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,16 +127,6 @@ Predecoder::moreBytes(const PCState &pc, Addr fetchPC, MachInst inst)
|
||||||
emi.fpscrLen = fpscr.len;
|
emi.fpscrLen = fpscr.len;
|
||||||
emi.fpscrStride = fpscr.stride;
|
emi.fpscrStride = fpscr.stride;
|
||||||
|
|
||||||
if (pc.forcedItStateIsValid()) {
|
|
||||||
// returns from exceptions/interrupts force the it state.
|
|
||||||
itstate = pc.forcedItState();
|
|
||||||
DPRINTF(Predecoder, "Predecoder, itstate forced = %08x.\n", pc.forcedItState());
|
|
||||||
} else if (predAddrValid && (pc.instAddr() != predAddr)) {
|
|
||||||
// Control flow changes necessitate a 0 itstate.
|
|
||||||
itstate.top6 = 0;
|
|
||||||
itstate.bottom2 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
outOfBytes = false;
|
outOfBytes = false;
|
||||||
process();
|
process();
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,9 +66,8 @@ namespace ArmISA
|
||||||
bool emiReady;
|
bool emiReady;
|
||||||
bool outOfBytes;
|
bool outOfBytes;
|
||||||
int offset;
|
int offset;
|
||||||
ITSTATE itstate;
|
bool foundIt;
|
||||||
Addr predAddr;
|
ITSTATE itBits;
|
||||||
bool predAddrValid;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void reset()
|
void reset()
|
||||||
|
@ -78,15 +77,7 @@ namespace ArmISA
|
||||||
emi = 0;
|
emi = 0;
|
||||||
emiReady = false;
|
emiReady = false;
|
||||||
outOfBytes = true;
|
outOfBytes = true;
|
||||||
itstate = 0;
|
foundIt = false;
|
||||||
predAddr = 0;
|
|
||||||
predAddrValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset(const ExtMachInst &old_emi)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
itstate = old_emi.newItstate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Predecoder(ThreadContext * _tc) :
|
Predecoder(ThreadContext * _tc) :
|
||||||
|
@ -106,7 +97,6 @@ namespace ArmISA
|
||||||
tc = _tc;
|
tc = _tc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void advanceThumbCond();
|
|
||||||
void process();
|
void process();
|
||||||
|
|
||||||
//Use this to give data to the predecoder. This should be used
|
//Use this to give data to the predecoder. This should be used
|
||||||
|
@ -149,11 +139,13 @@ namespace ArmISA
|
||||||
assert(emiReady);
|
assert(emiReady);
|
||||||
ExtMachInst thisEmi = emi;
|
ExtMachInst thisEmi = emi;
|
||||||
pc.npc(pc.pc() + getInstSize());
|
pc.npc(pc.pc() + getInstSize());
|
||||||
predAddrValid = true;
|
if (foundIt)
|
||||||
predAddr = pc.pc() + getInstSize();
|
pc.nextItstate(itBits);
|
||||||
|
thisEmi.itstate = pc.itstate();
|
||||||
pc.size(getInstSize());
|
pc.size(getInstSize());
|
||||||
emi = 0;
|
emi = 0;
|
||||||
emiReady = false;
|
emiReady = false;
|
||||||
|
foundIt = false;
|
||||||
return thisEmi;
|
return thisEmi;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,8 +53,22 @@ namespace ArmISA
|
||||||
{
|
{
|
||||||
typedef uint32_t MachInst;
|
typedef uint32_t MachInst;
|
||||||
|
|
||||||
|
BitUnion8(ITSTATE)
|
||||||
|
/* Note that the split (cond, mask) below is not as in ARM ARM.
|
||||||
|
* But it is more convenient for simulation. The condition
|
||||||
|
* is always the concatenation of the top 3 bits and the next bit,
|
||||||
|
* which applies when one of the bottom 4 bits is set.
|
||||||
|
* Refer to predecoder.cc for the use case.
|
||||||
|
*/
|
||||||
|
Bitfield<7, 4> cond;
|
||||||
|
Bitfield<3, 0> mask;
|
||||||
|
// Bitfields for moving to/from CPSR
|
||||||
|
Bitfield<7, 2> top6;
|
||||||
|
Bitfield<1, 0> bottom2;
|
||||||
|
EndBitUnion(ITSTATE)
|
||||||
|
|
||||||
|
|
||||||
BitUnion64(ExtMachInst)
|
BitUnion64(ExtMachInst)
|
||||||
Bitfield<63, 56> newItstate;
|
|
||||||
// ITSTATE bits
|
// ITSTATE bits
|
||||||
Bitfield<55, 48> itstate;
|
Bitfield<55, 48> itstate;
|
||||||
Bitfield<55, 52> itstateCond;
|
Bitfield<55, 52> itstateCond;
|
||||||
|
@ -202,11 +216,11 @@ namespace ArmISA
|
||||||
};
|
};
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint8_t nextFlags;
|
uint8_t nextFlags;
|
||||||
uint8_t forcedItStateValue;
|
uint8_t _itstate;
|
||||||
|
uint8_t _nextItstate;
|
||||||
uint8_t _size;
|
uint8_t _size;
|
||||||
bool forcedItStateValid;
|
|
||||||
public:
|
public:
|
||||||
PCState() : flags(0), nextFlags(0), forcedItStateValue(0), forcedItStateValid(false)
|
PCState() : flags(0), nextFlags(0), _itstate(0), _nextItstate(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -216,7 +230,7 @@ namespace ArmISA
|
||||||
npc(val + (thumb() ? 2 : 4));
|
npc(val + (thumb() ? 2 : 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
PCState(Addr val) : flags(0), nextFlags(0), forcedItStateValue(0), forcedItStateValid(false)
|
PCState(Addr val) : flags(0), nextFlags(0), _itstate(0), _nextItstate(0)
|
||||||
{ set(val); }
|
{ set(val); }
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -290,23 +304,27 @@ namespace ArmISA
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
forcedItState() const
|
itstate() const
|
||||||
{
|
{
|
||||||
return forcedItStateValue;
|
return _itstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
forcedItState(uint8_t value)
|
itstate(uint8_t value)
|
||||||
{
|
{
|
||||||
forcedItStateValue = value;
|
_itstate = value;
|
||||||
// Not valid unless the advance is called.
|
|
||||||
forcedItStateValid = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
uint8_t
|
||||||
forcedItStateIsValid() const
|
nextItstate() const
|
||||||
{
|
{
|
||||||
return forcedItStateValid;
|
return _nextItstate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nextItstate(uint8_t value)
|
||||||
|
{
|
||||||
|
_nextItstate = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -316,12 +334,27 @@ namespace ArmISA
|
||||||
npc(pc() + (thumb() ? 2 : 4));
|
npc(pc() + (thumb() ? 2 : 4));
|
||||||
flags = nextFlags;
|
flags = nextFlags;
|
||||||
|
|
||||||
// Validate the itState
|
if (_nextItstate) {
|
||||||
if (forcedItStateValue != 0 && !forcedItStateValid) {
|
_itstate = _nextItstate;
|
||||||
forcedItStateValid = true;
|
_nextItstate = 0;
|
||||||
} else {
|
} else if (_itstate) {
|
||||||
forcedItStateValid = false;
|
ITSTATE it = _itstate;
|
||||||
forcedItStateValue = 0;
|
uint8_t cond_mask = it.mask;
|
||||||
|
uint8_t thumb_cond = it.cond;
|
||||||
|
DPRINTF(Predecoder, "Advancing ITSTATE from %#x,%#x.\n",
|
||||||
|
thumb_cond, cond_mask);
|
||||||
|
cond_mask <<= 1;
|
||||||
|
uint8_t new_bit = bits(cond_mask, 4);
|
||||||
|
cond_mask &= mask(4);
|
||||||
|
if (cond_mask == 0)
|
||||||
|
thumb_cond = 0;
|
||||||
|
else
|
||||||
|
replaceBits(thumb_cond, 0, new_bit);
|
||||||
|
DPRINTF(Predecoder, "Advancing ITSTATE to %#x,%#x.\n",
|
||||||
|
thumb_cond, cond_mask);
|
||||||
|
it.mask = cond_mask;
|
||||||
|
it.cond = thumb_cond;
|
||||||
|
_itstate = it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,7 +428,8 @@ namespace ArmISA
|
||||||
operator == (const PCState &opc) const
|
operator == (const PCState &opc) const
|
||||||
{
|
{
|
||||||
return Base::operator == (opc) &&
|
return Base::operator == (opc) &&
|
||||||
flags == opc.flags && nextFlags == opc.nextFlags;
|
flags == opc.flags && nextFlags == opc.nextFlags &&
|
||||||
|
_itstate == opc._itstate && _nextItstate == opc._nextItstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -405,8 +439,8 @@ namespace ArmISA
|
||||||
SERIALIZE_SCALAR(flags);
|
SERIALIZE_SCALAR(flags);
|
||||||
SERIALIZE_SCALAR(_size);
|
SERIALIZE_SCALAR(_size);
|
||||||
SERIALIZE_SCALAR(nextFlags);
|
SERIALIZE_SCALAR(nextFlags);
|
||||||
SERIALIZE_SCALAR(forcedItStateValue);
|
SERIALIZE_SCALAR(_itstate);
|
||||||
SERIALIZE_SCALAR(forcedItStateValid);
|
SERIALIZE_SCALAR(_nextItstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -416,8 +450,8 @@ namespace ArmISA
|
||||||
UNSERIALIZE_SCALAR(flags);
|
UNSERIALIZE_SCALAR(flags);
|
||||||
UNSERIALIZE_SCALAR(_size);
|
UNSERIALIZE_SCALAR(_size);
|
||||||
UNSERIALIZE_SCALAR(nextFlags);
|
UNSERIALIZE_SCALAR(nextFlags);
|
||||||
UNSERIALIZE_SCALAR(forcedItStateValue);
|
UNSERIALIZE_SCALAR(_itstate);
|
||||||
UNSERIALIZE_SCALAR(forcedItStateValid);
|
UNSERIALIZE_SCALAR(_nextItstate);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -75,12 +75,6 @@ class Predecoder
|
||||||
emiIsReady = false;
|
emiIsReady = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
reset(const ExtMachInst &old_emi)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Use this to give data to the predecoder. This should be used
|
//Use this to give data to the predecoder. This should be used
|
||||||
//when there is control flow.
|
//when there is control flow.
|
||||||
void
|
void
|
||||||
|
|
|
@ -82,12 +82,6 @@ class Predecoder
|
||||||
emiIsReady = false;
|
emiIsReady = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
reset(const ExtMachInst &old_emi)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use this to give data to the predecoder. This should be used
|
// Use this to give data to the predecoder. This should be used
|
||||||
// when there is control flow.
|
// when there is control flow.
|
||||||
void
|
void
|
||||||
|
|
|
@ -75,12 +75,6 @@ class Predecoder
|
||||||
emiIsReady = false;
|
emiIsReady = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
reset(const ExtMachInst &old_emi)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use this to give data to the predecoder. This should be used
|
// Use this to give data to the predecoder. This should be used
|
||||||
// when there is control flow.
|
// when there is control flow.
|
||||||
void
|
void
|
||||||
|
|
|
@ -174,12 +174,6 @@ namespace X86ISA
|
||||||
state = ResetState;
|
state = ResetState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
reset(const ExtMachInst &old_emi)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadContext * getTC()
|
ThreadContext * getTC()
|
||||||
{
|
{
|
||||||
return tc;
|
return tc;
|
||||||
|
|
|
@ -821,8 +821,6 @@ DefaultFetch<Impl>::squash(const TheISA::PCState &newPC,
|
||||||
DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n", tid);
|
DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n", tid);
|
||||||
|
|
||||||
doSquash(newPC, tid);
|
doSquash(newPC, tid);
|
||||||
if (squashInst)
|
|
||||||
predecoder.reset(squashInst->staticInst->machInst);
|
|
||||||
|
|
||||||
// Tell the CPU to remove any instructions that are not in the ROB.
|
// Tell the CPU to remove any instructions that are not in the ROB.
|
||||||
cpu->removeInstsNotInROB(tid);
|
cpu->removeInstsNotInROB(tid);
|
||||||
|
|
Loading…
Reference in a new issue