summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:33 -0400
committerKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:33 -0400
commit6df63650956387d88f24122c783438553412768f (patch)
tree4aa1a3de620075e5a9994b6d1ae09da08d554ebc /src/cpu
parent19e3eb29154ad17664bfe239423f6ba64c77cf05 (diff)
downloadgem5-6df63650956387d88f24122c783438553412768f.tar.xz
inorder: add types for dependency checks
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/inorder/cpu.cc7
-rw-r--r--src/cpu/inorder/cpu.hh5
-rw-r--r--src/cpu/inorder/reg_dep_map.cc151
-rw-r--r--src/cpu/inorder/reg_dep_map.hh48
-rw-r--r--src/cpu/inorder/resources/use_def.cc245
-rw-r--r--src/cpu/inorder/resources/use_def.hh16
6 files changed, 206 insertions, 266 deletions
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index ffecb22fd..8b49c4f24 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -1096,15 +1096,18 @@ InOrderCPU::getPipeStage(int stage_num)
}
RegIndex
-InOrderCPU::flattenRegIdx(RegIndex reg_idx, ThreadID tid)
+InOrderCPU::flattenRegIdx(RegIndex reg_idx, RegType &reg_type, ThreadID tid)
{
if (reg_idx < FP_Base_DepTag) {
+ reg_type = IntType;
return isa[tid].flattenIntIndex(reg_idx);
} else if (reg_idx < Ctrl_Base_DepTag) {
+ reg_type = FloatType;
reg_idx -= FP_Base_DepTag;
return isa[tid].flattenFloatIndex(reg_idx);
} else {
- return reg_idx -= TheISA::Ctrl_Base_DepTag;
+ reg_type = MiscType;
+ return reg_idx - TheISA::Ctrl_Base_DepTag;
}
}
diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh
index 42d8da18c..75d4077d7 100644
--- a/src/cpu/inorder/cpu.hh
+++ b/src/cpu/inorder/cpu.hh
@@ -288,6 +288,9 @@ class InOrderCPU : public BaseCPU
/** Dependency Tracker for Integer & Floating Point Regs */
RegDepMap archRegDepMap[ThePipeline::MaxThreads];
+ /** Register Types Used in Dependency Tracking */
+ enum RegType { IntType, FloatType, MiscType, NumRegTypes};
+
/** Global communication structure */
TimeBuffer<TimeStruct> timeBuffer;
@@ -522,7 +525,7 @@ class InOrderCPU : public BaseCPU
void setFloatRegBits(RegIndex reg_idx, FloatRegBits val, ThreadID tid);
- RegIndex flattenRegIdx(RegIndex reg_idx, ThreadID tid);
+ RegIndex flattenRegIdx(RegIndex reg_idx, RegType &reg_type, ThreadID tid);
/** Reads a miscellaneous register. */
MiscReg readMiscRegNoEffect(int misc_reg, ThreadID tid = 0);
diff --git a/src/cpu/inorder/reg_dep_map.cc b/src/cpu/inorder/reg_dep_map.cc
index 9f2a8a02a..b8891bcc1 100644
--- a/src/cpu/inorder/reg_dep_map.cc
+++ b/src/cpu/inorder/reg_dep_map.cc
@@ -43,15 +43,15 @@ using namespace ThePipeline;
RegDepMap::RegDepMap(int size)
{
- regMap.resize(size);
+ regMap.resize(InOrderCPU::NumRegTypes);
+ regMap[InOrderCPU::IntType].resize(NumIntRegs);
+ regMap[InOrderCPU::FloatType].resize(NumFloatRegs);
+ regMap[InOrderCPU::MiscType].resize(NumMiscRegs);
}
RegDepMap::~RegDepMap()
{
- for (int i = 0; i < regMap.size(); i++) {
- regMap[i].clear();
- }
- regMap.clear();
+ clear();
}
string
@@ -60,6 +60,9 @@ RegDepMap::name()
return cpu->name() + ".RegDepMap";
}
+std::string RegDepMap::mapNames[InOrderCPU::NumRegTypes] =
+{"IntReg", "FloatReg", "MiscReg"};
+
void
RegDepMap::setCPU(InOrderCPU *_cpu)
{
@@ -70,6 +73,11 @@ RegDepMap::setCPU(InOrderCPU *_cpu)
void
RegDepMap::clear()
{
+ for (int i = 0; i < regMap.size(); i++) {
+ for (int j = 0; j < regMap[j].size(); j++)
+ regMap[i][j].clear();
+ regMap[i].clear();
+ }
regMap.clear();
}
@@ -84,26 +92,23 @@ RegDepMap::insert(DynInstPtr inst)
inst->staticInst->getName(),
dest_regs);
- for (int i = 0; i < dest_regs; i++) {
- int idx = inst->destRegIdx(i);
-
- //if (inst->numFPDestRegs())
- // idx += TheISA::FP_Base_DepTag;
-
- insert(idx, inst);
- }
+ for (int i = 0; i < dest_regs; i++)
+ insert(inst->destRegIdx(i), inst);
}
void
-RegDepMap::insert(unsigned idx, DynInstPtr inst)
+RegDepMap::insert(RegIndex idx, DynInstPtr inst)
{
- TheISA::RegIndex flat_idx = cpu->flattenRegIdx(idx, inst->threadNumber);
+ InOrderCPU::RegType reg_type;
+ TheISA::RegIndex flat_idx = cpu->flattenRegIdx(idx, reg_type,
+ inst->threadNumber);
- DPRINTF(RegDepMap, "Inserting [sn:%i] onto dep. list for reg. idx %i (%i).\n",
- inst->seqNum, idx, flat_idx);
+ DPRINTF(RegDepMap, "Inserting [sn:%i] onto %s dep. list for "
+ "reg. idx %i (%i).\n", inst->seqNum, mapNames[reg_type],
+ idx, flat_idx);
- regMap[flat_idx].push_back(inst);
+ regMap[reg_type][flat_idx].push_back(inst);
inst->setRegDepEntry();
}
@@ -116,52 +121,52 @@ RegDepMap::remove(DynInstPtr inst)
inst->seqNum);
int dest_regs = inst->numDestRegs();
-
- for (int i = 0; i < dest_regs; i++) {
- int idx = inst->destRegIdx(i);
- remove(idx, inst);
- }
+ for (int i = 0; i < dest_regs; i++)
+ remove(inst->destRegIdx(i), inst);
}
}
void
-RegDepMap::remove(unsigned idx, DynInstPtr inst)
+RegDepMap::remove(RegIndex idx, DynInstPtr inst)
{
- std::list<DynInstPtr>::iterator list_it = regMap[idx].begin();
- std::list<DynInstPtr>::iterator list_end = regMap[idx].end();
+ InOrderCPU::RegType reg_type;
+ TheISA::RegIndex flat_idx = cpu->flattenRegIdx(idx, reg_type,
+ inst->threadNumber);
+
+ std::list<DynInstPtr>::iterator list_it = regMap[reg_type][flat_idx].begin();
+ std::list<DynInstPtr>::iterator list_end = regMap[reg_type][flat_idx].end();
while (list_it != list_end) {
if((*list_it) == inst) {
- regMap[idx].erase(list_it);
+ regMap[reg_type][flat_idx].erase(list_it);
break;
}
-
list_it++;
}
}
void
-RegDepMap::removeFront(unsigned idx, DynInstPtr inst)
+RegDepMap::removeFront(uint8_t reg_type, RegIndex idx, DynInstPtr inst)
{
- std::list<DynInstPtr>::iterator list_it = regMap[idx].begin();
+ std::list<DynInstPtr>::iterator list_it = regMap[reg_type][idx].begin();
- DPRINTF(RegDepMap, "[tid:%u]: Removing dependency entry on phys. reg."
+ DPRINTF(RegDepMap, "[tid:%u]: Removing dependency entry on reg. idx"
"%i for [sn:%i].\n", inst->readTid(), idx, inst->seqNum);
- assert(list_it != regMap[idx].end());
+ assert(list_it != regMap[reg_type][idx].end());
assert(inst == (*list_it));
- regMap[idx].erase(list_it);
+ regMap[reg_type][idx].erase(list_it);
}
bool
-RegDepMap::canRead(unsigned idx, DynInstPtr inst)
+RegDepMap::canRead(uint8_t reg_type, RegIndex idx, DynInstPtr inst)
{
- if (regMap[idx].size() == 0)
+ if (regMap[reg_type][idx].size() == 0)
return true;
- std::list<DynInstPtr>::iterator list_it = regMap[idx].begin();
+ std::list<DynInstPtr>::iterator list_it = regMap[reg_type][idx].begin();
if (inst->seqNum <= (*list_it)->seqNum) {
return true;
@@ -174,14 +179,15 @@ RegDepMap::canRead(unsigned idx, DynInstPtr inst)
}
ThePipeline::DynInstPtr
-RegDepMap::canForward(unsigned reg_idx, DynInstPtr inst, unsigned clean_idx)
+RegDepMap::canForward(uint8_t reg_type, unsigned reg_idx, DynInstPtr inst,
+ unsigned clean_idx)
{
- std::list<DynInstPtr>::iterator list_it = regMap[reg_idx].begin();
- std::list<DynInstPtr>::iterator list_end = regMap[reg_idx].end();
+ std::list<DynInstPtr>::iterator list_it = regMap[reg_type][reg_idx].begin();
+ std::list<DynInstPtr>::iterator list_end = regMap[reg_type][reg_idx].end();
DynInstPtr forward_inst = NULL;
- // Look for first, oldest instruction
+ // Look for first/oldest instruction
while (list_it != list_end &&
(*list_it)->seqNum < inst->seqNum) {
forward_inst = (*list_it);
@@ -220,12 +226,12 @@ RegDepMap::canForward(unsigned reg_idx, DynInstPtr inst, unsigned clean_idx)
}
bool
-RegDepMap::canWrite(unsigned idx, DynInstPtr inst)
+RegDepMap::canWrite(uint8_t reg_type, RegIndex idx, DynInstPtr inst)
{
- if (regMap[idx].size() == 0)
+ if (regMap[reg_type][idx].size() == 0)
return true;
- std::list<DynInstPtr>::iterator list_it = regMap[idx].begin();
+ std::list<DynInstPtr>::iterator list_it = regMap[reg_type][idx].begin();
if (inst->seqNum <= (*list_it)->seqNum) {
return true;
@@ -238,52 +244,25 @@ RegDepMap::canWrite(unsigned idx, DynInstPtr inst)
return false;
}
-int
-RegDepMap::depSize(unsigned idx)
-{
- return regMap[idx].size();
-}
-
-ThePipeline::DynInstPtr
-RegDepMap::findBypassInst(unsigned idx)
-{
- std::list<DynInstPtr>::iterator list_it = regMap[idx].begin();
-
- if (depSize(idx) == 1)
- return NULL;
-
- list_it++;
-
- while (list_it != regMap[idx].end()) {
- if((*list_it)->isExecuted()) {
- return *list_it;
- break;
- }
- }
-
- return NULL;
-}
-
void
RegDepMap::dump()
{
-
- for (int idx=0; idx < regMap.size(); idx++) {
-
- if (regMap[idx].size() > 0) {
- cprintf("Reg #%i (size:%i): ", idx, regMap[idx].size());
-
- std::list<DynInstPtr>::iterator list_it = regMap[idx].begin();
- std::list<DynInstPtr>::iterator list_end = regMap[idx].end();
-
- while (list_it != list_end) {
- cprintf("[sn:%i] ", (*list_it)->seqNum);
-
- list_it++;
- }
-
- cprintf("\n");
+ for (int reg_type = 0; reg_type < InOrderCPU::NumRegTypes; reg_type++) {
+ for (int idx=0; idx < regMap.size(); idx++) {
+ if (regMap[idx].size() > 0) {
+ cprintf("Reg #%i (size:%i): ", idx, regMap[reg_type][idx].size());
+
+ std::list<DynInstPtr>::iterator list_it =
+ regMap[reg_type][idx].begin();
+ std::list<DynInstPtr>::iterator list_end =
+ regMap[reg_type][idx].end();
+
+ while (list_it != list_end) {
+ cprintf("[sn:%i] ", (*list_it)->seqNum);
+ list_it++;
+ }
+ cprintf("\n");
+ }
}
-
}
}
diff --git a/src/cpu/inorder/reg_dep_map.hh b/src/cpu/inorder/reg_dep_map.hh
index 77d0cf0ca..2aff5687b 100644
--- a/src/cpu/inorder/reg_dep_map.hh
+++ b/src/cpu/inorder/reg_dep_map.hh
@@ -34,22 +34,24 @@
#include <list>
#include <vector>
+#include <string>
#include "arch/isa_traits.hh"
#include "config/the_isa.hh"
#include "cpu/inorder/pipeline_traits.hh"
-class InOrderCPU;
-
class RegDepMap
{
+ public:
typedef ThePipeline::DynInstPtr DynInstPtr;
+ typedef TheISA::RegIndex RegIndex;
+ typedef uint8_t RegType;
- public:
RegDepMap(int size = TheISA::TotalNumRegs);
-
~RegDepMap();
+ static std::string mapNames[];
+
std::string name();
void setCPU(InOrderCPU *_cpu);
@@ -60,47 +62,49 @@ class RegDepMap
/** Insert all of a instruction's destination registers into map*/
void insert(DynInstPtr inst);
- /** Insert an instruction into a specific destination register index
- * onto map
- */
- void insert(unsigned idx, DynInstPtr inst);
-
/** Remove all of a instruction's destination registers into map*/
void remove(DynInstPtr inst);
- /** Remove a specific instruction and dest. register index from map*/
- void remove(unsigned idx, DynInstPtr inst);
-
/** Remove Front instruction from a destination register */
- void removeFront(unsigned idx, DynInstPtr inst);
+ void removeFront(uint8_t reg_type, RegIndex idx, DynInstPtr inst);
/** Is the current instruction able to read from this
* destination register?
*/
- bool canRead(unsigned idx, DynInstPtr inst);
+ bool canRead(uint8_t reg_type, RegIndex idx, DynInstPtr inst);
/** Is the current instruction able to get a forwarded value from
* another instruction for this destination register?
*/
- DynInstPtr canForward(unsigned reg_idx, DynInstPtr inst, unsigned clean_idx);
+ DynInstPtr canForward(uint8_t reg_type, unsigned reg_idx,
+ DynInstPtr inst, unsigned clean_idx);
/** find an instruction to forward/bypass a value from */
- DynInstPtr findBypassInst(unsigned idx);
+ DynInstPtr findBypassInst(RegIndex idx);
/** Is the current instruction able to write to this
* destination register?
*/
- bool canWrite(unsigned idx, DynInstPtr inst);
+ bool canWrite(uint8_t reg_type, RegIndex idx, DynInstPtr inst);
/** Size of Dependency of Map */
- int depSize(unsigned idx);
+ int depSize(RegIndex idx);
void dump();
- protected:
- // Eventually make this a map of lists for
- // efficiency sake!
- std::vector<std::list<DynInstPtr> > regMap;
+ private:
+ /** Insert an instruction into a specific destination register index
+ * onto map. This must be called w/the unflattened registered index
+ */
+ void insert(RegIndex idx, DynInstPtr inst);
+
+ /** Remove a specific instruction and dest. register index from map
+ * This must be called w/the unflattened registered index
+ */
+ void remove(RegIndex idx, DynInstPtr inst);
+
+ typedef std::vector<std::list<DynInstPtr> > DepMap;
+ std::vector<DepMap> regMap;
InOrderCPU *cpu;
};
diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc
index 73520f09e..d05f42413 100644
--- a/src/cpu/inorder/resources/use_def.cc
+++ b/src/cpu/inorder/resources/use_def.cc
@@ -47,16 +47,12 @@ using namespace ThePipeline;
UseDefUnit::UseDefUnit(string res_name, int res_id, int res_width,
int res_latency, InOrderCPU *_cpu,
ThePipeline::Params *params)
- : Resource(res_name, res_id, res_width, res_latency, _cpu),
- maxSeqNum((InstSeqNum)-1)
+ : Resource(res_name, res_id, res_width, res_latency, _cpu)
{
for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
nonSpecInstActive[tid] = &cpu->nonSpecInstActive[tid];
nonSpecSeqNum[tid] = &cpu->nonSpecSeqNum[tid];
- outReadSeqNum[tid] = maxSeqNum;
- outWriteSeqNum[tid] = maxSeqNum;
-
regDepMap[tid] = &cpu->archRegDepMap[tid];
}
@@ -167,21 +163,21 @@ UseDefUnit::execute(int slot_idx)
{
case ReadSrcReg:
{
+ InOrderCPU::RegType reg_type;
RegIndex reg_idx = inst->_srcRegIdx[ud_idx];
- RegIndex flat_idx = cpu->flattenRegIdx(reg_idx, tid);
+ RegIndex flat_idx = cpu->flattenRegIdx(reg_idx, reg_type, tid);
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Attempting to read source "
"register idx %i (reg #%i, flat#%i).\n",
tid, seq_num, ud_idx, reg_idx, flat_idx);
- // Ask register dependency map if it is OK to read from Arch.
- // Reg. File
- if (regDepMap[tid]->canRead(flat_idx, inst)) {
-
- uniqueRegMap[reg_idx] = true;
+ if (regDepMap[tid]->canRead(reg_type, flat_idx, inst)) {
+ switch (reg_type)
+ {
+ case InOrderCPU::IntType:
+ {
+ uniqueIntRegMap[flat_idx] = true;
- if (inst->seqNum <= outReadSeqNum[tid]) {
- if (reg_idx < FP_Base_DepTag) {
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Reading Int Reg %i"
" (%i) from Register File:%i.\n",
tid, seq_num,
@@ -190,12 +186,16 @@ UseDefUnit::execute(int slot_idx)
inst->setIntSrc(ud_idx,
cpu->readIntReg(flat_idx,
inst->readTid()));
- } else if (reg_idx < Ctrl_Base_DepTag) {
- reg_idx -= FP_Base_DepTag;
+ }
+ break;
+
+ case InOrderCPU::FloatType:
+ {
+ uniqueFloatRegMap[flat_idx] = true;
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Reading Float Reg %i"
" (%i) from Register File:%x (%08f).\n",
tid, seq_num,
- reg_idx, flat_idx,
+ reg_idx - FP_Base_DepTag, flat_idx,
cpu->readFloatRegBits(flat_idx,
inst->readTid()),
cpu->readFloatReg(flat_idx,
@@ -204,45 +204,45 @@ UseDefUnit::execute(int slot_idx)
inst->setFloatSrc(ud_idx,
cpu->readFloatReg(flat_idx,
inst->readTid()));
- } else {
- reg_idx -= Ctrl_Base_DepTag;
+ }
+ break;
+
+ case InOrderCPU::MiscType:
+ {
+ uniqueMiscRegMap[flat_idx] = true;
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Reading Misc Reg %i "
" (%i) from Register File:%i.\n",
tid, seq_num,
- reg_idx, flat_idx,
- cpu->readMiscReg(reg_idx,
+ reg_idx - Ctrl_Base_DepTag, flat_idx,
+ cpu->readMiscReg(flat_idx,
inst->readTid()));
inst->setIntSrc(ud_idx,
- cpu->readMiscReg(reg_idx,
+ cpu->readMiscReg(flat_idx,
inst->readTid()));
}
+ break;
- outReadSeqNum[tid] = maxSeqNum;
- regFileReads++;
- ud_req->done();
- } else {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Unable to read because "
- "of [sn:%i] hasnt read it's registers yet.\n",
- tid, seq_num, outReadSeqNum[tid]);
- DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
- "[sn:%i] to write\n",
- tid, outReadSeqNum[tid]);
- ud_req->done(false);
+ default:
+ panic("Invalid Register Type: %i", reg_type);
}
+ regFileReads++;
+ ud_req->done();
} else {
// Look for forwarding opportunities
- DynInstPtr forward_inst = regDepMap[tid]->canForward(flat_idx,
+ DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_type,
+ flat_idx,
inst,
reg_idx);
if (forward_inst) {
+ int dest_reg_idx =
+ forward_inst->getDestIdxNum(reg_idx);
- if (inst->seqNum <= outReadSeqNum[tid]) {
- int dest_reg_idx =
- forward_inst->getDestIdxNum(reg_idx);
-
- if (reg_idx < FP_Base_DepTag) {
+ switch (reg_type)
+ {
+ case InOrderCPU::IntType:
+ {
DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
" reg %i (%i), value 0x%x from "
"[sn:%i] to [sn:%i] source #%i.\n",
@@ -253,21 +253,29 @@ UseDefUnit::execute(int slot_idx)
inst->setIntSrc(ud_idx,
forward_inst->
readIntResult(dest_reg_idx));
- } else if (reg_idx < Ctrl_Base_DepTag) {
+ }
+ break;
+
+ case InOrderCPU::FloatType:
+ {
DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
" reg %i (%i) value 0x%x from "
"[sn:%i] to [sn:%i] source #%i.\n",
- tid, reg_idx, flat_idx,
+ tid, reg_idx - FP_Base_DepTag, flat_idx,
forward_inst->readFloatResult(dest_reg_idx),
forward_inst->seqNum, inst->seqNum, ud_idx);
inst->setFloatSrc(ud_idx,
forward_inst->
readFloatResult(dest_reg_idx));
- } else {
+ }
+ break;
+
+ case InOrderCPU::MiscType:
+ {
DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
" reg %i (%i) value 0x%x from "
"[sn:%i] to [sn:%i] source #%i.\n",
- tid, reg_idx, flat_idx,
+ tid, reg_idx - Ctrl_Base_DepTag, flat_idx,
forward_inst->readIntResult(dest_reg_idx),
forward_inst->seqNum,
inst->seqNum, ud_idx);
@@ -275,27 +283,21 @@ UseDefUnit::execute(int slot_idx)
forward_inst->
readIntResult(dest_reg_idx));
}
+ break;
- outReadSeqNum[tid] = maxSeqNum;
- regForwards++;
- ud_req->done();
- } else {
- DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read "
- "because of [sn:%i] hasnt read it's"
- " registers yet.\n", tid, outReadSeqNum[tid]);
- DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
- "[sn:%i] to forward\n",
- tid, outReadSeqNum[tid]);
- ud_req->done(false);
+ default:
+ panic("Invalid Register Type: %i", reg_type);
}
+
+ regForwards++;
+ ud_req->done();
} else {
- DPRINTF(InOrderUseDef, "[tid:%i]: Source register idx: %i"
+ DPRINTF(InOrderUseDef, "[tid:%i]: Source register idx: %i "
"is not ready to read.\n",
tid, reg_idx);
DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to read "
"register (idx=%i)\n",
tid, reg_idx);
- outReadSeqNum[tid] = inst->seqNum;
ud_req->done(false);
}
}
@@ -304,32 +306,41 @@ UseDefUnit::execute(int slot_idx)
case WriteDestReg:
{
+ InOrderCPU::RegType reg_type;
RegIndex reg_idx = inst->_destRegIdx[ud_idx];
- RegIndex flat_idx = cpu->flattenRegIdx(reg_idx, tid);
+ RegIndex flat_idx = cpu->flattenRegIdx(reg_idx, reg_type, tid);
- if (regDepMap[tid]->canWrite(flat_idx, inst)) {
+ if (regDepMap[tid]->canWrite(reg_type, flat_idx, inst)) {
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Flattening register idx %i "
"(%i) and Attempting to write to Register File.\n",
tid, seq_num, reg_idx, flat_idx);
- uniqueRegMap[reg_idx] = true;
- if (inst->seqNum <= outReadSeqNum[tid]) {
- if (reg_idx < FP_Base_DepTag) {
+
+ switch (reg_type)
+ {
+ case InOrderCPU::IntType:
+ {
+ uniqueIntRegMap[flat_idx] = true;
+
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing Int. Result "
"0x%x to register idx %i (%i).\n",
tid, seq_num, inst->readIntResult(ud_idx),
reg_idx, flat_idx);
// Remove Dependencies
- regDepMap[tid]->removeFront(flat_idx, inst);
+ regDepMap[tid]->removeFront(reg_type, flat_idx, inst);
cpu->setIntReg(flat_idx,
inst->readIntResult(ud_idx),
inst->readTid());
- } else if(reg_idx < Ctrl_Base_DepTag) {
- // Remove Dependencies
- regDepMap[tid]->removeFront(flat_idx, inst);
+ }
+ break;
+
+ case InOrderCPU::FloatType:
+ {
+ uniqueFloatRegMap[flat_idx] = true;
- reg_idx -= FP_Base_DepTag;
+ // Remove Reg. Dependecny Block on this Register
+ regDepMap[tid]->removeFront(reg_type, flat_idx, inst);
if (inst->resultType(ud_idx) ==
InOrderDynInst::Integer) {
@@ -339,12 +350,12 @@ UseDefUnit::execute(int slot_idx)
tid, seq_num,
inst->readFloatResult(ud_idx),
inst->readIntResult(ud_idx),
- reg_idx, flat_idx);
+ reg_idx - FP_Base_DepTag, flat_idx);
// Check for FloatRegBits Here
cpu->setFloatRegBits(flat_idx,
- inst->readIntResult(ud_idx),
- inst->readTid());
+ inst->readIntResult(ud_idx),
+ inst->readTid());
} else if (inst->resultType(ud_idx) ==
InOrderDynInst::Float) {
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing Float "
@@ -352,7 +363,7 @@ UseDefUnit::execute(int slot_idx)
"idx %i (%i).\n",
tid, seq_num, inst->readFloatResult(ud_idx),
inst->readIntResult(ud_idx),
- reg_idx, flat_idx);
+ reg_idx - FP_Base_DepTag, flat_idx);
cpu->setFloatReg(flat_idx,
inst->readFloatResult(ud_idx),
@@ -365,7 +376,7 @@ UseDefUnit::execute(int slot_idx)
tid, seq_num,
inst->readFloatResult(ud_idx),
inst->readIntResult(ud_idx),
- reg_idx, flat_idx);
+ reg_idx - FP_Base_DepTag, flat_idx);
// Check for FloatRegBits Here
cpu->setFloatReg(flat_idx,
@@ -376,33 +387,32 @@ UseDefUnit::execute(int slot_idx)
inst->seqNum, inst->instName());
}
- } else {
+ }
+ break;
+
+ case InOrderCPU::MiscType:
+ {
+ uniqueMiscRegMap[flat_idx] = true;
+
DPRINTF(InOrderUseDef, "[tid:%i]: Writing Misc. 0x%x "
"to register idx %i.\n",
- tid, inst->readIntResult(ud_idx), reg_idx);
+ tid, inst->readIntResult(ud_idx), reg_idx - Ctrl_Base_DepTag);
// Remove Dependencies
- regDepMap[tid]->removeFront(flat_idx, inst);
-
- reg_idx -= Ctrl_Base_DepTag;
+ regDepMap[tid]->removeFront(reg_type, flat_idx, inst);
- cpu->setMiscReg(reg_idx,
- inst->readIntResult(ud_idx),
+ cpu->setMiscReg(flat_idx,
+ inst->readIntResult(ud_idx),
inst->readTid());
}
+ break;
- outWriteSeqNum[tid] = maxSeqNum;
- regFileWrites++;
- ud_req->done();
- } else {
- DPRINTF(InOrderUseDef, "[tid:%i]: Unable to write because "
- "of [sn:%i] hasnt read it's"
- " registers yet.\n", tid, outReadSeqNum);
- DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
- "[sn:%i] to read\n",
- tid, outReadSeqNum);
- ud_req->done(false);
+ default:
+ panic("Invalid Register Type: %i", reg_type);
}
+
+ regFileWrites++;
+ ud_req->done();
} else {
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Dest. register idx: %i is "
"not ready to write.\n",
@@ -410,7 +420,6 @@ UseDefUnit::execute(int slot_idx)
DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to write "
"register (idx=%i)\n",
tid, reg_idx);
- outWriteSeqNum[tid] = inst->seqNum;
ud_req->done(false);
}
}
@@ -423,59 +432,11 @@ UseDefUnit::execute(int slot_idx)
}
void
-UseDefUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
- ThreadID tid)
-{
- DPRINTF(InOrderUseDef, "[tid:%i]: Updating Due To Squash After [sn:%i].\n",
- tid, squash_seq_num);
-
- for (int i = 0; i < width; i++) {
- ResReqPtr req_ptr = reqs[i];
-
- if (req_ptr->valid &&
- req_ptr->getInst()->readTid() == tid &&
- req_ptr->getInst()->seqNum > squash_seq_num) {
-
- DPRINTF(InOrderUseDef, "[tid:%i]: Squashing [sn:%i].\n",
- req_ptr->getInst()->readTid(),
- req_ptr->getInst()->seqNum);
-
- int req_slot_num = req_ptr->getSlot();
-
- if (latency > 0) {
- assert(0);
-
- unscheduleEvent(req_slot_num);
- }
-
- freeSlot(req_slot_num);
- }
- }
-
- if (outReadSeqNum[tid] >= squash_seq_num) {
- DPRINTF(InOrderUseDef, "[tid:%i]: Outstanding Read Seq Num Reset.\n",
- tid);
- outReadSeqNum[tid] = maxSeqNum;
- } else if (outReadSeqNum[tid] != maxSeqNum) {
- DPRINTF(InOrderUseDef, "[tid:%i]: No need to reset Outstanding Read "
- "Seq Num %i\n",
- tid, outReadSeqNum[tid]);
- }
-
- if (outWriteSeqNum[tid] >= squash_seq_num) {
- DPRINTF(InOrderUseDef, "[tid:%i]: Outstanding Write Seq Num Reset.\n",
- tid);
- outWriteSeqNum[tid] = maxSeqNum;
- } else if (outWriteSeqNum[tid] != maxSeqNum) {
- DPRINTF(InOrderUseDef, "[tid:%i]: No need to reset Outstanding Write "
- "Seq Num %i\n",
- tid, outWriteSeqNum[tid]);
- }
-}
-
-void
UseDefUnit::updateAfterContextSwitch(DynInstPtr inst, ThreadID tid)
{
- uniqueRegsPerSwitch = uniqueRegMap.size();
- uniqueRegMap.clear();
+ uniqueRegsPerSwitch = uniqueIntRegMap.size() + uniqueFloatRegMap.size()
+ + uniqueMiscRegMap.size();
+ uniqueIntRegMap.clear();
+ uniqueFloatRegMap.clear();
+ uniqueMiscRegMap.clear();
}
diff --git a/src/cpu/inorder/resources/use_def.hh b/src/cpu/inorder/resources/use_def.hh
index 9bb0c3333..ef33395a0 100644
--- a/src/cpu/inorder/resources/use_def.hh
+++ b/src/cpu/inorder/resources/use_def.hh
@@ -67,31 +67,21 @@ class UseDefUnit : public Resource {
void execute(int slot_num);
- void squash(DynInstPtr inst, int stage_num,
- InstSeqNum squash_seq_num, ThreadID tid);
-
void updateAfterContextSwitch(DynInstPtr inst, ThreadID tid);
- const InstSeqNum maxSeqNum;
-
void regStats();
protected:
RegDepMap *regDepMap[ThePipeline::MaxThreads];
- /** Outstanding Seq. Num. Trying to Read from Register File */
- InstSeqNum outReadSeqNum[ThePipeline::MaxThreads];
-
- InstSeqNum outWriteSeqNum[ThePipeline::MaxThreads];
-
bool *nonSpecInstActive[ThePipeline::MaxThreads];
InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
- InstSeqNum floatRegSize[ThePipeline::MaxThreads];
-
Stats::Average uniqueRegsPerSwitch;
- std::map<unsigned, bool> uniqueRegMap;
+ std::map<RegIndex, bool> uniqueIntRegMap;
+ std::map<RegIndex, bool> uniqueFloatRegMap;
+ std::map<RegIndex, bool> uniqueMiscRegMap;
public:
class UseDefRequest : public ResourceRequest {