base_dyn_inst.hh revision 6973
1/*
2 * Copyright (c) 2004-2006 The Regents of The University of Michigan
3 * Copyright (c) 2009 The University of Edinburgh
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Authors: Kevin Lim
30 *          Timothy M. Jones
31 */
32
33#ifndef __CPU_BASE_DYN_INST_HH__
34#define __CPU_BASE_DYN_INST_HH__
35
36#include <bitset>
37#include <list>
38#include <string>
39
40#include "arch/faults.hh"
41#include "base/fast_alloc.hh"
42#include "base/trace.hh"
43#include "config/full_system.hh"
44#include "config/the_isa.hh"
45#include "cpu/o3/comm.hh"
46#include "cpu/exetrace.hh"
47#include "cpu/inst_seq.hh"
48#include "cpu/op_class.hh"
49#include "cpu/static_inst.hh"
50#include "cpu/translation.hh"
51#include "mem/packet.hh"
52#include "sim/system.hh"
53#include "sim/tlb.hh"
54
55/**
56 * @file
57 * Defines a dynamic instruction context.
58 */
59
60// Forward declaration.
61class StaticInstPtr;
62
63template <class Impl>
64class BaseDynInst : public FastAlloc, public RefCounted
65{
66  public:
67    // Typedef for the CPU.
68    typedef typename Impl::CPUType ImplCPU;
69    typedef typename ImplCPU::ImplState ImplState;
70
71    // Logical register index type.
72    typedef TheISA::RegIndex RegIndex;
73    // Integer register type.
74    typedef TheISA::IntReg IntReg;
75    // Floating point register type.
76    typedef TheISA::FloatReg FloatReg;
77
78    // The DynInstPtr type.
79    typedef typename Impl::DynInstPtr DynInstPtr;
80
81    // The list of instructions iterator type.
82    typedef typename std::list<DynInstPtr>::iterator ListIt;
83
84    enum {
85        MaxInstSrcRegs = TheISA::MaxInstSrcRegs,        /// Max source regs
86        MaxInstDestRegs = TheISA::MaxInstDestRegs,      /// Max dest regs
87    };
88
89    /** The StaticInst used by this BaseDynInst. */
90    StaticInstPtr staticInst;
91
92    ////////////////////////////////////////////
93    //
94    // INSTRUCTION EXECUTION
95    //
96    ////////////////////////////////////////////
97    /** InstRecord that tracks this instructions. */
98    Trace::InstRecord *traceData;
99
100    void demapPage(Addr vaddr, uint64_t asn)
101    {
102        cpu->demapPage(vaddr, asn);
103    }
104    void demapInstPage(Addr vaddr, uint64_t asn)
105    {
106        cpu->demapPage(vaddr, asn);
107    }
108    void demapDataPage(Addr vaddr, uint64_t asn)
109    {
110        cpu->demapPage(vaddr, asn);
111    }
112
113    /**
114     * Does a read to a given address.
115     * @param addr The address to read.
116     * @param data The read's data is written into this parameter.
117     * @param flags The request's flags.
118     * @return Returns any fault due to the read.
119     */
120    template <class T>
121    Fault read(Addr addr, T &data, unsigned flags);
122
123    /**
124     * Does a write to a given address.
125     * @param data The data to be written.
126     * @param addr The address to write to.
127     * @param flags The request's flags.
128     * @param res The result of the write (for load locked/store conditionals).
129     * @return Returns any fault due to the write.
130     */
131    template <class T>
132    Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
133
134    /** Initiate a DTB address translation. */
135    void initiateTranslation(RequestPtr req, uint64_t *res,
136                             BaseTLB::Mode mode);
137
138    /** Finish a DTB address translation. */
139    void finishTranslation(WholeTranslationState *state);
140
141    void prefetch(Addr addr, unsigned flags);
142    void writeHint(Addr addr, int size, unsigned flags);
143    Fault copySrcTranslate(Addr src);
144    Fault copy(Addr dest);
145
146    /** @todo: Consider making this private. */
147  public:
148    /** The sequence number of the instruction. */
149    InstSeqNum seqNum;
150
151    enum Status {
152        IqEntry,                 /// Instruction is in the IQ
153        RobEntry,                /// Instruction is in the ROB
154        LsqEntry,                /// Instruction is in the LSQ
155        Completed,               /// Instruction has completed
156        ResultReady,             /// Instruction has its result
157        CanIssue,                /// Instruction can issue and execute
158        Issued,                  /// Instruction has issued
159        Executed,                /// Instruction has executed
160        CanCommit,               /// Instruction can commit
161        AtCommit,                /// Instruction has reached commit
162        Committed,               /// Instruction has committed
163        Squashed,                /// Instruction is squashed
164        SquashedInIQ,            /// Instruction is squashed in the IQ
165        SquashedInLSQ,           /// Instruction is squashed in the LSQ
166        SquashedInROB,           /// Instruction is squashed in the ROB
167        RecoverInst,             /// Is a recover instruction
168        BlockingInst,            /// Is a blocking instruction
169        ThreadsyncWait,          /// Is a thread synchronization instruction
170        SerializeBefore,         /// Needs to serialize on
171                                 /// instructions ahead of it
172        SerializeAfter,          /// Needs to serialize instructions behind it
173        SerializeHandled,        /// Serialization has been handled
174        NumStatus
175    };
176
177    /** The status of this BaseDynInst.  Several bits can be set. */
178    std::bitset<NumStatus> status;
179
180    /** The thread this instruction is from. */
181    ThreadID threadNumber;
182
183    /** data address space ID, for loads & stores. */
184    short asid;
185
186    /** How many source registers are ready. */
187    unsigned readyRegs;
188
189    /** Pointer to the Impl's CPU object. */
190    ImplCPU *cpu;
191
192    /** Pointer to the thread state. */
193    ImplState *thread;
194
195    /** The kind of fault this instruction has generated. */
196    Fault fault;
197
198    /** Pointer to the data for the memory access. */
199    uint8_t *memData;
200
201    /** The effective virtual address (lds & stores only). */
202    Addr effAddr;
203
204    /** Is the effective virtual address valid. */
205    bool effAddrValid;
206
207    /** The effective physical address. */
208    Addr physEffAddr;
209
210    /** Effective virtual address for a copy source. */
211    Addr copySrcEffAddr;
212
213    /** Effective physical address for a copy source. */
214    Addr copySrcPhysEffAddr;
215
216    /** The memory request flags (from translation). */
217    unsigned memReqFlags;
218
219    union Result {
220        uint64_t integer;
221//        float fp;
222        double dbl;
223    };
224
225    /** The result of the instruction; assumes for now that there's only one
226     *  destination register.
227     */
228    Result instResult;
229
230    /** Records changes to result? */
231    bool recordResult;
232
233    /** PC of this instruction. */
234    Addr PC;
235
236    /** Micro PC of this instruction. */
237    Addr microPC;
238
239  protected:
240    /** Next non-speculative PC.  It is not filled in at fetch, but rather
241     *  once the target of the branch is truly known (either decode or
242     *  execute).
243     */
244    Addr nextPC;
245
246    /** Next non-speculative NPC. Target PC for Mips or Sparc. */
247    Addr nextNPC;
248
249    /** Next non-speculative micro PC. */
250    Addr nextMicroPC;
251
252    /** Predicted next PC. */
253    Addr predPC;
254
255    /** Predicted next NPC. */
256    Addr predNPC;
257
258    /** Predicted next microPC */
259    Addr predMicroPC;
260
261    /** If this is a branch that was predicted taken */
262    bool predTaken;
263
264  public:
265
266#ifdef DEBUG
267    void dumpSNList();
268#endif
269
270    /** Whether or not the source register is ready.
271     *  @todo: Not sure this should be here vs the derived class.
272     */
273    bool _readySrcRegIdx[MaxInstSrcRegs];
274
275  protected:
276    /** Flattened register index of the destination registers of this
277     *  instruction.
278     */
279    TheISA::RegIndex _flatDestRegIdx[TheISA::MaxInstDestRegs];
280
281    /** Flattened register index of the source registers of this
282     *  instruction.
283     */
284    TheISA::RegIndex _flatSrcRegIdx[TheISA::MaxInstSrcRegs];
285
286    /** Physical register index of the destination registers of this
287     *  instruction.
288     */
289    PhysRegIndex _destRegIdx[TheISA::MaxInstDestRegs];
290
291    /** Physical register index of the source registers of this
292     *  instruction.
293     */
294    PhysRegIndex _srcRegIdx[TheISA::MaxInstSrcRegs];
295
296    /** Physical register index of the previous producers of the
297     *  architected destinations.
298     */
299    PhysRegIndex _prevDestRegIdx[TheISA::MaxInstDestRegs];
300
301  public:
302
303    /** Returns the physical register index of the i'th destination
304     *  register.
305     */
306    PhysRegIndex renamedDestRegIdx(int idx) const
307    {
308        return _destRegIdx[idx];
309    }
310
311    /** Returns the physical register index of the i'th source register. */
312    PhysRegIndex renamedSrcRegIdx(int idx) const
313    {
314        return _srcRegIdx[idx];
315    }
316
317    /** Returns the flattened register index of the i'th destination
318     *  register.
319     */
320    TheISA::RegIndex flattenedDestRegIdx(int idx) const
321    {
322        return _flatDestRegIdx[idx];
323    }
324
325    /** Returns the flattened register index of the i'th source register */
326    TheISA::RegIndex flattenedSrcRegIdx(int idx) const
327    {
328        return _flatSrcRegIdx[idx];
329    }
330
331    /** Returns the physical register index of the previous physical register
332     *  that remapped to the same logical register index.
333     */
334    PhysRegIndex prevDestRegIdx(int idx) const
335    {
336        return _prevDestRegIdx[idx];
337    }
338
339    /** Renames a destination register to a physical register.  Also records
340     *  the previous physical register that the logical register mapped to.
341     */
342    void renameDestReg(int idx,
343                       PhysRegIndex renamed_dest,
344                       PhysRegIndex previous_rename)
345    {
346        _destRegIdx[idx] = renamed_dest;
347        _prevDestRegIdx[idx] = previous_rename;
348    }
349
350    /** Renames a source logical register to the physical register which
351     *  has/will produce that logical register's result.
352     *  @todo: add in whether or not the source register is ready.
353     */
354    void renameSrcReg(int idx, PhysRegIndex renamed_src)
355    {
356        _srcRegIdx[idx] = renamed_src;
357    }
358
359    /** Flattens a source architectural register index into a logical index.
360     */
361    void flattenSrcReg(int idx, TheISA::RegIndex flattened_src)
362    {
363        _flatSrcRegIdx[idx] = flattened_src;
364    }
365
366    /** Flattens a destination architectural register index into a logical
367     * index.
368     */
369    void flattenDestReg(int idx, TheISA::RegIndex flattened_dest)
370    {
371        _flatDestRegIdx[idx] = flattened_dest;
372    }
373    /** BaseDynInst constructor given a binary instruction.
374     *  @param staticInst A StaticInstPtr to the underlying instruction.
375     *  @param PC The PC of the instruction.
376     *  @param pred_PC The predicted next PC.
377     *  @param pred_NPC The predicted next NPC.
378     *  @param seq_num The sequence number of the instruction.
379     *  @param cpu Pointer to the instruction's CPU.
380     */
381    BaseDynInst(StaticInstPtr staticInst, Addr PC, Addr NPC, Addr microPC,
382            Addr pred_PC, Addr pred_NPC, Addr pred_MicroPC,
383            InstSeqNum seq_num, ImplCPU *cpu);
384
385    /** BaseDynInst constructor given a binary instruction.
386     *  @param inst The binary instruction.
387     *  @param PC The PC of the instruction.
388     *  @param pred_PC The predicted next PC.
389     *  @param pred_NPC The predicted next NPC.
390     *  @param seq_num The sequence number of the instruction.
391     *  @param cpu Pointer to the instruction's CPU.
392     */
393    BaseDynInst(TheISA::ExtMachInst inst, Addr PC, Addr NPC, Addr microPC,
394            Addr pred_PC, Addr pred_NPC, Addr pred_MicroPC,
395            InstSeqNum seq_num, ImplCPU *cpu);
396
397    /** BaseDynInst constructor given a StaticInst pointer.
398     *  @param _staticInst The StaticInst for this BaseDynInst.
399     */
400    BaseDynInst(StaticInstPtr &_staticInst);
401
402    /** BaseDynInst destructor. */
403    ~BaseDynInst();
404
405  private:
406    /** Function to initialize variables in the constructors. */
407    void initVars();
408
409  public:
410    /** Dumps out contents of this BaseDynInst. */
411    void dump();
412
413    /** Dumps out contents of this BaseDynInst into given string. */
414    void dump(std::string &outstring);
415
416    /** Read this CPU's ID. */
417    int cpuId() { return cpu->cpuId(); }
418
419    /** Read this context's system-wide ID **/
420    int contextId() { return thread->contextId(); }
421
422    /** Returns the fault type. */
423    Fault getFault() { return fault; }
424
425    /** Checks whether or not this instruction has had its branch target
426     *  calculated yet.  For now it is not utilized and is hacked to be
427     *  always false.
428     *  @todo: Actually use this instruction.
429     */
430    bool doneTargCalc() { return false; }
431
432    /** Returns the next PC.  This could be the speculative next PC if it is
433     *  called prior to the actual branch target being calculated.
434     */
435    Addr readNextPC() { return nextPC; }
436
437    /** Returns the next NPC.  This could be the speculative next NPC if it is
438     *  called prior to the actual branch target being calculated.
439     */
440    Addr readNextNPC()
441    {
442#if ISA_HAS_DELAY_SLOT
443        return nextNPC;
444#else
445        return nextPC + sizeof(TheISA::MachInst);
446#endif
447    }
448
449    Addr readNextMicroPC()
450    {
451        return nextMicroPC;
452    }
453
454    /** Set the predicted target of this current instruction. */
455    void setPredTarg(Addr predicted_PC, Addr predicted_NPC,
456            Addr predicted_MicroPC)
457    {
458        predPC = predicted_PC;
459        predNPC = predicted_NPC;
460        predMicroPC = predicted_MicroPC;
461    }
462
463    /** Returns the predicted PC immediately after the branch. */
464    Addr readPredPC() { return predPC; }
465
466    /** Returns the predicted PC two instructions after the branch */
467    Addr readPredNPC() { return predNPC; }
468
469    /** Returns the predicted micro PC after the branch */
470    Addr readPredMicroPC() { return predMicroPC; }
471
472    /** Returns whether the instruction was predicted taken or not. */
473    bool readPredTaken()
474    {
475        return predTaken;
476    }
477
478    void setPredTaken(bool predicted_taken)
479    {
480        predTaken = predicted_taken;
481    }
482
483    /** Returns whether the instruction mispredicted. */
484    bool mispredicted()
485    {
486        return readPredPC() != readNextPC() ||
487            readPredNPC() != readNextNPC() ||
488            readPredMicroPC() != readNextMicroPC();
489    }
490
491    //
492    //  Instruction types.  Forward checks to StaticInst object.
493    //
494    bool isNop()          const { return staticInst->isNop(); }
495    bool isMemRef()       const { return staticInst->isMemRef(); }
496    bool isLoad()         const { return staticInst->isLoad(); }
497    bool isStore()        const { return staticInst->isStore(); }
498    bool isStoreConditional() const
499    { return staticInst->isStoreConditional(); }
500    bool isInstPrefetch() const { return staticInst->isInstPrefetch(); }
501    bool isDataPrefetch() const { return staticInst->isDataPrefetch(); }
502    bool isCopy()         const { return staticInst->isCopy(); }
503    bool isInteger()      const { return staticInst->isInteger(); }
504    bool isFloating()     const { return staticInst->isFloating(); }
505    bool isControl()      const { return staticInst->isControl(); }
506    bool isCall()         const { return staticInst->isCall(); }
507    bool isReturn()       const { return staticInst->isReturn(); }
508    bool isDirectCtrl()   const { return staticInst->isDirectCtrl(); }
509    bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); }
510    bool isCondCtrl()     const { return staticInst->isCondCtrl(); }
511    bool isUncondCtrl()   const { return staticInst->isUncondCtrl(); }
512    bool isCondDelaySlot() const { return staticInst->isCondDelaySlot(); }
513    bool isThreadSync()   const { return staticInst->isThreadSync(); }
514    bool isSerializing()  const { return staticInst->isSerializing(); }
515    bool isSerializeBefore() const
516    { return staticInst->isSerializeBefore() || status[SerializeBefore]; }
517    bool isSerializeAfter() const
518    { return staticInst->isSerializeAfter() || status[SerializeAfter]; }
519    bool isMemBarrier()   const { return staticInst->isMemBarrier(); }
520    bool isWriteBarrier() const { return staticInst->isWriteBarrier(); }
521    bool isNonSpeculative() const { return staticInst->isNonSpeculative(); }
522    bool isQuiesce() const { return staticInst->isQuiesce(); }
523    bool isIprAccess() const { return staticInst->isIprAccess(); }
524    bool isUnverifiable() const { return staticInst->isUnverifiable(); }
525    bool isSyscall() const { return staticInst->isSyscall(); }
526    bool isMacroop() const { return staticInst->isMacroop(); }
527    bool isMicroop() const { return staticInst->isMicroop(); }
528    bool isDelayedCommit() const { return staticInst->isDelayedCommit(); }
529    bool isLastMicroop() const { return staticInst->isLastMicroop(); }
530    bool isFirstMicroop() const { return staticInst->isFirstMicroop(); }
531    bool isMicroBranch() const { return staticInst->isMicroBranch(); }
532
533    /** Temporarily sets this instruction as a serialize before instruction. */
534    void setSerializeBefore() { status.set(SerializeBefore); }
535
536    /** Clears the serializeBefore part of this instruction. */
537    void clearSerializeBefore() { status.reset(SerializeBefore); }
538
539    /** Checks if this serializeBefore is only temporarily set. */
540    bool isTempSerializeBefore() { return status[SerializeBefore]; }
541
542    /** Temporarily sets this instruction as a serialize after instruction. */
543    void setSerializeAfter() { status.set(SerializeAfter); }
544
545    /** Clears the serializeAfter part of this instruction.*/
546    void clearSerializeAfter() { status.reset(SerializeAfter); }
547
548    /** Checks if this serializeAfter is only temporarily set. */
549    bool isTempSerializeAfter() { return status[SerializeAfter]; }
550
551    /** Sets the serialization part of this instruction as handled. */
552    void setSerializeHandled() { status.set(SerializeHandled); }
553
554    /** Checks if the serialization part of this instruction has been
555     *  handled.  This does not apply to the temporary serializing
556     *  state; it only applies to this instruction's own permanent
557     *  serializing state.
558     */
559    bool isSerializeHandled() { return status[SerializeHandled]; }
560
561    /** Returns the opclass of this instruction. */
562    OpClass opClass() const { return staticInst->opClass(); }
563
564    /** Returns the branch target address. */
565    Addr branchTarget() const { return staticInst->branchTarget(PC); }
566
567    /** Returns the number of source registers. */
568    int8_t numSrcRegs() const { return staticInst->numSrcRegs(); }
569
570    /** Returns the number of destination registers. */
571    int8_t numDestRegs() const { return staticInst->numDestRegs(); }
572
573    // the following are used to track physical register usage
574    // for machines with separate int & FP reg files
575    int8_t numFPDestRegs()  const { return staticInst->numFPDestRegs(); }
576    int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); }
577
578    /** Returns the logical register index of the i'th destination register. */
579    RegIndex destRegIdx(int i) const { return staticInst->destRegIdx(i); }
580
581    /** Returns the logical register index of the i'th source register. */
582    RegIndex srcRegIdx(int i) const { return staticInst->srcRegIdx(i); }
583
584    /** Returns the result of an integer instruction. */
585    uint64_t readIntResult() { return instResult.integer; }
586
587    /** Returns the result of a floating point instruction. */
588    float readFloatResult() { return (float)instResult.dbl; }
589
590    /** Returns the result of a floating point (double) instruction. */
591    double readDoubleResult() { return instResult.dbl; }
592
593    /** Records an integer register being set to a value. */
594    void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
595    {
596        if (recordResult)
597            instResult.integer = val;
598    }
599
600    /** Records an fp register being set to a value. */
601    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
602                            int width)
603    {
604        if (recordResult) {
605            if (width == 32)
606                instResult.dbl = (double)val;
607            else if (width == 64)
608                instResult.dbl = val;
609            else
610                panic("Unsupported width!");
611        }
612    }
613
614    /** Records an fp register being set to a value. */
615    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
616    {
617        if (recordResult)
618            instResult.dbl = (double)val;
619    }
620
621    /** Records an fp register being set to an integer value. */
622    void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val,
623                                int width)
624    {
625        if (recordResult)
626            instResult.integer = val;
627    }
628
629    /** Records an fp register being set to an integer value. */
630    void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val)
631    {
632        if (recordResult)
633            instResult.integer = val;
634    }
635
636    /** Records that one of the source registers is ready. */
637    void markSrcRegReady();
638
639    /** Marks a specific register as ready. */
640    void markSrcRegReady(RegIndex src_idx);
641
642    /** Returns if a source register is ready. */
643    bool isReadySrcRegIdx(int idx) const
644    {
645        return this->_readySrcRegIdx[idx];
646    }
647
648    /** Sets this instruction as completed. */
649    void setCompleted() { status.set(Completed); }
650
651    /** Returns whether or not this instruction is completed. */
652    bool isCompleted() const { return status[Completed]; }
653
654    /** Marks the result as ready. */
655    void setResultReady() { status.set(ResultReady); }
656
657    /** Returns whether or not the result is ready. */
658    bool isResultReady() const { return status[ResultReady]; }
659
660    /** Sets this instruction as ready to issue. */
661    void setCanIssue() { status.set(CanIssue); }
662
663    /** Returns whether or not this instruction is ready to issue. */
664    bool readyToIssue() const { return status[CanIssue]; }
665
666    /** Clears this instruction being able to issue. */
667    void clearCanIssue() { status.reset(CanIssue); }
668
669    /** Sets this instruction as issued from the IQ. */
670    void setIssued() { status.set(Issued); }
671
672    /** Returns whether or not this instruction has issued. */
673    bool isIssued() const { return status[Issued]; }
674
675    /** Clears this instruction as being issued. */
676    void clearIssued() { status.reset(Issued); }
677
678    /** Sets this instruction as executed. */
679    void setExecuted() { status.set(Executed); }
680
681    /** Returns whether or not this instruction has executed. */
682    bool isExecuted() const { return status[Executed]; }
683
684    /** Sets this instruction as ready to commit. */
685    void setCanCommit() { status.set(CanCommit); }
686
687    /** Clears this instruction as being ready to commit. */
688    void clearCanCommit() { status.reset(CanCommit); }
689
690    /** Returns whether or not this instruction is ready to commit. */
691    bool readyToCommit() const { return status[CanCommit]; }
692
693    void setAtCommit() { status.set(AtCommit); }
694
695    bool isAtCommit() { return status[AtCommit]; }
696
697    /** Sets this instruction as committed. */
698    void setCommitted() { status.set(Committed); }
699
700    /** Returns whether or not this instruction is committed. */
701    bool isCommitted() const { return status[Committed]; }
702
703    /** Sets this instruction as squashed. */
704    void setSquashed() { status.set(Squashed); }
705
706    /** Returns whether or not this instruction is squashed. */
707    bool isSquashed() const { return status[Squashed]; }
708
709    //Instruction Queue Entry
710    //-----------------------
711    /** Sets this instruction as a entry the IQ. */
712    void setInIQ() { status.set(IqEntry); }
713
714    /** Sets this instruction as a entry the IQ. */
715    void clearInIQ() { status.reset(IqEntry); }
716
717    /** Returns whether or not this instruction has issued. */
718    bool isInIQ() const { return status[IqEntry]; }
719
720    /** Sets this instruction as squashed in the IQ. */
721    void setSquashedInIQ() { status.set(SquashedInIQ); status.set(Squashed);}
722
723    /** Returns whether or not this instruction is squashed in the IQ. */
724    bool isSquashedInIQ() const { return status[SquashedInIQ]; }
725
726
727    //Load / Store Queue Functions
728    //-----------------------
729    /** Sets this instruction as a entry the LSQ. */
730    void setInLSQ() { status.set(LsqEntry); }
731
732    /** Sets this instruction as a entry the LSQ. */
733    void removeInLSQ() { status.reset(LsqEntry); }
734
735    /** Returns whether or not this instruction is in the LSQ. */
736    bool isInLSQ() const { return status[LsqEntry]; }
737
738    /** Sets this instruction as squashed in the LSQ. */
739    void setSquashedInLSQ() { status.set(SquashedInLSQ);}
740
741    /** Returns whether or not this instruction is squashed in the LSQ. */
742    bool isSquashedInLSQ() const { return status[SquashedInLSQ]; }
743
744
745    //Reorder Buffer Functions
746    //-----------------------
747    /** Sets this instruction as a entry the ROB. */
748    void setInROB() { status.set(RobEntry); }
749
750    /** Sets this instruction as a entry the ROB. */
751    void clearInROB() { status.reset(RobEntry); }
752
753    /** Returns whether or not this instruction is in the ROB. */
754    bool isInROB() const { return status[RobEntry]; }
755
756    /** Sets this instruction as squashed in the ROB. */
757    void setSquashedInROB() { status.set(SquashedInROB); }
758
759    /** Returns whether or not this instruction is squashed in the ROB. */
760    bool isSquashedInROB() const { return status[SquashedInROB]; }
761
762    /** Read the PC of this instruction. */
763    const Addr readPC() const { return PC; }
764
765    /**Read the micro PC of this instruction. */
766    const Addr readMicroPC() const { return microPC; }
767
768    /** Set the next PC of this instruction (its actual target). */
769    void setNextPC(Addr val)
770    {
771        nextPC = val;
772    }
773
774    /** Set the next NPC of this instruction (the target in Mips or Sparc).*/
775    void setNextNPC(Addr val)
776    {
777#if ISA_HAS_DELAY_SLOT
778        nextNPC = val;
779#endif
780    }
781
782    void setNextMicroPC(Addr val)
783    {
784        nextMicroPC = val;
785    }
786
787    /** Sets the ASID. */
788    void setASID(short addr_space_id) { asid = addr_space_id; }
789
790    /** Sets the thread id. */
791    void setTid(ThreadID tid) { threadNumber = tid; }
792
793    /** Sets the pointer to the thread state. */
794    void setThreadState(ImplState *state) { thread = state; }
795
796    /** Returns the thread context. */
797    ThreadContext *tcBase() { return thread->getTC(); }
798
799  private:
800    /** Instruction effective address.
801     *  @todo: Consider if this is necessary or not.
802     */
803    Addr instEffAddr;
804
805    /** Whether or not the effective address calculation is completed.
806     *  @todo: Consider if this is necessary or not.
807     */
808    bool eaCalcDone;
809
810    /** Is this instruction's memory access uncacheable. */
811    bool isUncacheable;
812
813    /** Has this instruction generated a memory request. */
814    bool reqMade;
815
816  public:
817    /** Sets the effective address. */
818    void setEA(Addr &ea) { instEffAddr = ea; eaCalcDone = true; }
819
820    /** Returns the effective address. */
821    const Addr &getEA() const { return instEffAddr; }
822
823    /** Returns whether or not the eff. addr. calculation has been completed. */
824    bool doneEACalc() { return eaCalcDone; }
825
826    /** Returns whether or not the eff. addr. source registers are ready. */
827    bool eaSrcsReady();
828
829    /** Whether or not the memory operation is done. */
830    bool memOpDone;
831
832    /** Is this instruction's memory access uncacheable. */
833    bool uncacheable() { return isUncacheable; }
834
835    /** Has this instruction generated a memory request. */
836    bool hasRequest() { return reqMade; }
837
838  public:
839    /** Load queue index. */
840    int16_t lqIdx;
841
842    /** Store queue index. */
843    int16_t sqIdx;
844
845    /** Iterator pointing to this BaseDynInst in the list of all insts. */
846    ListIt instListIt;
847
848    /** Returns iterator to this instruction in the list of all insts. */
849    ListIt &getInstListIt() { return instListIt; }
850
851    /** Sets iterator for this instruction in the list of all insts. */
852    void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; }
853
854  public:
855    /** Returns the number of consecutive store conditional failures. */
856    unsigned readStCondFailures()
857    { return thread->storeCondFailures; }
858
859    /** Sets the number of consecutive store conditional failures. */
860    void setStCondFailures(unsigned sc_failures)
861    { thread->storeCondFailures = sc_failures; }
862};
863
864template<class Impl>
865template<class T>
866inline Fault
867BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags)
868{
869    reqMade = true;
870    Request *req = new Request(asid, addr, sizeof(T), flags, this->PC,
871                               thread->contextId(), threadNumber);
872
873    initiateTranslation(req, NULL, BaseTLB::Read);
874
875    if (fault == NoFault) {
876        effAddr = req->getVaddr();
877        effAddrValid = true;
878        cpu->read(req, data, lqIdx);
879    } else {
880
881        // Return a fixed value to keep simulation deterministic even
882        // along misspeculated paths.
883        data = (T)-1;
884
885        // Commit will have to clean up whatever happened.  Set this
886        // instruction as executed.
887        this->setExecuted();
888    }
889
890    if (traceData) {
891        traceData->setAddr(addr);
892        traceData->setData(data);
893    }
894
895    return fault;
896}
897
898template<class Impl>
899template<class T>
900inline Fault
901BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res)
902{
903    if (traceData) {
904        traceData->setAddr(addr);
905        traceData->setData(data);
906    }
907
908    reqMade = true;
909    Request *req = new Request(asid, addr, sizeof(T), flags, this->PC,
910                               thread->contextId(), threadNumber);
911
912    initiateTranslation(req, res, BaseTLB::Write);
913
914    if (fault == NoFault) {
915        effAddr = req->getVaddr();
916        effAddrValid = true;
917        cpu->write(req, data, sqIdx);
918    }
919
920    return fault;
921}
922
923template<class Impl>
924inline void
925BaseDynInst<Impl>::initiateTranslation(RequestPtr req, uint64_t *res,
926                                       BaseTLB::Mode mode)
927{
928    WholeTranslationState *state =
929        new WholeTranslationState(req, NULL, res, mode);
930    DataTranslation<BaseDynInst<Impl> > *trans =
931        new DataTranslation<BaseDynInst<Impl> >(this, state);
932    cpu->dtb->translateTiming(req, thread->getTC(), trans, mode);
933}
934
935template<class Impl>
936inline void
937BaseDynInst<Impl>::finishTranslation(WholeTranslationState *state)
938{
939    fault = state->getFault();
940
941    if (state->isUncacheable())
942        isUncacheable = true;
943
944    if (fault == NoFault) {
945        physEffAddr = state->getPaddr();
946        memReqFlags = state->getFlags();
947
948        if (state->mainReq->isCondSwap()) {
949            assert(state->res);
950            state->mainReq->setExtraData(*state->res);
951        }
952
953    } else {
954        state->deleteReqs();
955    }
956    delete state;
957}
958
959#endif // __CPU_BASE_DYN_INST_HH__
960