X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Fbase_dyn_inst.hh;h=6d9a5325332387808e395b1d688fe432b037d28f;hb=8d476b41e60cfdadbde50c2d9ae54900455f6098;hp=9089d1069ad1b5ee439e7b540e62dd5dce675427;hpb=c3d41a2def15cdaf2ac3984315f452dacc6a0884;p=gem5.git diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 9089d1069..6d9a53253 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -1,5 +1,6 @@ /* - * Copyright (c) 2011 ARM Limited + * Copyright (c) 2011,2013 ARM Limited + * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -45,25 +46,28 @@ #ifndef __CPU_BASE_DYN_INST_HH__ #define __CPU_BASE_DYN_INST_HH__ +#include #include #include #include +#include -#include "arch/faults.hh" +#include "arch/generic/tlb.hh" #include "arch/utility.hh" -#include "base/fast_alloc.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" #include "cpu/static_inst.hh" #include "cpu/translation.hh" #include "mem/packet.hh" +#include "mem/request.hh" #include "sim/byteswap.hh" #include "sim/system.hh" -#include "sim/tlb.hh" /** * @file @@ -71,7 +75,7 @@ */ template -class BaseDynInst : public FastAlloc, public RefCounted +class BaseDynInst : public ExecContext, public RefCounted { public: // Typedef for the CPU. @@ -80,10 +84,6 @@ class BaseDynInst : public FastAlloc, 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; @@ -94,92 +94,19 @@ class BaseDynInst : public FastAlloc, public RefCounted enum { MaxInstSrcRegs = TheISA::MaxInstSrcRegs, /// Max source regs - MaxInstDestRegs = TheISA::MaxInstDestRegs, /// Max dest regs + MaxInstDestRegs = TheISA::MaxInstDestRegs /// Max dest regs }; - /** The StaticInst used by this BaseDynInst. */ - StaticInstPtr staticInst; - StaticInstPtr macroop; - - //////////////////////////////////////////// - // - // INSTRUCTION EXECUTION - // - //////////////////////////////////////////// - /** InstRecord that tracks this instructions. */ - Trace::InstRecord *traceData; - - void demapPage(Addr vaddr, uint64_t asn) - { - cpu->demapPage(vaddr, asn); - } - void demapInstPage(Addr vaddr, uint64_t asn) - { - cpu->demapPage(vaddr, asn); - } - void demapDataPage(Addr vaddr, uint64_t asn) - { - cpu->demapPage(vaddr, asn); - } - - 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); - - /** Splits a request in two if it crosses a dcache block. */ - void splitRequest(RequestPtr req, RequestPtr &sreqLow, - RequestPtr &sreqHigh); - - /** Initiate a DTB address translation. */ - void initiateTranslation(RequestPtr req, RequestPtr sreqLow, - RequestPtr sreqHigh, uint64_t *res, - BaseTLB::Mode mode); - - /** Finish a DTB address translation. */ - void finishTranslation(WholeTranslationState *state); - - /** True if the DTB address translation has started. */ - bool translationStarted; - - /** True if the DTB address translation has completed. */ - bool translationCompleted; - - /** True if this address was found to match a previous load and they issued - * out of order. If that happend, then it's only a problem if an incoming - * snoop invalidate modifies the line, in which case we need to squash. - * If nothing modified the line the order doesn't matter. - */ - bool possibleLoadViolation; - - /** True if the address hit a external snoop while sitting in the LSQ. - * If this is true and a older instruction sees it, this instruction must - * reexecute - */ - bool hitExternalSnoop; - - /** - * Returns true if the DTB address translation is being delayed due to a hw - * page table walk. - */ - bool isTranslationDelayed() const - { - return (translationStarted && !translationCompleted); - } - - /** - * Saved memory requests (needed when the DTB address translation is - * delayed due to a hw page table walk). - */ - RequestPtr savedReq; - RequestPtr savedSreqLow; - RequestPtr savedSreqHigh; - - /** @todo: Consider making this private. */ - public: - /** The sequence number of the instruction. */ - InstSeqNum seqNum; + union Result { + uint64_t integer; + double dbl; + void set(uint64_t i) { integer = i; } + void set(double d) { dbl = d; } + void get(uint64_t& i) { i = integer; } + void get(double& d) { d = dbl; } + }; + protected: enum Status { IqEntry, /// Instruction is in the IQ RobEntry, /// Instruction is in the ROB @@ -206,110 +133,240 @@ class BaseDynInst : public FastAlloc, public RefCounted NumStatus }; - /** The status of this BaseDynInst. Several bits can be set. */ - std::bitset status; - - /** The thread this instruction is from. */ - ThreadID threadNumber; + enum Flags { + TranslationStarted, + TranslationCompleted, + PossibleLoadViolation, + HitExternalSnoop, + EffAddrValid, + RecordResult, + Predicate, + PredTaken, + /** Whether or not the effective address calculation is completed. + * @todo: Consider if this is necessary or not. + */ + EACalcDone, + IsStrictlyOrdered, + ReqMade, + MemOpDone, + MaxFlags + }; - /** data address space ID, for loads & stores. */ - short asid; + public: + /** The sequence number of the instruction. */ + InstSeqNum seqNum; - /** How many source registers are ready. */ - unsigned readyRegs; + /** The StaticInst used by this BaseDynInst. */ + const StaticInstPtr staticInst; /** Pointer to the Impl's CPU object. */ ImplCPU *cpu; + BaseCPU *getCpuPtr() { return cpu; } + /** Pointer to the thread state. */ ImplState *thread; /** The kind of fault this instruction has generated. */ Fault fault; - /** Pointer to the data for the memory access. */ - uint8_t *memData; + /** InstRecord that tracks this instructions. */ + Trace::InstRecord *traceData; - /** The effective virtual address (lds & stores only). */ - Addr effAddr; + protected: + /** The result of the instruction; assumes an instruction can have many + * destination registers. + */ + std::queue instResult; - /** The size of the request */ - Addr effSize; + /** PC state for this instruction. */ + TheISA::PCState pc; - /** Is the effective virtual address valid. */ - bool effAddrValid; + /* An amalgamation of a lot of boolean values into one */ + std::bitset instFlags; + + /** The status of this BaseDynInst. Several bits can be set. */ + std::bitset status; + + /** Whether or not the source register is ready. + * @todo: Not sure this should be here vs the derived class. + */ + std::bitset _readySrcRegIdx; + + public: + /** The thread this instruction is from. */ + ThreadID threadNumber; + + /** Iterator pointing to this BaseDynInst in the list of all insts. */ + ListIt instListIt; + + ////////////////////// Branch Data /////////////// + /** Predicted PC state after this instruction. */ + TheISA::PCState predPC; + + /** The Macroop if one exists */ + const StaticInstPtr macroop; + + /** How many source registers are ready. */ + uint8_t readyRegs; + + public: + /////////////////////// Load Store Data ////////////////////// + /** The effective virtual address (lds & stores only). */ + 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; - 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; + /** data address space ID, for loads & stores. */ + short asid; - /** Records changes to result? */ - bool recordResult; + /** The size of the request */ + uint8_t effSize; - /** Did this instruction execute, or is it predicated false */ - bool predicate; + /** Pointer to the data for the memory access. */ + uint8_t *memData; - protected: - /** PC state for this instruction. */ - TheISA::PCState pc; + /** Load queue index. */ + int16_t lqIdx; - /** Predicted PC state after this instruction. */ - TheISA::PCState predPC; + /** Store queue index. */ + int16_t sqIdx; - /** If this is a branch that was predicted taken */ - bool predTaken; - public: + /////////////////////// TLB Miss ////////////////////// + /** + * Saved memory requests (needed when the DTB address translation is + * delayed due to a hw page table walk). + */ + RequestPtr savedReq; + RequestPtr savedSreqLow; + RequestPtr savedSreqHigh; -#ifdef DEBUG - void dumpSNList(); -#endif + /////////////////////// Checker ////////////////////// + // Need a copy of main request pointer to verify on writes. + RequestPtr reqToVerify; - /** Whether or not the source register is ready. - * @todo: Not sure this should be here vs the derived class. + private: + /** Instruction effective address. + * @todo: Consider if this is necessary or not. */ - bool _readySrcRegIdx[MaxInstSrcRegs]; + Addr instEffAddr; protected: /** 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]; + 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: + /** Records changes to result? */ + void recordResult(bool f) { instFlags[RecordResult] = f; } + + /** Is the effective virtual address valid. */ + bool effAddrValid() const { return instFlags[EffAddrValid]; } + + /** Whether or not the memory operation is done. */ + bool memOpDone() const { return instFlags[MemOpDone]; } + void memOpDone(bool f) { instFlags[MemOpDone] = f; } + + + //////////////////////////////////////////// + // + // INSTRUCTION EXECUTION + // + //////////////////////////////////////////// + + void demapPage(Addr vaddr, uint64_t asn) + { + cpu->demapPage(vaddr, asn); + } + void demapInstPage(Addr vaddr, uint64_t asn) + { + cpu->demapPage(vaddr, asn); + } + void demapDataPage(Addr vaddr, uint64_t asn) + { + cpu->demapPage(vaddr, asn); + } + + Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags); + + Fault writeMem(uint8_t *data, unsigned size, Addr addr, + Request::Flags flags, uint64_t *res); + + /** Splits a request in two if it crosses a dcache block. */ + void splitRequest(RequestPtr req, RequestPtr &sreqLow, + RequestPtr &sreqHigh); + + /** Initiate a DTB address translation. */ + void initiateTranslation(RequestPtr req, RequestPtr sreqLow, + RequestPtr sreqHigh, uint64_t *res, + BaseTLB::Mode mode); + + /** Finish a DTB address translation. */ + void finishTranslation(WholeTranslationState *state); + + /** True if the DTB address translation has started. */ + bool translationStarted() const { return instFlags[TranslationStarted]; } + void translationStarted(bool f) { instFlags[TranslationStarted] = f; } + + /** True if the DTB address translation has completed. */ + bool translationCompleted() const { return instFlags[TranslationCompleted]; } + void translationCompleted(bool f) { instFlags[TranslationCompleted] = f; } + + /** True if this address was found to match a previous load and they issued + * out of order. If that happend, then it's only a problem if an incoming + * snoop invalidate modifies the line, in which case we need to squash. + * If nothing modified the line the order doesn't matter. + */ + bool possibleLoadViolation() const { return instFlags[PossibleLoadViolation]; } + void possibleLoadViolation(bool f) { instFlags[PossibleLoadViolation] = f; } + + /** True if the address hit a external snoop while sitting in the LSQ. + * If this is true and a older instruction sees it, this instruction must + * reexecute + */ + bool hitExternalSnoop() const { return instFlags[HitExternalSnoop]; } + void hitExternalSnoop(bool f) { instFlags[HitExternalSnoop] = f; } + + /** + * Returns true if the DTB address translation is being delayed due to a hw + * page table walk. + */ + bool isTranslationDelayed() const + { + return (translationStarted() && !translationCompleted()); + } public: +#ifdef DEBUG + void dumpSNList(); +#endif /** Returns the physical register index of the i'th destination * register. @@ -322,6 +379,7 @@ class BaseDynInst : public FastAlloc, public RefCounted /** Returns the physical register index of the i'th source register. */ PhysRegIndex renamedSrcRegIdx(int idx) const { + assert(TheISA::MaxInstSrcRegs > idx); return _srcRegIdx[idx]; } @@ -333,12 +391,6 @@ class BaseDynInst : public FastAlloc, public RefCounted 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. */ @@ -367,13 +419,6 @@ class BaseDynInst : public FastAlloc, public RefCounted _srcRegIdx[idx] = renamed_src; } - /** 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. */ @@ -388,14 +433,14 @@ class BaseDynInst : public FastAlloc, 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(); @@ -412,13 +457,19 @@ class BaseDynInst : public FastAlloc, 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() 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 @@ -447,12 +498,12 @@ class BaseDynInst : public FastAlloc, public RefCounted /** Returns whether the instruction was predicted taken or not. */ bool readPredTaken() { - return predTaken; + return instFlags[PredTaken]; } void setPredTaken(bool predicted_taken) { - predTaken = predicted_taken; + instFlags[PredTaken] = predicted_taken; } /** Returns whether the instruction mispredicted. */ @@ -550,6 +601,7 @@ class BaseDynInst : public FastAlloc, 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); } @@ -557,56 +609,56 @@ class BaseDynInst : public FastAlloc, public RefCounted /** 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; } + /** Pops a result off the instResult queue */ + template + void popResult(T& t) + { + if (!instResult.empty()) { + instResult.front().get(t); + instResult.pop(); + } + } - /** Returns the result of a floating point instruction. */ - float readFloatResult() { return (float)instResult.dbl; } + /** Read the most recent result stored by this instruction */ + template + void readResult(T& t) + { + instResult.back().get(t); + } - /** Returns the result of a floating point (double) instruction. */ - double readDoubleResult() { return instResult.dbl; } + /** Pushes a result onto the instResult queue */ + template + void setResult(T t) + { + if (instFlags[RecordResult]) { + Result instRes; + instRes.set(t); + instResult.push(instRes); + } + } /** 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) { - if (recordResult) - instResult.integer = val; + setResult(val); } - /** Records an fp register being set to a value. */ - void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, - int width) + /** Records a CC register being set to a value. */ + void setCCRegOperand(const StaticInst *si, int idx, CCReg val) { - if (recordResult) { - if (width == 32) - instResult.dbl = (double)val; - else if (width == 64) - instResult.dbl = val; - else - panic("Unsupported width!"); - } + setResult(val); } /** Records an fp register being set to a value. */ void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) { - if (recordResult) - instResult.dbl = (double)val; + setResult(val); } /** Records an fp register being set to an integer value. */ - void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val, - int width) + void setFloatRegOperandBits(const StaticInst *si, int idx, FloatRegBits val) { - if (recordResult) - instResult.integer = val; - } - - /** Records an fp register being set to an integer value. */ - void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val) - { - if (recordResult) - instResult.integer = val; + setResult(val); } /** Records that one of the source registers is ready. */ @@ -736,28 +788,28 @@ class BaseDynInst : public FastAlloc, 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() { - return predicate; + return instFlags[Predicate]; } void setPredicate(bool val) { - predicate = val; + instFlags[Predicate] = val; if (traceData) { traceData->setPredicate(val); @@ -776,54 +828,24 @@ class BaseDynInst : public FastAlloc, public RefCounted /** Returns the thread context. */ ThreadContext *tcBase() { return thread->getTC(); } - 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; - - /** Is this instruction's memory access uncacheable. */ - bool isUncacheable; - - /** Has this instruction generated a memory request. */ - bool reqMade; - public: /** Sets the effective address. */ - void setEA(Addr &ea) { instEffAddr = ea; 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 eaCalcDone; } + bool doneEACalc() { return instFlags[EACalcDone]; } /** Returns whether or not the eff. addr. source registers are ready. */ bool eaSrcsReady(); - /** Whether or not the memory operation is done. */ - bool memOpDone; - - /** Is this instruction's memory access uncacheable. */ - bool uncacheable() { return 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 reqMade; } - - 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; + bool hasRequest() { return instFlags[ReqMade]; } /** Returns iterator to this instruction in the list of all insts. */ ListIt &getInstListIt() { return instListIt; } @@ -833,31 +855,42 @@ class BaseDynInst : public FastAlloc, 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, + Request::Flags flags) { - reqMade = true; + instFlags[ReqMade] = true; Request *req = NULL; Request *sreqLow = NULL; Request *sreqHigh = NULL; - if (reqMade && translationStarted) { + if (instFlags[ReqMade] && translationStarted()) { req = savedReq; sreqLow = savedSreqLow; sreqHigh = savedSreqHigh; } else { - req = new Request(asid, addr, size, flags, this->pc.instAddr(), - thread->contextId(), threadNumber); + req = new Request(asid, addr, size, flags, masterId(), this->pc.instAddr(), + thread->contextId()); + + req->taskId(cpu->taskId()); // Only split the request if the ISA supports unaligned accesses. if (TheISA::HasUnalignedMemAcc) { @@ -866,54 +899,54 @@ BaseDynInst::readMem(Addr addr, uint8_t *data, initiateTranslation(req, sreqLow, sreqHigh, NULL, BaseTLB::Read); } - if (translationCompleted) { + if (translationCompleted()) { if (fault == NoFault) { effAddr = req->getVaddr(); effSize = size; - effAddrValid = true; - fault = cpu->read(req, sreqLow, sreqHigh, data, lqIdx); + instFlags[EffAddrValid] = true; + + if (cpu->checker) { + if (reqToVerify != NULL) { + delete reqToVerify; + } + reqToVerify = new Request(*req); + } + 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; } template Fault -BaseDynInst::writeMem(uint8_t *data, unsigned size, - Addr addr, unsigned flags, uint64_t *res) +BaseDynInst::writeMem(uint8_t *data, unsigned size, Addr addr, + Request::Flags flags, uint64_t *res) { - if (traceData) { - traceData->setAddr(addr); - } + if (traceData) + traceData->setMem(addr, size, flags); - reqMade = true; + instFlags[ReqMade] = true; Request *req = NULL; Request *sreqLow = NULL; Request *sreqHigh = NULL; - if (reqMade && translationStarted) { + if (instFlags[ReqMade] && translationStarted()) { req = savedReq; sreqLow = savedSreqLow; sreqHigh = savedSreqHigh; } else { - req = new Request(asid, addr, size, flags, this->pc.instAddr(), - thread->contextId(), threadNumber); + req = new Request(asid, addr, size, flags, masterId(), this->pc.instAddr(), + thread->contextId()); + + req->taskId(cpu->taskId()); // Only split the request if the ISA supports unaligned accesses. if (TheISA::HasUnalignedMemAcc) { @@ -922,10 +955,17 @@ BaseDynInst::writeMem(uint8_t *data, unsigned size, initiateTranslation(req, sreqLow, sreqHigh, res, BaseTLB::Write); } - if (fault == NoFault && translationCompleted) { + if (fault == NoFault && translationCompleted()) { effAddr = req->getVaddr(); effSize = size; - effAddrValid = true; + instFlags[EffAddrValid] = true; + + if (cpu->checker) { + if (reqToVerify != NULL) { + delete reqToVerify; + } + reqToVerify = new Request(*req); + } fault = cpu->write(req, sreqLow, sreqHigh, data, sqIdx); } @@ -938,7 +978,7 @@ BaseDynInst::splitRequest(RequestPtr req, RequestPtr &sreqLow, RequestPtr &sreqHigh) { // Check to see if the request crosses the next level block boundary. - unsigned block_size = cpu->getDcachePort()->peerBlockSize(); + unsigned block_size = cpu->cacheLineSize(); Addr addr = req->getVaddr(); Addr split_addr = roundDown(addr + req->getSize() - 1, block_size); assert(split_addr <= addr || split_addr - addr < block_size); @@ -955,7 +995,7 @@ BaseDynInst::initiateTranslation(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh, uint64_t *res, BaseTLB::Mode mode) { - translationStarted = true; + translationStarted(true); if (!TheISA::HasUnalignedMemAcc || sreqLow == NULL) { WholeTranslationState *state = @@ -964,8 +1004,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) { + + 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; @@ -983,7 +1031,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) { + + 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; @@ -998,11 +1053,18 @@ BaseDynInst::finishTranslation(WholeTranslationState *state) { fault = state->getFault(); - if (state->isUncacheable()) - isUncacheable = true; + 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()) { @@ -1015,7 +1077,7 @@ BaseDynInst::finishTranslation(WholeTranslationState *state) } delete state; - translationCompleted = true; + translationCompleted(true); } #endif // __CPU_BASE_DYN_INST_HH__