base_dyn_inst.hh revision 13953:43ae8a30ec1f
110037SARM gem5 Developers/*
212271Sjose.marinho@arm.com * Copyright (c) 2011, 2013, 2016-2018 ARM Limited
312271Sjose.marinho@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
410037SARM gem5 Developers * All rights reserved.
512271Sjose.marinho@arm.com *
612271Sjose.marinho@arm.com * The license below extends only to copyright in the software and shall
712271Sjose.marinho@arm.com * not be construed as granting a license to any other intellectual
812271Sjose.marinho@arm.com * property including but not limited to intellectual property relating
912271Sjose.marinho@arm.com * to a hardware implementation of the functionality of the software
1012271Sjose.marinho@arm.com * licensed hereunder.  You may use the software subject to the license
1112271Sjose.marinho@arm.com * terms below provided that you ensure that this notice is replicated
1212271Sjose.marinho@arm.com * unmodified and in its entirety in all distributions of the software,
1310037SARM gem5 Developers * modified or unmodified, in source code or in binary form.
1412271Sjose.marinho@arm.com *
1512271Sjose.marinho@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan
1612271Sjose.marinho@arm.com * Copyright (c) 2009 The University of Edinburgh
1712271Sjose.marinho@arm.com * All rights reserved.
1812271Sjose.marinho@arm.com *
1912271Sjose.marinho@arm.com * Redistribution and use in source and binary forms, with or without
2012271Sjose.marinho@arm.com * modification, are permitted provided that the following conditions are
2112271Sjose.marinho@arm.com * met: redistributions of source code must retain the above copyright
2212271Sjose.marinho@arm.com * notice, this list of conditions and the following disclaimer;
2312271Sjose.marinho@arm.com * redistributions in binary form must reproduce the above copyright
2412271Sjose.marinho@arm.com * notice, this list of conditions and the following disclaimer in the
2512271Sjose.marinho@arm.com * documentation and/or other materials provided with the distribution;
2612271Sjose.marinho@arm.com * neither the name of the copyright holders nor the names of its
2712271Sjose.marinho@arm.com * contributors may be used to endorse or promote products derived from
2812271Sjose.marinho@arm.com * this software without specific prior written permission.
2912271Sjose.marinho@arm.com *
3012271Sjose.marinho@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3112271Sjose.marinho@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3212271Sjose.marinho@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3312271Sjose.marinho@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3412271Sjose.marinho@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3512271Sjose.marinho@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3612271Sjose.marinho@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3710037SARM gem5 Developers * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3810037SARM gem5 Developers * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3910037SARM gem5 Developers * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
4010037SARM gem5 Developers * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4110037SARM gem5 Developers *
4210037SARM gem5 Developers * Authors: Kevin Lim
4310037SARM gem5 Developers *          Timothy M. Jones
4410037SARM gem5 Developers */
4510037SARM gem5 Developers
4610037SARM gem5 Developers#ifndef __CPU_BASE_DYN_INST_HH__
4710037SARM gem5 Developers#define __CPU_BASE_DYN_INST_HH__
4810037SARM gem5 Developers
4910037SARM gem5 Developers#include <array>
5010037SARM gem5 Developers#include <bitset>
5110037SARM gem5 Developers#include <deque>
5210037SARM gem5 Developers#include <list>
5310037SARM gem5 Developers#include <string>
5410037SARM gem5 Developers
5510037SARM gem5 Developers#include "arch/generic/tlb.hh"
5610037SARM gem5 Developers#include "arch/utility.hh"
5710037SARM gem5 Developers#include "base/trace.hh"
5810037SARM gem5 Developers#include "config/the_isa.hh"
5910037SARM gem5 Developers#include "cpu/checker/cpu.hh"
6010037SARM gem5 Developers#include "cpu/exec_context.hh"
6110037SARM gem5 Developers#include "cpu/exetrace.hh"
6210037SARM gem5 Developers#include "cpu/inst_res.hh"
6310037SARM gem5 Developers#include "cpu/inst_seq.hh"
6410037SARM gem5 Developers#include "cpu/op_class.hh"
6510037SARM gem5 Developers#include "cpu/static_inst.hh"
6611258Skarthik.sangaiah@arm.com#include "cpu/translation.hh"
6711258Skarthik.sangaiah@arm.com#include "mem/packet.hh"
6811258Skarthik.sangaiah@arm.com#include "mem/request.hh"
6911258Skarthik.sangaiah@arm.com#include "sim/byteswap.hh"
7011258Skarthik.sangaiah@arm.com#include "sim/system.hh"
7111258Skarthik.sangaiah@arm.com
7210037SARM gem5 Developers/**
7310037SARM gem5 Developers * @file
7410037SARM gem5 Developers * Defines a dynamic instruction context.
7510037SARM gem5 Developers */
7610037SARM gem5 Developers
7710037SARM gem5 Developerstemplate <class Impl>
7810037SARM gem5 Developersclass BaseDynInst : public ExecContext, public RefCounted
7910037SARM gem5 Developers{
8010037SARM gem5 Developers  public:
8110037SARM gem5 Developers    // Typedef for the CPU.
8210037SARM gem5 Developers    typedef typename Impl::CPUType ImplCPU;
8310037SARM gem5 Developers    typedef typename ImplCPU::ImplState ImplState;
8410037SARM gem5 Developers    using VecRegContainer = TheISA::VecRegContainer;
8510037SARM gem5 Developers
8610037SARM gem5 Developers    using LSQRequestPtr = typename Impl::CPUPol::LSQ::LSQRequest*;
8710037SARM gem5 Developers    using LQIterator = typename Impl::CPUPol::LSQUnit::LQIterator;
8810037SARM gem5 Developers    using SQIterator = typename Impl::CPUPol::LSQUnit::SQIterator;
8910037SARM gem5 Developers
9010037SARM gem5 Developers    // The DynInstPtr type.
9110037SARM gem5 Developers    typedef typename Impl::DynInstPtr DynInstPtr;
9210037SARM gem5 Developers    typedef RefCountingPtr<BaseDynInst<Impl> > BaseDynInstPtr;
9310037SARM gem5 Developers
9410037SARM gem5 Developers    // The list of instructions iterator type.
9510037SARM gem5 Developers    typedef typename std::list<DynInstPtr>::iterator ListIt;
9610037SARM gem5 Developers
9710037SARM gem5 Developers    enum {
9810037SARM gem5 Developers        MaxInstSrcRegs = TheISA::MaxInstSrcRegs,        /// Max source regs
9910037SARM gem5 Developers        MaxInstDestRegs = TheISA::MaxInstDestRegs       /// Max dest regs
10010037SARM gem5 Developers    };
10110037SARM gem5 Developers
10210037SARM gem5 Developers  protected:
10310037SARM gem5 Developers    enum Status {
10410037SARM gem5 Developers        IqEntry,                 /// Instruction is in the IQ
10510037SARM gem5 Developers        RobEntry,                /// Instruction is in the ROB
10610037SARM gem5 Developers        LsqEntry,                /// Instruction is in the LSQ
10710037SARM gem5 Developers        Completed,               /// Instruction has completed
10810037SARM gem5 Developers        ResultReady,             /// Instruction has its result
10910037SARM gem5 Developers        CanIssue,                /// Instruction can issue and execute
11010037SARM gem5 Developers        Issued,                  /// Instruction has issued
11110037SARM gem5 Developers        Executed,                /// Instruction has executed
11210037SARM gem5 Developers        CanCommit,               /// Instruction can commit
11311258Skarthik.sangaiah@arm.com        AtCommit,                /// Instruction has reached commit
11411258Skarthik.sangaiah@arm.com        Committed,               /// Instruction has committed
11511258Skarthik.sangaiah@arm.com        Squashed,                /// Instruction is squashed
11611258Skarthik.sangaiah@arm.com        SquashedInIQ,            /// Instruction is squashed in the IQ
11711258Skarthik.sangaiah@arm.com        SquashedInLSQ,           /// Instruction is squashed in the LSQ
11811258Skarthik.sangaiah@arm.com        SquashedInROB,           /// Instruction is squashed in the ROB
11911258Skarthik.sangaiah@arm.com        RecoverInst,             /// Is a recover instruction
12010037SARM gem5 Developers        BlockingInst,            /// Is a blocking instruction
12110037SARM gem5 Developers        ThreadsyncWait,          /// Is a thread synchronization instruction
12210037SARM gem5 Developers        SerializeBefore,         /// Needs to serialize on
12310037SARM gem5 Developers                                 /// instructions ahead of it
12410037SARM gem5 Developers        SerializeAfter,          /// Needs to serialize instructions behind it
12510037SARM gem5 Developers        SerializeHandled,        /// Serialization has been handled
12610037SARM gem5 Developers        NumStatus
12710037SARM gem5 Developers    };
12810037SARM gem5 Developers
12910037SARM gem5 Developers    enum Flags {
13010037SARM gem5 Developers        NotAnInst,
13110037SARM gem5 Developers        TranslationStarted,
13210037SARM gem5 Developers        TranslationCompleted,
13310037SARM gem5 Developers        PossibleLoadViolation,
13410037SARM gem5 Developers        HitExternalSnoop,
13510037SARM gem5 Developers        EffAddrValid,
13610037SARM gem5 Developers        RecordResult,
13710037SARM gem5 Developers        Predicate,
13810037SARM gem5 Developers        MemAccPredicate,
13910037SARM gem5 Developers        PredTaken,
14010037SARM gem5 Developers        IsStrictlyOrdered,
14110037SARM gem5 Developers        ReqMade,
14210037SARM gem5 Developers        MemOpDone,
14310037SARM gem5 Developers        MaxFlags
14410037SARM gem5 Developers    };
14510037SARM gem5 Developers
14610037SARM gem5 Developers  public:
14710037SARM gem5 Developers    /** The sequence number of the instruction. */
14810037SARM gem5 Developers    InstSeqNum seqNum;
14910037SARM gem5 Developers
15010037SARM gem5 Developers    /** The StaticInst used by this BaseDynInst. */
15110037SARM gem5 Developers    const StaticInstPtr staticInst;
15210037SARM gem5 Developers
15310037SARM gem5 Developers    /** Pointer to the Impl's CPU object. */
15410037SARM gem5 Developers    ImplCPU *cpu;
15510037SARM gem5 Developers
15610037SARM gem5 Developers    BaseCPU *getCpuPtr() { return cpu; }
15710037SARM gem5 Developers
15810037SARM gem5 Developers    /** Pointer to the thread state. */
15910037SARM gem5 Developers    ImplState *thread;
16010037SARM gem5 Developers
16110037SARM gem5 Developers    /** The kind of fault this instruction has generated. */
16210037SARM gem5 Developers    Fault fault;
163
164    /** InstRecord that tracks this instructions. */
165    Trace::InstRecord *traceData;
166
167  protected:
168    /** The result of the instruction; assumes an instruction can have many
169     *  destination registers.
170     */
171    std::queue<InstResult> instResult;
172
173    /** PC state for this instruction. */
174    TheISA::PCState pc;
175
176    /* An amalgamation of a lot of boolean values into one */
177    std::bitset<MaxFlags> instFlags;
178
179    /** The status of this BaseDynInst.  Several bits can be set. */
180    std::bitset<NumStatus> status;
181
182     /** Whether or not the source register is ready.
183     *  @todo: Not sure this should be here vs the derived class.
184     */
185    std::bitset<MaxInstSrcRegs> _readySrcRegIdx;
186
187  public:
188    /** The thread this instruction is from. */
189    ThreadID threadNumber;
190
191    /** Iterator pointing to this BaseDynInst in the list of all insts. */
192    ListIt instListIt;
193
194    ////////////////////// Branch Data ///////////////
195    /** Predicted PC state after this instruction. */
196    TheISA::PCState predPC;
197
198    /** The Macroop if one exists */
199    const StaticInstPtr macroop;
200
201    /** How many source registers are ready. */
202    uint8_t readyRegs;
203
204  public:
205    /////////////////////// Load Store Data //////////////////////
206    /** The effective virtual address (lds & stores only). */
207    Addr effAddr;
208
209    /** The effective physical address. */
210    Addr physEffAddr;
211
212    /** The memory request flags (from translation). */
213    unsigned memReqFlags;
214
215    /** data address space ID, for loads & stores. */
216    short asid;
217
218    /** The size of the request */
219    uint8_t effSize;
220
221    /** Pointer to the data for the memory access. */
222    uint8_t *memData;
223
224    /** Load queue index. */
225    int16_t lqIdx;
226    LQIterator lqIt;
227
228    /** Store queue index. */
229    int16_t sqIdx;
230    SQIterator sqIt;
231
232
233    /////////////////////// TLB Miss //////////////////////
234    /**
235     * Saved memory request (needed when the DTB address translation is
236     * delayed due to a hw page table walk).
237     */
238    LSQRequestPtr savedReq;
239
240    /////////////////////// Checker //////////////////////
241    // Need a copy of main request pointer to verify on writes.
242    RequestPtr reqToVerify;
243
244  protected:
245    /** Flattened register index of the destination registers of this
246     *  instruction.
247     */
248    std::array<RegId, TheISA::MaxInstDestRegs> _flatDestRegIdx;
249
250    /** Physical register index of the destination registers of this
251     *  instruction.
252     */
253    std::array<PhysRegIdPtr, TheISA::MaxInstDestRegs> _destRegIdx;
254
255    /** Physical register index of the source registers of this
256     *  instruction.
257     */
258    std::array<PhysRegIdPtr, TheISA::MaxInstSrcRegs> _srcRegIdx;
259
260    /** Physical register index of the previous producers of the
261     *  architected destinations.
262     */
263    std::array<PhysRegIdPtr, TheISA::MaxInstDestRegs> _prevDestRegIdx;
264
265
266  public:
267    /** Records changes to result? */
268    void recordResult(bool f) { instFlags[RecordResult] = f; }
269
270    /** Is the effective virtual address valid. */
271    bool effAddrValid() const { return instFlags[EffAddrValid]; }
272    void effAddrValid(bool b) { instFlags[EffAddrValid] = b; }
273
274    /** Whether or not the memory operation is done. */
275    bool memOpDone() const { return instFlags[MemOpDone]; }
276    void memOpDone(bool f) { instFlags[MemOpDone] = f; }
277
278    bool notAnInst() const { return instFlags[NotAnInst]; }
279    void setNotAnInst() { instFlags[NotAnInst] = true; }
280
281
282    ////////////////////////////////////////////
283    //
284    // INSTRUCTION EXECUTION
285    //
286    ////////////////////////////////////////////
287
288    void demapPage(Addr vaddr, uint64_t asn)
289    {
290        cpu->demapPage(vaddr, asn);
291    }
292    void demapInstPage(Addr vaddr, uint64_t asn)
293    {
294        cpu->demapPage(vaddr, asn);
295    }
296    void demapDataPage(Addr vaddr, uint64_t asn)
297    {
298        cpu->demapPage(vaddr, asn);
299    }
300
301    Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags);
302
303    Fault writeMem(uint8_t *data, unsigned size, Addr addr,
304                   Request::Flags flags, uint64_t *res);
305
306    Fault initiateMemAMO(Addr addr, unsigned size, Request::Flags flags,
307                         AtomicOpFunctor *amo_op);
308
309    /** True if the DTB address translation has started. */
310    bool translationStarted() const { return instFlags[TranslationStarted]; }
311    void translationStarted(bool f) { instFlags[TranslationStarted] = f; }
312
313    /** True if the DTB address translation has completed. */
314    bool translationCompleted() const { return instFlags[TranslationCompleted]; }
315    void translationCompleted(bool f) { instFlags[TranslationCompleted] = f; }
316
317    /** True if this address was found to match a previous load and they issued
318     * out of order. If that happend, then it's only a problem if an incoming
319     * snoop invalidate modifies the line, in which case we need to squash.
320     * If nothing modified the line the order doesn't matter.
321     */
322    bool possibleLoadViolation() const { return instFlags[PossibleLoadViolation]; }
323    void possibleLoadViolation(bool f) { instFlags[PossibleLoadViolation] = f; }
324
325    /** True if the address hit a external snoop while sitting in the LSQ.
326     * If this is true and a older instruction sees it, this instruction must
327     * reexecute
328     */
329    bool hitExternalSnoop() const { return instFlags[HitExternalSnoop]; }
330    void hitExternalSnoop(bool f) { instFlags[HitExternalSnoop] = f; }
331
332    /**
333     * Returns true if the DTB address translation is being delayed due to a hw
334     * page table walk.
335     */
336    bool isTranslationDelayed() const
337    {
338        return (translationStarted() && !translationCompleted());
339    }
340
341  public:
342#ifdef DEBUG
343    void dumpSNList();
344#endif
345
346    /** Returns the physical register index of the i'th destination
347     *  register.
348     */
349    PhysRegIdPtr renamedDestRegIdx(int idx) const
350    {
351        return _destRegIdx[idx];
352    }
353
354    /** Returns the physical register index of the i'th source register. */
355    PhysRegIdPtr renamedSrcRegIdx(int idx) const
356    {
357        assert(TheISA::MaxInstSrcRegs > idx);
358        return _srcRegIdx[idx];
359    }
360
361    /** Returns the flattened register index of the i'th destination
362     *  register.
363     */
364    const RegId& flattenedDestRegIdx(int idx) const
365    {
366        return _flatDestRegIdx[idx];
367    }
368
369    /** Returns the physical register index of the previous physical register
370     *  that remapped to the same logical register index.
371     */
372    PhysRegIdPtr prevDestRegIdx(int idx) const
373    {
374        return _prevDestRegIdx[idx];
375    }
376
377    /** Renames a destination register to a physical register.  Also records
378     *  the previous physical register that the logical register mapped to.
379     */
380    void renameDestReg(int idx,
381                       PhysRegIdPtr renamed_dest,
382                       PhysRegIdPtr previous_rename)
383    {
384        _destRegIdx[idx] = renamed_dest;
385        _prevDestRegIdx[idx] = previous_rename;
386    }
387
388    /** Renames a source logical register to the physical register which
389     *  has/will produce that logical register's result.
390     *  @todo: add in whether or not the source register is ready.
391     */
392    void renameSrcReg(int idx, PhysRegIdPtr renamed_src)
393    {
394        _srcRegIdx[idx] = renamed_src;
395    }
396
397    /** Flattens a destination architectural register index into a logical
398     * index.
399     */
400    void flattenDestReg(int idx, const RegId& flattened_dest)
401    {
402        _flatDestRegIdx[idx] = flattened_dest;
403    }
404    /** BaseDynInst constructor given a binary instruction.
405     *  @param staticInst A StaticInstPtr to the underlying instruction.
406     *  @param pc The PC state for the instruction.
407     *  @param predPC The predicted next PC state for the instruction.
408     *  @param seq_num The sequence number of the instruction.
409     *  @param cpu Pointer to the instruction's CPU.
410     */
411    BaseDynInst(const StaticInstPtr &staticInst, const StaticInstPtr &macroop,
412                TheISA::PCState pc, TheISA::PCState predPC,
413                InstSeqNum seq_num, ImplCPU *cpu);
414
415    /** BaseDynInst constructor given a StaticInst pointer.
416     *  @param _staticInst The StaticInst for this BaseDynInst.
417     */
418    BaseDynInst(const StaticInstPtr &staticInst, const StaticInstPtr &macroop);
419
420    /** BaseDynInst destructor. */
421    ~BaseDynInst();
422
423  private:
424    /** Function to initialize variables in the constructors. */
425    void initVars();
426
427  public:
428    /** Dumps out contents of this BaseDynInst. */
429    void dump();
430
431    /** Dumps out contents of this BaseDynInst into given string. */
432    void dump(std::string &outstring);
433
434    /** Read this CPU's ID. */
435    int cpuId() const { return cpu->cpuId(); }
436
437    /** Read this CPU's Socket ID. */
438    uint32_t socketId() const { return cpu->socketId(); }
439
440    /** Read this CPU's data requestor ID */
441    MasterID masterId() const { return cpu->dataMasterId(); }
442
443    /** Read this context's system-wide ID **/
444    ContextID contextId() const { return thread->contextId(); }
445
446    /** Returns the fault type. */
447    Fault getFault() const { return fault; }
448    /** TODO: This I added for the LSQRequest side to be able to modify the
449     * fault. There should be a better mechanism in place. */
450    Fault& getFault() { return fault; }
451
452    /** Checks whether or not this instruction has had its branch target
453     *  calculated yet.  For now it is not utilized and is hacked to be
454     *  always false.
455     *  @todo: Actually use this instruction.
456     */
457    bool doneTargCalc() { return false; }
458
459    /** Set the predicted target of this current instruction. */
460    void setPredTarg(const TheISA::PCState &_predPC)
461    {
462        predPC = _predPC;
463    }
464
465    const TheISA::PCState &readPredTarg() { return predPC; }
466
467    /** Returns the predicted PC immediately after the branch. */
468    Addr predInstAddr() { return predPC.instAddr(); }
469
470    /** Returns the predicted PC two instructions after the branch */
471    Addr predNextInstAddr() { return predPC.nextInstAddr(); }
472
473    /** Returns the predicted micro PC after the branch */
474    Addr predMicroPC() { return predPC.microPC(); }
475
476    /** Returns whether the instruction was predicted taken or not. */
477    bool readPredTaken()
478    {
479        return instFlags[PredTaken];
480    }
481
482    void setPredTaken(bool predicted_taken)
483    {
484        instFlags[PredTaken] = predicted_taken;
485    }
486
487    /** Returns whether the instruction mispredicted. */
488    bool mispredicted()
489    {
490        TheISA::PCState tempPC = pc;
491        TheISA::advancePC(tempPC, staticInst);
492        return !(tempPC == predPC);
493    }
494
495    //
496    //  Instruction types.  Forward checks to StaticInst object.
497    //
498    bool isNop()          const { return staticInst->isNop(); }
499    bool isMemRef()       const { return staticInst->isMemRef(); }
500    bool isLoad()         const { return staticInst->isLoad(); }
501    bool isStore()        const { return staticInst->isStore(); }
502    bool isAtomic()       const { return staticInst->isAtomic(); }
503    bool isStoreConditional() const
504    { return staticInst->isStoreConditional(); }
505    bool isInstPrefetch() const { return staticInst->isInstPrefetch(); }
506    bool isDataPrefetch() const { return staticInst->isDataPrefetch(); }
507    bool isInteger()      const { return staticInst->isInteger(); }
508    bool isFloating()     const { return staticInst->isFloating(); }
509    bool isVector()       const { return staticInst->isVector(); }
510    bool isControl()      const { return staticInst->isControl(); }
511    bool isCall()         const { return staticInst->isCall(); }
512    bool isReturn()       const { return staticInst->isReturn(); }
513    bool isDirectCtrl()   const { return staticInst->isDirectCtrl(); }
514    bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); }
515    bool isCondCtrl()     const { return staticInst->isCondCtrl(); }
516    bool isUncondCtrl()   const { return staticInst->isUncondCtrl(); }
517    bool isCondDelaySlot() const { return staticInst->isCondDelaySlot(); }
518    bool isThreadSync()   const { return staticInst->isThreadSync(); }
519    bool isSerializing()  const { return staticInst->isSerializing(); }
520    bool isSerializeBefore() const
521    { return staticInst->isSerializeBefore() || status[SerializeBefore]; }
522    bool isSerializeAfter() const
523    { return staticInst->isSerializeAfter() || status[SerializeAfter]; }
524    bool isSquashAfter() const { return staticInst->isSquashAfter(); }
525    bool isMemBarrier()   const { return staticInst->isMemBarrier(); }
526    bool isWriteBarrier() const { return staticInst->isWriteBarrier(); }
527    bool isNonSpeculative() const { return staticInst->isNonSpeculative(); }
528    bool isQuiesce() const { return staticInst->isQuiesce(); }
529    bool isIprAccess() const { return staticInst->isIprAccess(); }
530    bool isUnverifiable() const { return staticInst->isUnverifiable(); }
531    bool isSyscall() const { return staticInst->isSyscall(); }
532    bool isMacroop() const { return staticInst->isMacroop(); }
533    bool isMicroop() const { return staticInst->isMicroop(); }
534    bool isDelayedCommit() const { return staticInst->isDelayedCommit(); }
535    bool isLastMicroop() const { return staticInst->isLastMicroop(); }
536    bool isFirstMicroop() const { return staticInst->isFirstMicroop(); }
537    bool isMicroBranch() const { return staticInst->isMicroBranch(); }
538
539    /** Temporarily sets this instruction as a serialize before instruction. */
540    void setSerializeBefore() { status.set(SerializeBefore); }
541
542    /** Clears the serializeBefore part of this instruction. */
543    void clearSerializeBefore() { status.reset(SerializeBefore); }
544
545    /** Checks if this serializeBefore is only temporarily set. */
546    bool isTempSerializeBefore() { return status[SerializeBefore]; }
547
548    /** Temporarily sets this instruction as a serialize after instruction. */
549    void setSerializeAfter() { status.set(SerializeAfter); }
550
551    /** Clears the serializeAfter part of this instruction.*/
552    void clearSerializeAfter() { status.reset(SerializeAfter); }
553
554    /** Checks if this serializeAfter is only temporarily set. */
555    bool isTempSerializeAfter() { return status[SerializeAfter]; }
556
557    /** Sets the serialization part of this instruction as handled. */
558    void setSerializeHandled() { status.set(SerializeHandled); }
559
560    /** Checks if the serialization part of this instruction has been
561     *  handled.  This does not apply to the temporary serializing
562     *  state; it only applies to this instruction's own permanent
563     *  serializing state.
564     */
565    bool isSerializeHandled() { return status[SerializeHandled]; }
566
567    /** Returns the opclass of this instruction. */
568    OpClass opClass() const { return staticInst->opClass(); }
569
570    /** Returns the branch target address. */
571    TheISA::PCState branchTarget() const
572    { return staticInst->branchTarget(pc); }
573
574    /** Returns the number of source registers. */
575    int8_t numSrcRegs() const { return staticInst->numSrcRegs(); }
576
577    /** Returns the number of destination registers. */
578    int8_t numDestRegs() const { return staticInst->numDestRegs(); }
579
580    // the following are used to track physical register usage
581    // for machines with separate int & FP reg files
582    int8_t numFPDestRegs()  const { return staticInst->numFPDestRegs(); }
583    int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); }
584    int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); }
585    int8_t numVecDestRegs() const { return staticInst->numVecDestRegs(); }
586    int8_t numVecElemDestRegs() const
587    {
588        return staticInst->numVecElemDestRegs();
589    }
590    int8_t
591    numVecPredDestRegs() const
592    {
593        return staticInst->numVecPredDestRegs();
594    }
595
596    /** Returns the logical register index of the i'th destination register. */
597    const RegId& destRegIdx(int i) const { return staticInst->destRegIdx(i); }
598
599    /** Returns the logical register index of the i'th source register. */
600    const RegId& srcRegIdx(int i) const { return staticInst->srcRegIdx(i); }
601
602    /** Return the size of the instResult queue. */
603    uint8_t resultSize() { return instResult.size(); }
604
605    /** Pops a result off the instResult queue.
606     * If the result stack is empty, return the default value.
607     * */
608    InstResult popResult(InstResult dflt = InstResult())
609    {
610        if (!instResult.empty()) {
611            InstResult t = instResult.front();
612            instResult.pop();
613            return t;
614        }
615        return dflt;
616    }
617
618    /** Pushes a result onto the instResult queue. */
619    /** @{ */
620    /** Scalar result. */
621    template<typename T>
622    void setScalarResult(T&& t)
623    {
624        if (instFlags[RecordResult]) {
625            instResult.push(InstResult(std::forward<T>(t),
626                        InstResult::ResultType::Scalar));
627        }
628    }
629
630    /** Full vector result. */
631    template<typename T>
632    void setVecResult(T&& t)
633    {
634        if (instFlags[RecordResult]) {
635            instResult.push(InstResult(std::forward<T>(t),
636                        InstResult::ResultType::VecReg));
637        }
638    }
639
640    /** Vector element result. */
641    template<typename T>
642    void setVecElemResult(T&& t)
643    {
644        if (instFlags[RecordResult]) {
645            instResult.push(InstResult(std::forward<T>(t),
646                        InstResult::ResultType::VecElem));
647        }
648    }
649
650    /** Predicate result. */
651    template<typename T>
652    void setVecPredResult(T&& t)
653    {
654        if (instFlags[RecordResult]) {
655            instResult.push(InstResult(std::forward<T>(t),
656                            InstResult::ResultType::VecPredReg));
657        }
658    }
659    /** @} */
660
661    /** Records an integer register being set to a value. */
662    void setIntRegOperand(const StaticInst *si, int idx, RegVal val)
663    {
664        setScalarResult(val);
665    }
666
667    /** Records a CC register being set to a value. */
668    void setCCRegOperand(const StaticInst *si, int idx, RegVal val)
669    {
670        setScalarResult(val);
671    }
672
673    /** Record a vector register being set to a value */
674    void setVecRegOperand(const StaticInst *si, int idx,
675            const VecRegContainer& val)
676    {
677        setVecResult(val);
678    }
679
680    /** Records an fp register being set to an integer value. */
681    void
682    setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val)
683    {
684        setScalarResult(val);
685    }
686
687    /** Record a vector register being set to a value */
688    void setVecElemOperand(const StaticInst *si, int idx, const VecElem val)
689    {
690        setVecElemResult(val);
691    }
692
693    /** Record a vector register being set to a value */
694    void setVecPredRegOperand(const StaticInst *si, int idx,
695                              const VecPredRegContainer& val)
696    {
697        setVecPredResult(val);
698    }
699
700    /** Records that one of the source registers is ready. */
701    void markSrcRegReady();
702
703    /** Marks a specific register as ready. */
704    void markSrcRegReady(RegIndex src_idx);
705
706    /** Returns if a source register is ready. */
707    bool isReadySrcRegIdx(int idx) const
708    {
709        return this->_readySrcRegIdx[idx];
710    }
711
712    /** Sets this instruction as completed. */
713    void setCompleted() { status.set(Completed); }
714
715    /** Returns whether or not this instruction is completed. */
716    bool isCompleted() const { return status[Completed]; }
717
718    /** Marks the result as ready. */
719    void setResultReady() { status.set(ResultReady); }
720
721    /** Returns whether or not the result is ready. */
722    bool isResultReady() const { return status[ResultReady]; }
723
724    /** Sets this instruction as ready to issue. */
725    void setCanIssue() { status.set(CanIssue); }
726
727    /** Returns whether or not this instruction is ready to issue. */
728    bool readyToIssue() const { return status[CanIssue]; }
729
730    /** Clears this instruction being able to issue. */
731    void clearCanIssue() { status.reset(CanIssue); }
732
733    /** Sets this instruction as issued from the IQ. */
734    void setIssued() { status.set(Issued); }
735
736    /** Returns whether or not this instruction has issued. */
737    bool isIssued() const { return status[Issued]; }
738
739    /** Clears this instruction as being issued. */
740    void clearIssued() { status.reset(Issued); }
741
742    /** Sets this instruction as executed. */
743    void setExecuted() { status.set(Executed); }
744
745    /** Returns whether or not this instruction has executed. */
746    bool isExecuted() const { return status[Executed]; }
747
748    /** Sets this instruction as ready to commit. */
749    void setCanCommit() { status.set(CanCommit); }
750
751    /** Clears this instruction as being ready to commit. */
752    void clearCanCommit() { status.reset(CanCommit); }
753
754    /** Returns whether or not this instruction is ready to commit. */
755    bool readyToCommit() const { return status[CanCommit]; }
756
757    void setAtCommit() { status.set(AtCommit); }
758
759    bool isAtCommit() { return status[AtCommit]; }
760
761    /** Sets this instruction as committed. */
762    void setCommitted() { status.set(Committed); }
763
764    /** Returns whether or not this instruction is committed. */
765    bool isCommitted() const { return status[Committed]; }
766
767    /** Sets this instruction as squashed. */
768    void setSquashed() { status.set(Squashed); }
769
770    /** Returns whether or not this instruction is squashed. */
771    bool isSquashed() const { return status[Squashed]; }
772
773    //Instruction Queue Entry
774    //-----------------------
775    /** Sets this instruction as a entry the IQ. */
776    void setInIQ() { status.set(IqEntry); }
777
778    /** Sets this instruction as a entry the IQ. */
779    void clearInIQ() { status.reset(IqEntry); }
780
781    /** Returns whether or not this instruction has issued. */
782    bool isInIQ() const { return status[IqEntry]; }
783
784    /** Sets this instruction as squashed in the IQ. */
785    void setSquashedInIQ() { status.set(SquashedInIQ); status.set(Squashed);}
786
787    /** Returns whether or not this instruction is squashed in the IQ. */
788    bool isSquashedInIQ() const { return status[SquashedInIQ]; }
789
790
791    //Load / Store Queue Functions
792    //-----------------------
793    /** Sets this instruction as a entry the LSQ. */
794    void setInLSQ() { status.set(LsqEntry); }
795
796    /** Sets this instruction as a entry the LSQ. */
797    void removeInLSQ() { status.reset(LsqEntry); }
798
799    /** Returns whether or not this instruction is in the LSQ. */
800    bool isInLSQ() const { return status[LsqEntry]; }
801
802    /** Sets this instruction as squashed in the LSQ. */
803    void setSquashedInLSQ() { status.set(SquashedInLSQ);}
804
805    /** Returns whether or not this instruction is squashed in the LSQ. */
806    bool isSquashedInLSQ() const { return status[SquashedInLSQ]; }
807
808
809    //Reorder Buffer Functions
810    //-----------------------
811    /** Sets this instruction as a entry the ROB. */
812    void setInROB() { status.set(RobEntry); }
813
814    /** Sets this instruction as a entry the ROB. */
815    void clearInROB() { status.reset(RobEntry); }
816
817    /** Returns whether or not this instruction is in the ROB. */
818    bool isInROB() const { return status[RobEntry]; }
819
820    /** Sets this instruction as squashed in the ROB. */
821    void setSquashedInROB() { status.set(SquashedInROB); }
822
823    /** Returns whether or not this instruction is squashed in the ROB. */
824    bool isSquashedInROB() const { return status[SquashedInROB]; }
825
826    /** Read the PC state of this instruction. */
827    TheISA::PCState pcState() const { return pc; }
828
829    /** Set the PC state of this instruction. */
830    void pcState(const TheISA::PCState &val) { pc = val; }
831
832    /** Read the PC of this instruction. */
833    Addr instAddr() const { return pc.instAddr(); }
834
835    /** Read the PC of the next instruction. */
836    Addr nextInstAddr() const { return pc.nextInstAddr(); }
837
838    /**Read the micro PC of this instruction. */
839    Addr microPC() const { return pc.microPC(); }
840
841    bool readPredicate() const
842    {
843        return instFlags[Predicate];
844    }
845
846    void setPredicate(bool val)
847    {
848        instFlags[Predicate] = val;
849
850        if (traceData) {
851            traceData->setPredicate(val);
852        }
853    }
854
855    bool
856    readMemAccPredicate() const
857    {
858        return instFlags[MemAccPredicate];
859    }
860
861    void
862    setMemAccPredicate(bool val)
863    {
864        instFlags[MemAccPredicate] = val;
865    }
866
867    /** Sets the ASID. */
868    void setASID(short addr_space_id) { asid = addr_space_id; }
869    short getASID() { return asid; }
870
871    /** Sets the thread id. */
872    void setTid(ThreadID tid) { threadNumber = tid; }
873
874    /** Sets the pointer to the thread state. */
875    void setThreadState(ImplState *state) { thread = state; }
876
877    /** Returns the thread context. */
878    ThreadContext *tcBase() { return thread->getTC(); }
879
880  public:
881    /** Returns whether or not the eff. addr. source registers are ready. */
882    bool eaSrcsReady() const;
883
884    /** Is this instruction's memory access strictly ordered? */
885    bool strictlyOrdered() const { return instFlags[IsStrictlyOrdered]; }
886    void strictlyOrdered(bool so) { instFlags[IsStrictlyOrdered] = so; }
887
888    /** Has this instruction generated a memory request. */
889    bool hasRequest() const { return instFlags[ReqMade]; }
890    /** Assert this instruction has generated a memory request. */
891    void setRequest() { instFlags[ReqMade] = true; }
892
893    /** Returns iterator to this instruction in the list of all insts. */
894    ListIt &getInstListIt() { return instListIt; }
895
896    /** Sets iterator for this instruction in the list of all insts. */
897    void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; }
898
899  public:
900    /** Returns the number of consecutive store conditional failures. */
901    unsigned int readStCondFailures() const
902    { return thread->storeCondFailures; }
903
904    /** Sets the number of consecutive store conditional failures. */
905    void setStCondFailures(unsigned int sc_failures)
906    { thread->storeCondFailures = sc_failures; }
907
908  public:
909    // monitor/mwait funtions
910    void armMonitor(Addr address) { cpu->armMonitor(threadNumber, address); }
911    bool mwait(PacketPtr pkt) { return cpu->mwait(threadNumber, pkt); }
912    void mwaitAtomic(ThreadContext *tc)
913    { return cpu->mwaitAtomic(threadNumber, tc, cpu->dtb); }
914    AddressMonitor *getAddrMonitor()
915    { return cpu->getCpuAddrMonitor(threadNumber); }
916};
917
918template<class Impl>
919Fault
920BaseDynInst<Impl>::initiateMemRead(Addr addr, unsigned size,
921                                   Request::Flags flags)
922{
923    return cpu->pushRequest(
924            dynamic_cast<typename DynInstPtr::PtrType>(this),
925            /* ld */ true, nullptr, size, addr, flags, nullptr);
926}
927
928template<class Impl>
929Fault
930BaseDynInst<Impl>::writeMem(uint8_t *data, unsigned size, Addr addr,
931                            Request::Flags flags, uint64_t *res)
932{
933    return cpu->pushRequest(
934            dynamic_cast<typename DynInstPtr::PtrType>(this),
935            /* st */ false, data, size, addr, flags, res);
936}
937
938template<class Impl>
939Fault
940BaseDynInst<Impl>::initiateMemAMO(Addr addr, unsigned size,
941                                  Request::Flags flags,
942                                  AtomicOpFunctor *amo_op)
943{
944    // atomic memory instructions do not have data to be written to memory yet
945    // since the atomic operations will be executed directly in cache/memory.
946    // Therefore, its `data` field is nullptr.
947    // Atomic memory requests need to carry their `amo_op` fields to cache/
948    // memory
949    return cpu->pushRequest(
950            dynamic_cast<typename DynInstPtr::PtrType>(this),
951            /* atomic */ false, nullptr, size, addr, flags, nullptr, amo_op);
952}
953
954#endif // __CPU_BASE_DYN_INST_HH__
955