summaryrefslogtreecommitdiff
path: root/src/cpu/inorder/resources/use_def.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/inorder/resources/use_def.cc')
-rw-r--r--src/cpu/inorder/resources/use_def.cc510
1 files changed, 0 insertions, 510 deletions
diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc
deleted file mode 100644
index 5a871d0d4..000000000
--- a/src/cpu/inorder/resources/use_def.cc
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Copyright (c) 2007 MIPS Technologies, Inc.
- * Copyright (c) 2013 Advanced Micro Devices, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Korey Sewell
- *
- */
-
-#include <list>
-#include <vector>
-
-#include "arch/isa_traits.hh"
-#include "config/the_isa.hh"
-#include "cpu/inorder/resources/use_def.hh"
-#include "cpu/inorder/cpu.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "debug/InOrderStall.hh"
-#include "debug/InOrderUseDef.hh"
-
-using namespace std;
-using namespace TheISA;
-using namespace ThePipeline;
-
-UseDefUnit::UseDefUnit(string res_name, int res_id, int res_width,
- Cycles res_latency, InOrderCPU *_cpu,
- ThePipeline::Params *params)
- : 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];
- serializeOnNextInst[tid] = false;
- serializeAfterSeqNum[tid] = 0;
- regDepMap[tid] = &cpu->archRegDepMap[tid];
- }
-
-}
-
-void
-UseDefUnit::regStats()
-{
- uniqueRegsPerSwitch
- .name(name() + ".uniqueRegsPerSwitch")
- .desc("Number of Unique Registers Needed Per Context Switch")
- .prereq(uniqueRegsPerSwitch);
-
- intRegFileReads
- .name(name() + ".intRegFileReads")
- .desc("Number of Reads from Int. Register File");
-
- intRegFileWrites
- .name(name() + ".intRegFileWrites")
- .desc("Number of Writes to Int. Register File");
-
- intRegFileAccs
- .name(name() + ".intRegFileAccesses")
- .desc("Total Accesses (Read+Write) to the Int. Register File");
- intRegFileAccs = intRegFileReads + intRegFileWrites;
-
- floatRegFileReads
- .name(name() + ".floatRegFileReads")
- .desc("Number of Reads from FP Register File");
-
- floatRegFileWrites
- .name(name() + ".floatRegFileWrites")
- .desc("Number of Writes to FP Register File");
-
- floatRegFileAccs
- .name(name() + ".floatRegFileAccesses")
- .desc("Total Accesses (Read+Write) to the FP Register File");
- floatRegFileAccs = floatRegFileReads + floatRegFileWrites;
-
- //@todo: add miscreg reads/writes
- // add forwarding by type???
-
- regForwards
- .name(name() + ".regForwards")
- .desc("Number of Registers Read Through Forwarding Logic");
-
- Resource::regStats();
-}
-
-void
-UseDefUnit::init()
-{
- // Set Up Resource Events to Appropriate Resource BandWidth
- if (latency > Cycles(0)) {
- resourceEvent = new ResourceEvent[width];
- } else {
- resourceEvent = NULL;
- }
-
- for (int i = 0; i < width; i++) {
- reqs[i] = new UseDefRequest(this);
- }
-
- initSlots();
-}
-
-ResReqPtr
-UseDefUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
- int slot_num, unsigned cmd)
-{
- UseDefRequest *ud_req = dynamic_cast<UseDefRequest*>(reqs[slot_num]);
- ud_req->setRequest(inst, stage_num, id, slot_num, cmd,
- inst->curSkedEntry->idx);
- return ud_req;
-}
-
-
-ResReqPtr
-UseDefUnit::findRequest(DynInstPtr inst)
-{
- for (int i = 0; i < width; i++) {
- UseDefRequest* ud_req =
- dynamic_cast<UseDefRequest*>(reqs[i]);
- assert(ud_req);
-
- if (ud_req->valid &&
- ud_req->getInst() == inst &&
- ud_req->cmd == inst->curSkedEntry->cmd &&
- ud_req->useDefIdx == inst->curSkedEntry->idx) {
- return ud_req;
- }
- }
-
- return NULL;
-}
-
-void
-UseDefUnit::execute(int slot_idx)
-{
- UseDefRequest* ud_req = dynamic_cast<UseDefRequest*>(reqs[slot_idx]);
- DynInstPtr inst = ud_req->inst;
- ThreadID tid = inst->readTid();
- InstSeqNum seq_num = inst->seqNum;
- int ud_idx = ud_req->useDefIdx;
-
- if (serializeOnNextInst[tid] &&
- seq_num > serializeAfterSeqNum[tid]) {
- inst->setSerializeBefore();
- serializeOnNextInst[tid] = false;
- }
-
- if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
- cpu->instList[tid].front() != inst) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] Serialize before instruction encountered."
- " Blocking until pipeline is clear.\n", tid, seq_num);
- ud_req->done(false);
- return;
- } else if (inst->isStoreConditional() || inst->isSerializeAfter()) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] Serialize after instruction encountered."
- " Blocking until pipeline is clear.\n", tid, seq_num);
- serializeOnNextInst[tid] = true;
- serializeAfterSeqNum[tid] = seq_num;
- }
-
- if (inst->fault != NoFault) {
- DPRINTF(InOrderUseDef,
- "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
- "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(),
- inst->pcState());
- ud_req->done();
- return;
- }
-
- // If there is a non-speculative instruction
- // in the pipeline then stall instructions here
- // ---
- if (*nonSpecInstActive[tid] && seq_num > *nonSpecSeqNum[tid]) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] cannot execute because"
- "there is non-speculative instruction [sn:%i] has not "
- "graduated.\n", tid, seq_num, *nonSpecSeqNum[tid]);
- ud_req->done(false);
- return;
- } else if (inst->isNonSpeculative()) {
- *nonSpecInstActive[tid] = true;
- *nonSpecSeqNum[tid] = seq_num;
- }
-
- switch (ud_req->cmd)
- {
- case ReadSrcReg:
- {
- RegClass 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);
-
- if (flat_idx == TheISA::ZeroReg && reg_type == IntRegClass) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Ignoring Reading of ISA-ZeroReg "
- "(Int. Reg %i).\n", tid, inst->seqNum, flat_idx);
- ud_req->done();
- return;
- } else {
- 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);
- }
-
- if (regDepMap[tid]->canRead(reg_type, flat_idx, inst)) {
- switch (reg_type)
- {
- case IntRegClass:
- {
- uniqueIntRegMap[flat_idx] = true;
-
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Reading Int Reg %i"
- " (%i) from Register File:0x%x.\n",
- tid, seq_num,
- reg_idx, flat_idx,
- cpu->readIntReg(flat_idx,inst->readTid()));
- inst->setIntSrc(ud_idx,
- cpu->readIntReg(flat_idx,
- inst->readTid()));
- intRegFileReads++;
- }
- break;
-
- case FloatRegClass:
- {
- 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 - FP_Reg_Base, flat_idx,
- cpu->readFloatRegBits(flat_idx,
- inst->readTid()),
- cpu->readFloatReg(flat_idx,
- inst->readTid()));
-
- inst->setFloatSrc(ud_idx,
- cpu->readFloatReg(flat_idx,
- inst->readTid()));
- inst->setFloatRegBitsSrc(ud_idx,
- cpu->readFloatRegBits(flat_idx,
- inst->readTid()));
- floatRegFileReads++;
- }
- break;
-
- case MiscRegClass:
- {
- uniqueMiscRegMap[flat_idx] = true;
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Reading Misc Reg %i "
- " (%i) from Register File:0x%x.\n",
- tid, seq_num,
- reg_idx - Misc_Reg_Base, flat_idx,
- cpu->readMiscReg(flat_idx,
- inst->readTid()));
- inst->setIntSrc(ud_idx,
- cpu->readMiscReg(flat_idx,
- inst->readTid()));
- }
- break;
-
- default:
- panic("Invalid Register Type: %i", reg_type);
- }
-
- ud_req->done();
- } else {
- // Look for forwarding opportunities
- DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_type,
- flat_idx,
- inst);
-
- if (forward_inst) {
- int dest_reg_idx =
- forward_inst->getDestIdxNum(flat_idx);
-
- switch (reg_type)
- {
- case IntRegClass:
- {
- DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
- " reg %i (%i), value 0x%x from "
- "[sn:%i] to [sn:%i] source #%x.\n",
- tid, reg_idx, flat_idx,
- forward_inst->readIntResult(dest_reg_idx),
- forward_inst->seqNum,
- inst->seqNum, ud_idx);
- inst->setIntSrc(ud_idx,
- forward_inst->
- readIntResult(dest_reg_idx));
- }
- break;
-
- case FloatRegClass:
- {
- DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
- " reg %i (%i) value 0x%x from "
- "[sn:%i] to [sn:%i] source #%i.\n",
- tid, reg_idx - FP_Reg_Base, 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));
- }
- break;
-
- case MiscRegClass:
- {
- DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
- " reg %i (%i) value 0x%x from "
- "[sn:%i] to [sn:%i] source #%i.\n",
- tid, reg_idx - Misc_Reg_Base, flat_idx,
- forward_inst->readIntResult(dest_reg_idx),
- forward_inst->seqNum,
- inst->seqNum, ud_idx);
- inst->setIntSrc(ud_idx,
- forward_inst->
- readIntResult(dest_reg_idx));
- }
- break;
-
- default:
- panic("Invalid Register Type: %i", reg_type);
- }
-
- regForwards++;
- ud_req->done();
- } else {
- 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);
- ud_req->done(false);
- }
- }
- }
- break;
-
- case WriteDestReg:
- {
- RegClass reg_type;
- RegIndex reg_idx = inst->_destRegIdx[ud_idx];
- RegIndex flat_idx = cpu->flattenRegIdx(reg_idx, reg_type, tid);
-
- if (flat_idx == TheISA::ZeroReg && reg_type == IntRegClass) {
- DPRINTF(IntRegs, "[tid:%i]: Ignoring Writing of ISA-ZeroReg "
- "(Int. Reg %i)\n", tid, flat_idx);
- ud_req->done();
- return;
- }
-
- 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);
-
- switch (reg_type)
- {
- case IntRegClass:
- {
- 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(reg_type, flat_idx, inst);
-
- cpu->setIntReg(flat_idx,
- inst->readIntResult(ud_idx),
- inst->readTid());
- intRegFileWrites++;
- }
- break;
-
- case FloatRegClass:
- {
- uniqueFloatRegMap[flat_idx] = true;
-
- // Remove Reg. Dependecny Block on this Register
- regDepMap[tid]->removeFront(reg_type, flat_idx, inst);
-
- if (inst->resultType(ud_idx) ==
- InOrderDynInst::FloatBits) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing FP-Bits "
- "Result %08f (bits:0x%x) to register "
- "idx %i (%i).\n",
- tid, seq_num,
- inst->readFloatResult(ud_idx),
- inst->readFloatBitsResult(ud_idx),
- reg_idx - FP_Reg_Base, flat_idx);
-
- // Check for FloatRegBits Here
- cpu->setFloatRegBits(flat_idx,
- inst->readFloatBitsResult(ud_idx),
- inst->readTid());
- } else if (inst->resultType(ud_idx) ==
- InOrderDynInst::Float) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing Float "
- "Result %08f (bits:0x%x) to register "
- "idx %i (%i).\n",
- tid, seq_num, inst->readFloatResult(ud_idx),
- inst->readIntResult(ud_idx),
- reg_idx - FP_Reg_Base, flat_idx);
-
- cpu->setFloatReg(flat_idx,
- inst->readFloatResult(ud_idx),
- inst->readTid());
- } else if (inst->resultType(ud_idx) ==
- InOrderDynInst::Double) {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Writing Double "
- "Result %08f (bits:0x%x) to register "
- "idx %i (%i).\n",
- tid, seq_num,
- inst->readFloatResult(ud_idx),
- inst->readIntResult(ud_idx),
- reg_idx - FP_Reg_Base, flat_idx);
-
- cpu->setFloatReg(flat_idx,
- inst->readFloatResult(ud_idx),
- inst->readTid());
- } else {
- panic("Result Type Not Set For [sn:%i] %s.\n",
- inst->seqNum, inst->instName());
- }
-
- floatRegFileWrites++;
- }
- break;
-
- case MiscRegClass:
- {
- uniqueMiscRegMap[flat_idx] = true;
-
- DPRINTF(InOrderUseDef, "[tid:%i]: Writing Misc. 0x%x "
- "to register idx %i.\n",
- tid, inst->readIntResult(ud_idx), reg_idx - Misc_Reg_Base);
-
- // Remove Dependencies
- regDepMap[tid]->removeFront(reg_type, flat_idx, inst);
-
- cpu->setMiscReg(flat_idx,
- inst->readIntResult(ud_idx),
- inst->readTid());
- }
- break;
-
- default:
- panic("Invalid Register Type: %i", reg_type);
- }
-
- ud_req->done();
- } else {
- DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i]: Dest. register idx: %i is "
- "not ready to write.\n",
- tid, seq_num, reg_idx);
- DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to write "
- "register (idx=%i)\n",
- tid, reg_idx);
- ud_req->done(false);
- }
- }
- break;
-
- case MarkDestRegs:
- {
- regDepMap[tid]->insert(inst);
- ud_req->done();
- }
- break;
-
- default:
- fatal("Unrecognized command to %s", resName);
- }
-
-}
-
-void
-UseDefUnit::updateAfterContextSwitch(DynInstPtr inst, ThreadID tid)
-{
- uniqueRegsPerSwitch = uniqueIntRegMap.size() + uniqueFloatRegMap.size()
- + uniqueMiscRegMap.size();
- uniqueIntRegMap.clear();
- uniqueFloatRegMap.clear();
- uniqueMiscRegMap.clear();
-}