dyn_inst.hh revision 13954
11689SN/A/* 27944SGiacomo.Gabrielli@arm.com * Copyright (c) 2013-2014 ARM Limited 37944SGiacomo.Gabrielli@arm.com * All rights reserved 47944SGiacomo.Gabrielli@arm.com * 57944SGiacomo.Gabrielli@arm.com * The license below extends only to copyright in the software and shall 67944SGiacomo.Gabrielli@arm.com * not be construed as granting a license to any other intellectual 77944SGiacomo.Gabrielli@arm.com * property including but not limited to intellectual property relating 87944SGiacomo.Gabrielli@arm.com * to a hardware implementation of the functionality of the software 97944SGiacomo.Gabrielli@arm.com * licensed hereunder. You may use the software subject to the license 107944SGiacomo.Gabrielli@arm.com * terms below provided that you ensure that this notice is replicated 117944SGiacomo.Gabrielli@arm.com * unmodified and in its entirety in all distributions of the software, 127944SGiacomo.Gabrielli@arm.com * modified or unmodified, in source code or in binary form. 137944SGiacomo.Gabrielli@arm.com * 142326SN/A * Redistribution and use in source and binary forms, with or without 151689SN/A * modification, are permitted provided that the following conditions are 161689SN/A * met: redistributions of source code must retain the above copyright 171689SN/A * notice, this list of conditions and the following disclaimer; 181689SN/A * redistributions in binary form must reproduce the above copyright 191689SN/A * notice, this list of conditions and the following disclaimer in the 201689SN/A * documentation and/or other materials provided with the distribution; 211689SN/A * neither the name of the copyright holders nor the names of its 221689SN/A * contributors may be used to endorse or promote products derived from 231689SN/A * this software without specific prior written permission. 241689SN/A * 251689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 261689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 271689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 281689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 291689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 301689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 311689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 321689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 331689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 341689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 351689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 361689SN/A * 371689SN/A * Authors: Andrew Bardsley 381689SN/A */ 392665Ssaidi@eecs.umich.edu 402665Ssaidi@eecs.umich.edu/** 411689SN/A * @file 421689SN/A * 432292SN/A * The dynamic instruction and instruction/line id (sequence numbers) 442292SN/A * definition for Minor. A spirited attempt is made here to not carry too 451060SN/A * much on this structure. 461060SN/A */ 471061SN/A 481060SN/A#ifndef __CPU_MINOR_DYN_INST_HH__ 491061SN/A#define __CPU_MINOR_DYN_INST_HH__ 501060SN/A 511062SN/A#include <iostream> 527813Ssteve.reinhardt@amd.com 536216Snate@binkert.org#include "base/refcnt.hh" 541061SN/A#include "cpu/minor/buffers.hh" 552326SN/A#include "cpu/inst_seq.hh" 562669Sktlim@umich.edu#include "cpu/static_inst.hh" 575529Snate@binkert.org#include "cpu/timing_expr.hh" 581060SN/A#include "sim/faults.hh" 595529Snate@binkert.org 602292SN/Anamespace Minor 612292SN/A{ 622292SN/A 631060SN/Aclass MinorDynInst; 641689SN/A 651689SN/A/** MinorDynInsts are currently reference counted. */ 661689SN/Atypedef RefCountingPtr<MinorDynInst> MinorDynInstPtr; 671689SN/A 681060SN/A/** Id for lines and instructions. This includes all the relevant sequence 691060SN/A * numbers and thread ids for all stages of execution. */ 701060SN/Aclass InstId 712292SN/A{ 722292SN/A public: 732292SN/A /** First sequence numbers to use in initialisation of the pipeline and 742292SN/A * to be expected on the first line/instruction issued */ 752292SN/A static const InstSeqNum firstStreamSeqNum = 1; 762292SN/A static const InstSeqNum firstPredictionSeqNum = 1; 772292SN/A static const InstSeqNum firstLineSeqNum = 1; 782292SN/A static const InstSeqNum firstFetchSeqNum = 1; 791060SN/A static const InstSeqNum firstExecSeqNum = 1; 801061SN/A 811060SN/A public: 821060SN/A /** The thread to which this line/instruction belongs */ 831060SN/A ThreadID threadId; 841060SN/A 852733Sktlim@umich.edu /** The 'stream' this instruction belongs to. Streams are interrupted 861061SN/A * (and sequence numbers increased) when Execute finds it wants to 871060SN/A * change the stream of instructions due to a branch. */ 882292SN/A InstSeqNum streamSeqNum; 891061SN/A 901061SN/A /** The predicted qualifier to stream, attached by Fetch2 as a 911061SN/A * consequence of branch prediction */ 921060SN/A InstSeqNum predictionSeqNum; 932292SN/A 941061SN/A /** Line sequence number. This is the sequence number of the fetched 951060SN/A * line from which this instruction was fetched */ 962733Sktlim@umich.edu InstSeqNum lineSeqNum; 972292SN/A 982292SN/A /** Fetch sequence number. This is 0 for bubbles and an ascending 992292SN/A * sequence for the stream of all fetched instructions */ 1002292SN/A InstSeqNum fetchSeqNum; 1012292SN/A 1022292SN/A /** 'Execute' sequence number. These are assigned after micro-op 1032292SN/A * decomposition and form an ascending sequence (starting with 1) for 1042292SN/A * post-micro-op decomposed instructions. */ 1052292SN/A InstSeqNum execSeqNum; 1062292SN/A 1072292SN/A public: 1082292SN/A /** Very boring default constructor */ 1092292SN/A InstId( 1102348SN/A ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0, 1112348SN/A InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0, 1122348SN/A InstSeqNum fetch_seq_num = 0, InstSeqNum exec_seq_num = 0) : 1132326SN/A threadId(thread_id), streamSeqNum(stream_seq_num), 1142326SN/A predictionSeqNum(prediction_seq_num), lineSeqNum(line_seq_num), 1152292SN/A fetchSeqNum(fetch_seq_num), execSeqNum(exec_seq_num) 1162292SN/A { } 1172292SN/A 1182292SN/A public: 1192292SN/A /* Equal if the thread and last set sequence number matches */ 1202292SN/A bool 1215336Shines@cs.fsu.edu operator== (const InstId &rhs) 1222326SN/A { 1231060SN/A /* If any of fetch and exec sequence number are not set 1241060SN/A * they need to be 0, so a straight comparison is still 1252292SN/A * fine */ 1265529Snate@binkert.org bool ret = (threadId == rhs.threadId && 1271061SN/A lineSeqNum == rhs.lineSeqNum && 1282292SN/A fetchSeqNum == rhs.fetchSeqNum && 1292292SN/A execSeqNum == rhs.execSeqNum); 1301061SN/A 1312292SN/A /* Stream and prediction *must* match if these are the same id */ 1322292SN/A if (ret) { 1331060SN/A assert(streamSeqNum == rhs.streamSeqNum && 1342292SN/A predictionSeqNum == rhs.predictionSeqNum); 1351062SN/A } 1361062SN/A 1372348SN/A return ret; 1382307SN/A } 1391060SN/A}; 1402292SN/A 1416221Snate@binkert.org/** Print this id in the usual slash-separated format expected by 1422292SN/A * MinorTrace */ 1432292SN/Astd::ostream &operator <<(std::ostream &os, const InstId &id); 1441060SN/A 1451060SN/Aclass MinorDynInst; 1462292SN/A 1471060SN/A/** Print a short reference to this instruction. '-' for a bubble and a 1481060SN/A * series of '/' separated sequence numbers for other instructions. The 1492348SN/A * sequence numbers will be in the order: stream, prediction, line, fetch, 1502307SN/A * exec with exec absent if it is 0. This is used by MinorTrace. */ 1512307SN/Astd::ostream &operator <<(std::ostream &os, const MinorDynInst &inst); 1522348SN/A 1532307SN/A/** Dynamic instruction for Minor. 1542307SN/A * MinorDynInst implements the BubbleIF interface 1552348SN/A * Has two separate notions of sequence number for pre/post-micro-op 1562307SN/A * decomposition: fetchSeqNum and execSeqNum */ 1572307SN/Aclass MinorDynInst : public RefCounted 1582292SN/A{ 1596221Snate@binkert.org private: 1602292SN/A /** A prototypical bubble instruction. You must call MinorDynInst::init 1612292SN/A * to initialise this */ 1622292SN/A static MinorDynInstPtr bubbleInst; 1632292SN/A 1642292SN/A public: 1651060SN/A StaticInstPtr staticInst; 1661060SN/A 1672292SN/A InstId id; 1686221Snate@binkert.org 1692292SN/A /** Trace information for this instruction's execution */ 1702292SN/A Trace::InstRecord *traceData; 1711060SN/A 1721060SN/A /** The fetch address of this instruction */ 1732292SN/A TheISA::PCState pc; 1746221Snate@binkert.org 1752292SN/A /** This is actually a fault masquerading as an instruction */ 1762292SN/A Fault fault; 1772292SN/A 1782292SN/A /** Tried to predict the destination of this inst (if a control 1792292SN/A * instruction or a sys call) */ 1801061SN/A bool triedToPredict; 1811060SN/A 1822292SN/A /** This instruction was predicted to change control flow and 1831061SN/A * the following instructions will have a newer predictionSeqNum */ 1841061SN/A bool predictedTaken; 1852292SN/A 1862292SN/A /** Predicted branch target */ 1872292SN/A TheISA::PCState predictedTarget; 1882292SN/A 1891060SN/A /** Fields only set during execution */ 1902348SN/A 1912348SN/A /** FU this instruction is issued to */ 1922348SN/A unsigned int fuIndex; 1932333SN/A 1942333SN/A /** This instruction is in the LSQ, not a functional unit */ 1957944SGiacomo.Gabrielli@arm.com bool inLSQ; 1967944SGiacomo.Gabrielli@arm.com 1977944SGiacomo.Gabrielli@arm.com /** The instruction has been sent to the store buffer */ 1987944SGiacomo.Gabrielli@arm.com bool inStoreBuffer; 1997944SGiacomo.Gabrielli@arm.com 2002292SN/A /** Can this instruction be executed out of order. In this model, 2012326SN/A * this only happens with mem refs that need to be issued early 2022326SN/A * to allow other instructions to fill the fetch delay */ 2032292SN/A bool canEarlyIssue; 2042326SN/A 2052326SN/A /** Flag controlling conditional execution of the instruction */ 2061755SN/A bool predicate; 2072292SN/A 2082292SN/A /** Flag controlling conditional execution of the memory access associated 2092292SN/A * with the instruction (only meaningful for loads/stores) */ 2102292SN/A bool memAccPredicate; 2112292SN/A 2122292SN/A /** execSeqNum of the latest inst on which this inst depends. 2132292SN/A * This can be used as a sanity check for dependency ordering 2141060SN/A * where slightly out of order execution is required (notably 2151060SN/A * initiateAcc for memory ops) */ 2162292SN/A InstSeqNum instToWaitFor; 2171061SN/A 2181061SN/A /** Extra delay at the end of the pipeline */ 2192292SN/A Cycles extraCommitDelay; 2202292SN/A TimingExpr *extraCommitDelayExpr; 2212292SN/A 2222292SN/A /** Once issued, extraCommitDelay becomes minimumCommitCycle 2236221Snate@binkert.org * to account for delay in absolute time */ 2241061SN/A Cycles minimumCommitCycle; 2252292SN/A 2262301SN/A /** Flat register indices so that, when clearing the scoreboard, we 2271755SN/A * have the same register indices as when the instruction was marked 2282292SN/A * up */ 2292292SN/A RegId flatDestRegIdx[TheISA::MaxInstDestRegs]; 2302292SN/A 2312292SN/A public: 2322292SN/A MinorDynInst(InstId id_ = InstId(), Fault fault_ = NoFault) : 2332292SN/A staticInst(NULL), id(id_), traceData(NULL), 2342292SN/A pc(TheISA::PCState(0)), fault(fault_), 2352292SN/A triedToPredict(false), predictedTaken(false), 2362292SN/A fuIndex(0), inLSQ(false), inStoreBuffer(false), 2372292SN/A canEarlyIssue(false), predicate(true), memAccPredicate(true), 2382292SN/A instToWaitFor(0), extraCommitDelay(Cycles(0)), 2392292SN/A extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0)) 2402292SN/A { } 2412292SN/A 2422292SN/A public: 2437944SGiacomo.Gabrielli@arm.com /** The BubbleIF interface. */ 2447944SGiacomo.Gabrielli@arm.com bool isBubble() const { return id.fetchSeqNum == 0; } 2457944SGiacomo.Gabrielli@arm.com 2467944SGiacomo.Gabrielli@arm.com /** There is a single bubble inst */ 2477944SGiacomo.Gabrielli@arm.com static MinorDynInstPtr bubble() { return bubbleInst; } 2487944SGiacomo.Gabrielli@arm.com 2492292SN/A /** Is this a fault rather than instruction */ 2501061SN/A bool isFault() const { return fault != NoFault; } 2511061SN/A 2522292SN/A /** Is this a real instruction */ 2532292SN/A bool isInst() const { return !isBubble() && !isFault(); } 2542292SN/A 2552292SN/A /** Is this a real mem ref instruction */ 2566221Snate@binkert.org bool isMemRef() const { return isInst() && staticInst->isMemRef(); } 2571060SN/A 2582292SN/A /** Is this an instruction that can be executed `for free' and 2596221Snate@binkert.org * needn't spend time in an FU */ 2601060SN/A bool isNoCostInst() const; 2612292SN/A 2622292SN/A /** Assuming this is not a fault, is this instruction either 2631060SN/A * a whole instruction or the last microop from a macroop */ 2641060SN/A bool isLastOpInInst() const; 2652292SN/A 2666221Snate@binkert.org /** Initialise the class */ 2672292SN/A static void init(); 2682292SN/A 2692292SN/A /** Print (possibly verbose) instruction information for 2702292SN/A * MinorTrace using the given Named object's name */ 2712292SN/A void minorTraceInst(const Named &named_object) const; 2721060SN/A 2732733Sktlim@umich.edu /** ReportIF interface */ 2741060SN/A void reportData(std::ostream &os) const; 2752292SN/A 2762292SN/A bool readPredicate() const { return predicate; } 2772292SN/A 2782292SN/A void setPredicate(bool val) { predicate = val; } 2792292SN/A 2802292SN/A bool readMemAccPredicate() const { return memAccPredicate; } 2811061SN/A 2821061SN/A void setMemAccPredicate(bool val) { memAccPredicate = val; } 2831061SN/A 2842292SN/A ~MinorDynInst(); 2851061SN/A}; 2861060SN/A 2871060SN/A/** Print a summary of the instruction */ 2881060SN/Astd::ostream &operator <<(std::ostream &os, const MinorDynInst &inst); 2891060SN/A 2901060SN/A} 2911060SN/A 2921060SN/A#endif /* __CPU_MINOR_DYN_INST_HH__ */ 2931060SN/A