base_dyn_inst.hh revision 2665
11060SN/A/*
21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
31060SN/A * All rights reserved.
41060SN/A *
51060SN/A * Redistribution and use in source and binary forms, with or without
61060SN/A * modification, are permitted provided that the following conditions are
71060SN/A * met: redistributions of source code must retain the above copyright
81060SN/A * notice, this list of conditions and the following disclaimer;
91060SN/A * redistributions in binary form must reproduce the above copyright
101060SN/A * notice, this list of conditions and the following disclaimer in the
111060SN/A * documentation and/or other materials provided with the distribution;
121060SN/A * neither the name of the copyright holders nor the names of its
131060SN/A * contributors may be used to endorse or promote products derived from
141060SN/A * this software without specific prior written permission.
151060SN/A *
161060SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171060SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181060SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191060SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201060SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211060SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221060SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231060SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241060SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Kevin Lim
291060SN/A */
301060SN/A
311464SN/A#ifndef __CPU_BASE_DYN_INST_HH__
321464SN/A#define __CPU_BASE_DYN_INST_HH__
331060SN/A
341464SN/A#include <string>
351060SN/A#include <vector>
361060SN/A
371060SN/A#include "base/fast_alloc.hh"
381060SN/A#include "base/trace.hh"
391858SN/A#include "config/full_system.hh"
401464SN/A#include "cpu/exetrace.hh"
411464SN/A#include "cpu/inst_seq.hh"
421717SN/A#include "cpu/o3/comm.hh"
431060SN/A#include "cpu/static_inst.hh"
441717SN/A#include "encumbered/cpu/full/bpred_update.hh"
451717SN/A#include "encumbered/cpu/full/op_class.hh"
461717SN/A#include "encumbered/cpu/full/spec_memory.hh"
471717SN/A#include "encumbered/cpu/full/spec_state.hh"
481717SN/A#include "encumbered/mem/functional/main.hh"
491060SN/A
501060SN/A/**
511060SN/A * @file
521060SN/A * Defines a dynamic instruction context.
531060SN/A */
541060SN/A
551061SN/A// Forward declaration.
561061SN/Aclass StaticInstPtr;
571060SN/A
581060SN/Atemplate <class Impl>
591061SN/Aclass BaseDynInst : public FastAlloc, public RefCounted
601060SN/A{
611060SN/A  public:
621060SN/A    // Typedef for the CPU.
631060SN/A    typedef typename Impl::FullCPU FullCPU;
641060SN/A
651060SN/A    /// Binary machine instruction type.
662107SN/A    typedef TheISA::MachInst MachInst;
671060SN/A    /// Logical register index type.
682107SN/A    typedef TheISA::RegIndex RegIndex;
691060SN/A    /// Integer register index type.
702107SN/A    typedef TheISA::IntReg IntReg;
711060SN/A
721060SN/A    enum {
732107SN/A        MaxInstSrcRegs = TheISA::MaxInstSrcRegs,        //< Max source regs
742107SN/A        MaxInstDestRegs = TheISA::MaxInstDestRegs,      //< Max dest regs
751060SN/A    };
761060SN/A
771684SN/A    /** The static inst used by this dyn inst. */
782107SN/A    StaticInstPtr staticInst;
791060SN/A
801060SN/A    ////////////////////////////////////////////
811060SN/A    //
821060SN/A    // INSTRUCTION EXECUTION
831060SN/A    //
841060SN/A    ////////////////////////////////////////////
851060SN/A    Trace::InstRecord *traceData;
861060SN/A
871060SN/A    template <class T>
882132SN/A    Fault read(Addr addr, T &data, unsigned flags);
891060SN/A
901060SN/A    template <class T>
912132SN/A    Fault write(T data, Addr addr, unsigned flags,
921060SN/A                        uint64_t *res);
931060SN/A
941060SN/A    void prefetch(Addr addr, unsigned flags);
951060SN/A    void writeHint(Addr addr, int size, unsigned flags);
962132SN/A    Fault copySrcTranslate(Addr src);
972132SN/A    Fault copy(Addr dest);
981060SN/A
991684SN/A    /** @todo: Consider making this private. */
1001060SN/A  public:
1011060SN/A    /** Is this instruction valid. */
1021060SN/A    bool valid;
1031060SN/A
1041060SN/A    /** The sequence number of the instruction. */
1051060SN/A    InstSeqNum seqNum;
1061060SN/A
1071060SN/A    /** How many source registers are ready. */
1081060SN/A    unsigned readyRegs;
1091060SN/A
1101464SN/A    /** Is the instruction completed. */
1111464SN/A    bool completed;
1121464SN/A
1131060SN/A    /** Can this instruction issue. */
1141060SN/A    bool canIssue;
1151060SN/A
1161060SN/A    /** Has this instruction issued. */
1171060SN/A    bool issued;
1181060SN/A
1191060SN/A    /** Has this instruction executed (or made it through execute) yet. */
1201060SN/A    bool executed;
1211060SN/A
1221060SN/A    /** Can this instruction commit. */
1231060SN/A    bool canCommit;
1241060SN/A
1251060SN/A    /** Is this instruction squashed. */
1261060SN/A    bool squashed;
1271060SN/A
1281060SN/A    /** Is this instruction squashed in the instruction queue. */
1291060SN/A    bool squashedInIQ;
1301060SN/A
1311060SN/A    /** Is this a recover instruction. */
1321060SN/A    bool recoverInst;
1331060SN/A
1341060SN/A    /** Is this a thread blocking instruction. */
1351060SN/A    bool blockingInst;	/* this inst has called thread_block() */
1361060SN/A
1371060SN/A    /** Is this a thread syncrhonization instruction. */
1381060SN/A    bool threadsyncWait;
1391060SN/A
1401060SN/A    /** The thread this instruction is from. */
1411060SN/A    short threadNumber;
1421060SN/A
1431060SN/A    /** data address space ID, for loads & stores. */
1441060SN/A    short asid;
1451060SN/A
1461060SN/A    /** Pointer to the FullCPU object. */
1471060SN/A    FullCPU *cpu;
1481060SN/A
1491060SN/A    /** Pointer to the exec context.  Will not exist in the final version. */
1502190SN/A    CPUExecContext *cpuXC;
1511060SN/A
1521060SN/A    /** The kind of fault this instruction has generated. */
1532132SN/A    Fault fault;
1541060SN/A
1551060SN/A    /** The effective virtual address (lds & stores only). */
1561060SN/A    Addr effAddr;
1571060SN/A
1581060SN/A    /** The effective physical address. */
1591060SN/A    Addr physEffAddr;
1601060SN/A
1611060SN/A    /** Effective virtual address for a copy source. */
1621060SN/A    Addr copySrcEffAddr;
1631060SN/A
1641060SN/A    /** Effective physical address for a copy source. */
1651060SN/A    Addr copySrcPhysEffAddr;
1661060SN/A
1671060SN/A    /** The memory request flags (from translation). */
1681060SN/A    unsigned memReqFlags;
1691060SN/A
1701060SN/A    /** The size of the data to be stored. */
1711060SN/A    int storeSize;
1721060SN/A
1731060SN/A    /** The data to be stored. */
1741060SN/A    IntReg storeData;
1751060SN/A
1761464SN/A    union Result {
1771464SN/A        uint64_t integer;
1781464SN/A        float fp;
1791464SN/A        double dbl;
1801464SN/A    };
1811060SN/A
1821464SN/A    /** The result of the instruction; assumes for now that there's only one
1831464SN/A     *  destination register.
1841464SN/A     */
1851464SN/A    Result instResult;
1861060SN/A
1871060SN/A    /** PC of this instruction. */
1881060SN/A    Addr PC;
1891060SN/A
1901060SN/A    /** Next non-speculative PC.  It is not filled in at fetch, but rather
1911060SN/A     *  once the target of the branch is truly known (either decode or
1921060SN/A     *  execute).
1931060SN/A     */
1941060SN/A    Addr nextPC;
1951060SN/A
1961060SN/A    /** Predicted next PC. */
1971060SN/A    Addr predPC;
1981060SN/A
1991060SN/A    /** Count of total number of dynamic instructions. */
2001060SN/A    static int instcount;
2011060SN/A
2021464SN/A    /** Whether or not the source register is ready.  Not sure this should be
2031464SN/A     *  here vs. the derived class.
2041060SN/A     */
2051060SN/A    bool _readySrcRegIdx[MaxInstSrcRegs];
2061060SN/A
2071060SN/A  public:
2081060SN/A    /** BaseDynInst constructor given a binary instruction. */
2091060SN/A    BaseDynInst(MachInst inst, Addr PC, Addr Pred_PC, InstSeqNum seq_num,
2101060SN/A                FullCPU *cpu);
2111060SN/A
2121060SN/A    /** BaseDynInst constructor given a static inst pointer. */
2132107SN/A    BaseDynInst(StaticInstPtr &_staticInst);
2141060SN/A
2151060SN/A    /** BaseDynInst destructor. */
2161060SN/A    ~BaseDynInst();
2171060SN/A
2181464SN/A  private:
2191684SN/A    /** Function to initialize variables in the constructors. */
2201464SN/A    void initVars();
2211060SN/A
2221464SN/A  public:
2231060SN/A    void
2242132SN/A    trace_mem(Fault fault,      // last fault
2251060SN/A              MemCmd cmd,       // last command
2261060SN/A              Addr addr,        // virtual address of access
2271060SN/A              void *p,          // memory accessed
2281060SN/A              int nbytes);      // access size
2291060SN/A
2301060SN/A    /** Dumps out contents of this BaseDynInst. */
2311060SN/A    void dump();
2321060SN/A
2331060SN/A    /** Dumps out contents of this BaseDynInst into given string. */
2341060SN/A    void dump(std::string &outstring);
2351060SN/A
2361060SN/A    /** Returns the fault type. */
2372132SN/A    Fault getFault() { return fault; }
2381060SN/A
2391060SN/A    /** Checks whether or not this instruction has had its branch target
2401060SN/A     *  calculated yet.  For now it is not utilized and is hacked to be
2411060SN/A     *  always false.
2421060SN/A     */
2431060SN/A    bool doneTargCalc() { return false; }
2441060SN/A
2451684SN/A    /** Returns the next PC.  This could be the speculative next PC if it is
2461684SN/A     *  called prior to the actual branch target being calculated.
2471684SN/A     */
2481060SN/A    Addr readNextPC() { return nextPC; }
2491060SN/A
2501060SN/A    /** Set the predicted target of this current instruction. */
2511060SN/A    void setPredTarg(Addr predicted_PC) { predPC = predicted_PC; }
2521060SN/A
2531060SN/A    /** Returns the predicted target of the branch. */
2541060SN/A    Addr readPredTarg() { return predPC; }
2551060SN/A
2561060SN/A    /** Returns whether the instruction was predicted taken or not. */
2571060SN/A    bool predTaken() {
2581060SN/A        return( predPC != (PC + sizeof(MachInst) ) );
2591060SN/A    }
2601060SN/A
2611060SN/A    /** Returns whether the instruction mispredicted. */
2621060SN/A    bool mispredicted() { return (predPC != nextPC); }
2631060SN/A
2641060SN/A    //
2651060SN/A    //  Instruction types.  Forward checks to StaticInst object.
2661060SN/A    //
2671060SN/A    bool isNop()	  const { return staticInst->isNop(); }
2681060SN/A    bool isMemRef()    	  const { return staticInst->isMemRef(); }
2691060SN/A    bool isLoad()	  const { return staticInst->isLoad(); }
2701060SN/A    bool isStore()	  const { return staticInst->isStore(); }
2711060SN/A    bool isInstPrefetch() const { return staticInst->isInstPrefetch(); }
2721060SN/A    bool isDataPrefetch() const { return staticInst->isDataPrefetch(); }
2731060SN/A    bool isCopy()         const { return staticInst->isCopy(); }
2741060SN/A    bool isInteger()	  const { return staticInst->isInteger(); }
2751060SN/A    bool isFloating()	  const { return staticInst->isFloating(); }
2761060SN/A    bool isControl()	  const { return staticInst->isControl(); }
2771060SN/A    bool isCall()	  const { return staticInst->isCall(); }
2781060SN/A    bool isReturn()	  const { return staticInst->isReturn(); }
2791060SN/A    bool isDirectCtrl()	  const { return staticInst->isDirectCtrl(); }
2801060SN/A    bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); }
2811060SN/A    bool isCondCtrl()	  const { return staticInst->isCondCtrl(); }
2821060SN/A    bool isUncondCtrl()	  const { return staticInst->isUncondCtrl(); }
2831060SN/A    bool isThreadSync()   const { return staticInst->isThreadSync(); }
2841060SN/A    bool isSerializing()  const { return staticInst->isSerializing(); }
2851060SN/A    bool isMemBarrier()   const { return staticInst->isMemBarrier(); }
2861060SN/A    bool isWriteBarrier() const { return staticInst->isWriteBarrier(); }
2871060SN/A    bool isNonSpeculative() const { return staticInst->isNonSpeculative(); }
2881060SN/A
2891464SN/A    /** Returns the opclass of this instruction. */
2901464SN/A    OpClass opClass() const { return staticInst->opClass(); }
2911464SN/A
2921464SN/A    /** Returns the branch target address. */
2931464SN/A    Addr branchTarget() const { return staticInst->branchTarget(PC); }
2941464SN/A
2951684SN/A    /** Number of source registers. */
2961060SN/A    int8_t numSrcRegs()	 const { return staticInst->numSrcRegs(); }
2971684SN/A
2981684SN/A    /** Number of destination registers. */
2991060SN/A    int8_t numDestRegs() const { return staticInst->numDestRegs(); }
3001060SN/A
3011060SN/A    // the following are used to track physical register usage
3021060SN/A    // for machines with separate int & FP reg files
3031060SN/A    int8_t numFPDestRegs()  const { return staticInst->numFPDestRegs(); }
3041060SN/A    int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); }
3051060SN/A
3061060SN/A    /** Returns the logical register index of the i'th destination register. */
3071060SN/A    RegIndex destRegIdx(int i) const
3081060SN/A    {
3091060SN/A        return staticInst->destRegIdx(i);
3101060SN/A    }
3111060SN/A
3121060SN/A    /** Returns the logical register index of the i'th source register. */
3131060SN/A    RegIndex srcRegIdx(int i) const
3141060SN/A    {
3151060SN/A        return staticInst->srcRegIdx(i);
3161060SN/A    }
3171060SN/A
3181684SN/A    /** Returns the result of an integer instruction. */
3191464SN/A    uint64_t readIntResult() { return instResult.integer; }
3201684SN/A
3211684SN/A    /** Returns the result of a floating point instruction. */
3221464SN/A    float readFloatResult() { return instResult.fp; }
3231684SN/A
3241684SN/A    /** Returns the result of a floating point (double) instruction. */
3251464SN/A    double readDoubleResult() { return instResult.dbl; }
3261060SN/A
3271060SN/A    //Push to .cc file.
3281060SN/A    /** Records that one of the source registers is ready. */
3291060SN/A    void markSrcRegReady()
3301060SN/A    {
3311060SN/A        ++readyRegs;
3321060SN/A        if(readyRegs == numSrcRegs()) {
3331060SN/A            canIssue = true;
3341060SN/A        }
3351060SN/A    }
3361060SN/A
3371684SN/A    /** Marks a specific register as ready.
3381684SN/A     *  @todo: Move this to .cc file.
3391684SN/A     */
3401060SN/A    void markSrcRegReady(RegIndex src_idx)
3411060SN/A    {
3421060SN/A        ++readyRegs;
3431060SN/A
3441060SN/A        _readySrcRegIdx[src_idx] = 1;
3451060SN/A
3461060SN/A        if(readyRegs == numSrcRegs()) {
3471060SN/A            canIssue = true;
3481060SN/A        }
3491060SN/A    }
3501060SN/A
3511684SN/A    /** Returns if a source register is ready. */
3521464SN/A    bool isReadySrcRegIdx(int idx) const
3531464SN/A    {
3541464SN/A        return this->_readySrcRegIdx[idx];
3551464SN/A    }
3561464SN/A
3571684SN/A    /** Sets this instruction as completed. */
3581464SN/A    void setCompleted() { completed = true; }
3591464SN/A
3601684SN/A    /** Returns whethe or not this instruction is completed. */
3611464SN/A    bool isCompleted() const { return completed; }
3621464SN/A
3631060SN/A    /** Sets this instruction as ready to issue. */
3641060SN/A    void setCanIssue() { canIssue = true; }
3651060SN/A
3661060SN/A    /** Returns whether or not this instruction is ready to issue. */
3671060SN/A    bool readyToIssue() const { return canIssue; }
3681060SN/A
3691060SN/A    /** Sets this instruction as issued from the IQ. */
3701060SN/A    void setIssued() { issued = true; }
3711060SN/A
3721060SN/A    /** Returns whether or not this instruction has issued. */
3731464SN/A    bool isIssued() const { return issued; }
3741060SN/A
3751060SN/A    /** Sets this instruction as executed. */
3761060SN/A    void setExecuted() { executed = true; }
3771060SN/A
3781060SN/A    /** Returns whether or not this instruction has executed. */
3791464SN/A    bool isExecuted() const { return executed; }
3801060SN/A
3811060SN/A    /** Sets this instruction as ready to commit. */
3821060SN/A    void setCanCommit() { canCommit = true; }
3831060SN/A
3841061SN/A    /** Clears this instruction as being ready to commit. */
3851061SN/A    void clearCanCommit() { canCommit = false; }
3861061SN/A
3871060SN/A    /** Returns whether or not this instruction is ready to commit. */
3881060SN/A    bool readyToCommit() const { return canCommit; }
3891060SN/A
3901060SN/A    /** Sets this instruction as squashed. */
3911060SN/A    void setSquashed() { squashed = true; }
3921060SN/A
3931060SN/A    /** Returns whether or not this instruction is squashed. */
3941060SN/A    bool isSquashed() const { return squashed; }
3951060SN/A
3961060SN/A    /** Sets this instruction as squashed in the IQ. */
3971060SN/A    void setSquashedInIQ() { squashedInIQ = true; }
3981060SN/A
3991060SN/A    /** Returns whether or not this instruction is squashed in the IQ. */
4001464SN/A    bool isSquashedInIQ() const { return squashedInIQ; }
4011060SN/A
4021060SN/A    /** Read the PC of this instruction. */
4031464SN/A    const Addr readPC() const { return PC; }
4041060SN/A
4051060SN/A    /** Set the next PC of this instruction (its actual target). */
4061060SN/A    void setNextPC(uint64_t val) { nextPC = val; }
4071060SN/A
4081684SN/A    /** Returns the exec context.
4091684SN/A     *  @todo: Remove this once the ExecContext is no longer used.
4101684SN/A     */
4112190SN/A    ExecContext *xcBase() { return cpuXC->getProxy(); }
4121464SN/A
4131464SN/A  private:
4141684SN/A    /** Instruction effective address.
4151684SN/A     *  @todo: Consider if this is necessary or not.
4161684SN/A     */
4171464SN/A    Addr instEffAddr;
4181684SN/A    /** Whether or not the effective address calculation is completed.
4191684SN/A     *  @todo: Consider if this is necessary or not.
4201684SN/A     */
4211464SN/A    bool eaCalcDone;
4221464SN/A
4231464SN/A  public:
4241684SN/A    /** Sets the effective address. */
4251464SN/A    void setEA(Addr &ea) { instEffAddr = ea; eaCalcDone = true; }
4261684SN/A
4271684SN/A    /** Returns the effective address. */
4281464SN/A    const Addr &getEA() const { return instEffAddr; }
4291684SN/A
4301684SN/A    /** Returns whether or not the eff. addr. calculation has been completed. */
4311464SN/A    bool doneEACalc() { return eaCalcDone; }
4321684SN/A
4331684SN/A    /** Returns whether or not the eff. addr. source registers are ready. */
4341464SN/A    bool eaSrcsReady();
4351681SN/A
4361681SN/A  public:
4371684SN/A    /** Load queue index. */
4381681SN/A    int16_t lqIdx;
4391684SN/A
4401684SN/A    /** Store queue index. */
4411681SN/A    int16_t sqIdx;
4421060SN/A};
4431060SN/A
4441060SN/Atemplate<class Impl>
4451060SN/Atemplate<class T>
4462132SN/Ainline Fault
4471060SN/ABaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags)
4481060SN/A{
4492190SN/A    MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), sizeof(T), flags);
4501060SN/A    req->asid = asid;
4511060SN/A
4521060SN/A    fault = cpu->translateDataReadReq(req);
4531060SN/A
4541060SN/A    // Record key MemReq parameters so we can generate another one
4551060SN/A    // just like it for the timing access without calling translate()
4561060SN/A    // again (which might mess up the TLB).
4571681SN/A    // Do I ever really need this? -KTL 3/05
4581060SN/A    effAddr = req->vaddr;
4591060SN/A    physEffAddr = req->paddr;
4601060SN/A    memReqFlags = req->flags;
4611060SN/A
4621060SN/A    /**
4631060SN/A     * @todo
4641060SN/A     * Replace the disjoint functional memory with a unified one and remove
4651060SN/A     * this hack.
4661060SN/A     */
4671858SN/A#if !FULL_SYSTEM
4681060SN/A    req->paddr = req->vaddr;
4691060SN/A#endif
4701060SN/A
4712090SN/A    if (fault == NoFault) {
4721681SN/A        fault = cpu->read(req, data, lqIdx);
4731684SN/A    } else {
4741060SN/A        // Return a fixed value to keep simulation deterministic even
4751060SN/A        // along misspeculated paths.
4761060SN/A        data = (T)-1;
4771060SN/A    }
4781060SN/A
4791060SN/A    if (traceData) {
4801060SN/A        traceData->setAddr(addr);
4811060SN/A        traceData->setData(data);
4821060SN/A    }
4831060SN/A
4841060SN/A    return fault;
4851060SN/A}
4861060SN/A
4871060SN/Atemplate<class Impl>
4881060SN/Atemplate<class T>
4892132SN/Ainline Fault
4901060SN/ABaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res)
4911060SN/A{
4921060SN/A    if (traceData) {
4931060SN/A        traceData->setAddr(addr);
4941060SN/A        traceData->setData(data);
4951060SN/A    }
4961060SN/A
4972190SN/A    MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), sizeof(T), flags);
4981060SN/A
4991060SN/A    req->asid = asid;
5001060SN/A
5011060SN/A    fault = cpu->translateDataWriteReq(req);
5021060SN/A
5031060SN/A    // Record key MemReq parameters so we can generate another one
5041060SN/A    // just like it for the timing access without calling translate()
5051060SN/A    // again (which might mess up the TLB).
5061060SN/A    effAddr = req->vaddr;
5071060SN/A    physEffAddr = req->paddr;
5081060SN/A    memReqFlags = req->flags;
5091060SN/A
5101060SN/A    /**
5111060SN/A     * @todo
5121060SN/A     * Replace the disjoint functional memory with a unified one and remove
5131060SN/A     * this hack.
5141060SN/A     */
5151858SN/A#if !FULL_SYSTEM
5161060SN/A    req->paddr = req->vaddr;
5171060SN/A#endif
5181060SN/A
5192090SN/A    if (fault == NoFault) {
5201681SN/A        fault = cpu->write(req, data, sqIdx);
5211060SN/A    }
5221060SN/A
5231060SN/A    if (res) {
5241060SN/A        // always return some result to keep misspeculated paths
5251060SN/A        // (which will ignore faults) deterministic
5262090SN/A        *res = (fault == NoFault) ? req->result : 0;
5271060SN/A    }
5281060SN/A
5291060SN/A    return fault;
5301060SN/A}
5311060SN/A
5321464SN/A#endif // __CPU_BASE_DYN_INST_HH__
533