Remove most of the special handling for delay slots since they have to be squashed anyway on a mispredict. This is because the NNPC value they saw when executing was incorrect.
--HG-- extra : convert_revision : b42c4eb28b4fbba66c65cbd0a5033bf886c1532d
This commit is contained in:
parent
6ec510385d
commit
c7f1cf1d58
|
@ -709,7 +709,9 @@ class BaseDynInst : public FastAlloc, public RefCounted
|
|||
/** Set the next NPC of this instruction (the target in Mips or Sparc).*/
|
||||
void setNextNPC(uint64_t val)
|
||||
{
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
nextNPC = val;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Sets the ASID. */
|
||||
|
|
|
@ -87,7 +87,6 @@ struct DefaultIEWDefaultCommit {
|
|||
bool squash[Impl::MaxThreads];
|
||||
bool branchMispredict[Impl::MaxThreads];
|
||||
bool branchTaken[Impl::MaxThreads];
|
||||
bool squashDelaySlot[Impl::MaxThreads];
|
||||
uint64_t mispredPC[Impl::MaxThreads];
|
||||
uint64_t nextPC[Impl::MaxThreads];
|
||||
uint64_t nextNPC[Impl::MaxThreads];
|
||||
|
@ -114,7 +113,6 @@ struct TimeBufStruct {
|
|||
uint64_t branchAddr;
|
||||
|
||||
InstSeqNum doneSeqNum;
|
||||
InstSeqNum bdelayDoneSeqNum;
|
||||
|
||||
// @todo: Might want to package this kind of branch stuff into a single
|
||||
// struct as it is used pretty frequently.
|
||||
|
@ -169,9 +167,6 @@ struct TimeBufStruct {
|
|||
// retired or squashed sequence number.
|
||||
InstSeqNum doneSeqNum;
|
||||
|
||||
InstSeqNum bdelayDoneSeqNum;
|
||||
bool squashDelaySlot;
|
||||
|
||||
//Just in case we want to do a commit/squash on a cycle
|
||||
//(necessary for multiple ROBs?)
|
||||
bool commitInsts;
|
||||
|
|
|
@ -741,38 +741,15 @@ DefaultCommit<Impl>::commit()
|
|||
// then use one older sequence number.
|
||||
InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
InstSeqNum bdelay_done_seq_num = squashed_inst;
|
||||
bool squash_bdelay_slot = fromIEW->squashDelaySlot[tid];
|
||||
bool branchMispredict = fromIEW->branchMispredict[tid];
|
||||
|
||||
// Squashing/not squashing the branch delay slot only makes
|
||||
// sense when you're squashing from a branch, ie from a branch
|
||||
// mispredict.
|
||||
if (branchMispredict && !squash_bdelay_slot) {
|
||||
bdelay_done_seq_num++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fromIEW->includeSquashInst[tid] == true) {
|
||||
squashed_inst--;
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
bdelay_done_seq_num--;
|
||||
#endif
|
||||
}
|
||||
|
||||
// All younger instructions will be squashed. Set the sequence
|
||||
// number as the youngest instruction in the ROB.
|
||||
youngestSeqNum[tid] = squashed_inst;
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
rob->squash(bdelay_done_seq_num, tid);
|
||||
toIEW->commitInfo[tid].squashDelaySlot = squash_bdelay_slot;
|
||||
toIEW->commitInfo[tid].bdelayDoneSeqNum = bdelay_done_seq_num;
|
||||
#else
|
||||
rob->squash(squashed_inst, tid);
|
||||
toIEW->commitInfo[tid].squashDelaySlot = true;
|
||||
#endif
|
||||
changedROBNumEntries[tid] = true;
|
||||
|
||||
toIEW->commitInfo[tid].doneSeqNum = squashed_inst;
|
||||
|
@ -809,10 +786,6 @@ DefaultCommit<Impl>::commit()
|
|||
|
||||
// Try to commit any instructions.
|
||||
commitInsts();
|
||||
} else {
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
skidInsert();
|
||||
#endif
|
||||
}
|
||||
|
||||
//Check for any activity
|
||||
|
@ -1164,37 +1137,13 @@ DefaultCommit<Impl>::getInsts()
|
|||
{
|
||||
DPRINTF(Commit, "Getting instructions from Rename stage.\n");
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
// Read any renamed instructions and place them into the ROB.
|
||||
int insts_to_process = std::min((int)renameWidth,
|
||||
(int)(fromRename->size + skidBuffer.size()));
|
||||
int rename_idx = 0;
|
||||
|
||||
DPRINTF(Commit, "%i insts available to process. Rename Insts:%i "
|
||||
"SkidBuffer Insts:%i\n", insts_to_process, fromRename->size,
|
||||
skidBuffer.size());
|
||||
#else
|
||||
// Read any renamed instructions and place them into the ROB.
|
||||
int insts_to_process = std::min((int)renameWidth, fromRename->size);
|
||||
#endif
|
||||
|
||||
|
||||
for (int inst_num = 0; inst_num < insts_to_process; ++inst_num) {
|
||||
DynInstPtr inst;
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
// Get insts from skidBuffer or from Rename
|
||||
if (skidBuffer.size() > 0) {
|
||||
DPRINTF(Commit, "Grabbing skidbuffer inst.\n");
|
||||
inst = skidBuffer.front();
|
||||
skidBuffer.pop();
|
||||
} else {
|
||||
DPRINTF(Commit, "Grabbing rename inst.\n");
|
||||
inst = fromRename->insts[rename_idx++];
|
||||
}
|
||||
#else
|
||||
inst = fromRename->insts[inst_num];
|
||||
#endif
|
||||
int tid = inst->threadNumber;
|
||||
|
||||
if (!inst->isSquashed() &&
|
||||
|
@ -1216,30 +1165,6 @@ DefaultCommit<Impl>::getInsts()
|
|||
inst->readPC(), inst->seqNum, tid);
|
||||
}
|
||||
}
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
if (rename_idx < fromRename->size) {
|
||||
DPRINTF(Commit,"Placing Rename Insts into skidBuffer.\n");
|
||||
|
||||
for (;
|
||||
rename_idx < fromRename->size;
|
||||
rename_idx++) {
|
||||
DynInstPtr inst = fromRename->insts[rename_idx];
|
||||
|
||||
if (!inst->isSquashed()) {
|
||||
DPRINTF(Commit, "Inserting PC %#x [sn:%i] [tid:%i] into ",
|
||||
"skidBuffer.\n", inst->readPC(), inst->seqNum,
|
||||
inst->threadNumber);
|
||||
skidBuffer.push(inst);
|
||||
} else {
|
||||
DPRINTF(Commit, "Instruction PC %#x [sn:%i] [tid:%i] was "
|
||||
"squashed, skipping.\n",
|
||||
inst->readPC(), inst->seqNum, inst->threadNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
|
|
@ -696,7 +696,7 @@ FullO3CPU<Impl>::removeThread(unsigned tid)
|
|||
|
||||
// Squash Throughout Pipeline
|
||||
InstSeqNum squash_seq_num = commit.rob->readHeadInst(tid)->seqNum;
|
||||
fetch.squash(0, sizeof(TheISA::MachInst), squash_seq_num, true, tid);
|
||||
fetch.squash(0, sizeof(TheISA::MachInst), squash_seq_num, tid);
|
||||
decode.squash(tid);
|
||||
rename.squash(squash_seq_num, tid);
|
||||
iew.squash(tid);
|
||||
|
@ -1226,9 +1226,7 @@ FullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst)
|
|||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::removeInstsNotInROB(unsigned tid,
|
||||
bool squash_delay_slot,
|
||||
const InstSeqNum &delay_slot_seq_num)
|
||||
FullO3CPU<Impl>::removeInstsNotInROB(unsigned tid)
|
||||
{
|
||||
DPRINTF(O3CPU, "Thread %i: Deleting instructions from instruction"
|
||||
" list.\n", tid);
|
||||
|
@ -1259,12 +1257,6 @@ FullO3CPU<Impl>::removeInstsNotInROB(unsigned tid,
|
|||
while (inst_it != end_it) {
|
||||
assert(!instList.empty());
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
if(!squash_delay_slot &&
|
||||
delay_slot_seq_num >= (*inst_it)->seqNum) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
squashInstIt(inst_it, tid);
|
||||
|
||||
inst_it--;
|
||||
|
|
|
@ -468,8 +468,7 @@ class FullO3CPU : public BaseO3CPU
|
|||
|
||||
/** Remove all instructions that are not currently in the ROB.
|
||||
* There's also an option to not squash delay slot instructions.*/
|
||||
void removeInstsNotInROB(unsigned tid, bool squash_delay_slot,
|
||||
const InstSeqNum &delay_slot_seq_num);
|
||||
void removeInstsNotInROB(unsigned tid);
|
||||
|
||||
/** Remove all instructions younger than the given sequence number. */
|
||||
void removeInstsUntil(const InstSeqNum &seq_num,unsigned tid);
|
||||
|
|
|
@ -49,8 +49,6 @@ DefaultDecode<Impl>::DefaultDecode(O3CPU *_cpu, Params *params)
|
|||
stalls[i].rename = false;
|
||||
stalls[i].iew = false;
|
||||
stalls[i].commit = false;
|
||||
|
||||
squashAfterDelaySlot[i] = false;
|
||||
}
|
||||
|
||||
// @todo: Make into a parameter
|
||||
|
@ -278,17 +276,12 @@ DefaultDecode<Impl>::squash(DynInstPtr &inst, unsigned tid)
|
|||
#if ISA_HAS_DELAY_SLOT
|
||||
toFetch->decodeInfo[tid].branchTaken = inst->readNextNPC() !=
|
||||
(inst->readNextPC() + sizeof(TheISA::MachInst));
|
||||
|
||||
toFetch->decodeInfo[tid].bdelayDoneSeqNum = bdelayDoneSeqNum[tid];
|
||||
squashAfterDelaySlot[tid] = false;
|
||||
|
||||
InstSeqNum squash_seq_num = bdelayDoneSeqNum[tid];
|
||||
#else
|
||||
toFetch->decodeInfo[tid].branchTaken =
|
||||
inst->readNextPC() != (inst->readPC() + sizeof(TheISA::MachInst));
|
||||
#endif
|
||||
|
||||
InstSeqNum squash_seq_num = inst->seqNum;
|
||||
#endif
|
||||
|
||||
// Might have to tell fetch to unblock.
|
||||
if (decodeStatus[tid] == Blocked ||
|
||||
|
@ -309,30 +302,10 @@ DefaultDecode<Impl>::squash(DynInstPtr &inst, unsigned tid)
|
|||
// Clear the instruction list and skid buffer in case they have any
|
||||
// insts in them.
|
||||
while (!insts[tid].empty()) {
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
if (insts[tid].front()->seqNum <= squash_seq_num) {
|
||||
DPRINTF(Decode, "[tid:%i]: Cannot remove incoming decode "
|
||||
"instructions before delay slot [sn:%i]. %i insts"
|
||||
"left in decode.\n", tid, squash_seq_num,
|
||||
insts[tid].size());
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
insts[tid].pop();
|
||||
}
|
||||
|
||||
while (!skidBuffer[tid].empty()) {
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
if (skidBuffer[tid].front()->seqNum <= squash_seq_num) {
|
||||
DPRINTF(Decode, "[tid:%i]: Cannot remove skidBuffer "
|
||||
"instructions before delay slot [sn:%i]. %i insts"
|
||||
"left in decode.\n", tid, squash_seq_num,
|
||||
insts[tid].size());
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
skidBuffer[tid].pop();
|
||||
}
|
||||
|
||||
|
@ -760,48 +733,12 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid)
|
|||
|
||||
// Might want to set some sort of boolean and just do
|
||||
// a check at the end
|
||||
#if !ISA_HAS_DELAY_SLOT
|
||||
squash(inst, inst->threadNumber);
|
||||
Addr target = inst->branchTarget();
|
||||
inst->setPredTarg(target, target + sizeof(TheISA::MachInst));
|
||||
break;
|
||||
#else
|
||||
// If mispredicted as taken, then ignore delay slot
|
||||
// instruction... else keep delay slot and squash
|
||||
// after it is sent to rename
|
||||
if (inst->readPredTaken() && inst->isCondDelaySlot()) {
|
||||
DPRINTF(Decode, "[tid:%i]: Conditional delay slot inst."
|
||||
"[sn:%i] PC %#x mispredicted as taken.\n", tid,
|
||||
inst->seqNum, inst->PC);
|
||||
bdelayDoneSeqNum[tid] = inst->seqNum;
|
||||
squash(inst, inst->threadNumber);
|
||||
Addr target = inst->branchTarget();
|
||||
inst->setPredTarg(target,
|
||||
target + sizeof(TheISA::MachInst));
|
||||
break;
|
||||
} else {
|
||||
DPRINTF(Decode, "[tid:%i]: Misprediction detected at "
|
||||
"[sn:%i] PC %#x, will squash after delay slot "
|
||||
"inst. is sent to Rename\n",
|
||||
tid, inst->seqNum, inst->PC);
|
||||
bdelayDoneSeqNum[tid] = inst->seqNum + 1;
|
||||
squashAfterDelaySlot[tid] = true;
|
||||
squashInst[tid] = inst;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (squashAfterDelaySlot[tid]) {
|
||||
assert(!inst->isSquashed());
|
||||
squash(squashInst[tid], squashInst[tid]->threadNumber);
|
||||
Addr target = squashInst[tid]->branchTarget();
|
||||
squashInst[tid]->setPredTarg(target,
|
||||
target + sizeof(TheISA::MachInst));
|
||||
assert(!inst->isSquashed());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't process all instructions, then we will need to block
|
||||
|
|
|
@ -263,8 +263,7 @@ class DefaultFetch
|
|||
* squash should be the commit stage.
|
||||
*/
|
||||
void squash(const Addr &new_PC, const Addr &new_NPC,
|
||||
const InstSeqNum &seq_num,
|
||||
bool squash_delay_slot, unsigned tid);
|
||||
const InstSeqNum &seq_num, unsigned tid);
|
||||
|
||||
/** Ticks the fetch stage, processing all inputs signals and fetching
|
||||
* as many instructions as possible.
|
||||
|
|
|
@ -774,20 +774,14 @@ DefaultFetch<Impl>::updateFetchStatus()
|
|||
template <class Impl>
|
||||
void
|
||||
DefaultFetch<Impl>::squash(const Addr &new_PC, const Addr &new_NPC,
|
||||
const InstSeqNum &seq_num,
|
||||
bool squash_delay_slot, unsigned tid)
|
||||
const InstSeqNum &seq_num, unsigned tid)
|
||||
{
|
||||
DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n",tid);
|
||||
|
||||
doSquash(new_PC, new_NPC, tid);
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
// Tell the CPU to remove any instructions that are not in the ROB.
|
||||
cpu->removeInstsNotInROB(tid, squash_delay_slot, seq_num);
|
||||
#else
|
||||
// Tell the CPU to remove any instructions that are not in the ROB.
|
||||
cpu->removeInstsNotInROB(tid, true, 0);
|
||||
#endif
|
||||
cpu->removeInstsNotInROB(tid);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
@ -896,17 +890,10 @@ DefaultFetch<Impl>::checkSignalsAndUpdate(unsigned tid)
|
|||
|
||||
DPRINTF(Fetch, "[tid:%u]: Squashing instructions due to squash "
|
||||
"from commit.\n",tid);
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].bdelayDoneSeqNum;
|
||||
#else
|
||||
InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].doneSeqNum;
|
||||
#endif
|
||||
// In any case, squash.
|
||||
squash(fromCommit->commitInfo[tid].nextPC,
|
||||
fromCommit->commitInfo[tid].nextNPC,
|
||||
doneSeqNum,
|
||||
fromCommit->commitInfo[tid].squashDelaySlot,
|
||||
fromCommit->commitInfo[tid].doneSeqNum,
|
||||
tid);
|
||||
|
||||
// Also check if there's a mispredict that happened.
|
||||
|
@ -955,18 +942,13 @@ DefaultFetch<Impl>::checkSignalsAndUpdate(unsigned tid)
|
|||
|
||||
if (fetchStatus[tid] != Squashing) {
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].bdelayDoneSeqNum;
|
||||
#else
|
||||
InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].doneSeqNum;
|
||||
#endif
|
||||
DPRINTF(Fetch, "Squashing from decode with PC = %#x, NPC = %#x\n",
|
||||
fromDecode->decodeInfo[tid].nextPC,
|
||||
fromDecode->decodeInfo[tid].nextNPC);
|
||||
// Squash unless we're already squashing
|
||||
squashFromDecode(fromDecode->decodeInfo[tid].nextPC,
|
||||
fromDecode->decodeInfo[tid].nextNPC,
|
||||
doneSeqNum,
|
||||
fromDecode->decodeInfo[tid].doneSeqNum,
|
||||
tid);
|
||||
|
||||
return true;
|
||||
|
@ -1157,9 +1139,6 @@ DefaultFetch<Impl>::fetch(bool &status_change)
|
|||
instruction->readPC());
|
||||
|
||||
///FIXME This needs to be more robust in dealing with delay slots
|
||||
#if !ISA_HAS_DELAY_SLOT
|
||||
// predicted_branch |=
|
||||
#endif
|
||||
lookupAndUpdateNextPC(instruction, next_PC, next_NPC);
|
||||
predicted_branch |= (next_PC != fetch_NPC);
|
||||
|
||||
|
@ -1213,11 +1192,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
|
|||
PC[tid] = next_PC;
|
||||
nextPC[tid] = next_NPC;
|
||||
nextNPC[tid] = next_NPC + instSize;
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, PC[tid]);
|
||||
#else
|
||||
DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, next_PC);
|
||||
#endif
|
||||
} else {
|
||||
// We shouldn't be in an icache miss and also have a fault (an ITB
|
||||
// miss)
|
||||
|
|
|
@ -402,9 +402,6 @@ class DefaultIEW
|
|||
/** Records if there is a fetch redirect on this cycle for each thread. */
|
||||
bool fetchRedirect[Impl::MaxThreads];
|
||||
|
||||
/** Keeps track of the last valid branch delay slot instss for threads */
|
||||
InstSeqNum bdelayDoneSeqNum[Impl::MaxThreads];
|
||||
|
||||
/** Used to track if all instructions have been dispatched this cycle.
|
||||
* If they have not, then blocking must have occurred, and the instructions
|
||||
* would already be added to the skid buffer.
|
||||
|
|
|
@ -69,7 +69,6 @@ DefaultIEW<Impl>::DefaultIEW(O3CPU *_cpu, Params *params)
|
|||
dispatchStatus[i] = Running;
|
||||
stalls[i].commit = false;
|
||||
fetchRedirect[i] = false;
|
||||
bdelayDoneSeqNum[i] = 0;
|
||||
}
|
||||
|
||||
wbMax = wbWidth * params->wbDepth;
|
||||
|
@ -410,31 +409,14 @@ DefaultIEW<Impl>::squash(unsigned tid)
|
|||
instQueue.squash(tid);
|
||||
|
||||
// Tell the LDSTQ to start squashing.
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
ldstQueue.squash(fromCommit->commitInfo[tid].bdelayDoneSeqNum, tid);
|
||||
#else
|
||||
ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
|
||||
#endif
|
||||
updatedQueues = true;
|
||||
|
||||
// Clear the skid buffer in case it has any data in it.
|
||||
DPRINTF(IEW, "[tid:%i]: Removing skidbuffer instructions until [sn:%i].\n",
|
||||
tid, fromCommit->commitInfo[tid].bdelayDoneSeqNum);
|
||||
tid, fromCommit->commitInfo[tid].doneSeqNum);
|
||||
|
||||
while (!skidBuffer[tid].empty()) {
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
if (skidBuffer[tid].front()->seqNum <=
|
||||
fromCommit->commitInfo[tid].bdelayDoneSeqNum) {
|
||||
DPRINTF(IEW, "[tid:%i]: Cannot remove skidbuffer instructions "
|
||||
"that occur before delay slot [sn:%i].\n",
|
||||
fromCommit->commitInfo[tid].bdelayDoneSeqNum,
|
||||
tid);
|
||||
break;
|
||||
} else {
|
||||
DPRINTF(IEW, "[tid:%i]: Removing instruction [sn:%i] from "
|
||||
"skidBuffer.\n", tid, skidBuffer[tid].front()->seqNum);
|
||||
}
|
||||
#endif
|
||||
if (skidBuffer[tid].front()->isLoad() ||
|
||||
skidBuffer[tid].front()->isStore() ) {
|
||||
toRename->iewInfo[tid].dispatchedToLSQ++;
|
||||
|
@ -445,8 +427,6 @@ DefaultIEW<Impl>::squash(unsigned tid)
|
|||
skidBuffer[tid].pop();
|
||||
}
|
||||
|
||||
bdelayDoneSeqNum[tid] = fromCommit->commitInfo[tid].bdelayDoneSeqNum;
|
||||
|
||||
emptyRenameInsts(tid);
|
||||
}
|
||||
|
||||
|
@ -462,38 +442,18 @@ DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid)
|
|||
toCommit->mispredPC[tid] = inst->readPC();
|
||||
toCommit->branchMispredict[tid] = true;
|
||||
|
||||
int instSize = sizeof(TheISA::MachInst);
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
bool branch_taken =
|
||||
int instSize = sizeof(TheISA::MachInst);
|
||||
toCommit->branchTaken[tid] =
|
||||
!(inst->readNextPC() + instSize == inst->readNextNPC() &&
|
||||
(inst->readNextPC() == inst->readPC() + instSize ||
|
||||
inst->readNextPC() == inst->readPC() + 2 * instSize));
|
||||
DPRINTF(Sparc, "Branch taken = %s [sn:%i]\n",
|
||||
branch_taken ? "true": "false", inst->seqNum);
|
||||
|
||||
toCommit->branchTaken[tid] = branch_taken;
|
||||
|
||||
bool squashDelaySlot = true;
|
||||
// (inst->readNextPC() != inst->readPC() + sizeof(TheISA::MachInst));
|
||||
DPRINTF(Sparc, "Squash delay slot = %s [sn:%i]\n",
|
||||
squashDelaySlot ? "true": "false", inst->seqNum);
|
||||
toCommit->squashDelaySlot[tid] = squashDelaySlot;
|
||||
//If we're squashing the delay slot, we need to pick back up at NextPC.
|
||||
//Otherwise, NextPC isn't being squashed, so we should pick back up at
|
||||
//NextNPC.
|
||||
if (squashDelaySlot) {
|
||||
toCommit->nextPC[tid] = inst->readNextPC();
|
||||
toCommit->nextNPC[tid] = inst->readNextNPC();
|
||||
} else {
|
||||
toCommit->nextPC[tid] = inst->readNextNPC();
|
||||
toCommit->nextNPC[tid] = inst->readNextNPC() + instSize;
|
||||
}
|
||||
#else
|
||||
toCommit->branchTaken[tid] = inst->readNextPC() !=
|
||||
(inst->readPC() + sizeof(TheISA::MachInst));
|
||||
toCommit->nextPC[tid] = inst->readNextPC();
|
||||
toCommit->nextNPC[tid] = inst->readNextPC() + instSize;
|
||||
#endif
|
||||
toCommit->nextPC[tid] = inst->readNextPC();
|
||||
toCommit->nextNPC[tid] = inst->readNextNPC();
|
||||
|
||||
toCommit->includeSquashInst[tid] = false;
|
||||
|
||||
|
@ -510,11 +470,7 @@ DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid)
|
|||
toCommit->squash[tid] = true;
|
||||
toCommit->squashedSeqNum[tid] = inst->seqNum;
|
||||
toCommit->nextPC[tid] = inst->readNextPC();
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
toCommit->nextNPC[tid] = inst->readNextNPC();
|
||||
#else
|
||||
toCommit->nextNPC[tid] = inst->readNextPC() + sizeof(TheISA::MachInst);
|
||||
#endif
|
||||
toCommit->branchMispredict[tid] = false;
|
||||
|
||||
toCommit->includeSquashInst[tid] = false;
|
||||
|
@ -532,11 +488,7 @@ DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid)
|
|||
toCommit->squash[tid] = true;
|
||||
toCommit->squashedSeqNum[tid] = inst->seqNum;
|
||||
toCommit->nextPC[tid] = inst->readPC();
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
toCommit->nextNPC[tid] = inst->readNextPC();
|
||||
#else
|
||||
toCommit->nextNPC[tid] = inst->readPC() + sizeof(TheISA::MachInst);
|
||||
#endif
|
||||
toCommit->branchMispredict[tid] = false;
|
||||
|
||||
// Must include the broadcasted SN in the squash.
|
||||
|
@ -880,10 +832,8 @@ DefaultIEW<Impl>::sortInsts()
|
|||
{
|
||||
int insts_from_rename = fromRename->size;
|
||||
#ifdef DEBUG
|
||||
#if !ISA_HAS_DELAY_SLOT
|
||||
for (int i = 0; i < numThreads; i++)
|
||||
assert(insts[i].empty());
|
||||
#endif
|
||||
#endif
|
||||
for (int i = 0; i < insts_from_rename; ++i) {
|
||||
insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]);
|
||||
|
@ -894,21 +844,9 @@ template <class Impl>
|
|||
void
|
||||
DefaultIEW<Impl>::emptyRenameInsts(unsigned tid)
|
||||
{
|
||||
DPRINTF(IEW, "[tid:%i]: Removing incoming rename instructions until "
|
||||
"[sn:%i].\n", tid, bdelayDoneSeqNum[tid]);
|
||||
DPRINTF(IEW, "[tid:%i]: Removing incoming rename instructions\n", tid);
|
||||
|
||||
while (!insts[tid].empty()) {
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
if (insts[tid].front()->seqNum <= bdelayDoneSeqNum[tid]) {
|
||||
DPRINTF(IEW, "[tid:%i]: Done removing, cannot remove instruction"
|
||||
" that occurs at or before delay slot [sn:%i].\n",
|
||||
tid, bdelayDoneSeqNum[tid]);
|
||||
break;
|
||||
} else {
|
||||
DPRINTF(IEW, "[tid:%i]: Removing incoming rename instruction "
|
||||
"[sn:%i].\n", tid, insts[tid].front()->seqNum);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (insts[tid].front()->isLoad() ||
|
||||
insts[tid].front()->isStore() ) {
|
||||
|
|
|
@ -1005,11 +1005,7 @@ InstructionQueue<Impl>::squash(unsigned tid)
|
|||
|
||||
// Read instruction sequence number of last instruction out of the
|
||||
// time buffer.
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
squashedSeqNum[tid] = fromCommit->commitInfo[tid].bdelayDoneSeqNum;
|
||||
#else
|
||||
squashedSeqNum[tid] = fromCommit->commitInfo[tid].doneSeqNum;
|
||||
#endif
|
||||
|
||||
// Call doSquash if there are insts in the IQ
|
||||
if (count[tid] > 0) {
|
||||
|
|
|
@ -356,47 +356,12 @@ DefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, unsigned tid)
|
|||
}
|
||||
|
||||
// Clear the instruction list and skid buffer in case they have any
|
||||
// insts in them. Since we support multiple ISAs, we cant just:
|
||||
// "insts[tid].clear();" or "skidBuffer[tid].clear()" since there is
|
||||
// a possible delay slot inst for different architectures
|
||||
// insts[tid].clear();
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
DPRINTF(Rename, "[tid:%i] Squashing incoming decode instructions until "
|
||||
"[sn:%i].\n",tid, squash_seq_num);
|
||||
ListIt ilist_it = insts[tid].begin();
|
||||
while (ilist_it != insts[tid].end()) {
|
||||
if ((*ilist_it)->seqNum > squash_seq_num) {
|
||||
(*ilist_it)->setSquashed();
|
||||
DPRINTF(Rename, "Squashing incoming decode instruction, "
|
||||
"[tid:%i] [sn:%i] PC %08p.\n", tid, (*ilist_it)->seqNum, (*ilist_it)->PC);
|
||||
}
|
||||
ilist_it++;
|
||||
}
|
||||
#else
|
||||
// insts in them.
|
||||
insts[tid].clear();
|
||||
#endif
|
||||
|
||||
// Clear the skid buffer in case it has any data in it.
|
||||
// See comments above.
|
||||
// skidBuffer[tid].clear();
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
DPRINTF(Rename, "[tid:%i] Squashing incoming skidbuffer instructions "
|
||||
"until [sn:%i].\n", tid, squash_seq_num);
|
||||
ListIt slist_it = skidBuffer[tid].begin();
|
||||
while (slist_it != skidBuffer[tid].end()) {
|
||||
if ((*slist_it)->seqNum > squash_seq_num) {
|
||||
(*slist_it)->setSquashed();
|
||||
DPRINTF(Rename, "Squashing skidbuffer instruction, [tid:%i] [sn:%i]"
|
||||
"PC %08p.\n", tid, (*slist_it)->seqNum, (*slist_it)->PC);
|
||||
}
|
||||
slist_it++;
|
||||
}
|
||||
resumeUnblocking = (skidBuffer[tid].size() != 0);
|
||||
DPRINTF(Rename, "Resume unblocking set to %s\n",
|
||||
resumeUnblocking ? "true" : "false");
|
||||
#else
|
||||
skidBuffer[tid].clear();
|
||||
#endif
|
||||
|
||||
doSquash(squash_seq_num, tid);
|
||||
}
|
||||
|
||||
|
@ -776,10 +741,8 @@ DefaultRename<Impl>::sortInsts()
|
|||
{
|
||||
int insts_from_decode = fromDecode->size;
|
||||
#ifdef DEBUG
|
||||
#if !ISA_HAS_DELAY_SLOT
|
||||
for (int i=0; i < numThreads; i++)
|
||||
assert(insts[i].empty());
|
||||
#endif
|
||||
#endif
|
||||
for (int i = 0; i < insts_from_decode; ++i) {
|
||||
DynInstPtr inst = fromDecode->insts[i];
|
||||
|
@ -1248,13 +1211,7 @@ DefaultRename<Impl>::checkSignalsAndUpdate(unsigned tid)
|
|||
DPRINTF(Rename, "[tid:%u]: Squashing instructions due to squash from "
|
||||
"commit.\n", tid);
|
||||
|
||||
#if ISA_HAS_DELAY_SLOT
|
||||
InstSeqNum squashed_seq_num = fromCommit->commitInfo[tid].bdelayDoneSeqNum;
|
||||
#else
|
||||
InstSeqNum squashed_seq_num = fromCommit->commitInfo[tid].doneSeqNum;
|
||||
#endif
|
||||
|
||||
squash(squashed_seq_num, tid);
|
||||
squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue