namespace AlphaISA
{
-
using namespace LittleEndianGuest;
// These enumerate all the registers for dependence tracking.
StaticInstPtr decodeInst(ExtMachInst);
+ // Alpha Does NOT have a delay slot
+ #define ISA_HAS_DELAY_SLOT 0
+
const Addr PageShift = 13;
const Addr PageBytes = ULL(1) << PageShift;
const Addr PageMask = ~(PageBytes - 1);
const Addr PageOffset = PageBytes - 1;
-
#if FULL_SYSTEM
////////////////////////////////////////////////////////////////////////
StaticInstPtr decodeInst(ExtMachInst);
+ // MIPS DOES a delay slot
+ #define ISA_HAS_DELAY_SLOT 1
+
const Addr PageShift = 13;
const Addr PageBytes = ULL(1) << PageShift;
const Addr PageMask = ~(PageBytes - 1);
//This makes sure the big endian versions of certain functions are used.
using namespace BigEndianGuest;
+ // Alpha Does NOT have a delay slot
+ #define ISA_HAS_DELAY_SLOT 1
+
//TODO this needs to be a SPARC Noop
// Alpha UNOP (ldq_u r31,0(r0))
const MachInst NoopMachInst = 0x2ffe0000;
/** Returns whether the instruction was predicted taken or not. */
bool predTaken()
-#if THE_ISA == ALPHA_ISA
- { return predPC != (PC + sizeof(MachInst)); }
-#else
+#if ISA_HAS_DELAY_SLOT
{ return predPC != (nextPC + sizeof(MachInst)); }
+#else
+ { return predPC != (PC + sizeof(MachInst)); }
#endif
/** Returns whether the instruction mispredicted. */
bool mispredicted()
-#if THE_ISA == ALPHA_ISA
- { return predPC != nextPC; }
-#else
+#if ISA_HAS_DELAY_SLOT
{ return predPC != nextNPC; }
+#else
+ { return predPC != nextPC; }
#endif
//
// Instruction types. Forward checks to StaticInst object.
*/
#include "arch/types.hh"
+#include "arch/isa_traits.hh"
#include "base/trace.hh"
#include "base/traceflags.hh"
#include "cpu/o3/bpred_unit.hh"
++BTBLookups;
if (inst->isCall()) {
-#if THE_ISA == ALPHA_ISA
- Addr ras_pc = PC + sizeof(MachInst); // Next PC
-#else
+#if ISA_HAS_DELAY_SLOT
Addr ras_pc = PC + (2 * sizeof(MachInst)); // Next Next PC
+#else
+ Addr ras_pc = PC + sizeof(MachInst); // Next PC
#endif
RAS[tid].push(ras_pc);
predict_record.wasCall = true;
DPRINTF(Fetch, "BranchPred: [tid:%i]: Instruction %#x was a call"
- ", adding %#x to the RAS.\n",
- tid, inst->readPC(), ras_pc);
+ ", adding %#x to the RAS index: %i.\n",
+ tid, inst->readPC(), ras_pc, RAS[tid].topIdx());
}
if (BTB.valid(PC, tid)) {
RAS[tid].restore(pred_hist.front().RASIndex,
pred_hist.front().RASTarget);
-
} else if (pred_hist.front().wasCall) {
DPRINTF(Fetch, "BranchPred: [tid:%i]: Removing speculative entry "
"added to the RAS.\n",tid);
// then use one older sequence number.
InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];
-#if THE_ISA != ALPHA_ISA
+#if ISA_HAS_DELAY_SLOT
InstSeqNum bdelay_done_seq_num;
bool squash_bdelay_slot;
if (fromIEW->includeSquashInst[tid] == true) {
squashed_inst--;
-#if THE_ISA != ALPHA_ISA
+#if ISA_HAS_DELAY_SLOT
bdelay_done_seq_num--;
#endif
}
// number as the youngest instruction in the ROB.
youngestSeqNum[tid] = squashed_inst;
-#if THE_ISA == ALPHA_ISA
- rob->squash(squashed_inst, tid);
- toIEW->commitInfo[tid].squashDelaySlot = true;
-#else
+#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;
// Try to commit any instructions.
commitInsts();
} else {
-#if THE_ISA != ALPHA_ISA
+#if ISA_HAS_DELAY_SLOT
skidInsert();
#endif
}
}
PC[tid] = nextPC[tid];
-#if THE_ISA == ALPHA_ISA
- nextPC[tid] = nextPC[tid] + sizeof(TheISA::MachInst);
-#else
+#if ISA_HAS_DELAY_SLOT
nextPC[tid] = nextNPC[tid];
nextNPC[tid] = nextNPC[tid] + sizeof(TheISA::MachInst);
+#else
+ nextPC[tid] = nextPC[tid] + sizeof(TheISA::MachInst);
#endif
#if FULL_SYSTEM
{
DPRINTF(Commit, "Getting instructions from Rename stage.\n");
-#if THE_ISA == ALPHA_ISA
- // Read any renamed instructions and place them into the ROB.
- int insts_to_process = std::min((int)renameWidth, fromRename->size);
-#else
+#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()));
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 THE_ISA == ALPHA_ISA
- inst = fromRename->insts[inst_num];
-#else
+#if ISA_HAS_DELAY_SLOT
// Get insts from skidBuffer or from Rename
if (skidBuffer.size() > 0) {
DPRINTF(Commit, "Grabbing skidbuffer inst.\n");
DPRINTF(Commit, "Grabbing rename inst.\n");
inst = fromRename->insts[rename_idx++];
}
+#else
+ inst = fromRename->insts[inst_num];
#endif
int tid = inst->threadNumber;
}
}
-#if THE_ISA != ALPHA_ISA
+#if ISA_HAS_DELAY_SLOT
if (rename_idx < fromRename->size) {
DPRINTF(Commit,"Placing Rename Insts into skidBuffer.\n");
params->activity),
globalSeqNum(1),
-
#if FULL_SYSTEM
system(params->system),
physmem(system->physmem),
lastActivatedCycle = -1;
+ // Give renameMap & rename stage access to the freeList;
+ //for (int i=0; i < numThreads; i++) {
+ //globalSeqNum[i] = 1;
+ //}
+
contextSwitch = false;
}
//Set PC/NPC/NNPC
setPC(src_tc->readPC(), tid);
setNextPC(src_tc->readNextPC(), tid);
-#if THE_ISA != ALPHA_ISA
+#if ISA_HAS_DELAY_SLOT
setNextNPC(src_tc->readNextNPC(), tid);
#endif
while (inst_it != end_it) {
assert(!instList.empty());
-#if THE_ISA != ALPHA_ISA
+#if ISA_HAS_DELAY_SLOT
if(!squash_delay_slot &&
delay_slot_seq_num >= (*inst_it)->seqNum) {
break;
}
/** The global sequence number counter. */
- InstSeqNum globalSeqNum;
+ InstSeqNum globalSeqNum;//[Impl::MaxThreads];
/** Pointer to the checker, which can dynamically verify
* instruction results at run time. This can be set to NULL if it
toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
toFetch->decodeInfo[tid].squash = true;
toFetch->decodeInfo[tid].nextPC = inst->branchTarget();
-#if THE_ISA == ALPHA_ISA
- toFetch->decodeInfo[tid].branchTaken =
- inst->readNextPC() != (inst->readPC() + sizeof(TheISA::MachInst));
-
- InstSeqNum squash_seq_num = inst->seqNum;
-#else
+#if ISA_HAS_DELAY_SLOT
toFetch->decodeInfo[tid].branchTaken = inst->readNextNPC() !=
(inst->readNextPC() + sizeof(TheISA::MachInst));
squashAfterDelaySlot[tid] = false;
InstSeqNum squash_seq_num = bdelayDoneSeqNum[tid];
+#else
+ toFetch->decodeInfo[tid].branchTaken =
+ inst->readNextPC() != (inst->readPC() + sizeof(TheISA::MachInst));
+
+ InstSeqNum squash_seq_num = inst->seqNum;
#endif
// Might have to tell fetch to unblock.
// insts in them.
while (!insts[tid].empty()) {
-#if THE_ISA != ALPHA_ISA
+#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"
while (!skidBuffer[tid].empty()) {
-#if THE_ISA != ALPHA_ISA
+#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"
// Might want to set some sort of boolean and just do
// a check at the end
-#if THE_ISA == ALPHA_ISA
+#if !ISA_HAS_DELAY_SLOT
squash(inst, inst->threadNumber);
inst->setPredTarg(inst->branchTarget());
break;
for (int tid = 0; tid < numThreads; tid++) {
PC[tid] = cpu->readPC(tid);
nextPC[tid] = cpu->readNextPC(tid);
-#if THE_ISA != ALPHA_ISA
+#if ISA_HAS_DELAY_SLOT
nextNPC[tid] = cpu->readNextNPC(tid);
#endif
}
stalls[i].commit = 0;
PC[i] = cpu->readPC(i);
nextPC[i] = cpu->readNextPC(i);
-#if THE_ISA != ALPHA_ISA
+#if ISA_HAS_DELAY_SLOT
nextNPC[i] = cpu->readNextNPC(i);
delaySlotInfo[i].branchSeqNum = -1;
delaySlotInfo[i].numInsts = 0;
bool predict_taken;
if (!inst->isControl()) {
-#if THE_ISA == ALPHA_ISA
- next_PC = next_PC + instSize;
- inst->setPredTarg(next_PC);
-#else
+#if ISA_HAS_DELAY_SLOT
Addr cur_PC = next_PC;
next_PC = cur_PC + instSize; //next_NPC;
next_NPC = cur_PC + (2 * instSize);//next_NPC + instSize;
inst->setPredTarg(next_NPC);
+#else
+ next_PC = next_PC + instSize;
+ inst->setPredTarg(next_PC);
#endif
return false;
}
int tid = inst->threadNumber;
-#if THE_ISA == ALPHA_ISA
- predict_taken = branchPred.predict(inst, next_PC, tid);
-#else
+#if ISA_HAS_DELAY_SLOT
Addr pred_PC = next_PC;
predict_taken = branchPred.predict(inst, pred_PC, tid);
next_NPC = next_NPC + instSize;
}
+#else
+ predict_taken = branchPred.predict(inst, next_PC, tid);
#endif
++fetchedBranches;
doSquash(new_PC, tid);
-#if THE_ISA != ALPHA_ISA
+#if ISA_HAS_DELAY_SLOT
if (seq_num <= delaySlotInfo[tid].branchSeqNum) {
delaySlotInfo[tid].numInsts = 0;
delaySlotInfo[tid].targetAddr = 0;
doSquash(new_PC, tid);
-#if THE_ISA == ALPHA_ISA
- // Tell the CPU to remove any instructions that are not in the ROB.
- cpu->removeInstsNotInROB(tid, true, 0);
-#else
+#if ISA_HAS_DELAY_SLOT
if (seq_num <= delaySlotInfo[tid].branchSeqNum) {
delaySlotInfo[tid].numInsts = 0;
delaySlotInfo[tid].targetAddr = 0;
// 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
}
DPRINTF(Fetch, "[tid:%u]: Squashing instructions due to squash "
"from commit.\n",tid);
-#if THE_ISA == ALPHA_ISA
- InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].doneSeqNum;
+#if ISA_HAS_DELAY_SLOT
+ InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].bdelayDoneSeqNum;
#else
- InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].bdelayDoneSeqNum;
+ InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].doneSeqNum;
#endif
// In any case, squash.
squash(fromCommit->commitInfo[tid].nextPC,
if (fetchStatus[tid] != Squashing) {
-#if THE_ISA == ALPHA_ISA
- InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].doneSeqNum;
-#else
+#if ISA_HAS_DELAY_SLOT
InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].bdelayDoneSeqNum;
+#else
+ InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].doneSeqNum;
#endif
// Squash unless we're already squashing
squashFromDecode(fromDecode->decodeInfo[tid].nextPC,
offset += instSize;
-#if THE_ISA != ALPHA_ISA
+#if ISA_HAS_DELAY_SLOT
if (predicted_branch) {
delaySlotInfo[tid].branchSeqNum = inst_seq;
// Now that fetching is completed, update the PC to signify what the next
// cycle will be.
if (fault == NoFault) {
-#if THE_ISA == ALPHA_ISA
- DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n",tid, next_PC);
- PC[tid] = next_PC;
- nextPC[tid] = next_PC + instSize;
-#else
+#if ISA_HAS_DELAY_SLOT
if (delaySlotInfo[tid].targetReady &&
delaySlotInfo[tid].numInsts == 0) {
// Set PC to target
}
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);
+ PC[tid] = next_PC;
+ nextPC[tid] = next_PC + instSize;
#endif
} else {
// We shouldn't be in an icache miss and also have a fault (an ITB
instQueue.squash(tid);
// Tell the LDSTQ to start squashing.
-#if THE_ISA == ALPHA_ISA
- ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
-#else
+#if ISA_HAS_DELAY_SLOT
ldstQueue.squash(fromCommit->commitInfo[tid].bdelayDoneSeqNum, tid);
+#else
+ ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
#endif
updatedQueues = true;
tid, fromCommit->commitInfo[tid].bdelayDoneSeqNum);
while (!skidBuffer[tid].empty()) {
-#if THE_ISA != ALPHA_ISA
+#if ISA_HAS_DELAY_SLOT
if (skidBuffer[tid].front()->seqNum <=
fromCommit->commitInfo[tid].bdelayDoneSeqNum) {
DPRINTF(IEW, "[tid:%i]: Cannot remove skidbuffer instructions "
toCommit->mispredPC[tid] = inst->readPC();
toCommit->branchMispredict[tid] = true;
-#if THE_ISA == ALPHA_ISA
- toCommit->branchTaken[tid] = inst->readNextPC() !=
- (inst->readPC() + sizeof(TheISA::MachInst));
- toCommit->nextPC[tid] = inst->readNextPC();
-#else
+#if ISA_HAS_DELAY_SLOT
bool branch_taken = inst->readNextNPC() !=
(inst->readNextPC() + sizeof(TheISA::MachInst));
} else {
toCommit->nextPC[tid] = inst->readNextNPC();
}
+#else
+ toCommit->branchTaken[tid] = inst->readNextPC() !=
+ (inst->readPC() + sizeof(TheISA::MachInst));
+ toCommit->nextPC[tid] = inst->readNextPC();
#endif
toCommit->includeSquashInst[tid] = false;
{
int insts_from_rename = fromRename->size;
#ifdef DEBUG
-#if THE_ISA == ALPHA_ISA
+#if !ISA_HAS_DELAY_SLOT
for (int i = 0; i < numThreads; i++)
assert(insts[i].empty());
#endif
"[sn:%i].\n", tid, bdelayDoneSeqNum[tid]);
while (!insts[tid].empty()) {
-
-#if THE_ISA != ALPHA_ISA
+#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",
fetchRedirect[tid] = true;
DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
-#if THE_ISA == ALPHA_ISA
+#if ISA_HAS_DELAY_SLOT
DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n",
- inst->nextPC);
+ inst->nextNPC);
#else
DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n",
- inst->nextNPC);
+ inst->nextPC);
#endif
// If incorrect, then signal the ROB that it must be squashed.
squashDueToBranch(inst, tid);
// Read instruction sequence number of last instruction out of the
// time buffer.
-#if THE_ISA == ALPHA_ISA
- squashedSeqNum[tid] = fromCommit->commitInfo[tid].doneSeqNum;
-#else
+#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
// "insts[tid].clear();" or "skidBuffer[tid].clear()" since there is
// a possible delay slot inst for different architectures
// insts[tid].clear();
-#if THE_ISA == ALPHA_ISA
- insts[tid].clear();
-#else
+#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();
}
ilist_it++;
}
+#else
+ insts[tid].clear();
#endif
// Clear the skid buffer in case it has any data in it.
// See comments above.
// skidBuffer[tid].clear();
-#if THE_ISA == ALPHA_ISA
- skidBuffer[tid].clear();
-#else
+#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();
}
slist_it++;
}
+#else
+ skidBuffer[tid].clear();
#endif
doSquash(squash_seq_num, tid);
}
{
int insts_from_decode = fromDecode->size;
#ifdef DEBUG
-#if THE_ISA == ALPHA_ISA
+#if !ISA_HAS_DELAY_SLOT
for (int i=0; i < numThreads; i++)
assert(insts[i].empty());
#endif
DPRINTF(Rename, "[tid:%u]: Squashing instructions due to squash from "
"commit.\n", tid);
-#if THE_ISA == ALPHA_ISA
- InstSeqNum squashed_seq_num = fromCommit->commitInfo[tid].doneSeqNum;
-#else
+#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);
BaseSimpleCPU::setupFetchRequest(Request *req)
{
// set up memory request for instruction fetch
-#if THE_ISA == ALPHA_ISA
- DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p",thread->readPC(),
- thread->readNextPC());
-#else
+#if ISA_HAS_DELAY_SLOT
DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",thread->readPC(),
thread->readNextPC(),thread->readNextNPC());
+#else
+ DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p",thread->readPC(),
+ thread->readNextPC());
#endif
req->setVirt(0, thread->readPC() & ~3, sizeof(MachInst),
else {
// go to the next instruction
thread->setPC(thread->readNextPC());
-#if THE_ISA == ALPHA_ISA
- thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
-#else
+#if ISA_HAS_DELAY_SLOT
thread->setNextPC(thread->readNextNPC());
thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
assert(thread->readNextPC() != thread->readNextNPC());
+#else
+ thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
#endif
}