summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/mips/isa/base.isa32
-rw-r--r--src/arch/mips/isa/decoder.isa3
-rw-r--r--src/cpu/o3/commit.hh6
-rw-r--r--src/cpu/o3/commit_impl.hh83
-rw-r--r--src/cpu/o3/fetch_impl.hh9
-rw-r--r--src/cpu/o3/mips/cpu_impl.hh4
6 files changed, 113 insertions, 24 deletions
diff --git a/src/arch/mips/isa/base.isa b/src/arch/mips/isa/base.isa
index f07b06e03..7c042f16f 100644
--- a/src/arch/mips/isa/base.isa
+++ b/src/arch/mips/isa/base.isa
@@ -79,21 +79,27 @@ output decoder {{
ccprintf(ss, "%-10s ", mnemonic);
- if(_numDestRegs > 0){
- printReg(ss, _destRegIdx[0]);
+ // Need to find standard way to not print
+ // this info. Maybe add bool variable to
+ // class?
+ if (mnemonic != "syscall") {
+ if(_numDestRegs > 0){
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ if(_numSrcRegs > 0) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ if(_numSrcRegs > 1) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
}
- if(_numSrcRegs > 0) {
- ss << ", ";
- printReg(ss, _srcRegIdx[0]);
- }
-
- if(_numSrcRegs > 1) {
- ss << ", ";
- printReg(ss, _srcRegIdx[1]);
- }
-
-
+ // Should we define a separate inst. class
+ // just for two insts?
if(mnemonic == "sll" || mnemonic == "sra"){
ccprintf(ss,", %d",SA);
}
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
index 13f6f9712..d65e3eb94 100644
--- a/src/arch/mips/isa/decoder.isa
+++ b/src/arch/mips/isa/decoder.isa
@@ -133,7 +133,8 @@ decode OPCODE_HI default Unknown::unknown() {
format BasicOp {
0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }});
0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }});
- 0x4: syscall({{ xc->syscall(R2); }}, IsNonSpeculative);
+ 0x4: syscall({{ xc->syscall(R2); }},
+ IsSerializeAfter, IsNonSpeculative);
0x7: sync({{ ; }}, IsMemBarrier);
}
diff --git a/src/cpu/o3/commit.hh b/src/cpu/o3/commit.hh
index cb83012f7..5caa317b3 100644
--- a/src/cpu/o3/commit.hh
+++ b/src/cpu/o3/commit.hh
@@ -165,6 +165,9 @@ class DefaultCommit
/** Sets the pointer to the IEW stage. */
void setIEWStage(IEW *iew_stage);
+ /** Skid buffer between rename and commit. */
+ std::queue<DynInstPtr> skidBuffer;
+
/** The pointer to the IEW stage. Used solely to ensure that
* various events (traps, interrupts, syscalls) do not occur until
* all stores have written back.
@@ -256,6 +259,9 @@ class DefaultCommit
/** Gets instructions from rename and inserts them into the ROB. */
void getInsts();
+ /** Insert all instructions from rename into skidBuffer */
+ void skidInsert();
+
/** Marks completed instructions using information sent from IEW. */
void markCompletedInsts();
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index 8a8035e73..e51d03994 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -26,6 +26,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
+ * Korey Sewell
*/
#include "config/full_system.hh"
@@ -800,6 +801,10 @@ DefaultCommit<Impl>::commit()
// Try to commit any instructions.
commitInsts();
+ } else {
+#if THE_ISA != ALPHA_ISA
+ skidInsert();
+#endif
}
//Check for any activity
@@ -1112,12 +1117,37 @@ DefaultCommit<Impl>::getInsts()
{
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 = min((int)renameWidth, fromRename->size);
+#else
+ // Read any renamed instructions and place them into the ROB.
+ int insts_to_process = min((int)renameWidth,
+ (int)(fromRename->size + skidBuffer.size()));
+ int rename_idx = 0;
- for (int inst_num = 0; inst_num < insts_to_process; ++inst_num)
- {
- DynInstPtr inst = fromRename->insts[inst_num];
+ DPRINTF(Commit, "%i insts available to process. Rename Insts:%i "
+ "SkidBuffer Insts:%i\n", insts_to_process, fromRename->size,
+ skidBuffer.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
+ // 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++];
+ }
+#endif
int tid = inst->threadNumber;
if (!inst->isSquashed() &&
@@ -1138,6 +1168,53 @@ DefaultCommit<Impl>::getInsts()
inst->readPC(), inst->seqNum, tid);
}
}
+
+#if THE_ISA != ALPHA_ISA
+ 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];
+ int tid = inst->threadNumber;
+
+ if (!inst->isSquashed()) {
+ DPRINTF(Commit, "Inserting PC %#x [sn:%i] [tid:%i] into ",
+ "skidBuffer.\n", inst->readPC(), inst->seqNum, tid);
+ skidBuffer.push(inst);
+ } else {
+ DPRINTF(Commit, "Instruction PC %#x [sn:%i] [tid:%i] was "
+ "squashed, skipping.\n",
+ inst->readPC(), inst->seqNum, tid);
+ }
+ }
+ }
+#endif
+
+}
+
+template <class Impl>
+void
+DefaultCommit<Impl>::skidInsert()
+{
+ DPRINTF(Commit, "Attempting to any instructions from rename into "
+ "skidBuffer.\n");
+
+ for (int inst_num = 0; inst_num < fromRename->size; ++inst_num) {
+ DynInstPtr inst = fromRename->insts[inst_num];
+ int tid = inst->threadNumber;
+
+ if (!inst->isSquashed()) {
+ DPRINTF(Commit, "Inserting PC %#x [sn:%i] [tid:%i] into ",
+ "skidBuffer.\n", inst->readPC(), inst->seqNum, tid);
+ skidBuffer.push(inst);
+ } else {
+ DPRINTF(Commit, "Instruction PC %#x [sn:%i] [tid:%i] was "
+ "squashed, skipping.\n",
+ inst->readPC(), inst->seqNum, tid);
+ }
+ }
}
template <class Impl>
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 54e35433b..274c7c46e 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -1208,9 +1208,8 @@ DefaultFetch<Impl>::fetch(bool &status_change)
// Now that fetching is completed, update the PC to signify what the next
// cycle will be.
if (fault == NoFault) {
- DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n",tid, next_PC);
-
#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
@@ -1227,6 +1226,8 @@ DefaultFetch<Impl>::fetch(bool &status_change)
nextPC[tid] = next_NPC;
nextNPC[tid] = next_NPC + instSize;
}
+
+ DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, PC[tid]);
#endif
} else {
// We shouldn't be in an icache miss and also have a fault (an ITB
@@ -1270,9 +1271,9 @@ DefaultFetch<Impl>::fetch(bool &status_change)
fetchStatus[tid] = TrapPending;
status_change = true;
- warn("cycle %lli: fault (%d) detected @ PC %08p", curTick, fault, PC[tid]);
+ warn("cycle %lli: fault (%s) detected @ PC %08p", curTick, fault->name(), PC[tid]);
#else // !FULL_SYSTEM
- warn("cycle %lli: fault (%d) detected @ PC %08p", curTick, fault, PC[tid]);
+ warn("cycle %lli: fault (%s) detected @ PC %08p", curTick, fault->name(), PC[tid]);
#endif // FULL_SYSTEM
}
}
diff --git a/src/cpu/o3/mips/cpu_impl.hh b/src/cpu/o3/mips/cpu_impl.hh
index 6b9f3ae10..72b64943b 100644
--- a/src/cpu/o3/mips/cpu_impl.hh
+++ b/src/cpu/o3/mips/cpu_impl.hh
@@ -237,9 +237,7 @@ template <class Impl>
void
MipsO3CPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
{
- // check for error condition. Mips syscall convention is to
- // indicate success/failure in reg a3 (r19) and put the
- // return value itself in the standard return value reg (v0).
+ // check for error condition.
if (return_value.successful()) {
// no error
this->setArchIntReg(SyscallSuccessReg, 0, tid);