X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Finorder%2Finorder_dyn_inst.hh;h=f49476ec595c5d4763176918279bd8bdb12a4b5a;hb=e8e9f9731281e8c2ecb50a9aa318a65402cbee5c;hp=9f52f954fef3cd5057d815068d7c74f7db1b0886;hpb=973d8b8b13b8e4ea178cafa95aaf6538699b8b15;p=gem5.git diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh index 9f52f954f..f49476ec5 100644 --- a/src/cpu/inorder/inorder_dyn_inst.hh +++ b/src/cpu/inorder/inorder_dyn_inst.hh @@ -38,29 +38,41 @@ #include #include "arch/faults.hh" +#include "arch/isa_traits.hh" +#include "arch/mt.hh" +#include "arch/types.hh" +#include "arch/utility.hh" #include "base/fast_alloc.hh" #include "base/trace.hh" -#include "cpu/inorder/inorder_trace.hh" +#include "base/types.hh" #include "config/full_system.hh" -#include "cpu/thread_context.hh" +#include "config/the_isa.hh" +#include "cpu/inorder/inorder_trace.hh" +#include "cpu/inorder/pipeline_traits.hh" +#include "cpu/inorder/resource.hh" +#include "cpu/inorder/resource_sked.hh" +#include "cpu/inorder/thread_state.hh" #include "cpu/exetrace.hh" #include "cpu/inst_seq.hh" #include "cpu/op_class.hh" #include "cpu/static_inst.hh" -#include "cpu/inorder/thread_state.hh" -#include "cpu/inorder/resource.hh" -#include "cpu/inorder/pipeline_traits.hh" +#include "cpu/thread_context.hh" +#include "debug/InOrderDynInst.hh" #include "mem/packet.hh" #include "sim/system.hh" +#if THE_ISA == ALPHA_ISA +#include "arch/alpha/ev5.hh" +#endif + /** * @file * Defines a dynamic instruction context for a inorder CPU model. */ // Forward declaration. -class StaticInstPtr; class ResourceRequest; +class Packet; class InOrderDynInst : public FastAlloc, public RefCounted { @@ -76,6 +88,8 @@ class InOrderDynInst : public FastAlloc, public RefCounted // Floating point register type. typedef TheISA::FloatReg FloatReg; // Floating point register type. + typedef TheISA::FloatRegBits FloatRegBits; + // Floating point register type. typedef TheISA::MiscReg MiscReg; typedef short int PhysRegIndex; @@ -89,36 +103,18 @@ class InOrderDynInst : public FastAlloc, public RefCounted typedef std::list::iterator ListIt; enum { - MaxInstSrcRegs = TheISA::MaxInstSrcRegs, /// Max source regs - MaxInstDestRegs = TheISA::MaxInstDestRegs, /// Max dest regs + MaxInstSrcRegs = TheISA::MaxInstSrcRegs, /// Max source regs + MaxInstDestRegs = TheISA::MaxInstDestRegs, /// Max dest regs }; 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. - */ - InOrderDynInst(ExtMachInst inst, Addr PC, Addr pred_PC, InstSeqNum seq_num, - InOrderCPU *cpu); - /** BaseDynInst constructor given a binary instruction. * @param seq_num The sequence number of the instruction. * @param cpu Pointer to the instruction's CPU. * NOTE: Must set Binary Instrution through Member Function */ - InOrderDynInst(InOrderCPU *cpu, InOrderThreadState *state, InstSeqNum seq_num, - unsigned tid); - - /** BaseDynInst constructor given a StaticInst pointer. - * @param _staticInst The StaticInst for this BaseDynInst. - */ - InOrderDynInst(StaticInstPtr &_staticInst); - - /** Skeleton Constructor. */ - InOrderDynInst(); + InOrderDynInst(InOrderCPU *cpu, InOrderThreadState *state, + InstSeqNum seq_num, ThreadID tid, unsigned asid = 0); /** InOrderDynInst destructor. */ ~InOrderDynInst(); @@ -127,11 +123,11 @@ class InOrderDynInst : public FastAlloc, public RefCounted /** The sequence number of the instruction. */ InstSeqNum seqNum; - /** The sequence number of the instruction. */ - InstSeqNum bdelaySeqNum; + /** If this instruction is squashing, the number should we squash behind. */ + InstSeqNum squashSeqNum; enum Status { - RegDepMapEntry, /// Instruction has been entered onto the RegDepMap + RegDepMapEntry, /// Instruction is entered onto the RegDepMap IqEntry, /// Instruction is in the IQ RobEntry, /// Instruction is in the ROB LsqEntry, /// Instruction is in the LSQ @@ -154,6 +150,7 @@ class InOrderDynInst : public FastAlloc, public RefCounted /// instructions ahead of it SerializeAfter, /// Needs to serialize instructions behind it SerializeHandled, /// Serialization has been handled + RemoveList, /// Is Instruction on Remove List? NumStatus }; @@ -196,9 +193,6 @@ class InOrderDynInst : public FastAlloc, public RefCounted /** Data used for a store for operation. */ uint64_t storeData; - /** The resource schedule for this inst */ - ThePipeline::ResSchedule resSched; - /** List of active resource requests for this instruction */ std::list reqList; @@ -208,29 +202,44 @@ class InOrderDynInst : public FastAlloc, public RefCounted /** 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; /** How many source registers are ready. */ unsigned readyRegs; + enum ResultType { + None, + Integer, + Float, + FloatBits, + Double + }; + /** An instruction src/dest has to be one of these types */ - union InstValue { - uint64_t integer; - float fp; - double dbl; + struct InstValue { + IntReg intVal; + union { + FloatReg f; + FloatRegBits i; + } fpVal; + + InstValue() + { + intVal = 0; + fpVal.i = 0; + } }; /** Result of an instruction execution */ struct InstResult { - InstValue val; + ResultType type; + InstValue res; Tick tick; + + InstResult() + : type(None), tick(0) + { } }; /** The source of the instruction; assumes for now that there's only one @@ -244,27 +253,13 @@ class InOrderDynInst : public FastAlloc, public RefCounted InstResult instResult[MaxInstDestRegs]; /** 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; - - /** Next 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 nextNPC; + TheISA::PCState pc; /** Predicted next PC. */ - Addr predPC; - - /** Address to fetch from */ - Addr fetchAddr; + TheISA::PCState predPC; /** Address to get/write data from/to */ + /* Fetching address when inst. starts, Data address for load/store after fetch*/ Addr memAddr; /** Whether or not the source register is ready. @@ -272,6 +267,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. */ @@ -289,11 +294,6 @@ class InOrderDynInst : public FastAlloc, public RefCounted int nextStage; - /* vars to keep track of InstStage's - used for resource sched defn */ - int nextInstStageNum; - ThePipeline::InstStage *currentInstStage; - std::list instStageList; - private: /** Function to initialize variables in the constructors. */ void initVars(); @@ -301,12 +301,31 @@ class InOrderDynInst : public FastAlloc, public RefCounted public: Tick memTime; + PacketDataPtr splitMemData; + RequestPtr splitMemReq; + int totalSize; + int split2ndSize; + Addr split2ndAddr; + bool split2ndAccess; + uint8_t split2ndData; + PacketDataPtr split2ndDataPtr; + unsigned split2ndFlags; + bool splitInst; + int splitFinishCnt; + uint64_t *split2ndStoreDataPtr; + bool splitInstSked; + //////////////////////////////////////////////////////////// // // BASE INSTRUCTION INFORMATION. // //////////////////////////////////////////////////////////// - void setMachInst(ExtMachInst inst); + std::string instName() + { return (staticInst) ? staticInst->getName() : "undecoded-inst"; } + + void setStaticInst(StaticInstPtr si); + + ExtMachInst getMachInst() { return staticInst->machInst; } /** Sets the StaticInst. */ void setStaticInst(StaticInstPtr &static_inst); @@ -321,7 +340,7 @@ class InOrderDynInst : public FastAlloc, public RefCounted short readTid() { return threadNumber; } /** Sets the thread id. */ - void setTid(unsigned tid) { threadNumber = tid; } + void setTid(ThreadID tid) { threadNumber = tid; } void setVpn(int id) { virtProcNumber = id; } @@ -336,29 +355,34 @@ class InOrderDynInst : public FastAlloc, public RefCounted /** Returns the fault type. */ Fault getFault() { return fault; } + /** Read this CPU's ID. */ + int cpuId(); + + /** Read this context's system-wide ID **/ + int contextId() { return thread->contextId(); } + //////////////////////////////////////////////////////////// // // 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 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 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 isCondCtrl() const { return staticInst->isCondCtrl(); } + bool isUncondCtrl() const { return staticInst->isUncondCtrl(); } bool isCondDelaySlot() const { return staticInst->isCondDelaySlot(); } bool isThreadSync() const { return staticInst->isThreadSync(); } @@ -373,72 +397,103 @@ class InOrderDynInst : public FastAlloc, public RefCounted bool isQuiesce() const { return staticInst->isQuiesce(); } bool isIprAccess() const { return staticInst->isIprAccess(); } bool isUnverifiable() const { return staticInst->isUnverifiable(); } + bool isSyscall() const + { return staticInst->isSyscall(); } + ///////////////////////////////////////////// // // RESOURCE SCHEDULING // ///////////////////////////////////////////// + typedef ThePipeline::RSkedPtr RSkedPtr; + bool inFrontEnd; - void setNextStage(int stage_num) { nextStage = stage_num; } - int getNextStage() { return nextStage; } + RSkedPtr frontSked; + RSkedIt frontSked_end; - ThePipeline::InstStage *addStage(); - ThePipeline::InstStage *addStage(int stage); - ThePipeline::InstStage *currentStage() { return currentInstStage; } - void deleteStages(); + RSkedPtr backSked; + RSkedIt backSked_end; - /** Add A Entry To Reource Schedule */ - void addToSched(ThePipeline::ScheduleEntry* sched_entry) - { resSched.push(sched_entry); } + RSkedIt curSkedEntry; + void setFrontSked(RSkedPtr front_sked) + { + frontSked = front_sked; + frontSked_end.init(frontSked); + frontSked_end = frontSked->end(); + //DPRINTF(InOrderDynInst, "Set FrontSked End to : %x \n" , + // frontSked_end.getIt()/*, frontSked->end()*/); + //assert(frontSked_end == frontSked->end()); + + // This initializes instruction to be able + // to walk the resource schedule + curSkedEntry.init(frontSked); + curSkedEntry = frontSked->begin(); + } - /** Print Resource Schedule */ - void printSched() + void setBackSked(RSkedPtr back_sked) { - using namespace ThePipeline; + backSked = back_sked; + backSked_end.init(backSked); + backSked_end = backSked->end(); + } - ResSchedule tempSched; - std::cerr << "\tInst. Res. Schedule: "; - while (!resSched.empty()) { - std::cerr << '\t' << resSched.top()->stageNum << "-" - << resSched.top()->resNum << ", "; + void setNextStage(int stage_num) { nextStage = stage_num; } + int getNextStage() { return nextStage; } - tempSched.push(resSched.top()); - resSched.pop(); + /** Print Resource Schedule */ + void printSked() + { + if (frontSked != NULL) { + frontSked->print(); } - std::cerr << std::endl; - resSched = tempSched; + if (backSked != NULL) { + backSked->print(); + } } /** Return Next Resource Stage To Be Used */ int nextResStage() { - if (resSched.empty()) - return -1; - else - return resSched.top()->stageNum; + assert((inFrontEnd && curSkedEntry != frontSked_end) || + (!inFrontEnd && curSkedEntry != backSked_end)); + + return curSkedEntry->stageNum; } /** Return Next Resource To Be Used */ int nextResource() { - if (resSched.empty()) - return -1; - else - return resSched.top()->resNum; + assert((inFrontEnd && curSkedEntry != frontSked_end) || + (!inFrontEnd && curSkedEntry != backSked_end)); + + return curSkedEntry->resNum; } - /** Remove & Deallocate a schedule entry */ - void popSchedEntry() + /** Finish using a schedule entry, increment to next entry */ + bool finishSkedEntry() { - if (!resSched.empty()) { - ThePipeline::ScheduleEntry* sked = resSched.top(); - resSched.pop(); - delete sked; + curSkedEntry++; + + if (inFrontEnd && curSkedEntry == frontSked_end) { + DPRINTF(InOrderDynInst, "[sn:%i] Switching to " + "back end schedule.\n", seqNum); + assert(backSked != NULL); + curSkedEntry.init(backSked); + curSkedEntry = backSked->begin(); + inFrontEnd = false; + } else if (!inFrontEnd && curSkedEntry == backSked_end) { + return true; } + + DPRINTF(InOrderDynInst, "[sn:%i] Next Stage: %i " + "Next Resource: %i.\n", seqNum, curSkedEntry->stageNum, + curSkedEntry->resNum); + + return false; } /** Release a Resource Request (Currently Unused) */ @@ -462,11 +517,18 @@ class InOrderDynInst : public FastAlloc, public RefCounted void setCurResSlot(unsigned slot_num) { curResSlot = slot_num; } /** Calls a syscall. */ +#if FULL_SYSTEM + /** Calls hardware return from error interrupt. */ + Fault hwrei(); + /** Traps to handle specified fault. */ + void trap(Fault fault); + bool simPalCheck(int palFunc); +#else + short syscallNum; +#endif + + /** Emulates a syscall. */ void syscall(int64_t callnum); - void prefetch(Addr addr, unsigned flags); - void writeHint(Addr addr, int size, unsigned flags); - Fault copySrcTranslate(Addr src); - Fault copy(Addr dest); //////////////////////////////////////////////////////////// // @@ -475,40 +537,20 @@ class InOrderDynInst : public FastAlloc, public RefCounted //////////////////////////////////////////////////////////// virtual void deallocateContext(int thread_num); - virtual void enableVirtProcElement(unsigned vpe); - virtual void disableVirtProcElement(unsigned vpe); - - virtual void enableMultiThreading(unsigned vpe); - virtual void disableMultiThreading(unsigned vpe); - - virtual void setThreadRescheduleCondition(uint32_t cond); - //////////////////////////////////////////////////////////// // // PROGRAM COUNTERS - PC/NPC/NPC // //////////////////////////////////////////////////////////// /** Read the PC of this instruction. */ - const Addr readPC() const { return PC; } + const TheISA::PCState &pcState() const { return pc; } /** Sets the PC of this instruction. */ - void setPC(Addr pc) { PC = pc; } - - /** 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 next PC of this instruction (its actual target). */ - void setNextPC(uint64_t val) { nextPC = val; } - - /** Returns the next NPC. This could be the speculative next NPC if it is - * called prior to the actual branch target being calculated. - */ - Addr readNextNPC() { return nextNPC; } + void pcState(const TheISA::PCState &_pc) { pc = _pc; } - /** Set the next PC of this instruction (its actual target). */ - void setNextNPC(uint64_t val) { nextNPC = val; } + const Addr instAddr() { return pc.instAddr(); } + const Addr nextInstAddr() { return pc.nextInstAddr(); } + const MicroPC microPC() { return pc.microPC(); } //////////////////////////////////////////////////////////// // @@ -516,31 +558,36 @@ class InOrderDynInst : public FastAlloc, public RefCounted // //////////////////////////////////////////////////////////// /** Set the predicted target of this current instruction. */ - void setPredTarg(Addr predicted_PC) { predPC = predicted_PC; } + void setPredTarg(const TheISA::PCState &predictedPC) + { predPC = predictedPC; } /** Returns the predicted target of the branch. */ - Addr readPredTarg() { return predPC; } + TheISA::PCState readPredTarg() { return predPC; } + + /** Returns the predicted PC immediately after the branch. */ + Addr predInstAddr() { return predPC.instAddr(); } + + /** Returns the predicted PC two instructions after the branch */ + Addr predNextInstAddr() { return predPC.nextInstAddr(); } + + /** Returns the predicted micro PC after the branch */ + Addr readPredMicroPC() { return predPC.microPC(); } /** Returns whether the instruction was predicted taken or not. */ bool predTaken() { return predictTaken; } /** Returns whether the instruction mispredicted. */ - bool mispredicted() + bool + mispredicted() { - // Special case since a not-taken, cond. delay slot, effectively - // nullifies the delay slot instruction - if (isCondDelaySlot() && !predictTaken) { - return predPC != nextPC; - } else { - return predPC != nextNPC; - } + TheISA::PCState nextPC = pc; + TheISA::advancePC(nextPC, staticInst); + return !(nextPC == predPC); } - /** Returns whether the instruction mispredicted. */ - bool mistargeted() { return predPC != nextNPC; } - /** Returns the branch target address. */ - Addr branchTarget() const { return staticInst->branchTarget(PC); } + TheISA::PCState branchTarget() const + { return staticInst->branchTarget(pc); } /** Checks whether or not this instruction has had its branch target * calculated yet. For now it is not utilized and is hacked to be @@ -557,35 +604,21 @@ class InOrderDynInst : public FastAlloc, public RefCounted bool procDelaySlotOnMispred; + void setSquashInfo(unsigned stage_num); + //////////////////////////////////////////// // // MEMORY ACCESS // //////////////////////////////////////////// - /** - * 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 - 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 - Fault write(T data, Addr addr, unsigned flags, - uint64_t *res); - /** Initiates a memory access - Calculate Eff. Addr & Initiate Memory Access - * Only valid for memory operations. + Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags); + + Fault writeMem(uint8_t *data, unsigned size, + Addr addr, unsigned flags, uint64_t *res); + + /** Initiates a memory access - Calculate Eff. Addr & Initiate Memory + * Access Only valid for memory operations. */ Fault initiateAcc(); @@ -598,7 +631,8 @@ class InOrderDynInst : public FastAlloc, public RefCounted /** Read Effective Address from instruction & do memory access */ Fault memAccess(); - RequestPtr memReq; + RequestPtr fetchMemReq; + RequestPtr dataMemReq; bool memAddrReady; @@ -614,17 +648,13 @@ class InOrderDynInst : public FastAlloc, public RefCounted Addr getMemAddr() { return memAddr; } - int getMemAccSize() { return staticInst->memAccSize(this); } - - int getMemFlags() { return staticInst->memAccFlags(); } - /** Sets the effective address. */ void setEA(Addr &ea) { instEffAddr = ea; eaCalcDone = true; } /** Returns the effective address. */ const Addr &getEA() const { return instEffAddr; } - /** Returns whether or not the eff. addr. calculation has been completed. */ + /** 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. @@ -648,7 +678,7 @@ class InOrderDynInst : public FastAlloc, public RefCounted // ////////////////////////////////////////////////// /** Returns the number of source registers. */ - int8_t numSrcRegs() const { return staticInst->numSrcRegs(); } + int8_t numSrcRegs() const { return staticInst->numSrcRegs(); } /** Returns the number of destination registers. */ int8_t numDestRegs() const { return staticInst->numDestRegs(); } @@ -683,6 +713,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. */ @@ -747,7 +806,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; } @@ -783,11 +842,11 @@ class InOrderDynInst : public FastAlloc, public RefCounted /** Functions that sets an integer or floating point * source register to a value. */ void setIntSrc(int idx, uint64_t val); - void setFloatSrc(int idx, FloatReg val, int width = 32); - void setFloatRegBitsSrc(int idx, uint64_t val); + void setFloatSrc(int idx, FloatReg val); + void setFloatRegBitsSrc(int idx, TheISA::FloatRegBits val); - uint64_t* getIntSrcPtr(int idx) { return &instSrc[idx].integer; } - uint64_t readIntSrc(int idx) { return instSrc[idx].integer; } + TheISA::IntReg* getIntSrcPtr(int idx) { return &instSrc[idx].intVal; } + uint64_t readIntSrc(int idx) { return instSrc[idx].intVal; } /** These Instructions read a integer/float/misc. source register * value in the instruction. The instruction's execute function will @@ -795,39 +854,64 @@ class InOrderDynInst : public FastAlloc, public RefCounted * language (which is why the name isnt readIntSrc(...)) Note: That * the source reg. value is set using the setSrcReg() function. */ - IntReg readIntRegOperand(const StaticInst *si, int idx, unsigned tid=0); - FloatReg readFloatRegOperand(const StaticInst *si, int idx, - int width = TheISA::SingleWidth); - FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx, - int width = TheISA::SingleWidth); + IntReg readIntRegOperand(const StaticInst *si, int idx, ThreadID tid = 0); + FloatReg readFloatRegOperand(const StaticInst *si, int idx); + TheISA::FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx); MiscReg readMiscReg(int misc_reg); MiscReg readMiscRegNoEffect(int misc_reg); MiscReg readMiscRegOperand(const StaticInst *si, int idx); MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx); /** Returns the result value instruction. */ - uint64_t readIntResult(int idx) { return instResult[idx].val.integer; } - float readFloatResult(int idx) { return instResult[idx].val.fp; } - double readDoubleResult(int idx) { return instResult[idx].val.dbl; } + ResultType resultType(int idx) + { + return instResult[idx].type; + } + + IntReg readIntResult(int idx) + { + return instResult[idx].res.intVal; + } + + FloatReg readFloatResult(int idx) + { + return instResult[idx].res.fpVal.f; + } + + FloatRegBits readFloatBitsResult(int idx) + { + return instResult[idx].res.fpVal.i; + } + Tick readResultTime(int idx) { return instResult[idx].tick; } - uint64_t* getIntResultPtr(int idx) { return &instResult[idx].val.integer; } + IntReg* getIntResultPtr(int idx) { return &instResult[idx].res.intVal; } /** This is the interface that an instruction will use to write * it's destination register. */ void setIntRegOperand(const StaticInst *si, int idx, IntReg val); - void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, - int width = TheISA::SingleWidth); - void setFloatRegOperandBits(const StaticInst *si, int idx, FloatRegBits val, - int width = TheISA::SingleWidth); + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val); + void setFloatRegOperandBits(const StaticInst *si, int idx, + TheISA::FloatRegBits val); void setMiscReg(int misc_reg, const MiscReg &val); void setMiscRegNoEffect(int misc_reg, const MiscReg &val); void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val); - void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val); + void setMiscRegOperandNoEffect(const StaticInst *si, int idx, + const MiscReg &val); + + virtual uint64_t readRegOtherThread(unsigned idx, + ThreadID tid = InvalidThreadID); + virtual void setRegOtherThread(unsigned idx, const uint64_t &val, + ThreadID tid = InvalidThreadID); + + /** Returns the number of consecutive store conditional failures. */ + unsigned readStCondFailures() + { return thread->storeCondFailures; } - virtual uint64_t readRegOtherThread(unsigned idx, int tid = -1); - virtual void setRegOtherThread(unsigned idx, const uint64_t &val, int tid = -1); + /** Sets the number of consecutive store conditional failures. */ + void setStCondFailures(unsigned sc_failures) + { thread->storeCondFailures = sc_failures; } ////////////////////////////////////////////////////////////// // @@ -837,9 +921,18 @@ class InOrderDynInst : public FastAlloc, public RefCounted /** Sets this instruction as entered on the CPU Reg Dep Map */ void setRegDepEntry() { status.set(RegDepMapEntry); } + /** Unsets this instruction as entered on the CPU Reg Dep Map */ + void clearRegDepEntry() { status.reset(RegDepMapEntry); } + /** Returns whether or not the entry is on the CPU Reg Dep Map */ bool isRegDepEntry() const { return status[RegDepMapEntry]; } + /** Sets this instruction as entered on the CPU Reg Dep Map */ + void setRemoveList() { status.set(RemoveList); } + + /** Returns whether or not the entry is on the CPU Reg Dep Map */ + bool isRemoveList() const { return status[RemoveList]; } + /** Sets this instruction as completed. */ void setCompleted() { status.set(Completed); } @@ -934,10 +1027,6 @@ class InOrderDynInst : public FastAlloc, public RefCounted */ bool eaCalcDone; - public: - /** Whether or not the memory operation is done. */ - bool memOpDone; - public: /** Load queue index. */ int16_t lqIdx; @@ -948,27 +1037,26 @@ class InOrderDynInst : public FastAlloc, public RefCounted /** Iterator pointing to this BaseDynInst in the list of all insts. */ ListIt instListIt; + bool onInstList; + /** Returns iterator to this instruction in the list of all insts. */ - ListIt &getInstListIt() { return instListIt; } + ListIt getInstListIt() { return instListIt; } /** Sets iterator for this instruction in the list of all insts. */ - void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; } + void setInstListIt(ListIt _instListIt) { onInstList = true; instListIt = _instListIt; } /** Count of total number of dynamic instructions. */ static int instcount; -#ifdef DEBUG - void dumpSNList(); -#endif - + void resetInstCount(); + /** Dumps out contents of this BaseDynInst. */ void dump(); /** Dumps out contents of this BaseDynInst into given string. */ void dump(std::string &outstring); - - //inline int curCount() { return curCount(); } + //inline int curCount() { return curCount(); } };