X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Fbase_dyn_inst.hh;h=031337aec32595800e31b817e52b48e4ed91981f;hb=be28d96510e0e722db83b26f1a12d3f5de979b32;hp=6aecd32dc7d36d06fec1647bfabc82ae0a6b36aa;hpb=2c293823aa7cb6d2cac4c0ff35e2023ff132a8f2;p=gem5.git diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 6aecd32dc..031337aec 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -46,16 +46,19 @@ #ifndef __CPU_BASE_DYN_INST_HH__ #define __CPU_BASE_DYN_INST_HH__ +#include #include #include #include #include +#include "arch/generic/tlb.hh" #include "arch/utility.hh" #include "base/trace.hh" #include "config/the_isa.hh" #include "cpu/checker/cpu.hh" #include "cpu/o3/comm.hh" +#include "cpu/exec_context.hh" #include "cpu/exetrace.hh" #include "cpu/inst_seq.hh" #include "cpu/op_class.hh" @@ -63,9 +66,7 @@ #include "cpu/translation.hh" #include "mem/packet.hh" #include "sim/byteswap.hh" -#include "sim/fault_fwd.hh" #include "sim/system.hh" -#include "sim/tlb.hh" /** * @file @@ -73,7 +74,7 @@ */ template -class BaseDynInst : public RefCounted +class BaseDynInst : public ExecContext, public RefCounted { public: // Typedef for the CPU. @@ -82,10 +83,6 @@ class BaseDynInst : public RefCounted // Logical register index type. typedef TheISA::RegIndex RegIndex; - // Integer register type. - typedef TheISA::IntReg IntReg; - // Floating point register type. - typedef TheISA::FloatReg FloatReg; // The DynInstPtr type. typedef typename Impl::DynInstPtr DynInstPtr; @@ -148,7 +145,7 @@ class BaseDynInst : public RefCounted * @todo: Consider if this is necessary or not. */ EACalcDone, - IsUncacheable, + IsStrictlyOrdered, ReqMade, MemOpDone, MaxFlags @@ -159,11 +156,13 @@ class BaseDynInst : public RefCounted InstSeqNum seqNum; /** The StaticInst used by this BaseDynInst. */ - StaticInstPtr staticInst; + const StaticInstPtr staticInst; /** Pointer to the Impl's CPU object. */ ImplCPU *cpu; + BaseCPU *getCpuPtr() { return cpu; } + /** Pointer to the thread state. */ ImplState *thread; @@ -205,7 +204,7 @@ class BaseDynInst : public RefCounted TheISA::PCState predPC; /** The Macroop if one exists */ - StaticInstPtr macroop; + const StaticInstPtr macroop; /** How many source registers are ready. */ uint8_t readyRegs; @@ -216,7 +215,12 @@ class BaseDynInst : public RefCounted Addr effAddr; /** The effective physical address. */ - Addr physEffAddr; + Addr physEffAddrLow; + + /** The effective physical address + * of the second request for a split request + */ + Addr physEffAddrHigh; /** The memory request flags (from translation). */ unsigned memReqFlags; @@ -260,22 +264,22 @@ class BaseDynInst : public RefCounted /** Flattened register index of the destination registers of this * instruction. */ - TheISA::RegIndex _flatDestRegIdx[TheISA::MaxInstDestRegs]; + std::array _flatDestRegIdx; /** Physical register index of the destination registers of this * instruction. */ - PhysRegIndex _destRegIdx[TheISA::MaxInstDestRegs]; + std::array _destRegIdx; /** Physical register index of the source registers of this * instruction. */ - PhysRegIndex _srcRegIdx[TheISA::MaxInstSrcRegs]; + std::array _srcRegIdx; /** Physical register index of the previous producers of the * architected destinations. */ - PhysRegIndex _prevDestRegIdx[TheISA::MaxInstDestRegs]; + std::array _prevDestRegIdx; public: @@ -309,7 +313,7 @@ class BaseDynInst : public RefCounted cpu->demapPage(vaddr, asn); } - Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags); + Fault initiateMemRead(Addr addr, unsigned size, unsigned flags); Fault writeMem(uint8_t *data, unsigned size, Addr addr, unsigned flags, uint64_t *res); @@ -428,14 +432,14 @@ class BaseDynInst : public RefCounted * @param seq_num The sequence number of the instruction. * @param cpu Pointer to the instruction's CPU. */ - BaseDynInst(StaticInstPtr staticInst, StaticInstPtr macroop, + BaseDynInst(const StaticInstPtr &staticInst, const StaticInstPtr ¯oop, TheISA::PCState pc, TheISA::PCState predPC, InstSeqNum seq_num, ImplCPU *cpu); /** BaseDynInst constructor given a StaticInst pointer. * @param _staticInst The StaticInst for this BaseDynInst. */ - BaseDynInst(StaticInstPtr staticInst, StaticInstPtr macroop); + BaseDynInst(const StaticInstPtr &staticInst, const StaticInstPtr ¯oop); /** BaseDynInst destructor. */ ~BaseDynInst(); @@ -452,16 +456,19 @@ class BaseDynInst : public RefCounted void dump(std::string &outstring); /** Read this CPU's ID. */ - int cpuId() { return cpu->cpuId(); } + int cpuId() const { return cpu->cpuId(); } + + /** Read this CPU's Socket ID. */ + uint32_t socketId() const { return cpu->socketId(); } /** Read this CPU's data requestor ID */ - MasterID masterId() { return cpu->dataMasterId(); } + MasterID masterId() const { return cpu->dataMasterId(); } /** Read this context's system-wide ID **/ - int contextId() { return thread->contextId(); } + ContextID contextId() const { return thread->contextId(); } /** Returns the fault type. */ - Fault getFault() { return fault; } + Fault getFault() const { 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 @@ -593,6 +600,7 @@ class BaseDynInst : public RefCounted // for machines with separate int & FP reg files int8_t numFPDestRegs() const { return staticInst->numFPDestRegs(); } int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); } + int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); } /** Returns the logical register index of the i'th destination register. */ RegIndex destRegIdx(int i) const { return staticInst->destRegIdx(i); } @@ -629,28 +637,17 @@ class BaseDynInst : public RefCounted } /** Records an integer register being set to a value. */ - void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) + void setIntRegOperand(const StaticInst *si, int idx, IntReg val) { setResult(val); } /** Records a CC register being set to a value. */ - void setCCRegOperand(const StaticInst *si, int idx, uint64_t val) + void setCCRegOperand(const StaticInst *si, int idx, CCReg val) { setResult(val); } - /** Records an fp register being set to a value. */ - void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, - int width) - { - if (width == 32 || width == 64) { - setResult(val); - } else { - panic("Unsupported width!"); - } - } - /** Records an fp register being set to a value. */ void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) { @@ -658,14 +655,7 @@ class BaseDynInst : public RefCounted } /** Records an fp register being set to an integer value. */ - void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val, - int width) - { - setResult(val); - } - - /** Records an fp register being set to an integer value. */ - void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val) + void setFloatRegOperandBits(const StaticInst *si, int idx, FloatRegBits val) { setResult(val); } @@ -797,19 +787,19 @@ class BaseDynInst : public RefCounted bool isSquashedInROB() const { return status[SquashedInROB]; } /** Read the PC state of this instruction. */ - const TheISA::PCState pcState() const { return pc; } + TheISA::PCState pcState() const { return pc; } /** Set the PC state of this instruction. */ - const void pcState(const TheISA::PCState &val) { pc = val; } + void pcState(const TheISA::PCState &val) { pc = val; } /** Read the PC of this instruction. */ - const Addr instAddr() const { return pc.instAddr(); } + Addr instAddr() const { return pc.instAddr(); } /** Read the PC of the next instruction. */ - const Addr nextInstAddr() const { return pc.nextInstAddr(); } + Addr nextInstAddr() const { return pc.nextInstAddr(); } /**Read the micro PC of this instruction. */ - const Addr microPC() const { return pc.microPC(); } + Addr microPC() const { return pc.microPC(); } bool readPredicate() { @@ -839,10 +829,10 @@ class BaseDynInst : public RefCounted public: /** Sets the effective address. */ - void setEA(Addr &ea) { instEffAddr = ea; instFlags[EACalcDone] = true; } + void setEA(Addr ea) { instEffAddr = ea; instFlags[EACalcDone] = true; } /** Returns the effective address. */ - const Addr &getEA() const { return instEffAddr; } + Addr getEA() const { return instEffAddr; } /** Returns whether or not the eff. addr. calculation has been completed. */ bool doneEACalc() { return instFlags[EACalcDone]; } @@ -850,8 +840,8 @@ class BaseDynInst : public RefCounted /** Returns whether or not the eff. addr. source registers are ready. */ bool eaSrcsReady(); - /** Is this instruction's memory access uncacheable. */ - bool uncacheable() { return instFlags[IsUncacheable]; } + /** Is this instruction's memory access strictly ordered? */ + bool strictlyOrdered() const { return instFlags[IsStrictlyOrdered]; } /** Has this instruction generated a memory request. */ bool hasRequest() { return instFlags[ReqMade]; } @@ -864,18 +854,26 @@ class BaseDynInst : public RefCounted public: /** Returns the number of consecutive store conditional failures. */ - unsigned readStCondFailures() + unsigned int readStCondFailures() const { return thread->storeCondFailures; } /** Sets the number of consecutive store conditional failures. */ - void setStCondFailures(unsigned sc_failures) + void setStCondFailures(unsigned int sc_failures) { thread->storeCondFailures = sc_failures; } + + public: + // monitor/mwait funtions + void armMonitor(Addr address) { cpu->armMonitor(threadNumber, address); } + bool mwait(PacketPtr pkt) { return cpu->mwait(threadNumber, pkt); } + void mwaitAtomic(ThreadContext *tc) + { return cpu->mwaitAtomic(threadNumber, tc, cpu->dtb); } + AddressMonitor *getAddrMonitor() + { return cpu->getCpuAddrMonitor(threadNumber); } }; template Fault -BaseDynInst::readMem(Addr addr, uint8_t *data, - unsigned size, unsigned flags) +BaseDynInst::initiateMemRead(Addr addr, unsigned size, unsigned flags) { instFlags[ReqMade] = true; Request *req = NULL; @@ -890,6 +888,8 @@ BaseDynInst::readMem(Addr addr, uint8_t *data, req = new Request(asid, addr, size, flags, masterId(), this->pc.instAddr(), thread->contextId(), threadNumber); + req->taskId(cpu->taskId()); + // Only split the request if the ISA supports unaligned accesses. if (TheISA::HasUnalignedMemAcc) { splitRequest(req, sreqLow, sreqHigh); @@ -909,24 +909,16 @@ BaseDynInst::readMem(Addr addr, uint8_t *data, } reqToVerify = new Request(*req); } - fault = cpu->read(req, sreqLow, sreqHigh, data, lqIdx); + fault = cpu->read(req, sreqLow, sreqHigh, lqIdx); } else { // Commit will have to clean up whatever happened. Set this // instruction as executed. this->setExecuted(); } - - if (fault != NoFault) { - // Return a fixed value to keep simulation deterministic even - // along misspeculated paths. - if (data) - bzero(data, size); - } } - if (traceData) { - traceData->setAddr(addr); - } + if (traceData) + traceData->setMem(addr, size, flags); return fault; } @@ -936,9 +928,8 @@ Fault BaseDynInst::writeMem(uint8_t *data, unsigned size, Addr addr, unsigned flags, uint64_t *res) { - if (traceData) { - traceData->setAddr(addr); - } + if (traceData) + traceData->setMem(addr, size, flags); instFlags[ReqMade] = true; Request *req = NULL; @@ -953,6 +944,8 @@ BaseDynInst::writeMem(uint8_t *data, unsigned size, req = new Request(asid, addr, size, flags, masterId(), this->pc.instAddr(), thread->contextId(), threadNumber); + req->taskId(cpu->taskId()); + // Only split the request if the ISA supports unaligned accesses. if (TheISA::HasUnalignedMemAcc) { splitRequest(req, sreqLow, sreqHigh); @@ -1009,8 +1002,16 @@ BaseDynInst::initiateTranslation(RequestPtr req, RequestPtr sreqLow, // One translation if the request isn't split. DataTranslation *trans = new DataTranslation(this, state); + cpu->dtb->translateTiming(req, thread->getTC(), trans, mode); + if (!translationCompleted()) { + // The translation isn't yet complete, so we can't possibly have a + // fault. Overwrite any existing fault we might have from a previous + // execution of this instruction (e.g. an uncachable load that + // couldn't execute because it wasn't at the head of the ROB). + fault = NoFault; + // Save memory requests. savedReq = state->mainReq; savedSreqLow = state->sreqLow; @@ -1028,7 +1029,14 @@ BaseDynInst::initiateTranslation(RequestPtr req, RequestPtr sreqLow, cpu->dtb->translateTiming(sreqLow, thread->getTC(), stransLow, mode); cpu->dtb->translateTiming(sreqHigh, thread->getTC(), stransHigh, mode); + if (!translationCompleted()) { + // The translation isn't yet complete, so we can't possibly have a + // fault. Overwrite any existing fault we might have from a previous + // execution of this instruction (e.g. an uncachable load that + // couldn't execute because it wasn't at the head of the ROB). + fault = NoFault; + // Save memory requests. savedReq = state->mainReq; savedSreqLow = state->sreqLow; @@ -1043,10 +1051,18 @@ BaseDynInst::finishTranslation(WholeTranslationState *state) { fault = state->getFault(); - instFlags[IsUncacheable] = state->isUncacheable(); + instFlags[IsStrictlyOrdered] = state->isStrictlyOrdered(); if (fault == NoFault) { - physEffAddr = state->getPaddr(); + // save Paddr for a single req + physEffAddrLow = state->getPaddr(); + + // case for the request that has been split + if (state->isSplit) { + physEffAddrLow = state->sreqLow->getPaddr(); + physEffAddrHigh = state->sreqHigh->getPaddr(); + } + memReqFlags = state->getFlags(); if (state->mainReq->isCondSwap()) {