dyn_inst.hh revision 14105
110259SAndrew.Bardsley@arm.com/* 214105Sgabor.dozsa@arm.com * Copyright (c) 2013-2014,2018 ARM Limited 310259SAndrew.Bardsley@arm.com * All rights reserved 410259SAndrew.Bardsley@arm.com * 510259SAndrew.Bardsley@arm.com * The license below extends only to copyright in the software and shall 610259SAndrew.Bardsley@arm.com * not be construed as granting a license to any other intellectual 710259SAndrew.Bardsley@arm.com * property including but not limited to intellectual property relating 810259SAndrew.Bardsley@arm.com * to a hardware implementation of the functionality of the software 910259SAndrew.Bardsley@arm.com * licensed hereunder. You may use the software subject to the license 1010259SAndrew.Bardsley@arm.com * terms below provided that you ensure that this notice is replicated 1110259SAndrew.Bardsley@arm.com * unmodified and in its entirety in all distributions of the software, 1210259SAndrew.Bardsley@arm.com * modified or unmodified, in source code or in binary form. 1310259SAndrew.Bardsley@arm.com * 1410259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without 1510259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are 1610259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright 1710259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer; 1810259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright 1910259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the 2010259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution; 2110259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its 2210259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from 2310259SAndrew.Bardsley@arm.com * this software without specific prior written permission. 2410259SAndrew.Bardsley@arm.com * 2510259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610259SAndrew.Bardsley@arm.com * 3710259SAndrew.Bardsley@arm.com * Authors: Andrew Bardsley 3810259SAndrew.Bardsley@arm.com */ 3910259SAndrew.Bardsley@arm.com 4010259SAndrew.Bardsley@arm.com/** 4110259SAndrew.Bardsley@arm.com * @file 4210259SAndrew.Bardsley@arm.com * 4310259SAndrew.Bardsley@arm.com * The dynamic instruction and instruction/line id (sequence numbers) 4410259SAndrew.Bardsley@arm.com * definition for Minor. A spirited attempt is made here to not carry too 4510259SAndrew.Bardsley@arm.com * much on this structure. 4610259SAndrew.Bardsley@arm.com */ 4710259SAndrew.Bardsley@arm.com 4810259SAndrew.Bardsley@arm.com#ifndef __CPU_MINOR_DYN_INST_HH__ 4910259SAndrew.Bardsley@arm.com#define __CPU_MINOR_DYN_INST_HH__ 5010259SAndrew.Bardsley@arm.com 5110259SAndrew.Bardsley@arm.com#include <iostream> 5210259SAndrew.Bardsley@arm.com 5310259SAndrew.Bardsley@arm.com#include "base/refcnt.hh" 5410259SAndrew.Bardsley@arm.com#include "cpu/minor/buffers.hh" 5510259SAndrew.Bardsley@arm.com#include "cpu/inst_seq.hh" 5610259SAndrew.Bardsley@arm.com#include "cpu/static_inst.hh" 5710259SAndrew.Bardsley@arm.com#include "cpu/timing_expr.hh" 5810259SAndrew.Bardsley@arm.com#include "sim/faults.hh" 5910259SAndrew.Bardsley@arm.com 6010259SAndrew.Bardsley@arm.comnamespace Minor 6110259SAndrew.Bardsley@arm.com{ 6210259SAndrew.Bardsley@arm.com 6310259SAndrew.Bardsley@arm.comclass MinorDynInst; 6410259SAndrew.Bardsley@arm.com 6510259SAndrew.Bardsley@arm.com/** MinorDynInsts are currently reference counted. */ 6610259SAndrew.Bardsley@arm.comtypedef RefCountingPtr<MinorDynInst> MinorDynInstPtr; 6710259SAndrew.Bardsley@arm.com 6810259SAndrew.Bardsley@arm.com/** Id for lines and instructions. This includes all the relevant sequence 6910259SAndrew.Bardsley@arm.com * numbers and thread ids for all stages of execution. */ 7010259SAndrew.Bardsley@arm.comclass InstId 7110259SAndrew.Bardsley@arm.com{ 7210259SAndrew.Bardsley@arm.com public: 7310259SAndrew.Bardsley@arm.com /** First sequence numbers to use in initialisation of the pipeline and 7410259SAndrew.Bardsley@arm.com * to be expected on the first line/instruction issued */ 7510259SAndrew.Bardsley@arm.com static const InstSeqNum firstStreamSeqNum = 1; 7610259SAndrew.Bardsley@arm.com static const InstSeqNum firstPredictionSeqNum = 1; 7710259SAndrew.Bardsley@arm.com static const InstSeqNum firstLineSeqNum = 1; 7810259SAndrew.Bardsley@arm.com static const InstSeqNum firstFetchSeqNum = 1; 7910259SAndrew.Bardsley@arm.com static const InstSeqNum firstExecSeqNum = 1; 8010259SAndrew.Bardsley@arm.com 8110259SAndrew.Bardsley@arm.com public: 8210259SAndrew.Bardsley@arm.com /** The thread to which this line/instruction belongs */ 8310259SAndrew.Bardsley@arm.com ThreadID threadId; 8410259SAndrew.Bardsley@arm.com 8510259SAndrew.Bardsley@arm.com /** The 'stream' this instruction belongs to. Streams are interrupted 8610259SAndrew.Bardsley@arm.com * (and sequence numbers increased) when Execute finds it wants to 8710259SAndrew.Bardsley@arm.com * change the stream of instructions due to a branch. */ 8810259SAndrew.Bardsley@arm.com InstSeqNum streamSeqNum; 8910259SAndrew.Bardsley@arm.com 9010259SAndrew.Bardsley@arm.com /** The predicted qualifier to stream, attached by Fetch2 as a 9110259SAndrew.Bardsley@arm.com * consequence of branch prediction */ 9210259SAndrew.Bardsley@arm.com InstSeqNum predictionSeqNum; 9310259SAndrew.Bardsley@arm.com 9410259SAndrew.Bardsley@arm.com /** Line sequence number. This is the sequence number of the fetched 9510259SAndrew.Bardsley@arm.com * line from which this instruction was fetched */ 9610259SAndrew.Bardsley@arm.com InstSeqNum lineSeqNum; 9710259SAndrew.Bardsley@arm.com 9810259SAndrew.Bardsley@arm.com /** Fetch sequence number. This is 0 for bubbles and an ascending 9910259SAndrew.Bardsley@arm.com * sequence for the stream of all fetched instructions */ 10010259SAndrew.Bardsley@arm.com InstSeqNum fetchSeqNum; 10110259SAndrew.Bardsley@arm.com 10210259SAndrew.Bardsley@arm.com /** 'Execute' sequence number. These are assigned after micro-op 10310259SAndrew.Bardsley@arm.com * decomposition and form an ascending sequence (starting with 1) for 10410259SAndrew.Bardsley@arm.com * post-micro-op decomposed instructions. */ 10510259SAndrew.Bardsley@arm.com InstSeqNum execSeqNum; 10610259SAndrew.Bardsley@arm.com 10710259SAndrew.Bardsley@arm.com public: 10810259SAndrew.Bardsley@arm.com /** Very boring default constructor */ 10910259SAndrew.Bardsley@arm.com InstId( 11010259SAndrew.Bardsley@arm.com ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0, 11110259SAndrew.Bardsley@arm.com InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0, 11210259SAndrew.Bardsley@arm.com InstSeqNum fetch_seq_num = 0, InstSeqNum exec_seq_num = 0) : 11310259SAndrew.Bardsley@arm.com threadId(thread_id), streamSeqNum(stream_seq_num), 11410259SAndrew.Bardsley@arm.com predictionSeqNum(prediction_seq_num), lineSeqNum(line_seq_num), 11510259SAndrew.Bardsley@arm.com fetchSeqNum(fetch_seq_num), execSeqNum(exec_seq_num) 11610259SAndrew.Bardsley@arm.com { } 11710259SAndrew.Bardsley@arm.com 11810259SAndrew.Bardsley@arm.com public: 11910259SAndrew.Bardsley@arm.com /* Equal if the thread and last set sequence number matches */ 12010259SAndrew.Bardsley@arm.com bool 12110259SAndrew.Bardsley@arm.com operator== (const InstId &rhs) 12210259SAndrew.Bardsley@arm.com { 12310259SAndrew.Bardsley@arm.com /* If any of fetch and exec sequence number are not set 12410259SAndrew.Bardsley@arm.com * they need to be 0, so a straight comparison is still 12510259SAndrew.Bardsley@arm.com * fine */ 12610259SAndrew.Bardsley@arm.com bool ret = (threadId == rhs.threadId && 12710259SAndrew.Bardsley@arm.com lineSeqNum == rhs.lineSeqNum && 12810259SAndrew.Bardsley@arm.com fetchSeqNum == rhs.fetchSeqNum && 12910259SAndrew.Bardsley@arm.com execSeqNum == rhs.execSeqNum); 13010259SAndrew.Bardsley@arm.com 13110259SAndrew.Bardsley@arm.com /* Stream and prediction *must* match if these are the same id */ 13210259SAndrew.Bardsley@arm.com if (ret) { 13310259SAndrew.Bardsley@arm.com assert(streamSeqNum == rhs.streamSeqNum && 13410259SAndrew.Bardsley@arm.com predictionSeqNum == rhs.predictionSeqNum); 13510259SAndrew.Bardsley@arm.com } 13610259SAndrew.Bardsley@arm.com 13710259SAndrew.Bardsley@arm.com return ret; 13810259SAndrew.Bardsley@arm.com } 13910259SAndrew.Bardsley@arm.com}; 14010259SAndrew.Bardsley@arm.com 14110259SAndrew.Bardsley@arm.com/** Print this id in the usual slash-separated format expected by 14210259SAndrew.Bardsley@arm.com * MinorTrace */ 14310259SAndrew.Bardsley@arm.comstd::ostream &operator <<(std::ostream &os, const InstId &id); 14410259SAndrew.Bardsley@arm.com 14510259SAndrew.Bardsley@arm.comclass MinorDynInst; 14610259SAndrew.Bardsley@arm.com 14710259SAndrew.Bardsley@arm.com/** Print a short reference to this instruction. '-' for a bubble and a 14810259SAndrew.Bardsley@arm.com * series of '/' separated sequence numbers for other instructions. The 14910259SAndrew.Bardsley@arm.com * sequence numbers will be in the order: stream, prediction, line, fetch, 15010259SAndrew.Bardsley@arm.com * exec with exec absent if it is 0. This is used by MinorTrace. */ 15110259SAndrew.Bardsley@arm.comstd::ostream &operator <<(std::ostream &os, const MinorDynInst &inst); 15210259SAndrew.Bardsley@arm.com 15310259SAndrew.Bardsley@arm.com/** Dynamic instruction for Minor. 15410259SAndrew.Bardsley@arm.com * MinorDynInst implements the BubbleIF interface 15510259SAndrew.Bardsley@arm.com * Has two separate notions of sequence number for pre/post-micro-op 15610259SAndrew.Bardsley@arm.com * decomposition: fetchSeqNum and execSeqNum */ 15710259SAndrew.Bardsley@arm.comclass MinorDynInst : public RefCounted 15810259SAndrew.Bardsley@arm.com{ 15910259SAndrew.Bardsley@arm.com private: 16010259SAndrew.Bardsley@arm.com /** A prototypical bubble instruction. You must call MinorDynInst::init 16110259SAndrew.Bardsley@arm.com * to initialise this */ 16210259SAndrew.Bardsley@arm.com static MinorDynInstPtr bubbleInst; 16310259SAndrew.Bardsley@arm.com 16410259SAndrew.Bardsley@arm.com public: 16510259SAndrew.Bardsley@arm.com StaticInstPtr staticInst; 16610259SAndrew.Bardsley@arm.com 16710259SAndrew.Bardsley@arm.com InstId id; 16810259SAndrew.Bardsley@arm.com 16910259SAndrew.Bardsley@arm.com /** Trace information for this instruction's execution */ 17010259SAndrew.Bardsley@arm.com Trace::InstRecord *traceData; 17110259SAndrew.Bardsley@arm.com 17210259SAndrew.Bardsley@arm.com /** The fetch address of this instruction */ 17310259SAndrew.Bardsley@arm.com TheISA::PCState pc; 17410259SAndrew.Bardsley@arm.com 17510259SAndrew.Bardsley@arm.com /** This is actually a fault masquerading as an instruction */ 17610259SAndrew.Bardsley@arm.com Fault fault; 17710259SAndrew.Bardsley@arm.com 17810259SAndrew.Bardsley@arm.com /** Tried to predict the destination of this inst (if a control 17910259SAndrew.Bardsley@arm.com * instruction or a sys call) */ 18010259SAndrew.Bardsley@arm.com bool triedToPredict; 18110259SAndrew.Bardsley@arm.com 18210259SAndrew.Bardsley@arm.com /** This instruction was predicted to change control flow and 18310259SAndrew.Bardsley@arm.com * the following instructions will have a newer predictionSeqNum */ 18410259SAndrew.Bardsley@arm.com bool predictedTaken; 18510259SAndrew.Bardsley@arm.com 18610259SAndrew.Bardsley@arm.com /** Predicted branch target */ 18710259SAndrew.Bardsley@arm.com TheISA::PCState predictedTarget; 18810259SAndrew.Bardsley@arm.com 18910259SAndrew.Bardsley@arm.com /** Fields only set during execution */ 19010259SAndrew.Bardsley@arm.com 19110259SAndrew.Bardsley@arm.com /** FU this instruction is issued to */ 19210259SAndrew.Bardsley@arm.com unsigned int fuIndex; 19310259SAndrew.Bardsley@arm.com 19410259SAndrew.Bardsley@arm.com /** This instruction is in the LSQ, not a functional unit */ 19510259SAndrew.Bardsley@arm.com bool inLSQ; 19610259SAndrew.Bardsley@arm.com 19714105Sgabor.dozsa@arm.com /** Translation fault in case of a mem ref */ 19814105Sgabor.dozsa@arm.com Fault translationFault; 19914105Sgabor.dozsa@arm.com 20010259SAndrew.Bardsley@arm.com /** The instruction has been sent to the store buffer */ 20110259SAndrew.Bardsley@arm.com bool inStoreBuffer; 20210259SAndrew.Bardsley@arm.com 20310259SAndrew.Bardsley@arm.com /** Can this instruction be executed out of order. In this model, 20410259SAndrew.Bardsley@arm.com * this only happens with mem refs that need to be issued early 20510259SAndrew.Bardsley@arm.com * to allow other instructions to fill the fetch delay */ 20610259SAndrew.Bardsley@arm.com bool canEarlyIssue; 20710259SAndrew.Bardsley@arm.com 20813954Sgiacomo.gabrielli@arm.com /** Flag controlling conditional execution of the instruction */ 20913954Sgiacomo.gabrielli@arm.com bool predicate; 21013954Sgiacomo.gabrielli@arm.com 21113954Sgiacomo.gabrielli@arm.com /** Flag controlling conditional execution of the memory access associated 21213954Sgiacomo.gabrielli@arm.com * with the instruction (only meaningful for loads/stores) */ 21313954Sgiacomo.gabrielli@arm.com bool memAccPredicate; 21413954Sgiacomo.gabrielli@arm.com 21510259SAndrew.Bardsley@arm.com /** execSeqNum of the latest inst on which this inst depends. 21610259SAndrew.Bardsley@arm.com * This can be used as a sanity check for dependency ordering 21710259SAndrew.Bardsley@arm.com * where slightly out of order execution is required (notably 21810259SAndrew.Bardsley@arm.com * initiateAcc for memory ops) */ 21910259SAndrew.Bardsley@arm.com InstSeqNum instToWaitFor; 22010259SAndrew.Bardsley@arm.com 22110259SAndrew.Bardsley@arm.com /** Extra delay at the end of the pipeline */ 22210259SAndrew.Bardsley@arm.com Cycles extraCommitDelay; 22310259SAndrew.Bardsley@arm.com TimingExpr *extraCommitDelayExpr; 22410259SAndrew.Bardsley@arm.com 22510259SAndrew.Bardsley@arm.com /** Once issued, extraCommitDelay becomes minimumCommitCycle 22610259SAndrew.Bardsley@arm.com * to account for delay in absolute time */ 22710259SAndrew.Bardsley@arm.com Cycles minimumCommitCycle; 22810259SAndrew.Bardsley@arm.com 22910259SAndrew.Bardsley@arm.com /** Flat register indices so that, when clearing the scoreboard, we 23010259SAndrew.Bardsley@arm.com * have the same register indices as when the instruction was marked 23110259SAndrew.Bardsley@arm.com * up */ 23212104Snathanael.premillieu@arm.com RegId flatDestRegIdx[TheISA::MaxInstDestRegs]; 23310259SAndrew.Bardsley@arm.com 23410259SAndrew.Bardsley@arm.com public: 23510259SAndrew.Bardsley@arm.com MinorDynInst(InstId id_ = InstId(), Fault fault_ = NoFault) : 23610259SAndrew.Bardsley@arm.com staticInst(NULL), id(id_), traceData(NULL), 23710259SAndrew.Bardsley@arm.com pc(TheISA::PCState(0)), fault(fault_), 23810259SAndrew.Bardsley@arm.com triedToPredict(false), predictedTaken(false), 23914105Sgabor.dozsa@arm.com fuIndex(0), inLSQ(false), translationFault(NoFault), 24014105Sgabor.dozsa@arm.com inStoreBuffer(false), canEarlyIssue(false), predicate(true), 24114105Sgabor.dozsa@arm.com memAccPredicate(true), instToWaitFor(0), extraCommitDelay(Cycles(0)), 24212420Sgabeblack@google.com extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0)) 24310259SAndrew.Bardsley@arm.com { } 24410259SAndrew.Bardsley@arm.com 24510259SAndrew.Bardsley@arm.com public: 24610259SAndrew.Bardsley@arm.com /** The BubbleIF interface. */ 24710259SAndrew.Bardsley@arm.com bool isBubble() const { return id.fetchSeqNum == 0; } 24810259SAndrew.Bardsley@arm.com 24910259SAndrew.Bardsley@arm.com /** There is a single bubble inst */ 25010259SAndrew.Bardsley@arm.com static MinorDynInstPtr bubble() { return bubbleInst; } 25110259SAndrew.Bardsley@arm.com 25210259SAndrew.Bardsley@arm.com /** Is this a fault rather than instruction */ 25310259SAndrew.Bardsley@arm.com bool isFault() const { return fault != NoFault; } 25410259SAndrew.Bardsley@arm.com 25510259SAndrew.Bardsley@arm.com /** Is this a real instruction */ 25610259SAndrew.Bardsley@arm.com bool isInst() const { return !isBubble() && !isFault(); } 25710259SAndrew.Bardsley@arm.com 25810259SAndrew.Bardsley@arm.com /** Is this a real mem ref instruction */ 25910259SAndrew.Bardsley@arm.com bool isMemRef() const { return isInst() && staticInst->isMemRef(); } 26010259SAndrew.Bardsley@arm.com 26110259SAndrew.Bardsley@arm.com /** Is this an instruction that can be executed `for free' and 26210259SAndrew.Bardsley@arm.com * needn't spend time in an FU */ 26310259SAndrew.Bardsley@arm.com bool isNoCostInst() const; 26410259SAndrew.Bardsley@arm.com 26510259SAndrew.Bardsley@arm.com /** Assuming this is not a fault, is this instruction either 26610259SAndrew.Bardsley@arm.com * a whole instruction or the last microop from a macroop */ 26710259SAndrew.Bardsley@arm.com bool isLastOpInInst() const; 26810259SAndrew.Bardsley@arm.com 26910259SAndrew.Bardsley@arm.com /** Initialise the class */ 27010259SAndrew.Bardsley@arm.com static void init(); 27110259SAndrew.Bardsley@arm.com 27210259SAndrew.Bardsley@arm.com /** Print (possibly verbose) instruction information for 27310259SAndrew.Bardsley@arm.com * MinorTrace using the given Named object's name */ 27410259SAndrew.Bardsley@arm.com void minorTraceInst(const Named &named_object) const; 27510259SAndrew.Bardsley@arm.com 27610259SAndrew.Bardsley@arm.com /** ReportIF interface */ 27710259SAndrew.Bardsley@arm.com void reportData(std::ostream &os) const; 27810259SAndrew.Bardsley@arm.com 27913954Sgiacomo.gabrielli@arm.com bool readPredicate() const { return predicate; } 28013954Sgiacomo.gabrielli@arm.com 28113954Sgiacomo.gabrielli@arm.com void setPredicate(bool val) { predicate = val; } 28213954Sgiacomo.gabrielli@arm.com 28313954Sgiacomo.gabrielli@arm.com bool readMemAccPredicate() const { return memAccPredicate; } 28413954Sgiacomo.gabrielli@arm.com 28513954Sgiacomo.gabrielli@arm.com void setMemAccPredicate(bool val) { memAccPredicate = val; } 28613954Sgiacomo.gabrielli@arm.com 28710259SAndrew.Bardsley@arm.com ~MinorDynInst(); 28810259SAndrew.Bardsley@arm.com}; 28910259SAndrew.Bardsley@arm.com 29010259SAndrew.Bardsley@arm.com/** Print a summary of the instruction */ 29110259SAndrew.Bardsley@arm.comstd::ostream &operator <<(std::ostream &os, const MinorDynInst &inst); 29210259SAndrew.Bardsley@arm.com 29310259SAndrew.Bardsley@arm.com} 29410259SAndrew.Bardsley@arm.com 29510259SAndrew.Bardsley@arm.com#endif /* __CPU_MINOR_DYN_INST_HH__ */ 296