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 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::commit() // Try to commit any instructions. commitInsts(); + } else { +#if THE_ISA != ALPHA_ISA + skidInsert(); +#endif } //Check for any activity @@ -1112,12 +1117,37 @@ DefaultCommit::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::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 +void +DefaultCommit::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 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::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::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::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 void MipsO3CPU::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);