diff options
Diffstat (limited to 'cpu/base_dyn_inst.hh')
-rw-r--r-- | cpu/base_dyn_inst.hh | 712 |
1 files changed, 0 insertions, 712 deletions
diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh deleted file mode 100644 index 6333a1fb1..000000000 --- a/cpu/base_dyn_inst.hh +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Copyright (c) 2004-2005 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. - */ - -#ifndef __CPU_BASE_DYN_INST_HH__ -#define __CPU_BASE_DYN_INST_HH__ - -#include <list> -#include <string> - -#include "base/fast_alloc.hh" -#include "base/trace.hh" -#include "config/full_system.hh" -#include "cpu/exetrace.hh" -#include "cpu/inst_seq.hh" -#include "cpu/static_inst.hh" -#include "encumbered/cpu/full/op_class.hh" -#include "mem/functional/memory_control.hh" -#include "sim/system.hh" -/* -#include "encumbered/cpu/full/bpred_update.hh" -#include "encumbered/cpu/full/spec_memory.hh" -#include "encumbered/cpu/full/spec_state.hh" -#include "encumbered/mem/functional/main.hh" -*/ - -/** - * @file - * Defines a dynamic instruction context. - */ - -// Forward declaration. -class StaticInstPtr; - -template <class Impl> -class BaseDynInst : public FastAlloc, public RefCounted -{ - public: - // Typedef for the CPU. - typedef typename Impl::FullCPU FullCPU; - typedef typename FullCPU::ImplState ImplState; - - // Binary machine instruction type. - typedef TheISA::MachInst MachInst; - // Extended machine instruction type - typedef TheISA::ExtMachInst ExtMachInst; - // Logical register index type. - typedef TheISA::RegIndex RegIndex; - // Integer register index type. - typedef TheISA::IntReg IntReg; - - // The DynInstPtr type. - typedef typename Impl::DynInstPtr DynInstPtr; - - // The list of instructions iterator type. - typedef typename std::list<DynInstPtr>::iterator ListIt; - - enum { - MaxInstSrcRegs = TheISA::MaxInstSrcRegs, /// Max source regs - MaxInstDestRegs = TheISA::MaxInstDestRegs, /// Max dest regs - }; - - /** The StaticInst used by this BaseDynInst. */ - StaticInstPtr staticInst; - - //////////////////////////////////////////// - // - // INSTRUCTION EXECUTION - // - //////////////////////////////////////////// - /** InstRecord that tracks this instructions. */ - Trace::InstRecord *traceData; - - /** - * Does a read to a given address. - * @param addr The address to read. - * @param data The read's data is written into this parameter. - * @param flags The request's flags. - * @return Returns any fault due to the read. - */ - template <class T> - Fault read(Addr addr, T &data, unsigned flags); - - /** - * Does a write to a given address. - * @param data The data to be written. - * @param addr The address to write to. - * @param flags The request's flags. - * @param res The result of the write (for load locked/store conditionals). - * @return Returns any fault due to the write. - */ - template <class T> - Fault write(T data, Addr addr, unsigned flags, - uint64_t *res); - - void prefetch(Addr addr, unsigned flags); - void writeHint(Addr addr, int size, unsigned flags); - Fault copySrcTranslate(Addr src); - Fault copy(Addr dest); - - /** @todo: Consider making this private. */ - public: - /** The sequence number of the instruction. */ - InstSeqNum seqNum; - - enum Status { - IqEntry, /// Instruction is in the IQ - RobEntry, /// Instruction is in the ROB - LsqEntry, /// Instruction is in the LSQ - Completed, /// Instruction has completed - ResultReady, /// Instruction has its result - CanIssue, /// Instruction can issue and execute - Issued, /// Instruction has issued - Executed, /// Instruction has executed - CanCommit, /// Instruction can commit - AtCommit, /// Instruction has reached commit - Committed, /// Instruction has committed - Squashed, /// Instruction is squashed - SquashedInIQ, /// Instruction is squashed in the IQ - SquashedInLSQ, /// Instruction is squashed in the LSQ - SquashedInROB, /// Instruction is squashed in the ROB - RecoverInst, /// Is a recover instruction - BlockingInst, /// Is a blocking instruction - ThreadsyncWait, /// Is a thread synchronization instruction - SerializeBefore, /// Needs to serialize on - /// instructions ahead of it - SerializeAfter, /// Needs to serialize instructions behind it - SerializeHandled, /// Serialization has been handled - NumStatus - }; - - /** The status of this BaseDynInst. Several bits can be set. */ - std::bitset<NumStatus> status; - - /** The thread this instruction is from. */ - short threadNumber; - - /** data address space ID, for loads & stores. */ - short asid; - - /** How many source registers are ready. */ - unsigned readyRegs; - - /** Pointer to the FullCPU object. */ - FullCPU *cpu; - - /** Pointer to the exec context. */ - ImplState *thread; - - /** The kind of fault this instruction has generated. */ - Fault fault; - - /** The memory request. */ - MemReqPtr req; - - /** The effective virtual address (lds & stores only). */ - Addr effAddr; - - /** The effective physical address. */ - Addr physEffAddr; - - /** Effective virtual address for a copy source. */ - Addr copySrcEffAddr; - - /** Effective physical address for a copy source. */ - Addr copySrcPhysEffAddr; - - /** The memory request flags (from translation). */ - unsigned memReqFlags; - - /** The size of the data to be stored. */ - int storeSize; - - /** The data to be stored. */ - IntReg storeData; - - union Result { - uint64_t integer; -// float fp; - double dbl; - }; - - /** The result of the instruction; assumes for now that there's only one - * destination register. - */ - Result instResult; - - /** PC of this instruction. */ - Addr PC; - - /** Next non-speculative PC. It is not filled in at fetch, but rather - * once the target of the branch is truly known (either decode or - * execute). - */ - Addr nextPC; - - /** Predicted next PC. */ - Addr predPC; - - /** Count of total number of dynamic instructions. */ - static int instcount; - -#ifdef DEBUG - void dumpSNList(); -#endif - - /** Whether or not the source register is ready. - * @todo: Not sure this should be here vs the derived class. - */ - bool _readySrcRegIdx[MaxInstSrcRegs]; - - public: - /** BaseDynInst constructor given a binary instruction. - * @param inst The binary instruction. - * @param PC The PC of the instruction. - * @param pred_PC The predicted next PC. - * @param seq_num The sequence number of the instruction. - * @param cpu Pointer to the instruction's CPU. - */ - BaseDynInst(ExtMachInst inst, Addr PC, Addr pred_PC, InstSeqNum seq_num, - FullCPU *cpu); - - /** BaseDynInst constructor given a StaticInst pointer. - * @param _staticInst The StaticInst for this BaseDynInst. - */ - BaseDynInst(StaticInstPtr &_staticInst); - - /** BaseDynInst destructor. */ - ~BaseDynInst(); - - private: - /** Function to initialize variables in the constructors. */ - void initVars(); - - public: - /** - * @todo: Make this function work; currently it is a dummy function. - * @param fault Last fault. - * @param cmd Last command. - * @param addr Virtual address of access. - * @param p Memory accessed. - * @param nbytes Access size. - */ - void - trace_mem(Fault fault, - MemCmd cmd, - Addr addr, - void *p, - int nbytes); - - /** Dumps out contents of this BaseDynInst. */ - void dump(); - - /** Dumps out contents of this BaseDynInst into given string. */ - void dump(std::string &outstring); - - /** Returns the fault type. */ - Fault getFault() { return fault; } - - /** Checks whether or not this instruction has had its branch target - * calculated yet. For now it is not utilized and is hacked to be - * always false. - * @todo: Actually use this instruction. - */ - bool doneTargCalc() { return false; } - - /** Returns the next PC. This could be the speculative next PC if it is - * called prior to the actual branch target being calculated. - */ - Addr readNextPC() { return nextPC; } - - /** Set the predicted target of this current instruction. */ - void setPredTarg(Addr predicted_PC) { predPC = predicted_PC; } - - /** Returns the predicted target of the branch. */ - Addr readPredTarg() { return predPC; } - - /** Returns whether the instruction was predicted taken or not. */ - bool predTaken() { return predPC != (PC + sizeof(MachInst)); } - - /** Returns whether the instruction mispredicted. */ - bool mispredicted() { return predPC != nextPC; } - - // - // Instruction types. Forward checks to StaticInst object. - // - bool isNop() const { return staticInst->isNop(); } - bool isMemRef() const { return staticInst->isMemRef(); } - bool isLoad() const { return staticInst->isLoad(); } - bool isStore() const { return staticInst->isStore(); } - bool isStoreConditional() const - { return staticInst->isStoreConditional(); } - bool isInstPrefetch() const { return staticInst->isInstPrefetch(); } - bool isDataPrefetch() const { return staticInst->isDataPrefetch(); } - bool isCopy() const { return staticInst->isCopy(); } - bool isInteger() const { return staticInst->isInteger(); } - bool isFloating() const { return staticInst->isFloating(); } - bool isControl() const { return staticInst->isControl(); } - bool isCall() const { return staticInst->isCall(); } - bool isReturn() const { return staticInst->isReturn(); } - bool isDirectCtrl() const { return staticInst->isDirectCtrl(); } - bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); } - bool isCondCtrl() const { return staticInst->isCondCtrl(); } - bool isUncondCtrl() const { return staticInst->isUncondCtrl(); } - bool isThreadSync() const { return staticInst->isThreadSync(); } - bool isSerializing() const { return staticInst->isSerializing(); } - bool isSerializeBefore() const - { return staticInst->isSerializeBefore() || status[SerializeBefore]; } - bool isSerializeAfter() const - { return staticInst->isSerializeAfter() || status[SerializeAfter]; } - bool isMemBarrier() const { return staticInst->isMemBarrier(); } - bool isWriteBarrier() const { return staticInst->isWriteBarrier(); } - bool isNonSpeculative() const { return staticInst->isNonSpeculative(); } - bool isQuiesce() const { return staticInst->isQuiesce(); } - bool isIprAccess() const { return staticInst->isIprAccess(); } - bool isUnverifiable() const { return staticInst->isUnverifiable(); } - - /** Temporarily sets this instruction as a serialize before instruction. */ - void setSerializeBefore() { status.set(SerializeBefore); } - - /** Clears the serializeBefore part of this instruction. */ - void clearSerializeBefore() { status.reset(SerializeBefore); } - - /** Checks if this serializeBefore is only temporarily set. */ - bool isTempSerializeBefore() { return status[SerializeBefore]; } - - /** Temporarily sets this instruction as a serialize after instruction. */ - void setSerializeAfter() { status.set(SerializeAfter); } - - /** Clears the serializeAfter part of this instruction.*/ - void clearSerializeAfter() { status.reset(SerializeAfter); } - - /** Checks if this serializeAfter is only temporarily set. */ - bool isTempSerializeAfter() { return status[SerializeAfter]; } - - /** Sets the serialization part of this instruction as handled. */ - void setSerializeHandled() { status.set(SerializeHandled); } - - /** Checks if the serialization part of this instruction has been - * handled. This does not apply to the temporary serializing - * state; it only applies to this instruction's own permanent - * serializing state. - */ - bool isSerializeHandled() { return status[SerializeHandled]; } - - /** Returns the opclass of this instruction. */ - OpClass opClass() const { return staticInst->opClass(); } - - /** Returns the branch target address. */ - Addr branchTarget() const { return staticInst->branchTarget(PC); } - - /** Returns the number of source registers. */ - int8_t numSrcRegs() const { return staticInst->numSrcRegs(); } - - /** Returns the number of destination registers. */ - int8_t numDestRegs() const { return staticInst->numDestRegs(); } - - // the following are used to track physical register usage - // for machines with separate int & FP reg files - int8_t numFPDestRegs() const { return staticInst->numFPDestRegs(); } - int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); } - - /** Returns the logical register index of the i'th destination register. */ - RegIndex destRegIdx(int i) const { return staticInst->destRegIdx(i); } - - /** Returns the logical register index of the i'th source register. */ - RegIndex srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } - - /** Returns the result of an integer instruction. */ - uint64_t readIntResult() { return instResult.integer; } - - /** Returns the result of a floating point instruction. */ - float readFloatResult() { return (float)instResult.dbl; } - - /** Returns the result of a floating point (double) instruction. */ - double readDoubleResult() { return instResult.dbl; } - - void setIntReg(const StaticInst *si, int idx, uint64_t val) - { - instResult.integer = val; - } - - void setFloatRegSingle(const StaticInst *si, int idx, float val) - { -// instResult.fp = val; - instResult.dbl = (double)val; - } - - void setFloatRegDouble(const StaticInst *si, int idx, double val) - { - instResult.dbl = val; - } - - void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) - { - instResult.integer = val; - } - - /** Records that one of the source registers is ready. */ - void markSrcRegReady(); - - /** Marks a specific register as ready. */ - void markSrcRegReady(RegIndex src_idx); - - /** Returns if a source register is ready. */ - bool isReadySrcRegIdx(int idx) const - { - return this->_readySrcRegIdx[idx]; - } - - /** Sets this instruction as completed. */ - void setCompleted() { status.set(Completed); } - - /** Returns whether or not this instruction is completed. */ - bool isCompleted() const { return status[Completed]; } - - /** Marks the result as ready. */ - void setResultReady() { status.set(ResultReady); } - - /** Returns whether or not the result is ready. */ - bool isResultReady() const { return status[ResultReady]; } - - /** Sets this instruction as ready to issue. */ - void setCanIssue() { status.set(CanIssue); } - - /** Returns whether or not this instruction is ready to issue. */ - bool readyToIssue() const { return status[CanIssue]; } - - /** Sets this instruction as issued from the IQ. */ - void setIssued() { status.set(Issued); } - - /** Returns whether or not this instruction has issued. */ - bool isIssued() const { return status[Issued]; } - - /** Sets this instruction as executed. */ - void setExecuted() { status.set(Executed); } - - /** Returns whether or not this instruction has executed. */ - bool isExecuted() const { return status[Executed]; } - - /** Sets this instruction as ready to commit. */ - void setCanCommit() { status.set(CanCommit); } - - /** Clears this instruction as being ready to commit. */ - void clearCanCommit() { status.reset(CanCommit); } - - /** Returns whether or not this instruction is ready to commit. */ - bool readyToCommit() const { return status[CanCommit]; } - - void setAtCommit() { status.set(AtCommit); } - - bool isAtCommit() { return status[AtCommit]; } - - /** Sets this instruction as committed. */ - void setCommitted() { status.set(Committed); } - - /** Returns whether or not this instruction is committed. */ - bool isCommitted() const { return status[Committed]; } - - /** Sets this instruction as squashed. */ - void setSquashed() { status.set(Squashed); } - - /** Returns whether or not this instruction is squashed. */ - bool isSquashed() const { return status[Squashed]; } - - //Instruction Queue Entry - //----------------------- - /** Sets this instruction as a entry the IQ. */ - void setInIQ() { status.set(IqEntry); } - - /** Sets this instruction as a entry the IQ. */ - void clearInIQ() { status.reset(IqEntry); } - - /** Returns whether or not this instruction has issued. */ - bool isInIQ() const { return status[IqEntry]; } - - /** Sets this instruction as squashed in the IQ. */ - void setSquashedInIQ() { status.set(SquashedInIQ); status.set(Squashed);} - - /** Returns whether or not this instruction is squashed in the IQ. */ - bool isSquashedInIQ() const { return status[SquashedInIQ]; } - - - //Load / Store Queue Functions - //----------------------- - /** Sets this instruction as a entry the LSQ. */ - void setInLSQ() { status.set(LsqEntry); } - - /** Sets this instruction as a entry the LSQ. */ - void removeInLSQ() { status.reset(LsqEntry); } - - /** Returns whether or not this instruction is in the LSQ. */ - bool isInLSQ() const { return status[LsqEntry]; } - - /** Sets this instruction as squashed in the LSQ. */ - void setSquashedInLSQ() { status.set(SquashedInLSQ);} - - /** Returns whether or not this instruction is squashed in the LSQ. */ - bool isSquashedInLSQ() const { return status[SquashedInLSQ]; } - - - //Reorder Buffer Functions - //----------------------- - /** Sets this instruction as a entry the ROB. */ - void setInROB() { status.set(RobEntry); } - - /** Sets this instruction as a entry the ROB. */ - void clearInROB() { status.reset(RobEntry); } - - /** Returns whether or not this instruction is in the ROB. */ - bool isInROB() const { return status[RobEntry]; } - - /** Sets this instruction as squashed in the ROB. */ - void setSquashedInROB() { status.set(SquashedInROB); } - - /** Returns whether or not this instruction is squashed in the ROB. */ - bool isSquashedInROB() const { return status[SquashedInROB]; } - - /** Read the PC of this instruction. */ - const Addr readPC() const { return PC; } - - /** Set the next PC of this instruction (its actual target). */ - void setNextPC(uint64_t val) - { - nextPC = val; -// instResult.integer = val; - } - - void setASID(short addr_space_id) { asid = addr_space_id; } - - void setThread(unsigned tid) { threadNumber = tid; } - - void setState(ImplState *state) { thread = state; } - - /** Returns the exec context. - * @todo: Remove this once the ExecContext is no longer used. - */ - ExecContext *xcBase() { return thread->getXCProxy(); } - - private: - /** Instruction effective address. - * @todo: Consider if this is necessary or not. - */ - Addr instEffAddr; - - /** Whether or not the effective address calculation is completed. - * @todo: Consider if this is necessary or not. - */ - bool eaCalcDone; - - public: - /** Sets the effective address. */ - void setEA(Addr &ea) { instEffAddr = ea; eaCalcDone = true; } - - /** Returns the effective address. */ - const Addr &getEA() const { return req->vaddr; } - - /** Returns whether or not the eff. addr. calculation has been completed. */ - bool doneEACalc() { return eaCalcDone; } - - /** Returns whether or not the eff. addr. source registers are ready. */ - bool eaSrcsReady(); - - /** Whether or not the memory operation is done. */ - bool memOpDone; - - public: - /** Load queue index. */ - int16_t lqIdx; - - /** Store queue index. */ - int16_t sqIdx; - - /** Iterator pointing to this BaseDynInst in the list of all insts. */ - ListIt instListIt; - - /** Returns iterator to this instruction in the list of all insts. */ - ListIt &getInstListIt() { return instListIt; } - - /** Sets iterator for this instruction in the list of all insts. */ - void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; } -}; - -template<class Impl> -template<class T> -inline Fault -BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags) -{ - if (status[Executed]) { - fault = cpu->read(req, data, lqIdx); - return fault; - } - - req = new MemReq(addr, thread->getXCProxy(), sizeof(T), flags); - req->asid = asid; - req->thread_num = threadNumber; - req->pc = this->PC; - - if ((req->vaddr & (TheISA::VMPageSize - 1)) + req->size > - TheISA::VMPageSize) { - return TheISA::genAlignmentFault(); - } - - fault = cpu->translateDataReadReq(req); - - effAddr = req->vaddr; - physEffAddr = req->paddr; - memReqFlags = req->flags; - - if (fault == NoFault) { -#if FULL_SYSTEM - if (cpu->system->memctrl->badaddr(physEffAddr)) { - fault = TheISA::genMachineCheckFault(); - data = (T)-1; - this->setExecuted(); - } else { - fault = cpu->read(req, data, lqIdx); - } -#else - fault = cpu->read(req, data, lqIdx); -#endif - } else { - // Return a fixed value to keep simulation deterministic even - // along misspeculated paths. - data = (T)-1; - - // Commit will have to clean up whatever happened. Set this - // instruction as executed. - this->setExecuted(); - } - - if (traceData) { - traceData->setAddr(addr); - traceData->setData(data); - } - - return fault; -} - -template<class Impl> -template<class T> -inline Fault -BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res) -{ - if (traceData) { - traceData->setAddr(addr); - traceData->setData(data); - } - - req = new MemReq(addr, thread->getXCProxy(), sizeof(T), flags); - - req->asid = asid; - req->thread_num = threadNumber; - req->pc = this->PC; - - if ((req->vaddr & (TheISA::VMPageSize - 1)) + req->size > - TheISA::VMPageSize) { - return TheISA::genAlignmentFault(); - } - - fault = cpu->translateDataWriteReq(req); - - effAddr = req->vaddr; - physEffAddr = req->paddr; - memReqFlags = req->flags; - - if (fault == NoFault) { -#if FULL_SYSTEM - if (cpu->system->memctrl->badaddr(physEffAddr)) { - fault = TheISA::genMachineCheckFault(); - } else { - fault = cpu->write(req, data, sqIdx); - } -#else - fault = cpu->write(req, data, sqIdx); -#endif - } - - if (res) { - // always return some result to keep misspeculated paths - // (which will ignore faults) deterministic - *res = (fault == NoFault) ? req->result : 0; - } - - return fault; -} - -#endif // __CPU_BASE_DYN_INST_HH__ |