dyn_inst.hh revision 13954
17008SN/A/* 27008SN/A * Copyright (c) 2013-2014 ARM Limited 37008SN/A * All rights reserved 47008SN/A * 57008SN/A * The license below extends only to copyright in the software and shall 67008SN/A * not be construed as granting a license to any other intellectual 77008SN/A * property including but not limited to intellectual property relating 87008SN/A * to a hardware implementation of the functionality of the software 97008SN/A * licensed hereunder. You may use the software subject to the license 107008SN/A * terms below provided that you ensure that this notice is replicated 117008SN/A * unmodified and in its entirety in all distributions of the software, 127008SN/A * modified or unmodified, in source code or in binary form. 137008SN/A * 147008SN/A * Redistribution and use in source and binary forms, with or without 157008SN/A * modification, are permitted provided that the following conditions are 167008SN/A * met: redistributions of source code must retain the above copyright 177008SN/A * notice, this list of conditions and the following disclaimer; 187008SN/A * redistributions in binary form must reproduce the above copyright 197008SN/A * notice, this list of conditions and the following disclaimer in the 207008SN/A * documentation and/or other materials provided with the distribution; 217008SN/A * neither the name of the copyright holders nor the names of its 227008SN/A * contributors may be used to endorse or promote products derived from 237008SN/A * this software without specific prior written permission. 247008SN/A * 257008SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 267008SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 277008SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 286145SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 297039SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 307039SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 316145SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210301Snilay@cs.wisc.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 336145SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 346145SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 356145SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 366145SN/A * 376145SN/A * Authors: Andrew Bardsley 386145SN/A */ 396145SN/A 406145SN/A/** 416145SN/A * @file 426145SN/A * 436145SN/A * The dynamic instruction and instruction/line id (sequence numbers) 446145SN/A * definition for Minor. A spirited attempt is made here to not carry too 456145SN/A * much on this structure. 466145SN/A */ 477039SN/A 487039SN/A#ifndef __CPU_MINOR_DYN_INST_HH__ 497039SN/A#define __CPU_MINOR_DYN_INST_HH__ 507039SN/A 517039SN/A#include <iostream> 526145SN/A 539505SN/A#include "base/refcnt.hh" 547039SN/A#include "cpu/minor/buffers.hh" 556145SN/A#include "cpu/inst_seq.hh" 567039SN/A#include "cpu/static_inst.hh" 577039SN/A#include "cpu/timing_expr.hh" 587039SN/A#include "sim/faults.hh" 597039SN/A 607039SN/Anamespace Minor 616145SN/A{ 626145SN/A 636145SN/Aclass MinorDynInst; 646145SN/A 657039SN/A/** MinorDynInsts are currently reference counted. */ 666145SN/Atypedef RefCountingPtr<MinorDynInst> MinorDynInstPtr; 677039SN/A 687039SN/A/** Id for lines and instructions. This includes all the relevant sequence 696145SN/A * numbers and thread ids for all stages of execution. */ 707039SN/Aclass InstId 717039SN/A{ 726145SN/A public: 737039SN/A /** First sequence numbers to use in initialisation of the pipeline and 747039SN/A * to be expected on the first line/instruction issued */ 757039SN/A static const InstSeqNum firstStreamSeqNum = 1; 767039SN/A static const InstSeqNum firstPredictionSeqNum = 1; 777039SN/A static const InstSeqNum firstLineSeqNum = 1; 787039SN/A static const InstSeqNum firstFetchSeqNum = 1; 797039SN/A static const InstSeqNum firstExecSeqNum = 1; 807039SN/A 817039SN/A public: 827039SN/A /** The thread to which this line/instruction belongs */ 837039SN/A ThreadID threadId; 847039SN/A 857039SN/A /** The 'stream' this instruction belongs to. Streams are interrupted 867039SN/A * (and sequence numbers increased) when Execute finds it wants to 877039SN/A * change the stream of instructions due to a branch. */ 887039SN/A InstSeqNum streamSeqNum; 896145SN/A 906145SN/A /** The predicted qualifier to stream, attached by Fetch2 as a 916145SN/A * consequence of branch prediction */ 926145SN/A InstSeqNum predictionSeqNum; 936145SN/A 947039SN/A /** Line sequence number. This is the sequence number of the fetched 957039SN/A * line from which this instruction was fetched */ 966145SN/A InstSeqNum lineSeqNum; 976145SN/A 987039SN/A /** Fetch sequence number. This is 0 for bubbles and an ascending 999505SN/A * sequence for the stream of all fetched instructions */ 1007039SN/A InstSeqNum fetchSeqNum; 1017039SN/A 1027039SN/A /** 'Execute' sequence number. These are assigned after micro-op 1036145SN/A * decomposition and form an ascending sequence (starting with 1) for 1047039SN/A * post-micro-op decomposed instructions. */ 1057039SN/A InstSeqNum execSeqNum; 1067039SN/A 1077039SN/A public: 1087039SN/A /** Very boring default constructor */ 1097039SN/A InstId( 1107039SN/A ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0, 1117039SN/A InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0, 1127039SN/A InstSeqNum fetch_seq_num = 0, InstSeqNum exec_seq_num = 0) : 1137039SN/A threadId(thread_id), streamSeqNum(stream_seq_num), 1147039SN/A predictionSeqNum(prediction_seq_num), lineSeqNum(line_seq_num), 1156145SN/A fetchSeqNum(fetch_seq_num), execSeqNum(exec_seq_num) 1166145SN/A { } 1177039SN/A 1187039SN/A public: 1197039SN/A /* Equal if the thread and last set sequence number matches */ 1207039SN/A bool 1217039SN/A operator== (const InstId &rhs) 1226145SN/A { 1237039SN/A /* If any of fetch and exec sequence number are not set 1247039SN/A * they need to be 0, so a straight comparison is still 1257039SN/A * fine */ 1267039SN/A bool ret = (threadId == rhs.threadId && 1277039SN/A lineSeqNum == rhs.lineSeqNum && 1287039SN/A fetchSeqNum == rhs.fetchSeqNum && 1297039SN/A execSeqNum == rhs.execSeqNum); 1307039SN/A 1316145SN/A /* Stream and prediction *must* match if these are the same id */ 1327039SN/A if (ret) { 1337039SN/A assert(streamSeqNum == rhs.streamSeqNum && 1347039SN/A predictionSeqNum == rhs.predictionSeqNum); 1356145SN/A } 1366145SN/A 1377039SN/A return ret; 138 } 139}; 140 141/** Print this id in the usual slash-separated format expected by 142 * MinorTrace */ 143std::ostream &operator <<(std::ostream &os, const InstId &id); 144 145class MinorDynInst; 146 147/** Print a short reference to this instruction. '-' for a bubble and a 148 * series of '/' separated sequence numbers for other instructions. The 149 * sequence numbers will be in the order: stream, prediction, line, fetch, 150 * exec with exec absent if it is 0. This is used by MinorTrace. */ 151std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst); 152 153/** Dynamic instruction for Minor. 154 * MinorDynInst implements the BubbleIF interface 155 * Has two separate notions of sequence number for pre/post-micro-op 156 * decomposition: fetchSeqNum and execSeqNum */ 157class MinorDynInst : public RefCounted 158{ 159 private: 160 /** A prototypical bubble instruction. You must call MinorDynInst::init 161 * to initialise this */ 162 static MinorDynInstPtr bubbleInst; 163 164 public: 165 StaticInstPtr staticInst; 166 167 InstId id; 168 169 /** Trace information for this instruction's execution */ 170 Trace::InstRecord *traceData; 171 172 /** The fetch address of this instruction */ 173 TheISA::PCState pc; 174 175 /** This is actually a fault masquerading as an instruction */ 176 Fault fault; 177 178 /** Tried to predict the destination of this inst (if a control 179 * instruction or a sys call) */ 180 bool triedToPredict; 181 182 /** This instruction was predicted to change control flow and 183 * the following instructions will have a newer predictionSeqNum */ 184 bool predictedTaken; 185 186 /** Predicted branch target */ 187 TheISA::PCState predictedTarget; 188 189 /** Fields only set during execution */ 190 191 /** FU this instruction is issued to */ 192 unsigned int fuIndex; 193 194 /** This instruction is in the LSQ, not a functional unit */ 195 bool inLSQ; 196 197 /** The instruction has been sent to the store buffer */ 198 bool inStoreBuffer; 199 200 /** Can this instruction be executed out of order. In this model, 201 * this only happens with mem refs that need to be issued early 202 * to allow other instructions to fill the fetch delay */ 203 bool canEarlyIssue; 204 205 /** Flag controlling conditional execution of the instruction */ 206 bool predicate; 207 208 /** Flag controlling conditional execution of the memory access associated 209 * with the instruction (only meaningful for loads/stores) */ 210 bool memAccPredicate; 211 212 /** execSeqNum of the latest inst on which this inst depends. 213 * This can be used as a sanity check for dependency ordering 214 * where slightly out of order execution is required (notably 215 * initiateAcc for memory ops) */ 216 InstSeqNum instToWaitFor; 217 218 /** Extra delay at the end of the pipeline */ 219 Cycles extraCommitDelay; 220 TimingExpr *extraCommitDelayExpr; 221 222 /** Once issued, extraCommitDelay becomes minimumCommitCycle 223 * to account for delay in absolute time */ 224 Cycles minimumCommitCycle; 225 226 /** Flat register indices so that, when clearing the scoreboard, we 227 * have the same register indices as when the instruction was marked 228 * up */ 229 RegId flatDestRegIdx[TheISA::MaxInstDestRegs]; 230 231 public: 232 MinorDynInst(InstId id_ = InstId(), Fault fault_ = NoFault) : 233 staticInst(NULL), id(id_), traceData(NULL), 234 pc(TheISA::PCState(0)), fault(fault_), 235 triedToPredict(false), predictedTaken(false), 236 fuIndex(0), inLSQ(false), inStoreBuffer(false), 237 canEarlyIssue(false), predicate(true), memAccPredicate(true), 238 instToWaitFor(0), extraCommitDelay(Cycles(0)), 239 extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0)) 240 { } 241 242 public: 243 /** The BubbleIF interface. */ 244 bool isBubble() const { return id.fetchSeqNum == 0; } 245 246 /** There is a single bubble inst */ 247 static MinorDynInstPtr bubble() { return bubbleInst; } 248 249 /** Is this a fault rather than instruction */ 250 bool isFault() const { return fault != NoFault; } 251 252 /** Is this a real instruction */ 253 bool isInst() const { return !isBubble() && !isFault(); } 254 255 /** Is this a real mem ref instruction */ 256 bool isMemRef() const { return isInst() && staticInst->isMemRef(); } 257 258 /** Is this an instruction that can be executed `for free' and 259 * needn't spend time in an FU */ 260 bool isNoCostInst() const; 261 262 /** Assuming this is not a fault, is this instruction either 263 * a whole instruction or the last microop from a macroop */ 264 bool isLastOpInInst() const; 265 266 /** Initialise the class */ 267 static void init(); 268 269 /** Print (possibly verbose) instruction information for 270 * MinorTrace using the given Named object's name */ 271 void minorTraceInst(const Named &named_object) const; 272 273 /** ReportIF interface */ 274 void reportData(std::ostream &os) const; 275 276 bool readPredicate() const { return predicate; } 277 278 void setPredicate(bool val) { predicate = val; } 279 280 bool readMemAccPredicate() const { return memAccPredicate; } 281 282 void setMemAccPredicate(bool val) { memAccPredicate = val; } 283 284 ~MinorDynInst(); 285}; 286 287/** Print a summary of the instruction */ 288std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst); 289 290} 291 292#endif /* __CPU_MINOR_DYN_INST_HH__ */ 293