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