| /* |
| * Copyright (c) 2005-2006 The Regents of The University of Michigan |
| * 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: Kevin Lim |
| */ |
| |
| #ifndef __CPU_OZONE_DYN_INST_HH__ |
| #define __CPU_OZONE_DYN_INST_HH__ |
| |
| #include "arch/isa_traits.hh" |
| #include "arch/types.hh" |
| #include "config/full_system.hh" |
| #include "cpu/base_dyn_inst.hh" |
| #include "cpu/inst_seq.hh" |
| #include "cpu/ozone/cpu.hh" // MUST include this |
| #include "cpu/ozone/ozone_impl.hh" |
| |
| #include <list> |
| #include <vector> |
| |
| template <class Impl> |
| class OzoneDynInst : public BaseDynInst<Impl> |
| { |
| public: |
| // Typedefs |
| typedef typename Impl::OzoneCPU OzoneCPU; |
| |
| typedef typename OzoneCPU::ImplState ImplState; |
| |
| // Typedef for DynInstPtr. This is really just a RefCountingPtr<OoODynInst>. |
| typedef typename Impl::DynInstPtr DynInstPtr; |
| |
| typedef TheISA::ExtMachInst ExtMachInst; |
| typedef TheISA::MachInst MachInst; |
| typedef TheISA::FloatReg FloatReg; |
| typedef TheISA::FloatRegBits FloatRegBits; |
| typedef TheISA::MiscReg MiscReg; |
| typedef typename std::list<DynInstPtr>::iterator ListIt; |
| |
| // Note that this is duplicated from the BaseDynInst class; I'm |
| // simply not sure the enum would carry through so I could use it |
| // in array declarations in this class. |
| enum { |
| MaxInstSrcRegs = TheISA::MaxInstSrcRegs, |
| MaxInstDestRegs = TheISA::MaxInstDestRegs |
| }; |
| |
| OzoneDynInst(OzoneCPU *cpu); |
| |
| OzoneDynInst(ExtMachInst inst, Addr PC, Addr Pred_PC, |
| InstSeqNum seq_num, OzoneCPU *cpu); |
| |
| OzoneDynInst(StaticInstPtr inst); |
| |
| ~OzoneDynInst(); |
| |
| void setSrcInst(DynInstPtr &newSrcInst, int regIdx) |
| { srcInsts[regIdx] = newSrcInst; } |
| |
| bool srcInstReady(int regIdx); |
| |
| void setPrevDestInst(DynInstPtr &oldDestInst, int regIdx) |
| { prevDestInst[regIdx] = oldDestInst; } |
| |
| DynInstPtr &getPrevDestInst(int regIdx) |
| { return prevDestInst[regIdx]; } |
| |
| void addDependent(DynInstPtr &dependent_inst); |
| |
| std::vector<DynInstPtr> &getDependents() { return dependents; } |
| std::vector<DynInstPtr> &getMemDeps() { return memDependents; } |
| std::list<DynInstPtr> &getMemSrcs() { return srcMemInsts; } |
| |
| void wakeDependents(); |
| |
| void wakeMemDependents(); |
| |
| void addMemDependent(DynInstPtr &inst) { memDependents.push_back(inst); } |
| |
| void addSrcMemInst(DynInstPtr &inst) { srcMemInsts.push_back(inst); } |
| |
| void markMemInstReady(OzoneDynInst<Impl> *inst); |
| |
| // For now I will remove instructions from the list when they wake |
| // up. In the future, you only really need a counter. |
| bool memDepReady() { return srcMemInsts.empty(); } |
| |
| private: |
| void initInstPtrs(); |
| |
| std::vector<DynInstPtr> dependents; |
| |
| std::vector<DynInstPtr> memDependents; |
| |
| std::list<DynInstPtr> srcMemInsts; |
| |
| /** The instruction that produces the value of the source |
| * registers. These may be NULL if the value has already been |
| * read from the source instruction. |
| */ |
| DynInstPtr srcInsts[MaxInstSrcRegs]; |
| |
| /** |
| * Previous rename instruction for this destination. |
| */ |
| DynInstPtr prevDestInst[MaxInstSrcRegs]; |
| |
| public: |
| |
| Fault initiateAcc(); |
| |
| Fault completeAcc(PacketPtr pkt); |
| |
| // The register accessor methods provide the index of the |
| // instruction's operand (e.g., 0 or 1), not the architectural |
| // register index, to simplify the implementation of register |
| // renaming. We find the architectural register index by indexing |
| // into the instruction's own operand index table. Note that a |
| // raw pointer to the StaticInst is provided instead of a |
| // ref-counted StaticInstPtr to redice overhead. This is fine as |
| // long as these methods don't copy the pointer into any long-term |
| // storage (which is pretty hard to imagine they would have reason |
| // to do). |
| |
| uint64_t readIntRegOperand(const StaticInst *si, int idx) |
| { |
| return srcInsts[idx]->readIntResult(); |
| } |
| |
| FloatReg readFloatRegOperand(const StaticInst *si, int idx) |
| { |
| return srcInsts[idx]->readFloatResult(); |
| } |
| |
| FloatReg readFloatRegOperand(const StaticInst *si, int idx) |
| { |
| return srcInsts[idx]->readFloatResult(); |
| } |
| |
| FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) |
| { |
| return srcInsts[idx]->readIntResult(); |
| } |
| |
| /** @todo: Make results into arrays so they can handle multiple dest |
| * registers. |
| */ |
| void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) |
| { |
| BaseDynInst<Impl>::setIntReg(si, idx, val); |
| } |
| |
| void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) |
| { |
| BaseDynInst<Impl>::setFloatReg(si, idx, val); |
| } |
| |
| void setFloatRegOperandBits(const StaticInst *si, int idx, |
| FloatRegBits val) |
| { |
| BaseDynInst<Impl>::setFloatRegBits(si, idx, val); |
| } |
| |
| void setIntResult(uint64_t result) { this->instResult.integer = result; } |
| void setDoubleResult(double result) { this->instResult.dbl = result; } |
| |
| bool srcsReady(); |
| bool eaSrcsReady(); |
| |
| Fault execute(); |
| |
| Fault executeEAComp() |
| { return NoFault; } |
| |
| Fault executeMemAcc() |
| { return this->staticInst->memAccInst()->execute(this, this->traceData); } |
| |
| void clearDependents(); |
| |
| void clearMemDependents(); |
| |
| public: |
| // ISA stuff |
| MiscReg readMiscRegNoEffect(int misc_reg); |
| |
| MiscReg readMiscReg(int misc_reg); |
| |
| void setMiscRegNoEffect(int misc_reg, const MiscReg &val); |
| |
| void setMiscReg(int misc_reg, const MiscReg &val); |
| |
| #if FULL_SYSTEM |
| Fault hwrei(); |
| void trap(Fault fault); |
| bool simPalCheck(int palFunc); |
| #else |
| void syscall(uint64_t &callnum); |
| #endif |
| |
| ListIt iqIt; |
| bool iqItValid; |
| }; |
| |
| #endif // __CPU_OZONE_DYN_INST_HH__ |