diff options
-rw-r--r-- | src/cpu/inorder/inorder_dyn_inst.cc | 5 | ||||
-rw-r--r-- | src/cpu/inorder/inorder_dyn_inst.hh | 41 | ||||
-rw-r--r-- | src/cpu/inorder/reg_dep_map.cc | 42 | ||||
-rw-r--r-- | src/cpu/inorder/reg_dep_map.hh | 6 | ||||
-rw-r--r-- | src/cpu/inorder/resources/cache_unit.cc | 2 | ||||
-rw-r--r-- | src/cpu/inorder/resources/use_def.cc | 6 |
6 files changed, 73 insertions, 29 deletions
diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc index d42e84016..7cf117ce4 100644 --- a/src/cpu/inorder/inorder_dyn_inst.cc +++ b/src/cpu/inorder/inorder_dyn_inst.cc @@ -324,9 +324,10 @@ InOrderDynInst::setSquashInfo(unsigned stage_num) // the faulting instruction too. Squash // functions squash above a seqNum, so we // decrement here for that case - if (fault != NoFault) + if (fault != NoFault) { squashSeqNum = seqNum - 1; - else + return; + } else squashSeqNum = seqNum; #if ISA_HAS_DELAY_SLOT diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh index 0776dc5aa..c2c484074 100644 --- a/src/cpu/inorder/inorder_dyn_inst.hh +++ b/src/cpu/inorder/inorder_dyn_inst.hh @@ -261,6 +261,16 @@ class InOrderDynInst : public FastAlloc, public RefCounted */ bool _readySrcRegIdx[MaxInstSrcRegs]; + /** Flattened register index of the destination registers of this + * instruction. + */ + TheISA::RegIndex _flatDestRegIdx[TheISA::MaxInstDestRegs]; + + /** Flattened register index of the source registers of this + * instruction. + */ + TheISA::RegIndex _flatSrcRegIdx[TheISA::MaxInstSrcRegs]; + /** Physical register index of the destination registers of this * instruction. */ @@ -706,6 +716,35 @@ class InOrderDynInst : public FastAlloc, public RefCounted return _srcRegIdx[idx]; } + /** Flattens a source architectural register index into a logical index. + */ + void flattenSrcReg(int idx, TheISA::RegIndex flattened_src) + { + _flatSrcRegIdx[idx] = flattened_src; + } + + /** Flattens a destination architectural register index into a logical + * index. + */ + void flattenDestReg(int idx, TheISA::RegIndex flattened_dest) + { + _flatDestRegIdx[idx] = flattened_dest; + } + + /** Returns the flattened register index of the i'th destination + * register. + */ + TheISA::RegIndex flattenedDestRegIdx(int idx) const + { + return _flatDestRegIdx[idx]; + } + + /** Returns the flattened register index of the i'th source register */ + TheISA::RegIndex flattenedSrcRegIdx(int idx) const + { + return _flatSrcRegIdx[idx]; + } + /** Returns the physical register index of the previous physical register * that remapped to the same logical register index. */ @@ -770,7 +809,7 @@ class InOrderDynInst : public FastAlloc, public RefCounted int getDestIdxNum(PhysRegIndex dest_idx) { for (int i=0; i < staticInst->numDestRegs(); i++) { - if (_destRegIdx[i] == dest_idx) + if (_flatDestRegIdx[i] == dest_idx) return i; } diff --git a/src/cpu/inorder/reg_dep_map.cc b/src/cpu/inorder/reg_dep_map.cc index b8891bcc1..b95450f9d 100644 --- a/src/cpu/inorder/reg_dep_map.cc +++ b/src/cpu/inorder/reg_dep_map.cc @@ -92,23 +92,26 @@ RegDepMap::insert(DynInstPtr inst) inst->staticInst->getName(), dest_regs); - for (int i = 0; i < dest_regs; i++) - insert(inst->destRegIdx(i), inst); + for (int i = 0; i < dest_regs; i++) { + InOrderCPU::RegType reg_type; + TheISA::RegIndex raw_idx = inst->destRegIdx(i); + TheISA::RegIndex flat_idx = cpu->flattenRegIdx(raw_idx, + reg_type, + inst->threadNumber); + inst->flattenDestReg(i, flat_idx); + insert(reg_type, flat_idx, inst); + } } void -RegDepMap::insert(RegIndex idx, DynInstPtr inst) +RegDepMap::insert(uint8_t reg_type, RegIndex idx, DynInstPtr inst) { - InOrderCPU::RegType reg_type; - TheISA::RegIndex flat_idx = cpu->flattenRegIdx(idx, reg_type, - inst->threadNumber); - DPRINTF(RegDepMap, "Inserting [sn:%i] onto %s dep. list for " - "reg. idx %i (%i).\n", inst->seqNum, mapNames[reg_type], - idx, flat_idx); + "reg. idx %i.\n", inst->seqNum, mapNames[reg_type], + idx); - regMap[reg_type][flat_idx].push_back(inst); + regMap[reg_type][idx].push_back(inst); inst->setRegDepEntry(); } @@ -179,36 +182,37 @@ RegDepMap::canRead(uint8_t reg_type, RegIndex idx, DynInstPtr inst) } ThePipeline::DynInstPtr -RegDepMap::canForward(uint8_t reg_type, unsigned reg_idx, DynInstPtr inst, - unsigned clean_idx) +RegDepMap::canForward(uint8_t reg_type, unsigned reg_idx, DynInstPtr inst) { 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 instruction immediately in front of requestor to supply + // data while (list_it != list_end && (*list_it)->seqNum < inst->seqNum) { forward_inst = (*list_it); list_it++; } - DPRINTF(RegDepMap, "[sn:%i] Found potential forwarding value for reg %i (%i)" - " w/ [sn:%i]\n", - inst->seqNum, reg_idx, clean_idx, inst->seqNum); if (forward_inst) { - int dest_reg_idx = forward_inst->getDestIdxNum(clean_idx); + int dest_reg_idx = forward_inst->getDestIdxNum(reg_idx); assert(dest_reg_idx != -1); + DPRINTF(RegDepMap, "[sn:%i] Found potential forwarding value for reg %i " + " w/ [sn:%i] dest. reg. #%i\n", + inst->seqNum, reg_idx, forward_inst->seqNum, dest_reg_idx); + if (forward_inst->isExecuted() && forward_inst->readResultTime(dest_reg_idx) < curTick()) { return forward_inst; } else { if (!forward_inst->isExecuted()) { DPRINTF(RegDepMap, "[sn:%i] Can't get value through " - "forwarding, [sn:%i] has not been executed yet.\n", - inst->seqNum, forward_inst->seqNum); + "forwarding, [sn:%i] %s has not been executed yet.\n", + inst->seqNum, forward_inst->seqNum, forward_inst->instName()); } else if (forward_inst->readResultTime(dest_reg_idx) >= curTick()) { DPRINTF(RegDepMap, "[sn:%i] Can't get value through " "forwarding, [sn:%i] executed on tick:%i.\n", diff --git a/src/cpu/inorder/reg_dep_map.hh b/src/cpu/inorder/reg_dep_map.hh index 2aff5687b..03eb6bd65 100644 --- a/src/cpu/inorder/reg_dep_map.hh +++ b/src/cpu/inorder/reg_dep_map.hh @@ -77,7 +77,7 @@ class RegDepMap * another instruction for this destination register? */ DynInstPtr canForward(uint8_t reg_type, unsigned reg_idx, - DynInstPtr inst, unsigned clean_idx); + DynInstPtr inst); /** find an instruction to forward/bypass a value from */ DynInstPtr findBypassInst(RegIndex idx); @@ -94,9 +94,9 @@ class RegDepMap private: /** Insert an instruction into a specific destination register index - * onto map. This must be called w/the unflattened registered index + * onto map. */ - void insert(RegIndex idx, DynInstPtr inst); + void insert(uint8_t reg_type, RegIndex idx, DynInstPtr inst); /** Remove a specific instruction and dest. register index from map * This must be called w/the unflattened registered index diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 760fdb134..1050713a1 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -1075,7 +1075,7 @@ CacheUnitEvent::process() //@todo: eventually, we should do a timing translation w/ // hw page table walk on tlb miss - DPRINTF(Fault, "Handling Fault %s\n", inst->fault->name()); + DPRINTF(Fault, "Handling Fault %s : [sn:%i] %x\n", inst->fault->name(), inst->seqNum, inst->getMemAddr()); inst->fault->invoke(tlb_res->cpu->tcBase(tid), inst->staticInst); tlb_res->tlbBlocked[tid] = false; diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc index a66b64bfc..392239d42 100644 --- a/src/cpu/inorder/resources/use_def.cc +++ b/src/cpu/inorder/resources/use_def.cc @@ -179,6 +179,7 @@ UseDefUnit::execute(int slot_idx) InOrderCPU::RegType reg_type; RegIndex reg_idx = inst->_srcRegIdx[ud_idx]; RegIndex flat_idx = cpu->flattenRegIdx(reg_idx, reg_type, tid); + inst->flattenSrcReg(ud_idx, flat_idx); DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Attempting to read source " "register idx %i (reg #%i, flat#%i).\n", @@ -246,12 +247,11 @@ UseDefUnit::execute(int slot_idx) // Look for forwarding opportunities DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_type, flat_idx, - inst, - reg_idx); + inst); if (forward_inst) { int dest_reg_idx = - forward_inst->getDestIdxNum(reg_idx); + forward_inst->getDestIdxNum(flat_idx); switch (reg_type) { |