| /* | |
| * Copyright (c) 2013-2014 ARM Limited | |
| * All rights reserved | |
| * | |
| * The license below extends only to copyright in the software and shall | |
| * not be construed as granting a license to any other intellectual | |
| * property including but not limited to intellectual property relating | |
| * to a hardware implementation of the functionality of the software | |
| * licensed hereunder. You may use the software subject to the license | |
| * terms below provided that you ensure that this notice is replicated | |
| * unmodified and in its entirety in all distributions of the software, | |
| * modified or unmodified, in source code or in binary form. | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions are | |
| * met: redistributions of source code must retain the above copyright | |
| * notice, this list of conditions and the following disclaimer; | |
| * redistributions in binary form must reproduce the above copyright | |
| * notice, this list of conditions and the following disclaimer in the | |
| * documentation and/or other materials provided with the distribution; | |
| * neither the name of the copyright holders nor the names of its | |
| * contributors may be used to endorse or promote products derived from | |
| * this software without specific prior written permission. | |
| * | |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| * | |
| * Authors: Andrew Bardsley | |
| */ | |
| /** | |
| * @file | |
| * | |
| * The dynamic instruction and instruction/line id (sequence numbers) | |
| * definition for Minor. A spirited attempt is made here to not carry too | |
| * much on this structure. | |
| */ | |
| #ifndef __CPU_MINOR_DYN_INST_HH__ | |
| #define __CPU_MINOR_DYN_INST_HH__ | |
| #include <iostream> | |
| #include "base/refcnt.hh" | |
| #include "cpu/minor/buffers.hh" | |
| #include "cpu/inst_seq.hh" | |
| #include "cpu/static_inst.hh" | |
| #include "cpu/timing_expr.hh" | |
| #include "sim/faults.hh" | |
| namespace Minor | |
| { | |
| class MinorDynInst; | |
| /** MinorDynInsts are currently reference counted. */ | |
| typedef RefCountingPtr<MinorDynInst> MinorDynInstPtr; | |
| /** Id for lines and instructions. This includes all the relevant sequence | |
| * numbers and thread ids for all stages of execution. */ | |
| class InstId | |
| { | |
| public: | |
| /** First sequence numbers to use in initialisation of the pipeline and | |
| * to be expected on the first line/instruction issued */ | |
| static const InstSeqNum firstStreamSeqNum = 1; | |
| static const InstSeqNum firstPredictionSeqNum = 1; | |
| static const InstSeqNum firstLineSeqNum = 1; | |
| static const InstSeqNum firstFetchSeqNum = 1; | |
| static const InstSeqNum firstExecSeqNum = 1; | |
| public: | |
| /** The thread to which this line/instruction belongs */ | |
| ThreadID threadId; | |
| /** The 'stream' this instruction belongs to. Streams are interrupted | |
| * (and sequence numbers increased) when Execute finds it wants to | |
| * change the stream of instructions due to a branch. */ | |
| InstSeqNum streamSeqNum; | |
| /** The predicted qualifier to stream, attached by Fetch2 as a | |
| * consequence of branch prediction */ | |
| InstSeqNum predictionSeqNum; | |
| /** Line sequence number. This is the sequence number of the fetched | |
| * line from which this instruction was fetched */ | |
| InstSeqNum lineSeqNum; | |
| /** Fetch sequence number. This is 0 for bubbles and an ascending | |
| * sequence for the stream of all fetched instructions */ | |
| InstSeqNum fetchSeqNum; | |
| /** 'Execute' sequence number. These are assigned after micro-op | |
| * decomposition and form an ascending sequence (starting with 1) for | |
| * post-micro-op decomposed instructions. */ | |
| InstSeqNum execSeqNum; | |
| public: | |
| /** Very boring default constructor */ | |
| InstId( | |
| ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0, | |
| InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0, | |
| InstSeqNum fetch_seq_num = 0, InstSeqNum exec_seq_num = 0) : | |
| threadId(thread_id), streamSeqNum(stream_seq_num), | |
| predictionSeqNum(prediction_seq_num), lineSeqNum(line_seq_num), | |
| fetchSeqNum(fetch_seq_num), execSeqNum(exec_seq_num) | |
| { } | |
| public: | |
| /* Equal if the thread and last set sequence number matches */ | |
| bool | |
| operator== (const InstId &rhs) | |
| { | |
| /* If any of fetch and exec sequence number are not set | |
| * they need to be 0, so a straight comparison is still | |
| * fine */ | |
| bool ret = (threadId == rhs.threadId && | |
| lineSeqNum == rhs.lineSeqNum && | |
| fetchSeqNum == rhs.fetchSeqNum && | |
| execSeqNum == rhs.execSeqNum); | |
| /* Stream and prediction *must* match if these are the same id */ | |
| if (ret) { | |
| assert(streamSeqNum == rhs.streamSeqNum && | |
| predictionSeqNum == rhs.predictionSeqNum); | |
| } | |
| return ret; | |
| } | |
| }; | |
| /** Print this id in the usual slash-separated format expected by | |
| * MinorTrace */ | |
| std::ostream &operator <<(std::ostream &os, const InstId &id); | |
| class MinorDynInst; | |
| /** Print a short reference to this instruction. '-' for a bubble and a | |
| * series of '/' separated sequence numbers for other instructions. The | |
| * sequence numbers will be in the order: stream, prediction, line, fetch, | |
| * exec with exec absent if it is 0. This is used by MinorTrace. */ | |
| std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst); | |
| /** Dynamic instruction for Minor. | |
| * MinorDynInst implements the BubbleIF interface | |
| * Has two separate notions of sequence number for pre/post-micro-op | |
| * decomposition: fetchSeqNum and execSeqNum */ | |
| class MinorDynInst : public RefCounted | |
| { | |
| private: | |
| /** A prototypical bubble instruction. You must call MinorDynInst::init | |
| * to initialise this */ | |
| static MinorDynInstPtr bubbleInst; | |
| public: | |
| StaticInstPtr staticInst; | |
| InstId id; | |
| /** Trace information for this instruction's execution */ | |
| Trace::InstRecord *traceData; | |
| /** The fetch address of this instruction */ | |
| TheISA::PCState pc; | |
| /** This is actually a fault masquerading as an instruction */ | |
| Fault fault; | |
| /** Tried to predict the destination of this inst (if a control | |
| * instruction or a sys call) */ | |
| bool triedToPredict; | |
| /** This instruction was predicted to change control flow and | |
| * the following instructions will have a newer predictionSeqNum */ | |
| bool predictedTaken; | |
| /** Predicted branch target */ | |
| TheISA::PCState predictedTarget; | |
| /** Fields only set during execution */ | |
| /** FU this instruction is issued to */ | |
| unsigned int fuIndex; | |
| /** This instruction is in the LSQ, not a functional unit */ | |
| bool inLSQ; | |
| /** The instruction has been sent to the store buffer */ | |
| bool inStoreBuffer; | |
| /** Can this instruction be executed out of order. In this model, | |
| * this only happens with mem refs that need to be issued early | |
| * to allow other instructions to fill the fetch delay */ | |
| bool canEarlyIssue; | |
| /** execSeqNum of the latest inst on which this inst depends. | |
| * This can be used as a sanity check for dependency ordering | |
| * where slightly out of order execution is required (notably | |
| * initiateAcc for memory ops) */ | |
| InstSeqNum instToWaitFor; | |
| /** Extra delay at the end of the pipeline */ | |
| Cycles extraCommitDelay; | |
| TimingExpr *extraCommitDelayExpr; | |
| /** Once issued, extraCommitDelay becomes minimumCommitCycle | |
| * to account for delay in absolute time */ | |
| Cycles minimumCommitCycle; | |
| /** Flat register indices so that, when clearing the scoreboard, we | |
| * have the same register indices as when the instruction was marked | |
| * up */ | |
| TheISA::RegIndex flatDestRegIdx[TheISA::MaxInstDestRegs]; | |
| /** Effective address as set by ExecContext::setEA */ | |
| Addr ea; | |
| public: | |
| MinorDynInst(InstId id_ = InstId(), Fault fault_ = NoFault) : | |
| staticInst(NULL), id(id_), traceData(NULL), | |
| pc(TheISA::PCState(0)), fault(fault_), | |
| triedToPredict(false), predictedTaken(false), | |
| fuIndex(0), inLSQ(false), inStoreBuffer(false), | |
| canEarlyIssue(false), | |
| instToWaitFor(0), extraCommitDelay(Cycles(0)), | |
| extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0)), | |
| ea(0) | |
| { } | |
| public: | |
| /** The BubbleIF interface. */ | |
| bool isBubble() const { return id.fetchSeqNum == 0; } | |
| /** There is a single bubble inst */ | |
| static MinorDynInstPtr bubble() { return bubbleInst; } | |
| /** Is this a fault rather than instruction */ | |
| bool isFault() const { return fault != NoFault; } | |
| /** Is this a real instruction */ | |
| bool isInst() const { return !isBubble() && !isFault(); } | |
| /** Is this a real mem ref instruction */ | |
| bool isMemRef() const { return isInst() && staticInst->isMemRef(); } | |
| /** Is this an instruction that can be executed `for free' and | |
| * needn't spend time in an FU */ | |
| bool isNoCostInst() const; | |
| /** Assuming this is not a fault, is this instruction either | |
| * a whole instruction or the last microop from a macroop */ | |
| bool isLastOpInInst() const; | |
| /** Initialise the class */ | |
| static void init(); | |
| /** Print (possibly verbose) instruction information for | |
| * MinorTrace using the given Named object's name */ | |
| void minorTraceInst(const Named &named_object) const; | |
| /** ReportIF interface */ | |
| void reportData(std::ostream &os) const; | |
| ~MinorDynInst(); | |
| }; | |
| /** Print a summary of the instruction */ | |
| std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst); | |
| } | |
| #endif /* __CPU_MINOR_DYN_INST_HH__ */ |