X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Finorder%2Finorder_dyn_inst.hh;h=f49476ec595c5d4763176918279bd8bdb12a4b5a;hb=e8e9f9731281e8c2ecb50a9aa318a65402cbee5c;hp=1a349676ffa869429c6f6778eae15ef1fc159cf0;hpb=f95430d97e0a9a77b920ab3ca24b134bc682f655;p=gem5.git diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh index 1a349676f..f49476ec5 100644 --- a/src/cpu/inorder/inorder_dyn_inst.hh +++ b/src/cpu/inorder/inorder_dyn_inst.hh @@ -41,20 +41,23 @@ #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 "base/types.hh" #include "config/full_system.hh" #include "config/the_isa.hh" -#include "cpu/exetrace.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/thread_context.hh" +#include "debug/InOrderDynInst.hh" #include "mem/packet.hh" #include "sim/system.hh" @@ -68,7 +71,6 @@ */ // Forward declaration. -class StaticInstPtr; class ResourceRequest; class Packet; @@ -86,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; @@ -99,21 +103,11 @@ 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. @@ -122,14 +116,6 @@ class InOrderDynInst : public FastAlloc, public RefCounted InOrderDynInst(InOrderCPU *cpu, InOrderThreadState *state, InstSeqNum seq_num, ThreadID tid, unsigned asid = 0); - /** BaseDynInst constructor given a StaticInst pointer. - * @param _staticInst The StaticInst for this BaseDynInst. - */ - InOrderDynInst(StaticInstPtr &_staticInst); - - /** Skeleton Constructor. */ - InOrderDynInst(); - /** InOrderDynInst destructor. */ ~InOrderDynInst(); @@ -137,8 +123,8 @@ 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 is entered onto the RegDepMap @@ -207,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; @@ -219,42 +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; - /** An instruction src/dest has to be one of these types */ - union InstValue { - uint64_t integer; - double dbl; - }; - - //@TODO: Naming Convention for Enums? enum ResultType { None, Integer, Float, + FloatBits, Double }; + /** An instruction src/dest has to be one of these types */ + struct InstValue { + IntReg intVal; + union { + FloatReg f; + FloatRegBits i; + } fpVal; + + InstValue() + { + intVal = 0; + fpVal.i = 0; + } + }; /** Result of an instruction execution */ struct InstResult { ResultType type; - InstValue val; + InstValue res; Tick tick; InstResult() - : type(None), tick(0) - {} + : type(None), tick(0) + { } }; /** The source of the instruction; assumes for now that there's only one @@ -268,33 +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; - - /** Predicted next NPC. */ - Addr predNPC; - - /** Predicted next microPC */ - Addr predMicroPC; - - /** 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. @@ -302,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. */ @@ -319,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(); @@ -333,7 +303,7 @@ class InOrderDynInst : public FastAlloc, public RefCounted PacketDataPtr splitMemData; RequestPtr splitMemReq; - int splitTotalSize; + int totalSize; int split2ndSize; Addr split2ndAddr; bool split2ndAccess; @@ -350,10 +320,12 @@ class InOrderDynInst : public FastAlloc, public RefCounted // BASE INSTRUCTION INFORMATION. // //////////////////////////////////////////////////////////// - std::string instName() { return staticInst->getName(); } + std::string instName() + { return (staticInst) ? staticInst->getName() : "undecoded-inst"; } + void setStaticInst(StaticInstPtr si); - void setMachInst(ExtMachInst inst); + ExtMachInst getMachInst() { return staticInst->machInst; } /** Sets the StaticInst. */ void setStaticInst(StaticInstPtr &static_inst); @@ -383,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(); } @@ -420,74 +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; + + RSkedPtr backSked; + RSkedIt backSked_end; - ThePipeline::InstStage *addStage(); - ThePipeline::InstStage *addStage(int stage); - ThePipeline::InstStage *currentStage() { return currentInstStage; } - void deleteStages(); + 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(); + } - /** Add A Entry To Reource Schedule */ - void addToSched(ThePipeline::ScheduleEntry* sched_entry) - { resSched.push(sched_entry); } + void setBackSked(RSkedPtr back_sked) + { + backSked = back_sked; + backSked_end.init(backSked); + backSked_end = backSked->end(); + } + void setNextStage(int stage_num) { nextStage = stage_num; } + int getNextStage() { return nextStage; } /** Print Resource Schedule */ - /** @NOTE: DEBUG ONLY */ - void printSched() + void printSked() { - ThePipeline::ResSchedule tempSched; - std::cerr << "\tInst. Res. Schedule: "; - while (!resSched.empty()) { - std::cerr << '\t' << resSched.top()->stageNum << "-" - << resSched.top()->resNum << ", "; - - tempSched.push(resSched.top()); - resSched.pop(); + 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(); - if (sked != 0) { - 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) */ @@ -518,13 +524,11 @@ class InOrderDynInst : public FastAlloc, public RefCounted void trap(Fault fault); bool simPalCheck(int palFunc); #else - /** Calls a syscall. */ - void syscall(int64_t callnum); + short syscallNum; #endif - void prefetch(Addr addr, unsigned flags); - void writeHint(Addr addr, int size, unsigned flags); - Fault copySrcTranslate(Addr src); - Fault copy(Addr dest); + + /** Emulates a syscall. */ + void syscall(int64_t callnum); //////////////////////////////////////////////////////////// // @@ -539,33 +543,14 @@ class InOrderDynInst : public FastAlloc, public RefCounted // //////////////////////////////////////////////////////////// /** 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; } + void pcState(const TheISA::PCState &_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() - { -#if ISA_HAS_DELAY_SLOT - return nextNPC; -#else - return nextPC + sizeof(TheISA::MachInst); -#endif - } - - /** 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(); } //////////////////////////////////////////////////////////// // @@ -573,38 +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 readPredPC() { return predPC; } + Addr predInstAddr() { return predPC.instAddr(); } /** Returns the predicted PC two instructions after the branch */ - Addr readPredNPC() { return predNPC; } + Addr predNextInstAddr() { return predPC.nextInstAddr(); } /** Returns the predicted micro PC after the branch */ - Addr readPredMicroPC() { return predMicroPC; } + 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() { -#if ISA_HAS_DELAY_SLOT - return predPC != nextNPC; -#else - return predPC != nextPC; -#endif + 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 @@ -621,32 +604,18 @@ 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); + + 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. @@ -709,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(); } @@ -744,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. */ @@ -808,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; } @@ -845,10 +843,10 @@ class InOrderDynInst : public FastAlloc, public RefCounted * source register to a value. */ void setIntSrc(int idx, uint64_t val); void setFloatSrc(int idx, FloatReg val); - void setFloatRegBitsSrc(int idx, uint64_t 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 @@ -870,20 +868,24 @@ class InOrderDynInst : public FastAlloc, public RefCounted return instResult[idx].type; } - uint64_t readIntResult(int idx) + IntReg readIntResult(int idx) + { + return instResult[idx].res.intVal; + } + + FloatReg readFloatResult(int idx) { - return instResult[idx].val.integer; + return instResult[idx].res.fpVal.f; } - /** Depending on type, return Float or Double */ - double readFloatResult(int idx) + FloatRegBits readFloatBitsResult(int idx) { - return instResult[idx].val.dbl; + 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. @@ -903,6 +905,10 @@ class InOrderDynInst : public FastAlloc, public RefCounted 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; } + /** Sets the number of consecutive store conditional failures. */ void setStCondFailures(unsigned sc_failures) { thread->storeCondFailures = sc_failures; } @@ -915,6 +921,9 @@ 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]; } @@ -1018,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; @@ -1032,11 +1037,13 @@ 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;